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:51 UTC
[10/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/ui-build.sh
----------------------------------------------------------------------
diff --git a/eagle-server/ui-build.sh b/eagle-server/ui-build.sh
new file mode 100644
index 0000000..9f17ba6
--- /dev/null
+++ b/eagle-server/ui-build.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+# 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.
+
+echo "=============== Web APP Building Start ==============="
+echo "Environment Check..."
+# Pre-build check
+if [ -z "$(command -v git)" ]
+then
+ echo "git not installed!"
+ exit 1
+fi
+if [ -z "$(command -v npm)" ]
+then
+ echo "npm not installed!"
+ exit 1
+fi
+echo "Environment Check...Pass"
+
+# npm install
+cd src/main/webapp/app
+echo "npm install..."
+npm install
+
+# grunt build
+echo "building..."
+npm run build
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/Gruntfile.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/Gruntfile.js b/eagle-webservice/src/main/webapp/Gruntfile.js
deleted file mode 100644
index d2a3a42..0000000
--- a/eagle-webservice/src/main/webapp/Gruntfile.js
+++ /dev/null
@@ -1,175 +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.
-*/
-'use strict';
-
-module.exports = function (grunt) {
- // Project configuration.
- grunt.initConfig({
- pkg: grunt.file.readJSON('package.json'),
- config: grunt.file.readJSON('grunt.json'),
-
- jshint: {
- options: {
- browser: true,
- globals: {
- $: true,
- jQuery: true,
- moment: true
- }
- },
- all: [
- 'app/**/*.js'
- ]
- },
-
- clean: {
- build: ['ui/', 'tmp/'],
- tmp: ['tmp/'],
- ui: ['ui/']
- },
- concat: {
- app: {
- src: [
- 'app/public/js/app.js',
-
- 'app/public/js/srv/main.js',
- 'app/public/js/srv/**.js',
-
- 'app/public/js/app.*.js',
-
- 'app/public/js/common.js',
-
- 'app/public/js/components/main.js',
- 'app/public/js/components/**.js',
- 'app/public/js/components/**/**.js',
-
- 'app/public/js/ctrl/main.js',
- 'app/public/js/ctrl/*.js'
- ],
- dest: 'tmp/public/js/scripts.js'
- },
- js: '<%= config.concat.js %>',
- css: {
- options: {
- process: function(src, filepath) {
- return "@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);" +
- src.replace('@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);', '');
- }
- },
- src: '<%= config.concat.css.src %>',
- dest: '<%= config.concat.css.dest %>'
- }
- },
- 'regex-replace': {
- strict: {
- src: ['tmp/public/js/scripts.js'],
- actions: [
- {
- name: 'use strict',
- search: '\\\'use strict\\\';?',
- replace: '',
- flags: 'gmi'
- },
- {
- name: 'build timestamp',
- search: '\\/\\/ GRUNT REPLACEMENT\\: eagleApp\\.buildTimestamp \\= TIMESTAMP',
- replace: 'eagleApp.buildTimestamp = ' + (+new Date()) + ';',
- flags: 'gmi'
- }
- ]
- }
- },
- uglify: {
- ui: {
- options: {
- mangle: false
- },
- files: [
- {
- src: 'tmp/public/js/scripts.js',
- dest: 'tmp/public/js/scripts.min.js'
- },
- {
- expand: true,
- src: '**/*.js',
- dest: 'tmp/feature',
- cwd: 'app/public/feature'
- }
- ]
- }
- },
- cssmin: {
- ui: {
- files: {
- 'tmp/public/css/styles.css': ['app/public/css/main.css', 'app/public/css/animation.css']
- }
- }
- },
- htmlrefs: {
- ui: {
- src: 'app/index.html',
- dest: "tmp/index.html"
- }
- },
- copy: {
- feature: {
- files: [
- {expand: true, cwd: 'app/', src: ['public/feature/**'], dest: 'tmp'}
- ]
- },
- ui: {
- files: [
- {expand: true, cwd: 'tmp/', src: ['**'], dest: 'ui'},
- {expand: true, cwd: 'app/', src: ['public/images/**', 'partials/**'], dest: 'ui'},
- {expand: true, cwd: 'node_modules/font-awesome/', src: ['fonts/**'], dest: 'ui/public'},
- {expand: true, cwd: 'node_modules/bootstrap/', src: ['fonts/**'], dest: 'ui/public'}
- ]
- }
- }
- });
-
- grunt.loadNpmTasks('grunt-contrib-jshint');
- grunt.loadNpmTasks('grunt-contrib-clean');
- grunt.loadNpmTasks('grunt-contrib-concat');
- grunt.loadNpmTasks('grunt-contrib-uglify');
- grunt.loadNpmTasks('grunt-contrib-cssmin');
- grunt.loadNpmTasks('grunt-htmlrefs');
- grunt.loadNpmTasks('grunt-regex-replace');
- grunt.loadNpmTasks('grunt-contrib-copy');
-
- grunt.registerTask('default', [
- // jshint
- 'jshint:all',
- // Clean Env
- 'clean:build',
- // Compress JS
- 'copy:feature',
- 'concat:app',
- 'regex-replace:strict',
- 'uglify',
- 'concat:js',
- // Compress CSS
- 'cssmin',
- 'concat:css',
- // Pass HTML Resources
- 'htmlrefs',
- 'copy:ui',
- // Clean Env
- 'clean:tmp'
- ]);
-};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/README.md
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/README.md b/eagle-webservice/src/main/webapp/README.md
deleted file mode 100644
index b4168d5..0000000
--- a/eagle-webservice/src/main/webapp/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Apache Eagle Web APP
-==
-
-Web client for Apache Eagle
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/index.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/index.html b/eagle-webservice/src/main/webapp/_app/index.html
new file mode 100644
index 0000000..7cd3e25
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/index.html
@@ -0,0 +1,281 @@
+<!DOCTYPE html>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<html ng-app="eagleApp" ng-controller="MainCtrl">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta charset="UTF-8">
+ <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
+ <link rel="shortcut icon" href="public/images/favicon.png">
+
+ <title>Eagle</title>
+ <link rel="shortcut icon" type="image/png" href="public/images/favicon.png">
+
+ <!-- ref:css public/css/styles.min.css -->
+ <link href="public/css/main.css" rel="stylesheet" type="text/css" media="screen">
+ <link href="public/css/animation.css" rel="stylesheet" type="text/css" media="screen">
+ <link href="../node_modules/bootstrap/dist/css/bootstrap.css" rel="stylesheet" type="text/css" media="screen">
+ <link href="../node_modules/zombiej-bootstrap-components/bootstrap-components/css/bootstrap-components.css" rel="stylesheet" type="text/css" media="screen">
+ <link href="../node_modules/zombiej-nvd3/build/nv.d3.css" rel="stylesheet" type="text/css" />
+ <link href="../node_modules/font-awesome/css/font-awesome.css" rel="stylesheet" type="text/css" />
+ <link href="../node_modules/admin-lte/dist/css/AdminLTE.css" rel="stylesheet" type="text/css" />
+ <link href="../node_modules/admin-lte/dist/css/skins/skin-blue.css" rel="stylesheet" type="text/css" />
+ <!-- endref -->
+ </head>
+ <body class="skin-blue sidebar-mini" ng-class="{'no-sidebar' : PageConfig.hideSidebar}">
+ <!-- Site wrapper -->
+ <div class="wrapper">
+ <header class="main-header">
+ <a href="#/" class="logo">
+ <span class="logo-mini"><img src="public/images/favicon_white.png" /></span>
+ <span class="logo-lg">Apache Eagle</span>
+ </a>
+ <!-- Header Navbar: style can be found in header.less -->
+ <nav class="navbar navbar-static-top" role="navigation">
+ <!-- Sidebar toggle button-->
+ <a ng-hide="PageConfig.hideSidebar" class="sidebar-toggle" data-toggle="offcanvas" role="button">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </a>
+
+ <div class="navbar-custom-menu">
+ <ul class="nav navbar-nav">
+ <!-- Admin error list -->
+ <li class="dropdown" ng-show="ServiceError.list.length">
+ <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
+ <i class="fa fa-exclamation-triangle" ng-class="{blink: ServiceError.hasUnread}"></i>
+ </a>
+ <ul class="dropdown-menu">
+ <li ng-repeat="error in ServiceError.list">
+ <a ng-click="ServiceError.showError(error);">
+ <span class="fa" ng-class="{'fa-envelope': !error._read, 'fa-check': error._read}"></span>
+ {{error.title}}
+ </a>
+ </li>
+ <li role="separator" class="divider"></li>
+ <li>
+ <a ng-click="ServiceError.clearAll();">
+ <span class="fa fa-trash"></span>
+ Clear All
+ </a>
+ </li>
+ </ul>
+ </li>
+
+ <!-- Site -->
+ <li class="dropdown" ng-show="!PageConfig.hideSite && !PageConfig.lockSite">
+ <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
+ <i class="fa fa-server"></i>
+ {{Site.current().tags.site}}
+ <i class="fa fa-caret-down"></i>
+ </a>
+ <ul class="dropdown-menu">
+ <li ng-repeat="_site in Site.list" ng-if="_site.enabled">
+ <a ng-click="Site.current(_site);">
+ <span class="fa fa-database"></span> {{_site.tags.site}}
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li class="dropdown" ng-show="PageConfig.lockSite">
+ <a>
+ <i class="fa fa-server"></i>
+ {{Site.current().tags.site}}
+ </a>
+ </li>
+
+ <!-- User -->
+ <li class="dropdown user user-menu" ng-hide="PageConfig.hideUser">
+ <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
+ <i class="fa fa-user"></i>
+ {{Auth.userProfile.username}}
+ </a>
+ <ul class="dropdown-menu">
+ <!-- User image -->
+ <li class="user-header">
+ <span class="img-circle">
+ <span class="fa fa-user" alt="User Image"></span>
+ </span>
+ <p>
+ {{Auth.userProfile.username}}
+ <small>
+ <span ng-repeat="role in Auth.userProfile.authorities">{{role.authority}} </span>
+ </small>
+ </p>
+ </li>
+ <!-- Menu Footer-->
+ <li class="user-footer">
+ <div class="pull-left" ng-if="Auth.isRole('ROLE_ADMIN')">
+ <a href="#/config/site" class="btn btn-default btn-flat">Management</a>
+ </div>
+ <div class="pull-right">
+ <a ng-click="logout();" class="btn btn-default btn-flat">Sign out</a>
+ </div>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+
+ <!-- Applications -->
+ <div ng-hide="PageConfig.hideApplication">
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#moduleMenu">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="fa fa-map"></span>
+ </button>
+ <div class="collapse navbar-collapse" id="moduleMenu">
+ <ul class="nav navbar-nav">
+ <li ng-repeat="_grp in Site.current().applicationGroupList" ng-if="_grp.enabledList.length"
+ class="dropdown" ng-class="{active: Application.current().group === _grp.name}">
+ <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
+ {{_grp.name}}
+ </a>
+ <ul class="dropdown-menu">
+ <li ng-repeat="_app in _grp.enabledList">
+ <a ng-click="Application.current(_app);">
+ <span class="fa fa-cubes"></span> {{_app.displayName}}
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </nav>
+ </header>
+
+ <!-- =============================================== -->
+ <!-- Left side column. contains the side bar -->
+ <aside class="main-sidebar" ng-hide="PageConfig.hideSidebar">
+ <!-- side bar: style can be found in sidebar.less -->
+ <section class="sidebar">
+ <ul class="sidebar-menu">
+ <li class="header">
+ {{Application.current().group || 'Application'}} >
+ {{Application.current().displayName || 'Features'}}
+ </li>
+ <li ng-repeat="page in PageConfig.navConfig.pageList track by $index" ng-class="getNavClass(page)" ng-show="getNavVisible(page)">
+ <a href="{{page.url}}">
+ <i class="fa fa-{{page.icon}}"></i> <span>{{page.title}}</span>
+ </a>
+ </li>
+ </ul>
+ </section>
+ <!-- /.sidebar -->
+ </aside>
+
+ <!-- =============================================== -->
+ <!-- Right side column. Contains the navbar and content of the page -->
+ <div class="content-wrapper">
+ <!-- Content Header (Page header) -->
+ <section class="content-header" ng-hide="PageConfig.hideSidebar">
+ <h1>
+ <span class="pageTitle">{{PageConfig.pageTitle}}</span>
+ <small class="pageSubTitle">{{PageConfig.pageSubTitle}}</small>
+ </h1>
+
+
+ <ol class="breadcrumb">
+ <li ng-repeat="navPath in PageConfig.navPath">
+ <a ng-href="#{{navPath.path}}">
+ <span class="fa fa-home" ng-if="$first"></span>
+ {{navPath.title || navPath.path}}
+ </a>
+ </li>
+ </ol>
+ </section>
+
+ <!-- Main content -->
+ <section class="content">
+ <div id="content">
+ <div ui-view></div>
+ </div>
+ </section><!-- /.content -->
+ </div><!-- /.content-wrapper -->
+
+ <footer class="main-footer">
+ <div class="pull-right hidden-xs">
+ <b>License</b>
+ <a href="http://www.apache.org/licenses/LICENSE-2.0" class="text-muted">Apache-2.0</a>
+ </div>
+ <strong>
+ Apache Eagle
+ <a target="_blank" href="https://eagle.incubator.apache.org/">Home</a> /
+ <a target="_blank" href="https://eagle.incubator.apache.org/docs/community.html">Community</a> /
+ <a target="_blank" href="https://cwiki.apache.org/confluence/display/EAG/FAQ">FAQ</a>
+ </strong>
+ </footer>
+ </div><!-- ./wrapper -->
+
+ <!-- ref:js public/js/doc.js -->
+ <script src="../node_modules/jquery/dist/jquery.js"></script>
+ <script src="../node_modules/jquery-slimscroll/jquery.slimscroll.min.js"></script>
+ <script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
+ <script src="../node_modules/zombiej-bootstrap-components/bootstrap-components/js/bootstrap-components.min.js"></script>
+ <script src="../node_modules/moment/min/moment-with-locales.min.js"></script>
+ <script src="../node_modules/moment-timezone/builds/moment-timezone-with-data.min.js"></script>
+ <script src="../node_modules/admin-lte/dist/js/app.min.js"></script>
+ <script src="../node_modules/angular/angular.js"></script>
+ <script src="../node_modules/angular-resource/angular-resource.js"></script>
+ <script src="../node_modules/angular-route/angular-route.js"></script>
+ <script src="../node_modules/angular-animate/angular-animate.js"></script>
+ <script src="../node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js"></script>
+ <script src="../node_modules/angular-ui-router/release/angular-ui-router.js"></script>
+ <script src="../node_modules/d3/d3.js"></script>
+ <script src="../node_modules/zombiej-nvd3/build/nv.d3.js"></script>
+
+ <!-- Application -->
+ <script src="public/js/app.js" type="text/javascript" charset="utf-8"></script>
+
+ <!-- Service -->
+ <script src="public/js/srv/main.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/srv/applicationSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/srv/authorizationSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/srv/entitiesSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/srv/siteSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/srv/pageSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/srv/wrapStateSrv.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/srv/uiSrv.js" type="text/javascript" charset="utf-8"></script>
+
+ <!-- Misc -->
+ <script src="public/js/app.ui.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/app.time.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/app.config.js" type="text/javascript" charset="utf-8"></script>
+
+ <script src="public/js/common.js" type="text/javascript" charset="utf-8"></script>
+
+ <!-- Components -->
+ <script src="public/js/components/main.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/components/sortTable.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/components/tabs.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/components/file.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/components/charts/line3d.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/components/nvd3.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/components/sortable.js" type="text/javascript" charset="utf-8"></script>
+
+ <!-- Controllers -->
+ <script src="public/js/ctrl/main.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/ctrl/authController.js" type="text/javascript" charset="utf-8"></script>
+ <script src="public/js/ctrl/configurationController.js" type="text/javascript" charset="utf-8"></script>
+ <!-- endref -->
+ </body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/partials/config/application.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/partials/config/application.html b/eagle-webservice/src/main/webapp/_app/partials/config/application.html
new file mode 100644
index 0000000..0bf194c
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/partials/config/application.html
@@ -0,0 +1,124 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<div class="box box-info">
+ <div class="box-header with-border">
+ <h3 class="box-title">
+ <span class="fa fa-cogs"></span>
+ Configuration
+ <small class="text-danger" ng-show="changed">
+ <span class="label label-warning label-sm">Unsaved</span>
+ </small>
+ </h3>
+ </div><!-- /.box-header -->
+
+ <div class="box-body">
+ <div class="row">
+ <div class="col-md-3">
+ <ul class="nav nav-pills nav-stacked">
+ <li class="disabled"><a>Application</a></li>
+ <li role="presentation" ng-repeat="_application in Application.list track by $index" ng-class="{active: application === _application}">
+ <a ng-click="setApplication(_application)">
+ <span class="fa fa-server"></span>
+ {{_application.tags.application}}
+ <span ng-if="_application.alias">({{_application.alias}})</span>
+ </a>
+ </li>
+
+ <li>
+ <a class="text-light-blue" ng-click="newApplication()" ng-disabled="_pageLock">
+ <span class="fa fa-plus-square"></span>
+ New Application
+ </a>
+ </li>
+ </ul>
+ </div>
+
+ <div class="col-md-9">
+ <a class="pull-right btn btn-danger btn-xs" ng-click="deleteApplication(application)" ng-disabled="_pageLock">
+ <span class="fa fa-trash-o"></span>
+ Delete Application
+ </a>
+
+ <!-- Title -->
+ <h3 class="guideline">
+ Application
+ <small>{{application.tags.application}}</small>
+ </h3>
+ <hr/>
+
+ <!-- Config -->
+ <div class="form-group">
+ <label for="displayName">Display Name</label>
+ <input type="text" class="form-control" id="displayName" placeholder="(Optional) Display name." ng-model="applications[application.tags.application].alias">
+ </div>
+ <div class="form-group">
+ <label for="applicationGroup">Group</label>
+ <input type="text" class="form-control" id="applicationGroup" placeholder="(Optional) Group name" ng-model="applications[application.tags.application].groupName">
+ </div>
+ <div class="form-group">
+ <label for="applicationDescription">Description</label>
+ <textarea id="applicationDescription" class="form-control" placeholder="(Optional) Application description" rows="2" ng-model="applications[application.tags.application].description"></textarea>
+ </div>
+ <div class="form-group">
+ <label for="applicationConfiguration">Configuration</label>
+ <span class="text-danger">{{configCheck(applications[application.tags.application].config)}}</span>
+ <textarea id="applicationConfiguration" class="form-control" placeholder="Application configuration. Feature can read this " rows="5" ng-model="applications[application.tags.application].config"></textarea>
+ </div>
+
+ <!-- Feature -->
+ <label>* Feature</label>
+ <div class="row">
+ <div class="col-sm-6">
+ <h1 class="text-muted text-center" ng-show="applications[application.tags.application].features.length === 0">No feature in using</h1>
+ <ul class="products-list product-list-in-box fixed-height" ng-show="applications[application.tags.application].features.length !== 0">
+ <li class="item" ng-repeat="feature in applications[application.tags.application].features track by $index" ng-class="{active: _feature === feature}">
+ <div class="product-operation">
+ <a class="fa fa-chevron-up" ng-click="moveFeature(feature, applications[application.tags.application].features, -1)"></a>
+ <a class="fa fa-chevron-down" ng-click="moveFeature(feature, applications[application.tags.application].features, 1)"></a>
+ </div>
+ <div class="product-info">
+ <a class="fa fa-times pull-right" ng-click="removeFeature(feature, applications[application.tags.application])"></a>
+ <span class="product-title">{{feature}}</span>
+ <span class="product-description">{{Application.featureList.set[feature].description}}</span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div class="col-sm-6">
+ <ul class="products-list product-list-in-box fixed-height">
+ <li class="item" ng-repeat="feature in applications[application.tags.application].optionalFeatures track by $index">
+ <button class="btn btn-lg btn-primary pull-left" ng-click="addFeature(feature, applications[application.tags.application])" ng-disabled="_pageLock">
+ <span class="fa fa-star-o"></span>
+ </button>
+ <div class="product-info">
+ <span class="product-title">{{feature}}</span>
+ <span class="product-description">{{Application.featureList.set[feature].description}}</span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div><!-- /.box-body -->
+
+ <div class="box-footer clearfix">
+ <button class="btn btn-primary" ng-click="saveAll()" ng-disabled="_pageLock">Save All</button>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/partials/config/feature.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/partials/config/feature.html b/eagle-webservice/src/main/webapp/_app/partials/config/feature.html
new file mode 100644
index 0000000..945d90b
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/partials/config/feature.html
@@ -0,0 +1,85 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<div class="box box-info">
+ <div class="box-header with-border">
+ <h3 class="box-title">
+ <span class="fa fa-cogs"></span>
+ Configuration
+ <small class="text-danger" ng-show="changed">
+ <span class="label label-warning label-sm">Unsaved</span>
+ </small>
+ </h3>
+ </div><!-- /.box-header -->
+
+ <div class="box-body">
+ <div class="row">
+ <div class="col-md-3">
+ <ul class="nav nav-pills nav-stacked">
+ <li class="disabled">
+ <a>Feature</a>
+ </li>
+ <li role="presentation" ng-repeat="_feature in Application.featureList" ng-class="{active: feature === _feature}">
+ <a ng-click="setFeature(_feature)">
+ <span class="fa fa-leaf" ng-class="{'text-danger': _feature._loaded === false}" uib-tooltip="Module load failed!" tooltip-enable="_feature._loaded === false"></span>
+ {{_feature.tags.feature}}
+ </a>
+ </li>
+ <li>
+ <a class="text-light-blue" ng-click="newFeature()" ng-disabled="_pageLock">
+ <span class="fa fa-plus-square"></span>
+ New Feature
+ </a>
+ </li>
+ </ul>
+ </div>
+
+ <div class="col-md-9">
+ <a class="pull-right btn btn-danger btn-xs" ng-click="deleteFeature(feature)" ng-disabled="_pageLock">
+ <span class="fa fa-trash-o"></span>
+ Delete Feature
+ </a>
+
+ <h3 class="guideline">
+ <span class="fa fa-exclamation-triangle text-danger" uib-tooltip="Module load failed!" ng-show="feature._loaded === false"></span>
+ {{feature.tags.feature}}
+ </h3>
+ <hr/>
+
+ <p class="text text-muted">
+ Will load the start up file <code>controller.js</code> from <code>public/feature/{{feature.tags.feature}}</code>.
+ If you are developing customized feature, please reference provided feature.
+ </p>
+
+ <!-- Config -->
+ <div class="form-group">
+ <label for="featureVersion">Version</label>
+ <input id="featureVersion" type="text" class="form-control" placeholder="(Optional) Feature version." ng-model="features[feature.tags.feature].version">
+ </div>
+ <div class="form-group">
+ <label for="featureDescription">Description</label>
+ <textarea id="featureDescription" class="form-control" placeholder="(Optional) Feature description." rows="10" ng-model="features[feature.tags.feature].description"></textarea>
+ </div>
+ </div>
+ </div>
+ </div><!-- /.box-body -->
+
+ <div class="box-footer clearfix">
+ <button class="btn btn-primary" ng-click="saveAll()" ng-disabled="_pageLock">Save All</button>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/partials/config/site.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/partials/config/site.html b/eagle-webservice/src/main/webapp/_app/partials/config/site.html
new file mode 100644
index 0000000..f7d43eb
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/partials/config/site.html
@@ -0,0 +1,115 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<div class="box box-info">
+ <div class="box-header with-border">
+ <h3 class="box-title">
+ <span class="fa fa-cogs"></span>
+ Configuration
+ <small class="text-danger" ng-show="changed">
+ <span class="label label-warning label-sm">Unsaved</span>
+ </small>
+ </h3>
+ </div><!-- /.box-header -->
+
+ <div class="box-body">
+ <div class="row">
+ <div class="col-md-3">
+ <ul class="nav nav-pills nav-stacked">
+ <li class="disabled"><a>Site</a></li>
+ <li role="presentation" ng-repeat="_site in Site.list track by $index" ng-class="{active: site === _site}">
+ <a ng-click="setSite(_site)">
+ <span class="fa fa-server"></span>
+ {{_site.tags.site}}
+ </a>
+ </li>
+
+ <li>
+ <a class="text-light-blue" ng-click="newSite()" ng-disabled="_pageLock">
+ <span class="fa fa-plus-square"></span>
+ New Site
+ </a>
+ </li>
+ </ul>
+ </div>
+
+ <div class="col-md-9">
+ <a class="pull-right btn btn-danger btn-xs" ng-click="deleteSite(site)" ng-disabled="_pageLock">
+ <span class="fa fa-trash-o"></span>
+ Delete Site
+ </a>
+
+ <!-- Title -->
+ <h3 class="guideline">
+ Site
+ <small>{{site.tags.site}}</small>
+ </h3>
+ <hr/>
+
+ <!-- Config -->
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" ng-checked="sites[site.tags.site].enabled" ng-click="sites[site.tags.site].enabled = !sites[site.tags.site].enabled">
+ <strong>Enabled</strong>
+ </label>
+ </div>
+ <hr/>
+
+ <!-- Application -->
+ <label>* Application</label>
+ <div class="row">
+ <div class="col-sm-6">
+ <h1 class="text-muted text-center" ng-show="sites[site.tags.site].applications.length === 0">No application in using</h1>
+ <ul class="products-list product-list-in-box fixed-height" ng-show="sites[site.tags.site].applications.length !== 0">
+ <li class="item" ng-repeat="application in sites[site.tags.site].applications track by $index" ng-class="{active: _application === application}">
+ <div class="product-operation single">
+ <span class="fa fa-cubes"></span>
+ </div>
+ <div class="product-info">
+ <a class="fa fa-times pull-right" ng-click="removeApplication(application, sites[site.tags.site])"></a>
+ <span class="product-title">
+ <a class="fa fa-cog" ng-click="setApplication(application)"></a>
+ {{application.tags.application}}
+ </span>
+ <span class="product-description">{{Application.list.set[application.tags.application].description}}</span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div class="col-sm-6">
+ <ul class="products-list product-list-in-box fixed-height">
+ <li class="item" ng-repeat="application in sites[site.tags.site].optionalApplications track by $index">
+ <button class="btn btn-lg btn-primary pull-left" ng-click="addApplication(application, sites[site.tags.site])" ng-disabled="_pageLock">
+ <span class="fa fa-star-o"></span>
+ </button>
+ <div class="product-info">
+ <span class="product-title">{{application.tags.application}}</span>
+ <span class="product-description">{{Application.list.set[application.tags.application].description}}</span>
+ </div>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div><!-- /.box-body -->
+
+ <div class="box-footer clearfix">
+ <button class="btn btn-primary" ng-click="saveAll()" ng-disabled="_pageLock">Save All</button>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/partials/landing.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/partials/landing.html b/eagle-webservice/src/main/webapp/_app/partials/landing.html
new file mode 100644
index 0000000..a2e0f47
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/partials/landing.html
@@ -0,0 +1,30 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<p class="lead">
+ <span ng-if="!Application.current()">Current site do not use any application.</span>
+ <span ng-if="Application.current()">Current application do not install any feature.</span>
+
+ <span ng-if="Auth.isRole('ROLE_ADMIN')">
+ Click
+ <a href="#/config/site" ng-if="!Application.current()">here</a>
+ <a href="#/config/application" ng-if="Application.current()">here</a>
+ to configure.
+ </span>
+ <span ng-if="!Auth.isRole('ROLE_ADMIN')">Please contact your admin.</span>
+</p>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/partials/login.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/partials/login.html b/eagle-webservice/src/main/webapp/_app/partials/login.html
new file mode 100644
index 0000000..7faef42
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/partials/login.html
@@ -0,0 +1,54 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<div class="login-box">
+ <div class="login-logo">
+ <a href="#/">Apache Eagle</a>
+ </div>
+
+ <div class="login-box-body" ng-show="!loginSuccess">
+ <p class="login-box-msg">Sign in to start your session</p>
+ <div class="form-group has-feedback">
+ <input type="text" class="form-control" placeholder="User Name" ng-model="username" ng-keypress="login($event)" autocomplete="off" id="username">
+ <span class="glyphicon glyphicon-user form-control-feedback"></span>
+ </div>
+ <div class="form-group has-feedback">
+ <input type="password" class="form-control" placeholder="Password" ng-model="password" ng-keypress="login($event)">
+ <span class="glyphicon glyphicon-lock form-control-feedback"></span>
+ </div>
+ <div class="row">
+ <div class="col-xs-8">
+ <div class="checkbox">
+ <label> <input type="checkbox" ng-checked="rememberUser" ng-click="rememberUser = !rememberUser;" /> Remember Me
+ </label>
+ </div>
+ </div>
+ <div class="col-xs-4">
+ <button class="btn btn-primary btn-block btn-flat" ng-click="login($event, true)" ng-disabled="lock">Sign In</button>
+ </div>
+ </div>
+ </div>
+
+ <div class="login-box-body text-center" ng-show="loginSuccess">
+ <p class="login-box-msg">Login success</p>
+ <p>
+ <span class="fa fa-refresh fa-spin"></span>
+ Loading environment...
+ </p>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/public/css/animation.css
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/css/animation.css b/eagle-webservice/src/main/webapp/_app/public/css/animation.css
new file mode 100644
index 0000000..954bd29
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/css/animation.css
@@ -0,0 +1,46 @@
+@CHARSET "UTF-8";
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+[ui-view].ng-enter, [ui-view].ng-leave {
+ position: absolute;
+ left: 0;
+ right: 0;
+ -webkit-transition: all .5s ease-in-out;
+ -moz-transition: all .5s ease-in-out;
+ -o-transition: all .5s ease-in-out;
+ transition: all .3s ease-in-out;
+}
+
+[ui-view].ng-enter {
+ opacity: 0;
+}
+
+[ui-view].ng-enter-active {
+ opacity: 1;
+}
+
+[ui-view].ng-leave {
+ opacity: 1;
+ transform:translate3d(0, 0, 0);
+}
+
+[ui-view].ng-leave-active {
+ opacity: 0;
+ transform:translate3d(20%, 0, 0);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/afb89794/eagle-webservice/src/main/webapp/_app/public/css/main.css
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/css/main.css b/eagle-webservice/src/main/webapp/_app/public/css/main.css
new file mode 100644
index 0000000..a7eba4b
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/css/main.css
@@ -0,0 +1,805 @@
+@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.
+ */
+
+/* Frame */
+body.no-sidebar .content-wrapper {
+ margin-left: 0;
+
+ -webkit-transition: none;
+ -moz-transition: none;
+ -o-transition: none;
+ transition: none;
+}
+
+body.no-sidebar .main-footer {
+ margin-left: 0;
+}
+
+/* Navigation */
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header .img-circle {
+ display: inline-block;
+ border: 3px solid;
+ border-color: rgba(255,255,255,0.2);
+ width: 90px;
+ height: 90px;
+ margin-top: 10px;
+}
+
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header .fa {
+ font-size: 60px;
+ color: rgba(255,255,255,0.8);
+ margin-top: 10px;
+}
+
+ /* Common */
+a {
+ cursor: pointer;
+}
+
+/* Table */
+.table.table-sm>tbody>tr>td,
+.table.table-sm>tbody>tr>th,
+.table.table-sm>tfoot>tr>td,
+.table.table-sm>tfoot>tr>th,
+.table.table-sm>thead>tr>td,
+.table.table-sm>thead>tr>th{
+ padding: 3px 8px;
+}
+
+.table thead th .fa.fa-sort,
+.table thead th .fa.fa-sort-asc,
+.table thead th .fa.fa-sort-desc {
+ margin-top: 5px;
+ opacity: 0.3;
+ float: right;
+}
+.table thead th:hover .fa.fa-sort,
+.table thead th:hover .fa.fa-sort-asc,
+.table thead th:hover .fa.fa-sort-desc {
+ opacity: 0.8;
+}
+
+.table tr th,
+.table tr td {
+ -webkit-transition: background .5s linear;
+ -o-transition: background .5s linear;
+ transition: background .5s linear;
+}
+
+.sortTable-cntr .pagination {
+ margin-top: 0;
+}
+
+.table th.input-field,
+.table td.input-field {
+ padding: 0;
+ vertical-align: middle;
+}
+
+.table th.input-field > input,
+.table td.input-field > input,
+.table th.input-field > select,
+.table td.input-field > select {
+ border: none;
+ transition: border-color 0s;
+}
+
+.table th.input-field > input:focus,
+.table td.input-field > input:focus,
+.table th.input-field > select:focus,
+.table td.input-field > select:focus {
+ box-shadow: inset 1px 1px 0px #3c8dbc, inset -1px -1px 0px #3c8dbc;
+}
+
+.table th.input-field > input.has-warning,
+.table td.input-field > input.has-warning {
+ box-shadow: inset 1px 1px 0px #f39c12, inset -1px -1px 0px #f39c12;
+}
+
+/* Box */
+.small-box > a.inner {
+ color: #FFF;
+ display: block;
+}
+
+.small-box > a.inner h3 {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ font-size: 32px;
+}
+
+.info-box.bg-gray,
+.info-box a {
+ color: #FFFFFF;
+}
+.info-box a:hover {
+ color: #FFFFFF;
+ text-decoration: underline;
+}
+
+.info-box-content a.config {
+ color: rgba(255,255,255,0.8);
+}
+.info-box-content a.config:hover {
+ color: #FFFFFF;
+}
+
+.info-box-content.box-clickable {
+ box-shadow: 0 0 3px;
+}
+.box-clickable {
+ cursor: pointer;
+}
+
+.info-box-content .info-box-text.text-large {
+ font-size: 26px;
+ margin: 5px 0 10px 0;
+}
+
+/* inline group */
+.inline-group dl,
+.inline-group dl dt,
+.inline-group dl dd {
+ display: inline-block;
+}
+
+.inline-group dl {
+ margin-right: 35px;
+}
+.inline-group dl dt {
+ margin-right: 20px;
+}
+
+.inline-group.form-inline {
+ margin-top: 5px;
+}
+.inline-group dl {
+ margin-right: 25px;
+}
+.inline-group dl dt {
+ margin-right: 5px;
+}
+
+/* Search box */
+.search-box {
+ position: relative;
+ margin-bottom: 15px;
+}
+.search-box input[type="search"] {
+ padding-left: 26px;
+}
+.search-box .fa.fa-search {
+ position: absolute;
+ top: 8px;
+ left: 8px;
+ z-index: 2;
+ pointer-events: none;
+ color: #999;
+}
+
+/* Navigation Tab */
+ul.nav.nav-tabs li .btn {
+ margin-top: 1px;
+}
+
+.modal-body ul.nav.nav-tabs {
+ border-bottom-color: #F4F4F4;
+ margin-bottom: 15px;
+}
+
+.modal-body ul.nav.nav-tabs li {
+ border-top: 3px solid #FFFFFF;
+ margin-right: 3px;
+}
+.modal-body ul.nav.nav-tabs li.active {
+ border-top-color: #3c8dbc;
+}
+
+.modal-body ul.nav.nav-tabs li > a,
+.modal-body ul.nav.nav-tabs li > a:active,
+.modal-body ul.nav.nav-tabs li > a:hover {
+ border: none;
+ border-radius: 0;
+ margin: 0;
+ padding: 6px 15px 8px 15px;
+ color: #444;
+}
+.modal-body ul.nav.nav-tabs li:not(.active) > a:hover {
+ background: rgba(0,0,0,0);
+ color: #999;
+}
+.modal-body ul.nav.nav-tabs li.active > a {
+ border-left: 1px solid #F4F4F4;
+ border-right: 1px solid #F4F4F4;
+}
+
+/* Step Navigation */
+.step-cntr .step {
+ background: #3c8dbc;
+ margin: 0 0 20px 0;
+ color: #FFF;
+ height: 60px;
+ border-radius: 3px;
+ box-shadow: 0 1px 1px rgba(0,0,0,0.1);
+ display: block;
+
+ -webkit-transition: background .15s linear;
+ -o-transition: background .15s linear;
+ transition: background .15s linear;
+}
+.step-cntr .step.active {
+ background: #f39c12;
+}
+
+.step-cntr .step h1,
+.step-cntr .step h2,
+.step-cntr .step p {
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.step-cntr .step h1 {
+ display: inline-block;
+ font-size: 30px;
+ float: left;
+ border-right: 2px solid rgba(255,255,255,0.2);
+ width: 60px;
+ height: 60px;
+ text-align: center;
+ padding-top: 12px;
+ margin-right: 10px;
+}
+.step-cntr .step h2 {
+ font-size: 18px;
+ padding: 8px 0 5px 0;
+}
+
+/* Panel */
+.panel-group.panel-group-sm .panel .panel-heading {
+ padding: 5px 6px 5px 10px;
+}
+.panel-group.panel-group-sm .panel .panel-heading h4 {
+ font-size: 14px;
+}
+.panel-group.panel-group-sm .panel .panel-heading h4 a {
+ display: block;
+}
+.panel-group.panel-group-sm .panel .panel-heading .pull-right {
+ padding-left: 5px;
+ padding-right: 5px;
+ border-radius: 3px;
+}
+
+/* Drop Down */
+.dropdown-menu > li.danger > a {
+ color: #dd4b39;
+}
+.dropdown-menu > li.danger > a:hover {
+ color: #FFFFFF;
+ background: #dd4b39;
+}
+
+/* Drop Down */
+.dropdown-menu.left {
+ right: 0;
+ left: auto;
+}
+
+.dropdown-submenu{position:relative;}
+.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;}
+.dropdown-submenu:hover>.dropdown-menu{display:block;}
+.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;}
+.dropdown-submenu:hover>a:after{border-left-color:#ffffff;}
+.dropdown-submenu.pull-left{float:none;}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;}
+
+/* Input Group */
+.input-group .input-group-btn select {
+ width: auto;
+}
+
+/* Form group */
+.form-group .checkbox {
+ display: inline;
+ margin-right: 10px;
+}
+
+.form-group select.has-warning,
+.form-group input.has-warning {
+ border-color: #f39c12;
+ box-shadow: none;
+}
+
+.checkbox.noMargin {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+
+/* UL */
+ul.path {
+ margin-left: 0;
+}
+
+ul.path li {
+ padding: 0;
+ margin-right: 5px;
+}
+ul.path li a {
+ color: #FFFFFF;
+}
+
+ul.tree {
+ padding: 0 0 0 5px;
+}
+
+ul.tree > li,
+ul.tree > li > ul > li {
+ list-style-type: none;
+}
+
+ul.tree .tree-item .hover {
+ display: none;
+}
+ul.tree .tree-item:hover .hover {
+ display: inline-block;
+}
+
+ul.tree > li > ul {
+ padding: 0 0 0 25px;
+}
+
+ul.tree > li > ul > li.active {
+ background: #F4F4F4;
+}
+
+ul.tree.tree-bordered {
+ border: 1px solid #f4f4f4;
+}
+ul.tree.tree-bordered,
+ul.tree.tree-bordered > li > ul {
+ padding: 0;
+}
+ul.tree.tree-bordered > li:not(:last-child) {
+ border-bottom: 1px solid #f4f4f4;
+}
+ul.tree.tree-bordered > li > ul > li {
+ border-top: 1px solid #f4f4f4;
+}
+ul.tree.tree-bordered > li > span,
+ul.tree.tree-bordered > li > a {
+ display: block;
+ padding: 8px;
+}
+ul.tree.tree-bordered > li > ul > li > span,
+ul.tree.tree-bordered > li > ul > li > a {
+ display: block;
+ padding: 8px 8px 8px 30px;
+}
+
+.product-list-in-box > .item {
+ -webkit-transition: background .5s linear;
+ -o-transition: background .5s linear;
+ transition: background .5s linear;
+}
+.product-list-in-box > .item.ng-animate {
+ transition: 0s;
+}
+.product-list-in-box > .item.active {
+ background: #F5FAFC;
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+}
+
+.nav.fixed-height,
+.products-list.fixed-height {
+ height: 402px;
+ overflow-y: auto;
+}
+
+.products-list .product-operation {
+ float: left;
+ border: 1px solid #9EC8E0;
+ border-radius: 5px;
+ overflow: hidden;
+}
+
+.products-list .product-operation .fa {
+ display: block;
+ padding: 4px 16px;
+ color: #3c8dbc;
+}
+.products-list .product-operation a.fa:hover {
+ color: #FFFFFF;
+ background: #337ab7;
+}
+
+.products-list .product-operation.single .fa {
+ padding: 12px 12px;
+ font-size: 20px;
+}
+
+.products-list .item .product-info a.fa.fa-times {
+ display: none;
+}
+.products-list .item:hover .product-info a.fa.fa-times {
+ display: block;
+}
+
+/* Label */
+.label.label-default {
+ color: #FFFFFF;
+}
+
+.label.label-sm {
+ padding: .0em .4em .1em;
+}
+
+/* Row */
+.row.narrow {
+ margin-left: -5px;
+ margin-right: -5px;
+ margin-bottom: -10px;
+}
+
+.row.narrow>.col-xs-1, .row.narrow>.col-sm-1, .row.narrow>.col-md-1, .row.narrow>.col-lg-1, .row.narrow>.col-xs-2, .row.narrow>.col-sm-2, .row.narrow>.col-md-2, .row.narrow>.col-lg-2, .row.narrow>.col-xs-3, .row.narrow>.col-sm-3, .row.narrow>.col-md-3, .row.narrow>.col-lg-3, .row.narrow>.col-xs-4, .row.narrow>.col-sm-4, .row.narrow>.col-md-4, .row.narrow>.col-lg-4, .row.narrow>.col-xs-5, .row.narrow>.col-sm-5, .row.narrow>.col-md-5, .row.narrow>.col-lg-5, .row.narrow>.col-xs-6, .row.narrow>.col-sm-6, .row.narrow>.col-md-6, .row.narrow>.col-lg-6, .row.narrow>.col-xs-7, .row.narrow>.col-sm-7, .row.narrow>.col-md-7, .row.narrow>.col-lg-7, .row.narrow>.col-xs-8, .row.narrow>.col-sm-8, .row.narrow>.col-md-8, .row.narrow>.col-lg-8, .row.narrow>.col-xs-9, .row.narrow>.col-sm-9, .row.narrow>.col-md-9, .row.narrow>.col-lg-9, .row.narrow>.col-xs-10, .row.narrow>.col-sm-10, .row.narrow>.col-md-10, .row.narrow>.col-lg-10, .row.narrow>.col-xs-11, .row.narrow>.col-sm-11, .row.narrow>.col-md-11, .
row.narrow>.col-lg-11, .row.narrow>.col-xs-12, .row.narrow>.col-sm-12, .row.narrow>.col-md-12, .row.narrow>.col-lg-12 {
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+.row.narrow > [class^="col-"],
+.row.narrow > [class*=" col-"] {
+ margin-bottom: 10px;
+}
+
+/* Chart */
+.sortable-mock-element .nvd3-chart-wrapper {
+ background: #FFFFFF;
+ opacity: 0.8;
+}
+
+.sortable-enter .nvd3-chart-wrapper {
+ border-color: #3c8dbc;
+ pointer-events: none;
+}
+.sortable-enter .nvd3-chart-wrapper .nvtooltip {
+ display: none;
+}
+
+.nvd3-chart-wrapper {
+ position: relative;
+ border: 1px solid rgba(0,0,0,0.1);
+}
+.nvd3-chart-wrapper:hover {
+ //border-color: #F4F4F4;
+}
+
+.nvd3-chart-wrapper .nvd3-chart-config {
+ position: absolute;
+ top: 1px;
+ right: 1px;
+ display: none;
+ border-radius: 0;
+ padding: 0 5px;
+ background: rgba(0,0,0,0.7);
+}
+.nvd3-chart-wrapper:hover .nvd3-chart-config {
+ display: block;
+}
+
+.nvd3-chart-wrapper .nvd3-chart-config a {
+ color: rgba(255,255,255, 0.9);
+ padding: 5px 2px 4px 2px;
+ font-size: 16px;
+}
+.nvd3-chart-wrapper .nvd3-chart-config a:hover {
+ color: #FFFFFF;
+}
+
+.nvd3-chart-cntr {
+ padding: 5px;
+}
+
+.nvd3-chart-cntr > h3 {
+ text-align: center;
+ font-size: 16px;
+ font-weight: bolder;
+ margin: 0;
+ padding: 5px 0;
+
+ overflow:hidden;
+ text-overflow:ellipsis;
+
+}
+
+.nvd3-chart-cntr > svg.nvd3-svg {
+ height: 200px;
+}
+
+.nvd3-chart-cntr.lg > svg.nvd3-svg {
+ height: 400px;
+}
+
+/* Tab */
+body .tab-content>.tab-pane {
+ display: block;
+ height: 0px;
+ overflow: hidden;
+ position: relative;
+}
+body .tab-content>.tab-pane.active {
+ height: auto;
+ overflow-x: visible;
+ overflow-y: visible;
+}
+
+body .modal-body .nav-pills > li > a,
+body .box-body .nav-pills > li > a {
+ padding: 5px 15px;
+ border: none;
+}
+
+body .modal-body .nav-stacked > li {
+ border-bottom: 1px solid #f4f4f4;
+ margin: 0;
+}
+body .modal-body .nav-stacked > li:last-child {
+ border-bottom: none;
+}
+
+body .box-body .nav-tabs-custom {
+ box-shadow: none;
+ margin-bottom: 0;
+}
+body .box-body .nav-tabs-custom > .nav-tabs > li:first-of-type.active > a {
+ border-left-color: #f4f4f4;
+}
+body .box-body .nav-tabs-custom > .nav-tabs > li > a {
+ padding: 8px 15px;
+}
+body .box-body .nav-tabs-custom > .tab-content {
+ padding: 10px 0;
+}
+
+/* Box */
+.box .guideline {
+ margin-top: 0;
+}
+
+.box.inner-box {
+ border: none;
+ box-shadow: none;
+ padding: 5px 10px;
+ margin: 0;
+ border-bottom: 1px solid #f4f4f4;
+ position: relative;
+ border-radius: 0;
+}
+
+.box.inner-box .box-title {
+ margin: 0 5px 5px 0;
+ padding: 0;
+ font-size: 16px;
+ font-weight: bolder;
+ display: inline-block;
+ word-break: break-all;
+}
+
+.box.inner-box .box-tools {
+ position: absolute;
+ top: 0;
+ right: 0;
+}
+
+.box.inner-box:last-child {
+ border-bottom: none;
+}
+
+/* Navigation Tab */
+.nav-tabs-custom {
+ position: relative;
+}
+
+.nav-tabs-custom .box-tools {
+ position: absolute;
+ right: 15px;
+ top: 8px;
+}
+
+.nav-tabs-custom .box-tools .strong {
+ font-weight: bolder;
+}
+
+/* Customize */
+#content {
+ position: relative;
+}
+
+.page-fixed {
+ position: absolute;
+ top: -45px;
+ right: 0;
+}
+
+@media (max-width:991px) {
+ .page-fixed {
+ top: -70px;
+ }
+}
+
+.fixed-right {
+ position: absolute;
+ right: 0;
+ z-index: 3;
+}
+
+.main-header .logo img {
+ height: 34px;
+}
+
+.main-header .navbar-toggle {
+ float: none;
+ border-radius: 0;
+}
+.main-header .navbar-toggle:hover {
+ background: rgba(0, 0, 0, 0.1);
+}
+
+#moduleMenu > ul > li.active > a {
+ border-top: 3px solid rgba(255,255,255,0.8);
+ padding-top: 12px;
+}
+
+@media (max-width: 767px) {
+ #moduleMenu > ul > li.active > a {
+ padding: 10px 15px;
+ border-top: none;
+ border-left: 3px solid rgba(255,255,255,0.8);
+ }
+
+ .main-header .navbar .navbar-custom-menu .nav .dropdown-menu li a {
+ color: #333;
+ }
+ .main-header .navbar .navbar-custom-menu .nav .dropdown-menu li a:hover {
+ color: #FFF;
+ }
+}
+
+#timeRangePickerCntr .navbar-form {
+ display: inline-block;
+ padding-right: 0;
+}
+
+#timeRangePickerCntr #timeRangePicker {
+ min-width: 300px;
+}
+
+body .login-box, body .register-box {
+ margin: 3% auto;
+}
+
+.content-header > .breadcrumb > li {
+ font-size: 14px;
+}
+
+.daterangepicker .ranges {
+ width: 110px!important;
+}
+.daterangepicker .daterangepicker_start_input,
+.daterangepicker .daterangepicker_end_input {
+ display: block!important;
+ padding: 0!important;
+ float: none!important;
+}
+.daterangepicker .daterangepicker_start_input .input-mini,
+.daterangepicker .daterangepicker_end_input .input-mini {
+ width: 110px!important;
+}
+
+.form-group.inner-icon {
+ position: relative;
+}
+.form-group.inner-icon .fa {
+ position: absolute;
+ left: 10px;
+ top: 10px;
+}
+.form-group.inner-icon input {
+ padding-left: 35px;
+}
+
+#autoRefreshCntr > a {
+ border: none;
+ opacity: 0.3;
+}
+#autoRefreshCntr.autoRefresh > a {
+ opacity: 1;
+}
+
+.table-responsive .row {
+ margin: 0;
+}
+
+
+/* Misc */
+body .tooltip-inner {
+ max-width: 500px;
+}
+
+.text-nowrap {
+ white-space: nowrap;
+}
+
+.text-ellipsis,
+.label.text-ellipsis {
+ overflow:hidden;
+ text-overflow:ellipsis;
+ display: inline-block;
+ white-space: nowrap;
+ max-width: 100%;
+}
+td.text-ellipsis {
+ display: table-cell;
+}
+
+.text-breakall {
+ max-width: 100%;
+ display: inline-block;
+ word-wrap: break-word;
+}
+
+.btn.btn-xs.sm {
+ font-size: 12px;
+ padding: 2px 6px;
+}
+
+.form-control.input-xs {
+ height: 24px;
+ padding: 2px 8px;
+ font-size: 12px;
+ line-height: 100%;
+}
+
+pre.noWrap {
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ margin: 0;
+ padding: 0;
+}
+
+.noSelect {
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+}
+
+.blink {
+ animation: blinker 1s linear infinite;
+}
+
+@keyframes blinker {
+ 50% {opacity: 0.0;}
+}
\ 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/classification/controller.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/classification/controller.js b/eagle-webservice/src/main/webapp/_app/public/feature/classification/controller.js
new file mode 100644
index 0000000..462b41b
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/feature/classification/controller.js
@@ -0,0 +1,358 @@
+/*
+ * 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("classification");
+ var eagleApp = angular.module('eagleApp');
+
+ // ==============================================================
+ // = Function =
+ // ==============================================================
+
+ // =============================================================
+ // = Sensitivity =
+ // =============================================================
+ feature.navItem("sensitivity", "Classification", "user-secret");
+ feature.controller('sensitivity', function(PageConfig, Site, $scope, Application, Entities, UI) {
+ PageConfig.pageTitle = "Data Classification";
+ PageConfig.pageSubTitle = Site.current().tags.site;
+ $scope.ajaxId = eagleApp._TRS();
+ $scope.viewConfig = Application.current().configObj.view;
+
+ if(!$scope.viewConfig) {
+ $.dialog({
+ title: "OPS",
+ content: "View configuration not defined in Application."
+ });
+ return;
+ }
+
+ // ===================== Function =====================
+ $scope.export = function() {
+ var _data = {};
+ UI.fieldConfirm({title: "Export Classification", confirm: false, size: "large"}, _data, [
+ {name: "Data", field: "data", type: "blob", rows: 20, optional: true, readonly: true}]
+ );
+
+ Entities.queryEntities($scope.viewConfig.service, {site: Site.current().tags.site})._promise.then(function(data) {
+ _data.data = JSON.stringify(data, null, "\t");
+ });
+ };
+
+ $scope.import = function() {
+ UI.fieldConfirm({title: "Import Classification", size: "large"}, {}, [
+ {name: "Data", field: "data", type: "blob", rows: 20, optional: true}
+ ], function(entity) {
+ var _list = common.parseJSON(entity.data, false);
+ if(!_list) {
+ return "Invalid JSON format";
+ }
+ if(!$.isArray(_list)) {
+ return "Not an array";
+ }
+ }).then(null, null, function(holder) {
+ Entities.updateEntity($scope.viewConfig.service, common.parseJSON(holder.entity.data, []), {timestamp: false})._promise.then(function() {
+ holder.closeFunc();
+ location.reload();
+ });
+ });
+ };
+
+ $scope.deleteAll = function() {
+ UI.deleteConfirm("All the Classification Data").then(null, null, function(holder) {
+ Entities.deleteEntities($scope.viewConfig.service, {site: Site.current().tags.site})._promise.then(function() {
+ holder.closeFunc();
+ location.reload();
+ });
+ });
+ };
+ });
+ // =============================================================
+ // = Sensitivity - Job =
+ // =============================================================
+ feature.controller('sensitivityViewJob', function(Site, $scope, $wrapState, Entities) {
+ $scope.items = [];
+
+ // Mark sensitivity
+ $scope._oriItem = {};
+ $scope._markItem = {};
+
+ // ======================= View =======================
+ // Item
+ $scope.updateItems = function() {
+ $scope.items = Entities.query($scope.viewConfig.api, {site: Site.current().tags.site});
+ };
+
+
+ $scope.updateItems();
+
+ // =================== Sensitivity ===================
+ $scope.markSensitivity = function(item) {
+ $scope._oriItem = item;
+ $scope._markItem = {
+ prefix: $scope.viewConfig.prefix,
+ tags: {
+ site: Site.current().tags.site
+ },
+ sensitivityType: ""
+ };
+
+ $scope._markItem.tags[$scope.viewConfig.keys[0]] = item.jobId;
+ $("#sensitivityMDL").modal();
+ };
+ $scope.confirmUpateSensitivity = function() {
+ $scope._oriItem.sensitiveType = $scope._markItem.sensitivityType;
+ Entities.updateEntity($scope.viewConfig.service, $scope._markItem, {timestamp: false})._promise.success(function(data) {
+ Entities.dialog(data);
+ });
+ $("#sensitivityMDL").modal('hide');
+ };
+ $scope.unmarkSensitivity = function(item) {
+ $.dialog({
+ title: "Unmark Confirm",
+ content: "Do you want to remove the sensitivity mark on '" + item.jobId + "'?",
+ confirm: true
+ }, function(ret) {
+ if(!ret) return;
+
+ var _cond = {site: Site.current().tags.site};
+ _cond[$scope.viewConfig.keys[0]] = item.jobId;
+ Entities.deleteEntities($scope.viewConfig.service, _cond);
+
+ item.sensitiveType = null;
+ $scope.$apply();
+ });
+ };
+ });
+ // =============================================================
+ // = Sensitivity - Folder =
+ // =============================================================
+ feature.controller('sensitivityViewFolder', function(Site, $scope, $wrapState, Entities) {
+ $scope.path = $wrapState.param.path || "/";
+ $scope.pathUnitList = [];
+ $scope.items = [];
+
+ // Mark sensitivity
+ $scope._oriItem = {};
+ $scope._markItem = {};
+
+ // ======================= View =======================
+ // Path
+ function _refreshPathUnitList(_path) {
+ var _start,_current, _unitList = [];
+ _path = _path + (_path.match(/\/$/) ? "" : "/");
+ for(_current = _start = 0 ; _current < _path.length ; _current += 1) {
+ if(_path[_current] === "/") {
+ _unitList.push({
+ name: _path.substring(_start, _current + (_current === 0 ? 1 : 0)),
+ path: _path.substring(0, _current === 0 ? 1 : _current)
+ });
+ _start = _current + 1;
+ }
+ }
+ $scope.pathUnitList = _unitList;
+ }
+
+ // Item
+ $scope.updateItems = function(path) {
+ if(path) $scope.path = path;
+
+ $scope.items = Entities.query($scope.viewConfig.api, {site: Site.current().tags.site, path: $scope.path});
+ $scope.items._promise.success(function(data) {
+ Entities.dialog(data, function() {
+ if($scope.path !== "/") $scope.updateItems("/");
+ });
+ });
+ _refreshPathUnitList($scope.path);
+ };
+
+ $scope.getFileName = function(item) {
+ return (item.resource + "").replace(/^.*\//, "");
+ };
+
+ $scope.updateItems($scope.path);
+
+ // =================== Sensitivity ===================
+ $scope.markSensitivity = function(item) {
+ $scope._oriItem = item;
+ $scope._markItem = {
+ prefix: $scope.viewConfig.prefix,
+ tags: {
+ site: Site.current().tags.site
+ },
+ sensitivityType: ""
+ };
+ $scope._markItem.tags[$scope.viewConfig.keys[0]] = item.resource;
+ $("#sensitivityMDL").modal();
+ };
+ $scope.confirmUpateSensitivity = function() {
+ $scope._oriItem.sensitiveType = $scope._markItem.sensitivityType;
+ Entities.updateEntity($scope.viewConfig.service, $scope._markItem, {timestamp: false})._promise.success(function(data) {
+ Entities.dialog(data);
+ });
+ $("#sensitivityMDL").modal('hide');
+ };
+ $scope.unmarkSensitivity = function(item) {
+ $.dialog({
+ title: "Unmark Confirm",
+ content: "Do you want to remove the sensitivity mark on '" + item.resource + "'?",
+ confirm: true
+ }, function(ret) {
+ if(!ret) return;
+
+ var _cond = {site: Site.current().tags.site};
+ _cond[$scope.viewConfig.keys[0]] = item.resource;
+ Entities.deleteEntities($scope.viewConfig.service, _cond);
+
+ item.sensitiveType = null;
+ $scope.$apply();
+ });
+ };
+ });
+
+ // =============================================================
+ // = Sensitivity - Table =
+ // =============================================================
+ feature.controller('sensitivityViewTable', function(Site, $scope, Entities) {
+ $scope.databases = null;
+ $scope.table = null;
+
+ // Mark sensitivity
+ $scope._oriItem = {};
+ $scope._markItem = {};
+
+ // ======================= View =======================
+ var _fillAttr = function(list, key, target) {
+ list._promise.then(function() {
+ $.each(list, function(i, unit) {
+ unit[key] = unit[target];
+ });
+ });
+ return list._promise;
+ };
+
+ $scope.loadDatabases = function(database) {
+ var _dbs = Entities.query($scope.viewConfig.api.database, {site: Site.current().tags.site});
+ return _fillAttr(_dbs, "database", $scope.viewConfig.mapping.database).then(function() {
+ if($scope.databases) {
+ $.each($scope.databases, function(i, oriDB) {
+ var db = common.array.find(oriDB.resource, _dbs, "resource");
+ if(db) {
+ db.show = oriDB.show;
+ db.tables = oriDB.tables;
+ }
+ });
+ }
+ $scope.databases = _dbs;
+ });
+ };
+ $scope.loadDatabases();
+
+ $scope.loadTables = function(database, force) {
+ var _tables, _qry;
+ if(database.tables && !force) return;
+ _qry = {
+ site: Site.current().tags.site
+ };
+ _qry[$scope.viewConfig.mapping.database] = database[$scope.viewConfig.mapping.database];
+ _tables = Entities.query($scope.viewConfig.api.table, _qry);
+ if(!database.tables) database.tables = _tables;
+ _fillAttr(_tables, "table", $scope.viewConfig.mapping.table);
+ return _fillAttr(_tables, "database", $scope.viewConfig.mapping.database).then(function() {
+ database.tables = _tables;
+ });
+ };
+
+ $scope.loadColumns = function(database, table) {
+ $scope.table = table;
+
+ if(table.columns) return;
+ var _qry = {
+ site: Site.current().tags.site
+ };
+ _qry[$scope.viewConfig.mapping.database] = database[$scope.viewConfig.mapping.database];
+ _qry[$scope.viewConfig.mapping.table] = table[$scope.viewConfig.mapping.table];
+ table.columns = Entities.query($scope.viewConfig.api.column, _qry);
+ _fillAttr(table.columns, "column", $scope.viewConfig.mapping.column);
+ };
+
+ $scope.refreshData = function() {
+ $scope.loadDatabases().then(function() {
+ if(!$scope.table) return;
+
+ var _table = $scope.table;
+ var _db = common.array.find($scope.table.database, $scope.databases, "database");
+ if(_db) {
+ $scope.loadTables(_db, true).then(function() {
+ $scope.table = common.array.find(_table.table, _db.tables, "table");
+ $scope.table.columns = _table.columns;
+ });
+ }
+ });
+ };
+
+ // =================== Sensitivity ===================
+ $scope.markSensitivity = function(item, event) {
+ if(event) event.stopPropagation();
+
+ $scope._oriItem = item;
+ $scope._markItem = {
+ prefix: $scope.viewConfig.prefix,
+ tags: {
+ site: Site.current().tags.site
+ },
+ sensitivityType: ""
+ };
+ $scope._markItem.tags[$scope.viewConfig.keys[0]] = item.resource;
+ $("#sensitivityMDL").modal();
+ };
+ $scope.confirmUpateSensitivity = function() {
+ $scope._oriItem.sensitiveType = $scope._markItem.sensitivityType;
+ Entities.updateEntity($scope.viewConfig.service, $scope._markItem, {timestamp: false})._promise.success(function(data) {
+ Entities.dialog(data);
+ $scope.refreshData();
+ });
+ $("#sensitivityMDL").modal('hide');
+ };
+ $scope.unmarkSensitivity = function(item, event) {
+ if(event) event.stopPropagation();
+
+ $.dialog({
+ title: "Unmark Confirm",
+ content: "Do you want to remove the sensitivity mark on '" + item.resource + "'?",
+ confirm: true
+ }, function(ret) {
+ if(!ret) return;
+
+ var _qry = {
+ site: Site.current().tags.site
+ };
+ _qry[$scope.viewConfig.keys[0]] = item.resource;
+ Entities.deleteEntities($scope.viewConfig.service, _qry)._promise.then(function() {
+ $scope.refreshData();
+ });
+
+ item.sensitiveType = null;
+ $scope.$apply();
+ });
+ };
+ });
+})();
\ 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/classification/page/sensitivity.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/classification/page/sensitivity.html b/eagle-webservice/src/main/webapp/_app/public/feature/classification/page/sensitivity.html
new file mode 100644
index 0000000..41fb291
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/feature/classification/page/sensitivity.html
@@ -0,0 +1,40 @@
+<!--
+ 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-folder-open"></i>
+ <h3 class="box-title ng-binding">{{Application.current().displayName}}</h3>
+ <div class="box-tools pull-right" ng-if="viewConfig">
+ <div class="btn-group">
+ <button type="button" class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown">
+ <span class="fa fa-wrench"></span>
+ </button>
+ <ul class="dropdown-menu" role="menu">
+ <li><a ng-click="import()"><span class="fa fa-cloud-upload"></span> Import</a></li>
+ <li><a ng-click="export()"><span class="fa fa-cloud-download"></span> Export</a></li>
+ <li class="divider"></li>
+ <li class="danger"><a ng-click="deleteAll()"><span class="fa fa-trash"></span> Delete All</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div class="box-body">
+ <ng-include ng-if="viewConfig" src="'public/feature/classification/page/sensitivity/' + viewConfig.type + '.html?_=' + ajaxId"></ng-include>
+ </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/classification/page/sensitivity/folder.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/classification/page/sensitivity/folder.html b/eagle-webservice/src/main/webapp/_app/public/feature/classification/page/sensitivity/folder.html
new file mode 100644
index 0000000..cfefffa
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/feature/classification/page/sensitivity/folder.html
@@ -0,0 +1,110 @@
+<!--
+ 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 ng-controller="classification_sensitivityViewFolder">
+ <ul class="list-inline path">
+ <li>Path:</li>
+ <li ng-repeat="unit in pathUnitList">
+ <a ng-click="updateItems(unit.path)" class="label bg-black">{{unit.name}}</a>
+ </li>
+ </ul>
+
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <th width="15%">File Name</th>
+ <th width="10%">Owner</th>
+ <th width="10%">Group</th>
+ <th>Sensitivity Type</th>
+ <th width="10" ng-show="Auth.isRole('ROLE_ADMIN')"> </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-show="items._promise.$$state.status !== 1">
+ <td colspan="5">
+ <span class="fa fa-refresh fa-spin"> </span>
+ Loading...
+ </td>
+ </tr>
+ <tr ng-show="items._promise.$$state.status === 1 && !items.length">
+ <td colspan="5">
+ <span class="fa fa-exclamation-triangle"> </span>
+ Empty Folder
+ </td>
+ </tr>
+ <tr ng-repeat="item in items" ng-class="{warning : item.sensitiveType}">
+ <td>
+ <span ng-show="!item.isdir">
+ <span class="fa fa-file"> </span>
+ {{getFileName(item)}}
+ </span>
+ <a ng-show="item.isdir" ng-click="updateItems(item.resource)">
+ <span class="fa fa-folder"> </span>
+ {{getFileName(item)}}
+ </a>
+
+ <span class="pull-right" ng-show="item.childSensitiveTypes.length">
+ <span class="fa fa-dot-circle-o text-muted" uib-tooltip="Contain child sensitivity defination"> </span>
+ </span>
+ </td>
+ <td>{{item.owner}}</td>
+ <td>{{item.groupName}}</td>
+ <td>{{item.sensitiveType}}</td>
+ <td ng-show="Auth.isRole('ROLE_ADMIN')">
+ <button class="fa fa-eye btn btn-primary btn-xs" ng-click="markSensitivity(item)" ng-show="!item.sensitiveType"
+ uib-tooltip="Mark as sensitivity data" tooltip-animation="false" tooltip-placement="left"> </button>
+ <button class="fa fa-eye-slash btn btn-warning btn-xs" ng-click="unmarkSensitivity(item)" ng-show="item.sensitiveType"
+ uib-tooltip="Remove the sensitivity mark" tooltip-animation="false" tooltip-placement="left"> </button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+
+ <!-- Modal: Create / Edit site -->
+ <div class="modal fade" id="sensitivityMDL" tabindex="-1" role="dialog">
+ <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">Mark Sensitivity Data</h4>
+ </div>
+ <div class="modal-body">
+ <div class="form-group">
+ <label>Resource</label>
+ <input type="text" readonly="readonly" class="form-control" ng-model="_markItem.tags.filedir" />
+ </div>
+ <div class="form-group">
+ <label>* Sensitivity Type</label>
+ <input type="text" class="form-control" ng-model="_markItem.sensitivityType" id="sensitiveType" />
+ </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="confirmUpateSensitivity()" ng-disabled="!_markItem.sensitivityType">
+ Update
+ </button>
+ </div>
+ </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/classification/page/sensitivity/job.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/classification/page/sensitivity/job.html b/eagle-webservice/src/main/webapp/_app/public/feature/classification/page/sensitivity/job.html
new file mode 100644
index 0000000..05d70da
--- /dev/null
+++ b/eagle-webservice/src/main/webapp/_app/public/feature/classification/page/sensitivity/job.html
@@ -0,0 +1,92 @@
+<!--
+ 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 ng-controller="classification_sensitivityViewJob">
+ <ul class="list-inline path">
+ <li>Oozie CoordinatorJob:</li>
+ </ul>
+
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <th width="15%">JobId</th>
+ <th width="10%">AppName</th>
+ <th>Sensitivity Type</th>
+ <th width="10" ng-show="Auth.isRole('ROLE_ADMIN')"> </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-show="items._promise.$$state.status !== 1">
+ <td colspan="5">
+ <span class="fa fa-refresh fa-spin"> </span>
+ Loading...
+ </td>
+ </tr>
+ <tr ng-show="items._promise.$$state.status === 1 && !items.length">
+ <td colspan="5">
+ <span class="fa fa-exclamation-triangle"> </span>
+ Empty
+ </td>
+ </tr>
+ <tr ng-repeat="item in items" ng-class="{warning : item.sensitiveType}">
+ <td>{{item.jobId}}</td>
+ <td>{{item.name}}</td>
+ <td>{{item.sensitiveType}}</td>
+ <td ng-show="Auth.isRole('ROLE_ADMIN')">
+ <button class="fa fa-eye btn btn-primary btn-xs" ng-click="markSensitivity(item)" ng-show="!item.sensitiveType"
+ uib-tooltip="Mark as sensitivity data" tooltip-animation="false" tooltip-placement="left"> </button>
+ <button class="fa fa-eye-slash btn btn-warning btn-xs" ng-click="unmarkSensitivity(item)" ng-show="item.sensitiveType"
+ uib-tooltip="Remove the sensitivity mark" tooltip-animation="false" tooltip-placement="left"> </button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+
+ <!-- Modal: Create / Edit site -->
+ <div class="modal fade" id="sensitivityMDL" tabindex="-1" role="dialog">
+ <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">Mark Sensitivity Data</h4>
+ </div>
+ <div class="modal-body">
+ <div class="form-group">
+ <label>Resource</label>
+ <input type="text" readonly="readonly" class="form-control" ng-model="_markItem.tags.oozieResource" />
+ </div>
+ <div class="form-group">
+ <label>* Sensitivity Type</label>
+ <input type="text" class="form-control" ng-model="_markItem.sensitivityType" id="sensitiveType" />
+ </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="confirmUpateSensitivity()" ng-disabled="!_markItem.sensitivityType">
+ Update
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+</div>
\ No newline at end of file