http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/app/public/feature/metrics/controller.js ---------------------------------------------------------------------- diff --git a/eagle-webservice/src/main/webapp/app/public/feature/metrics/controller.js b/eagle-webservice/src/main/webapp/app/public/feature/metrics/controller.js deleted file mode 100644 index d717ad1..0000000 --- a/eagle-webservice/src/main/webapp/app/public/feature/metrics/controller.js +++ /dev/null @@ -1,571 +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. - */ - -(function() { - 'use strict'; - - var featureControllers = angular.module('featureControllers'); - var feature = featureControllers.register("metrics"); - - // ============================================================== - // = Initialization = - // ============================================================== - - // ============================================================== - // = Function = - // ============================================================== - // Format dashboard unit. Will adjust format with old version and add miss attributes. - feature.service("DashboardFormatter", function() { - return { - parse: function(unit) { - unit = unit || {}; - unit.groups = unit.groups || []; - - $.each(unit.groups, function (i, group) { - group.charts = group.charts || []; - $.each(group.charts, function (i, chart) { - if (!chart.metrics && chart.metric) { - chart.metrics = [{ - aggregations: chart.aggregations, - dataSource: chart.dataSource, - metric: chart.metric - }]; - - delete chart.aggregations; - delete chart.dataSource; - delete chart.metric; - } else if (!chart.metrics) { - chart.metrics = []; - } - }); - }); - - return unit; - } - }; - }); - - // ============================================================== - // = Controller = - // ============================================================== - - // ========================= Dashboard ========================== - feature.navItem("dashboard", "Metrics", "line-chart"); - - feature.controller('dashboard', function(PageConfig, $scope, $http, $q, UI, Site, Authorization, Application, Entities, DashboardFormatter) { - var _siteApp = Site.currentSiteApplication(); - var _druidConfig = _siteApp.configObj.getValueByPath("web.druid"); - var _refreshInterval; - - var _menu_newChart; - - $scope.lock = false; - - $scope.dataSourceListReady = false; - $scope.dataSourceList = []; - $scope.dashboard = { - groups: [] - }; - $scope.dashboardEntity = null; - $scope.dashboardReady = false; - - $scope._newMetricFilter = ""; - $scope._newMetricDataSrc = null; - $scope._newMetricDataMetric = null; - - $scope.tabHolder = {}; - - $scope.endTime = app.time.now(); - $scope.startTime = $scope.endTime.clone(); - - // =================== Initialization =================== - if(!_druidConfig || !_druidConfig.coordinator || !_druidConfig.broker) { - $.dialog({ - title: "OPS", - content: "Druid configuration can't be empty!" - }); - return; - } - - $scope.autoRefreshList = [ - {title: "Last 1 Month", timeDes: "day", getStartTime: function(endTime) {return endTime.clone().subtract(1, "month");}}, - {title: "Last 1 Day", timeDes: "thirty_minute", getStartTime: function(endTime) {return endTime.clone().subtract(1, "day");}}, - {title: "Last 6 Hour", timeDes: "fifteen_minute", getStartTime: function(endTime) {return endTime.clone().subtract(6, "hour");}}, - {title: "Last 2 Hour", timeDes: "fifteen_minute", getStartTime: function(endTime) {return endTime.clone().subtract(2, "hour");}}, - {title: "Last 1 Hour", timeDes: "minute", getStartTime: function(endTime) {return endTime.clone().subtract(1, "hour");}} - ]; - $scope.autoRefreshSelect = $scope.autoRefreshList[2]; - - // ====================== Function ====================== - $scope.setAuthRefresh = function(item) { - $scope.autoRefreshSelect = item; - $scope.refreshAllChart(true); - }; - - $scope.refreshTimeDisplay = function() { - PageConfig.pageSubTitle = common.format.date($scope.startTime) + " ~ " + common.format.date($scope.endTime) + " [refresh interval: 30s]"; - }; - $scope.refreshTimeDisplay(); - - // ======================= Metric ======================= - // Fetch metric data - $http.get(_druidConfig.coordinator + "/druid/coordinator/v1/metadata/datasources", {withCredentials: false}).then(function(data) { - var _endTime = new moment(); - var _startTime = _endTime.clone().subtract(1, "day"); - var _intervals = _startTime.toISOString() + "/" + _endTime.toISOString(); - - $scope.dataSourceList = $.map(data.data, function(dataSrc) { - return { - dataSource: dataSrc, - metricList: [] - }; - }); - - // List dataSource metrics - var _metrixList_promiseList = $.map($scope.dataSourceList, function(dataSrc) { - var _data = JSON.stringify({ - "queryType": "groupBy", - "dataSource": dataSrc.dataSource, - "granularity": "all", - "dimensions": ["metric"], - "aggregations": [ - { - "type":"count", - "name":"count" - } - ], - "intervals": [_intervals] - }); - - return $http.post(_druidConfig.broker + "/druid/v2", _data, {withCredentials: false}).then(function(response) { - dataSrc.metricList = $.map(response.data, function(entity) { - return entity.event.metric; - }); - }); - }); - - $q.all(_metrixList_promiseList).finally(function() { - $scope.dataSourceListReady = true; - - $scope._newMetricDataSrc = $scope.dataSourceList[0]; - $scope._newMetricDataMetric = common.getValueByPath($scope._newMetricDataSrc, "metricList.0"); - }); - }, function() { - $.dialog({ - title: "OPS", - content: "Fetch data source failed. Please check Site Application Metrics configuration." - }); - }); - - // Filter data source - $scope.dataSourceMetricList = function(dataSrc, filter) { - filter = (filter || "").toLowerCase().trim().split(/\s+/); - return $.grep((dataSrc && dataSrc.metricList) || [], function(metric) { - for(var i = 0 ; i < filter.length ; i += 1) { - if(metric.toLowerCase().indexOf(filter[i]) === -1) return false; - } - return true; - }); - }; - - // New metric select - $scope.newMetricSelectDataSource = function(dataSrc) { - if(dataSrc !== $scope._newMetricDataMetric) $scope._newMetricDataMetric = dataSrc.metricList[0]; - $scope._newMetricDataSrc = dataSrc; - }; - $scope.newMetricSelectMetric = function(metric) { - $scope._newMetricDataMetric = metric; - }; - - // Confirm new metric - $scope.confirmSelectMetric = function() { - var group = $scope.tabHolder.selectedPane.data; - var metric = { - dataSource: $scope._newMetricDataSrc.dataSource, - metric: $scope._newMetricDataMetric, - aggregations: ["max"] - }; - $("#metricMDL").modal('hide'); - - if($scope.metricForConfigChart) { - $scope.configPreviewChart.metrics.push(metric); - $scope.refreshChart($scope.configPreviewChart, true, true); - } else { - group.charts.push({ - chart: "line", - metrics: [metric] - }); - $scope.refreshAllChart(); - } - }; - - // ======================== Menu ======================== - function _checkGroupName(entity) { - if(common.array.find(entity.name, $scope.dashboard.groups, "name")) { - return "Group name conflict"; - } - } - - $scope.newGroup = function() { - if($scope.lock) return; - - UI.createConfirm("Group", {}, [{field: "name"}], _checkGroupName).then(null, null, function(holder) { - $scope.dashboard.groups.push({ - name: holder.entity.name, - charts: [] - }); - holder.closeFunc(); - - setTimeout(function() { - $scope.tabHolder.setSelect(holder.entity.name); - }, 0); - }); - }; - - function renameGroup() { - var group = $scope.tabHolder.selectedPane.data; - UI.updateConfirm("Group", {}, [{field: "name", name: "New Name"}], _checkGroupName).then(null, null, function(holder) { - group.name = holder.entity.name; - holder.closeFunc(); - }); - } - - function deleteGroup() { - var group = $scope.tabHolder.selectedPane.data; - UI.deleteConfirm(group.name).then(null, null, function(holder) { - common.array.remove(group, $scope.dashboard.groups); - holder.closeFunc(); - }); - } - - _menu_newChart = {title: "Add Metric", func: function() {$scope.newChart();}}; - Object.defineProperties(_menu_newChart, { - icon: { - get: function() {return $scope.dataSourceListReady ? 'plus' : 'refresh fa-spin';} - }, - disabled: { - get: function() {return !$scope.dataSourceListReady;} - } - }); - - $scope.menu = Authorization.isRole('ROLE_ADMIN') ? [ - {icon: "cog", title: "Configuration", list: [ - _menu_newChart, - {icon: "pencil", title: "Rename Group", func: renameGroup}, - {icon: "trash", title: "Delete Group", danger: true, func: deleteGroup} - ]}, - {icon: "plus", title: "New Group", func: $scope.newGroup} - ] : []; - - // ===================== Dashboard ====================== - $scope.dashboardList = Entities.queryEntities("GenericResourceService", { - site: Site.current().tags.site, - application: Application.current().tags.application - }); - $scope.dashboardList._promise.then(function(list) { - $scope.dashboardEntity = list[0]; - $scope.dashboard = DashboardFormatter.parse(common.parseJSON($scope.dashboardEntity.value)); - $scope.refreshAllChart(); - }).finally(function() { - $scope.dashboardReady = true; - }); - - $scope.saveDashboard = function() { - $scope.lock = true; - - if(!$scope.dashboardEntity) { - $scope.dashboardEntity = { - tags: { - site: Site.current().tags.site, - application: Application.current().tags.application, - name: "/metric_dashboard/dashboard/default" - } - }; - } - $scope.dashboardEntity.value = common.stringify($scope.dashboard); - - Entities.updateEntity("GenericResourceService", $scope.dashboardEntity)._promise.then(function() { - $.dialog({ - title: "Done", - content: "Save success!" - }); - }, function() { - $.dialog({ - title: "POS", - content: "Save failed. Please retry." - }); - }).finally(function() { - $scope.lock = false; - }); - }; - - // ======================= Chart ======================== - $scope.configTargetChart = null; - $scope.configPreviewChart = null; - $scope.metricForConfigChart = false; - $scope.viewChart = null; - - $scope.chartConfig = { - xType: "time" - }; - - $scope.chartTypeList = [ - {icon: "line-chart", chart: "line"}, - {icon: "area-chart", chart: "area"}, - {icon: "bar-chart", chart: "column"}, - {icon: "pie-chart", chart: "pie"} - ]; - - $scope.chartSeriesList = [ - {name: "Min", series: "min"}, - {name: "Max", series: "max"}, - {name: "Avg", series: "avg"}, - {name: "Count", series: "count"}, - {name: "Sum", series: "sum"} - ]; - - $scope.newChart = function() { - $scope.metricForConfigChart = false; - $("#metricMDL").modal(); - }; - - $scope.configPreviewChartMinimumCheck = function() { - $scope.configPreviewChart.min = $scope.configPreviewChart.min === 0 ? undefined : 0; - }; - - $scope.seriesChecked = function(metric, series) { - if(!metric) return false; - return $.inArray(series, metric.aggregations || []) !== -1; - }; - $scope.seriesCheckClick = function(metric, series, chart) { - if(!metric || !chart) return; - if($scope.seriesChecked(metric, series)) { - common.array.remove(series, metric.aggregations); - } else { - metric.aggregations.push(series); - } - $scope.chartSeriesUpdate(chart); - }; - - $scope.chartSeriesUpdate = function(chart) { - chart._data = $.map(chart._oriData, function(groupData, i) { - var metric = chart.metrics[i]; - return $.map(groupData, function(series) { - if($.inArray(series._key, metric.aggregations) !== -1) return series; - }); - }); - }; - - $scope.configAddMetric = function() { - $scope.metricForConfigChart = true; - $("#metricMDL").modal(); - }; - - $scope.configRemoveMetric = function(metric) { - common.array.remove(metric, $scope.configPreviewChart.metrics); - }; - - $scope.getChartConfig = function(chart) { - if(!chart) return null; - - var _config = chart._config = chart._config || $.extend({}, $scope.chartConfig); - _config.yMin = chart.min; - - return _config; - }; - - $scope.configChart = function(chart) { - $scope.configTargetChart = chart; - $scope.configPreviewChart = $.extend({}, chart); - $scope.configPreviewChart.metrics = $.map(chart.metrics, function(metric) { - return $.extend({}, metric, {aggregations: (metric.aggregations || []).slice()}); - }); - delete $scope.configPreviewChart._config; - $("#chartMDL").modal(); - setTimeout(function() { - $(window).resize(); - }, 200); - }; - - $scope.confirmUpdateChart = function() { - $("#chartMDL").modal('hide'); - $.extend($scope.configTargetChart, $scope.configPreviewChart); - $scope.chartSeriesUpdate($scope.configTargetChart); - if($scope.configTargetChart._holder) $scope.configTargetChart._holder.refreshAll(); - $scope.configPreviewChart = null; - }; - - $scope.deleteChart = function(group, chart) { - UI.deleteConfirm(chart.metric).then(null, null, function(holder) { - common.array.remove(chart, group.charts); - holder.closeFunc(); - $scope.refreshAllChart(false, true); - }); - }; - - $scope.showChart = function(chart) { - $scope.viewChart = chart; - $("#chartViewMDL").modal(); - setTimeout(function() { - $(window).resize(); - }, 200); - }; - - $scope.refreshChart = function(chart, forceRefresh, refreshAll) { - var _intervals = $scope.startTime.toISOString() + "/" + $scope.endTime.toISOString(); - - function _refreshChart() { - if (chart._holder) { - if (refreshAll) { - chart._holder.refreshAll(); - } else { - chart._holder.refresh(); - } - } - } - - var _tmpData, _metricPromiseList; - - if (chart._data && !forceRefresh) { - // Refresh chart without reload - _refreshChart(); - } else { - // Refresh chart with reload - _tmpData = []; - _metricPromiseList = $.map(chart.metrics, function (metric, k) { - // Each Metric - var _query = JSON.stringify({ - "queryType": "groupBy", - "dataSource": metric.dataSource, - "granularity": $scope.autoRefreshSelect.timeDes, - "dimensions": ["metric"], - "filter": {"type": "selector", "dimension": "metric", "value": metric.metric}, - "aggregations": [ - { - "type": "max", - "name": "max", - "fieldName": "maxValue" - }, - { - "type": "min", - "name": "min", - "fieldName": "maxValue" - }, - { - "type": "count", - "name": "count", - "fieldName": "maxValue" - }, - { - "type": "longSum", - "name": "sum", - "fieldName": "maxValue" - } - ], - "postAggregations" : [ - { - "type": "javascript", - "name": "avg", - "fieldNames": ["sum", "count"], - "function": "function(sum, cnt) { return sum / cnt;}" - } - ], - "intervals": [_intervals] - }); - - return $http.post(_druidConfig.broker + "/druid/v2", _query, {withCredentials: false}).then(function (response) { - var _data = nvd3.convert.druid([response.data]); - _tmpData[k] = _data; - - // Process series name - $.each(_data, function(i, series) { - series._key = series.key; - if(chart.metrics.length > 1) { - series.key = metric.metric.replace(/^.*\./, "") + "-" +series._key; - } - }); - }); - }); - - $q.all(_metricPromiseList).then(function() { - chart._oriData = _tmpData; - $scope.chartSeriesUpdate(chart); - _refreshChart(); - }); - } - }; - - $scope.refreshAllChart = function(forceRefresh, refreshAll) { - setTimeout(function() { - $scope.endTime = app.time.now(); - $scope.startTime = $scope.autoRefreshSelect.getStartTime($scope.endTime); - - $scope.refreshTimeDisplay(); - - $.each($scope.dashboard.groups, function (i, group) { - $.each(group.charts, function (j, chart) { - $scope.refreshChart(chart, forceRefresh, refreshAll); - }); - }); - - $(window).resize(); - }, 0); - }; - - $scope.chartSwitchRefresh = function(source, target) { - var _oriSize = source.size; - source.size = target.size; - target.size = _oriSize; - - if(source._holder) source._holder.refreshAll(); - if(target._holder) target._holder.refreshAll(); - - }; - - _refreshInterval = setInterval(function() { - if(!$scope.dashboardReady) return; - $scope.refreshAllChart(true); - }, 1000 * 30); - - // > Chart UI - $scope.configChartSize = function(chart, sizeOffset) { - chart.size = (chart.size || 6) + sizeOffset; - if(chart.size <= 0) chart.size = 1; - if(chart.size > 12) chart.size = 12; - setTimeout(function() { - $(window).resize(); - }, 1); - }; - - // ========================= UI ========================= - $("#metricMDL").on('hidden.bs.modal', function () { - if($(".modal-backdrop").length) { - $("body").addClass("modal-open"); - } - }); - - $("#chartViewMDL").on('hidden.bs.modal', function () { - $scope.viewChart = null; - }); - - // ====================== Clean Up ====================== - $scope.$on('$destroy', function() { - clearInterval(_refreshInterval); - }); - }); -})(); \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/app/public/feature/metrics/page/dashboard.html ---------------------------------------------------------------------- diff --git a/eagle-webservice/src/main/webapp/app/public/feature/metrics/page/dashboard.html b/eagle-webservice/src/main/webapp/app/public/feature/metrics/page/dashboard.html deleted file mode 100644 index 2acb954..0000000 --- a/eagle-webservice/src/main/webapp/app/public/feature/metrics/page/dashboard.html +++ /dev/null @@ -1,250 +0,0 @@ -<!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<div class="page-fixed"> - <div class="dropdown inline"> - <button data-toggle="dropdown" class="btn btn-primary"> - <span class="fa fa-clock-o"></span> {{autoRefreshSelect.title}} - </button> - <ul class="dropdown-menu left"> - <li ng-repeat="item in autoRefreshList track by $index"> - <a ng-click="setAuthRefresh(item)"> - <span class="fa fa-clock-o"></span> - <span ng-class="{'text-bold': item === autoRefreshSelect}">{{item.title}}</span> - </a> - </li> - </ul> - </div> - - <button class="btn btn-primary" ng-if="Auth.isRole('ROLE_ADMIN')" - ng-click="saveDashboard()" ng-disabled="lock"> - <span class="fa fa-floppy-o"></span> Save - </button> -</div> - -<div class="box box-default" ng-if="!dashboard.groups.length"> - <div class="box-header with-border"> - <h3 class="box-title">Empty Dashboard</h3> - </div> - <div class="box-body"> - <div ng-show="!dashboardReady"> - Loading... - </div> - <div ng-show="dashboardReady"> - Current dashboard is empty. - <span ng-if="Auth.isRole('ROLE_ADMIN')">Click <a ng-click="newGroup()">here</a> to create a new group.</span> - </div> - </div> - <div class="overlay" ng-show="!dashboardReady"> - <i class="fa fa-refresh fa-spin"></i> - </div> -</div> - -<div tabs menu="menu" holder="tabHolder" ng-show="dashboard.groups.length" data-sortable-model="Auth.isRole('ROLE_ADMIN') ? dashboard.groups : null"> - <pane ng-repeat="group in dashboard.groups" data-data="group" data-title="{{group.name}}"> - <div uie-sortable ng-model="group.charts" class="row narrow" sortable-update-func="chartSwitchRefresh" ng-show="group.charts.length"> - <div ng-repeat="chart in group.charts track by $index" class="col-md-{{chart.size || 6}}"> - <div class="nvd3-chart-wrapper"> - <div nvd3="chart._data" data-holder="chart._holder" data-title="{{chart.title || chart.metrics[0].metric}}" data-watching="false" - data-chart="{{chart.chart || 'line'}}" data-config="getChartConfig(chart)" class="nvd3-chart-cntr"></div> - <div class="nvd3-chart-config"> - <a class="fa fa-expand" ng-click="showChart(chart, -1)"></a> - <span ng-if="Auth.isRole('ROLE_ADMIN')"> - <a class="fa fa-minus" ng-click="configChartSize(chart, -1)"></a> - <a class="fa fa-plus" ng-click="configChartSize(chart, 1)"></a> - <a class="fa fa-cog" ng-click="configChart(chart)"></a> - <a class="fa fa-trash" ng-click="deleteChart(group, chart)"></a> - </span> - </div> - </div> - </div> - </div> - - <p ng-if="!group.charts.length"> - Empty group. - <span ng-if="Auth.isRole('ROLE_ADMIN')"> - Click - <span ng-hide="dataSourceListReady" class="fa fa-refresh fa-spin"></span> - <a ng-show="dataSourceListReady" ng-click="newChart()">here</a> - to add metric. - </span> - </p> - </pane> -</div> - - - -<!-- Modal: Chart configuration --> -<div class="modal fade" id="chartMDL" 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">Chart Configuration</h4> - </div> - <div class="modal-body"> - <div class="row"> - <div class="col-md-6"> - <div class="nvd3-chart-wrapper"> - <div nvd3="configPreviewChart._data" data-title="{{configPreviewChart.title || configPreviewChart.metrics[0].metric}}" - data-watching="true" data-chart="{{configPreviewChart.chart || 'line'}}" data-config="getChartConfig(configPreviewChart)" class="nvd3-chart-cntr"></div> - </div> - </div> - <div class="col-md-6"> - <!-- Chart Configuration --> - <table class="table"> - <tbody> - <tr> - <th width="100">Name</th> - <td><input type="text" class="form-control input-xs" ng-model="configPreviewChart.title" placeholder="Default: {{configPreviewChart.metrics[0].metric}}" /></td> - </tr> - <tr> - <th>Chart Type</th> - <td> - <div class="btn-group" data-toggle="buttons"> - <label class="btn btn-default btn-xs" ng-class="{active: (configPreviewChart.chart || 'line') === type.chart}" - ng-repeat="type in chartTypeList track by $index" ng-click="configPreviewChart.chart = type.chart;"> - <input type="radio" name="chartType" autocomplete="off" - ng-checked="(configPreviewChart.chart || 'line') === type.chart"> - <span class="fa fa-{{type.icon}}"></span> - </label> - </div> - </td> - </tr> - <tr> - <th>Minimum</th> - <td><input type="checkbox" ng-checked="configPreviewChart.min === 0" ng-disabled="configPreviewChart.chart === 'area' || configPreviewChart.chart === 'pie'" - ng-click="configPreviewChartMinimumCheck()" /></td> - </tr> - <tr> - <th>Metrics</th> - <td> - <div ng-repeat="metric in configPreviewChart.metrics" class="box inner-box"> - <div class="box-tools"> - <button class="btn btn-box-tool" ng-click="configRemoveMetric(metric)"> - <span class="fa fa-times"></span> - </button> - </div> - - <h3 class="box-title">{{metric.metric}}</h3> - <div class="checkbox noMargin" ng-repeat="series in chartSeriesList track by $index"> - <label> - <input type="checkbox" ng-checked="seriesChecked(metric, series.series)" - ng-click="seriesCheckClick(metric, series.series, configPreviewChart)" /> - {{series.name}} - </label> - </div> - </div> - <a ng-click="configAddMetric()">+ Add Metric</a> - </td> - </tr> - </tbody> - </table> - </div> - </div> - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-default" data-dismiss="modal"> - Close - </button> - <button type="button" class="btn btn-primary" ng-click="confirmUpdateChart()"> - Confirm - </button> - </div> - </div> - </div> -</div> - - - -<!-- Modal: Metric selector --> -<div class="modal fade" id="metricMDL" 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">Select Metric</h4> - </div> - <div class="modal-body"> - <div class="input-group" style="margin-bottom: 10px;"> - <input type="text" class="form-control" placeholder="Filter..." ng-model="_newMetricFilter" /> - <span class="input-group-btn"> - <button class="btn btn-default btn-flat" ng-click="_newMetricFilter = '';"><span class="fa fa-times"></span></button> - </span> - </div> - - <div class="row"> - <div class="col-md-4"> - <ul class="nav nav-pills nav-stacked fixed-height"> - <li class="disabled"><a>Data Source</a></li> - <li ng-repeat="dataSrc in dataSourceList track by $index" ng-class="{active: _newMetricDataSrc === dataSrc}"> - <a ng-click="newMetricSelectDataSource(dataSrc)">{{dataSrc.dataSource}}</a> - </li> - </ul> - </div> - <div class="col-md-8"> - <ul class="nav nav-pills nav-stacked fixed-height"> - <li class="disabled"><a>Metric</a></li> - <li ng-repeat="metric in dataSourceMetricList(_newMetricDataSrc, _newMetricFilter) track by $index" ng-class="{active: _newMetricDataMetric === metric}"> - <a ng-click="newMetricSelectMetric(metric)">{{metric}}</a> - </li> - </ul> - </div> - </div> - </div> - <div class="modal-footer"> - <span class="text-primary pull-left">{{_newMetricDataSrc.dataSource}} <span class="fa fa-arrow-right"></span> {{_newMetricDataMetric}}</span> - <button type="button" class="btn btn-default" data-dismiss="modal"> - Close - </button> - <button type="button" class="btn btn-primary" ng-click="confirmSelectMetric()"> - Select - </button> - </div> - </div> - </div> -</div> - - - -<!-- Modal: Chart View --> -<div class="modal fade" id="chartViewMDL" 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">{{viewChart.title || viewChart.metrics[0].metric}}</h4> - </div> - <div class="modal-body"> - <div nvd3="viewChart._data" data-title="{{viewChart.title || viewChart.metrics[0].metric}}" - data-watching="true" data-chart="{{viewChart.chart || 'line'}}" data-config="getChartConfig(viewChart)" class="nvd3-chart-cntr lg"></div> - </div> - <div class="modal-footer"> - <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/afb89794/eagle-webservice/src/main/webapp/app/public/feature/topology/controller.js ---------------------------------------------------------------------- diff --git a/eagle-webservice/src/main/webapp/app/public/feature/topology/controller.js b/eagle-webservice/src/main/webapp/app/public/feature/topology/controller.js deleted file mode 100644 index 94886c9..0000000 --- a/eagle-webservice/src/main/webapp/app/public/feature/topology/controller.js +++ /dev/null @@ -1,257 +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. - */ - -(function() { - 'use strict'; - - var featureControllers = angular.module('featureControllers'); - var feature = featureControllers.register("topology", { - global: true // Global Feature needn't add to applications - }); - - // ============================================================== - // = Initialization = - // ============================================================== - - // ============================================================== - // = Function = - // ============================================================== - //feature.service("DashboardFormatter", function() { - //}); - - // ============================================================== - // = Controller = - // ============================================================== - feature.configNavItem("monitoring", "Topology", "usb"); - - // ========================= Monitoring ========================= - feature.configController('monitoring', function(PageConfig, $scope, $interval, Entities, UI, Site, Application) { - var topologyRefreshInterval; - - PageConfig.hideApplication = true; - PageConfig.hideSite = true; - PageConfig.pageTitle = "Topology Execution"; - - $scope.topologyExecutionList = null; - - $scope.currentTopologyExecution = null; - $scope.currentTopologyExecutionOptList = []; - - // ======================= Function ======================= - function refreshExecutionList() { - var _list = Entities.queryEntities("TopologyExecutionService"); - _list._promise.then(function () { - $scope.topologyExecutionList = _list; - }); - } - - $scope.showTopologyDetail = function (topologyExecution) { - $scope.currentTopologyExecution = topologyExecution; - $("#topologyMDL").modal(); - - $scope.currentTopologyExecutionOptList = Entities.queryEntities("TopologyOperationService", { - site: topologyExecution.tags.site, - application: topologyExecution.tags.application, - topology: topologyExecution.tags.topology, - _pageSize: 10, - _duration: 1000 * 60 * 60 * 24 * 30 - }); - }; - - $scope.getStatusClass = function (status) { - switch (status) { - case "NEW": - return "info"; - case "STARTING": - case "STOPPING": - return "warning"; - case "STARTED": - return "success"; - case "STOPPED": - return "danger"; - default: - return "default"; - } - }; - - // ==================== Initialization ==================== - refreshExecutionList(); - topologyRefreshInterval = $interval(refreshExecutionList, 10 * 1000); - - $scope.topologyList = Entities.queryEntities("TopologyDescriptionService"); - $scope.topologyList._promise.then(function () { - $scope.topologyList = $.map($scope.topologyList, function (topology) { - return topology.tags.topology; - }); - }); - - $scope.applicationList = $.map(Application.list, function (application) { - return application.tags.application; - }); - - $scope.siteList = $.map(Site.list, function (site) { - return site.tags.site; - }); - - // ================== Topology Execution ================== - $scope.newTopologyExecution = function () { - UI.createConfirm("Topology", {}, [ - {field: "site", type: "select", valueList: $scope.siteList}, - {field: "application", type: "select", valueList: $scope.applicationList}, - {field: "topology", type: "select", valueList: $scope.topologyList} - ], function (entity) { - for(var i = 0 ; i < $scope.topologyExecutionList.length; i += 1) { - var _entity = $scope.topologyExecutionList[i].tags; - if(_entity.site === entity.site && _entity.application === entity.application && _entity.topology === entity.topology) { - return "Topology already exist!"; - } - } - }).then(null, null, function(holder) { - var _entity = { - tags: { - site: holder.entity.site, - application: holder.entity.application, - topology: holder.entity.topology - }, - status: "NEW" - }; - Entities.updateEntity("TopologyExecutionService", _entity)._promise.then(function() { - holder.closeFunc(); - $scope.topologyExecutionList.push(_entity); - refreshExecutionList(); - }); - }); - }; - - $scope.deleteTopologyExecution = function (topologyExecution) { - UI.deleteConfirm(topologyExecution.tags.topology).then(null, null, function(holder) { - Entities.deleteEntities("TopologyExecutionService", topologyExecution.tags)._promise.then(function() { - holder.closeFunc(); - common.array.remove(topologyExecution, $scope.topologyExecutionList); - }); - }); - }; - - // ================== Topology Operation ================== - $scope.doTopologyOperation = function (topologyExecution, operation) { - $.dialog({ - title: operation + " Confirm", - content: "Do you want to " + operation + " '" + topologyExecution.tags.topology + "'?", - confirm: true - }, function (ret) { - if(!ret) return; - - var list = Entities.queryEntities("TopologyOperationService", { - site: topologyExecution.tags.site, - application: topologyExecution.tags.application, - topology: topologyExecution.tags.topology, - _pageSize: 20 - }); - - list._promise.then(function () { - var lastOperation = common.array.find(operation, list, "tags.operation"); - if(lastOperation && (lastOperation.status === "INITIALIZED" || lastOperation.status === "PENDING")) { - refreshExecutionList(); - return; - } - - Entities.updateEntity("rest/app/operation", { - tags: { - site: topologyExecution.tags.site, - application: topologyExecution.tags.application, - topology: topologyExecution.tags.topology, - operation: operation - }, - status: "INITIALIZED" - }, {timestamp: false, hook: true}); - }); - }); - }; - - $scope.startTopologyOperation = function (topologyExecution) { - $scope.doTopologyOperation(topologyExecution, "START"); - }; - $scope.stopTopologyOperation = function (topologyExecution) { - $scope.doTopologyOperation(topologyExecution, "STOP"); - }; - - // ======================= Clean Up ======================= - $scope.$on('$destroy', function() { - $interval.cancel(topologyRefreshInterval); - }); - }); - - // ========================= Management ========================= - feature.configController('management', function(PageConfig, $scope, Entities, UI) { - PageConfig.hideApplication = true; - PageConfig.hideSite = true; - PageConfig.pageTitle = "Topology"; - - var typeList = ["CLASS", "DYNAMIC"]; - var topologyDefineAttrs = [ - {field: "topology", name: "name"}, - {field: "type", type: "select", valueList: typeList}, - {field: "exeClass", name: "execution entry", description: function (entity) { - if(entity.type === "CLASS") return "Class implements interface TopologyExecutable"; - if(entity.type === "DYNAMIC") return "DSL based topology definition"; - }, type: "blob", rows: 5}, - {field: "version", optional: true}, - {field: "description", optional: true, type: "blob"} - ]; - var topologyUpdateAttrs = $.extend(topologyDefineAttrs.concat(), [{field: "topology", name: "name", readonly: true}]); - - $scope.topologyList = Entities.queryEntities("TopologyDescriptionService"); - - $scope.newTopology = function () { - UI.createConfirm("Topology", {}, topologyDefineAttrs, function (entity) { - if(common.array.find(entity.topology, $scope.topologyList, "tags.topology", false, false)) { - return "Topology name conflict!"; - } - }).then(null, null, function(holder) { - holder.entity.tags = { - topology: holder.entity.topology - }; - Entities.updateEntity("TopologyDescriptionService", holder.entity, {timestamp: false})._promise.then(function() { - holder.closeFunc(); - $scope.topologyList.push(holder.entity); - }); - }); - }; - - $scope.updateTopology = function (topology) { - UI.updateConfirm("Topology", $.extend({}, topology, {topology: topology.tags.topology}), topologyUpdateAttrs).then(null, null, function(holder) { - holder.entity.tags = { - topology: holder.entity.topology - }; - Entities.updateEntity("TopologyDescriptionService", holder.entity, {timestamp: false})._promise.then(function() { - holder.closeFunc(); - $.extend(topology, holder.entity); - }); - }); - }; - - $scope.deleteTopology = function (topology) { - UI.deleteConfirm(topology.tags.topology).then(null, null, function(holder) { - Entities.delete("TopologyDescriptionService", {topology: topology.tags.topology})._promise.then(function() { - holder.closeFunc(); - common.array.remove(topology, $scope.topologyList); - }); - }); - }; - }); -})(); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/app/public/feature/topology/page/management.html ---------------------------------------------------------------------- diff --git a/eagle-webservice/src/main/webapp/app/public/feature/topology/page/management.html b/eagle-webservice/src/main/webapp/app/public/feature/topology/page/management.html deleted file mode 100644 index 9e22c84..0000000 --- a/eagle-webservice/src/main/webapp/app/public/feature/topology/page/management.html +++ /dev/null @@ -1,52 +0,0 @@ -<div class="box box-primary"> - <div class="box-header with-border"> - <i class="fa fa-cog"></i> - <a class="pull-right" href="#/config/topology/monitoring"><span class="fa fa-angle-right"></span> Monitoring</a> - <h3 class="box-title"> - Management - </h3> - </div> - <div class="box-body"> - <table class="table table-bordered"> - <thead> - <tr> - <th>Name</th> - <th width="20%">Execution Class</th> - <th>Type</th> - <th width="50%">Description</th> - <th>Version</th> - <th width="70"></th> - </tr> - </thead> - <tbody> - <tr ng-repeat="item in topologyList"> - <td>{{item.tags.topology}}</td> - <td><pre class="noWrap">{{item.exeClass}}</pre></td> - <td>{{item.type}}</td> - <td>{{item.description}}</td> - <td>{{item.version}}</td> - <td class="text-center"> - <button class="rm fa fa-pencil btn btn-default btn-xs" uib-tooltip="Edit" tooltip-animation="false" ng-click="updateTopology(item)"> </button> - <button class="rm fa fa-trash-o btn btn-danger btn-xs" uib-tooltip="Delete" tooltip-animation="false" ng-click="deleteTopology(item)"> </button> - </td> - </tr> - <tr ng-if="topologyList.length === 0"> - <td colspan="6"> - <span class="text-muted">Empty list</span> - </td> - </tr> - </tbody> - </table> - </div> - - <div class="box-footer"> - <button class="btn btn-primary pull-right" ng-click="newTopology()"> - New Topology - <i class="fa fa-plus-circle"> </i> - </button> - </div> - - <div class="overlay" ng-hide="topologyList._promise.$$state.status === 1;"> - <i class="fa fa-refresh fa-spin"></i> - </div> -</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/app/public/feature/topology/page/monitoring.html ---------------------------------------------------------------------- diff --git a/eagle-webservice/src/main/webapp/app/public/feature/topology/page/monitoring.html b/eagle-webservice/src/main/webapp/app/public/feature/topology/page/monitoring.html deleted file mode 100644 index 0acb2c1..0000000 --- a/eagle-webservice/src/main/webapp/app/public/feature/topology/page/monitoring.html +++ /dev/null @@ -1,151 +0,0 @@ -<div class="box box-primary"> - <div class="box-header with-border"> - <i class="fa fa-eye"></i> - <a class="pull-right" href="#/config/topology/management"><span class="fa fa-angle-right"></span> Management</a> - <h3 class="box-title"> - Monitoring - </h3> - </div> - <div class="box-body"> - <div sorttable source="topologyExecutionList"> - <table class="table table-bordered" ng-non-bindable> - <thead> - <tr> - <th width="70" sortpath="status">Status</th> - <th width="90" sortpath="tags.topology">Topology</th> - <th width="60" sortpath="tags.site">Site</th> - <th width="100" sortpath="tags.application">Application</th> - <th width="60" sortpath="mode">Mode</th> - <th sortpath="description">Description</th> - <th width="70" style="min-width: 70px;"></th> - </tr> - </thead> - <tbody> - <tr> - <td class="text-center"> - <span class="label label-{{_parent.getStatusClass(item.status)}}">{{item.status}}</span> - </td> - <td><a ng-click="_parent.showTopologyDetail(item)">{{item.tags.topology}}</a></td> - <td>{{item.tags.site}}</td> - <td>{{item.tags.application}}</td> - <td>{{item.mode}}</td> - <td>{{item.description}}</td> - <td class="text-center"> - <button ng-if="item.status === 'NEW' || item.status === 'STOPPED'" class="fa fa-play sm btn btn-default btn-xs" uib-tooltip="Start" tooltip-animation="false" ng-click="_parent.startTopologyOperation(item)"> </button> - <button ng-if="item.status === 'STARTED'" class="fa fa-stop sm btn btn-default btn-xs" uib-tooltip="Stop" tooltip-animation="false" ng-click="_parent.stopTopologyOperation(item)"> </button> - <button ng-if="item.status !== 'NEW' && item.status !== 'STARTED' && item.status !== 'STOPPED'" class="fa fa-ban sm btn btn-default btn-xs" disabled="disabled"> </button> - <button class="rm fa fa-trash-o btn btn-danger btn-xs" uib-tooltip="Delete" tooltip-animation="false" ng-click="_parent.deleteTopologyExecution(item)"> </button> - </td> - </tr> - </tbody> - </table> - </div> - </div> - - <div class="box-footer"> - <button class="btn btn-primary pull-right" ng-click="newTopologyExecution()"> - New Topology Execution - <i class="fa fa-plus-circle"> </i> - </button> - </div> - - <div class="overlay" ng-hide="topologyExecutionList._promise.$$state.status === 1;"> - <i class="fa fa-refresh fa-spin"></i> - </div> -</div> - - - - -<!-- Modal: Topology Detail --> -<div class="modal fade" id="topologyMDL" 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">Topology Detail</h4> - </div> - <div class="modal-body"> - <h3>Detail</h3> - <table class="table"> - <tbody> - <tr> - <th>Site</th> - <td>{{currentTopologyExecution.tags.site}}</td> - </tr> - <tr> - <th>Application</th> - <td>{{currentTopologyExecution.tags.application}}</td> - </tr> - <tr> - <th>Topology</th> - <td>{{currentTopologyExecution.tags.topology}}</td> - </tr> - <tr> - <th>Full Name</th> - <td>{{currentTopologyExecution.fullName || "-"}}</td> - </tr> - <tr> - <th>Status</th> - <td> - <span class="label label-{{getStatusClass(currentTopologyExecution.status)}}">{{currentTopologyExecution.status}}</span> - </td> - </tr> - <tr> - <th>Mode</th> - <td>{{currentTopologyExecution.mode || "-"}}</td> - </tr> - <tr> - <th>Environment</th> - <td>{{currentTopologyExecution.environment || "-"}}</td> - </tr> - <tr> - <th>Url</th> - <td> - <a ng-if="currentTopologyExecution.url" href="{{currentTopologyExecution.url}}" target="_blank">{{currentTopologyExecution.url}}</a> - <span ng-if="!currentTopologyExecution.url">-</span> - </td> - </tr> - <tr> - <th>Description</th> - <td>{{currentTopologyExecution.description || "-"}}</td> - </tr> - <tr> - <th>Last Modified Date</th> - <td>{{common.format.date(currentTopologyExecution.lastModifiedDate) || "-"}}</td> - </tr> - </tbody> - </table> - - <h3>Latest Operations</h3> - <div class="table-responsive"> - <table class="table table-bordered table-sm margin-bottom-none"> - <thead> - <tr> - <th>Date Time</th> - <th>Operation</th> - <th>Status</th> - <th>Message</th> - </tr> - </thead> - <tbody> - <tr ng-repeat="action in currentTopologyExecutionOptList track by $index"> - <td>{{common.format.date(action.lastModifiedDate) || "-"}}</td> - <td>{{action.tags.operation}}</td> - <td>{{action.status}}</td> - <td><pre class="noWrap">{{action.message}}</pre></td> - </tr> - </tbody> - </table> - </div> - </div> - <div class="modal-footer"> - <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/afb89794/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 deleted file mode 100644 index ed619d3..0000000 --- a/eagle-webservice/src/main/webapp/app/public/feature/userProfile/controller.js +++ /dev/null @@ -1,268 +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. - */ - -(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, application: "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/afb89794/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 deleted file mode 100644 index 0f94e03..0000000 --- a/eagle-webservice/src/main/webapp/app/public/feature/userProfile/page/detail.html +++ /dev/null @@ -1,87 +0,0 @@ -<!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> -<div class="box box-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/afb89794/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 deleted file mode 100644 index 2f14479..0000000 --- a/eagle-webservice/src/main/webapp/app/public/feature/userProfile/page/list.html +++ /dev/null @@ -1,138 +0,0 @@ -<!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> -<div class="box box-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/afb89794/eagle-webservice/src/main/webapp/app/public/images/favicon.png ---------------------------------------------------------------------- diff --git a/eagle-webservice/src/main/webapp/app/public/images/favicon.png b/eagle-webservice/src/main/webapp/app/public/images/favicon.png deleted file mode 100644 index 3bede2a..0000000 Binary files a/eagle-webservice/src/main/webapp/app/public/images/favicon.png and /dev/null differ http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/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 deleted file mode 100644 index 9879e92..0000000 Binary files a/eagle-webservice/src/main/webapp/app/public/images/favicon_white.png and /dev/null differ http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/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 deleted file mode 100644 index d7c4be9..0000000 --- a/eagle-webservice/src/main/webapp/app/public/js/app.config.js +++ /dev/null @@ -1,126 +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. - */ - -(function() { - 'use strict'; - - app.config = { - // ============================================================================ - // = URLs = - // ============================================================================ - urls: { - HOST: '..', - - updateEntity: 'rest/entities?serviceName=${serviceName}', - queryEntity: 'rest/entities/rowkey?serviceName=${serviceName}&value=${encodedRowkey}', - queryEntities: 'rest/entities?query=${serviceName}[${condition}]{${values}}&pageSize=100000', - deleteEntity: 'rest/entities/delete?serviceName=${serviceName}&byId=true', - deleteEntities: 'rest/entities?query=${serviceName}[${condition}]{*}&pageSize=100000', - - queryGroup: 'rest/entities?query=${serviceName}[${condition}]<${groupBy}>{${values}}&pageSize=100000', - querySeries: 'rest/entities?query=${serviceName}[${condition}]<${groupBy}>{${values}}&pageSize=100000&timeSeries=true&intervalmin=${intervalmin}', - - query: 'rest/', - - userProfile: 'rest/authentication', - logout: 'logout', - - maprNameResolver: '../rest/maprNameResolver', - - DELETE_HOOK: { - FeatureDescService: 'rest/module/feature?feature=${feature}', - ApplicationDescService: 'rest/module/application?application=${application}', - SiteDescService: 'rest/module/site?site=${site}', - TopologyDescriptionService: 'rest/app/topology?topology=${topology}' - }, - UPDATE_HOOK: { - SiteDescService: 'rest/module/siteApplication' - } - }, - }; - - // ============================================================================ - // = URLs = - // ============================================================================ - app.getURL = function(name, kvs) { - var _path = app.config.urls[name]; - if(!_path) throw "URL:'" + name + "' not exist!"; - var _url = app.packageURL(_path); - if(kvs !== undefined) { - _url = common.template(_url, kvs); - } - return _url; - }; - - app.getMapRNameResolverURL = function(name,value, site) { - var key = "maprNameResolver"; - var _path = app.config.urls[key]; - if(!_path) throw "URL:'" + name + "' not exist!"; - var _url = _path; - if(name == "fNameResolver") { - _url += "/" + name + "?fName=" + value + "&site=" + site; - } else if(name == "sNameResolver") { - _url += "/" + name + "?sName=" + value + "&site=" + site; - } else if (name == "vNameResolver") { - _url += "/" + name + "?vName=" + value + "&site=" + site; - } else{ - throw "resolver:'" + name + "' not exist!"; - } - return _url; - }; - - function getHookURL(hookType, serviceName) { - var _path = app.config.urls[hookType][serviceName]; - if(!_path) return null; - - return app.packageURL(_path); - } - - /*** - * 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.packageURL = function (path) { - var _host = localStorage.getItem("HOST") || app.config.urls.HOST; - return (_host ? _host + "/" : '') + path; - }; - - 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/afb89794/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 deleted file mode 100644 index 70b4afe..0000000 --- a/eagle-webservice/src/main/webapp/app/public/js/app.js +++ /dev/null @@ -1,499 +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. - */ - -var app = {}; - -(function() { - 'use strict'; - - /* App Module */ - var eagleApp = angular.module('eagleApp', ['ngRoute', 'ngAnimate', 'ui.router', 'eagleControllers', 'featureControllers', 'eagle.service']); - - // GRUNT REPLACEMENT: eagleApp.buildTimestamp = TIMESTAMP - eagleApp._TRS = function() { - return eagleApp.buildTimestamp || Math.random(); - }; - - // ====================================================================================== - // = 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; - }); - - featureControllers.service("Feature", function($wrapState, PageConfig, ConfigPageConfig, FeaturePageConfig) { - var _features = {}; - var _services = {}; - - var Feature = function(name, config) { - this.name = name; - this.config = config || {}; - this.features = {}; - }; - - /*** - * 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); - }); - }); - } - _constructor.$inject = _$inject; - - for(i = 0 ; i < _$inject.length ; i += 1) { - srvName = _$inject[i]; - _$inject[i] = this.features[srvName] || _$inject[i]; - } - - return _constructor; - }; - - /*** - * 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 { - throw "Service '" + name + "' has already be registered by feature '" + _services[name] + "'"; - } - }; - - /*** - * 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."); - } - }; - - /*** - * 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 - }); - }; - - /*** - * 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; - } - - return _name; - }; - - /*** - * 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; - } - - return _name; - }; - - /*** - * 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 - }); - }; - - // Register - featureControllers.register = Feature.register = function(featureName, config) { - _features[featureName] = _features[featureName] || new Feature(featureName, config); - return _features[featureName]; - }; - - // 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); - } - }; - - // Get feature by name - Feature.get = function (featureName) { - return _features[featureName]; - }; - - return Feature; - }); - - // ====================================================================================== - // = Router config = - // ====================================================================================== - eagleApp.config(function ($stateProvider, $urlRouterProvider, $animateProvider) { - // Resolve - function _resolve(config) { - config = config || {}; - - 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(); - }); - - return _deferred.promise; - }; - } - - return resolve; - } - - // Router - var _featureBase = { - templateUrl: function ($stateParams) { - var _htmlTemplate = featureControllerCustomizeHtmlTemplate[$stateParams.feature + "_" + $stateParams.page]; - return "public/feature/" + $stateParams.feature + "/page/" + (_htmlTemplate || $stateParams.page) + ".html?_=" + eagleApp._TRS(); - }, - controllerProvider: function ($stateParams) { - return $stateParams.feature + "_" + $stateParams.page; - }, - resolve: _resolve({featureCheck: true}), - pageConfig: "FeaturePageConfig" - }; - - $urlRouterProvider.otherwise("/landing"); - $stateProvider - // =================== Landing =================== - .state('landing', { - url: "/landing", - templateUrl: "partials/landing.html?_=" + eagleApp._TRS(), - controller: "landingCtrl", - resolve: _resolve({featureCheck: true}) - }) - - // ================ Authorization ================ - .state('login', { - url: "/login", - templateUrl: "partials/login.html?_=" + eagleApp._TRS(), - controller: "authLoginCtrl", - access: {skipCheck: true} - }) - - // ================ Configuration ================ - // Site - .state('configSite', { - url: "/config/site", - templateUrl: "partials/config/site.html?_=" + eagleApp._TRS(), - controller: "configSiteCtrl", - pageConfig: "ConfigPageConfig", - resolve: _resolve({roleType: 'ROLE_ADMIN'}) - }) - - // Application - .state('configApplication', { - url: "/config/application", - templateUrl: "partials/config/application.html?_=" + eagleApp._TRS(), - controller: "configApplicationCtrl", - pageConfig: "ConfigPageConfig", - resolve: _resolve({roleType: 'ROLE_ADMIN'}) - }) - - // Feature - .state('configFeature', { - url: "/config/feature", - templateUrl: "partials/config/feature.html?_=" + eagleApp._TRS(), - 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?_=" + eagleApp._TRS(); - }, - 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)) - ; - - // Animation - $animateProvider.classNameFilter(/^((?!(fa-spin)).)*$/); - $animateProvider.classNameFilter(/^((?!(tab-pane)).)*$/); - }); - - eagleApp.filter('parseJSON', function () { - return function (input, defaultVal) { - return common.parseJSON(input, defaultVal); - }; - }); - - eagleApp.filter('split', function () { - return function (input, regex) { - return input.split(regex); - }; - }); - - eagleApp.filter('reverse', function () { - return function (items) { - return items.slice().reverse(); - }; - }); - - // ====================================================================================== - // = Main Controller = - // ====================================================================================== - eagleApp.controller('MainCtrl', function ($scope, $wrapState, $http, $injector, ServiceError, PageConfig, FeaturePageConfig, Site, Authorization, Entities, nvd3, Application, Feature, UI) { - window.serviceError = $scope.ServiceError = ServiceError; - 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(); - } - }); - - // 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(); - - // Dynamic navigation list - if(next.pageConfig) { - $scope.PageConfig.navConfig = $injector.get(next.pageConfig); - } else { - $scope.PageConfig.navConfig = {}; - } - - // Authorization - // > Login check - if (!common.getValueByPath(next, "access.skipCheck", false)) { - if (!Authorization.isLogin) { - console.log("[Authorization] Need access. Redirect..."); - $wrapState.go("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) { - $wrapState.path("/dam"); - } - }*/ - }); - - $scope.$on('$stateChangeError', function (event, next, nextParam, current, currentParam, error) { - console.error("[Switch] Error", arguments); - }); - - // Get side bar navigation item class - $scope.getNavClass = function (page) { - var path = page.url.replace(/^#/, ''); - - if ($wrapState.path() === path) { - PageConfig.pageTitle = PageConfig.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 () { - console.log("[Authorization] Logout. Redirect..."); - Authorization.logout(); - $wrapState.go("login"); - }; - }); -})(); \ No newline at end of file