You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@eagle.apache.org by ji...@apache.org on 2016/09/28 05:38:53 UTC
[12/14] incubator-eagle git commit: [EAGLE-574] UI refactor for
support 0.5 api
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/index.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/index.html b/eagle-server/src/main/webapp/app/dev/index.html
new file mode 100644
index 0000000..56850d7
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/index.html
@@ -0,0 +1,250 @@
+<!DOCTYPE html>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<html ng-controller="MainCtrl">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta charset="UTF-8">
+ <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
+ <link rel="shortcut icon" href="public/images/favicon.png">
+
+ <title>Eagle</title>
+ <link rel="shortcut icon" type="image/png" href="public/images/favicon.png">
+
+ <!-- ref:css public/css/doc.css -->
+ <link href="../node_modules/bootstrap/dist/css/bootstrap.css" rel="stylesheet" type="text/css" media="screen">
+ <link href="../node_modules/zombiej-bootstrap-components/bootstrap-components/css/bootstrap-components.css" rel="stylesheet" type="text/css" media="screen">
+
+ <link href="../node_modules/zombiej-nvd3/build/nv.d3.css" rel="stylesheet" type="text/css" />
+
+ <link href="../node_modules/font-awesome/css/font-awesome.css" rel="stylesheet" type="text/css" />
+
+ <link href="../node_modules/admin-lte/dist/css/AdminLTE.css" rel="stylesheet" type="text/css" />
+ <link href="../node_modules/admin-lte/dist/css/skins/skin-blue.css" rel="stylesheet" type="text/css" />
+
+ <link href="public/css/animation.css" rel="stylesheet" type="text/css" media="screen">
+ <link href="public/css/sortTable.css" rel="stylesheet" type="text/css" media="screen">
+ <link href="public/css/main.css" rel="stylesheet" type="text/css" media="screen">
+ <!-- endref -->
+ </head>
+ <body class="skin-blue sidebar-mini" ng-class="{'no-sidebar' : PageConfig.hideSidebar}">
+ <!-- Site wrapper -->
+ <div class="wrapper">
+ <header class="main-header">
+ <a href="#/" class="logo">
+ <span class="logo-mini"><img src="public/images/favicon_white.png" /></span>
+ <span class="logo-lg">Apache Eagle</span>
+ </a>
+ <!-- Header Navbar: style can be found in header.less -->
+ <nav class="navbar navbar-static-top" role="navigation">
+ <!-- Sidebar toggle button-->
+ <a ng-hide="PageConfig.hideSidebar" class="sidebar-toggle" data-toggle="offcanvas" role="button">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </a>
+
+ <div class="navbar-custom-menu">
+ <ul class="nav navbar-nav">
+ <li class="dropdown time-picker" ng-if="Time.pickerType === Time.TIME_RANGE_PICKER">
+ <a data-toggle="dropdown" aria-expanded="false">
+ <i class="fa fa-calendar"></i>
+ {{Time.format("startTime", Time.SHORT_FORMAT)}} ~ {{Time.format("endTime", Time.SHORT_FORMAT)}}
+ </a>
+ <ul class="dropdown-menu">
+ <li><a ng-click="setLastDuration(2)"><i class="fa fa-clock-o"></i>Last 2 Hours</a></li>
+ <li><a ng-click="setLastDuration(6)"><i class="fa fa-clock-o"></i>Last 6 Hours</a></li>
+ <li><a ng-click="setLastDuration(12)"><i class="fa fa-clock-o"></i>Last 12 Hours</a></li>
+ <li><a ng-click="setLastDuration(24)"><i class="fa fa-clock-o"></i>Last 24 Hours</a></li>
+ <li><a ng-click="customizeTimeRange()"><i class="fa fa-clock-o"></i>Customize</a></li>
+ </ul>
+ </li>
+ <li>
+ <a data-toggle="dropdown" aria-expanded="false">
+ <i class="glyphicon glyphicon-question-sign"></i>
+ </a>
+
+ <ul class="dropdown-menu">
+ <li><a>How to start using eagle</a></li>
+ <li><a>How to register new site</a></li>
+ <li><a>How to install application</a></li>
+ <li><a>How to manage application</a></li>
+ <li><a>How to develop application</a></li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </nav>
+ </header>
+
+ <!-- =============================================== -->
+ <!-- Left side column. contains the side bar -->
+ <aside class="main-sidebar" ng-hide="PageConfig.hideSidebar">
+ <!-- side bar: style can be found in sidebar.less -->
+ <section class="sidebar">
+ <ul class="sidebar-menu">
+ <li ng-repeat="portal in Portal.list track by $index" ng-class="{treeview: portal.list}">
+ <a ng-href="{{portal.path}}">
+ <i class="fa fa-{{portal.icon || 'circle-o'}}"></i>
+ <span>{{portal.name}}</span>
+ <i class="fa fa-angle-left pull-right" ng-if="portal.list"></i>
+ </a>
+ <ul class="treeview-menu" ng-if="portal.list">
+ <li ng-repeat="subPortal in portal.list track by $index" ng-class="{active: getNavClass(subPortal)}">
+ <a ng-href="{{subPortal.path}}">
+ <i class="fa fa-{{subPortal.icon || 'circle-o'}}"></i>
+ <span>{{subPortal.name}}</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </section>
+ <!-- /.sidebar -->
+ </aside>
+
+ <!-- =============================================== -->
+ <!-- Right side column. Contains the navbar and content of the page -->
+ <div class="content-wrapper">
+ <!-- Content Header (Page header) -->
+ <section class="content-header" ng-hide="PageConfig.hideTitle">
+ <h1>
+ <span class="pageTitle">{{PageConfig.title}}</span>
+ <small class="pageSubTitle">{{PageConfig.subTitle}}</small>
+ </h1>
+
+
+ <ol class="breadcrumb">
+ <li ng-repeat="navPath in PageConfig.navPath">
+ <a ng-href="#{{navPath.path}}">
+ <span class="fa fa-home" ng-if="$first"></span>
+ {{navPath.title || navPath.path}}
+ </a>
+ </li>
+ </ol>
+ </section>
+
+ <!-- Main content -->
+ <section class="content">
+ <div id="content">
+ <div ui-view></div>
+ </div>
+ </section><!-- /.content -->
+ </div><!-- /.content-wrapper -->
+
+ <footer class="main-footer">
+ <div class="pull-right hidden-xs">
+ <b>License</b>
+ <a href="http://www.apache.org/licenses/LICENSE-2.0" class="text-muted">Apache-2.0</a>
+ </div>
+ <strong>
+ Apache Eagle
+ <a target="_blank" href="https://eagle.incubator.apache.org/">Home</a> /
+ <a target="_blank" href="https://eagle.incubator.apache.org/docs/community.html">Community</a> /
+ <a target="_blank" href="https://cwiki.apache.org/confluence/display/EAG/FAQ">FAQ</a>
+ </strong>
+ </footer>
+ </div><!-- ./wrapper -->
+
+ <!-- Modal: Time Range Picker -->
+ <div class="modal fade" tabindex="-1" role="dialog" id="eagleTimeRangeMDL">
+ <div class="modal-dialog" 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">Customize Time Range</h4>
+ </div>
+ <div class="modal-body">
+ <div class="row">
+ <div class="col-sm-6">
+ <div class="form-group">
+ <label for="eagleStartTime">Start Time</label>
+ <input type="text" class="form-control" data-container="body" data-toggle="datepicker" id="eagleStartTime">
+ </div>
+ </div>
+ <div class="col-sm-6">
+ <div class="form-group">
+ <label for="eagleEndTime">End Time</label>
+ <input type="text" class="form-control" data-container="body" data-toggle="datepicker" id="eagleEndTime" data-position="right">
+ </div>
+ </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="updateTimeRange()">Change</button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- ref:js public/js/modules.js -->
+ <script src="../node_modules/jquery/dist/jquery.min.js"></script>
+ <script src="../node_modules/jquery-slimscroll/jquery.slimscroll.min.js"></script>
+ <script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
+ <script src="../node_modules/zombiej-bootstrap-components/bootstrap-components/js/bootstrap-components.min.js"></script>
+ <script src="../node_modules/moment/min/moment-with-locales.min.js"></script>
+ <script src="../node_modules/moment-timezone/builds/moment-timezone-with-data.min.js"></script>
+ <script src="../node_modules/echarts/dist/echarts.min.js"></script>
+ <script src="../node_modules/admin-lte/dist/js/app.min.js"></script>
+ <script src="../node_modules/angular/angular.min.js"></script>
+ <script src="../node_modules/angular-resource/angular-resource.min.js"></script>
+ <script src="../node_modules/angular-route/angular-route.min.js"></script>
+ <script src="../node_modules/angular-animate/angular-animate.min.js"></script>
+ <script src="../node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js"></script>
+ <script src="../node_modules/angular-ui-router/release/angular-ui-router.min.js"></script>
+ <!-- endref -->
+
+ <!-- ref:js public/js/doc.min.js -->
+ <!-- Worker -->
+ <script src="public/js/worker/sortTableFunc.js" type="text/javascript" charset="utf-8"></script>
+
+ <!-- Application -->
+ <script src="public/js/common.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/index.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/app.js" type="text/javascript" charset="utf-8"></script>
+
+ <!-- Service -->
+ <script src="public/js/services/main.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/services/timeSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/services/pageSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/services/widgetSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/services/wrapStateSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/services/entitySrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/services/siteSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/services/applicationSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/services/uiSrv.js" type="text/javascript" charset="utf-8"></script>
+
+ <!-- Components -->
+ <script src="public/js/components/main.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/components/sortTable.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/components/chart.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/components/widget.js" type="text/javascript" charset="utf-8"></script>
+
+ <!-- Controllers -->
+ <script src="public/js/ctrls/main.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/ctrls/mainCtrl.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/ctrls/alertCtrl.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/ctrls/integrationCtrl.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/ctrls/siteCtrl.js" type="text/javascript" charset="utf-8"></script>
+ <!-- endref -->
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/alert/list.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/alert/list.html b/eagle-server/src/main/webapp/app/dev/partials/alert/list.html
new file mode 100644
index 0000000..d493976
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/alert/list.html
@@ -0,0 +1,21 @@
+<!--
+ 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-body">
+ Good!
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/alert/main.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/alert/main.html b/eagle-server/src/main/webapp/app/dev/partials/alert/main.html
new file mode 100644
index 0000000..2e062a8
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/alert/main.html
@@ -0,0 +1,29 @@
+<!--
+ 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="nav-tabs-custom">
+ <ul class="nav nav-tabs">
+ <li ng-class="{active: getState() === 'alert.list'}"><a href="#/alert/">Explore Triggered Alerts</a></li>
+ <li ng-class="{active: getState() === 'alert.policyList'}"><a href="#/alert/policyList">Manage Policies</a></li>
+ <li ng-class="{active: ['alert.policyCreate', 'alert.policyEdit'].indexOf(getState()) >= 0}"><a href="#/alert/policyCreate">Define Alert Policy</a></li>
+ </ul>
+ <div class="tab-content no-padding">
+ <div ui-view></div>
+ </div>
+</div>
+
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/alert/policyEdit.back.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/alert/policyEdit.back.html b/eagle-server/src/main/webapp/app/dev/partials/alert/policyEdit.back.html
new file mode 100644
index 0000000..3c335f7
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/alert/policyEdit.back.html
@@ -0,0 +1,108 @@
+<!--
+ 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-body">
+ <ul class="timeline">
+ <!-- Base Info -->
+ <li class="time-label">
+ <span class="bg-blue">#1. Basic Information</span>
+ </li>
+ <li>
+ <span class="fa fa-file-text bg-aqua"></span>
+ <div class="timeline-item">
+ <div class="timeline-body">
+ <div class="form-group">
+ <label>Policy Name</label>
+ <input type="text" class="form-control" ng-model="policy.name" />
+ </div>
+ <div class="form-group">
+ <label>Severity</label>
+ <select class="form-control" ng-model="policy.severity">
+ <option>WARNING</option>
+ <option>CRITICAL</option>
+ <option>DANGER</option>
+ </select>
+ </div>
+ <div class="form-group">
+ <label>Description</label>
+ <textarea class="form-control" ng-model="policy.description" rows="3"></textarea>
+ </div>
+ </div>
+ </div>
+ </li>
+
+ <!-- Alert Stream -->
+ <li class="time-label">
+ <span class="bg-blue">#2. Alert Stream</span>
+ </li>
+ <li>
+ <span class="fa fa-rocket bg-aqua"></span>
+ <div class="timeline-item">
+ <div class="timeline-body">
+ <div class="form-group">
+ <label>App Integration</label>
+ <select class="form-control"></select>
+ </div>
+ <div class="form-group">
+ <label>Alert Stream</label>
+ <select class="form-control"></select>
+ </div>
+ </div>
+ </div>
+ </li>
+
+ <!-- Streaming Logic -->
+ <li class="time-label">
+ <span class="bg-blue">#3. Streaming Logic</span>
+ </li>
+ <li>
+ <span class="fa fa-trophy bg-aqua"></span>
+ <div class="timeline-item">
+ <div class="timeline-body">
+ <div class="form-group">
+ <label>Policy Type</label>
+ <select class="form-control"></select>
+ </div>
+ <div class="form-group">
+ <label>Policy Logic</label>
+ <textarea class="form-control" rows="5"></textarea>
+ </div>
+ </div>
+ </div>
+ </li>
+
+ <!-- Publication Configuration -->
+ <li class="time-label">
+ <span class="bg-blue">#4. Publication Configuration</span>
+ </li>
+ <li>
+ <span class="fa fa-envelope bg-aqua"></span>
+ <div class="timeline-item">
+ <div class="timeline-body">
+ <div class="form-group">
+ <label>Publication Type</label>
+ <select class="form-control">
+ <option>NOTIFICATION</option>
+ </select>
+ </div>
+ <a>+ New Publication</a>
+ </div>
+ </div>
+ </li>
+ </ul>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/alert/policyEdit.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/alert/policyEdit.html b/eagle-server/src/main/webapp/app/dev/partials/alert/policyEdit.html
new file mode 100644
index 0000000..9a1cbe4
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/alert/policyEdit.html
@@ -0,0 +1,29 @@
+<!--
+ 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-body">
+ <ul class="stepGuide">
+ <li>
+ <span class="icon bg-green">1</span>
+ <span class="title">This is the title!!!</span>
+ </li>
+ <li>
+ <span class="icon">2</span>
+ </li>
+ </ul>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/alert/policyList.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/alert/policyList.html b/eagle-server/src/main/webapp/app/dev/partials/alert/policyList.html
new file mode 100644
index 0000000..2d4703f
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/alert/policyList.html
@@ -0,0 +1,63 @@
+<!--
+ 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-solid">
+ <div class="box-body">
+ <div sort-table="policyList" ng-show="policyList.length">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <th sortpath="name" width="20%">Name</th>
+ <th sortpath="definition.type" width="70">Type</th>
+ <th>Description</th>
+ <th width="85">Action</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <a ng-href="#/alert/policyEdit/{{item.name}}">{{item.name}}</a>
+ </td>
+ <td class="text-center"><span class="label label-primary">{{item.definition.type}}</span></td>
+ <td>{{item.description}}</td>
+ <td class="text-center">
+ <div class="btn-group btn-group-xs">
+ <button class="btn btn-default"><span class="fa fa-play"></span></button>
+ <button class="btn btn-default"><span class="fa fa-pencil"></span></button>
+ <button class="btn btn-danger" ng-click="deletePolicy(item)"><span class="fa fa-trash"></span></button>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div class="callout callout-warning no-margin" ng-show="policyList._done && policyList.length === 0">
+ <h4>No Policy yet</h4>
+ <p>You have not create policy yet. Click <a href="#/alert/policyCreate">here</a> to create a new policy.</p>
+ </div>
+ </div>
+
+ <div class="overlay" ng-if="!policyList._done">
+ <i class="fa fa-refresh fa-spin"></i>
+ </div>
+
+ <div class="box-footer text-right">
+ <a href="#/alert/policyCreate" class="btn btn-primary">New Policy</a>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/home.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/home.html b/eagle-server/src/main/webapp/app/dev/partials/home.html
new file mode 100644
index 0000000..ab75b18
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/home.html
@@ -0,0 +1,60 @@
+<!--
+ 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="row" ng-repeat="banner in bannerList track by $index">
+ <div class="col-sm-12" ng-if="banner.title">
+ <h3>{{banner.title}}</h3>
+ </div>
+ <div class="col-sm-6 col-md-4 col-lg-3" ng-repeat="widget in banner.list track by $index">
+ <div class="small-box {{widget.color || 'bg-aqua'}}">
+ <div class="inner">
+ <h3>{{widget.title || "Untitled"}}</h3>
+ <p>{{widget.description || "-"}}</p>
+ <p>{{widget.additionalTips || " "}}</p>
+ </div>
+ <div class="icon">
+ <i class="fa fa-question-circle"></i>
+ </div>
+ <a class="small-box-footer">More info <i class="fa fa-arrow-circle-right"></i></a>
+ </div>
+ </div>
+</div-->
+<div class="row flex">
+ <div class="col-sm-6 col-md-4 col-lg-3" ng-repeat="widget in Widget.list track by $index">
+ <div widget="widget"></div>
+ </div>
+</div>
+
+<!--div class="row flex">
+ <div class="col-md-4">
+ <div style="background: red; height: 200px;">111</div>
+ </div>
+ <div class="col-md-4">
+ <div style="background: green;">222</div>
+ <div style="background: blue;">222</div>
+ </div>
+ <div class="col-md-4">
+ <div style="background: red;">333</div>
+ </div>
+ <div class="col-md-4">
+ <div style="background: green;">444</div>
+ </div>
+ <div class="col-md-4">
+ <div style="background: red;">555</div>
+ </div>
+</div-->
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/integration/applicationList.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/integration/applicationList.html b/eagle-server/src/main/webapp/app/dev/partials/integration/applicationList.html
new file mode 100644
index 0000000..bc603a7
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/integration/applicationList.html
@@ -0,0 +1,80 @@
+<!--
+ 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-body">
+ <table class="table table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>Application</th>
+ <th>Type</th>
+ <th>Version</th>
+ <th>Path</th>
+ <th>Streams</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="app in Application.providerList track by $index">
+ <td class="text-no-break"><a ng-click="showAppDetail(app)">{{app.name}}</a></td>
+ <td>{{app.type}}</td>
+ <td class="text-no-break">{{app.version}}</td>
+ <td>{{app.viewPath}}</td>
+ <td>
+ <ul>
+ <li ng-repeat="stream in app.streams track by $index">
+ {{stream.streamId}}
+ </li>
+ </ul>
+ </td>
+ <td>{{app.description}}</td>
+ </tr>
+ </tbody>
+ </table>
+</div>
+
+
+<!-- Modal: Application information -->
+<div class="modal fade" role="dialog" id="appMDL">
+ <div class="modal-dialog modal-lg">
+ <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" id="myModalLabel">{{application.name}}</h4>
+ </div>
+ <div class="modal-body">
+ <ul class="nav nav-tabs">
+ <li class="active"><a href="[data-id='install']" data-toggle="tab">Install</a></li>
+ <li><a href="[data-id='uninstall']" data-toggle="tab">Uninstall</a></li>
+ </ul>
+ <div class="tab-content">
+ <div class="tab-pane active" data-id="install">
+ <pre ng-bind-html="installHTML"></pre>
+ </div>
+ <div class="tab-pane" data-id="uninstall">
+ <pre ng-bind-html="uninstallHTML"></pre>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/integration/main.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/integration/main.html b/eagle-server/src/main/webapp/app/dev/partials/integration/main.html
new file mode 100644
index 0000000..daea22e
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/integration/main.html
@@ -0,0 +1,29 @@
+<!--
+ 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="nav-tabs-custom">
+ <ul class="nav nav-tabs">
+ <li ng-class="{active: getState().indexOf('integration.site') !== -1}"><a href="#/integration/siteList">Sites</a></li>
+ <li ng-class="{active: getState() === 'integration.applicationList'}"><a href="#/integration/applicationList">Applications</a></li>
+ <li ng-class="{active: getState() === 'integration.streamList'}"><a href="#/integration/streamList">Streams</a></li>
+ </ul>
+ <div class="tab-content no-padding">
+ <div ui-view></div>
+ </div>
+</div>
+
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/integration/site.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/integration/site.html b/eagle-server/src/main/webapp/app/dev/partials/integration/site.html
new file mode 100644
index 0000000..b391b49
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/integration/site.html
@@ -0,0 +1,95 @@
+<!--
+ 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-body">
+ <p class="text-danger" ng-if="site.applicationList.length === 0">
+ <span class="fa fa-exclamation-triangle"></span> Site must install at least one application to start up.
+ </p>
+ <p class="text-warning" ng-if="site.applicationList.length !== 0 && getStartedAppCount() === 0">
+ <span class="fa fa-exclamation-triangle"></span> No application started.
+ </p>
+
+ <table class="table table-bordered table-hover">
+ <thead>
+ <tr>
+ <th>App</th>
+ <th width="10">Status</th>
+ <th>Version</th>
+ <th>Description</th>
+ <!--th>Quick Links</th-->
+ <th width="150">Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="app in applicationList track by $index">
+ <td><a ng-click="showAppDetail(app)">{{app.origin.name}}</a></td>
+ <td class="text-center">
+ <span class="label label-{{getAppStatusClass(app)}}" ng-if="app.installed">{{app.status}}</span>
+ <span class="label label-default" ng-if="!app.installed">UNINSTALLED</span>
+ </td>
+ <td>{{app.origin.version}}</td>
+ <td>{{app.description}}</td>
+ <!--td>TODO: ui link</td-->
+ <td class="text-center">
+ <div class="btn-group btn-group-xs" ng-if="app.installed">
+ <!--button class="btn btn-default btn-sm">Monitor</button-->
+ <button class="btn btn-default btn-sm" ng-click="startApp(app)">Start</button>
+ <button class="btn btn-default btn-sm" ng-click="stopApp(app)">Stop</button>
+ <button class="btn btn-default btn-sm" ng-click="uninstallApp(app)">Uninstall</button>
+ </div>
+ <div class="btn-group btn-group-xs" ng-if="!app.installed">
+ <button class="btn btn-primary btn-sm" ng-click="installApp(app)">Install Application</button>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+</div>
+
+
+
+<!-- Modal: Application information -->
+<div class="modal fade" role="dialog" id="appMDL">
+ <div class="modal-dialog modal-lg">
+ <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" id="myModalLabel">{{application.name}}</h4>
+ </div>
+ <div class="modal-body">
+ <ul class="nav nav-tabs">
+ <li class="active"><a href="[data-id='install']" data-toggle="tab">Install</a></li>
+ <li><a href="[data-id='uninstall']" data-toggle="tab">Uninstall</a></li>
+ </ul>
+ <div class="tab-content">
+ <div class="tab-pane active" data-id="install">
+ <pre ng-bind-html="installHTML"></pre>
+ </div>
+ <div class="tab-pane" data-id="uninstall">
+ <pre ng-bind-html="uninstallHTML"></pre>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/integration/siteList.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/integration/siteList.html b/eagle-server/src/main/webapp/app/dev/partials/integration/siteList.html
new file mode 100644
index 0000000..491d902
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/integration/siteList.html
@@ -0,0 +1,60 @@
+<!--
+ 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-body">
+ <table class="table table-bordered table-hover">
+ <thead>
+ <tr>
+ <th>Site</th>
+ <th>Description</th>
+ <th>Enabled Apps</th>
+ <th width="95">Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="site in Site.list track by $index">
+ <td>
+ <a ui-sref="integration.site({id: site.siteId})">
+ {{site.siteId}}
+ <span ng-if="site.siteName">({{site.siteName}})</span>
+ </a>
+ </td>
+ <td>{{site.description}}</td>
+ <td>
+ <span class="text-muted" ng-if="site.applicationList.length === 0">(Nothing installed...)</span>
+ <ul class="list-inline no-margin">
+ <li ng-repeat="app in site.applicationList track by $index">
+ <span class="label label-primary">
+ {{app.descriptor.name}}
+ </span>
+ </li>
+ </ul>
+ </td>
+ <td class="text-center">
+ <div class="btn-group btn-group-xs">
+ <a class="btn btn-default btn-sm" ui-sref="integration.site({id: site.siteId})">Edit</a>
+ <button class="btn btn-default btn-sm" ng-click="deleteSite(site)">Delete</button>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+</div>
+<div class="box-footer text-right">
+ <button class="btn btn-primary" ng-click="newSite()">New Site</button>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/integration/streamList.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/integration/streamList.html b/eagle-server/src/main/webapp/app/dev/partials/integration/streamList.html
new file mode 100644
index 0000000..beaf743
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/integration/streamList.html
@@ -0,0 +1,52 @@
+<!--
+ 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-body">
+ <div sort-table="streamList">
+ <table class="table table-bordered table-hover">
+ <thead>
+ <tr>
+ <th>Stream</th>
+ <th>Provider (App)</th>
+ <th>Site</th>
+ <th>Schema</th>
+ <th width="10">Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><span class="label label-primary">{{item.streamId}}</span></td>
+ <td>{{item.appType}}</td>
+ <td>{{item.siteId}}</td>
+ <td>
+ <ul class="no-margin">
+ <li ng-repeat="column in item.schema.columns track by $index">
+ <strong>{{column.name}}</strong>:
+ {{column.type}}
+ </li>
+ </ul>
+ </td>
+ <td>
+ <!-- TODO:link with alert -->
+ <button class="btn btn-primary btn-sm">New Alert</button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/partials/setup.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/setup.html b/eagle-server/src/main/webapp/app/dev/partials/setup.html
new file mode 100644
index 0000000..64944fb
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/setup.html
@@ -0,0 +1,46 @@
+<!--
+ 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.
+ -->
+
+<h2>Welcome for using Apache Eagle!</h2>
+<p class="lead">
+ As the first installation, please create a <code>SITE</code>.
+ (A site is a cluster/service which you want to monitor, as a quick start, you could use <code>sandbox</code> by default)
+</p>
+
+<div class="box box-primary">
+ <div class="box-header with-border">
+ <h3 class="box-title">Create new site</h3>
+ </div>
+ <div class="box-body">
+ <div class="form-group">
+ <label>* Site Id</label>
+ <input class="form-control" placeholder="Site id should be unique" ng-model="siteId">
+ </div>
+ <div class="form-group">
+ <label>Display Name</label>
+ <input class="form-control" placeholder="Site display name in UI" ng-model="siteName">
+ </div>
+ <div class="form-group">
+ <label>Description</label>
+ <textarea class="form-control" placeholder="Description about current site" ng-model="description" rows="5"></textarea>
+ </div>
+ </div>
+ <div class="box-footer text-right">
+ <button class="btn btn-primary" ng-click="createSite()" ng-disabled="site === '' || lock">Next</button>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/public/css/animation.css
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/css/animation.css b/eagle-server/src/main/webapp/app/dev/public/css/animation.css
new file mode 100644
index 0000000..cbf4973
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/public/css/animation.css
@@ -0,0 +1,47 @@
+@CHARSET "UTF-8";
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#content > [ui-view].ng-enter,
+#content > [ui-view].ng-leave {
+ position: absolute;
+ left: 0;
+ right: 0;
+ -webkit-transition: all .5s ease-in-out;
+ -moz-transition: all .5s ease-in-out;
+ -o-transition: all .5s ease-in-out;
+ transition: all .3s ease-in-out;
+}
+
+#content > [ui-view].ng-enter {
+ opacity: 0;
+}
+
+#content > [ui-view].ng-enter-active {
+ opacity: 1;
+}
+
+#content > [ui-view].ng-leave {
+ opacity: 1;
+ transform:translate3d(0, 0, 0);
+}
+
+#content > [ui-view].ng-leave-active {
+ opacity: 0;
+ transform:translate3d(20%, 0, 0);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/public/css/main.css
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/css/main.css b/eagle-server/src/main/webapp/app/dev/public/css/main.css
new file mode 100644
index 0000000..83f9b14
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/public/css/main.css
@@ -0,0 +1,317 @@
+@CHARSET "UTF-8";
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+a {
+ cursor: pointer;
+}
+
+/* ========================================================================
+ * = Side Bar =
+ * ======================================================================== */
+.sidebar-mini.sidebar-collapse .main-header .logo > .logo-mini > img {
+ max-height: 30px;
+}
+
+.main-sidebar .customize-panel {
+ padding: 10px;
+}
+
+.sidebar-collapse .main-sidebar .customize-panel {
+ display: none;
+}
+
+.main-sidebar .customize-panel .btn-group,
+.main-sidebar .customize-panel .btn-group button,
+.main-sidebar .customize-panel .btn-group .dropdown-menu {
+ width: 100%;
+}
+
+.main-sidebar .customize-panel .btn-group button {
+ padding: 5px;
+ background: #374850;
+ border: none;
+ overflow-x: hidden;
+}
+.main-sidebar .customize-panel .btn-group.open button{
+ background: #455b63;
+}
+
+.main-sidebar .customize-panel .btn-group button .caret {
+ position: absolute;
+ right: 10px;
+ top: 13px;
+}
+
+/* ========================================================================
+ * = Main =
+ * ======================================================================== */
+#content {
+ position: relative;
+}
+
+/* ========================================================================
+ * = Grid =
+ * ======================================================================== */
+
+@media (min-width: 1200px) {
+ .row.flex {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ flex-wrap: wrap;
+ }
+
+ .row.flex > [class*='col-'] {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ flex-direction: column;
+ flex-wrap: nowrap;
+ }
+
+ .row.flex > [class*='col-'] > * {
+ flex: auto;
+ }
+}
+
+.row.border-split > div {
+ border: 1px solid #f4f4f4;
+}
+
+.no-padding > .row.border-split {
+ margin-left: 0;
+ margin-right: 0;
+}
+
+/* ========================================================================
+ * = Table =
+ * ======================================================================== */
+table .info-wrapper .info-detail {
+ display: none;
+}
+
+table .info-wrapper:hover .info-detail {
+ display: table-row;
+}
+
+table ul {
+ padding: 0 0 0 20px;
+}
+
+table.table pre {
+ white-space: pre-wrap;
+ margin: 0;
+}
+
+table.table pre.inline {
+ padding: 0;
+ border: 0;
+ border-radius: 0;
+ background: transparent;
+}
+
+table.table.table-sm th,
+table.table.table-sm td {
+ padding: 3px 5px;
+ line-height: 120%;
+}
+
+/* ========================================================================
+ * = Step Guide =
+ * ======================================================================== */
+ul.stepGuide {
+ padding: 0;
+ position: relative;
+ display: inline-block;
+}
+ul.stepGuide:before {
+ display: block;
+ height: 6px;
+ background: #f4f4f4;
+ content: "";
+ position: absolute;
+ top: 12px;
+ left: 5px;
+ right: 5px;
+}
+
+ul.stepGuide li {
+ position: relative;
+ display: inline-block;
+ vertical-align: top;
+ text-align: center;
+}
+ul.stepGuide li:not(:first-child) {
+ margin-left: 15px;
+}
+
+ul.stepGuide li > .icon {
+ display: inline-block;
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+ text-align: center;
+ background: #f4f4f4;
+ border-radius: 100%;
+}
+
+ul.stepGuide li > .title {
+ display: block;
+}
+
+/* ========================================================================
+ * = Box =
+ * ======================================================================== */
+.box .box-title .label {
+ font-size: 12px;
+ padding: 1px 7px;
+}
+
+.small-box {
+ position: relative;
+ padding-bottom: 30px;
+}
+
+.small-box > .inner a {
+ color: #FFFFFF;
+}
+
+.small-box > .inner a:hover {
+ text-decoration: underline;
+}
+
+.small-box > .small-box-footer {
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
+
+ /* ========================================================================
+ * = Tab =
+ * ======================================================================== */
+.tab-content.keepContent > .tab-pane {
+ display: block;
+}
+
+.tab-content.keepContent > .tab-pane:not(.active) {
+ max-height: 0;
+ overflow: hidden;
+}
+
+/* ========================================================================
+ * = Modal =
+ * ======================================================================== */
+.modal .nav-tabs li {
+ border-top: 3px solid transparent;
+}
+
+.modal .nav-tabs li.active {
+ border-top-color: #3c8dbc;
+}
+
+.modal .nav-tabs li a {
+ padding: 8px 15px;
+ border-radius: 0;
+ margin: 0;
+}
+
+.modal .nav-tabs li a,
+.modal .nav-tabs li.active a,
+.modal .nav-tabs li:hover a {
+ border-top: 0;
+}
+
+.modal .tab-content {
+ padding-top: 10px;
+}
+
+/* ========================================================================
+ * = Call out =
+ * ======================================================================== */
+.callout p,
+.callout span {
+ color: #FFF;
+}
+
+/* ========================================================================
+ * = list =
+ * ======================================================================== */
+.list-inline > li > .label {
+ margin-bottom: 2px;
+ display: inline-block;
+}
+
+/* ========================================================================
+ * = label =
+ * ======================================================================== */
+.label.label-sm {
+ padding: .1em .4em .2em;
+}
+
+/* ========================================================================
+ * = Timeline =
+ * ======================================================================== */
+.nav-tabs-custom .timeline li .timeline-item {
+ background: #f4f4f4;
+}
+
+/* ========================================================================
+ * = Widget =
+ * ======================================================================== */
+@media (min-width: 1200px) {
+ .row.flex div[widget] {
+ height: 100%;
+ }
+}
+
+/* ========================================================================
+ * = Misc =
+ * ======================================================================== */
+.ng-hide.ng-hide-animate.no-animate {
+ -webkit-transition: none !important;
+ transition: none !important;
+}
+
+.ng-hide.ng-hide-animate.no-animate {
+ display: none;
+}
+
+.text-break {
+ word-break:break-all;
+}
+
+.text-no-break {
+ white-space: nowrap;
+}
+
+.no-select {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.bsc-datepicker {
+ z-index: 2000;
+}
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/public/css/sortTable.css
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/css/sortTable.css b/eagle-server/src/main/webapp/app/dev/public/css/sortTable.css
new file mode 100644
index 0000000..529eb1a
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/public/css/sortTable.css
@@ -0,0 +1,61 @@
+@CHARSET "UTF-8";
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+[sort-table] .tool-container .search-box {
+ margin: 0 0 10px 0;
+ position: relative;
+ max-width: 250px;
+ float: left;
+}
+
+[sort-table] .tool-container .search-box input {
+ padding-left: 28px;
+}
+
+[sort-table] .tool-container .search-box .fa-search {
+ pointer-events:none;
+ position: absolute;
+ top: 8px;
+ left: 8px;
+ opacity: 0.5;
+}
+
+[sort-table] .tool-container .page-size {
+ float: right;
+}
+
+[sort-table] .tool-container .page-size select {
+ width: initial;
+ display: inline-block;
+ margin: 0 7px;
+ height: 26px;
+ padding: 0 5px;
+}
+
+[sort-table] .fa.sort-mark {
+ float: right;
+ margin-top: 3px;
+ pointer-events: none;
+ color: #AAA;
+}
+
+[sort-table] .navigation-bar .pagination {
+ float: right;
+ margin-top: 0;
+}
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/public/images/favicon.png
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/images/favicon.png b/eagle-server/src/main/webapp/app/dev/public/images/favicon.png
new file mode 100644
index 0000000..3bede2a
Binary files /dev/null and b/eagle-server/src/main/webapp/app/dev/public/images/favicon.png differ
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/public/images/favicon_white.png
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/images/favicon_white.png b/eagle-server/src/main/webapp/app/dev/public/images/favicon_white.png
new file mode 100644
index 0000000..9879e92
Binary files /dev/null and b/eagle-server/src/main/webapp/app/dev/public/images/favicon_white.png differ
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/public/js/app.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/app.js b/eagle-server/src/main/webapp/app/dev/public/js/app.js
new file mode 100644
index 0000000..4ec77d9
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/public/js/app.js
@@ -0,0 +1,311 @@
+/*
+ * 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';
+
+ $(document).on("APPLICATION_READY", function (event, register) {
+ console.info("[Eagle] Angular bootstrap...");
+
+ var STATE_NAME_MATCH = /^[^.]*/;
+ var state_next;
+ var state_current;
+ var param_next;
+ var param_current;
+
+ // ======================================================================================
+ // = Initialization =
+ // ======================================================================================
+ var eagleApp = angular.module('eagleApp', ['ngRoute', 'ngAnimate', 'ui.router', 'eagleControllers', 'eagle.service'].concat(register.appList));
+
+ // ======================================================================================
+ // = Router config =
+ // ======================================================================================
+ function routeResolve(config) {
+ var resolve = {};
+ if(config === false) return resolve;
+
+ config = $.extend({
+ auth: true,
+ site: true,
+ application: true
+ }, config);
+
+ if(config.auth) {
+ // TODO: need auth module
+ }
+
+ resolve.Site = function (Site) {
+ return Site.getPromise(config);
+ };
+
+ resolve.Application = function (Application) {
+ return Application.getPromise();
+ };
+
+ resolve.Time = function (Time) {
+ return Time.getPromise(config, state_next, param_next);
+ };
+
+ return resolve;
+ }
+
+ eagleApp.config(function ($stateProvider, $urlRouterProvider, $httpProvider, $animateProvider) {
+ $urlRouterProvider.otherwise("/");
+ $stateProvider
+ // ================================== Home ==================================
+ .state('home', {
+ url: "/",
+ templateUrl: "partials/home.html?_=" + window._TRS(),
+ controller: "homeCtrl",
+ resolve: routeResolve()
+ })
+ .state('setup', {
+ url: "/setup",
+ templateUrl: "partials/setup.html?_=" + window._TRS(),
+ controller: "setupCtrl",
+ resolve: routeResolve({ site: false, application: false })
+ })
+ // ================================= Alerts =================================
+ .state('alert', {
+ abstract: true,
+ url: "/alert/",
+ templateUrl: "partials/alert/main.html?_=" + window._TRS(),
+ controller: "alertCtrl",
+ resolve: routeResolve(false)
+ })
+ .state('alert.list', {
+ url: "",
+ templateUrl: "partials/alert/list.html?_=" + window._TRS(),
+ controller: "alertListCtrl",
+ resolve: routeResolve()
+ })
+ .state('alert.policyList', {
+ url: "policyList",
+ templateUrl: "partials/alert/policyList.html?_=" + window._TRS(),
+ controller: "policyListCtrl",
+ resolve: routeResolve()
+ })
+ .state('alert.policyCreate', {
+ url: "policyCreate",
+ templateUrl: "partials/alert/policyEdit.html?_=" + window._TRS(),
+ controller: "policyCreateCtrl",
+ resolve: routeResolve()
+ })
+ .state('alert.policyEdit', {
+ url: "policyEdit/{name}",
+ templateUrl: "partials/alert/policyEdit.html?_=" + window._TRS(),
+ controller: "policyEditCtrl",
+ resolve: routeResolve()
+ })
+ // =============================== Integration ==============================
+ .state('integration', {
+ abstract: true,
+ url: "/integration/",
+ templateUrl: "partials/integration/main.html?_=" + window._TRS(),
+ controller: "integrationCtrl",
+ resolve: routeResolve(false)
+ })
+ .state('integration.siteList', {
+ url: "siteList",
+ templateUrl: "partials/integration/siteList.html?_=" + window._TRS(),
+ controller: "integrationSiteListCtrl",
+ resolve: routeResolve({ application: false })
+ })
+ .state('integration.site', {
+ url: "site/:id",
+ templateUrl: "partials/integration/site.html?_=" + window._TRS(),
+ controller: "integrationSiteCtrl",
+ resolve: routeResolve({ application: false })
+ })
+ .state('integration.applicationList', {
+ url: "applicationList",
+ templateUrl: "partials/integration/applicationList.html?_=" + window._TRS(),
+ controller: "integrationApplicationListCtrl",
+ resolve: routeResolve({ application: false })
+ })
+ .state('integration.streamList', {
+ url: "streamList",
+ templateUrl: "partials/integration/streamList.html?_=" + window._TRS(),
+ controller: "integrationStreamListCtrl",
+ resolve: routeResolve()
+ })
+ // ================================== Site ==================================
+ .state('site', {
+ url: "/site/:siteId",
+ templateUrl: "partials/home.html?_=" + window._TRS(),
+ controller: "siteCtrl",
+ resolve: routeResolve()
+ })
+ ;
+
+ // =========================== Application States ===========================
+ $.each(register.routeList, function (i, route) {
+ var config = $.extend({}, route.config);
+
+ var resolve = {};
+ var resolveConfig = {};
+ if(route.config.resolve) {
+ $.each(route.config.resolve, function (key, value) {
+ if (typeof value === "function") {
+ resolve[key] = value;
+ } else {
+ resolveConfig[key] = value;
+ }
+ });
+ }
+ config.resolve = $.extend(routeResolve(resolveConfig), resolve);
+
+ $stateProvider.state(route.state, config);
+ });
+
+ $httpProvider.interceptors.push(function($q) {
+ function eagleRequestHandle(res) {
+ var data = res.data || {
+ exception: "",
+ message: ""
+ };
+ if(res.status === -1) {
+ $.dialog({
+ title: "AJAX Failed",
+ content: $("<pre>")
+ .text("url:\n" + common.getValueByPath(res, ["config", "url"]))
+ });
+ } else if(data.success === false || res.status === 404) {
+ $.dialog({
+ title: "AJAX Error",
+ content: $("<pre>")
+ .text(
+ "url:\n" + common.getValueByPath(res, ["config", "url"]) + "\n\n" +
+ "status:\n" + res.status + "\n\n" +
+ "exception:\n" + data.exception + "\n\n" +
+ "message:\n" + data.message
+ )
+ });
+ }
+ return res;
+ }
+
+ return {
+ response: eagleRequestHandle,
+ responseError: function(res) {
+ return $q.reject(eagleRequestHandle(res));
+ }
+ };
+ });
+ });
+
+ // ======================================================================================
+ // = Main Controller =
+ // ======================================================================================
+ eagleApp.controller('MainCtrl', function ($scope, $wrapState, $urlRouter, PageConfig, Portal, Widget, Entity, Site, Application, UI, Time) {
+ window._WrapState = $scope.$wrapState = $wrapState;
+ window._PageConfig = $scope.PageConfig = PageConfig;
+ window._Portal = $scope.Portal = Portal;
+ window._Widget = $scope.Widget = Widget;
+ window._Entity = $scope.Entity = Entity;
+ window._Site = $scope.Site = Site;
+ window._Application = $scope.Application = Application;
+ window._UI = $scope.UI = UI;
+ window._Time = $scope.Time = Time;
+ $scope.common = common;
+
+ Object.defineProperty(window, "scope", {
+ get: function () {
+ return angular.element("#content .ng-scope").scope();
+ }
+ });
+
+ // ============================== Route Update ==============================
+ $scope.$on('$stateChangeStart', function (event, next, nextParam, current, currentParam) {
+ console.log("[Switch] current ->", current, currentParam);
+ console.log("[Switch] next ->", next, nextParam);
+
+ state_next = next || {};
+ state_current = current || {};
+ param_next = nextParam;
+ param_current = currentParam;
+
+ var currentName = (current || {}).name || "";
+ var nextName = (next || {}).name || "";
+
+ // Page initialization
+ if(currentName.match(STATE_NAME_MATCH)[0] !== nextName.match(STATE_NAME_MATCH)[0]) {
+ PageConfig.reset();
+ }
+ });
+
+ // ================================ Function ================================
+ // Get side bar navigation item class
+ $scope.getNavClass = function (portal) {
+ var path = (portal.path || "").replace(/^#/, '');
+
+ if ($wrapState.path() === path) {
+ return "active";
+ } else {
+ return "";
+ }
+ };
+
+ // Customize time range
+ $scope.customizeTimeRange = function () {
+ $("#eagleStartTime").val(Time.format("startTime"));
+ $("#eagleEndTime").val(Time.format("endTime"));
+ $("#eagleTimeRangeMDL").modal();
+ };
+
+ $scope.setLastDuration = function (hours) {
+ var endTime = new Time();
+ var startTime = endTime.clone().subtract(hours, "hours");
+ Time.timeRange(startTime, endTime);
+ };
+
+ $scope.updateTimeRange = function () {
+ var startTime = Time.verifyTime($("#eagleStartTime").val());
+ var endTime = Time.verifyTime($("#eagleEndTime").val());
+ if(startTime && endTime) {
+ Time.timeRange(startTime, endTime);
+ $("#eagleTimeRangeMDL").modal("hide");
+ } else {
+ alert("Time range not validate");
+ }
+ };
+
+ // ================================== Init ==================================
+ $.each(register.portalList, function (i, config) {
+ Portal.register(config.portal, config.isSite);
+ });
+
+ $.each(register.widgetList, function (i, config) {
+ Widget.register(config.widget, config.isSite);
+ });
+ });
+
+ // ======================================================================================
+ // = Bootstrap =
+ // ======================================================================================
+ //noinspection JSCheckFunctionSignatures
+ angular.element(document).ready(function() {
+ console.info("[Eagle] UI start...");
+ //noinspection JSCheckFunctionSignatures
+ angular.bootstrap(document, ['eagleApp']);
+ });
+ });
+})();
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/public/js/common.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/common.js b/eagle-server/src/main/webapp/app/dev/public/js/common.js
new file mode 100644
index 0000000..9f5c4b1
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/public/js/common.js
@@ -0,0 +1,387 @@
+/*
+ * 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 scope = {};
+ if(typeof window != 'undefined') {
+ scope = window;
+ } else if(typeof self != 'undefined') {
+ scope = self;
+ }
+ var common = scope.common = {};
+
+ // ============================ 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 can't be empty!";
+ if(path === "" || path === null || path === undefined) return unit;
+
+ if(typeof path === "string") {
+ path = path.replace(/\[(\d+)\]/g, ".$1").replace(/^\./, "").split(/\./);
+ }
+ for(var i = 0 ; i < path.length ; i += 1) {
+ unit = unit[path[i]];
+ if(unit === null || unit === undefined) {
+ unit = null;
+ break;
+ }
+ }
+ 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.stringify = function(json) {
+ return JSON.stringify(json, function(key, value) {
+ if(/^(_|\$)/.test(key)) return undefined;
+ return value;
+ });
+ };
+
+ common.isEmpty = function(val) {
+ if($.isArray(val)) {
+ return val.length === 0;
+ } else {
+ return val === null || val === undefined;
+ }
+ };
+
+ common.extend = function(target, origin) {
+ $.each(origin, function(key, value) {
+ if(/^(_|\$)/.test(key)) return;
+
+ target[key] = value;
+ });
+ return target;
+ };
+
+ function merge(obj1, obj2) {
+ $.each(obj2, function (key, value) {
+ var oriValue = obj1[key];
+
+ if(typeof oriValue === "object" && typeof value === "object" && !common.isEmpty(value)) {
+ merge(oriValue, value);
+ } else {
+ obj1[key] = value;
+ }
+ });
+ }
+
+ common.merge = function (mergedObj) {
+ for(var i = 1 ; i < arguments.length ; i += 1) {
+ var obj = arguments[i];
+ merge(mergedObj, obj);
+ }
+
+ return mergedObj;
+ };
+
+ // ============================ String ============================
+ common.string = {};
+ common.string.safeText = function (str) {
+ return str
+ .replace(/&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>');
+ };
+
+ common.string.capitalize = function (str) {
+ return (str + "").replace(/\b\w/g, function(match) {
+ return match.toUpperCase();
+ });
+ };
+
+ common.string.preFill = function (str, key, len) {
+ str = str + "";
+ len = len || 2;
+ while(str.length < len) {
+ str = key + str;
+ }
+ return str;
+ };
+
+ // ============================ Array =============================
+ common.array = {};
+
+ common.array.findIndex = function(val, list, path, findAll, caseSensitive) {
+ var _list = [];
+ val = caseSensitive === false ? (val + "").toUpperCase() : val;
+
+ for(var i = 0 ; i < list.length ; i += 1) {
+ var unit = list[i];
+ var _val = common.getValueByPath(unit, path);
+ _val = caseSensitive === false ? (_val + "").toUpperCase() : _val;
+
+ if(_val === val) {
+ if(!findAll) return i;
+ _list.push(i);
+ }
+ }
+
+ return findAll ? _list: -1;
+ };
+
+ common.array.find = function(val, list, path, findAll, caseSensitive) {
+ var index = common.array.findIndex(val, list, path, findAll, caseSensitive);
+
+ if(findAll) {
+ return $.map(index, function (index) {
+ return list[index];
+ });
+ } else {
+ return index === -1 ? null : list[index];
+ }
+ };
+
+ common.array.minus = function (list1, list2, path1, path2) {
+ if(arguments.length === 3) path2 = path1;
+ var list = [];
+ $.each(list1, function (i, item) {
+ var val1 = common.getValueByPath(item, path1);
+ if(!common.array.find(val1, list2, path2)) {
+ list.push(item);
+ }
+ });
+ return list;
+ };
+
+ common.array.doSort = function (list, path, asc, sortList) {
+ var sortFunc;
+ sortList = sortList || [];
+
+ if(asc !== false) {
+ sortFunc = function (obj1, obj2) {
+ var val1 = common.getValueByPath(obj1, path);
+ var val2 = common.getValueByPath(obj2, path);
+
+ var index1 = common.array.findIndex(val1, sortList);
+ var index2 = common.array.findIndex(val2, sortList);
+
+ if(index1 !== -1 && index2 === -1) {
+ return -1;
+ } else if(index1 == -1 && index2 !== -1) {
+ return 1;
+ } else if(index1 !== -1 && index2 !== -1) {
+ return index1 - index2;
+ }
+
+ if (val1 === val2) {
+ return 0;
+ } else if (val1 === null || val1 === undefined || val1 < val2) {
+ return -1;
+ }
+ return 1;
+ };
+ } else {
+ sortFunc = function (obj1, obj2) {
+ var val1 = common.getValueByPath(obj1, path);
+ var val2 = common.getValueByPath(obj2, path);
+
+ var index1 = common.array.findIndex(val1, sortList);
+ var index2 = common.array.findIndex(val2, sortList);
+
+ if(index1 !== -1 && index2 === -1) {
+ return -1;
+ } else if(index1 == -1 && index2 !== -1) {
+ return 1;
+ } else if(index1 !== -1 && index2 !== -1) {
+ return index1 - index2;
+ }
+
+ if (val1 === val2) {
+ return 0;
+ } else if (val1 === null || val1 === undefined || val1 < val2) {
+ return 1;
+ }
+ return -1;
+ };
+ }
+
+ return list.sort(sortFunc);
+ };
+
+ // =========================== Deferred ===========================
+ common.deferred = {};
+
+
+ common.deferred.all = function (deferredList) {
+ var deferred = $.Deferred();
+ var successList = [];
+ var failureList = [];
+ var hasFailure = false;
+ var rest = deferredList.length;
+ function doCheck() {
+ rest -= 1;
+ if(rest === 0) {
+ if(hasFailure) {
+ deferred.reject(failureList);
+ } else {
+ deferred.resolve(successList);
+ }
+ }
+ }
+
+ $.each(deferredList, function (i, deferred) {
+ if(deferred && deferred.then) {
+ deferred.then(function (data) {
+ successList[i] = data;
+ }, function (data) {
+ failureList[i] = data;
+ hasFailure = true;
+ }).always(doCheck);
+ } else {
+ successList[i] = deferred;
+ doCheck();
+ }
+ });
+
+ return deferred;
+ };
+
+ // ============================ Number ============================
+ common.number = {};
+
+ common.number.isNumber = function (num) {
+ return typeof num === "number" && !isNaN(num);
+ };
+
+ common.number.toFixed = function (num, fixed) {
+ if(!common.number.isNumber(num)) return "-";
+ num = Number(num);
+ return num.toFixed(fixed || 0);
+ };
+
+ common.number.format = function (num, fixed) {
+ if(!common.number.isNumber(num)) return "-";
+ return common.number.toFixed(num, fixed).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+ };
+
+ common.number.abbr = function (number, isByte, digits) {
+ digits = digits || 2;
+ var decPlaces = Math.pow(10, digits);
+ var abbrev = isByte ? ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['K', 'M', 'B', 'T', 'Q'];
+ var base = isByte ? 1024 : 1000;
+ var sign = number < 0 ? -1 : 1;
+ var unit = '';
+ number = Math.abs(number);
+
+ for(var i = abbrev.length - 1; i >= 0; i--) {
+ var size = Math.pow(base, i + 1);
+ if(size <= number) {
+ number = Math.round(number * decPlaces / size) / decPlaces;
+ if((number === base) && (i < abbrev.length - 1)) {
+ number = 1;
+ i++;
+ }
+ unit = abbrev[i];
+ break;
+ }
+ }
+ unit = unit ? unit : "";
+ return (number * sign).toFixed(digits) + unit;
+ };
+
+ common.number.compare = function (num1, num2) {
+ if(!common.number.isNumber(num1) || !common.number.isNumber(num2)) return "-";
+ if(num1 === 0) return 'N/A';
+ return (num2 - num1) / num1;
+ };
+
+ common.number.inRange = function (rangList, num) {
+ for(var i = 0 ; i < rangList.length - 1 ; i += 1) {
+ var start = rangList[i];
+ var end = rangList[i + 1];
+ if(start <= num && num < end) return i;
+ }
+ return rangList.length - 1;
+ };
+
+ common.number.sum = function (list, path) {
+ var total = 0;
+ $.each(list, function (i, obj) {
+ var value = common.getValueByPath(obj, path);
+ if(typeof value === "number" && !isNaN(value)) {
+ total += value;
+ }
+ });
+ return total;
+ };
+})();
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/public/js/components/chart.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/components/chart.js b/eagle-server/src/main/webapp/app/dev/public/js/components/chart.js
new file mode 100644
index 0000000..99f74d5
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/public/js/components/chart.js
@@ -0,0 +1,188 @@
+/*
+ * 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 eagleComponents = angular.module('eagle.components');
+
+ eagleComponents.service('Chart', function () {
+ return {
+ color: [ "#0073b7", "#dd4b39", "#00a65a", "#f39c12", "#605ca8", "#001F3F", "#39CCCC", "#D81B60", "#3c8dbc", "#f56954", "#00c0ef", "#3D9970", "#FF851B" , "#01FF70", "#F012BE"],
+ //color: ['#4285f4', '#c23531','#2f4554', '#61a0a8', '#d48265', '#91c7ae','#749f83', '#ca8622', '#bda29a','#6e7074', '#546570', '#c4ccd3'],
+ charts: {}
+ };
+ });
+
+ eagleComponents.directive('chart', function(Chart) {
+ var charts = Chart.charts;
+
+ function chartResize() {
+ setTimeout(function () {
+ $.each(charts, function (id, chart) {
+ chart.resize();
+ });
+ }, 310);
+ }
+
+ $(window).resize(chartResize);
+ $("body").on("expanded.pushMenu collapsed.pushMenu", chartResize);
+
+ return {
+ restrict: 'AE',
+ scope: {
+ title: "@?title",
+ series: "=",
+ category: "=?category",
+ categoryFunc: "=?categoryFunc",
+ xTitle: "@?xTitle",
+ yTitle: "@?yTitle",
+
+ option: "=?option",
+
+ click: "=?ngClick",
+
+ chart: "@?chart"
+ },
+ controller: function ($scope, $element, $attrs, Time) {
+ var i;
+ var lastTooltipEvent;
+ var chart = echarts.init($element[0]);
+ charts[chart.id] = chart;
+
+ function refreshChart() {
+ var maxYAxis = 0;
+ var legendList = [];
+ var categoryList = $scope.category ? $scope.category : [];
+
+ var seriesList = $.map($scope.series || [], function (series, id) {
+ if(id === 0 && !$scope.category) {
+ //var preDate = -1;
+ categoryList = $.map(series.data, function (point) {
+ /*ivar time = new Time(point.x);
+ f(preDate !== time.date()) {
+ preDate = time.date();
+ return Time.format(point.x, "MMM.D HH:mm");
+ }*/
+ if($scope.categoryFunc) {
+ return $scope.categoryFunc(point.x);
+ }
+ return Time.format(point.x, "HH:mm");
+ });
+ }
+
+ legendList.push(series.name);
+ if(series.yAxisIndex) maxYAxis = Math.max(series.yAxisIndex, maxYAxis);
+
+ return $.extend({}, series, {
+ data: $scope.category ? series.data : $.map(series.data, function (point) {
+ return point.y;
+ })
+ });
+ });
+
+ var yAxis = [];
+ for(i = 0 ; i <= maxYAxis ; i += 1) {
+ yAxis.push({
+ name: $scope.yTitle,
+ type: "value"
+ });
+ }
+
+ var option = {
+ color: Chart.color.concat(),
+ title: [{text: $scope.title}],
+ tooltip: {trigger: 'axis'},
+ legend: [{
+ data: legendList
+ }],
+ grid: {
+ top: '30',
+ left: '0',
+ right: '0',
+ bottom: '0',
+ containLabel: true
+ },
+ xAxis: {
+ name: $scope.xTitle,
+ type: 'category',
+ data: categoryList,
+ axisTick: { show: false }
+ },
+ yAxis: yAxis,
+ series: seriesList
+ };
+
+ if($scope.option) {
+ option = common.merge(option, $scope.option);
+ }
+
+ chart.setOption(option);
+ }
+
+ // Event handle
+ var chartClick = false;
+ chart.on("click", function (e) {
+ if($scope.click) {
+ if($scope.click(e)) {
+ refreshChart();
+ }
+ }
+ chartClick = true;
+ });
+
+ chart.getZr().on('click', function () {
+ if(!chartClick && $scope.click) {
+ if($scope.click($.extend({
+ componentType: "tooltip"
+ }, lastTooltipEvent))) {
+ refreshChart();
+ }
+ }
+ chartClick = false;
+ });
+
+ chart.on('showtip', function (e) {
+ lastTooltipEvent = e;
+ });
+
+ // Insert chart object to parent scope
+ if($attrs.chart) {
+ $scope.$parent.$parent[$attrs.chart] = chart;
+ }
+
+ chart.refresh = function () {
+ refreshChart();
+ };
+
+ // Render
+ refreshChart();
+ $scope.$watch("series", refreshChart);
+
+ $scope.$on('$destroy', function() {
+ delete charts[chart.id];
+ chart.dispose();
+
+ delete $scope.$parent.$parent[$attrs.chart];
+ });
+ },
+ template: '<div>Loading...</div>',
+ replace: true
+ };
+ });
+})();
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-server/src/main/webapp/app/dev/public/js/components/main.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/components/main.js b/eagle-server/src/main/webapp/app/dev/public/js/components/main.js
new file mode 100644
index 0000000..0c8a54c
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/public/js/components/main.js
@@ -0,0 +1,24 @@
+/*
+ * 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';
+
+ angular.module('eagle.components', []);
+})();