Repository: kylin Updated Branches: refs/heads/2.x-staging [created] 170464fd1
KYLIN-1431 load streaming table ui update add cluster info when add table Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/2de177fa Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/2de177fa Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/2de177fa Branch: refs/heads/2.x-staging Commit: 2de177fa26b48450dfd80f3b28c4d4599180afae Parents: 9021f17 Author: Jason <jiat...@163.com> Authored: Wed Mar 9 19:01:42 2016 +0800 Committer: Jason <jiat...@163.com> Committed: Wed Mar 9 19:01:42 2016 +0800 ---------------------------------------------------------------------- .../kylin/rest/controller/CubeController.java | 68 ----------- .../kylin/rest/service/StreamingService.java | 4 +- webapp/app/js/controllers/cubeEdit.js | 82 ++++++-------- webapp/app/js/controllers/cubeRefresh.js | 1 - webapp/app/js/controllers/cubeSchema.js | 2 +- webapp/app/js/controllers/sourceMeta.js | 82 ++++++++++++-- webapp/app/js/controllers/streamingConfig.js | 8 ++ webapp/app/js/model/modelsManager.js | 1 + webapp/app/less/app.less | 4 + .../partials/cubeDesigner/streamingConfig.html | 16 +-- .../app/partials/tables/loadStreamingTable.html | 89 +++++++++++++++ webapp/app/partials/tables/table_load.html | 112 +++++-------------- 12 files changed, 242 insertions(+), 227 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/server/src/main/java/org/apache/kylin/rest/controller/CubeController.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/kylin/rest/controller/CubeController.java b/server/src/main/java/org/apache/kylin/rest/controller/CubeController.java index e60f330..bc00795 100644 --- a/server/src/main/java/org/apache/kylin/rest/controller/CubeController.java +++ b/server/src/main/java/org/apache/kylin/rest/controller/CubeController.java @@ -356,74 +356,6 @@ public class CubeController extends BasicController { throw new InternalErrorException(e.getLocalizedMessage(), e); } - boolean createStreamingConfigSuccess = false, createKafkaConfigSuccess = false; - StreamingConfig streamingConfig = null; - KafkaConfig kafkaConfig = null; - - boolean isStreamingCube = cubeRequest.getStreamingCube() != null && cubeRequest.getStreamingCube().equals("true"); - try { - //streaming Cube - if (isStreamingCube) { - streamingConfig = deserializeStreamingDesc(cubeRequest); - kafkaConfig = deserializeKafkaDesc(cubeRequest); - // validate before create, rollback when error - if (kafkaConfig == null) { - cubeRequest.setMessage("No KafkaConfig info defined."); - return cubeRequest; - } - if (streamingConfig == null) { - cubeRequest.setMessage("No StreamingConfig info defined."); - return cubeRequest; - } - - try { - streamingConfig.setUuid(UUID.randomUUID().toString()); - streamingService.createStreamingConfig(streamingConfig); - createStreamingConfigSuccess = true; - } catch (IOException e) { - logger.error("Failed to save StreamingConfig:" + e.getLocalizedMessage(), e); - throw new InternalErrorException("Failed to save StreamingConfig: " + e.getLocalizedMessage()); - } - try { - kafkaConfig.setUuid(UUID.randomUUID().toString()); - kafkaConfigService.createKafkaConfig(kafkaConfig); - createKafkaConfigSuccess = true; - } catch (IOException e) { - logger.error("Failed to save KafkaConfig:" + e.getLocalizedMessage(), e); - throw new InternalErrorException("Failed to save KafkaConfig: " + e.getLocalizedMessage()); - } - - } - } finally { - //rollback if failed - if (isStreamingCube) { - if (createStreamingConfigSuccess == false || createKafkaConfigSuccess == false) { - try { - cubeService.deleteCube(cubeInstance); - } catch (Exception ex) { - throw new InternalErrorException("Failed to rollback on delete cube. " + " Caused by: " + ex.getMessage(), ex); - } - if (createStreamingConfigSuccess == true) { - try { - streamingService.dropStreamingConfig(streamingConfig); - } catch (IOException e) { - throw new InternalErrorException("Failed to create cube, and StreamingConfig created and failed to delete: " + e.getLocalizedMessage()); - } - } - if (createKafkaConfigSuccess == true) { - try { - kafkaConfigService.dropKafkaConfig(kafkaConfig); - } catch (IOException e) { - throw new InternalErrorException("Failed to create cube, and KafkaConfig created and failed to delete: " + e.getLocalizedMessage()); - } - } - - } - - } - - } - cubeRequest.setUuid(desc.getUuid()); cubeRequest.setSuccessful(true); return cubeRequest; http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/server/src/main/java/org/apache/kylin/rest/service/StreamingService.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/kylin/rest/service/StreamingService.java b/server/src/main/java/org/apache/kylin/rest/service/StreamingService.java index a0473e9..9627e8f 100644 --- a/server/src/main/java/org/apache/kylin/rest/service/StreamingService.java +++ b/server/src/main/java/org/apache/kylin/rest/service/StreamingService.java @@ -45,7 +45,9 @@ public class StreamingService extends BasicService { streamingConfigs = getStreamingManager().listAllStreaming(); } else { StreamingConfig config = getStreamingManager().getConfig(table); - streamingConfigs.add(config); + if(config!=null){ + streamingConfigs.add(config); + } } return streamingConfigs; http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/webapp/app/js/controllers/cubeEdit.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeEdit.js b/webapp/app/js/controllers/cubeEdit.js index 6f0df38..24bdf8d 100755 --- a/webapp/app/js/controllers/cubeEdit.js +++ b/webapp/app/js/controllers/cubeEdit.js @@ -171,24 +171,25 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio if (!modelsManager.getModels().length) { ModelDescService.query({model_name: $scope.cubeMetaFrame.model_name}, function (_model) { $scope.metaModel.model = _model; + + StreamingService.getConfig({table:$scope.metaModel.model.fact_table}, function (kfkConfigs) { + if(!!kfkConfigs[0]){ + $scope.cubeState.isStreaming = true; + } + else{ + return; + } + $scope.streamingMeta = kfkConfigs[0]; + StreamingService.getKfkConfig({kafkaConfigName:$scope.streamingMeta.name}, function (streamings) { + $scope.kafkaMeta = streamings[0]; + }) + }) }); } - $scope.metaModel.model = modelsManager.getModel($scope.cubeMetaFrame.model_name); $scope.state.cubeSchema = angular.toJson($scope.cubeMetaFrame, true); - StreamingService.getConfig({cubeName:$scope.cubeMetaFrame.name}, function (kfkConfigs) { - if(!!kfkConfigs[0]){ - $scope.cubeState.isStreaming = true; - } - else{ - return; - } - $scope.streamingMeta = kfkConfigs[0]; - StreamingService.getKfkConfig({kafkaConfigName:$scope.streamingMeta.name}, function (streamings) { - $scope.kafkaMeta = streamings[0]; - }) - }) + } }); @@ -732,41 +733,32 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio }); - $scope.streamingCfg = { - parseTsColumn:"{{}}", - columnOptions:[] - } //dimensions options is depend on the model input when add cube - $scope.$watch('cubeMetaFrame.model_name', function (newValue, oldValue) { - if (!newValue) { - return; - } - $scope.metaModel.model = modelsManager.getModel(newValue); + //$scope.$watch('cubeMetaFrame.model_name', function (newValue, oldValue) { + // if (!newValue) { + // return; + // } + // $scope.metaModel.model = modelsManager.getModel(newValue); + // + // if(!$scope.metaModel.model){ + // return; + // } + // + // var factTable = $scope.metaModel.model.fact_table; + // var cols = $scope.getColumnsByTable(factTable); + // + // for(var i=0;i<cols.length;i++){ + // var col = cols[i]; + // if(col.datatype === "timestamp"){ + // $scope.streamingCfg.columnOptions.push(col.name); + // } + // } + // $scope.kafkaMeta.parserProperties = "tsColName=' ';formatTs=TRUE"; + // + // + //}); - if(!$scope.metaModel.model){ - return; - } - - var factTable = $scope.metaModel.model.fact_table; - var cols = $scope.getColumnsByTable(factTable); - - for(var i=0;i<cols.length;i++){ - var col = cols[i]; - if(col.datatype === "timestamp"){ - $scope.streamingCfg.columnOptions.push(col.name); - } - } - $scope.kafkaMeta.parserProperties = "tsColName=' ';formatTs=TRUE"; - - }); - - $scope.streamingTsColUpdate = function(){ - if(!$scope.streamingCfg.parseTsColumn){ - $scope.streamingCfg.parseTsColumn = ' '; - } - $scope.kafkaMeta.parserProperties = "tsColName="+$scope.streamingCfg.parseTsColumn+";formatTs=TRUE"; - } $scope.$on('DimensionsEdited', function (event) { if ($scope.cubeMetaFrame) { reGenerateRowKey(); http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/webapp/app/js/controllers/cubeRefresh.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeRefresh.js b/webapp/app/js/controllers/cubeRefresh.js index d0de50a..ac4b7f7 100644 --- a/webapp/app/js/controllers/cubeRefresh.js +++ b/webapp/app/js/controllers/cubeRefresh.js @@ -23,7 +23,6 @@ KylinApp.controller('CubeRefreshCtrl', function ($scope, $modal,cubeConfig,MetaM //edit model if($scope.state.mode==="edit") { - $scope.metaModel = MetaModel; if(!$scope.cubeMetaFrame.auto_merge_time_ranges){ $scope.cubeMetaFrame.auto_merge_time_ranges = []; } http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/webapp/app/js/controllers/cubeSchema.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeSchema.js b/webapp/app/js/controllers/cubeSchema.js index d446730..d4f1e1c 100755 --- a/webapp/app/js/controllers/cubeSchema.js +++ b/webapp/app/js/controllers/cubeSchema.js @@ -34,7 +34,7 @@ KylinApp.controller('CubeSchemaCtrl', function ($scope, QueryService, UserServic if (UserService.hasRole("ROLE_ADMIN")) { $scope.wizardSteps.push({title: 'Advanced Setting', src: 'partials/cubeDesigner/advanced_settings.html', isComplete: false,form:'cube_setting_form'}); } - $scope.wizardSteps.push({title: 'Streaming', src: 'partials/cubeDesigner/streamingConfig.html', isComplete: false,form:'cube_streaming_form'}); + //$scope.wizardSteps.push({title: 'Streaming', src: 'partials/cubeDesigner/streamingConfig.html', isComplete: false,form:'cube_streaming_form'}); $scope.wizardSteps.push({title: 'Overview', src: 'partials/cubeDesigner/overview.html', isComplete: false,form:null}); $scope.curStep = $scope.wizardSteps[0]; http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/webapp/app/js/controllers/sourceMeta.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/sourceMeta.js b/webapp/app/js/controllers/sourceMeta.js index 69f1a44..472b18b 100755 --- a/webapp/app/js/controllers/sourceMeta.js +++ b/webapp/app/js/controllers/sourceMeta.js @@ -422,7 +422,72 @@ KylinApp }); }; - var StreamingSourceCtrl = function ($scope, $location, $modalInstance, tableNames, MessageService, projectName, scope, tableConfig,cubeConfig) { + var StreamingSourceCtrl = function ($scope, $location, $modalInstance, tableNames, MessageService, projectName, scope, tableConfig,cubeConfig,StreamingModel) { + + $scope.cubeState={ + "isStreaming": false + } + $scope.state={ + 'mode':'edit' + } + + $scope.streamingMeta = StreamingModel.createStreamingConfig(); + $scope.kafkaMeta = StreamingModel.createKafkaConfig(); + + + $scope.steps = { + curStep:1 + }; + + $scope.streamingCfg = { + parseTsColumn:"{{}}", + columnOptions:[] + } + + $scope.previewStep = function(){ + $scope.steps.curStep--; + } + + $scope.nextStep = function(){ + //check form + $scope.form['setStreamingSchema'].$sbumitted = true; + if(!$scope.streaming.sourceSchema||$scope.streaming.sourceSchema===""){ + return; + } + + if(!$scope.table.name||$scope.table.name===""){ + return; + } + + $scope.prepareNextStep(); + + if(!$scope.rule.timestampColumnExist){ + return; + } + + $scope.steps.curStep++; + } + + $scope.prepareNextStep = function(){ + $scope.streamingCfg.columnOptions = []; + angular.forEach($scope.columnList,function(column,$index){ + if (column.checked == "Y" && column.fromSource=="Y" && column.type == "timestamp") { + $scope.streamingCfg.columnOptions.push(column.name); + $scope.rule.timestampColumnExist = true; + } + }) + + if($scope.streamingCfg.columnOptions.length==1){ + $scope.streamingCfg.parseTsColumn = $scope.streamingCfg.columnOptions[0]; + $scope.kafkaMeta.parserProperties = "tsColName="+$scope.streamingCfg.parseTsColumn; + } + if($scope.kafkaMeta.parserProperties!==''){ + $scope.state.isParserHeaderOpen = false; + }else{ + $scope.state.isParserHeaderOpen = true; + } + } + $scope.projectName = projectName; $scope.tableConfig = tableConfig; $scope.cubeConfig = cubeConfig; @@ -433,7 +498,8 @@ KylinApp $scope.table = { name: '', - sourceValid:false + sourceValid:false, + schemaChecked:false } $scope.cancel = function () { @@ -447,6 +513,7 @@ KylinApp $scope.columnList = []; $scope.streamingOnChange = function () { + $scope.table.schemaChecked = true; console.log($scope.streaming.sourceSchema); try { $scope.streaming.parseResult = JSON.parse($scope.streaming.sourceSchema); @@ -525,17 +592,9 @@ KylinApp $scope.form={}; $scope.rule={ - 'timestampColumnConflict':false + 'timestampColumnExist':false } $scope.syncStreamingSchema = function () { - $scope.form['setStreamingSchema'].$sbumitted = true; - if(!$scope.streaming.sourceSchema||$scope.streaming.sourceSchema===""){ - return; - } - - if(!$scope.table.name||$scope.table.name===""){ - return; - } var columns = []; angular.forEach($scope.columnList,function(column,$index){ @@ -552,6 +611,7 @@ KylinApp $scope.tableData = { "name": $scope.table.name, + "source_type":1, "columns": columns, 'database':'Default' } http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/webapp/app/js/controllers/streamingConfig.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/streamingConfig.js b/webapp/app/js/controllers/streamingConfig.js index 53b30e0..b0a1ebd 100644 --- a/webapp/app/js/controllers/streamingConfig.js +++ b/webapp/app/js/controllers/streamingConfig.js @@ -72,4 +72,12 @@ KylinApp.controller('streamingConfigCtrl', function ($scope, $q, $routeParams, $ delete cluster.newBroker; } + + $scope.streamingTsColUpdate = function(){ + if(!$scope.streamingCfg.parseTsColumn){ + $scope.streamingCfg.parseTsColumn = ' '; + } + $scope.kafkaMeta.parserProperties = "tsColName="+$scope.streamingCfg.parseTsColumn; + } + }); http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/webapp/app/js/model/modelsManager.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/model/modelsManager.js b/webapp/app/js/model/modelsManager.js index e117053..03f0480 100644 --- a/webapp/app/js/model/modelsManager.js +++ b/webapp/app/js/model/modelsManager.js @@ -87,6 +87,7 @@ KylinApp.service('modelsManager',function(ModelService,CubeService,$q,AccessServ }) } + this.getModels = function(){ return _this.models; } http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/webapp/app/less/app.less ---------------------------------------------------------------------- diff --git a/webapp/app/less/app.less b/webapp/app/less/app.less index b6b3131..238e72e 100644 --- a/webapp/app/less/app.less +++ b/webapp/app/less/app.less @@ -788,3 +788,7 @@ input:-moz-placeholder { .dropdown-menu{ z-index:9999; } + +.panel-group .panel{ + overflow: auto !important; +} http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/webapp/app/partials/cubeDesigner/streamingConfig.html ---------------------------------------------------------------------- diff --git a/webapp/app/partials/cubeDesigner/streamingConfig.html b/webapp/app/partials/cubeDesigner/streamingConfig.html index ed03229..c3afd26 100644 --- a/webapp/app/partials/cubeDesigner/streamingConfig.html +++ b/webapp/app/partials/cubeDesigner/streamingConfig.html @@ -18,22 +18,8 @@ <div ng-controller="streamingConfigCtrl"> <ng-form name="forms.cube_streaming_form" novalidate> - <div class="form-group"> - <div class="row"> - <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"> - <b>Is this cube for streaming use?</b> - </label> - <div class="col-xs-12 col-sm-6" ng-if="state.mode=='edit'" > - <toggle-switch ng-model="cubeState.isStreaming" on-label="YES" off-label="NO"> <toggle-switch> - </div> - <div class="col-xs-12 col-sm-6" ng-if="state.mode=='view'" > - <span>{{(!!cubeState.isStreaming)?'YES':'NO'}}</span> - </div> - </div> - </div> -{{}} - <div ng-if="cubeState.isStreaming"> + <div> <accordion> <accordion-group is-open="state.isKfkSettingOpen" ng-init="state.isKfkSettingOpen=true"> <accordion-heading> http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/webapp/app/partials/tables/loadStreamingTable.html ---------------------------------------------------------------------- diff --git a/webapp/app/partials/tables/loadStreamingTable.html b/webapp/app/partials/tables/loadStreamingTable.html new file mode 100644 index 0000000..5e6116c --- /dev/null +++ b/webapp/app/partials/tables/loadStreamingTable.html @@ -0,0 +1,89 @@ + +<div class="modal-body streaming-source" style="height: 360px;"> + <div class="col-xs-5"> + <p class="text-info"> + Need to input streaming source record here, will detect the source schema and create a table schema for + streaming. + </p> + <div class="has-error" ng-if="!table.sourceValid&&table.schemaChecked"> + <small class="help-block"> + Source json invalid. + </small> + </div> + <div style="padding:15px;" class="has-error"> + <small class="help-block" ng-show="streaming.sourceSchema==''&&form.setStreamingSchema.$sbumitted">Please + input Streaming source record to generate schema. + </small> + </div> + <div style="margin-bottom: 20px;"> + <span class="label label-info">JSON</span> + </div> + <div ng-model="streaming.sourceSchema" ui-ace="{ + useWrapMode : true, + mode:'json', + onLoad: streamingOnLoad + }"> + + </div> + </div> + <div class="col-xs-1" style="margin-top:300px;text-align:center;"> + <button type="button" class="btn btn-primary" ng-click="streamingOnChange()"><i + class="fa fa-angle-double-right fa-5" style="font-size:2em;"></i></button> + </div> + <div class="col-xs-6" ng-show="table.schemaChecked"> + <ol class="text-info" style="margin-bottom: 30px;"> + <li>Choose 'timestamp' type column for streaming table.</li> + <li>derived time dimensions are calculated from timestamp field to help analysis against different time granularities.</li> + </ol> + <form class="form-horizontal" name="form.setStreamingSchema" novalidate> + <div class="form-group required"> + <label class="col-xs-4 control-label" style="text-align: left;">Table Name</label> + + <div class="col-xs-8" + ng-class="{'has-error':form.setStreamingSchema.streamingObject.$invalid && (form.setStreamingSchema.streamingObject.$dirty||form.setStreamingSchema.$sbumitted)}"> + <input type="text" name="streamingObject" required="" ng-model="table.name" class="form-control"/> + <small class="help-block" + ng-show="form.setStreamingSchema.streamingObject.$error.required&&(form.setStreamingSchema.streamingObject.$dirty||form.setStreamingSchema.$sbumitted)"> + Table name is required. + </small> + </div> + </div> + </form> + <table class="table table-hover table-bordered"> + <tr> + <th></th> + <th>Column</th> + <th>Column Type</th> + <th>Comment</th> + </tr> + <tr ng-repeat="column in columnList"> + <td><label style="width:100%;cursor: pointer;" for="{{column.name}}"><input style="width:1em;height:1em;" + type="checkbox" + id="{{column.name}}" + ng-model="column.checked" + ng-true-value="Y" + ng-false-value="N"/></label> + </td> + <td>{{column.name}}</td> + <td> + <select chosen ng-model="column.type" + ng-options="type as type for type in tableConfig.dataTypes" + data-placeholder="select a column type" + style="width: 120px !important;" + class="chosen-select"> + </select> + </td> + <td> + <label ng-if="column.type=='timestamp'&&column.fromSource=='Y'" class="badge badge-info">timestamp</label> + <label ng-if="column.fromSource=='N'" class="badge badge-info">derived time dimension</label> + </td> + </tr> + </table> + + <div class="has-error" ng-if="!rule.timestampColumnExist&&form.setStreamingSchema.$sbumitted"> + <small class="help-block"> + You should choose at least one 'timestamp' type column generated from source schema. + </small> + </div> + </div> +</div> http://git-wip-us.apache.org/repos/asf/kylin/blob/2de177fa/webapp/app/partials/tables/table_load.html ---------------------------------------------------------------------- diff --git a/webapp/app/partials/tables/table_load.html b/webapp/app/partials/tables/table_load.html index 29a2e9a..1fd4751 100644 --- a/webapp/app/partials/tables/table_load.html +++ b/webapp/app/partials/tables/table_load.html @@ -33,98 +33,40 @@ </script> <script type="text/ng-template" id="addStreamingSource.html"> - <div class="modal-header"> - <h2>Create Streaming Table Schema</h2> - </div> - <div class="modal-body streaming-source" style="height: 660px;"> - <div class="col-xs-5"> - <p class="text-info"> - Need to input streaming source record here, will detect the source schema and create a table schema for - streaming. - </p> - - <div style="padding:15px;" class="has-error"> - <small class="help-block" ng-show="streaming.sourceSchema==''&&form.setStreamingSchema.$sbumitted">Please - input Streaming source record to generate schema. - </small> - </div> - <div style="margin-bottom: 20px;"> - <span class="label label-info">JSON</span> - </div> - <div ng-model="streaming.sourceSchema" ui-ace="{ - useWrapMode : true, - mode:'json', - onLoad: streamingOnLoad - }"> + <div class="modal-header"> + <div class="box-header"> + <h3 class="box-title">Streaming Table And Cluster Info</h3> + <div class="box-tools pull-right"> + <button type="button" class="btn btn-box-tool" ng-click="cancel()" data-widget="remove"><i class="fa fa-times"></i></button> </div> </div> - <div class="col-xs-1" style="margin-top:300px;text-align:center;"> - <button type="button" class="btn btn-primary" ng-click="streamingOnChange()"><i - class="fa fa-angle-double-right fa-5" style="font-size:2em;"></i></button> - </div> - <div class="col-xs-6" ng-show="table.sourceValid"> - <ol class="text-info" style="margin-bottom: 30px;"> - <li>Choose 'timestamp' type column for streaming table.</li> - <li>derived time dimensions are calculated from timestamp field to help analysis against different time granularities.</li> - </ol> - <form class="form-horizontal" name="form.setStreamingSchema" novalidate> - <div class="form-group required"> - <label class="col-xs-4 control-label" style="text-align: left;">Table Name</label> + </div> - <div class="col-xs-8" - ng-class="{'has-error':form.setStreamingSchema.streamingObject.$invalid && (form.setStreamingSchema.streamingObject.$dirty||form.setStreamingSchema.$sbumitted)}"> - <input type="text" name="streamingObject" required="" ng-model="table.name" class="form-control"/> - <small class="help-block" - ng-show="form.setStreamingSchema.streamingObject.$error.required&&(form.setStreamingSchema.streamingObject.$dirty||form.setStreamingSchema.$sbumitted)"> - Table name is required. - </small> - </div> + <div class="modal-body streaming-source" style="height: 660px;overflow-y:auto;"> + <div ng-show="steps.curStep==1" ng-include="'partials/tables/loadStreamingTable.html'"></div> + <div ng-show="steps.curStep==2" ng-include="'partials/cubeDesigner/streamingConfig.html'"></div> + </div> + <div class="modal-footer"> + <div class="row"> + <div class="col-xs-8"> + <div> </div> - </form> - <table class="table table-hover table-bordered"> - <tr> - <th></th> - <th>Column</th> - <th>Column Type</th> - <th>Comment</th> - </tr> - <tr ng-repeat="column in columnList"> - <td><label style="width:100%;cursor: pointer;" for="{{column.name}}"><input style="width:1em;height:1em;" - type="checkbox" - id="{{column.name}}" - ng-model="column.checked" - ng-true-value="Y" - ng-false-value="N"/></label> - </td> - <td>{{column.name}}</td> - <td> - <select chosen ng-model="column.type" - ng-options="type as type for type in tableConfig.dataTypes" - data-placeholder="select a column type" - style="width: 120px !important;" - class="chosen-select"> - </select> - </td> - <td> - <label ng-if="column.type=='timestamp'&&column.fromSource=='Y'" class="badge badge-info">timestamp</label> - <label ng-if="column.fromSource=='N'" class="badge badge-info">derived time dimension</label> - </td> - </tr> - </table> - - <div class="has-error" ng-if="rule.timestampColumnConflict"> - <small class="help-block"> - You should choose one, and only one 'timestamp' type column generated from source schema. - </small> + </div> + <div class="col-xs-4"> + <button class="btn btn-prev" ng-click="previewStep();" ng-show="steps.curStep==2"> + <i class="ace-icon fa fa-arrow-left"></i> + Prev + </button> + <button id="nextButton" class="btn btn-success btn-next" ng-click="nextStep();" ng-show="steps.curStep==1"> + Next + <i class="ace-icon fa fa-arrow-right icon-on-right"></i> + </button> + <button class="btn btn-primary" ng-click="syncStreamingSchema()" ng-show="steps.curStep==2"> + Submit + </button> </div> </div> </div> - <div class="modal-footer"> - <button class="btn btn-primary" ng-click="syncStreamingSchema()" ng-disabled="form.setStreamingSchema.$invalid"> - Submit - </button> - <button class="btn btn-primary" ng-click="cancel()">Cancel</button> - </div> </script>