You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by zh...@apache.org on 2015/10/22 12:06:54 UTC
[2/5] incubator-kylin git commit: KYLIN-1041, Streaming UI
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/js/model/cubeListModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/cubeListModel.js b/webapp/app/js/model/cubeListModel.js
index 7145092..5a2d1b2 100755
--- a/webapp/app/js/model/cubeListModel.js
+++ b/webapp/app/js/model/cubeListModel.js
@@ -17,8 +17,8 @@
*/
KylinApp.service('CubeList',function(CubeService,$q,AccessService){
- var cubes=[];
var _this = this;
+ this.cubes=[];
this.list = function(queryParam){
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/js/model/streamingListModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/streamingListModel.js b/webapp/app/js/model/streamingListModel.js
new file mode 100644
index 0000000..113ffe6
--- /dev/null
+++ b/webapp/app/js/model/streamingListModel.js
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+KylinApp.service('StreamingList', function (CubeService, $q, AccessService, StreamingService) {
+ var _this = this;
+ this.streamingConfigs = [];
+ this.kafkaConfigs = [];
+
+
+ this.list = function () {
+ var defer = $q.defer();
+
+ var streamingPromises = [];
+ var kafkaPromises = [];
+
+
+ kafkaPromises.push(StreamingService.getKfkConfig({}, function (kfkConfigs) {
+ _this.kafkaConfigs = kfkConfigs;
+ },function(){
+ defer.reject("Failed to load models");
+ }).$promise);
+
+ streamingPromises.push(StreamingService.getConfig({}, function (streamings) {
+ _this.streamingConfigs = streamings;
+ },function(){
+ defer.reject("Failed to load models");
+ }).$promise);
+
+ $q.all(streamingPromises,kafkaPromises).then(function(result,rs){
+ defer.resolve("success");
+ },function(){
+ defer.resolve("failed");
+ })
+ return defer.promise;
+
+ };
+
+ this.checkCubeExist = function(cubeName){
+ var result = {streaming:null,exist:false};
+ for(var i=0;i<_this.streamingConfigs.length;i++){
+ if(_this.streamingConfigs[i].cubeName == cubeName){
+ result ={
+ streaming:_this.streamingConfigs[i],
+ exist:true
+ }
+ break;
+ }
+ }
+ return result;
+ }
+
+ this.getKafkaConfig = function(kfkName){
+ for(var i=0;i<_this.kafkaConfigs.length;i++) {
+ if(_this.kafkaConfigs[i].name == kfkName){
+ return _this.kafkaConfigs[i];
+ }
+ }
+ }
+
+ this.removeAll = function () {
+ _this.streamingConfigs = [];
+ _this.kafkaConfigs = [];
+ };
+
+});
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/js/model/streamingModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/streamingModel.js b/webapp/app/js/model/streamingModel.js
new file mode 100644
index 0000000..fa2d20c
--- /dev/null
+++ b/webapp/app/js/model/streamingModel.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.
+ */
+
+KylinApp.service('StreamingModel', function () {
+
+ //
+ this.createStreamingConfig = function () {
+ var streamingConfig = {
+ "name": "",
+ "iiName": "",
+ "cubeName": ""
+ };
+
+ return streamingConfig;
+ };
+
+ this.createKafkaConfig = function () {
+ var kafkaConfig = {
+ "name": "",
+ "topic": "",
+ "timeout": "60000",
+ "maxReadCount": "1000",
+ "bufferSize": "65536",
+ "parserName": "org.apache.kylin.streaming.TimedJsonStreamParser",
+ "margin": "300000",
+ "clusters":[],
+ "parserProperties":""
+ }
+
+ return kafkaConfig;
+ }
+
+ this.createKafkaCluster = function () {
+ var kafkaCluster = {
+ "brokers":[]
+ }
+
+ return kafkaCluster;
+ }
+
+ this.createBrokerConfig = function () {
+ var brokerConfig = {
+ "id":'',
+ "host":'',
+ "port":''
+ }
+
+ return brokerConfig;
+ }
+
+})
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/js/services/streaming.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/services/streaming.js b/webapp/app/js/services/streaming.js
new file mode 100644
index 0000000..9da4394
--- /dev/null
+++ b/webapp/app/js/services/streaming.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.
+*/
+
+KylinApp.factory('StreamingService', ['$resource', function ($resource, config) {
+ return $resource(Config.service.url + 'streaming/:streamingId/:propName/:propValue/:action', {}, {
+ list: {method: 'GET', params: {}, isArray: true},
+ 'getConfig': {method: 'GET',params: {action:'getConfig'},isArray:true},
+ 'getKfkConfig': {method: 'GET',params: {action:'getKfkConfig'},isArray:true},
+ drop: {method: 'DELETE', params: {}, isArray: false},
+ save: {method: 'POST', params: {}, isArray: false},
+ update: {method: 'PUT', params: {}, isArray: false}
+ });
+}]);
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/filter.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/filter.html b/webapp/app/partials/cubeDesigner/filter.html
deleted file mode 100644
index 118c4aa..0000000
--- a/webapp/app/partials/cubeDesigner/filter.html
+++ /dev/null
@@ -1,66 +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.
--->
-
-<div ng-controller="CubeFilterCtrl">
-<div class="row">
- <div class="col-xs-8">
- <!--Cube Designer-->
- <div class="form-group" ng-if="state.mode=='edit'"
- style="font-family:'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro'">
- <label for="filter_condition"
- style="color: #930f80;"><b>WHERE</b></label>
- <textarea id="filter_condition" type="text"
- style="height:150px"
- class="form-control box-default"
- placeholder="Please input WHERE clause without typing 'WHERE'"
- ng-model="metaModel.model.filter_condition">
- </textarea>
- </div>
- <!--Cube Detail-->
- <div class="form-group row" ng-if="state.mode=='view'"
- style="font-family:'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro'">
- <div ng-if="metaModel.model.filter_condition" class="col-md-11 col-md-offset-1">
- <p style="color: #930f80;"><b>WHERE</b></p>
- <span>{{metaModel.model.filter_condition}}</span>
- </div>
- <div ng-if="!metaModel.model.filter_condition" no-result text="No Filter."></div>
- </div>
- </div>
-
- <!--Tips-->
- <div class="col-xs-4">
- <div class="box box-solid">
- <div class="box-header">
- <h4 class="box-title">Tips</h4>
- </div>
- <div class="box-body">
- <div class="row">
- <div class="col-xs-12">
- <ol class="text-info">
- <li>Where clause to filter data from source</li>
- <li>Do not include date column which will be used for incremental refresh</li>
- <li>Do not include "Where"</li>
- <li>Please verify SQL when finish cube design from SQL view of cube</li>
- </ol>
- </div>
- </div>
- </div>
- </div>
- </div>
-</div>
-</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/info.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/info.html b/webapp/app/partials/cubeDesigner/info.html
index f680487..3389c4a 100644
--- a/webapp/app/partials/cubeDesigner/info.html
+++ b/webapp/app/partials/cubeDesigner/info.html
@@ -20,7 +20,7 @@
<div class="col-xs-8">
<ng-form name="forms.cube_info_form" novalidate>
<!--Project-->
- <div class="form-group required">
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
<div class="row">
<label class="col-xs-12 col-sm-3 control-label no-padding-right">
<b>Model Name</b>
@@ -40,7 +40,7 @@
</div>
<!--Cube Name-->
- <div class="form-group required">
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
<div class="row">
<label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default">
<b>Cube Name</b>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/kafkaAdvancedConfig.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/kafkaAdvancedConfig.html b/webapp/app/partials/cubeDesigner/kafkaAdvancedConfig.html
new file mode 100644
index 0000000..c0b2b39
--- /dev/null
+++ b/webapp/app/partials/cubeDesigner/kafkaAdvancedConfig.html
@@ -0,0 +1,165 @@
+<!--
+* 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 ng-controller="kafkaConfigCtrl">
+ <ng-form name="forms.kafka_ad_config_form" novalidate>
+ <accordion>
+
+ <accordion-group is-open="state.isStreamingAdOpen" ng-init="state.isStreamingAdOpen=true">
+ <accordion-heading>
+ Advanced Setting
+ <i class="pull-right glyphicon"
+ ng-class="{'glyphicon-chevron-down': state.isStreamingAdOpen, 'glyphicon-chevron-right': !state.isStreamingAdOpen}"></i>
+ </accordion-heading>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Timeout</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.kafka_ad_config_form.timeout.$invalid && (forms.kafka_ad_config_form.timeout.$dirty||forms.kafka_ad_config_form.timeout.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.timeout" type="text"
+ placeholder="Input kafkaConfig timeout"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.kafka_ad_config_form.timeout.$error.required && (forms.kafka_ad_config_form.timeout.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+ Kafka timeout is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.timeout}}</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Max Read Count</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.kafka_ad_config_form.maxReadCount.$invalid && (forms.kafka_ad_config_form.maxReadCount.$dirty||forms.kafka_ad_config_form.maxReadCount.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.maxReadCount" type="text"
+ placeholder="Input kafkaConfig maxReadCount"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.kafka_ad_config_form.maxReadCount.$error.required && (forms.kafka_ad_config_form.maxReadCount.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+ Kafka maxReadCount is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.maxReadCount}}</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Buffer Size</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.kafka_ad_config_form.bufferSize.$invalid && (forms.kafka_ad_config_form.bufferSize.$dirty||forms.kafka_ad_config_form.bufferSize.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.bufferSize" type="text"
+ placeholder="Input kafkaConfig bufferSize"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.kafka_ad_config_form.bufferSize.$error.required && (forms.kafka_ad_config_form.bufferSize.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+ Kafka bufferSize is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.bufferSize}}</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Margin</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.kafka_ad_config_form.margin.$invalid && (forms.kafka_ad_config_form.margin.$dirty||forms.kafka_ad_config_form.margin.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.margin" type="text"
+ placeholder="Input kafkaConfig margin"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.kafka_ad_config_form.margin.$error.required && (forms.kafka_ad_config_form.margin.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+ Kafka margin is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.margin}}</span>
+ </div>
+ </div>
+ </div>
+ </accordion-group>
+ </accordion>
+
+ <hr/>
+ <accordion>
+
+ <accordion-group is-open="state.isParserHeaderOpen">
+ <accordion-heading>
+ Parser Setting
+ <i class="pull-right glyphicon"
+ ng-class="{'glyphicon-chevron-down': state.isParserHeaderOpen, 'glyphicon-chevron-right': !state.isParserHeaderOpen}"></i>
+ </accordion-heading>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Parser Name</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.kafka_ad_config_form.parserName.$invalid && (forms.kafka_ad_config_form.parserName.$dirty||forms.kafka_ad_config_form.parserName.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.parserName" type="text"
+ placeholder="Input kafkaConfig parserName"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.kafka_ad_config_form.parserName.$error.required && (forms.kafka_ad_config_form.parserName.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+ Kafka parserName is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.parserName}}</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Parser Properties</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.kafka_ad_config_form.parserProperties.$invalid && (forms.kafka_ad_config_form.parserProperties.$dirty||forms.kafka_ad_config_form.parserProperties.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.parserProperties" type="text"
+ placeholder="configA=1;configB=2"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.kafka_ad_config_form.parserProperties.$error.required && (forms.kafka_ad_config_form.parserProperties.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+ Parser Properties is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.parserProperties}}</span>
+ </div>
+ </div>
+ </div>
+ </accordion-group>
+ </accordion>
+
+ </ng-form>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/kafkaBasicConfig.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/kafkaBasicConfig.html b/webapp/app/partials/cubeDesigner/kafkaBasicConfig.html
new file mode 100644
index 0000000..d9ca5b1
--- /dev/null
+++ b/webapp/app/partials/cubeDesigner/kafkaBasicConfig.html
@@ -0,0 +1,114 @@
+<!--
+* 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 ng-controller="kafkaConfigCtrl">
+ <ng-form name="forms.kafka_config_form" novalidate>
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Topic</b>
+ </label>
+ <div class="col-xs-12 col-sm-6" ng-class="{'has-error':forms.kafka_config_form.topic.$invalid && (forms.kafka_config_form.topic.$dirty||forms.kafka_config_form.topic.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.topic" type="text"
+ placeholder="Input kafkaConfig topic"
+ class="form-control"/>
+ <small class="help-block" ng-show="forms.kafka_config_form.topic.$error.required && (forms.kafka_config_form.topic.$dirty||forms.kafka_config_form.$sbumitted)">Kafka topic is required.</small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.topic}}</span>
+ </div>
+ </div>
+ </div>
+
+
+
+
+ <div ng-repeat="cluster in kafkaMeta.clusters | filter: state.measureFilter track by $index" class="box">
+ <div class="box-header">
+ <h3 class="box-title">Cluster-{{$index+1}}</h3>
+ <button type="button" ng-click="removeCluster(cluster)" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
+ </div>
+ <div class="box-body no-padding">
+ <table class="table table-condensed" ng-if="cluster.brokers.length||cluster.newBroker">
+ <thead>
+ <tr>
+ <th>ID</th>
+ <th>Host</th>
+ <th>Port</th>
+ <th ng-if="state.mode=='edit'">Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="broker in cluster.brokers| filter: state.measureFilter track by $index">
+ <td>{{broker.id}}</td>
+ <td>{{broker.host}}</td>
+ <td>{{broker.port}}</td>
+ <td ng-if="state.mode=='edit'">
+ <!--Edit Button -->
+ <button class="btn btn-xs btn-info" ng-click="addBroker(cluster,broker)">
+ <i class="fa fa-pencil"></i>
+ </button>
+
+ <button class="btn btn-xs btn-danger" ng-click="removeElement(cluster,broker)"><i class="fa fa-trash-o"></i>
+ </button>
+ </td>
+ </tr>
+ <tr ng-if="cluster.newBroker">
+ <td>
+ <div class="input-group">
+ <input class="form-control" type="text" ng-model="cluster.newBroker.id" name="broker_id" placeholder="Input broker ID"/>
+ </div>
+ </td>
+ <td>
+ <div class="input-group">
+ <input class="form-control" type="text" ng-model="cluster.newBroker.host" name="broker_host" placeholder="Input broker host">
+ </div>
+ </td>
+ <td>
+ <div class="input-group">
+ <input class="form-control" type="text" ng-model="cluster.newBroker.port" name="broker_port" placeholder="Input broker port">
+ </div>
+ </td>
+ <td>
+ <button class="btn btn-xs btn-danger" ng-click="removeNewBroker(cluster)"><i class="fa fa-trash-o"></i>
+ </button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div class="box-footer">
+ <div>
+ <button class="btn btn-sm btn-success" ng-click="addBroker(cluster)" ng-show="state.mode=='edit'&&!cluster.newBroker">
+ <i class="fa fa-plus"></i> Broker
+ </button>
+ <button class="btn btn-sm btn-info" ng-click="saveNewBroker(cluster)" ng-show="state.mode=='edit'&&cluster.newBroker">
+ <i class="fa fa-saved"></i> Save
+ </button>
+ <button class="btn btn-link" ng-click="clearNewBroker(cluster)" ng-show="state.mode=='edit'&&cluster.newBroker">Cancel</button>
+ </div>
+ </div>
+ </div>
+ <!--Add Measures Button-->
+ <div class="form-group">
+ <button class="btn btn-sm btn-info" ng-click="addCluster()" ng-show="state.mode=='edit'">
+ <i class="fa fa-plus"></i> Cluster
+ </button>
+ </div>
+
+
+ </ng-form>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/measures.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/measures.html b/webapp/app/partials/cubeDesigner/measures.html
index e4962dc..ece2b7d 100755
--- a/webapp/app/partials/cubeDesigner/measures.html
+++ b/webapp/app/partials/cubeDesigner/measures.html
@@ -17,186 +17,188 @@
-->
<!-- Measures Summary -->
-<ng-form name="forms.cube_measure_form">
- <div class="dataTables_wrapper form-inline no-footer" ng-if="cubeMetaFrame.measures.length > 0">
- <table class="table table-striped table-hover">
- <thead>
- <tr>
- <th>ID</th>
- <th>Name</th>
- <th>Expression</th>
- <th>Param Type</th>
- <th>Param Value</th>
- <th>Return Type</th>
- <th ng-if="state.mode=='edit'">Actions</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="measure in cubeMetaFrame.measures | filter: state.measureFilter track by $index">
- <td>
- <!--ID -->
- <b>{{measure.id = ($index + 1)}}</b>
- </td>
- <td>
- <!--Name -->
- <span tooltip="measure name..">{{measure.name}}</span>
- </td>
- <td>
- <!--Expression -->
- <span>{{measure.function.expression}}</span>
- </td>
- <td>
- <!--Param Type -->
- <span>{{measure.function.parameter.type}}</span>
- </td>
- <td>
- <!--Param Value -->
- <span>{{measure.function.parameter.value}}</span>
- </td>
- <td>
- <!--Return Type -->
- <span>{{measure.function.returntype}}</span>
- </td>
- <td ng-if="state.mode=='edit'">
- <!--Edit Button -->
- <button class="btn btn-xs btn-info" ng-click="addNewMeasure(measure)">
- <i class="fa fa-pencil"></i>
- </button>
- <!--Remove Button -->
- <button class="btn btn-xs btn-danger" ng-click="removeElement(cubeMetaFrame.measures, measure)">
- <i class="fa fa-trash-o"></i>
- </button>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
-</ng-form>
+<div ng-controller="CubeMeasuresCtrl">
+ <ng-form name="forms.cube_measure_form">
+ <div class="dataTables_wrapper form-inline no-footer" ng-if="cubeMetaFrame.measures.length > 0">
+ <table class="table table-striped table-hover">
+ <thead>
+ <tr>
+ <th>ID</th>
+ <th>Name</th>
+ <th>Expression</th>
+ <th>Param Type</th>
+ <th>Param Value</th>
+ <th>Return Type</th>
+ <th ng-if="state.mode=='edit'">Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="measure in cubeMetaFrame.measures | filter: state.measureFilter track by $index">
+ <td>
+ <!--ID -->
+ <b>{{measure.id = ($index + 1)}}</b>
+ </td>
+ <td>
+ <!--Name -->
+ <span tooltip="measure name..">{{measure.name}}</span>
+ </td>
+ <td>
+ <!--Expression -->
+ <span>{{measure.function.expression}}</span>
+ </td>
+ <td>
+ <!--Param Type -->
+ <span>{{measure.function.parameter.type}}</span>
+ </td>
+ <td>
+ <!--Param Value -->
+ <span>{{measure.function.parameter.value}}</span>
+ </td>
+ <td>
+ <!--Return Type -->
+ <span>{{measure.function.returntype}}</span>
+ </td>
+ <td ng-if="state.mode=='edit'">
+ <!--Edit Button -->
+ <button class="btn btn-xs btn-info" ng-click="addNewMeasure(measure)">
+ <i class="fa fa-pencil"></i>
+ </button>
+ <!--Remove Button -->
+ <button class="btn btn-xs btn-danger" ng-click="removeElement(cubeMetaFrame.measures, measure)">
+ <i class="fa fa-trash-o"></i>
+ </button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </ng-form>
-<!--Add Measures Button-->
-<div class="form-group">
- <button class="btn btn-sm btn-info" ng-click="addNewMeasure()" ng-show="state.mode=='edit' && !newMeasure">
- <i class="fa fa-plus"></i> Measure
- </button>
-</div>
+ <!--Add Measures Button-->
+ <div class="form-group">
+ <button class="btn btn-sm btn-info" ng-click="addNewMeasure()" ng-show="state.mode=='edit' && !newMeasure">
+ <i class="fa fa-plus"></i> Measure
+ </button>
+ </div>
-<!--Edit Measure-->
-<ng-form name="edit_mes_form">
-<div class="box box-solid" ng-if="newMeasure">
- <div class="box-header">
- <h4 class="box-title text-info">Edit Measure</h4>
- </div>
- <div class="box-body">
- <div class="row">
- <div class="col-xs-8">
- <!--Name-->
- <div class="form-group">
- <div class="row">
- <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Name</b></label>
- <div class="col-xs-12 col-sm-6">
- <input type="text" placeholder="Name.." class="form-control"
- tooltip="measure name.." tooltip-trigger="focus"
- ng-model="newMeasure.name" required />
- </div>
- </div>
- </div>
- <!--Expression-->
- <div class="form-group">
- <div class="row">
- <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Expression</b></label>
- <div class="col-xs-12 col-sm-6">
- <select class="form-control"
- ng-init="newMeasure.function.expression = (!!newMeasure.function.expression)?newMeasure.function.expression:cubeConfig.dftSelections.measureExpression" chosen ng-model="newMeasure.function.expression" required
- ng-change="measureReturnTypeUpdate();"
- ng-options="me as me for me in cubeConfig.measureExpressions">
- <option value=""></option>
- </select>
- </div>
- </div>
- </div>
- <!--Param Type-->
- <div class="form-group">
- <div class="row">
- <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Param Type</b></label>
- <div class="col-xs-12 col-sm-6">
- <select class="form-control" ng-if="newMeasure.function.expression != 'COUNT'"
- ng-init="newMeasure.function.parameter.type=(!!newMeasure.function.parameter.type)?newMeasure.function.parameter.type: 'column' "
- chosen ng-model="newMeasure.function.parameter.type" required
- ng-change="measureReturnTypeUpdate();"
- ng-options="mpt as mpt for mpt in cubeConfig.measureParamType">
- <option value=""></option>
- </select>
- <span class="font-color-default"
- ng-if="newMeasure.function.expression == 'COUNT'"
- ng-init="newMeasure.function.parameter.type= 'constant' "><b> constant</b>
- </span>
- </div>
- </div>
- </div>
- <!--Param Value-->
- <div class="form-group">
- <div class="row">
- <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Param Value</b></label>
- <div class="col-xs-12 col-sm-6">
- <span class="font-color-default"
- ng-if="newMeasure.function.parameter.type == 'constant'"
- ng-init="newMeasure.function.parameter.value = 1"><b> 1</b></span>
- <select class="form-control" chosen
- ng-if="newMeasure.function.parameter.type == 'column'"
- ng-model="newMeasure.function.parameter.value"
- ng-change="measureReturnTypeUpdate();"
- ng-options="columns.name as columns.name for columns in getMetricColumnsByTable(metaModel.model.fact_table)" >
- <option value="">-- Select a Fact Table Column --</option>
- </select>
- </div>
- </div>
- </div>
- <!--Return Type-->
- <div class="form-group">
- <div class="row">
- <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Return Type</b></label>
- <div class="col-xs-12 col-sm-6">
- <select class="form-control"
- ng-if="newMeasure.function.expression == 'COUNT_DISTINCT'"
- ng-init="newMeasure.function.returntype = (!!newMeasure.function.returntype)?newMeasure.function.returntype:cubeConfig.dftSelections.distinctDataType.value"
- chosen ng-model="newMeasure.function.returntype" required
- ng-options="ddt.value as ddt.name for ddt in cubeConfig.distinctDataTypes">
- <option value=""></option>
- </select>
- <span class="font-color-default"
- ng-if="newMeasure.function.expression != 'COUNT_DISTINCT'"
- ><b> {{newMeasure.function.returntype | uppercase}}</b>
- </span>
- </div>
- </div>
- </div>
- </div>
+ <!--Edit Measure-->
+ <ng-form name="edit_mes_form">
+ <div class="box box-solid" ng-if="newMeasure">
+ <div class="box-header">
+ <h4 class="box-title text-info">Edit Measure</h4>
+ </div>
+ <div class="box-body">
+ <div class="row">
+ <div class="col-xs-8">
+ <!--Name-->
+ <div class="form-group">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Name</b></label>
+ <div class="col-xs-12 col-sm-6">
+ <input type="text" placeholder="Name.." class="form-control"
+ tooltip="measure name.." tooltip-trigger="focus"
+ ng-model="newMeasure.name" required />
+ </div>
+ </div>
+ </div>
+ <!--Expression-->
+ <div class="form-group">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Expression</b></label>
+ <div class="col-xs-12 col-sm-6">
+ <select class="form-control"
+ ng-init="newMeasure.function.expression = (!!newMeasure.function.expression)?newMeasure.function.expression:cubeConfig.dftSelections.measureExpression" chosen ng-model="newMeasure.function.expression" required
+ ng-change="measureReturnTypeUpdate();"
+ ng-options="me as me for me in cubeConfig.measureExpressions">
+ <option value=""></option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <!--Param Type-->
+ <div class="form-group">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Param Type</b></label>
+ <div class="col-xs-12 col-sm-6">
+ <select class="form-control" ng-if="newMeasure.function.expression != 'COUNT'"
+ ng-init="newMeasure.function.parameter.type=(!!newMeasure.function.parameter.type)?newMeasure.function.parameter.type: 'column' "
+ chosen ng-model="newMeasure.function.parameter.type" required
+ ng-change="measureReturnTypeUpdate();"
+ ng-options="mpt as mpt for mpt in cubeConfig.measureParamType">
+ <option value=""></option>
+ </select>
+ <span class="font-color-default"
+ ng-if="newMeasure.function.expression == 'COUNT'"
+ ng-init="newMeasure.function.parameter.type= 'constant' "><b> constant</b>
+ </span>
+ </div>
+ </div>
+ </div>
+ <!--Param Value-->
+ <div class="form-group">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Param Value</b></label>
+ <div class="col-xs-12 col-sm-6">
+ <span class="font-color-default"
+ ng-if="newMeasure.function.parameter.type == 'constant'"
+ ng-init="newMeasure.function.parameter.value = 1"><b> 1</b></span>
+ <select class="form-control" chosen
+ ng-if="newMeasure.function.parameter.type == 'column'"
+ ng-model="newMeasure.function.parameter.value"
+ ng-change="measureReturnTypeUpdate();"
+ ng-options="columns.name as columns.name for columns in getMetricColumnsByTable(metaModel.model.fact_table)" >
+ <option value="">-- Select a Fact Table Column --</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <!--Return Type-->
+ <div class="form-group">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Return Type</b></label>
+ <div class="col-xs-12 col-sm-6">
+ <select class="form-control"
+ ng-if="newMeasure.function.expression == 'COUNT_DISTINCT'"
+ ng-init="newMeasure.function.returntype = (!!newMeasure.function.returntype)?newMeasure.function.returntype:cubeConfig.dftSelections.distinctDataType.value"
+ chosen ng-model="newMeasure.function.returntype" required
+ ng-options="ddt.value as ddt.name for ddt in cubeConfig.distinctDataTypes">
+ <option value=""></option>
+ </select>
+ <span class="font-color-default"
+ ng-if="newMeasure.function.expression != 'COUNT_DISTINCT'"
+ ><b> {{newMeasure.function.returntype | uppercase}}</b>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
- <!--Tips-->
- <div class="col-xs-4">
- <div class="box box-solid">
- <div class="box-header">
- <h4 class="box-title">Tips</h4>
- </div>
- <div class="box-body">
- <div class="row">
- <div class="col-xs-12">
- <ol class="text-info">
- <li>All cubes have to contain one measure for Count(1), suggest use "_Count_" as name (Has been generated automatically)</li>
- <li>Only accept single column in param value with "Column" type</li>
- <li>Distinct Count is approximate, please indicate Error Rate, higher accuracy degree accompanied with larger storage size and longer build time</li>
- </ol>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="box-footer">
- <button class="btn btn-sm btn-info" ng-disabled="edit_mes_form.$invalid"
- ng-click="saveNewMeasure()" ng-show="state.mode=='edit'">OK</button>
- <button class="btn btn-link" ng-click="clearNewMeasure()">Cancel</button>
- </div>
+ <!--Tips-->
+ <div class="col-xs-4">
+ <div class="box box-solid">
+ <div class="box-header">
+ <h4 class="box-title">Tips</h4>
+ </div>
+ <div class="box-body">
+ <div class="row">
+ <div class="col-xs-12">
+ <ol class="text-info">
+ <li>All cubes have to contain one measure for Count(1), suggest use "_Count_" as name (Has been generated automatically)</li>
+ <li>Only accept single column in param value with "Column" type</li>
+ <li>Distinct Count is approximate, please indicate Error Rate, higher accuracy degree accompanied with larger storage size and longer build time</li>
+ </ol>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="box-footer">
+ <button class="btn btn-sm btn-info" ng-disabled="edit_mes_form.$invalid"
+ ng-click="saveNewMeasure()" ng-show="state.mode=='edit'">OK</button>
+ <button class="btn btn-link" ng-click="clearNewMeasure()">Cancel</button>
+ </div>
+ </div>
+ </ng-form>
</div>
-</ng-form>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/streamingConfig.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/streamingConfig.html b/webapp/app/partials/cubeDesigner/streamingConfig.html
new file mode 100644
index 0000000..f8ab61d
--- /dev/null
+++ b/webapp/app/partials/cubeDesigner/streamingConfig.html
@@ -0,0 +1,282 @@
+<!--
+* 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 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">
+ <accordion>
+ <accordion-group is-open="state.isKfkSettingOpen" ng-init="state.isKfkSettingOpen=true">
+ <accordion-heading>
+ Kafka Setting
+ <i class="pull-right glyphicon"
+ ng-class="{'glyphicon-chevron-down': state.isKfkSettingOpen, 'glyphicon-chevron-right': !state.isKfkSettingOpen}"></i>
+ </accordion-heading>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Topic</b>
+ </label>
+ <div class="col-xs-12 col-sm-6" ng-class="{'has-error':forms.cube_streaming_form.topic.$invalid && (forms.cube_streaming_form.topic.$dirty||forms.cube_streaming_form.topic.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="topic" required ng-model="kafkaMeta.topic" type="text"
+ placeholder="Input kafkaConfig topic"
+ class="form-control"/>
+ <small class="help-block" ng-show="forms.cube_streaming_form.topic.$error.required && (forms.cube_streaming_form.topic.$dirty||forms.cube_streaming_form.$sbumitted)">Kafka topic is required.</small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.topic}}</span>
+ </div>
+ </div>
+ </div>
+
+ <div ng-repeat="cluster in kafkaMeta.clusters | filter: state.measureFilter track by $index" class="box">
+ <div class="box-header">
+ <h3 class="box-title">Cluster-{{$index+1}}</h3>
+ <button ng-if="state.mode=='edit'" type="button" ng-click="removeCluster(cluster)" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
+ </div>
+ <div class="box-body no-padding">
+ <table class="table table-condensed" ng-if="cluster.brokers.length||cluster.newBroker">
+ <thead>
+ <tr>
+ <th>ID</th>
+ <th>Host</th>
+ <th>Port</th>
+ <th ng-if="state.mode=='edit'">Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="broker in cluster.brokers| filter: state.measureFilter track by $index">
+ <td>{{broker.id}}</td>
+ <td>{{broker.host}}</td>
+ <td>{{broker.port}}</td>
+ <td ng-if="state.mode=='edit'">
+ <!--Edit Button -->
+ <button class="btn btn-xs btn-info" ng-click="addBroker(cluster,broker)">
+ <i class="fa fa-pencil"></i>
+ </button>
+
+ <button class="btn btn-xs btn-danger" ng-click="removeElement(cluster,broker)"><i class="fa fa-trash-o"></i>
+ </button>
+ </td>
+ </tr>
+ <tr ng-if="cluster.newBroker">
+ <td>
+ <div class="input-group">
+ <input class="form-control" type="text" ng-model="cluster.newBroker.id" name="broker_id" placeholder="Input broker ID"/>
+ </div>
+ </td>
+ <td>
+ <div class="input-group">
+ <input class="form-control" type="text" ng-model="cluster.newBroker.host" name="broker_host" placeholder="Input broker host">
+ </div>
+ </td>
+ <td>
+ <div class="input-group">
+ <input class="form-control" type="text" ng-model="cluster.newBroker.port" name="broker_port" placeholder="Input broker port">
+ </div>
+ </td>
+ <td>
+ <button class="btn btn-xs btn-danger" ng-click="removeNewBroker(cluster)"><i class="fa fa-trash-o"></i>
+ </button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div class="box-footer">
+ <div>
+ <button class="btn btn-sm btn-success" ng-click="addBroker(cluster)" ng-show="state.mode=='edit'&&!cluster.newBroker">
+ <i class="fa fa-plus"></i> Broker
+ </button>
+ <button class="btn btn-sm btn-info" ng-click="saveNewBroker(cluster)" ng-show="state.mode=='edit'&&cluster.newBroker">
+ <i class="fa fa-saved"></i> Save
+ </button>
+ <button class="btn btn-link" ng-click="clearNewBroker(cluster)" ng-show="state.mode=='edit'&&cluster.newBroker">Cancel</button>
+ </div>
+ </div>
+ </div>
+ <!--Add Measures Button-->
+ <div class="form-group">
+ <button class="btn btn-sm btn-info" ng-click="addCluster()" ng-show="state.mode=='edit'">
+ <i class="fa fa-plus"></i> Cluster
+ </button>
+ </div>
+
+ </accordion-group>
+ </accordion>
+
+ <hr/>
+ <!--Advanced setting-->
+ <accordion>
+ <accordion-group is-open="state.isStreamingAdOpen" ng-init="state.isStreamingAdOpen=true">
+ <accordion-heading>
+ Advanced Setting
+ <i class="pull-right glyphicon"
+ ng-class="{'glyphicon-chevron-down': state.isStreamingAdOpen, 'glyphicon-chevron-right': !state.isStreamingAdOpen}"></i>
+ </accordion-heading>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Timeout</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.cube_streaming_form.timeout.$invalid && (forms.cube_streaming_form.timeout.$dirty||forms.cube_streaming_form.timeout.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.timeout" type="text"
+ placeholder="Input kafkaConfig timeout"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.cube_streaming_form.timeout.$error.required && (forms.cube_streaming_form.timeout.$dirty||forms.cube_streaming_form.$sbumitted)">
+ Kafka timeout is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.timeout}}</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Max Read Count</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.cube_streaming_form.maxReadCount.$invalid && (forms.cube_streaming_form.maxReadCount.$dirty||forms.cube_streaming_form.maxReadCount.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.maxReadCount" type="text"
+ placeholder="Input kafkaConfig maxReadCount"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.cube_streaming_form.maxReadCount.$error.required && (forms.cube_streaming_form.maxReadCount.$dirty||forms.cube_streaming_form.$sbumitted)">
+ Kafka maxReadCount is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.maxReadCount}}</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Buffer Size</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.cube_streaming_form.bufferSize.$invalid && (forms.cube_streaming_form.bufferSize.$dirty||forms.cube_streaming_form.bufferSize.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.bufferSize" type="text"
+ placeholder="Input kafkaConfig bufferSize"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.cube_streaming_form.bufferSize.$error.required && (forms.cube_streaming_form.bufferSize.$dirty||forms.cube_streaming_form.$sbumitted)">
+ Kafka bufferSize is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.bufferSize}}</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Margin</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.cube_streaming_form.margin.$invalid && (forms.cube_streaming_form.margin.$dirty||forms.cube_streaming_form.margin.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.margin" type="text"
+ placeholder="Input kafkaConfig margin"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.cube_streaming_form.margin.$error.required && (forms.cube_streaming_form.margin.$dirty||forms.cube_streaming_form.$sbumitted)">
+ Kafka margin is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.margin}}</span>
+ </div>
+ </div>
+ </div>
+ </accordion-group>
+ </accordion>
+
+ <hr/>
+ <accordion>
+
+ <accordion-group is-open="state.isParserHeaderOpen">
+ <accordion-heading>
+ Parser Setting
+ <i class="pull-right glyphicon"
+ ng-class="{'glyphicon-chevron-down': state.isParserHeaderOpen, 'glyphicon-chevron-right': !state.isParserHeaderOpen}"></i>
+ </accordion-heading>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Parser Name</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.cube_streaming_form.parserName.$invalid && (forms.cube_streaming_form.parserName.$dirty||forms.cube_streaming_form.parserName.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.parserName" type="text"
+ placeholder="Input kafkaConfig parserName"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.cube_streaming_form.parserName.$error.required && (forms.cube_streaming_form.parserName.$dirty||forms.cube_streaming_form.$sbumitted)">
+ Kafka parserName is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.parserName}}</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+ <b>Parser Properties</b>
+ </label>
+
+ <div class="col-xs-12 col-sm-6"
+ ng-class="{'has-error':forms.cube_streaming_form.parserProperties.$invalid && (forms.cube_streaming_form.parserProperties.$dirty||forms.cube_streaming_form.parserProperties.$sbumitted)}">
+ <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.parserProperties" type="text"
+ placeholder="configA=1;configB=2"
+ class="form-control"/>
+ <small class="help-block"
+ ng-show="forms.cube_streaming_form.parserProperties.$error.required && (forms.cube_streaming_form.parserProperties.$dirty||forms.cube_streaming_form.$sbumitted)">
+ Parser Properties is required.
+ </small>
+ <span ng-if="state.mode=='view'">{{kafkaMeta.parserProperties}}</span>
+ </div>
+ </div>
+ </div>
+ </accordion-group>
+ </accordion>
+
+ </div>
+ </ng-form>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubes/cube_detail.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubes/cube_detail.html b/webapp/app/partials/cubes/cube_detail.html
index 48a22d7..49e2578 100755
--- a/webapp/app/partials/cubes/cube_detail.html
+++ b/webapp/app/partials/cubes/cube_detail.html
@@ -46,19 +46,17 @@
ng-if="userService.hasRole('ROLE_ADMIN')">
<a href="" ng-click="cube.visiblePage='hbase';getHbaseInfo(cube)">HBase</a>
</li>
-
</ul>
<div class="cube-detail" ng-if="!cube.visiblePage || cube.visiblePage=='metadata'">
<div ng-include="'partials/cubes/cube_schema.html'" ng-controller="CubeSchemaCtrl"
- ng-init="state={mode:'view', cubeName:cube.name}"></div>
+ ng-init="state={mode:'view', cubeName:cube.name};cubeState={isStreaming:(!!cube.streaming)?true:false}"></div>
</div>
<div ng-show="cube.visiblePage=='sql'" class="cube-detail">
<div ng-if="cube.sql">
<pre style="background-color: white;border: 0px">{{cube.sql}}</pre>
</div>
-
<div ng-if="!cube.sql">
<span calss="text-info">No SQL GENERATED.</span>
</div>
@@ -101,7 +99,7 @@
</div>
</div>
- <div class="cube-detail" ng-show="cube.visiblePage=='hbase'">
+ <div class="cube-detail" ng-show="cube.visiblePage=='hbase'">
<div style="margin: 15px;">
<div ng-repeat="table in cube.hbase">
<h5><b>HTable:</b> {{table.tableName}}</h5>
@@ -115,10 +113,12 @@
<div ng-if="cube.hbase">
<div class="hr hr8 hr-double hr-dotted"></div>
<h5><b>Total Size:</b> <span class="red">{{cube.totalSize | bytes:2}}</span></h5>
+ <h5><b>Total Number:</b> <span class="red">{{cube.hbase.length}}</span></h5>
</div>
<div ng-if="cube.hbase.length == 0">
<h5>No HBase Info.</h5>
</div>
</div>
</div>
-</div>
+ </div>
+
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubes/cubes.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubes/cubes.html b/webapp/app/partials/cubes/cubes.html
index 3c8c2e7..fdf3277 100644
--- a/webapp/app/partials/cubes/cubes.html
+++ b/webapp/app/partials/cubes/cubes.html
@@ -45,6 +45,7 @@
</th>
<th>Actions</th>
<th ng-if="userService.hasRole('ROLE_ADMIN')">Admins</th>
+ <th></th>
</tr>
</thead>
<!--Body-->
@@ -83,6 +84,7 @@
<a ng-click="dropCube(cube)" tooltip="Drop the cube, related jobs and data permanently.">Drop</a></li>
<li ng-if="cube.status=='DISABLED' && (userService.hasRole('ROLE_ADMIN') || hasPermission(cube, permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask))">
<a ng-click="cubeEdit(cube);">Edit</a></li>
+ <li ng-if="cube.streaming && cube.status=='DISABLED' && (userService.hasRole('ROLE_ADMIN') || hasPermission(cube, permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask))">
<li><a ng-click="startJobSubmit(cube);">Build</a></li>
<li><a ng-click="startRefresh(cube)">Refresh</a></li>
<li><a ng-click="startMerge(cube)">Merge</a></li>
@@ -106,6 +108,11 @@
</ul>
</div>
</td>
+ <td ng-if="cube.streaming">
+ <label class="badge label-info" style="cursor:pointer;">STREAMING</label>
+ </td>
+ <td ng-if="!cube.streaming">
+ </td>
</tr>
<tr ng-show="cube.showDetail">
<td colspan="9" style="padding: 10px 30px 10px 30px;">
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/modelDesigner/conditions_settings.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/conditions_settings.html b/webapp/app/partials/modelDesigner/conditions_settings.html
index 7a0d463..6e836ee 100644
--- a/webapp/app/partials/modelDesigner/conditions_settings.html
+++ b/webapp/app/partials/modelDesigner/conditions_settings.html
@@ -132,7 +132,11 @@
<div class="col-xs-12">
<ol class="text-info">
<li>Partition date column not required,leave as default if cube always need full build</li>
- <li>Partition date column will select 'date' or 'string' type column from fact table</li>
+ <li>Partition date column will select 'date' type column from fact table</li>
+ <li>Where clause to filter data from source</li>
+ <li>Do not include date column which will be used for incremental refresh</li>
+ <li>Do not include "Where"</li>
+ <li>Please verify SQL when finish cube design from SQL view of cube</li>
</ol>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/modelDesigner/data_model.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/data_model.html b/webapp/app/partials/modelDesigner/data_model.html
index e100287..e1cae39 100644
--- a/webapp/app/partials/modelDesigner/data_model.html
+++ b/webapp/app/partials/modelDesigner/data_model.html
@@ -20,7 +20,7 @@
<ng-form name="forms.data_model_form">
<!-- Fact Table Name -->
- <div class="form-group required">
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
<div class="row">
<label class="col-xs-12 col-sm-2 control-label concube.detailtrol-label no-padding-right font-color-default">
<b>Fact Table</b>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/modelDesigner/model_info.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/model_info.html b/webapp/app/partials/modelDesigner/model_info.html
index aed4325..a290bfb 100644
--- a/webapp/app/partials/modelDesigner/model_info.html
+++ b/webapp/app/partials/modelDesigner/model_info.html
@@ -22,7 +22,7 @@
<ng-form name="forms.model_info_form" novalidate>
<!--Model Name-->
- <div class="form-group required">
+ <div class="form-group" ng-class="{'required':state.mode=='edit'}">
<div class="row">
<label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default">
<b>Model Name</b>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/models/models_tree.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/models/models_tree.html b/webapp/app/partials/models/models_tree.html
index 722d65f..9d86c50 100644
--- a/webapp/app/partials/models/models_tree.html
+++ b/webapp/app/partials/models/models_tree.html
@@ -44,10 +44,6 @@
<a href="models/add" ng-if="userService.hasRole('ROLE_MODELER')"><i class="fa fa-star"></i> New Model</a>
</li>
- <li ng-if="userService.hasRole('ROLE_ADMIN')">
- <a href="streaming/add" ng-if="userService.hasRole('ROLE_MODELER')"><i class="fa fa-area-chart"></i>New Streaming</a>
- </li>
-
</ul>
</div>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/streaming/streaming_edit.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/streaming/streaming_edit.html b/webapp/app/partials/streaming/streaming_edit.html
new file mode 100644
index 0000000..d4b4926
--- /dev/null
+++ b/webapp/app/partials/streaming/streaming_edit.html
@@ -0,0 +1,34 @@
+<!--
+* 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="row">
+ <div class="col-xs-3">
+ <div ng-include src="'partials/models/models_tree.html'" ng-controller="ModelsCtrl"></div>
+ <!--<div ng-include src="'partials/tables/source_table_tree.html'" ng-controller="SourceMetaCtrl"></div>-->
+ </div>
+ <div class="col-xs-9">
+ <form role="form" name="cube_form" novalidate>
+ <!-- This margin in order to align with table tree in left part -->
+ <div style="margin-top: 20px;" ng-controller="CubeEditCtrl">
+ <div ng-include="'partials/streaming/streaming_schema.html'" ng-controller="StreamingSchemaCtrl">
+ </div>
+ </div>
+ </form>
+ </div>
+</div>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/streaming/streaming_schema.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/streaming/streaming_schema.html b/webapp/app/partials/streaming/streaming_schema.html
new file mode 100644
index 0000000..a45904c
--- /dev/null
+++ b/webapp/app/partials/streaming/streaming_schema.html
@@ -0,0 +1,63 @@
+<!--
+* 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.
+-->
+
+<!--hide when view model and no model selected-->
+<div class="box box-primary model-design box-2px" ng-init="model">
+ <div class="box-header widget-header-blue widget-header-flat">
+ <h4 class="box-title text-info">Streaming Designer</h4>
+ </div>
+ <div class="box-body">
+ <div>
+ <ul class="wizard-steps">
+ <li ng-repeat="step in wizardSteps"
+ class="{{step==curStep?'active':''}} {{step.isComplete?'complete':''}}">
+ <span style="cursor:pointer;" ng-click="checkForm()?goToStep($index):''" class="step">{{step.step = ($index + 1)}}</span>
+ <span class="title">{{step.title}}</span>
+ </li>
+ </ul>
+ </div>
+ <hr/>
+ <div class="step-content pos-rel" id="step-container">
+ <div ng-include src="curStep.src"></div>
+ </div>
+ <hr/>
+ <div class="wizard-actions">
+ <div class="row">
+ <div class="col-xs-8" style="display:block;">
+ <div>
+ </div>
+ </div>
+ <div class="col-xs-4 pull-right">
+ <button class="btn btn-prev" ng-click="preView()" ng-show="curStep.title!='Streaming Config'">
+ <i class="ace-icon fa fa-arrow-left"></i>
+ Prev
+ </button>
+ <button id="nextButton" class="btn btn-success btn-next" ng-disabled="forms[curStep.form].$invalid" ng-click="checkForm()?nextView():''"
+ ng-show="curStep.title!='Advanced Settings'">
+ Next
+ <i class="ace-icon fa fa-arrow-right icon-on-right"></i>
+ </button>
+ <button class="btn btn-primary" ng-click="checkForm()?saveStreaming():''"
+ ng-if="curStep.title=='Advanced Settings' && state.mode=='edit'">
+ Save
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/tables/source_table_tree.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/tables/source_table_tree.html b/webapp/app/partials/tables/source_table_tree.html
index ff95d10..767eb43 100755
--- a/webapp/app/partials/tables/source_table_tree.html
+++ b/webapp/app/partials/tables/source_table_tree.html
@@ -45,3 +45,5 @@
<div no-result ng-if="tableModel.selectedSrcDb.length == 0"></div>
</div>
</div>
+
+<div ng-include="'partials/tables/table_load.html'"></div>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/tables/table_detail.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/tables/table_detail.html b/webapp/app/partials/tables/table_detail.html
index e692269..b232375 100644
--- a/webapp/app/partials/tables/table_detail.html
+++ b/webapp/app/partials/tables/table_detail.html
@@ -199,117 +199,4 @@
</div>
</div>
-
- <script type="text/ng-template" id="addHiveTable.html">
- <div class="modal-header">
- <h4>Load Hive Table Metadata</h4>
- </div>
- <div class="modal-body">
- <span><strong>Project: </strong>{{ $parent.projectName!=null?$parent.projectName:'NULL'}}</span>
- <label for="tables"> Table Names:(Seperate with comma)</label>
- <textarea ng-model="$parent.tableNames" class="form-control" id="tables"
- placeholder="table1,table2 By default,system will choose 'Default' as database,you can specify database like this 'database.table'"></textarea>
- </div>
- <div class="modal-footer">
- <button class="btn btn-primary" ng-click="add()">Sync</button>
- <button class="btn btn-primary" ng-click="cancel()">Cancel</button>
- </div>
- </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: 480px;">
- <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>
- </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 one 'timestamp' type column for streaming table.</li>
- <li>Uncheck the 'timestamp' type column which will not be used.</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>Check As Column</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: 200px !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">AUTO APPEND</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>
- </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>
</div>
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/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
new file mode 100644
index 0000000..99c993d
--- /dev/null
+++ b/webapp/app/partials/tables/table_load.html
@@ -0,0 +1,130 @@
+<!--
+* 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.
+-->
+
+ <script type="text/ng-template" id="addHiveTable.html">
+ <div class="modal-header">
+ <h4>Load Hive Table Metadata</h4>
+ </div>
+ <div class="modal-body">
+ <span><strong>Project: </strong>{{ $parent.projectName!=null?$parent.projectName:'NULL'}}</span>
+ <label for="tables"> Table Names:(Seperate with comma)</label>
+ <textarea ng-model="$parent.tableNames" class="form-control" id="tables"
+ placeholder="table1,table2 By default,system will choose 'Default' as database,you can specify database like this 'database.table'"></textarea>
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-primary" ng-click="add()">Sync</button>
+ <button class="btn btn-primary" ng-click="cancel()">Cancel</button>
+ </div>
+ </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>
+ </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 one 'timestamp' type column for streaming table.</li>
+ <li>Uncheck the 'timestamp' type column which will not be used.</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>Check As Column</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: 200px !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">AUTO APPEND</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>
+ </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>
\ No newline at end of file