Repository: incubator-eagle Updated Branches: refs/heads/master eb0734b6f -> d37643b0a
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/d37643b0/eagle-webservice/src/main/webapp/app/public/js/srv/applicationSrv.js ---------------------------------------------------------------------- diff --git a/eagle-webservice/src/main/webapp/app/public/js/srv/applicationSrv.js b/eagle-webservice/src/main/webapp/app/public/js/srv/applicationSrv.js new file mode 100644 index 0000000..67d714f --- /dev/null +++ b/eagle-webservice/src/main/webapp/app/public/js/srv/applicationSrv.js @@ -0,0 +1,168 @@ +/* + * 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('Application', function($q, $location, $wrapState, Entities) { + var Application = {}; + var _current; + var _featureCache = {};// After loading feature will be in cache. Which will not load twice. + var _deferred; + + Application.list = []; + Application.list.set = {}; + Application.featureList = []; + Application.featureList.set = {}; + + // Set current application + Application.current = function(app) { + if(arguments.length && _current !== app) { + var _prev = _current; + _current = app; + + if(sessionStorage && _current) { + sessionStorage.setItem("application", _current.tags.application); + } + + if(_prev) { + console.log("[Application] Switch. Redirect to landing page."); + $wrapState.go('landing', true); + } + } + return _current; + }; + Application.find = function(appName) { + return common.array.find(appName, Application.list, "tags.application"); + }; + + Application.reload = function() { + _deferred = $q.defer(); + + if(Application.list && Application.list._promise) Application.list._promise.abort(); + if(Application.featureList && Application.featureList._promise) Application.featureList._promise.abort(); + + Application.list = Entities.queryEntities("ApplicationDescService", ''); + Application.list.set = {}; + Application.featureList = Entities.queryEntities("FeatureDescService", ''); + Application.featureList.set = {}; + + Application.featureList._promise.then(function() { + var _promiseList; + // Load feature script + _promiseList = $.map(Application.featureList, function(feature) { + var _ajax_deferred, _script; + if(_featureCache[feature.tags.feature]) return; + + _featureCache[feature.tags.feature] = true; + _ajax_deferred = $q.defer(); + _script = document.createElement('script'); + _script.type = 'text/javascript'; + _script.src = "public/feature/" + feature.tags.feature + "/controller.js?_=" + Math.random(); + document.head.appendChild(_script); + _script.onload = function() { + feature._loaded = true; + _ajax_deferred.resolve(); + }; + _script.onerror = function() { + feature._loaded = false; + _featureCache[feature.tags.feature] = false; + _ajax_deferred.reject(); + }; + return _ajax_deferred.promise; + }); + + // Merge application & feature + Application.list._promise.then(function() { + // Fill feature set + $.each(Application.featureList, function(i, feature) { + Application.featureList.set[feature.tags.feature] = feature; + }); + + // Fill application set + $.each(Application.list, function(i, application) { + Application.list.set[application.tags.application] = application; + application.features = application.features || []; + var _configObj = common.parseJSON(application.config, {}); + var _appFeatureList = $.map(application.features, function(featureName) { + var _feature = Application.featureList.set[featureName]; + if(!_feature) { + console.warn("[Application] Feature not mapping:", application.tags.application, "-", featureName); + } else { + return _feature; + } + }); + + // Find feature + _appFeatureList.find = function(featureName) { + return common.array.find(featureName, _appFeatureList, "tags.feature"); + }; + + Object.defineProperties(application, { + featureList: { + get: function () { + return _appFeatureList; + } + }, + // Get format group name. Will mark as 'Others' if no group defined + groupName: { + get: function () { + return this.group || "Others"; + } + }, + configObj: { + get: function() { + return _configObj; + } + }, + displayName: { + get: function() { + return this.alias || this.tags.application; + } + } + }); + }); + + // Set current application + if(!Application.current() && sessionStorage && Application.find(sessionStorage.getItem("application"))) { + Application.current(Application.find(sessionStorage.getItem("application"))); + } + }); + + // Process all promise + $q.all(_promiseList.concat(Application.list._promise)).finally(function() { + _deferred.resolve(Application); + }); + }, function() { + _deferred.reject(Application); + }); + + return _deferred.promise; + }; + + Application._promise = function() { + if(!_deferred) { + Application.reload(); + } + return _deferred.promise; + }; + + return Application; + }); +})(); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/d37643b0/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..337b567 --- /dev/null +++ b/eagle-webservice/src/main/webapp/app/public/js/srv/authorizationSrv.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'); + 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; + }; + + return content; + }); +})(); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/d37643b0/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..b580f92 --- /dev/null +++ b/eagle-webservice/src/main/webapp/app/public/js/srv/entitiesSrv.js @@ -0,0 +1,281 @@ +/* + * 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 _addtionalCondition = _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(_addtionalCondition._duration) { + _endTime = app.time.now(); + _startTime = _endTime.clone().subtract(_addtionalCondition._duration, "ms"); + + // Debug usage. Extend more time duration for end time + if(_addtionalCondition.__ETD) { + _endTime.add(_addtionalCondition.__ETD, "ms"); + } + + _addtionalCondition._startTime = _startTime; + _addtionalCondition._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(_addtionalCondition._startTime && _addtionalCondition._endTime) { + _startTimeStr = _addtionalCondition._startTime.format("YYYY-MM-DD HH:mm:ss"); + _endTimeStr = _addtionalCondition._endTime.clone().add(1, "s").format("YYYY-MM-DD HH:mm:ss"); + + _url += "&startTime=" + _startTimeStr + "&endTime=" + _endTimeStr; + } + + // > Query contains metric name + if(_addtionalCondition._metricName) { + _url += "&metricName=" + _addtionalCondition._metricName; + } + + // > Customize page size + if(_addtionalCondition._pageSize) { + _url = _url.replace(/pageSize=\d+/, "pageSize=" + _addtionalCondition._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 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, + + 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); + } 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/d37643b0/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..82765b8 --- /dev/null +++ b/eagle-webservice/src/main/webapp/app/public/js/srv/main.js @@ -0,0 +1,19 @@ +/* + * 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. + */ + +angular.module('eagle.service', []); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/d37643b0/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/d37643b0/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..907915d --- /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.parseJSON(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.groupName] = _site.applicationGroup[_application.groupName] || []; + _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/d37643b0/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..f82c838 --- /dev/null +++ b/eagle-webservice/src/main/webapp/app/public/js/srv/uiSrv.js @@ -0,0 +1,218 @@ +/* + * 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('UI', function($rootScope, $q, $compile) { + var UI = {}; + + 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.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; + } + }); + }; + + return _deferred.promise; + } + + /*** + * Create a creation confirm modal. + * @param name Name title + * @param entity bind entity + * @param fieldList Array. Format: {name, field, type(optional: blob), rows(optional: number), description(optional), optional(optional), readonly(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: blob), rows(optional: number), description(optional), optional(optional), readonly(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 config Configuration object + * @param config.title Title of dialog box + * @param config.size "large". Set dialog size + * @param config.confirm Boolean. Display or not confirm button + * @param config.confirmDesc Confirm button display description + * @param entity bind entity + * @param fieldList Array. Format: {name, field, type(optional: blob), rows(optional: number), description(optional), optional(optional), readonly(optional)} + * @param 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">×</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="{{field.description || field.name || field.field + \'...\'}}" ng-model="entity[field.field]" rows="{{ field.rows || 10 }}" ng-readonly="field.readonly" ng-disabled="lock" ng-switch-when="blob"></textarea>' + + '<input type="text" class="form-control" placeholder="{{field.description || field.name || field.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" 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">×</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/d37643b0/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/d37643b0/eagle-webservice/src/main/webapp/grunt.json ---------------------------------------------------------------------- diff --git a/eagle-webservice/src/main/webapp/grunt.json b/eagle-webservice/src/main/webapp/grunt.json index 0b8ad5a..c921862 100644 --- a/eagle-webservice/src/main/webapp/grunt.json +++ b/eagle-webservice/src/main/webapp/grunt.json @@ -15,8 +15,9 @@ "node_modules/angular/angular.min.js", "node_modules/angular-resource/angular-resource.min.js", "node_modules/angular-route/angular-route.min.js", - "node_modules/angular-cookies/angular-cookies.min.js", + "node_modules/angular-animate/angular-animate.min.js", "node_modules/angular-ui-bootstrap/ui-bootstrap-tpls.min.js", + "node_modules/angular-ui-router/release/angular-ui-router.min.js", "node_modules/d3/d3.min.js", "node_modules/zombiej-nvd3/build/nv.d3.min.js", @@ -28,8 +29,8 @@ "src": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", "node_modules/zombiej-bootstrap-components/bootstrap-components/css/bootstrap-components.min.css", - "node_modules/font-awesome/css/font-awesome.min.css", "node_modules/zombiej-nvd3/build/nv.d3.min.css", + "node_modules/font-awesome/css/font-awesome.min.css", "node_modules/admin-lte/dist/css/AdminLTE.min.css", "node_modules/admin-lte/dist/css/skins/skin-blue.min.css", http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/d37643b0/eagle-webservice/src/main/webapp/package.json ---------------------------------------------------------------------- diff --git a/eagle-webservice/src/main/webapp/package.json b/eagle-webservice/src/main/webapp/package.json index 713b93c..1e6f8d4 100644 --- a/eagle-webservice/src/main/webapp/package.json +++ b/eagle-webservice/src/main/webapp/package.json @@ -20,10 +20,11 @@ "angular-cookies" : "1.4.7", "angular-animate" : "1.4.7", "angular-ui-bootstrap" : "0.14.3", - "d3" : "~3.5.10", - "zombiej-nvd3" : "~1.8.1-1", - "jquery-slimscroll": "1.3.6", - "zombiej-bootstrap-components" : "~1.1.1" + "angular-ui-router" : "~0.2.17", + "d3" : "3.5.14", + "zombiej-nvd3" : "1.8.1-1", + "jquery-slimscroll" :"1.3.6", + "zombiej-bootstrap-components" : "1.1.1" }, "devDependencies": {