You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@eagle.apache.org by ha...@apache.org on 2016/02/25 11:25:19 UTC
[3/7] incubator-eagle git commit: EAGLE-139 EAGLE-163 Eagle UI
Modularization and fix bugs in policy extensions
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/d37643b0/eagle-webservice/src/main/webapp/app/public/feature/userProfile/controller.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/public/feature/userProfile/controller.js b/eagle-webservice/src/main/webapp/app/public/feature/userProfile/controller.js
new file mode 100644
index 0000000..f048a85
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/app/public/feature/userProfile/controller.js
@@ -0,0 +1,268 @@
+/*
+ * 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 featureControllers = angular.module('featureControllers');
+ var feature = featureControllers.register("userProfile");
+
+ // ==============================================================
+ // = Function =
+ // ==============================================================
+
+ // ==============================================================
+ // = User Profile =
+ // ==============================================================
+
+ // ======================== Profile List ========================
+ //feature.navItem("list", "User Profiles", "graduation-cap");
+ feature.controller('list', function(PageConfig, Site, $scope, $interval, Entities) {
+ PageConfig.pageSubTitle = Site.current().tags.site;
+
+ $scope.common = common;
+ $scope.algorithms = [];
+
+ // ======================================== Algorithms ========================================
+ $scope.algorithmEntity = {};
+ Entities.queryEntities("AlertDefinitionService", {site: Site.current().tags.site, dataSource: "userProfile"})._promise.then(function(data) {
+ $scope.algorithmEntity = common.getValueByPath(data, "obj[0]");
+ $scope.algorithmEntity.policy = common.parseJSON($scope.algorithmEntity.policyDef);
+ });
+
+ // ======================================= User profile =======================================
+ $scope.profileList = Entities.queryEntities("MLModelService", {site: Site.current().tags.site}, ["user", "algorithm", "content", "version"]);
+ $scope.profileList._promise.then(function() {
+ var _algorithms = {};
+ var _users = {};
+
+ // Map user
+ $.each($scope.profileList, function(i, unit) {
+ _algorithms[unit.tags.algorithm] = unit.tags.algorithm;
+ var _user = _users[unit.tags.user] = _users[unit.tags.user] || {user: unit.tags.user};
+ _user[unit.tags.algorithm] = {
+ version: unit.version
+ };
+
+ // DE
+ if(unit.tags.algorithm === "DE") {
+ var _statistics = common.parseJSON(unit.content);
+ _statistics = common.getValueByPath(_statistics, "statistics", []);
+ _user[unit.tags.algorithm].topCommands = $.map(common.array.top(_statistics, "mean"), function(command) {
+ return command.commandName;
+ });
+ }
+ });
+
+ // Map algorithms
+ $scope.algorithms = $.map(_algorithms, function(algorithm) {
+ return algorithm;
+ }).sort();
+
+ $scope.profileList.splice(0);
+ $scope.profileList.push.apply($scope.profileList, common.map.toArray(_users));
+ });
+
+ // =========================================== Task ===========================================
+ $scope.tasks = [];
+ function _loadTasks() {
+ var _tasks = Entities.queryEntities("ScheduleTaskService", {
+ site: Site.current().tags.site,
+ _pageSize: 100,
+ _duration: 1000 * 60 * 60 * 24 * 14,
+ __ETD: 1000 * 60 * 60 * 24
+ });
+ _tasks._promise.then(function() {
+ $scope.tasks.splice(0);
+ $scope.tasks.push.apply($scope.tasks, _tasks);
+
+ // Duration
+ $.each($scope.tasks, function(i, data) {
+ if(data.timestamp && data.updateTime) {
+ var _ms = (new moment(data.updateTime)).diff(new moment(data.timestamp));
+ var _d = moment.duration(_ms);
+ data._duration = Math.floor(_d.asHours()) + moment.utc(_ms).format(":mm:ss");
+ data.duration = _ms;
+ } else {
+ data._duration = "--";
+ }
+ });
+ });
+ }
+
+ $scope.runningTaskCount = function () {
+ return common.array.count($scope.tasks, "INITIALIZED", "status") +
+ common.array.count($scope.tasks, "PENDING", "status") +
+ common.array.count($scope.tasks, "EXECUTING", "status");
+ };
+
+ // Create task
+ $scope.updateTask = function() {
+ $.dialog({
+ title: "Confirm",
+ content: "Do you want to update now?",
+ confirm: true
+ }, function(ret) {
+ if(!ret) return;
+
+ var _entity = {
+ status: "INITIALIZED",
+ detail: "Newly created command",
+ tags: {
+ site: Site.current().tags.site,
+ type: "USER_PROFILE_TRAINING"
+ },
+ timestamp: +new Date()
+ };
+ Entities.updateEntity("ScheduleTaskService", _entity, {timestamp: false})._promise.success(function(data) {
+ if(!Entities.dialog(data)) {
+ _loadTasks();
+ }
+ });
+ });
+ };
+
+ // Show detail
+ $scope.showTaskDetail = function(task) {
+ var _content = $("<pre>").text(task.detail);
+
+ var $mdl = $.dialog({
+ title: "Detail",
+ content: _content
+ });
+
+ _content.click(function(e) {
+ if(!e.ctrlKey) return;
+
+ $.dialog({
+ title: "Confirm",
+ content: "Remove this task?",
+ confirm: true
+ }, function(ret) {
+ if(!ret) return;
+
+ $mdl.modal('hide');
+ Entities.deleteEntity("ScheduleTaskService", task)._promise.then(function() {
+ _loadTasks();
+ });
+ });
+ });
+ };
+
+ _loadTasks();
+ var _loadInterval = $interval(_loadTasks, app.time.refreshInterval);
+ $scope.$on('$destroy',function(){
+ $interval.cancel(_loadInterval);
+ });
+ });
+
+ // ======================= Profile Detail =======================
+ feature.controller('detail', function(PageConfig, Site, $scope, $wrapState, Entities) {
+ PageConfig.pageTitle = "User Profile";
+ PageConfig.pageSubTitle = Site.current().tags.site;
+ PageConfig
+ .addNavPath("User Profile", "/userProfile/list")
+ .addNavPath("Detail");
+
+ $scope.user = $wrapState.param.filter;
+
+ // User profile
+ $scope.profiles = {};
+ $scope.profileList = Entities.queryEntities("MLModelService", {site: Site.current().tags.site, user: $scope.user});
+ $scope.profileList._promise.then(function() {
+ $.each($scope.profileList, function(i, unit) {
+ unit._content = common.parseJSON(unit.content);
+ $scope.profiles[unit.tags.algorithm] = unit;
+ });
+
+ // DE
+ if($scope.profiles.DE) {
+ console.log($scope.profiles.DE);
+
+ $scope.profiles.DE._chart = {};
+
+ $scope.profiles.DE.estimates = {};
+ $.each($scope.profiles.DE._content, function(key, value) {
+ if(key !== "statistics") {
+ $scope.profiles.DE.estimates[key] = value;
+ }
+ });
+
+ var _meanList = [];
+ var _stddevList = [];
+
+ $.each($scope.profiles.DE._content.statistics, function(i, unit) {
+ _meanList[i] = {
+ x: unit.commandName,
+ y: unit.mean
+ };
+ _stddevList[i] = {
+ x: unit.commandName,
+ y: unit.stddev
+ };
+ });
+ $scope.profiles.DE._chart.series = [
+ {
+ key: "mean",
+ values: _meanList
+ },
+ {
+ key: "stddev",
+ values: _stddevList
+ }
+ ];
+
+ // Percentage table list
+ $scope.profiles.DE.meanList = [];
+ var _total = common.array.sum($scope.profiles.DE._content.statistics, "mean");
+ $.each($scope.profiles.DE._content.statistics, function(i, unit) {
+ $scope.profiles.DE.meanList.push({
+ command: unit.commandName,
+ percentage: unit.mean / _total
+ });
+ });
+ }
+
+ // EigenDecomposition
+ if($scope.profiles.EigenDecomposition && $scope.profiles.EigenDecomposition._content.principalComponents) {
+ $scope.profiles.EigenDecomposition._chart = {
+ series: [],
+ };
+
+ $.each($scope.profiles.EigenDecomposition._content.principalComponents, function(z, grp) {
+ var _line = [];
+ $.each(grp, function(x, y) {
+ _line.push([x,y,z]);
+ });
+
+ $scope.profiles.EigenDecomposition._chart.series.push({
+ data: _line
+ });
+ });
+ }
+ });
+
+ // UI
+ $scope.showRawData = function(content) {
+ $.dialog({
+ title: "Raw Data",
+ content: $("<pre>").text(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/feature/userProfile/page/detail.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/public/feature/userProfile/page/detail.html b/eagle-webservice/src/main/webapp/app/public/feature/userProfile/page/detail.html
new file mode 100644
index 0000000..0f94e03
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/app/public/feature/userProfile/page/detail.html
@@ -0,0 +1,87 @@
+<!--
+ 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-primary">
+ <div class="box-header with-border">
+ <i class="fa fa-user"> </i>
+ <h3 class="box-title">
+ {{user}}
+ </h3>
+ </div>
+ <div class="box-body">
+ <div>
+ <div class="inline-group">
+ <dl><dt>User</dt><dd>{{user}}</dd></dl>
+ <dl><dt>Site</dt><dd>{{Site.current().tags.site}}</dd></dl>
+ </div>
+ <div class="inline-group">
+ <dl><dt>Other Info</dt><dd class="text-muted">N/A</dd></dl>
+ </div>
+ </div>
+
+ <div class="overlay" ng-hide="profileList._promise.$$state.status === 1;">
+ <span class="fa fa-refresh fa-spin"></span>
+ </div>
+ </div>
+</div>
+
+<!-- Analysis -->
+<div class="nav-tabs-custom">
+ <ul class="nav nav-tabs">
+ <li class="active">
+ <a href="[data-id='DE']" data-toggle="tab" ng-click=" currentTab='DE'">DE</a>
+ </li>
+ <li>
+ <a href="[data-id='EigenDecomposition']" data-toggle="tab" ng-click=" currentTab='EigenDecomposition'">EigenDecomposition</a>
+ </li>
+ <li class="pull-right">
+ <button class="btn btn-primary" ng-click="showRawData(currentTab === 'EigenDecomposition' ? profiles.EigenDecomposition.content : profiles.DE.content)">Raw Data</button>
+ </li>
+ </ul>
+ <div class="tab-content">
+ <div class="tab-pane active" data-id="DE">
+ <div class="row">
+ <div class="col-md-9">
+ <div nvd3="profiles.DE._chart.series" data-config="{chart: 'column', xType: 'text', height: 400}" class="nvd3-chart-cntr" height="400"></div>
+ <div class="inline-group text-center">
+ <dl ng-repeat="(key, value) in profiles.DE.estimates"><dt>{{key}}</dt><dd>{{value}}</dd></dl>
+ </div>
+ </div>
+
+ <div class="col-md-3">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <th>Command</th>
+ <th>Percentage</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="unit in profiles.DE.meanList">
+ <td>{{unit.command}}</td>
+ <td class="text-right">{{(unit.percentage*100).toFixed(2)}}%</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div><!-- /.tab-pane -->
+ <div class="tab-pane" data-id="EigenDecomposition">
+ <div line3d-chart height="400" data="profiles.EigenDecomposition._chart.series"> </div>
+ </div><!-- /.tab-pane -->
+ </div><!-- /.tab-content -->
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/d37643b0/eagle-webservice/src/main/webapp/app/public/feature/userProfile/page/list.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/public/feature/userProfile/page/list.html b/eagle-webservice/src/main/webapp/app/public/feature/userProfile/page/list.html
new file mode 100644
index 0000000..2f14479
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/app/public/feature/userProfile/page/list.html
@@ -0,0 +1,138 @@
+<!--
+ 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-primary">
+ <div class="box-header with-border">
+ <i class="fa fa-list-alt"> </i>
+ <h3 class="box-title">
+ User Profiles
+ <small><a data-toggle="collapse" href="[data-id='algorithms']">Detail</a></small>
+ </h3>
+ <div class="pull-right">
+ <a class="label label-primary" ng-class="runningTaskCount() ? 'label-primary' : 'label-default'" data-toggle="modal" data-target="#taskMDL">Update</a>
+ </div>
+ </div>
+ <div class="box-body">
+ <!-- Algorithms -->
+ <div data-id="algorithms" class="collapse">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <td>Feature</td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="algorithm in algorithmEntity.policy.algorithms">
+ <td>{{algorithm.name}}</td>
+ <td>{{algorithm.features}}</td>
+ </tr>
+ </tbody>
+ </table>
+ <hr/>
+ </div>
+
+ <!-- User Profile List -->
+ <p ng-show="profileList._promise.$$state.status !== 1">
+ <span class="fa fa-refresh fa-spin"> </span>
+ Loading...
+ </p>
+
+ <div sorttable source="profileList" ng-show="profileList._promise.$$state.status === 1">
+ <table class="table table-bordered" ng-non-bindable>
+ <thead>
+ <tr>
+ <th width="10%" sortpath="user">User</th>
+ <th>Most Predominat Feature</th>
+ <th width="10"></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <a href="#/userProfile/detail/{{item.user}}">{{item.user}}</a>
+ </td>
+ <td>
+ {{item.DE.topCommands.slice(0,3).join(", ")}}
+ </td>
+ <td>
+ <a href="#/userProfile/detail/{{item.user}}">Detail</a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+
+<!-- Modal: User profile Schedule Task -->
+<div class="modal fade" id="taskMDL" tabindex="-1" role="dialog">
+ <div class="modal-dialog modal-lg" 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">Training History</h4>
+ </div>
+ <div class="modal-body">
+ <div sorttable source="tasks">
+ <table class="table table-bordered" ng-non-bindable>
+ <thead>
+ <tr>
+ <th sortpath="tags.type">Command</th>
+ <th sortpath="timestamp">Start Time</th>
+ <th sortpath="updateTime">Update Time</th>
+ <th sortpath="duration">Duration</th>
+ <th sortpath="status">Status</th>
+ <th width="10"> </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{item.tags.type}}</td>
+ <td>{{common.format.date(item.timestamp) || "--"}}</td>
+ <td>{{common.format.date(item.updateTime) || "--"}}</td>
+ <td>{{item._duration}}</td>
+ <td class="text-nowrap">
+ <span class="fa fa-hourglass-start text-muted" ng-show="item.status === 'INITIALIZED'"></span>
+ <span class="fa fa-hourglass-half text-info" ng-show="item.status === 'PENDING'"></span>
+ <span class="fa fa-circle-o-notch text-primary" ng-show="item.status === 'EXECUTING'"></span>
+ <span class="fa fa-check-circle text-success" ng-show="item.status === 'SUCCEEDED'"></span>
+ <span class="fa fa-exclamation-circle text-danger" ng-show="item.status === 'FAILED'"></span>
+ <span class="fa fa-ban text-muted" ng-show="item.status === 'CANCELED'"></span>
+ {{item.status}}
+ </td>
+ <td>
+ <a ng-click="_parent.showTaskDetail(item)">Detail</a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-primary pull-left" ng-click="updateTask()" ng-show="Auth.isRole('ROLE_ADMIN')">
+ Update Now
+ </button>
+ <button type="button" class="btn btn-default" data-dismiss="modal">
+ Close
+ </button>
+ </div>
+ </div>
+ </div>
+</div>
\ 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/images/favicon_white.png
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/public/images/favicon_white.png b/eagle-webservice/src/main/webapp/app/public/images/favicon_white.png
new file mode 100644
index 0000000..9879e92
Binary files /dev/null and b/eagle-webservice/src/main/webapp/app/public/images/favicon_white.png differ
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/d37643b0/eagle-webservice/src/main/webapp/app/public/js/app.config.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/public/js/app.config.js b/eagle-webservice/src/main/webapp/app/public/js/app.config.js
index f18b846..1e6fd79 100644
--- a/eagle-webservice/src/main/webapp/app/public/js/app.config.js
+++ b/eagle-webservice/src/main/webapp/app/public/js/app.config.js
@@ -1,77 +1,104 @@
-/*
- * 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';
-
- app.config = {
- // ============================================================================
- // = URLs =
- // ============================================================================
- urls: {
- HOST: '..',
-
- updateEntity: 'rest/entities?serviceName=${serviceName}',
- queryEntity: 'rest/entities/rowkey?serviceName=${serviceName}&value=${encodedRowkey}',
- queryEntities: 'rest/list?query=${serviceName}[${condition}]{${values}}&pageSize=100000',
- deleteEntity: 'rest/entities/delete?serviceName=${serviceName}&byId=true',
- deleteEntities: 'rest/entities?query=${serviceName}[${condition}]{*}&pageSize=100000',
-
- queryGroup: 'rest/list?query=${serviceName}[${condition}]<${groupBy}>{${values}}&pageSize=100000',
- querySeries: 'rest/list?query=${serviceName}[${condition}]<${groupBy}>{${values}}&pageSize=100000&timeSeries=true&intervalmin=${intervalmin}',
-
- query: 'rest/',
-
- userProfile: 'rest/authentication',
- logout: 'logout',
- },
-
- // ============================================================================
- // = Data Sources =
- // ============================================================================
- dataSource: {
- uiInvisibleList: ["userProfile"],
- },
- };
-
- // ============================================================================
- // = URLs =
- // ============================================================================
- app.getURL = function(name, kvs) {
- var _host = localStorage.getItem("HOST") || app.config.urls.HOST;
- var _path = app.config.urls[name];
- if(!_path) throw "URL:'" + name + "' not exist!";
- var _url = (_host ? _host + "/" : '') + _path;
- if(kvs !== undefined) {
- _url = common.template(_url, kvs);
- }
- return _url;
- };
-
- app._Host = function(host) {
- if(host) {
- localStorage.setItem("HOST", host);
- return app;
- }
- return localStorage.getItem("HOST");
- };
- app._Host.clear = function() {
- localStorage.removeItem("HOST");
- };
- app._Host.sample = "http://localhost:9099/eagle-service";
+/*
+ * 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';
+
+ app.config = {
+ // ============================================================================
+ // = URLs =
+ // ============================================================================
+ urls: {
+ HOST: '..',
+
+ updateEntity: 'rest/entities?serviceName=${serviceName}',
+ queryEntity: 'rest/entities/rowkey?serviceName=${serviceName}&value=${encodedRowkey}',
+ queryEntities: 'rest/list?query=${serviceName}[${condition}]{${values}}&pageSize=100000',
+ deleteEntity: 'rest/entities/delete?serviceName=${serviceName}&byId=true',
+ deleteEntities: 'rest/entities?query=${serviceName}[${condition}]{*}&pageSize=100000',
+
+ queryGroup: 'rest/list?query=${serviceName}[${condition}]<${groupBy}>{${values}}&pageSize=100000',
+ querySeries: 'rest/list?query=${serviceName}[${condition}]<${groupBy}>{${values}}&pageSize=100000&timeSeries=true&intervalmin=${intervalmin}',
+
+ query: 'rest/',
+
+ userProfile: 'rest/authentication',
+ logout: 'logout',
+
+ DELETE_HOOK: {
+ FeatureDescService: 'rest/module/feature?feature=${feature}',
+ ApplicationDescService: 'rest/module/application?application=${application}',
+ SiteDescService: 'rest/module/site?site=${site}'
+ },
+ UPDATE_HOOK: {
+ SiteDescService: 'rest/module/siteApplication'
+ }
+ },
+ };
+
+ // ============================================================================
+ // = URLs =
+ // ============================================================================
+ app.getURL = function(name, kvs) {
+ var _host = localStorage.getItem("HOST") || app.config.urls.HOST;
+ var _path = app.config.urls[name];
+ if(!_path) throw "URL:'" + name + "' not exist!";
+ var _url = (_host ? _host + "/" : '') + _path;
+ if(kvs !== undefined) {
+ _url = common.template(_url, kvs);
+ }
+ return _url;
+ };
+
+ function getHookURL(hookType, serviceName) {
+ var _path = app.config.urls[hookType][serviceName];
+ if(!_path) return null;
+
+ var _host = localStorage.getItem("HOST") || app.config.urls.HOST;
+ var _url = (_host ? _host + "/" : '') + _path;
+ return _url;
+ }
+
+ /***
+ * Eagle support delete function to process special entity delete. Which will delete all the relative entity.
+ * @param serviceName
+ */
+ app.getDeleteURL = function(serviceName) {
+ return getHookURL('DELETE_HOOK', serviceName);
+ };
+
+ /***
+ * Eagle support update function to process special entity update. Which will update all the relative entity.
+ * @param serviceName
+ */
+ app.getUpdateURL = function(serviceName) {
+ return getHookURL('UPDATE_HOOK', serviceName);
+ };
+
+ app._Host = function(host) {
+ if(host) {
+ localStorage.setItem("HOST", host);
+ return app;
+ }
+ return localStorage.getItem("HOST");
+ };
+ app._Host.clear = function() {
+ localStorage.removeItem("HOST");
+ };
+ app._Host.sample = "http://localhost:9099/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/app.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/public/js/app.js b/eagle-webservice/src/main/webapp/app/public/js/app.js
index 777844d..e9dfb2a 100644
--- a/eagle-webservice/src/main/webapp/app/public/js/app.js
+++ b/eagle-webservice/src/main/webapp/app/public/js/app.js
@@ -18,693 +18,467 @@
var app = {};
-/* App Module */
-var eagleApp = angular.module('eagleApp', ['ngRoute', 'ngCookies', 'damControllers']);
-
-eagleApp.config(function($routeProvider) {
+(function() {
'use strict';
- $routeProvider.when('/dam/summary', {
- templateUrl : 'partials/dam/summary.html',
- controller : 'summaryCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
-
- // Authorization
- }).when('/dam/login', {
- templateUrl : 'partials/dam/login.html',
- controller : 'authLoginCtrl',
- access: {skipCheck: true},
-
- // Policy
- }).when('/dam/policyList', {
- templateUrl : 'partials/dam/policyList.html',
- controller : 'policyListCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
- }).when('/dam/policyList/:dataSource', {
- templateUrl : 'partials/dam/policyList.html',
- controller : 'policyListCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
- }).when('/dam/policyDetail/', {
- templateUrl : 'partials/dam/policyDetail.html',
- controller : 'policyDetailCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
- }).when('/dam/policyDetail/:encodedRowkey', {
- templateUrl : 'partials/dam/policyDetail.html',
- controller : 'policyDetailCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
- }).when('/dam/policyEdit/:encodedRowkey', {
- templateUrl : 'partials/dam/policyEdit.html',
- controller : 'policyEditCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
- }).when('/dam/policyCreate/', {
- templateUrl : 'partials/dam/policyEdit.html',
- controller : 'policyCreateCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
-
- // Alert
- }).when('/dam/alertList', {
- templateUrl : 'partials/dam/alertList.html',
- controller : 'alertListCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
- }).when('/dam/alertList/:dataSource', {
- templateUrl : 'partials/dam/alertList.html',
- controller : 'alertListCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
- }).when('/dam/alertDetail/:encodedRowkey', {
- templateUrl : 'partials/dam/alertDetail.html',
- controller : 'alertDetailCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
-
- // Stream
- }).when('/dam/streamList', {
- templateUrl : 'partials/dam/streamList.html',
- controller : 'streamListCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
-
- // Site
- }).when('/dam/siteList', {
- templateUrl : 'partials/dam/siteList.html',
- controller : 'siteListCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
- access: {roles: ["ROLE_ADMIN"]},
-
- // Sensitivity
- }).when('/dam/sensitivitySummary', {
- templateUrl : 'partials/dam/sensitivitySummary.html',
- controller : 'sensitivitySummaryCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
- }).when('/dam/sensitivity/:dataSrc', {
- templateUrl : 'partials/dam/sensitivity.html',
- controller : 'sensitivityCtrl',
- reloadOnSearch: false,
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
-
- // User Profile
- }).when('/dam/userProfileList', {
- templateUrl : 'partials/dam/userProfileList.html',
- controller : 'userProfileListCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
- }).when('/dam/userProfileDetail/:user', {
- templateUrl : 'partials/dam/userProfileDetail.html',
- controller : 'userProfileDetailCtrl',
- resolve: {
- site: function(Site) {return Site._promise();},
- auth: function(Authorization) {return Authorization._promise();},
- },
-
- }).otherwise({
- redirectTo : '/dam/summary'
+ /* App Module */
+ var eagleApp = angular.module('eagleApp', ['ngRoute', 'ngAnimate', 'ui.router', 'eagleControllers', 'featureControllers', 'eagle.service']);
+
+ // ======================================================================================
+ // = Feature Module =
+ // ======================================================================================
+ var FN_ARGS = /^[^\(]*\(\s*([^\)]*)\)/m;
+ var FN_ARG_SPLIT = /,/;
+ var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
+ var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
+
+ var featureControllers = angular.module('featureControllers', ['ui.bootstrap', 'eagle.components']);
+ var featureControllerCustomizeHtmlTemplate = {};
+ var featureControllerProvider;
+ var featureProvider;
+
+ featureControllers.config(function ($controllerProvider, $provide) {
+ featureControllerProvider = $controllerProvider;
+ featureProvider = $provide;
});
-});
-
-eagleApp.service('globalContent', function(Entities, $rootScope, $route, $location) {
- 'use strict';
-
- var content = {
- pageTitle: "",
- pageSubTitle: "",
- pageList: [],
- navPath: [],
- navMapping: {},
-
- hideSite: false,
- lockSite: false,
- dataSrcList: [],
+ featureControllers.service("Feature", function($wrapState, PageConfig, ConfigPageConfig, FeaturePageConfig) {
+ var _features = {};
+ var _services = {};
- setConfig: function(config) {
- // Clean up
- content.navPath = [];
-
- // Fill configuration
- $.extend(content, config);
- },
- };
-
- return content;
-});
-
-// Site
-eagleApp.service('Site', function(Authorization, Entities, $rootScope, $route, $location, $q) {
- 'use strict';
-
- var _currentSite;
- var content = {};
-
- content.list = [];
- content.list.set = {};
- content.dataSrcList = [];
-
- content.current = function(site) {
- if(site) {
- var _prev = _currentSite;
- _currentSite = site;
-
- // Broadcast if site update
- if(!_prev || _prev.name !== _currentSite.name) {
- if(sessionStorage) {
- sessionStorage.setItem("site", _currentSite.name);
- }
+ var Feature = function(name, version) {
+ this.name = name;
+ this.version = version;
+ this.features = {};
+ };
- if(!content.hideSite) $route.reload();
+ /***
+ * Inner function. Replace the dependency of constructor.
+ * @param constructor
+ * @private
+ */
+ Feature.prototype._replaceDependencies = function(constructor) {
+ var i, srvName;
+ var _constructor, _$inject;
+ var fnText, argDecl;
+
+ if($.isArray(constructor)) {
+ _constructor = constructor[constructor.length - 1];
+ _$inject = constructor.slice(0, -1);
+ } else if(constructor.$inject) {
+ _constructor = constructor;
+ _$inject = constructor.$inject;
+ } else {
+ _$inject = [];
+ _constructor = constructor;
+ fnText = constructor.toString().replace(STRIP_COMMENTS, '');
+ argDecl = fnText.match(FN_ARGS);
+ $.each(argDecl[1].split(FN_ARG_SPLIT), function(i, arg) {
+ arg.replace(FN_ARG, function(all, underscore, name) {
+ _$inject.push(name);
+ });
+ });
}
- }
- return _currentSite;
- };
- content.find = function(siteName) {
- return common.array.find(siteName, content.list, "name");
- };
- content.url = function(site, url) {
- if(arguments.length == 1) {
- url = site;
- } else {
- content.current(site);
- }
- $location.url(url);
+ _constructor.$inject = _$inject;
- if ($rootScope.$$phase != '$apply' && $rootScope.$$phase != '$digest') {
- $rootScope.$apply();
- }
- };
-
- var _promise;
- content.refresh = function() {
- content.list = [];
- content.list.set = {};
-
- content.dataSrcList = Entities.queryEntities("AlertDataSourceService", '');
- content.dataSrcList._promise.success(function() {
- $.each(content.dataSrcList, function(i, dataSrc) {
- var _site = content.list.set[dataSrc.tags.site];
- if(!_site) {
- _site = content.list.set[dataSrc.tags.site] = {
- name: dataSrc.tags.site,
- dataSrcList: []
- };
- _site.dataSrcList.find = function(dataSrcName) {
- return common.array.find(dataSrcName, _site.dataSrcList, "tags.dataSource");
- };
- content.list.push(_site);
- }
- _site.dataSrcList.push(dataSrc);
+ for(i = 0 ; i < _$inject.length ; i += 1) {
+ srvName = _$inject[i];
+ _$inject[i] = this.features[srvName] || _$inject[i];
+ }
- // UI visible check
- if($.inArray(dataSrc.tags.dataSource, app.config.dataSource.uiInvisibleList) !== -1) {
- dataSrc.hide = true;
- }
- });
+ return _constructor;
+ };
- if(sessionStorage && content.find(sessionStorage.getItem("site"))) {
- content.current(content.find(sessionStorage.getItem("site")));
+ /***
+ * Register a common service for feature usage. Common service will share between the feature. If you are coding customize feature, use 'Feature.service' is the better way.
+ * @param name
+ * @param constructor
+ */
+ Feature.prototype.commonService = function(name, constructor) {
+ if(!_services[name]) {
+ featureProvider.service(name, constructor);
+ _services[name] = this.name;
} else {
- content.current(content.list[0]);
+ throw "Service '" + name + "' has already be registered by feature '" + _services[name] + "'";
}
- });
+ };
- _promise = content.dataSrcList._promise;
- return _promise;
- };
+ /***
+ * Register a service for feature usage.
+ * @param name
+ * @param constructor
+ */
+ Feature.prototype.service = function(name, constructor) {
+ var _serviceName;
+ if(!this.features[name]) {
+ _serviceName = "__FEATURE_" + this.name + "_" + name;
+ featureProvider.service(_serviceName, this._replaceDependencies(constructor));
+ this.features[name] = _serviceName;
+ } else {
+ console.warn("Service '" + name + "' has already be registered.");
+ }
+ };
- content._promise = function() {
- if(!_promise) {
- content.refresh();
- }
- return _promise;
- };
+ /***
+ * Create an navigation item in left navigation bar
+ * @param path
+ * @param title
+ * @param icon use Font Awesome. Needn't with 'fa fa-'.
+ */
+ Feature.prototype.navItem = function(path, title, icon) {
+ title = title || path;
+ icon = icon || "question";
+
+ FeaturePageConfig.addNavItem(this.name, {
+ icon: icon,
+ title: title,
+ url: "#/" + this.name + "/" + path
+ });
+ };
- return content;
-});
+ /***
+ * Register a controller.
+ * @param name
+ * @param constructor
+ */
+ Feature.prototype.controller = function(name, constructor, htmlTemplatePath) {
+ var _name = this.name + "_" + name;
+
+ // Replace feature registered service
+ constructor = this._replaceDependencies(constructor);
+
+ // Register controller
+ featureControllerProvider.register(_name, constructor);
+ if(htmlTemplatePath) {
+ featureControllerCustomizeHtmlTemplate[_name] = htmlTemplatePath;
+ }
-// Authorization
-eagleApp.service('Authorization', function($http, $location, $cookies) {
- 'use strict';
+ return _name;
+ };
- $http.defaults.withCredentials = true;
-
- var _path = "";
- var _userProfile = null;
-
- var content = {
- isLogin: true, // Status mark. Work for UI status check, changed when eagle api return 403 authorization failure.
- needLogin: function() {
- _path = _path || $location.path();
- content.isLogin = false;
- $location.path("/dam/login");
- },
- 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) {
- $location.path(_path || "");
- _path = "";
+ /***
+ * Register a configuration controller for admin usage.
+ * @param name
+ * @param constructor
+ */
+ Feature.prototype.configController = function(name, constructor, htmlTemplatePath) {
+ var _name = "config_" + this.name + "_" + name;
+
+ // Replace feature registered service
+ constructor = this._replaceDependencies(constructor);
+
+ // Register controller
+ featureControllerProvider.register(_name, constructor);
+ if(htmlTemplatePath) {
+ featureControllerCustomizeHtmlTemplate[_name] = htmlTemplatePath;
}
- },
- };
-
- var _promise;
- content.userProfile = {};
- content.isRole = function(role) {
- if(!content.userProfile.roles) return null;
-
- return content.userProfile.roles[role] === true;
- };
-
- content.refresh = 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 _promise;
- };
- content._promise = function() {
- if(!_promise) {
- content.refresh();
- }
- return _promise;
- };
+ return _name;
+ };
- return content;
-});
+ /***
+ * Create an navigation item in left navigation bar for admin configuraion page
+ * @param path
+ * @param title
+ * @param icon use Font Awesome. Needn't with 'fa fa-'.
+ */
+ Feature.prototype.configNavItem = function(path, title, icon) {
+ title = title || path;
+ icon = icon || "question";
+
+ ConfigPageConfig.addNavItem(this.name, {
+ icon: icon,
+ title: title,
+ url: "#/config/" + this.name + "/" + path
+ });
+ };
-eagleApp.service('Entities', function($http, $q, $rootScope, $location, Authorization) {
- 'use strict';
+ // Register
+ featureControllers.register = Feature.register = function(featureName) {
+ _features[featureName] = _features[featureName] || new Feature(featureName);
+ return _features[featureName];
+ };
- // 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;
- }
+ // Page go
+ Feature.go = function(feature, page, filter) {
+ if(!filter) {
+ $wrapState.go("page", {
+ feature: feature,
+ page: page
+ }, 2);
+ } else {
+ $wrapState.go("pageFilter", {
+ feature: feature,
+ page: page,
+ filter: filter
+ }, 2);
+ }
+ };
- // > Values
- if(!kvs.values) {
- kvs.values = "*";
- } else if($.isArray(kvs.values)) {
- kvs.values = $.map(kvs.values, function(field) {
- return (field[0] === "@" ? '' : '@') + field;
- }).join(",");
- }
+ return Feature;
+ });
- var _url = app.getURL(name, kvs);
+ // ======================================================================================
+ // = Router config =
+ // ======================================================================================
+ eagleApp.config(function ($stateProvider, $urlRouterProvider) {
+ // Resolve
+ function _resolve(config) {
+ config = config || {};
- // Fill special parameters
- // > Query by time duration
- if(_addtionalCondition._duration) {
- _endTime = app.time.now();
- _startTime = _endTime.clone().subtract(_addtionalCondition._duration, "ms");
+ var resolve = {
+ Site: function (Site) {
+ return Site._promise();
+ },
+ Authorization: function (Authorization) {
+ if(!config.roleType) {
+ return Authorization._promise();
+ } else {
+ return Authorization.rolePromise(config.roleType);
+ }
+ },
+ Application: function (Application) {
+ return Application._promise();
+ }
+ };
+
+ if(config.featureCheck) {
+ resolve._navigationCheck = function($q, $wrapState, Site, Application) {
+ var _deferred = $q.defer();
+
+ $q.all(Site._promise(), Application._promise()).then(function() {
+ var _match, i, tmpApp;
+ var _site = Site.current();
+ var _app = Application.current();
+
+ // Check application
+ if(_site && (
+ !_app ||
+ !_site.applicationList.set[_app.tags.application] ||
+ !_site.applicationList.set[_app.tags.application].enabled
+ )
+ ) {
+ _match = false;
+
+ for(i = 0 ; i < _site.applicationGroupList.length ; i += 1) {
+ tmpApp = _site.applicationGroupList[i].enabledList[0];
+ if(tmpApp) {
+ _app = Application.current(tmpApp);
+ _match = true;
+ break;
+ }
+ }
+
+ if(!_match) {
+ _app = null;
+ Application.current(null);
+ }
+ }
+ }).finally(function() {
+ _deferred.resolve();
+ });
- // Debug usage. Extend more time duration for end time
- if(_addtionalCondition.__ETD) {
- _endTime.add(_addtionalCondition.__ETD, "ms");
+ return _deferred.promise;
+ };
}
- _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");
+ return resolve;
+ }
- _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");
+ // Router
+ var _featureBase = {
+ templateUrl: function ($stateParams) {
+ var _htmlTemplate = featureControllerCustomizeHtmlTemplate[$stateParams.feature + "_" + $stateParams.page];
+ return "public/feature/" + $stateParams.feature + "/page/" + (_htmlTemplate || $stateParams.page) + ".html?_=" + Math.random();
+ },
+ controllerProvider: function ($stateParams) {
+ return $stateParams.feature + "_" + $stateParams.page;
+ },
+ resolve: _resolve({featureCheck: true}),
+ pageConfig: "FeaturePageConfig"
+ };
- _url += "&startTime=" + _startTimeStr + "&endTime=" + _endTimeStr;
- }
+ $urlRouterProvider.otherwise("/landing");
+ $stateProvider
+ // =================== Landing ===================
+ .state('landing', {
+ url: "/landing",
+ templateUrl: "partials/landing.html?_=" + Math.random(),
+ controller: "landingCtrl",
+ resolve: _resolve({featureCheck: true})
+ })
+
+ // ================ Authorization ================
+ .state('login', {
+ url: "/login",
+ templateUrl: "partials/login.html?_=" + Math.random(),
+ controller: "authLoginCtrl",
+ access: {skipCheck: true}
+ })
+
+ // ================ Configuration ================
+ // Site
+ .state('configSite', {
+ url: "/config/site",
+ templateUrl: "partials/config/site.html?_=" + Math.random(),
+ controller: "configSiteCtrl",
+ pageConfig: "ConfigPageConfig",
+ resolve: _resolve({roleType: 'ROLE_ADMIN'})
+ })
+
+ // Application
+ .state('configApplication', {
+ url: "/config/application",
+ templateUrl: "partials/config/application.html?_=" + Math.random(),
+ controller: "configApplicationCtrl",
+ pageConfig: "ConfigPageConfig",
+ resolve: _resolve({roleType: 'ROLE_ADMIN'})
+ })
+
+ // Feature
+ .state('configFeature', {
+ url: "/config/feature",
+ templateUrl: "partials/config/feature.html?_=" + Math.random(),
+ controller: "configFeatureCtrl",
+ pageConfig: "ConfigPageConfig",
+ resolve: _resolve({roleType: 'ROLE_ADMIN'})
+ })
+
+ // Feature configuration page
+ .state('configFeatureDetail', $.extend({url: "/config/:feature/:page"}, {
+ templateUrl: function ($stateParams) {
+ var _htmlTemplate = featureControllerCustomizeHtmlTemplate[$stateParams.feature + "_" + $stateParams.page];
+ return "public/feature/" + $stateParams.feature + "/page/" + (_htmlTemplate || $stateParams.page) + ".html?_=" + Math.random();
+ },
+ controllerProvider: function ($stateParams) {
+ return "config_" + $stateParams.feature + "_" + $stateParams.page;
+ },
+ pageConfig: "ConfigPageConfig",
+ resolve: _resolve({roleType: 'ROLE_ADMIN'})
+ }))
+
+ // =================== Feature ===================
+ // Dynamic feature page
+ .state('page', $.extend({url: "/:feature/:page"}, _featureBase))
+ .state('pageFilter', $.extend({url: "/:feature/:page/:filter"}, _featureBase))
+ ;
+ });
- // > Query contains metric name
- if(_addtionalCondition._metricName) {
- _url += "&metricName=" + _addtionalCondition._metricName;
- }
+ eagleApp.filter('parseJSON', function () {
+ return function (input, defaultVal) {
+ return common.parseJSON(input, defaultVal);
+ };
+ });
- // > Customize page size
- if(_addtionalCondition._pageSize) {
- _url = _url.replace(/pageSize=\d+/, "pageSize=" + _addtionalCondition._pageSize);
- }
+ eagleApp.filter('split', function () {
+ return function (input, regex) {
+ return input.split(regex);
+ };
+ });
- // AJAX
- var canceler = $q.defer();
- _list._promise = $http.get(_url, {timeout: canceler.promise}).success(function(data) {
- _list.push.apply(_list, data.obj);
- });
- _list._promise.abort = function() {
- canceler.resolve();
+ eagleApp.filter('reverse', function () {
+ return function (items) {
+ return items.slice().reverse();
};
+ });
- _list._promise.then(function() {}, function(data) {
- if(data.status === 403) {
- Authorization.needLogin();
+ // ======================================================================================
+ // = Main Controller =
+ // ======================================================================================
+ eagleApp.controller('MainCtrl', function ($scope, $wrapState, $http, $injector, PageConfig, FeaturePageConfig, Site, Authorization, Entities, nvd3, Application, Feature, UI) {
+ window.site = $scope.Site = Site;
+ window.auth = $scope.Auth = Authorization;
+ window.entities = $scope.Entities = Entities;
+ window.application = $scope.Application = Application;
+ window.pageConfig = $scope.PageConfig = PageConfig;
+ window.featurePageConfig = $scope.FeaturePageConfig = FeaturePageConfig;
+ window.feature = $scope.Feature = Feature;
+ window.ui = $scope.UI = UI;
+ window.nvd3 = nvd3;
+ $scope.app = app;
+ $scope.common = common;
+
+ Object.defineProperty(window, "scope",{
+ get: function() {
+ return angular.element("[ui-view]").scope();
}
});
- 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;
- }
+ // Clean up
+ $scope.$on('$stateChangeStart', function (event, next, nextParam, current, currentParam) {
+ console.log("[Switch] current ->", current, currentParam);
+ console.log("[Switch] next ->", next, nextParam);
+ // Page initialization
+ PageConfig.reset();
- var pkg = {
- _query: _query,
- _post: _post,
-
- updateEntity: function(serviceName, entities, config) {
- config = config || {};
- if(!$.isArray(entities)) entities = [entities];
+ // Dynamic navigation list
+ if(next.pageConfig) {
+ $scope.PageConfig.navConfig = $injector.get(next.pageConfig);
+ } else {
+ $scope.PageConfig.navConfig = {};
+ }
- // Post clone entities
- var _entities = $.map(entities, function(entity) {
- var _entity = {};
+ // Authorization
+ // > Login check
+ if (!common.getValueByPath(next, "access.skipCheck", false)) {
+ if (!Authorization.isLogin) {
+ console.log("[Authorization] Need access. Redirect...");
+ $wrapState.go("login");
+ }
+ }
- // Clone variables
- $.each(entity, function(key, value) {
- // Skip inner variables
- if(!key.match(/^__/)) {
- _entity[key] = entity[key];
+ // > Role control
+ /*var _roles = common.getValueByPath(next, "access.roles", []);
+ if (_roles.length && Authorization.userProfile.roles) {
+ var _roleMatch = false;
+ $.each(_roles, function (i, roleName) {
+ if (Authorization.isRole(roleName)) {
+ _roleMatch = true;
+ return false;
}
});
- // 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();
- }
+ if (!_roleMatch) {
+ $wrapState.path("/dam");
}
+ }*/
+ });
- return _entity;
- });
+ $scope.$on('$stateChangeError', function (event, next, nextParam, current, currentParam, error) {
+ console.error("[Switch] Error", arguments);
+ });
- return _post(app.getURL("updateEntity", {serviceName: serviceName}), _entities);
- },
+ // Get side bar navigation item class
+ $scope.getNavClass = function (page) {
+ var path = page.url.replace(/^#/, '');
- deleteEntity: function(serviceName, entities) {
- if(!$.isArray(entities)) entities = [entities];
+ if ($wrapState.path() === path) {
+ PageConfig.pageTitle = PageConfig.pageTitle || page.title;
+ return "active";
+ } else {
+ return "";
+ }
+ };
- 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}));
- },
-
- 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.success(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]);
- }
+ // Get side bar navigation item class visible
+ $scope.getNavVisible = function (page) {
+ if (!page.roles) return true;
- 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");
- });
+ for (var i = 0; i < page.roles.length; i += 1) {
+ var roleName = page.roles[i];
+ if (Authorization.isRole(roleName)) {
+ return true;
}
- });
- 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;
-});
-
-eagleApp.filter('parseJSON', function() {
- 'use strict';
-
- return function(input, defaultVal) {
- return common.parseJSON(input, defaultVal);
- };
-});
-eagleApp.filter('split', function() {
- 'use strict';
-
- return function(input, regex) {
- return input.split(regex);
- };
-});
-
-eagleApp.filter('reverse', function() {
- 'use strict';
-
- return function(items) {
- return items.slice().reverse();
- };
-});
-
-eagleApp.controller('MainCtrl', function($scope, $location, $http, globalContent, Site, Authorization, Entities, nvd3) {
- 'use strict';
-
- window.globalContent = $scope.globalContent = globalContent;
- window.site = $scope.site = Site;
- window.auth = $scope.auth = Authorization;
- window.entities = $scope.entities = Entities;
- window.nvd3 = nvd3;
- $scope.app = app;
-
- // Clean up
- $scope.$on('$routeChangeStart', function(event, next, current) {
- // Page initialization
- globalContent.pageTitle = "";
- globalContent.pageSubTitle = "";
- globalContent.hideSite = false;
- globalContent.lockSite = false;
- globalContent.hideSidebar = false;
- globalContent.hideUser = false;
+ return false;
+ };
// Authorization
- // > Login check
- if(!common.getValueByPath(next, "access.skipCheck", false)) {
- if(!Authorization.isLogin) {
- $location.path("/dam/login");
- }
- }
-
- // > Role control
- var _roles = common.getValueByPath(next, "access.roles", []);
- if(_roles.length && Authorization.userProfile.roles) {
- var _roleMatch = false;
- $.each(_roles, function(i, roleName) {
- if(Authorization.isRole(roleName)) {
- _roleMatch = true;
- return false;
- }
- });
-
- if(!_roleMatch) {
- $location.path("/dam");
- }
- }
+ $scope.logout = function () {
+ console.log("[Authorization] Logout. Redirect...");
+ Authorization.logout();
+ $wrapState.go("login");
+ };
});
-
- // Get side bar navigation item class
- $scope.getNavClass = function(page) {
- var path = page.url.replace(/^#/, '');
-
- if ($location.path() == path) {
- globalContent.pageTitle = globalContent.pageTitle || page.title;
- return "active";
- } else {
- return "";
- }
- };
-
- // Get side bar navigation item class visible
- $scope.getNavVisible = function(page) {
- if(!page.roles) return true;
-
- for(var i = 0 ; i < page.roles.length ; i += 1) {
- var roleName = page.roles[i];
- if(Authorization.isRole(roleName)) {
- return true;
- }
- }
-
- return false;
- };
-
- // Authorization
- $scope.logout = function() {
- Authorization.logout();
- $location.path("/dam/login");
- };
-});
+})();
\ 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/app.ui.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/public/js/app.ui.js b/eagle-webservice/src/main/webapp/app/public/js/app.ui.js
index 4e0ee6e..28727ba 100644
--- a/eagle-webservice/src/main/webapp/app/public/js/app.ui.js
+++ b/eagle-webservice/src/main/webapp/app/public/js/app.ui.js
@@ -1,66 +1,76 @@
-/*
- * 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() {
- // ================== AdminLTE Update ==================
- var _boxSelect = $.AdminLTE.options.boxWidgetOptions.boxWidgetSelectors;
-
- // Box collapse
- $(document).on("click", _boxSelect.collapse, function(e) {
- if(common.getValueByPath($._data(this), "events.click")) return;
-
- e.preventDefault();
- $.AdminLTE.boxWidget.collapse($(this));
- });
-
- // Box remove
- $(document).on("click", _boxSelect.remove, function(e) {
- if(common.getValueByPath($._data(this), "events.click")) return;
-
- e.preventDefault();
- $.AdminLTE.boxWidget.remove($(this));
- });
-
- // =================== jQuery Update ===================
- // Slide Toggle
- var _slideToggle = $.fn.slideToggle;
- $.fn.slideToggle = function(showOrHide) {
- if(arguments.length === 1 && typeof showOrHide === "boolean") {
- if(showOrHide) {
- this.slideDown();
- } else {
- this.slideUp();
- }
- } else {
- _slideToggle.apply(this, arguments);
- }
- };
-
- // Fade Toggle
- var _fadeToggle = $.fn.fadeToggle;
- $.fn.fadeToggle = function(showOrHide) {
- if(arguments.length === 1 && typeof showOrHide === "boolean") {
- if(showOrHide) {
- this.fadeIn();
- } else {
- this.fadeOut();
- }
- } else {
- _fadeToggle.apply(this, arguments);
- }
- };
+/*
+ * 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() {
+ // ================== AdminLTE Update ==================
+ var _boxSelect = $.AdminLTE.options.boxWidgetOptions.boxWidgetSelectors;
+
+ // Box collapse
+ $(document).on("click", _boxSelect.collapse, function(e) {
+ if(common.getValueByPath($._data(this), "events.click")) return;
+
+ e.preventDefault();
+ $.AdminLTE.boxWidget.collapse($(this));
+ });
+
+ // Box remove
+ $(document).on("click", _boxSelect.remove, function(e) {
+ if(common.getValueByPath($._data(this), "events.click")) return;
+
+ e.preventDefault();
+ $.AdminLTE.boxWidget.remove($(this));
+ });
+
+ // =================== jQuery Update ===================
+ // Slide Toggle
+ var _slideToggle = $.fn.slideToggle;
+ $.fn.slideToggle = function(showOrHide) {
+ if(arguments.length === 1 && typeof showOrHide === "boolean") {
+ if(showOrHide) {
+ this.slideDown();
+ } else {
+ this.slideUp();
+ }
+ } else {
+ _slideToggle.apply(this, arguments);
+ }
+ };
+
+ // Fade Toggle
+ var _fadeToggle = $.fn.fadeToggle;
+ $.fn.fadeToggle = function(showOrHide) {
+ if(arguments.length === 1 && typeof showOrHide === "boolean") {
+ if(showOrHide) {
+ this.fadeIn();
+ } else {
+ this.fadeOut();
+ }
+ } else {
+ _fadeToggle.apply(this, arguments);
+ }
+ };
+
+ // Modal
+ var _modal = $.fn.modal;
+ $.fn.modal = function() {
+ setTimeout(function() {
+ $(this).find("input, textarea").filter(':visible:first').focus();
+ }.bind(this), 500);
+ _modal.apply(this, arguments);
+ return this;
+ };
})();
\ 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/common.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/public/js/common.js b/eagle-webservice/src/main/webapp/app/public/js/common.js
index c5b385f..706eeec 100644
--- a/eagle-webservice/src/main/webapp/app/public/js/common.js
+++ b/eagle-webservice/src/main/webapp/app/public/js/common.js
@@ -1,211 +1,226 @@
-/*
- * 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.
- */
-
-var common = {};
-
-common.template = function (str, list) {
- $.each(list, function(key, value) {
- var _regex = new RegExp("\\$\\{" + key + "\\}", "g");
- str = str.replace(_regex, value);
- });
- return str;
-};
-
-common.getValueByPath = function (unit, path, defaultValue) {
- if(unit === null || unit === undefined) throw "Unit or path can't be empty!";
- if(path === "" || path === null || path === undefined) return unit;
-
- path = path.replace(/\[(\d+)\]/g, ".$1").replace(/^\./, "").split(/\./);
- $.each(path, function(i, path) {
- unit = unit[path];
- if(unit === null || unit === undefined) {
- unit = null;
- return false;
- }
- });
- if(unit === null && defaultValue !== undefined) {
- unit = defaultValue;
- }
- return unit;
-};
-
-common.setValueByPath = function(unit, path, value) {
- if(!unit || typeof path !== "string" || path === "") throw "Unit or path can't be empty!";
-
- var _inArray = false;
- var _end = 0;
- var _start = 0;
- var _unit = unit;
-
- function _nextPath(array) {
- var _key = path.slice(_start, _end);
- if(_inArray) {
- _key = _key.slice(0, -1);
- }
- if(!_unit[_key]) {
- if(array) {
- _unit[_key] = [];
- } else {
- _unit[_key] = {};
- }
- }
- _unit = _unit[_key];
- }
-
- for(; _end < path.length ; _end += 1) {
- if(path[_end] === ".") {
- _nextPath(false);
- _start = _end + 1;
- _inArray = false;
- } else if(path[_end] === "[") {
- _nextPath(true);
- _start = _end + 1;
- _inArray = true;
- }
- }
-
- _unit[path.slice(_start, _inArray ? -1 : _end)] = value;
-
- return unit;
-};
-
-common.parseJSON = function (str, defaultVal) {
- try {
- return JSON.parse(str);
- } catch(err) {
- if(defaultVal === undefined) {
- console.warn("Can't parse JSON: " + str);
- }
- }
- return defaultVal === undefined ? null : defaultVal;
-};
-
-common.isEmpty = function(val) {
- if($.isArray(val)) {
- return val.length === 0;
- } else {
- return val === null || val === undefined;
- }
-};
-
-// ====================== Format ======================
-common.format = {};
-
-/*
- * Format date to string. Support number, string, Date instance. Will auto convert time zone offset(Moment instance will keep time zone).
- */
-common.format.date = function(val, type) {
- if(val === undefined || val === null) return "";
-
- if(typeof val === "number" || typeof val === "string" || val instanceof Date) {
- val = app.time.offset(val);
- }
- switch(type) {
- default:
- return val.format("YYYY-MM-DD HH:mm:ss") + (val.utcOffset() === 0 ? '[UTC]' : '');
- }
-};
-
-// ====================== Array =======================
-common.array = {};
-
-common.array.sum = function(list, path) {
- var _sum = 0;
- if(list) {
- $.each(list, function(i, unit) {
- var _val = common.getValueByPath(unit, path);
- if(typeof _val === "number") {
- _sum += _val;
- }
- });
- }
- return _sum;
-};
-
-common.array.max = function(list, path) {
- var _max = null;
- if(list) {
- $.each(list, function(i, unit) {
- var _val = common.getValueByPath(unit, path);
- if(typeof _val === "number" && (_max === null || _max < _val)) {
- _max = _val;
- }
- });
- }
- return _max;
-};
-
-common.array.bottom = function(list, path, count) {
- var _list = list.slice();
-
- _list.sort(function(a, b) {
- var _a = common.getValueByPath(a, path, null);
- var _b = common.getValueByPath(b, path, null);
-
- if(_a === _b) return 0;
- if(_a < _b || _a === null) {
- return -1;
- } else {
- return 1;
- }
- });
- return !count ? _list : _list.slice(0, count);
-};
-common.array.top = function(list, path, count) {
- var _list = common.array.bottom(list, path);
- _list.reverse();
- return !count ? _list : _list.slice(0, count);
-};
-
-common.array.find = function(val, list, path, findAll) {
- path = path || "";
- var _list = $.grep(list, function(unit) {
- return val === common.getValueByPath(unit, path);
- });
- return findAll ? _list : (_list.length === 0 ? null : _list[0]);
-};
-
-common.array.filter = function(val, list, path) {
- return common.array.find(val, list, path, true);
-};
-
-common.array.count = function(list, val, path) {
- if(arguments.length === 1) {
- return list.length;
- } else {
- return common.array.find(val, list, path, true).length;
- }
-};
-
-common.array.remove = function(val, list) {
- for(var i = 0 ; i < list.length ; i += 1) {
- if(list[i] === val) {
- list.splice(i, 1);
- i -= 1;
- }
- }
-};
-
-// ======================= Map ========================
-common.map = {};
-
-common.map.toArray = function(map) {
- return $.map(map, function(unit) {
- return unit;
- });
+/*
+ * 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.
+ */
+
+var common = {};
+
+common.template = function (str, list) {
+ $.each(list, function(key, value) {
+ var _regex = new RegExp("\\$\\{" + key + "\\}", "g");
+ str = str.replace(_regex, value);
+ });
+ return str;
+};
+
+common.getValueByPath = function (unit, path, defaultValue) {
+ if(unit === null || unit === undefined) throw "Unit or path can't be empty!";
+ if(path === "" || path === null || path === undefined) return unit;
+
+ path = path.replace(/\[(\d+)\]/g, ".$1").replace(/^\./, "").split(/\./);
+ $.each(path, function(i, path) {
+ unit = unit[path];
+ if(unit === null || unit === undefined) {
+ unit = null;
+ return false;
+ }
+ });
+ if(unit === null && defaultValue !== undefined) {
+ unit = defaultValue;
+ }
+ return unit;
+};
+
+common.setValueByPath = function(unit, path, value) {
+ if(!unit || typeof path !== "string" || path === "") throw "Unit or path can't be empty!";
+
+ var _inArray = false;
+ var _end = 0;
+ var _start = 0;
+ var _unit = unit;
+
+ function _nextPath(array) {
+ var _key = path.slice(_start, _end);
+ if(_inArray) {
+ _key = _key.slice(0, -1);
+ }
+ if(!_unit[_key]) {
+ if(array) {
+ _unit[_key] = [];
+ } else {
+ _unit[_key] = {};
+ }
+ }
+ _unit = _unit[_key];
+ }
+
+ for(; _end < path.length ; _end += 1) {
+ if(path[_end] === ".") {
+ _nextPath(false);
+ _start = _end + 1;
+ _inArray = false;
+ } else if(path[_end] === "[") {
+ _nextPath(true);
+ _start = _end + 1;
+ _inArray = true;
+ }
+ }
+
+ _unit[path.slice(_start, _inArray ? -1 : _end)] = value;
+
+ return unit;
+};
+
+common.parseJSON = function (str, defaultVal) {
+ try {
+ str = (str + "").trim();
+ if(Number(str).toString() === str) throw "Number format";
+ return JSON.parse(str);
+ } catch(err) {
+ if(defaultVal === undefined) {
+ console.warn("Can't parse JSON: " + str);
+ }
+ }
+ return defaultVal === undefined ? null : defaultVal;
+};
+
+common.isEmpty = function(val) {
+ if($.isArray(val)) {
+ return val.length === 0;
+ } else {
+ return val === null || val === undefined;
+ }
+};
+
+// ====================== Format ======================
+common.format = {};
+
+/*
+ * Format date to string. Support number, string, Date instance. Will auto convert time zone offset(Moment instance will keep time zone).
+ */
+common.format.date = function(val, type) {
+ if(val === undefined || val === null) return "";
+
+ if(typeof val === "number" || typeof val === "string" || val instanceof Date) {
+ val = app.time.offset(val);
+ }
+ switch(type) {
+ default:
+ return val.format("YYYY-MM-DD HH:mm:ss") + (val.utcOffset() === 0 ? '[UTC]' : '');
+ }
+};
+
+// ====================== Array =======================
+common.array = {};
+
+common.array.sum = function(list, path) {
+ var _sum = 0;
+ if(list) {
+ $.each(list, function(i, unit) {
+ var _val = common.getValueByPath(unit, path);
+ if(typeof _val === "number") {
+ _sum += _val;
+ }
+ });
+ }
+ return _sum;
+};
+
+common.array.max = function(list, path) {
+ var _max = null;
+ if(list) {
+ $.each(list, function(i, unit) {
+ var _val = common.getValueByPath(unit, path);
+ if(typeof _val === "number" && (_max === null || _max < _val)) {
+ _max = _val;
+ }
+ });
+ }
+ return _max;
+};
+
+common.array.bottom = function(list, path, count) {
+ var _list = list.slice();
+
+ _list.sort(function(a, b) {
+ var _a = common.getValueByPath(a, path, null);
+ var _b = common.getValueByPath(b, path, null);
+
+ if(_a === _b) return 0;
+ if(_a < _b || _a === null) {
+ return -1;
+ } else {
+ return 1;
+ }
+ });
+ return !count ? _list : _list.slice(0, count);
+};
+common.array.top = function(list, path, count) {
+ var _list = common.array.bottom(list, path);
+ _list.reverse();
+ return !count ? _list : _list.slice(0, count);
+};
+
+common.array.find = function(val, list, path, findAll) {
+ path = path || "";
+ var _list = $.grep(list, function(unit) {
+ return val === common.getValueByPath(unit, path);
+ });
+ return findAll ? _list : (_list.length === 0 ? null : _list[0]);
+};
+
+common.array.filter = function(val, list, path) {
+ return common.array.find(val, list, path, true);
+};
+
+common.array.count = function(list, val, path) {
+ if(arguments.length === 1) {
+ return list.length;
+ } else {
+ return common.array.find(val, list, path, true).length;
+ }
+};
+
+common.array.remove = function(val, list) {
+ for(var i = 0 ; i < list.length ; i += 1) {
+ if(list[i] === val) {
+ list.splice(i, 1);
+ i -= 1;
+ }
+ }
+};
+
+common.array.insert = function(val, list, index) {
+ list.splice(index, 0, val);
+};
+
+common.array.moveOffset = function(item, list, offset) {
+ var _index = $.inArray(item, list);
+ var _tgtPos = _index + offset;
+ if(_tgtPos < 0 || _tgtPos >= list.length) return;
+
+ common.array.remove(item, list);
+ common.array.insert(item, list, _index + offset);
+};
+
+// ======================= Map ========================
+common.map = {};
+
+common.map.toArray = function(map) {
+ return $.map(map, function(unit) {
+ return unit;
+ });
};
\ 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/ctrl/alertController.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/public/js/ctrl/alertController.js b/eagle-webservice/src/main/webapp/app/public/js/ctrl/alertController.js
deleted file mode 100644
index 2399234..0000000
--- a/eagle-webservice/src/main/webapp/app/public/js/ctrl/alertController.js
+++ /dev/null
@@ -1,128 +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.
- */
-
-// =============================================================
-// = Alert List =
-// =============================================================
-damControllers.controller('alertListCtrl', function(globalContent, Site, damContent, $scope, $routeParams, $interval, $timeout, Entities) {
- 'use strict';
-
- globalContent.setConfig(damContent.config);
- globalContent.pageSubTitle = Site.current().name;
-
- var MAX_PAGESIZE = 10000;
-
- // Initial load
- $scope.dataSource = $routeParams.dataSource;
-
- $scope.alertList = [];
- $scope.alertList.ready = false;
-
- // Load data
- function _loadAlerts() {
- if($scope.alertList._promise) {
- $scope.alertList._promise.abort();
- }
-
- var _list = Entities.queryEntities("AlertService", {
- site: Site.current().name,
- dataSource: $scope.dataSource,
- hostname: null,
- _pageSize: MAX_PAGESIZE,
- _duration: 1000 * 60 * 60 * 24 * 30,
- __ETD: 1000 * 60 * 60 * 24
- });
- $scope.alertList._promise = _list._promise;
- _list._promise.then(function() {
- var index;
-
- if($scope.alertList[0]) {
- // List new alerts
- for(index = 0 ; index < _list.length ; index += 1) {
- var _alert = _list[index];
- _alert.__new = true;
- if(_alert.encodedRowkey === $scope.alertList[0].encodedRowkey) {
- break;
- }
- }
-
- if(index > 0) {
- $scope.alertList.unshift.apply($scope.alertList, _list.slice(0, index));
-
- // Clean up UI highlight
- $timeout(function() {
- $.each(_list, function(i, alert) {
- delete alert.__new;
- });
- }, 100);
- }
- } else {
- // List all alerts
- $scope.alertList.push.apply($scope.alertList, _list);
- }
-
- $scope.alertList.ready = true;
- });
- }
-
- _loadAlerts();
- var _loadInterval = $interval(_loadAlerts, app.time.refreshInterval);
- $scope.$on('$destroy',function(){
- $interval.cancel(_loadInterval);
- });
-});
-
-// =============================================================
-// = Alert Detail =
-// =============================================================
-damControllers.controller('alertDetailCtrl', function(globalContent, Site, damContent, $scope, $routeParams, Entities) {
- 'use strict';
-
- globalContent.setConfig(damContent.config);
- globalContent.pageTitle = "Alert Detail";
- globalContent.navPath = ["Alert List", "Alert Detail"];
- globalContent.lockSite = true;
-
- $scope.common = common;
-
- // Query policy
- $scope.alertList = Entities.queryEntity("AlertService", $routeParams.encodedRowkey);
- $scope.alertList._promise.then(function() {
- if($scope.alertList.length === 0) {
- $.dialog({
- title: "OPS!",
- content: "Alert not found!",
- }, function() {
- location.href = "#/dam/alertList";
- });
- return;
- } else {
- var alert = $scope.alertList[0];
-
- $scope.alert = alert;
- Site.current(Site.find($scope.alert.tags.site));
- console.log($scope.alert);
- }
- });
-
- // UI
- $scope.getMessageTime = function(alert) {
- var _time = common.getValueByPath(alert, "alertContext.properties.timestamp");
- return Number(_time);
- };
-});
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/d37643b0/eagle-webservice/src/main/webapp/app/public/js/ctrl/authController.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/app/public/js/ctrl/authController.js b/eagle-webservice/src/main/webapp/app/public/js/ctrl/authController.js
index 1131ca5..1b4f602 100644
--- a/eagle-webservice/src/main/webapp/app/public/js/ctrl/authController.js
+++ b/eagle-webservice/src/main/webapp/app/public/js/ctrl/authController.js
@@ -16,48 +16,54 @@
* limitations under the License.
*/
-// =============================================================
-// = User Profile List =
-// =============================================================
-damControllers.controller('authLoginCtrl', function(globalContent, Site, Authorization, $scope) {
+(function() {
'use strict';
- globalContent.hideSidebar = true;
- globalContent.hideSite = true;
- globalContent.hideUser = true;
+ var eagleControllers = angular.module('eagleControllers');
+ // =============================================================
+ // = User Profile List =
+ // =============================================================
+ eagleControllers.controller('authLoginCtrl', function (PageConfig, Site, Authorization, Application, $scope) {
+ PageConfig.hideSidebar = true;
+ PageConfig.hideApplication = true;
+ PageConfig.hideSite = true;
+ PageConfig.hideUser = true;
- $scope.username = "";
- $scope.password = "";
- $scope.lock = false;
+ $scope.username = "";
+ $scope.password = "";
+ $scope.lock = false;
- // UI
- setTimeout(function() {
- $("#username").focus();
- });
+ // UI
+ setTimeout(function () {
+ $("#username").focus();
+ });
- // Login
- $scope.login = function(event, forceSubmit) {
- if($scope.lock) return;
+ // Login
+ $scope.login = function (event, forceSubmit) {
+ if ($scope.lock) return;
- if(event.which === 13 || forceSubmit) {
- $scope.lock = true;
+ if (event.which === 13 || forceSubmit) {
+ $scope.lock = true;
- Authorization.login($scope.username, $scope.password).then(function(success) {
- if(success) {
- Site.refresh();
- Authorization.refresh();
- Authorization.path(true);
- } else {
- $.dialog({
- title: "OPS",
- content: "User name or password not correct."
- }).on("hidden.bs.modal", function() {
- $("#username").focus();
- });
- }
- }).finally(function() {
- $scope.lock = false;
- });
- }
- };
-});
\ No newline at end of file
+ Authorization.login($scope.username, $scope.password).then(function (success) {
+ if (success) {
+ console.log("[Login] Login success! Reload data...");
+ Authorization.reload().then(function() {}, function() {console.warn("Site error!");});
+ Application.reload().then(function() {}, function() {console.warn("Site error!");});
+ Site.reload().then(function() {}, function() {console.warn("Site error!");});
+ Authorization.path(true);
+ } else {
+ $.dialog({
+ title: "OPS",
+ content: "User name or password not correct."
+ }).on("hidden.bs.modal", function () {
+ $("#username").focus();
+ });
+ }
+ }).finally(function () {
+ $scope.lock = false;
+ });
+ }
+ };
+ });
+})();
\ No newline at end of file