eagle-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ji...@apache.org
Subject [06/14] incubator-eagle git commit: [EAGLE-574] UI refactor for support 0.5 api
Date Wed, 28 Sep 2016 05:38:47 GMT
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/public/js/srv/authorizationSrv.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/js/srv/authorizationSrv.js b/eagle-webservice/src/main/webapp/_app/public/js/srv/authorizationSrv.js
new file mode 100644
index 0000000..dad9f6d
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/js/srv/authorizationSrv.js
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+(function() {
+	'use strict';
+
+	var serviceModule = angular.module('eagle.service');
+	serviceModule.service('Authorization', function ($rootScope, $http, $wrapState, $q) {
+		$http.defaults.withCredentials = true;
+
+		var _promise;
+		var _path = "";
+
+		var content = {
+			isLogin: true,	// Status mark. Work for UI status check, changed when eagle api return 403 authorization failure.
+			needLogin: function () {
+				console.log("[Authorization] Need Login!");
+				if(content.isLogin) {
+					_path = _path || $wrapState.path();
+					content.isLogin = false;
+					console.log("[Authorization] Call need login. Redirect...");
+					$wrapState.go("login", 99);
+				} else {
+					console.log("[Authorization] Already login state...");
+				}
+			},
+			login: function (username, password) {
+				var _hash = btoa(username + ':' + password);
+				return $http({
+					url: app.getURL('userProfile'),
+					method: "GET",
+					headers: {
+						'Authorization': "Basic " + _hash
+					}
+				}).then(function () {
+					content.isLogin = true;
+					return true;
+				}, function () {
+					return false;
+				});
+			},
+			logout: function () {
+				$http({
+					url: app.getURL('logout'),
+					method: "GET"
+				});
+			},
+			path: function (path) {
+				if (typeof path === "string") {
+					_path = path;
+				} else if (path === true) {
+					$wrapState.path(_path || "");
+					_path = "";
+				}
+			}
+		};
+
+		content.userProfile = {};
+		content.isRole = function (role) {
+			if (!content.userProfile.roles) return null;
+
+			return content.userProfile.roles[role] === true;
+		};
+
+		content.reload = function () {
+			_promise = $http({
+				url: app.getURL('userProfile'),
+				method: "GET"
+			}).then(function (data) {
+				content.userProfile = data.data;
+
+				// Role
+				content.userProfile.roles = {};
+				$.each(content.userProfile.authorities, function (i, role) {
+					content.userProfile.roles[role.authority] = true;
+				});
+
+				return content;
+			}, function(data) {
+				if(data.status === 403) {
+					content.needLogin();
+				}
+			});
+			return _promise;
+		};
+
+		content._promise = function () {
+			if (!_promise) {
+				content.reload();
+			}
+			return _promise;
+		};
+
+		content.rolePromise = function(role, rejectState) {
+			var _deferred = $q.defer();
+			var _oriPromise = content._promise();
+			_oriPromise.then(function() {
+				if(content.isRole(role)) {
+					_deferred.resolve(content);
+				} else if(content.isLogin) {
+					_deferred.resolve(content);
+					console.log("[Authorization] go landing...");
+					$wrapState.go(rejectState || "landing");
+				} else {
+					_deferred.reject(content);
+				}
+
+				return content;
+			});
+
+			return _deferred.promise;
+		};
+
+		// Call web service to keep session
+		setInterval(function() {
+			if(!content.isLogin) return;
+
+			$http.get(app.getURL('userProfile')).then(null, function (response) {
+				if(response.status === 403) {
+					console.log("[Session] Out of date...", response);
+					content.needLogin();
+				}
+			});
+		}, 1000 * 60 * 5);
+
+		return content;
+	});
+})();
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/public/js/srv/entitiesSrv.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/js/srv/entitiesSrv.js b/eagle-webservice/src/main/webapp/_app/public/js/srv/entitiesSrv.js
new file mode 100644
index 0000000..b725054
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/js/srv/entitiesSrv.js
@@ -0,0 +1,301 @@
+/*
+ * 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.
+ */
+
+(function() {
+	'use strict';
+
+	var serviceModule = angular.module('eagle.service');
+	serviceModule.service('Entities', function($http, $q, $rootScope, $location, Authorization) {
+		var pkg;
+
+		// Query
+		function _query(name, kvs) {
+			kvs = kvs || {};
+			var _list = [];
+			var _condition = kvs._condition || {};
+			var _additionalCondition = _condition.additionalCondition || {};
+			var _startTime, _endTime;
+			var _startTimeStr, _endTimeStr;
+
+			// Initial
+			// > Condition
+			delete kvs._condition;
+			if(_condition) {
+				kvs.condition = _condition.condition;
+			}
+
+			// > Values
+			if(!kvs.values) {
+				kvs.values = "*";
+			} else if($.isArray(kvs.values)) {
+				kvs.values = $.map(kvs.values, function(field) {
+					return (field[0] === "@" ? '' : '@') + field;
+				}).join(",");
+			}
+
+			var _url = app.getURL(name, kvs);
+
+			// Fill special parameters
+			// > Query by time duration
+			if(_additionalCondition._duration) {
+				_endTime = app.time.now();
+				_startTime = _endTime.clone().subtract(_additionalCondition._duration, "ms");
+
+				// Debug usage. Extend more time duration for end time
+				if(_additionalCondition.__ETD) {
+					_endTime.add(_additionalCondition.__ETD, "ms");
+				}
+
+				_additionalCondition._startTime = _startTime;
+				_additionalCondition._endTime = _endTime;
+
+				_startTimeStr = _startTime.format("YYYY-MM-DD HH:mm:ss");
+				_endTimeStr = _endTime.clone().add(1, "s").format("YYYY-MM-DD HH:mm:ss");
+
+				_url += "&startTime=" + _startTimeStr + "&endTime=" + _endTimeStr;
+			} else if(_additionalCondition._startTime && _additionalCondition._endTime) {
+				_startTimeStr = _additionalCondition._startTime.format("YYYY-MM-DD HH:mm:ss");
+				_endTimeStr = _additionalCondition._endTime.clone().add(1, "s").format("YYYY-MM-DD HH:mm:ss");
+
+				_url += "&startTime=" + _startTimeStr + "&endTime=" + _endTimeStr;
+			}
+
+			// > Query contains metric name
+			if(_additionalCondition._metricName) {
+				_url += "&metricName=" + _additionalCondition._metricName;
+			}
+
+			// > Customize page size
+			if(_additionalCondition._pageSize) {
+				_url = _url.replace(/pageSize=\d+/, "pageSize=" + _additionalCondition._pageSize);
+			}
+
+			// AJAX
+			var canceler = $q.defer();
+			_list._promise = $http.get(_url, {timeout: canceler.promise}).then(function(status) {
+				_list.push.apply(_list, status.data.obj);
+				return _list;
+			});
+			_list._promise.abort = function() {
+				canceler.resolve();
+			};
+
+			_list._promise.then(function() {}, function(data) {
+				if(data.status === 403) {
+					Authorization.needLogin();
+				}
+			});
+
+			return _list;
+		}
+		function _post(url, entities) {
+			var _list = [];
+			_list._promise = $http({
+				method: 'POST',
+				url: url,
+				headers: {
+					"Content-Type": "application/json"
+				},
+				data: entities
+			}).success(function(data) {
+				_list.push.apply(_list, data.obj);
+			});
+			return _list;
+		}
+		function _delete(url) {
+			var _list = [];
+			_list._promise = $http({
+				method: 'DELETE',
+				url: url,
+				headers: {
+					"Content-Type": "application/json"
+				}
+			}).success(function(data) {
+				_list.push.apply(_list, data.obj);
+			});
+			return _list;
+		}
+		function _get(url) {
+			var _list = [];
+			_list._promise = $http({
+				method: 'GET',
+				url: url,
+				headers: {
+					"Content-Type": "text/plain"
+				}
+			}).success(function(data) {
+				// console.log(data);
+				_list.push.apply(_list, data.obj);
+			});
+			return _list;
+		}
+		function ParseCondition(condition) {
+			var _this = this;
+			_this.condition = "";
+			_this.additionalCondition = {};
+
+			if(typeof condition === "string") {
+				_this.condition = condition;
+			} else {
+				_this.condition = $.map(condition, function(value, key) {
+					if(!key.match(/^_/)) {
+						if(value === undefined || value === null) {
+							return '@' + key + '=~".*"';
+						} else {
+							return '@' + key + '="' + value + '"';
+						}
+					} else {
+						_this.additionalCondition[key] = value;
+						return null;
+					}
+				}).join(" AND ");
+			}
+			return _this;
+		}
+
+		pkg = {
+			_query: _query,
+			_post: _post,
+
+			maprfsNameToID: function(serviceName, value, site) {
+				//var _url = "../rest/maprIDResolver/fNameResolver?fName="+name;
+				var _url = app.getMapRNameResolverURL(serviceName, value, site);
+				return _get(_url);
+			},
+
+			updateEntity: function(serviceName, entities, config) {
+				var _url;
+				config = config || {};
+				if(!$.isArray(entities)) entities = [entities];
+
+				// Post clone entities
+				var _entities = $.map(entities, function(entity) {
+					var _entity = {};
+
+					// Clone variables
+					$.each(entity, function(key) {
+						// Skip inner variables
+						if(!key.match(/^__/)) {
+							_entity[key] = entity[key];
+						}
+					});
+
+					// Add timestamp
+					if(config.timestamp !== false) {
+						if(config.createTime !== false && !_entity.createdTime) {
+							_entity.createdTime = new moment().valueOf();
+						}
+						if(config.lastModifiedDate !== false) {
+							_entity.lastModifiedDate = new moment().valueOf();
+						}
+					}
+
+					return _entity;
+				});
+
+				// Check for url hook
+				if(config.hook) {
+					_url = app.getUpdateURL(serviceName) || app.packageURL(serviceName);
+				} else {
+					_url = app.getURL("updateEntity", {serviceName: serviceName});
+				}
+
+				return _post(_url, _entities);
+			},
+
+			deleteEntity: function(serviceName, entities) {
+				if (!$.isArray(entities)) entities = [entities];
+
+				var _entities = $.map(entities, function (entity) {
+					return typeof entity === "object" ? entity.encodedRowkey : entity;
+				});
+				return _post(app.getURL("deleteEntity", {serviceName: serviceName}), _entities);
+			},
+			deleteEntities: function(serviceName, condition) {
+				return _delete(app.getURL("deleteEntities", {serviceName: serviceName, condition: new ParseCondition(condition).condition}));
+			},
+			delete: function(serviceName, kvs) {
+				var _deleteURL = app.getDeleteURL(serviceName);
+				return _delete(common.template(_deleteURL, kvs));
+			},
+
+			queryEntity: function(serviceName, encodedRowkey) {
+				return _query("queryEntity", {serviceName: serviceName, encodedRowkey: encodedRowkey});
+			},
+			queryEntities: function(serviceName, condition, fields) {
+				return _query("queryEntities", {serviceName: serviceName, _condition: new ParseCondition(condition), values: fields});
+			},
+			queryGroup: function(serviceName, condition, groupBy, fields) {
+				return _query("queryGroup", {serviceName: serviceName, _condition: new ParseCondition(condition), groupBy: groupBy, values: fields});
+			},
+			querySeries: function(serviceName, condition, groupBy, fields, intervalmin) {
+				var _cond = new ParseCondition(condition);
+				var _list = _query("querySeries", {serviceName: serviceName, _condition: _cond, groupBy: groupBy, values: fields, intervalmin: intervalmin});
+				_list._promise.then(function() {
+					if(_list.length === 0) {
+						_list._empty = true;
+						_list._convert = true;
+
+						for(var i = 0; i <= (_cond.additionalCondition._endTime.valueOf() - _cond.additionalCondition._startTime.valueOf()) / (1000 * 60 * intervalmin); i += 1) {
+							_list.push(0);
+						}
+					} else if(_list.length === 1) {
+						_list._convert = true;
+						var _unit = _list.pop();
+						_list.push.apply(_list, _unit.value[0]);
+					}
+
+					if(_list._convert) {
+						var _current = _cond.additionalCondition._startTime.clone();
+						$.each(_list, function(i, value) {
+							_list[i] = {
+								x: _current.valueOf(),
+								y: value
+							};
+							_current.add(intervalmin, "m");
+						});
+					}
+				});
+				return _list;
+			},
+
+			query: function(path, params) {
+				var _list = [];
+				_list._promise = $http({
+					method: 'GET',
+					url: app.getURL("query") + path,
+					params: params
+				}).success(function(data) {
+					_list.push.apply(_list, data.obj);
+				});
+				return _list;
+			},
+
+			dialog: function(data, callback) {
+				if(data.success === false || (data.exception || "").trim()) {
+					return $.dialog({
+						title: "OPS",
+						content: $("<pre>").html(data.exception)
+					}, callback);
+				}
+				return false;
+			}
+		};
+		return pkg;
+	});
+})();
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/public/js/srv/main.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/js/srv/main.js b/eagle-webservice/src/main/webapp/_app/public/js/srv/main.js
new file mode 100644
index 0000000..4f5a72a
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/js/srv/main.js
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+(function() {
+	'use strict';
+
+	var eagleSrv = angular.module('eagle.service', []);
+
+	eagleSrv.provider('ServiceError', function() {
+		var errorContainer = {
+			list: [],
+			newError: function(err) {
+				err._read = false;
+				errorContainer.list.unshift(err);
+			},
+			showError: function(err) {
+				err._read = true;
+				$.dialog({
+					size: "large",
+					title: err.title,
+					content: $("<pre>").html(err.description)
+				});
+			},
+			clearAll: function() {
+				errorContainer.list = [];
+			}
+		};
+
+		Object.defineProperty(errorContainer, 'hasUnread', {
+			get: function() {
+				return !!common.array.find(false, errorContainer.list, "_read");
+			}
+		});
+
+		this.$get = function() {
+			return errorContainer;
+		};
+	});
+
+	eagleSrv.config(function ($httpProvider, ServiceErrorProvider) {
+		$httpProvider.interceptors.push(function ($q, $timeout) {
+			return {
+				response: function (response) {
+					var data = response.data;
+					if(data.exception) {
+						console.log(response);
+						ServiceErrorProvider.$get().newError({
+							title: "Http Request Error",
+							description: "URL:\n" + response.config.url + "\n\nParams:\n" + JSON.stringify(response.config.params, null, "\t") + "\n\nException:\n" + data.exception
+						});
+					}
+					return response;
+				}
+			};
+		});
+	});
+})();

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/public/js/srv/pageSrv.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/js/srv/pageSrv.js b/eagle-webservice/src/main/webapp/_app/public/js/srv/pageSrv.js
new file mode 100644
index 0000000..e59d8a3
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/js/srv/pageSrv.js
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+(function() {
+	'use strict';
+
+	var serviceModule = angular.module('eagle.service');
+
+	// ===========================================================
+	// =                         Service                         =
+	// ===========================================================
+	// Feature page
+	serviceModule.service('PageConfig', function() {
+		var _tmplConfig = {
+			pageTitle: "",
+			pageSubTitle: "",
+
+			hideSite: false,
+			lockSite: false,
+			hideApplication: false,
+			hideSidebar: false,
+			hideUser: false,
+
+			// Current page navigation path
+			navPath: [],
+
+			navConfig: {}
+		};
+
+		var PageConfig = {};
+
+		// Reset
+		PageConfig.reset = function() {
+			$.extend(PageConfig, _tmplConfig);
+			PageConfig.navPath = [];
+		};
+		PageConfig.reset();
+
+		// Create navigation path
+		PageConfig.addNavPath = function(title, path) {
+			PageConfig.navPath.push({
+				title: title,
+				path: path
+			});
+			return PageConfig;
+		};
+
+		return PageConfig;
+	});
+
+	// Feature page
+	serviceModule.service('FeaturePageConfig', function(Application) {
+		var config = {
+			// Feature mapping pages
+			_navItemMapping: {}
+		};
+
+		// Register feature controller
+		config.addNavItem = function(feature, item) {
+			var _navItemList = config._navItemMapping[feature] = config._navItemMapping[feature] || [];
+			_navItemList.push(item);
+		};
+
+		// Page list
+		Object.defineProperty(config, "pageList", {
+			get: function() {
+				var _app = Application.current();
+				var _list = [];
+
+				if(_app && _app.features) {
+					$.each(_app.features, function(i, featureName) {
+						_list = _list.concat(config._navItemMapping[featureName] || []);
+					});
+				}
+
+				return _list;
+			}
+		});
+
+		return config;
+	});
+
+	// Configuration page
+	serviceModule.service('ConfigPageConfig', function(Application) {
+		var _originPageList = [
+			{icon: "server", title: "Sites", url: "#/config/site"},
+			{icon: "cubes", title: "Applications", url: "#/config/application"},
+			{icon: "leaf", title: "Features", url: "#/config/feature"}
+		];
+
+		var config = {
+			_navItemMapping: {}
+		};
+
+		// Register feature controller
+		config.addNavItem = function(feature, item) {
+			var _navItemList = config._navItemMapping[feature] = config._navItemMapping[feature] || [];
+			_navItemList.push(item);
+		};
+
+		// Page list
+		Object.defineProperty(config, "pageList", {
+			get: function() {
+				var _list = _originPageList;
+
+				$.each(Application.featureList, function(i, feature) {
+					_list = _list.concat(config._navItemMapping[feature.tags.feature] || []);
+				});
+
+				return _list;
+			}
+		});
+
+		return config;
+	});
+})();

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/public/js/srv/siteSrv.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/js/srv/siteSrv.js b/eagle-webservice/src/main/webapp/_app/public/js/srv/siteSrv.js
new file mode 100644
index 0000000..fce64c0
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/js/srv/siteSrv.js
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ */
+
+(function() {
+	'use strict';
+
+	var serviceModule = angular.module('eagle.service');
+	serviceModule.service('Site', function($rootScope, $wrapState, $location, $q, Entities, Application) {
+		var _currentSite;
+		var Site = {};
+		var _promise;
+
+		Site.list = [];
+		Site.list.set = {};
+
+		Site.current = function(site) {
+			if(site) {
+				var _prev = _currentSite;
+				_currentSite = site;
+
+				// Keep current site and reload page
+				if(!_prev || _prev.tags.site !== _currentSite.tags.site) {
+					if(sessionStorage) {
+						sessionStorage.setItem("site", _currentSite.tags.site);
+					}
+
+					if(!$wrapState.current.abstract && $wrapState.current.name !== "login") {
+						console.log("[Site]", "Switch. Reload.");
+						$wrapState.reload();
+					}
+				}
+			}
+			return _currentSite;
+		};
+		Site.find = function(siteName) {
+			return common.array.find(siteName, Site.list, "tags.site");
+		};
+		Site.url = function(site, url) {
+			console.warn("[Site] Site.url is a deprecated function.");
+			if(arguments.length == 1) {
+				url = site;
+			} else {
+				Site.current(site);
+			}
+			$wrapState.url(url);
+
+			if ($rootScope.$$phase != '$apply' && $rootScope.$$phase != '$digest') {
+				$rootScope.$apply();
+			}
+		};
+
+		Site.currentSiteApplication = function() {
+			var _app = Application.current();
+			if(!_app) return null;
+
+			return _currentSite.applicationList.set[_app.tags.application];
+		};
+
+		Site.reload = function() {
+			var _applicationList;
+
+			if(Site.list && Site.list._promise) Site.list._promise.abort();
+
+			Site.list = Entities.queryEntities("SiteDescService", '');
+			Site.list.set = {};
+			_applicationList = Entities.queryEntities("SiteApplicationService", '');
+
+			_promise = $q.all([Site.list._promise, _applicationList._promise, Application._promise()]).then(function() {
+				// Fill site set
+				$.each(Site.list, function(i, site) {
+					var _list = [];
+					var _appGrp = {};
+					var _appGrpList = [];
+					_list.set = {};
+					Site.list.set[site.tags.site] = site;
+
+					// Find application
+					_list.find = function(applicationName) {
+						return common.array.find(applicationName, _list, "tags.application");
+					};
+
+					// Define properties
+					Object.defineProperties(site, {
+						applicationList: {
+							get: function() {
+								return _list;
+							}
+						},
+						applicationGroup: {
+							get: function() {
+								return _appGrp;
+							}
+						},
+						applicationGroupList: {
+							get: function() {
+								return _appGrpList;
+							}
+						}
+					});
+				});
+
+				// Fill site application mapping
+				$.each(_applicationList, function(i, siteApplication) {
+					var _site = Site.list.set[siteApplication.tags.site];
+					var _application = Application.find(siteApplication.tags.application);
+					var _appGroup, _configObj;
+
+					if(!_site) {
+						console.warn("[Site] Application not match site:", siteApplication.tags.site, "-", siteApplication.tags.application);
+					} else if(!_application) {
+						console.warn("[Site] Application not found:", siteApplication.tags.site, "-", siteApplication.tags.application);
+					} else {
+						_configObj = common.properties.parse(siteApplication.config, {});
+						Object.defineProperties(siteApplication, {
+							application: {
+								get: function () {
+									return _application;
+								}
+							},
+							configObj: {
+								get: function () {
+									return _configObj;
+								}
+							}
+						});
+
+						_site.applicationList.push(siteApplication);
+						_site.applicationList.set[siteApplication.tags.application] = siteApplication;
+
+						_appGroup = _site.applicationGroup[_application.group] = _site.applicationGroup[_application.group] || [];
+						_appGroup.push(_application);
+					}
+				});
+
+				// Fill site application group attributes
+				$.each(Site.list, function(i, site) {
+					$.each(site.applicationGroup, function(grpName, grpList) {
+						var grp = {
+							name: grpName,
+							list: grpList,
+							enabledList: $.grep(grpList, function(application) {return site.applicationList.set[application.tags.application].enabled;}),
+							disabledList: $.grep(grpList, function(application) {return !site.applicationList.set[application.tags.application].enabled;})
+						};
+
+						site.applicationGroupList.push(grp);
+					});
+
+					site.applicationGroupList.sort(function(a, b) {
+						if(a.name === b.name) return 0;
+						if(a.name === "Others") return 1;
+						if(b.name === "Others") return -1;
+						return a.name < b.name ? -1 : 1;
+					});
+				});
+
+				// Set current site
+				if(sessionStorage && Site.find(sessionStorage.getItem("site"))) {
+					Site.current(Site.find(sessionStorage.getItem("site")));
+				} else {
+					Site.current(Site.list[0]);
+				}
+
+				return Site;
+			});
+
+			return _promise;
+		};
+
+		Site._promise = function() {
+			if(!_promise) {
+				Site.reload();
+			}
+			return _promise;
+		};
+
+		return Site;
+	});
+})();
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/public/js/srv/uiSrv.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/js/srv/uiSrv.js b/eagle-webservice/src/main/webapp/_app/public/js/srv/uiSrv.js
new file mode 100644
index 0000000..9955fac
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/js/srv/uiSrv.js
@@ -0,0 +1,247 @@
+/*
+ * 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.
+ */
+
+(function() {
+	'use strict';
+
+	/**
+	 * Check function to check fields pass or not
+	 * @callback checkFieldFunction
+	 * @param {{}} entity
+	 * @return {string}
+     */
+
+	var serviceModule = angular.module('eagle.service');
+
+	// ===========================================================
+	// =                         Service                         =
+	// ===========================================================
+	// Feature page
+	serviceModule.service('UI', function($rootScope, $q, $compile) {
+		var UI = {};
+
+		function _bindShortcut($dialog) {
+			$dialog.on("keydown", function (event) {
+				if(event.which === 13) {
+					if(!$(":focus").is("textarea")) {
+						$dialog.find(".confirmBtn:enabled").click();
+					}
+				}
+			});
+		}
+
+		function _fieldDialog(create, name, entity, fieldList, checkFunc) {
+			var _deferred, $mdl, $scope;
+
+			_deferred = $q.defer();
+			$scope = $rootScope.$new(true);
+			$scope.name = name;
+			$scope.entity = entity;
+			$scope.fieldList = fieldList;
+			$scope.checkFunc = checkFunc;
+			$scope.lock = false;
+			$scope.create = create;
+
+			$scope.config = typeof name === "object" ? name : {};
+
+			// Modal
+			$mdl = $(TMPL_FIELDS).appendTo('body');
+			$compile($mdl)($scope);
+			$mdl.modal();
+
+			$mdl.on("hide.bs.modal", function() {
+				_deferred.reject();
+			});
+			$mdl.on("hidden.bs.modal", function() {
+				_deferred.resolve({
+					entity: entity
+				});
+				$mdl.remove();
+			});
+
+			// Function
+			$scope.getFieldDescription = function (field) {
+				if(typeof field.description === "function") {
+					return field.description($scope.entity);
+				}
+				return field.description || ((field.name || field.field) + '...');
+			};
+
+			$scope.emptyFieldList = function() {
+				return $.map(fieldList, function(field) {
+					if(!field.optional && !entity[field.field]) {
+						return field.field;
+					}
+				});
+			};
+
+			$scope.confirm = function() {
+				$scope.lock = true;
+				_deferred.notify({
+					entity: entity,
+					closeFunc: function() {
+						$mdl.modal('hide');
+					},
+					unlock: function() {
+						$scope.lock = false;
+					}
+				});
+			};
+
+			_bindShortcut($mdl);
+
+			return _deferred.promise;
+		}
+
+		/***
+		 * Create a creation confirm modal.
+		 * @param name			Name title
+		 * @param entity		bind entity
+		 * @param fieldList	Array. Format: {name, field, type(optional: select, blob), rows(optional: number), description(optional), optional(optional), readonly(optional), valueList(optional)}
+		 * @param checkFunc	Check logic function. Return string will prevent access
+		 */
+		UI.createConfirm = function(name, entity, fieldList, checkFunc) {
+			return _fieldDialog(true, name, entity, fieldList, checkFunc);
+		};
+
+		/***
+		 * Create a update confirm modal.
+		 * @param name			Name title
+		 * @param entity		bind entity
+		 * @param fieldList	Array. Format: {name, field, type(optional: select, blob), rows(optional: number), description(optional), optional(optional), readonly(optional), valueList(optional)}
+		 * @param checkFunc	Check logic function. Return string will prevent access
+		 */
+		UI.updateConfirm = function(name, entity, fieldList, checkFunc) {
+			return _fieldDialog(false, name, entity, fieldList, checkFunc);
+		};
+
+		/***
+		 * Create a customize field confirm modal.
+		 * @param {object} config					- Configuration object
+		 * @param {string=} config.title				- Title of dialog box
+		 * @param {string=} config.size				- "large". Set dialog size
+		 * @param {boolean=} config.confirm			- Display or not confirm button
+		 * @param {string=} config.confirmDesc		- Confirm button display description
+		 * @param {object} entity					- bind entity
+		 * @param {{name:string, field:string,type:('select'|'blob'),rows:number,description:string,optional:boolean,readonly:boolean,valueList:Array}[]} fieldList - Display fields
+		 * @param {checkFieldFunction=} checkFunc	- Check logic function. Return string will prevent access
+		 */
+		UI.fieldConfirm = function(config, entity, fieldList, checkFunc) {
+			return _fieldDialog("field", config, entity, fieldList, checkFunc);
+		};
+
+		UI.deleteConfirm = function(name) {
+			var _deferred, $mdl, $scope;
+
+			_deferred = $q.defer();
+			$scope = $rootScope.$new(true);
+			$scope.name = name;
+			$scope.lock = false;
+
+			// Modal
+			$mdl = $(TMPL_DELETE).appendTo('body');
+			$compile($mdl)($scope);
+			$mdl.modal();
+
+			$mdl.on("hide.bs.modal", function() {
+				_deferred.reject();
+			});
+			$mdl.on("hidden.bs.modal", function() {
+				_deferred.resolve({
+					name: name
+				});
+				$mdl.remove();
+			});
+
+			// Function
+			$scope.delete = function() {
+				$scope.lock = true;
+				_deferred.notify({
+					name: name,
+					closeFunc: function() {
+						$mdl.modal('hide');
+					},
+					unlock: function() {
+						$scope.lock = false;
+					}
+				});
+			};
+
+			return _deferred.promise;
+		};
+
+		return UI;
+	});
+
+	// ===========================================================
+	// =                         Template                        =
+	// ===========================================================
+	var TMPL_FIELDS =
+		'<div class="modal fade" tabindex="-1" role="dialog">' +
+			'<div class="modal-dialog" ng-class="{\'modal-lg\': config.size === \'large\'}" role="document">' +
+				'<div class="modal-content">' +
+					'<div class="modal-header">' +
+						'<button type="button" class="close" data-dismiss="modal" aria-label="Close">' +
+							'<span aria-hidden="true">&times;</span>' +
+						'</button>' +
+						'<h4 class="modal-title">{{config.title || (create ? "New" : "Update") + " " + name}}</h4>' +
+					'</div>' +
+					'<div class="modal-body">' +
+						'<div class="form-group" ng-repeat="field in fieldList" ng-switch="field.type">' +
+							'<label for="featureName">' +
+								'<span ng-if="!field.optional">*</span> ' +
+								'{{field.name || field.field}}' +
+							'</label>' +
+							'<textarea class="form-control" placeholder="{{getFieldDescription(field)}}" ng-model="entity[field.field]" rows="{{ field.rows || 10 }}" ng-readonly="field.readonly" ng-disabled="lock" ng-switch-when="blob"></textarea>' +
+							'<select class="form-control" ng-model="entity[field.field]" ng-init="entity[field.field] = entity[field.field] || field.valueList[0]" ng-switch-when="select">' +
+								'<option ng-repeat="value in field.valueList">{{value}}</option>' +
+							'</select>' +
+							'<input type="text" class="form-control" placeholder="{{getFieldDescription(field)}}" ng-model="entity[field.field]" ng-readonly="field.readonly" ng-disabled="lock" ng-switch-default>' +
+						'</div>' +
+					'</div>' +
+					'<div class="modal-footer">' +
+						'<p class="pull-left text-danger">{{checkFunc(entity)}}</p>' +
+						'<button type="button" class="btn btn-default" data-dismiss="modal" ng-disabled="lock">Close</button>' +
+						'<button type="button" class="btn btn-primary confirmBtn" ng-click="confirm()" ng-disabled="checkFunc(entity) || emptyFieldList().length || lock" ng-if="config.confirm !== false">' +
+							'{{config.confirmDesc || (create ? "Create" : "Update")}}' +
+						'</button>' +
+					'</div>' +
+				'</div>' +
+			'</div>' +
+		'</div>';
+
+	var TMPL_DELETE =
+		'<div class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">' +
+			'<div class="modal-dialog">' +
+				'<div class="modal-content">' +
+					'<div class="modal-header">' +
+						'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>' +
+						'<h4 class="modal-title">Delete Confirm</h4></div>' +
+						'<div class="modal-body">' +
+							'<span class="text-red fa fa-exclamation-triangle pull-left" style="font-size: 50px;"></span>' +
+							'<p>You are <strong class="text-red">DELETING</strong> \'{{name}}\'!</p>' +
+							'<p>Proceed to delete?</p>' +
+						'</div>' +
+						'<div class="modal-footer">' +
+							'<button type="button" class="btn btn-danger" ng-click="delete()" ng-disabled="lock">Delete</button>' +
+							'<button type="button" class="btn btn-default" data-dismiss="modal" ng-disabled="lock">Cancel</button>' +
+						'</div>' +
+				'</div>' +
+			'</div>' +
+		'</div>';
+})();

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/public/js/srv/wrapStateSrv.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/js/srv/wrapStateSrv.js b/eagle-webservice/src/main/webapp/_app/public/js/srv/wrapStateSrv.js
new file mode 100644
index 0000000..57872b2
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/js/srv/wrapStateSrv.js
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+(function() {
+	'use strict';
+
+	var serviceModule = angular.module('eagle.service');
+	serviceModule.service('$wrapState', function($state, $location, $stateParams) {
+		var $wrapState = {};
+		var _targetState = null;
+		var _targetPriority = 0;
+
+		// Go
+		$wrapState.go = function(state, param, priority) {
+			setTimeout(function() {
+				_targetState = null;
+				_targetPriority = 0;
+			});
+
+			if(typeof param !== "object") {
+				param = {};
+				priority = param;
+			}
+
+			priority = priority === true ? 1 : (priority || 0);
+			if(_targetPriority > priority) {
+				console.log("[Wrap State] Go - low priority:", state, "(Skip)");
+				return false;
+			}
+
+			if(_targetState !== state || priority) {
+				if($state.current && $state.current.name === state && angular.equals($state.params, param)) {
+					console.log($state);
+					console.log("[Wrap State] Go reload.");
+					$state.reload();
+				} else {
+					console.log("[Wrap State] Go:", state, param, priority);
+					$state.go(state, param);
+				}
+				_targetState = state;
+				_targetPriority = priority;
+				return true;
+			} else {
+				console.log("[Wrap State] Go:", state, "(Ignored)");
+			}
+			return false;
+		};
+
+		// Reload
+		$wrapState.reload = function() {
+			console.log("[Wrap State] Do reload.");
+			$state.reload();
+		};
+
+		// Path
+		$wrapState.path = function(path) {
+			if(path !== undefined) {
+				console.log("[Wrap State][Deprecated] Switch path:", path);
+			}
+			return $location.path(path);
+		};
+
+		// URL
+		$wrapState.url = function(url) {
+			if(url !== undefined) console.log("[Wrap State] Switch url:", url);
+			return $location.url(url);
+		};
+
+		Object.defineProperties($wrapState, {
+			// Origin $state
+			origin: {
+				get: function() {
+					return $state;
+				}
+			},
+
+			// Current
+			current: {
+				get: function() {
+					return $state.current;
+				}
+			},
+
+			// Parameter
+			param: {
+				get: function() {
+					return $.extend({}, $location.search(), $stateParams);
+				}
+			}
+		});
+
+		return $wrapState;
+	});
+})();
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/app/index.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/index.html b/eagle-webservice/src/main/webapp/app/index.html
deleted file mode 100644
index 7cd3e25..0000000
--- a/eagle-webservice/src/main/webapp/app/index.html
+++ /dev/null
@@ -1,281 +0,0 @@
-<!DOCTYPE html>
-<!--
-  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.
-  -->
-
-<html ng-app="eagleApp" ng-controller="MainCtrl">
-	<head>
-		<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
-		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-		<meta charset="UTF-8">
-		<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
-		<link rel="shortcut icon" href="public/images/favicon.png">
-
-		<title>Eagle</title>
-		<link rel="shortcut icon" type="image/png" href="public/images/favicon.png">
-
-		<!-- ref:css public/css/styles.min.css -->
-		<link href="public/css/main.css" rel="stylesheet" type="text/css" media="screen">
-		<link href="public/css/animation.css" rel="stylesheet" type="text/css" media="screen">
-		<link href="../node_modules/bootstrap/dist/css/bootstrap.css" rel="stylesheet" type="text/css" media="screen">
-		<link href="../node_modules/zombiej-bootstrap-components/bootstrap-components/css/bootstrap-components.css" rel="stylesheet" type="text/css" media="screen">
-		<link href="../node_modules/zombiej-nvd3/build/nv.d3.css" rel="stylesheet" type="text/css" />
-		<link href="../node_modules/font-awesome/css/font-awesome.css" rel="stylesheet" type="text/css" />
-		<link href="../node_modules/admin-lte/dist/css/AdminLTE.css" rel="stylesheet" type="text/css" />
-		<link href="../node_modules/admin-lte/dist/css/skins/skin-blue.css" rel="stylesheet" type="text/css" />
-		<!-- endref -->
-	</head>
-	<body class="skin-blue sidebar-mini" ng-class="{'no-sidebar' : PageConfig.hideSidebar}">
-		<!-- Site wrapper -->
-		<div class="wrapper">
-			<header class="main-header">
-				<a href="#/" class="logo">
-					<span class="logo-mini"><img src="public/images/favicon_white.png" /></span>
-					<span class="logo-lg">Apache Eagle</span>
-				</a>
-				<!-- Header Navbar: style can be found in header.less -->
-				<nav class="navbar navbar-static-top" role="navigation">
-					<!-- Sidebar toggle button-->
-					<a ng-hide="PageConfig.hideSidebar" class="sidebar-toggle" data-toggle="offcanvas" role="button">
-						<span class="sr-only">Toggle navigation</span>
-						<span class="icon-bar"></span>
-						<span class="icon-bar"></span>
-						<span class="icon-bar"></span>
-					</a>
-
-					<div class="navbar-custom-menu">
-						<ul class="nav navbar-nav">
-							<!-- Admin error list -->
-							<li class="dropdown" ng-show="ServiceError.list.length">
-								<a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
-									<i class="fa fa-exclamation-triangle" ng-class="{blink: ServiceError.hasUnread}"></i>
-								</a>
-								<ul class="dropdown-menu">
-									<li ng-repeat="error in ServiceError.list">
-										<a ng-click="ServiceError.showError(error);">
-											<span class="fa" ng-class="{'fa-envelope': !error._read, 'fa-check': error._read}"></span>
-											{{error.title}}
-										</a>
-									</li>
-									<li role="separator" class="divider"></li>
-									<li>
-										<a ng-click="ServiceError.clearAll();">
-											<span class="fa fa-trash"></span>
-											Clear All
-										</a>
-									</li>
-								</ul>
-							</li>
-
-							<!-- Site -->
-							<li class="dropdown" ng-show="!PageConfig.hideSite && !PageConfig.lockSite">
-								<a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
-									<i class="fa fa-server"></i>
-									{{Site.current().tags.site}}
-									<i class="fa fa-caret-down"></i>
-								</a>
-								<ul class="dropdown-menu">
-									<li ng-repeat="_site in Site.list" ng-if="_site.enabled">
-										<a ng-click="Site.current(_site);">
-											<span class="fa fa-database"></span> {{_site.tags.site}}
-										</a>
-									</li>
-								</ul>
-							</li>
-							<li class="dropdown" ng-show="PageConfig.lockSite">
-								<a>
-									<i class="fa fa-server"></i>
-									{{Site.current().tags.site}}
-								</a>
-							</li>
-
-							<!-- User -->
-							<li class="dropdown user user-menu" ng-hide="PageConfig.hideUser">
-								<a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
-									<i class="fa fa-user"></i>
-									{{Auth.userProfile.username}}
-								</a>
-								<ul class="dropdown-menu">
-									<!-- User image -->
-									<li class="user-header">
-										<span class="img-circle">
-											<span class="fa fa-user" alt="User Image"></span>
-										</span>
-										<p>
-											{{Auth.userProfile.username}}
-											<small>
-												<span ng-repeat="role in Auth.userProfile.authorities">{{role.authority}} </span>
-											</small>
-										</p>
-									</li>
-									<!-- Menu Footer-->
-									<li class="user-footer">
-										<div class="pull-left" ng-if="Auth.isRole('ROLE_ADMIN')">
-											<a href="#/config/site" class="btn btn-default btn-flat">Management</a>
-										</div>
-										<div class="pull-right">
-											<a ng-click="logout();" class="btn btn-default btn-flat">Sign out</a>
-										</div>
-									</li>
-								</ul>
-							</li>
-						</ul>
-					</div>
-
-					<!-- Applications -->
-					<div ng-hide="PageConfig.hideApplication">
-						<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#moduleMenu">
-							<span class="sr-only">Toggle navigation</span>
-							<span class="fa fa-map"></span>
-						</button>
-						<div class="collapse navbar-collapse" id="moduleMenu">
-							<ul class="nav navbar-nav">
-								<li ng-repeat="_grp in Site.current().applicationGroupList" ng-if="_grp.enabledList.length"
-									class="dropdown" ng-class="{active: Application.current().group === _grp.name}">
-									<a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
-										{{_grp.name}}
-									</a>
-									<ul class="dropdown-menu">
-										<li ng-repeat="_app in _grp.enabledList">
-											<a ng-click="Application.current(_app);">
-												<span class="fa fa-cubes"></span> {{_app.displayName}}
-											</a>
-										</li>
-									</ul>
-								</li>
-							</ul>
-						</div>
-					</div>
-				</nav>
-			</header>
-
-			<!-- =============================================== -->
-			<!-- Left side column. contains the side bar -->
-			<aside class="main-sidebar" ng-hide="PageConfig.hideSidebar">
-				<!-- side bar: style can be found in sidebar.less -->
-				<section class="sidebar">
-					<ul class="sidebar-menu">
-						<li class="header">
-							{{Application.current().group || 'Application'}} >
-							{{Application.current().displayName || 'Features'}}
-						</li>
-						<li ng-repeat="page in PageConfig.navConfig.pageList track by $index" ng-class="getNavClass(page)" ng-show="getNavVisible(page)">
-							<a href="{{page.url}}">
-								<i class="fa fa-{{page.icon}}"></i> <span>{{page.title}}</span> 
-							</a>
-						</li>
-					</ul>
-				</section>
-				<!-- /.sidebar -->
-			</aside>
-
-			<!-- =============================================== -->
-			<!-- Right side column. Contains the navbar and content of the page -->
-			<div class="content-wrapper">
-				<!-- Content Header (Page header) -->
-				<section class="content-header" ng-hide="PageConfig.hideSidebar">
-					<h1>
-						<span class="pageTitle">{{PageConfig.pageTitle}}</span>
-						<small class="pageSubTitle">{{PageConfig.pageSubTitle}}</small>
-					</h1>
-
-
-					<ol class="breadcrumb">
-						<li ng-repeat="navPath in PageConfig.navPath">
-							<a ng-href="#{{navPath.path}}">
-								<span class="fa fa-home" ng-if="$first"></span>
-								{{navPath.title || navPath.path}}
-							</a>
-						</li>
-					</ol>
-				</section>
-
-				<!-- Main content -->
-				<section class="content">
-					<div id="content">
-						<div ui-view></div>
-					</div>
-				</section><!-- /.content -->
-			</div><!-- /.content-wrapper -->
-
-			<footer class="main-footer">
-				<div class="pull-right hidden-xs">
-					<b>License</b>
-					<a href="http://www.apache.org/licenses/LICENSE-2.0" class="text-muted">Apache-2.0</a>
-				</div>
-				<strong>
-					Apache Eagle
-					<a target="_blank" href="https://eagle.incubator.apache.org/">Home</a> /
-					<a target="_blank" href="https://eagle.incubator.apache.org/docs/community.html">Community</a> /
-					<a target="_blank" href="https://cwiki.apache.org/confluence/display/EAG/FAQ">FAQ</a>
-				</strong>
-			</footer>
-		</div><!-- ./wrapper -->
-
-		<!-- ref:js public/js/doc.js -->
-		<script src="../node_modules/jquery/dist/jquery.js"></script>
-		<script src="../node_modules/jquery-slimscroll/jquery.slimscroll.min.js"></script>
-		<script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
-		<script src="../node_modules/zombiej-bootstrap-components/bootstrap-components/js/bootstrap-components.min.js"></script>
-		<script src="../node_modules/moment/min/moment-with-locales.min.js"></script>
-		<script src="../node_modules/moment-timezone/builds/moment-timezone-with-data.min.js"></script>
-		<script src="../node_modules/admin-lte/dist/js/app.min.js"></script>
-		<script src="../node_modules/angular/angular.js"></script>
-		<script src="../node_modules/angular-resource/angular-resource.js"></script>
-		<script src="../node_modules/angular-route/angular-route.js"></script>
-		<script src="../node_modules/angular-animate/angular-animate.js"></script>
-		<script src="../node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js"></script>
-		<script src="../node_modules/angular-ui-router/release/angular-ui-router.js"></script>
-		<script src="../node_modules/d3/d3.js"></script>
-		<script src="../node_modules/zombiej-nvd3/build/nv.d3.js"></script>
-
-		<!-- Application -->
-		<script src="public/js/app.js" type="text/javascript" charset="utf-8"></script>
-
-		<!-- Service -->
-		<script src="public/js/srv/main.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/srv/applicationSrv.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/srv/authorizationSrv.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/srv/entitiesSrv.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/srv/siteSrv.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/srv/pageSrv.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/srv/wrapStateSrv.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/srv/uiSrv.js" type="text/javascript" charset="utf-8"></script>
-
-		<!-- Misc -->
-		<script src="public/js/app.ui.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/app.time.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/app.config.js" type="text/javascript" charset="utf-8"></script>
-
-		<script src="public/js/common.js" type="text/javascript" charset="utf-8"></script>
-
-		<!-- Components -->
-		<script src="public/js/components/main.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/components/sortTable.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/components/tabs.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/components/file.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/components/charts/line3d.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/components/nvd3.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/components/sortable.js" type="text/javascript" charset="utf-8"></script>
-
-		<!-- Controllers -->
-		<script src="public/js/ctrl/main.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/ctrl/authController.js" type="text/javascript" charset="utf-8"></script>
-		<script src="public/js/ctrl/configurationController.js" type="text/javascript" charset="utf-8"></script>
-		<!-- endref -->
-	</body>
-</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/app/partials/config/application.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/partials/config/application.html b/eagle-webservice/src/main/webapp/app/partials/config/application.html
deleted file mode 100644
index 0bf194c..0000000
--- a/eagle-webservice/src/main/webapp/app/partials/config/application.html
+++ /dev/null
@@ -1,124 +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 class="box box-info">
-	<div class="box-header with-border">
-		<h3 class="box-title">
-			<span class="fa fa-cogs"></span>
-			Configuration
-			<small class="text-danger" ng-show="changed">
-				<span class="label label-warning label-sm">Unsaved</span>
-			</small>
-		</h3>
-	</div><!-- /.box-header -->
-
-	<div class="box-body">
-		<div class="row">
-			<div class="col-md-3">
-				<ul class="nav nav-pills nav-stacked">
-					<li class="disabled"><a>Application</a></li>
-					<li role="presentation" ng-repeat="_application in Application.list track by $index" ng-class="{active: application === _application}">
-						<a ng-click="setApplication(_application)">
-							<span class="fa fa-server"></span>
-							{{_application.tags.application}}
-							<span ng-if="_application.alias">({{_application.alias}})</span>
-						</a>
-					</li>
-
-					<li>
-						<a class="text-light-blue" ng-click="newApplication()" ng-disabled="_pageLock">
-							<span class="fa fa-plus-square"></span>
-							New Application
-						</a>
-					</li>
-				</ul>
-			</div>
-
-			<div class="col-md-9">
-				<a class="pull-right btn btn-danger btn-xs" ng-click="deleteApplication(application)" ng-disabled="_pageLock">
-					<span class="fa fa-trash-o"></span>
-					Delete Application
-				</a>
-
-				<!-- Title -->
-				<h3 class="guideline">
-					Application
-					<small>{{application.tags.application}}</small>
-				</h3>
-				<hr/>
-
-				<!-- Config -->
-				<div class="form-group">
-					<label for="displayName">Display Name</label>
-					<input type="text" class="form-control" id="displayName" placeholder="(Optional) Display name." ng-model="applications[application.tags.application].alias">
-				</div>
-				<div class="form-group">
-					<label for="applicationGroup">Group</label>
-					<input type="text" class="form-control" id="applicationGroup" placeholder="(Optional) Group name" ng-model="applications[application.tags.application].groupName">
-				</div>
-				<div class="form-group">
-					<label for="applicationDescription">Description</label>
-					<textarea id="applicationDescription" class="form-control" placeholder="(Optional) Application description" rows="2" ng-model="applications[application.tags.application].description"></textarea>
-				</div>
-				<div class="form-group">
-					<label for="applicationConfiguration">Configuration</label>
-					<span class="text-danger">{{configCheck(applications[application.tags.application].config)}}</span>
-					<textarea id="applicationConfiguration" class="form-control" placeholder="Application configuration. Feature can read this " rows="5" ng-model="applications[application.tags.application].config"></textarea>
-				</div>
-
-				<!-- Feature -->
-				<label>* Feature</label>
-				<div class="row">
-					<div class="col-sm-6">
-						<h1 class="text-muted text-center" ng-show="applications[application.tags.application].features.length === 0">No feature in using</h1>
-						<ul class="products-list product-list-in-box fixed-height" ng-show="applications[application.tags.application].features.length !== 0">
-							<li class="item" ng-repeat="feature in applications[application.tags.application].features track by $index" ng-class="{active: _feature === feature}">
-								<div class="product-operation">
-									<a class="fa fa-chevron-up" ng-click="moveFeature(feature, applications[application.tags.application].features, -1)"></a>
-									<a class="fa fa-chevron-down" ng-click="moveFeature(feature, applications[application.tags.application].features, 1)"></a>
-								</div>
-								<div class="product-info">
-									<a class="fa fa-times pull-right" ng-click="removeFeature(feature, applications[application.tags.application])"></a>
-									<span class="product-title">{{feature}}</span>
-									<span class="product-description">{{Application.featureList.set[feature].description}}</span>
-								</div>
-							</li>
-						</ul>
-					</div>
-					<div class="col-sm-6">
-						<ul class="products-list product-list-in-box fixed-height">
-							<li class="item" ng-repeat="feature in applications[application.tags.application].optionalFeatures track by $index">
-								<button class="btn btn-lg btn-primary pull-left" ng-click="addFeature(feature, applications[application.tags.application])" ng-disabled="_pageLock">
-									<span class="fa fa-star-o"></span>
-								</button>
-								<div class="product-info">
-									<span class="product-title">{{feature}}</span>
-									<span class="product-description">{{Application.featureList.set[feature].description}}</span>
-								</div>
-							</li>
-						</ul>
-					</div>
-				</div>
-			</div>
-		</div>
-	</div><!-- /.box-body -->
-
-	<div class="box-footer clearfix">
-		<button class="btn btn-primary" ng-click="saveAll()" ng-disabled="_pageLock">Save All</button>
-	</div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/app/partials/config/feature.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/partials/config/feature.html b/eagle-webservice/src/main/webapp/app/partials/config/feature.html
deleted file mode 100644
index 945d90b..0000000
--- a/eagle-webservice/src/main/webapp/app/partials/config/feature.html
+++ /dev/null
@@ -1,85 +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 class="box box-info">
-	<div class="box-header with-border">
-		<h3 class="box-title">
-			<span class="fa fa-cogs"></span>
-			Configuration
-			<small class="text-danger" ng-show="changed">
-				<span class="label label-warning label-sm">Unsaved</span>
-			</small>
-		</h3>
-	</div><!-- /.box-header -->
-
-	<div class="box-body">
-		<div class="row">
-			<div class="col-md-3">
-				<ul class="nav nav-pills nav-stacked">
-					<li class="disabled">
-						<a>Feature</a>
-					</li>
-					<li role="presentation" ng-repeat="_feature in Application.featureList" ng-class="{active: feature === _feature}">
-						<a ng-click="setFeature(_feature)">
-							<span class="fa fa-leaf" ng-class="{'text-danger': _feature._loaded === false}" uib-tooltip="Module load failed!" tooltip-enable="_feature._loaded === false"></span>
-							{{_feature.tags.feature}}
-						</a>
-					</li>
-					<li>
-						<a class="text-light-blue" ng-click="newFeature()" ng-disabled="_pageLock">
-							<span class="fa fa-plus-square"></span>
-							New Feature
-						</a>
-					</li>
-				</ul>
-			</div>
-
-			<div class="col-md-9">
-				<a class="pull-right btn btn-danger btn-xs" ng-click="deleteFeature(feature)" ng-disabled="_pageLock">
-					<span class="fa fa-trash-o"></span>
-					Delete Feature
-				</a>
-
-				<h3 class="guideline">
-					<span class="fa fa-exclamation-triangle text-danger" uib-tooltip="Module load failed!" ng-show="feature._loaded === false"></span>
-					{{feature.tags.feature}}
-				</h3>
-				<hr/>
-
-				<p class="text text-muted">
-					Will load the start up file <code>controller.js</code> from <code>public/feature/{{feature.tags.feature}}</code>.
-					If you are developing customized feature, please reference provided feature.
-				</p>
-
-				<!-- Config -->
-				<div class="form-group">
-					<label for="featureVersion">Version</label>
-					<input id="featureVersion" type="text" class="form-control" placeholder="(Optional) Feature version." ng-model="features[feature.tags.feature].version">
-				</div>
-				<div class="form-group">
-					<label for="featureDescription">Description</label>
-					<textarea id="featureDescription" class="form-control" placeholder="(Optional) Feature description." rows="10" ng-model="features[feature.tags.feature].description"></textarea>
-				</div>
-			</div>
-		</div>
-	</div><!-- /.box-body -->
-
-	<div class="box-footer clearfix">
-		<button class="btn btn-primary" ng-click="saveAll()" ng-disabled="_pageLock">Save All</button>
-	</div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/app/partials/config/site.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/partials/config/site.html b/eagle-webservice/src/main/webapp/app/partials/config/site.html
deleted file mode 100644
index f7d43eb..0000000
--- a/eagle-webservice/src/main/webapp/app/partials/config/site.html
+++ /dev/null
@@ -1,115 +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 class="box box-info">
-	<div class="box-header with-border">
-		<h3 class="box-title">
-			<span class="fa fa-cogs"></span>
-			Configuration
-			<small class="text-danger" ng-show="changed">
-				<span class="label label-warning label-sm">Unsaved</span>
-			</small>
-		</h3>
-	</div><!-- /.box-header -->
-
-	<div class="box-body">
-		<div class="row">
-			<div class="col-md-3">
-				<ul class="nav nav-pills nav-stacked">
-					<li class="disabled"><a>Site</a></li>
-					<li role="presentation" ng-repeat="_site in Site.list track by $index" ng-class="{active: site === _site}">
-						<a ng-click="setSite(_site)">
-							<span class="fa fa-server"></span>
-							{{_site.tags.site}}
-						</a>
-					</li>
-
-					<li>
-						<a class="text-light-blue" ng-click="newSite()" ng-disabled="_pageLock">
-							<span class="fa fa-plus-square"></span>
-							New Site
-						</a>
-					</li>
-				</ul>
-			</div>
-
-			<div class="col-md-9">
-				<a class="pull-right btn btn-danger btn-xs" ng-click="deleteSite(site)" ng-disabled="_pageLock">
-					<span class="fa fa-trash-o"></span>
-					Delete Site
-				</a>
-
-				<!-- Title -->
-				<h3 class="guideline">
-					Site
-					<small>{{site.tags.site}}</small>
-				</h3>
-				<hr/>
-
-				<!-- Config -->
-				<div class="checkbox">
-					<label>
-						<input type="checkbox" ng-checked="sites[site.tags.site].enabled" ng-click="sites[site.tags.site].enabled = !sites[site.tags.site].enabled">
-						<strong>Enabled</strong>
-					</label>
-				</div>
-				<hr/>
-
-				<!-- Application -->
-				<label>* Application</label>
-				<div class="row">
-					<div class="col-sm-6">
-						<h1 class="text-muted text-center" ng-show="sites[site.tags.site].applications.length === 0">No application in using</h1>
-						<ul class="products-list product-list-in-box fixed-height" ng-show="sites[site.tags.site].applications.length !== 0">
-							<li class="item" ng-repeat="application in sites[site.tags.site].applications track by $index" ng-class="{active: _application === application}">
-								<div class="product-operation single">
-									<span class="fa fa-cubes"></span>
-								</div>
-								<div class="product-info">
-									<a class="fa fa-times pull-right" ng-click="removeApplication(application, sites[site.tags.site])"></a>
-									<span class="product-title">
-										<a class="fa fa-cog" ng-click="setApplication(application)"></a>
-										{{application.tags.application}}
-									</span>
-									<span class="product-description">{{Application.list.set[application.tags.application].description}}</span>
-								</div>
-							</li>
-						</ul>
-					</div>
-					<div class="col-sm-6">
-						<ul class="products-list product-list-in-box fixed-height">
-							<li class="item" ng-repeat="application in sites[site.tags.site].optionalApplications track by $index">
-								<button class="btn btn-lg btn-primary pull-left" ng-click="addApplication(application, sites[site.tags.site])" ng-disabled="_pageLock">
-									<span class="fa fa-star-o"></span>
-								</button>
-								<div class="product-info">
-									<span class="product-title">{{application.tags.application}}</span>
-									<span class="product-description">{{Application.list.set[application.tags.application].description}}</span>
-								</div>
-							</li>
-						</ul>
-					</div>
-				</div>
-			</div>
-		</div>
-	</div><!-- /.box-body -->
-
-	<div class="box-footer clearfix">
-		<button class="btn btn-primary" ng-click="saveAll()" ng-disabled="_pageLock">Save All</button>
-	</div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/app/partials/landing.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/partials/landing.html b/eagle-webservice/src/main/webapp/app/partials/landing.html
deleted file mode 100644
index a2e0f47..0000000
--- a/eagle-webservice/src/main/webapp/app/partials/landing.html
+++ /dev/null
@@ -1,30 +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.
-  -->
-
-<p class="lead">
-	<span ng-if="!Application.current()">Current site do not use any application.</span>
-	<span ng-if="Application.current()">Current application do not install any feature.</span>
-
-	<span ng-if="Auth.isRole('ROLE_ADMIN')">
-		Click
-		<a href="#/config/site" ng-if="!Application.current()">here</a>
-		<a href="#/config/application" ng-if="Application.current()">here</a>
-		to configure.
-	</span>
-	<span ng-if="!Auth.isRole('ROLE_ADMIN')">Please contact your admin.</span>
-</p>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/app/partials/login.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/partials/login.html b/eagle-webservice/src/main/webapp/app/partials/login.html
deleted file mode 100644
index 7faef42..0000000
--- a/eagle-webservice/src/main/webapp/app/partials/login.html
+++ /dev/null
@@ -1,54 +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 class="login-box">
-	<div class="login-logo">
-		<a href="#/">Apache Eagle</a>
-	</div>
-
-	<div class="login-box-body" ng-show="!loginSuccess">
-		<p class="login-box-msg">Sign in to start your session</p>
-		<div class="form-group has-feedback">
-			<input type="text" class="form-control" placeholder="User Name" ng-model="username" ng-keypress="login($event)" autocomplete="off" id="username">
-			<span class="glyphicon glyphicon-user form-control-feedback"></span>
-		</div>
-		<div class="form-group has-feedback">
-			<input type="password" class="form-control" placeholder="Password" ng-model="password" ng-keypress="login($event)">
-			<span class="glyphicon glyphicon-lock form-control-feedback"></span>
-		</div>
-		<div class="row">
-			<div class="col-xs-8">
-				<div class="checkbox">
-					<label> <input type="checkbox" ng-checked="rememberUser" ng-click="rememberUser = !rememberUser;" /> Remember Me
-					</label>
-				</div>
-			</div>
-			<div class="col-xs-4">
-				<button class="btn btn-primary btn-block btn-flat" ng-click="login($event, true)" ng-disabled="lock">Sign In</button>
-			</div>
-		</div>
-	</div>
-
-	<div class="login-box-body text-center" ng-show="loginSuccess">
-		<p class="login-box-msg">Login success</p>
-		<p>
-			<span class="fa fa-refresh fa-spin"></span>
-			Loading environment...
-		</p>
-	</div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/app/public/css/animation.css
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/public/css/animation.css b/eagle-webservice/src/main/webapp/app/public/css/animation.css
deleted file mode 100644
index 954bd29..0000000
--- a/eagle-webservice/src/main/webapp/app/public/css/animation.css
+++ /dev/null
@@ -1,46 +0,0 @@
-@CHARSET "UTF-8";
-/*
- * 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.
- */
-
-[ui-view].ng-enter, [ui-view].ng-leave {
-	position: absolute;
-	left: 0;
-	right: 0;
-	-webkit-transition: all .5s ease-in-out;
-	-moz-transition: all .5s ease-in-out;
-	-o-transition: all .5s ease-in-out;
-	transition: all .3s ease-in-out;
-}
-
-[ui-view].ng-enter {
-	opacity: 0;
-}
-
-[ui-view].ng-enter-active {
-	opacity: 1;
-}
-
-[ui-view].ng-leave {
-	opacity: 1;
-	transform:translate3d(0, 0, 0);
-}
-
-[ui-view].ng-leave-active {
-	opacity: 0;
-	transform:translate3d(20%, 0, 0);
-}
\ No newline at end of file


Mime
View raw message