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 2016/04/14 15:24:43 UTC
kylin git commit: KYLIN-1441 UI add partition time column,
base on patch from @Dipesh
Repository: kylin
Updated Branches:
refs/heads/master 45759972a -> e564d45c7
KYLIN-1441 UI add partition time column, base on patch from @Dipesh
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/e564d45c
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/e564d45c
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/e564d45c
Branch: refs/heads/master
Commit: e564d45c7818ef239f507596d2e0bb84db25498a
Parents: 4575997
Author: Jason <ji...@163.com>
Authored: Thu Apr 14 21:24:25 2016 +0800
Committer: Jason <ji...@163.com>
Committed: Thu Apr 14 21:24:25 2016 +0800
----------------------------------------------------------------------
pom.xml | 1 +
webapp/app/index.html | 3 +
webapp/app/js/app.js | 2 +-
webapp/app/js/controllers/modelEdit.js | 7 +
webapp/app/js/directives/datetimepicker.js | 418 +++++++++++++++++++
webapp/app/js/directives/directives.js | 40 +-
webapp/app/js/model/cubeConfig.js | 5 +
webapp/app/js/model/metaModel.js | 8 +-
.../partials/cubeDesigner/refresh_settings.html | 16 +-
webapp/app/partials/jobs/job_submit.html | 24 +-
.../modelDesigner/conditions_settings.html | 39 ++
webapp/bower.json | 3 +-
webapp/grunt.json | 1 +
13 files changed, 553 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 80e9be0..c223b12 100644
--- a/pom.xml
+++ b/pom.xml
@@ -784,6 +784,7 @@
<exclude>webapp/app/css/AdminLTE.css</exclude>
<exclude>webapp/app/js/directives/kylin_abn_tree_directive.js</exclude>
<exclude>webapp/app/js/directives/angular-tree-control.js</exclude>
+ <exclude>webapp/app/js/directives/datetimepicker.js</exclude>
<!--configuration file -->
<exclude>webapp/app/routes.json</exclude>
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/webapp/app/index.html
----------------------------------------------------------------------
diff --git a/webapp/app/index.html b/webapp/app/index.html
index b4eb9d7..82cef34 100644
--- a/webapp/app/index.html
+++ b/webapp/app/index.html
@@ -46,6 +46,7 @@
<link rel="stylesheet" type="text/css" href="components/angular-bootstrap-nav-tree/dist/abn_tree.css">
<link rel="stylesheet" type="text/css" href="components/angular-toggle-switch/angular-toggle-switch.css">
<link rel="stylesheet" type="text/css" href="components/angular-ui-select/dist/select.css">
+ <link rel="stylesheet" type="text/css" href="components/angular-bootstrap-datetimepicker/src/css/datetimepicker.css">
<link rel="stylesheet/less" href="less/build.less">
<!-- endref -->
@@ -114,6 +115,8 @@
<script src="js/directives/directives.js"></script>
<script src="js/directives/kylin_abn_tree_directive.js"></script>
<script src="js/directives/angular-tree-control.js"></script>
+<script src="js/directives/datetimepicker.js"></script>
+
<script src="js/factories/graph.js"></script>
<script src="js/services/cache.js"></script>
<script src="js/services/message.js"></script>
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/webapp/app/js/app.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/app.js b/webapp/app/js/app.js
index 817d24d..b681aca 100644
--- a/webapp/app/js/app.js
+++ b/webapp/app/js/app.js
@@ -17,4 +17,4 @@
*/
//Kylin Application Module
-KylinApp = angular.module('kylin', ['ngRoute', 'ngResource', 'ngGrid', 'ui.bootstrap', 'ui.ace', 'base64', 'angularLocalStorage', 'localytics.directives', 'treeControl', 'nvd3ChartDirectives','ngLoadingRequest','oitozero.ngSweetAlert','ngCookies','angular-underscore', 'ngAnimate', 'ui.sortable','angularBootstrapNavTree','toggle-switch','ngSanitize','ui.select']);
+KylinApp = angular.module('kylin', ['ngRoute', 'ngResource', 'ngGrid', 'ui.bootstrap', 'ui.ace', 'base64', 'angularLocalStorage', 'localytics.directives', 'treeControl', 'nvd3ChartDirectives','ngLoadingRequest','oitozero.ngSweetAlert','ngCookies','angular-underscore', 'ngAnimate', 'ui.sortable','angularBootstrapNavTree','toggle-switch','ngSanitize','ui.select','ui.bootstrap.datetimepicker']);
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/webapp/app/js/controllers/modelEdit.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/modelEdit.js b/webapp/app/js/controllers/modelEdit.js
index 2de251e..903b584 100644
--- a/webapp/app/js/controllers/modelEdit.js
+++ b/webapp/app/js/controllers/modelEdit.js
@@ -40,6 +40,13 @@ KylinApp.controller('ModelEditCtrl', function ($scope, $q, $routeParams, $locati
return columns;
};
+ $scope.getPartitonTimeColumns = function(tableName){
+ var columns = _.filter($scope.getColumnsByTable(tableName),function(column){
+ return column.datatype==="time"||column.datatype==="timestamp"||column.datatype==="string"||column.datatype.startsWith("varchar");
+ });
+ return columns;
+ };
+
$scope.getColumnsByTable = function (tableName) {
var temp = [];
angular.forEach(TableModel.selectProjectTables, function (table) {
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/webapp/app/js/directives/datetimepicker.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/directives/datetimepicker.js b/webapp/app/js/directives/datetimepicker.js
new file mode 100644
index 0000000..4541836
--- /dev/null
+++ b/webapp/app/js/directives/datetimepicker.js
@@ -0,0 +1,418 @@
+/*globals define, jQuery, module, require */
+/*jslint vars:true */
+
+/**
+ * @license angular-bootstrap-datetimepicker version: 0.3.15
+ * Copyright 2015 Knight Rider Consulting, Inc. http://www.knightrider.com
+ * License: MIT
+ */
+
+/**
+ *
+ * @author Dale "Ducky" Lotts
+ * @since 2013-Jul-8
+ * @Modified Jason,Zhong
+ */
+
+(function (factory) {
+ 'use strict';
+ /* istanbul ignore if */
+ if (typeof define === 'function' && /* istanbul ignore next */ define.amd) {
+ define(['angular', 'moment'], factory); // AMD
+ /* istanbul ignore next */
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('angular'), require('moment')); // CommonJS
+ } else {
+ factory(window.angular, window.moment); // Browser global
+ }
+}(function (angular, moment) {
+ 'use strict';
+ angular.module('ui.bootstrap.datetimepicker', [])
+ .constant('dateTimePickerConfig', {
+ dropdownSelector: null,
+ minuteStep: 5,
+ minView: 'minute',
+ startView: 'day'
+ })
+ .directive('datetimepicker', ['$log', 'dateTimePickerConfig', function datetimepickerDirective($log, defaultConfig) {
+
+ function DateObject() {
+
+ var tempDate = new Date();
+ var localOffset = tempDate.getTimezoneOffset() * 60000;
+ this.utcDateValue = tempDate.getTime();
+ this.selectable = true;
+
+ this.localDateValue = function () {
+ return this.utcDateValue + localOffset;
+ };
+
+ var validProperties = ['utcDateValue', 'localDateValue', 'display', 'active', 'selectable', 'past', 'future'];
+
+ for (var prop in arguments[0]) {
+ /* istanbul ignore else */
+ //noinspection JSUnfilteredForInLoop
+ if (validProperties.indexOf(prop) >= 0) {
+ //noinspection JSUnfilteredForInLoop
+ this[prop] = arguments[0][prop];
+ }
+ }
+ }
+
+ var validateConfiguration = function validateConfiguration(configuration) {
+ var validOptions = ['startView', 'minView', 'minuteStep', 'dropdownSelector'];
+
+ for (var prop in configuration) {
+ //noinspection JSUnfilteredForInLoop
+ if (validOptions.indexOf(prop) < 0) {
+ throw ('invalid option: ' + prop);
+ }
+ }
+
+ // Order of the elements in the validViews array is significant.
+ var validViews = ['minute', 'hour', 'day', 'month', 'year'];
+
+ if (validViews.indexOf(configuration.startView) < 0) {
+ throw ('invalid startView value: ' + configuration.startView);
+ }
+
+ if (validViews.indexOf(configuration.minView) < 0) {
+ throw ('invalid minView value: ' + configuration.minView);
+ }
+
+ if (validViews.indexOf(configuration.minView) > validViews.indexOf(configuration.startView)) {
+ throw ('startView must be greater than minView');
+ }
+
+ if (!angular.isNumber(configuration.minuteStep)) {
+ throw ('minuteStep must be numeric');
+ }
+ if (configuration.minuteStep <= 0 || configuration.minuteStep >= 60) {
+ throw ('minuteStep must be greater than zero and less than 60');
+ }
+ if (configuration.dropdownSelector !== null && !angular.isString(configuration.dropdownSelector)) {
+ throw ('dropdownSelector must be a string');
+ }
+
+ /* istanbul ignore next */
+ if (configuration.dropdownSelector !== null && ((typeof jQuery === 'undefined') || (typeof jQuery().dropdown !== 'function'))) {
+ $log.error('Please DO NOT specify the dropdownSelector option unless you are using jQuery AND Bootstrap.js. ' +
+ 'Please include jQuery AND Bootstrap.js, or write code to close the dropdown in the on-set-time callback. \n\n' +
+ 'The dropdownSelector configuration option is being removed because it will not function properly.');
+ delete configuration.dropdownSelector;
+ }
+ };
+
+ return {
+ restrict: 'E',
+ require: 'ngModel',
+ template: '<div class="datetimepicker table-responsive">' +
+ '<table class="table table-condensed {{ data.currentView }}-view">' +
+ ' <thead>' +
+ ' <tr>' +
+ ' <th class="left" data-ng-click="changeView(data.currentView, data.leftDate, $event)" data-ng-show="data.leftDate.selectable"><i class="glyphicon glyphicon-arrow-left"/></th>' +
+ ' <th class="switch" colspan="5" data-ng-show="data.previousViewDate.selectable" data-ng-click="changeView(data.previousView, data.previousViewDate, $event)">{{ data.previousViewDate.display }}</th>' +
+ ' <th class="right" data-ng-click="changeView(data.currentView, data.rightDate, $event)" data-ng-show="data.rightDate.selectable"><i class="glyphicon glyphicon-arrow-right"/></th>' +
+ ' </tr>' +
+ ' <tr>' +
+ ' <th class="dow" data-ng-repeat="day in data.dayNames" >{{ day }}</th>' +
+ ' </tr>' +
+ ' </thead>' +
+ ' <tbody>' +
+ ' <tr data-ng-if="data.currentView !== \'day\'" >' +
+ ' <td colspan="7" >' +
+ ' <span class="{{ data.currentView }}" ' +
+ ' data-ng-repeat="dateObject in data.dates" ' +
+ ' data-ng-class="{active: dateObject.active, past: dateObject.past, future: dateObject.future, disabled: !dateObject.selectable}" ' +
+ ' data-ng-click="changeView(data.nextView, dateObject, $event)">{{ dateObject.display }}</span> ' +
+ ' </td>' +
+ ' </tr>' +
+ ' <tr data-ng-if="data.currentView === \'day\'" data-ng-repeat="week in data.weeks">' +
+ ' <td data-ng-repeat="dateObject in week.dates" ' +
+ ' data-ng-click="changeView(data.nextView, dateObject, $event)"' +
+ ' class="day" ' +
+ ' data-ng-class="{active: dateObject.active, past: dateObject.past, future: dateObject.future, disabled: !dateObject.selectable}" >{{ dateObject.display }}</td>' +
+ ' </tr>' +
+ ' </tbody>' +
+ '</table></div>',
+ scope: {
+ onSetTime: '&',
+ beforeRender: '&'
+ },
+ replace: true,
+ link: function link(scope, element, attrs, ngModelController) {
+
+ var directiveConfig = {};
+
+ if (attrs.datetimepickerConfig) {
+ directiveConfig = scope.$parent.$eval(attrs.datetimepickerConfig);
+ }
+
+ var configuration = {};
+
+ angular.extend(configuration, defaultConfig, directiveConfig);
+
+ validateConfiguration(configuration);
+
+ var startOfDecade = function startOfDecade(unixDate) {
+ var startYear = (parseInt(moment.utc(unixDate).year() / 10, 10) * 10);
+ return moment.utc(unixDate).year(startYear).startOf('year');
+ };
+
+ var dataFactory = {
+ year: function year(unixDate) {
+ var selectedDate = moment.utc(unixDate).startOf('year');
+ // View starts one year before the decade starts and ends one year after the decade ends
+ // i.e. passing in a date of 1/1/2013 will give a range of 2009 to 2020
+ // Truncate the last digit from the current year and subtract 1 to get the start of the decade
+ var startDecade = (parseInt(selectedDate.year() / 10, 10) * 10);
+ var startDate = moment.utc(startOfDecade(unixDate)).subtract(1, 'year').startOf('year');
+
+ var activeYear = ngModelController.$modelValue ? moment(ngModelController.$modelValue).year() : 0;
+
+ var result = {
+ 'currentView': 'year',
+ 'nextView': configuration.minView === 'year' ? 'setTime' : 'month',
+ 'previousViewDate': new DateObject({
+ utcDateValue: null,
+ display: startDecade + '-' + (startDecade + 9)
+ }),
+ 'leftDate': new DateObject({utcDateValue: moment.utc(startDate).subtract(9, 'year').valueOf()}),
+ 'rightDate': new DateObject({utcDateValue: moment.utc(startDate).add(11, 'year').valueOf()}),
+ 'dates': []
+ };
+
+ for (var i = 0; i < 12; i += 1) {
+ var yearMoment = moment.utc(startDate).add(i, 'years');
+ var dateValue = {
+ 'utcDateValue': yearMoment.valueOf(),
+ 'display': yearMoment.format('YYYY'),
+ 'past': yearMoment.year() < startDecade,
+ 'future': yearMoment.year() > startDecade + 9,
+ 'active': yearMoment.year() === activeYear
+ };
+
+ result.dates.push(new DateObject(dateValue));
+ }
+
+ return result;
+ },
+
+ month: function month(unixDate) {
+
+ var startDate = moment.utc(unixDate).startOf('year');
+ var previousViewDate = startOfDecade(unixDate);
+ var activeDate = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MMM') : 0;
+
+ var result = {
+ 'previousView': 'year',
+ 'currentView': 'month',
+ 'nextView': configuration.minView === 'month' ? 'setTime' : 'day',
+ 'previousViewDate': new DateObject({
+ utcDateValue: previousViewDate.valueOf(),
+ display: startDate.format('YYYY')
+ }),
+ 'leftDate': new DateObject({utcDateValue: moment.utc(startDate).subtract(1, 'year').valueOf()}),
+ 'rightDate': new DateObject({utcDateValue: moment.utc(startDate).add(1, 'year').valueOf()}),
+ 'dates': []
+ };
+
+ for (var i = 0; i < 12; i += 1) {
+ var monthMoment = moment.utc(startDate).add(i, 'months');
+ var dateValue = {
+ 'utcDateValue': monthMoment.valueOf(),
+ 'display': monthMoment.format('MMM'),
+ 'active': monthMoment.format('YYYY-MMM') === activeDate
+ };
+
+ result.dates.push(new DateObject(dateValue));
+ }
+
+ return result;
+ },
+
+ day: function day(unixDate) {
+
+ var selectedDate = moment.utc(unixDate);
+ var startOfMonth = moment.utc(selectedDate).startOf('month');
+ var previousViewDate = moment.utc(selectedDate).startOf('year');
+ var endOfMonth = moment.utc(selectedDate).endOf('month');
+
+ var startDate = moment.utc(startOfMonth).subtract(Math.abs(startOfMonth.weekday()), 'days');
+
+ var activeDate = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MMM-DD') : '';
+
+ var result = {
+ 'previousView': 'month',
+ 'currentView': 'day',
+ 'nextView': configuration.minView === 'day' ? 'setTime' : 'hour',
+ 'previousViewDate': new DateObject({
+ utcDateValue: previousViewDate.valueOf(),
+ display: startOfMonth.format('YYYY-MMM')
+ }),
+ 'leftDate': new DateObject({utcDateValue: moment.utc(startOfMonth).subtract(1, 'months').valueOf()}),
+ 'rightDate': new DateObject({utcDateValue: moment.utc(startOfMonth).add(1, 'months').valueOf()}),
+ 'dayNames': [],
+ 'weeks': []
+ };
+
+
+ for (var dayNumber = 0; dayNumber < 7; dayNumber += 1) {
+ result.dayNames.push(moment.utc().weekday(dayNumber).format('dd'));
+ }
+
+ for (var i = 0; i < 6; i += 1) {
+ var week = {dates: []};
+ for (var j = 0; j < 7; j += 1) {
+ var monthMoment = moment.utc(startDate).add((i * 7) + j, 'days');
+ var dateValue = {
+ 'utcDateValue': monthMoment.valueOf(),
+ 'display': monthMoment.format('D'),
+ 'active': monthMoment.format('YYYY-MMM-DD') === activeDate,
+ 'past': monthMoment.isBefore(startOfMonth),
+ 'future': monthMoment.isAfter(endOfMonth)
+ };
+ week.dates.push(new DateObject(dateValue));
+ }
+ result.weeks.push(week);
+ }
+
+ return result;
+ },
+
+ hour: function hour(unixDate) {
+ var selectedDate = moment.utc(unixDate).startOf('day');
+ var previousViewDate = moment.utc(selectedDate).startOf('month');
+
+ var activeFormat = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MM-DD H') : '';
+
+ var result = {
+ 'previousView': 'day',
+ 'currentView': 'hour',
+ 'nextView': configuration.minView === 'hour' ? 'setTime' : 'minute',
+ 'previousViewDate': new DateObject({
+ utcDateValue: previousViewDate.valueOf(),
+ display: selectedDate.format('ll')
+ }),
+ 'leftDate': new DateObject({utcDateValue: moment.utc(selectedDate).subtract(1, 'days').valueOf()}),
+ 'rightDate': new DateObject({utcDateValue: moment.utc(selectedDate).add(1, 'days').valueOf()}),
+ 'dates': []
+ };
+
+ for (var i = 0; i < 24; i += 1) {
+ var hourMoment = moment.utc(selectedDate).add(i, 'hours');
+ var dateValue = {
+ 'utcDateValue': hourMoment.valueOf(),
+ 'display': hourMoment.format('LT'),
+ 'active': hourMoment.format('YYYY-MM-DD H') === activeFormat
+ };
+
+ result.dates.push(new DateObject(dateValue));
+ }
+
+ return result;
+ },
+
+ minute: function minute(unixDate) {
+ var selectedDate = moment.utc(unixDate).startOf('hour');
+ var previousViewDate = moment.utc(selectedDate).startOf('day');
+ var activeFormat = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MM-DD H:mm') : '';
+
+ var result = {
+ 'previousView': 'hour',
+ 'currentView': 'minute',
+ 'nextView': 'setTime',
+ 'previousViewDate': new DateObject({
+ utcDateValue: previousViewDate.valueOf(),
+ display: selectedDate.format('lll')
+ }),
+ 'leftDate': new DateObject({utcDateValue: moment.utc(selectedDate).subtract(1, 'hours').valueOf()}),
+ 'rightDate': new DateObject({utcDateValue: moment.utc(selectedDate).add(1, 'hours').valueOf()}),
+ 'dates': []
+ };
+
+ var limit = 60 / configuration.minuteStep;
+
+ for (var i = 0; i < limit; i += 1) {
+ var hourMoment = moment.utc(selectedDate).add(i * configuration.minuteStep, 'minute');
+ var dateValue = {
+ 'utcDateValue': hourMoment.valueOf(),
+ 'display': hourMoment.format('LT'),
+ 'active': hourMoment.format('YYYY-MM-DD H:mm') === activeFormat
+ };
+
+ result.dates.push(new DateObject(dateValue));
+ }
+
+ return result;
+ },
+
+ setTime: function setTime(unixDate) {
+ var tempDate = new Date(unixDate);
+ var newDate = new Date(tempDate.getTime() + (tempDate.getTimezoneOffset() * 60000));
+
+ var oldDate = ngModelController.$modelValue;
+ ngModelController.$setViewValue(unixDate);
+
+ if (configuration.dropdownSelector) {
+ jQuery(configuration.dropdownSelector).dropdown('toggle');
+ }
+
+ scope.onSetTime({newDate: newDate, oldDate: oldDate});
+
+ return dataFactory[configuration.startView](unixDate);
+ }
+ };
+
+ var getUTCTime = function getUTCTime(modelValue) {
+ //var tempDate = (modelValue ? moment(modelValue).toDate() : new Date());
+ //return tempDate.getTime() - (tempDate.getTimezoneOffset() * 60000);
+ var date = new Date();
+ if(!modelValue){
+ var tmp = new Date();
+ date = new Date(tmp.getFullYear(),tmp.getMonth()+1,tmp.getDate());
+ }else{
+ date = new Date(modelValue);
+ }
+ return date.getTime() - (date.getTimezoneOffset() * 60000);
+ };
+
+ scope.changeView = function changeView(viewName, dateObject, event) {
+ if (event) {
+ event.stopPropagation();
+ event.preventDefault();
+ }
+
+ if (viewName && (dateObject.utcDateValue > -Infinity) && dateObject.selectable && dataFactory[viewName]) {
+ var result = dataFactory[viewName](dateObject.utcDateValue);
+
+ var weekDates = [];
+ if (result.weeks) {
+ for (var i = 0; i < result.weeks.length; i += 1) {
+ var week = result.weeks[i];
+ for (var j = 0; j < week.dates.length; j += 1) {
+ var weekDate = week.dates[j];
+ weekDates.push(weekDate);
+ }
+ }
+ }
+
+ scope.beforeRender({
+ $view: result.currentView,
+ $dates: result.dates || weekDates,
+ $leftDate: result.leftDate,
+ $upDate: result.previousViewDate,
+ $rightDate: result.rightDate
+ });
+
+ scope.data = result;
+ }
+ };
+
+ ngModelController.$render = function $render() {
+ scope.changeView(configuration.startView, new DateObject({utcDateValue: getUTCTime(ngModelController.$viewValue)}));
+ };
+ }
+ };
+ }]);
+}));
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/webapp/app/js/directives/directives.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/directives/directives.js b/webapp/app/js/directives/directives.js
index 2deb0aa..a3b7bf2 100644
--- a/webapp/app/js/directives/directives.js
+++ b/webapp/app/js/directives/directives.js
@@ -248,7 +248,45 @@ KylinApp.directive('kylinPagination', function ($parse, $q) {
});
}
};
- }).directive("parametertree", function($compile) {
+ }).directive('dateTimepickerTimezone', function () {
+ // this directive workaround to convert GMT0 timestamp to GMT date for datepicker
+ return {
+ restrict: 'A',
+ priority: 1,
+ require: 'ngModel',
+ link: function (scope, element, attrs, ctrl) {
+ ctrl.$formatters.push(function (value) {
+
+ //set null for 0
+ if(value===0){
+ return '';
+ }
+
+ //return value;
+ var newDate = new Date(value + (60000 * new Date().getTimezoneOffset()));
+
+ var year = newDate.getFullYear();
+ var month = (newDate.getMonth()+1)<10?'0'+(newDate.getMonth()+1):(newDate.getMonth()+1);
+ var date = newDate.getDate()<10?'0'+newDate.getDate():newDate.getDate();
+
+ var hour = newDate.getHours()<10?'0'+newDate.getHours():newDate.getHours();
+ var mins = newDate.getMinutes()<10?'0'+newDate.getMinutes():newDate.getMinutes();
+ var seconds = newDate.getSeconds()<10?'0'+newDate.getSeconds():getSeconds();
+
+ var viewVal = year+"-"+month+"-"+date+" "+hour+":"+mins+":"+seconds;
+ return viewVal;
+ });
+
+ ctrl.$parsers.push(function (value) {
+ if (isNaN(value)||value==null) {
+ return value;
+ }
+ //value = new Date(value.getFullYear(), value.getMonth(), value.getDate(), 0, 0, 0, 0);
+ return value.getTime()-(60000 * value.getTimezoneOffset());
+ });
+ }
+ };
+}).directive("parametertree", function($compile) {
return {
restrict: "E",
transclude: true,
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/webapp/app/js/model/cubeConfig.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/cubeConfig.js b/webapp/app/js/model/cubeConfig.js
index 76d9ae9..b5c77f9 100644
--- a/webapp/app/js/model/cubeConfig.js
+++ b/webapp/app/js/model/cubeConfig.js
@@ -89,5 +89,10 @@ KylinApp.constant('cubeConfig', {
partitionDateFormatOpt:[
'yyyy-MM-dd',
'yyyyMMdd'
+ ],
+ partitionTimeFormatOpt:[
+ 'HH:mm:ss',
+ 'HH:mm',
+ 'HH'
]
});
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/webapp/app/js/model/metaModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/metaModel.js b/webapp/app/js/model/metaModel.js
index 008337f..3f05b3d 100644
--- a/webapp/app/js/model/metaModel.js
+++ b/webapp/app/js/model/metaModel.js
@@ -34,7 +34,9 @@ KylinApp.service('MetaModel',function(){
"partition_desc" : {
"partition_date_column" : null,
"partition_date_start" : null,
- "partition_type" : 'APPEND'
+ "partition_type" : 'APPEND',
+ "partition_time_column" : null,
+ "partition_time_start" : null
},
last_modified:0
};
@@ -81,7 +83,9 @@ KylinApp.service('MetaModel',function(){
"partition_date_column" : null,
"partition_date_start" : null,
"partition_type" : 'APPEND',
- "partition_date_format":'yyyy-MM-dd'
+ "partition_date_format":'yyyy-MM-dd',
+ "partition_time_column" : null,
+ "partition_time_start" : null
},
last_modified:0
};
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/webapp/app/partials/cubeDesigner/refresh_settings.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/refresh_settings.html b/webapp/app/partials/cubeDesigner/refresh_settings.html
index 1ad294e..814c453 100755
--- a/webapp/app/partials/cubeDesigner/refresh_settings.html
+++ b/webapp/app/partials/cubeDesigner/refresh_settings.html
@@ -123,9 +123,19 @@
<div class="col-xs-12 col-sm-6"
ng-class="metaModel.model.partition_desc.partition_date_column!=null&& cubeMetaFrame.partition_date_start==null?'has-error':''">
<!--edit model will convert –>-->
- <input type="text" class="form-control" datepicker-popup="yyyy-MM-dd" datepicker-timezone
- ng-model="cubeMetaFrame.partition_date_start" ng-if="state.mode=='edit'"
- placeholder="Click to choose start date..." is-open="opened"/>
+ <!--<input type="text" class="form-control" datepicker-popup="yyyy-MM-dd" datepicker-timezone-->
+ <!--ng-model="cubeMetaFrame.partition_date_start" ng-if="state.mode=='edit'"-->
+ <!--placeholder="Click to choose start date..." is-open="opened"/>-->
+ <div ng-if="state.mode=='edit'" class="dropdown">
+ <a class="dropdown-toggle" id="dropdown2" role="button" data-toggle="dropdown" data-target="#" href="#">
+ <div class="input-group"><input type="text" class="form-control" date-timepicker-timezone data-ng-model="cubeMetaFrame.partition_date_start"><span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
+ </div>
+ </a>
+ <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
+ <datetimepicker data-ng-model="cubeMetaFrame.partition_date_start" data-datetimepicker-config="{ dropdownSelector: '#dropdown2' }"/>
+ </ul>
+ </div>
+
<small class="help-block"
ng-show="metaModel.model.partition_desc.partition_date_column!=null&& cubeMetaFrame.partition_date_start==null">
Please input start date when partition date column is defined in model.
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/webapp/app/partials/jobs/job_submit.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/jobs/job_submit.html b/webapp/app/partials/jobs/job_submit.html
index 16bca6b..fbf1e4b 100644
--- a/webapp/app/partials/jobs/job_submit.html
+++ b/webapp/app/partials/jobs/job_submit.html
@@ -50,12 +50,24 @@
</td>
</tr>
<tr>
- <td>End Date (Exclude)</td>
- <td>
- <input type="text" datepicker-popup="yyyy-MM-dd" class="input-sm" style="width: 98%" datepicker-timezone
- ng-model="jobBuildRequest.endTime"
- placeholder="Click to choose END date..." is-open="opened" />
- </td>
+ <td width="50%;">End Date (Exclude)</td>
+ <td width="50%;">
+ <!--<input type="text" datepicker-popup="yyyy-MM-dd" class="input-sm" style="width: 98%" datepicker-timezone-->
+ <!--ng-model="jobBuildRequest.endTime"-->
+ <!--placeholder="Click to choose END date..." is-open="opened" />-->
+
+ <div class="dropdown" style="width: 98%;">
+ <a class="dropdown-toggle" id="dropdown2" role="button" data-toggle="dropdown" data-target="#" href="#">
+ <div class="input-group"><input type="text" class="form-control" date-timepicker-timezone data-ng-model="jobBuildRequest.endTime">
+ <span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
+ </div>
+ </a>
+ <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
+ <datetimepicker data-ng-model="jobBuildRequest.endTime" data-datetimepicker-config="{ dropdownSelector: '#dropdown2' }"/>
+ </ul>
+ </div>
+
+ </td>
</tr>
</tbody>
</table>
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/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 95dc4b6..2a46698 100644
--- a/webapp/app/partials/modelDesigner/conditions_settings.html
+++ b/webapp/app/partials/modelDesigner/conditions_settings.html
@@ -74,6 +74,45 @@
</div>
</div>
+ <!--Partition Time Column-->
+ <div class="form-group">
+ <div class="row">
+ <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Partition Time Column</b></label>
+ <div class="col-xs-12 col-sm-6">
+
+ <select style="width: 100%" chosen data-placeholder="e.g. DEFAULT.TEST_KYLIN_FACT.CAL_DT"
+ ng-model="modelsManager.selectedModel.partition_desc.partition_time_column"
+ ng-if="state.mode=='edit'"
+ data-placement=""
+ ng-options="modelsManager.selectedModel.fact_table+'.'+columns.name as modelsManager.selectedModel.fact_table+'.'+columns.name for columns in getPartitonTimeColumns(modelsManager.selectedModel.fact_table)" >
+ <option value="">--Select Partition Column--</option>
+ </select>
+ <small class="help-block text-red" ng-show="state.mode=='edit'">(Column Type should be TIME Type)</small>
+
+ <span ng-if="state.mode=='view'">
+ {{!!(modelsManager.selectedModel.partition_desc.partition_time_column)?modelsManager.selectedModel.partition_desc.partition_time_column: ''}}</span>
+ </div>
+ </div>
+ </div>
+
+ <!--Time Format-->
+ <div class="form-group">
+ <div class="row">
+ <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Time Format</b></label>
+ <div class="col-xs-12 col-sm-6">
+ <select style="width: 100%" chosen
+ ng-required="modelsManager.selectedModel.partition_desc.partition_time_format"
+ ng-model="modelsManager.selectedModel.partition_desc.partition_time_format"
+ ng-if="state.mode=='edit'"
+ data-placement=""
+ ng-options="ddt as ddt for ddt in cubeConfig.partitionTimeFormatOpt">
+ <option value="">--Select Time Format--</option>
+ </select>
+ <span ng-if="state.mode=='view'&&modelsManager.selectedModel.partition_desc.partition_time_column">{{(modelsManager.selectedModel.partition_desc.partition_time_format)}}</span>
+ </div>
+ </div>
+ </div>
+
<div class="form-group" ng-show="userService.hasRole('ROLE_ADMIN')">
<div class="row">
<label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Cube Size</b></label>
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/webapp/bower.json
----------------------------------------------------------------------
diff --git a/webapp/bower.json b/webapp/bower.json
index bba4a52..21fb7f4 100755
--- a/webapp/bower.json
+++ b/webapp/bower.json
@@ -33,7 +33,8 @@
"angular-toggle-switch":"1.3.0",
"angular-ui-select": "0.13.2",
"angular-sanitize": "1.2.18",
- "angular-tree-control": "0.2.8"
+ "angular-tree-control": "0.2.8",
+ "angular-bootstrap-datetimepicker": "0.3.15"
},
"devDependencies": {
"less.js": "~1.4.0",
http://git-wip-us.apache.org/repos/asf/kylin/blob/e564d45c/webapp/grunt.json
----------------------------------------------------------------------
diff --git a/webapp/grunt.json b/webapp/grunt.json
index 86ad1dc..abf1cb5 100755
--- a/webapp/grunt.json
+++ b/webapp/grunt.json
@@ -65,6 +65,7 @@
"app/components/angular-bootstrap-nav-tree/dist/abn_tree.css",
"app/components/angular-toggle-switch/angular-toggle-switch.css",
"app/components/angular-ui-select/dist/select.css",
+ "app/components/angular-bootstrap-datetimepicker/src/css/datetimepicker.css",
"tmp/css/styles.css"
],
"dest": "tmp/css/styles.min.css"