This contains the angular boilerplate, some initial structure and the navigation component.
Signed-off-by: Tiago Melo <tmelo@suse.com>
$ ceph mgr module ls
+Currently you will need to manually generate the frontend code.
+Instructions can be found in `./frontend/README.md`.
+
In order to be able to log in, you need to define a username and password, which
will be stored in the MON's configuration database::
--- /dev/null
+{
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+ "project": {
+ "name": "ceph-dashboard"
+ },
+ "apps": [
+ {
+ "root": "src",
+ "outDir": "dist",
+ "assets": [
+ "assets",
+ "favicon.ico"
+ ],
+ "index": "index.html",
+ "main": "main.ts",
+ "polyfills": "polyfills.ts",
+ "test": "test.ts",
+ "tsconfig": "tsconfig.app.json",
+ "testTsconfig": "tsconfig.spec.json",
+ "prefix": "oa",
+ "styles": [
+ "../node_modules/bootstrap/dist/css/bootstrap.css",
+ "styles.scss"
+ ],
+ "scripts": [],
+ "environmentSource": "environments/environment.ts",
+ "environments": {
+ "dev": "environments/environment.ts",
+ "prod": "environments/environment.prod.ts"
+ }
+ }
+ ],
+ "e2e": {
+ "protractor": {
+ "config": "./protractor.conf.js"
+ }
+ },
+ "lint": [
+ {
+ "project": "src/tsconfig.app.json",
+ "exclude": "**/node_modules/**"
+ },
+ {
+ "project": "src/tsconfig.spec.json",
+ "exclude": "**/node_modules/**"
+ },
+ {
+ "project": "e2e/tsconfig.e2e.json",
+ "exclude": "**/node_modules/**"
+ }
+ ],
+ "test": {
+ "karma": {
+ "config": "./karma.conf.js"
+ }
+ },
+ "defaults": {
+ "styleExt": "scss",
+ "component": {}
+ }
+}
--- /dev/null
+# Editor configuration, see http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false
--- /dev/null
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+
+# compiled output
+/dist
+/tmp
+/out-tsc
+
+# dependencies
+/node_modules
+
+# IDEs and editors
+/.idea
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-workspace
+
+# IDE - VSCode
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+
+# misc
+/.sass-cache
+/connect.lock
+/coverage
+/libpeerconnection.log
+npm-debug.log
+testem.log
+/typings
+
+# e2e
+/e2e/*.js
+/e2e/*.map
+
+# System Files
+.DS_Store
+Thumbs.db
+
+# Package lock files
+yarn.lock
+package-lock.json
+
+# Ceph
+!core
+!*.core
--- /dev/null
+# Ceph Dashboard
+
+This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.6.3.
+
+## Installation
+
+Run `npm install` to install the required packages locally.
+
+**Note**
+
+If you do not have installed [Angular CLI](https://github.com/angular/angular-cli) globally, then you need to execute ``ng`` commands with an additional ``npm run`` before it.
+
+## Development server
+
+Run `npm start` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
+
+## Code scaffolding
+
+Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
+
+## Build
+
+Run `npm run build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. Navigate to `http://localhost:8080`.
+
+## Running unit tests
+
+Run `npm run test` to execute the unit tests via [Karma](https://karma-runner.github.io).
+
+## Running end-to-end tests
+
+Run `npm run e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
+
+## Further help
+
+To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
+
+## Examples of generator
+
+```
+# Create module 'Core'
+src/app> ng generate module core -m=app --routing
+
+# Create module 'Auth' under module 'Core'
+src/app/core> ng generate module auth -m=core --routing
+or, alternatively:
+src/app> ng generate module core/auth -m=core --routing
+
+# Create component 'Login' under module 'Auth'
+src/app/core/auth> ng generate component login -m=core/auth
+or, alternatively:
+src/app> ng generate component core/auth/login -m=core/auth
+```
--- /dev/null
+import { AppPage } from './app.po';
+
+describe('ceph-dashboard App', () => {
+ let page: AppPage;
+
+ beforeEach(() => {
+ page = new AppPage();
+ });
+
+ it('should display welcome message', () => {
+ page.navigateTo();
+ expect(page.getParagraphText()).toEqual('Welcome to oa!');
+ });
+});
--- /dev/null
+import { browser, by, element } from 'protractor';
+
+export class AppPage {
+ navigateTo() {
+ return browser.get('/');
+ }
+
+ getParagraphText() {
+ return element(by.css('oa-root h1')).getText();
+ }
+}
--- /dev/null
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../out-tsc/e2e",
+ "baseUrl": "./",
+ "module": "commonjs",
+ "target": "es5",
+ "types": [
+ "jasmine",
+ "jasminewd2",
+ "node"
+ ]
+ }
+}
--- /dev/null
+// Karma configuration file, see link for more information
+// https://karma-runner.github.io/1.0/config/configuration-file.html
+
+module.exports = function (config) {
+ config.set({
+ basePath: '',
+ frameworks: ['jasmine', '@angular/cli'],
+ plugins: [
+ require('karma-jasmine'),
+ require('karma-chrome-launcher'),
+ require('karma-jasmine-html-reporter'),
+ require('karma-coverage-istanbul-reporter'),
+ require('@angular/cli/plugins/karma')
+ ],
+ client:{
+ clearContext: false // leave Jasmine Spec Runner output visible in browser
+ },
+ coverageIstanbulReporter: {
+ reports: [ 'html', 'lcovonly' ],
+ fixWebpackSourcePaths: true
+ },
+ angularCli: {
+ environment: 'dev'
+ },
+ reporters: ['progress', 'kjhtml'],
+ port: 9876,
+ colors: true,
+ logLevel: config.LOG_INFO,
+ autoWatch: true,
+ browsers: ['Chrome'],
+ singleRun: false
+ });
+};
--- /dev/null
+{
+ "name": "ceph-dashboard",
+ "version": "0.0.0",
+ "license": "MIT",
+ "scripts": {
+ "ng": "ng",
+ "start": "ng serve",
+ "build": "ng build",
+ "test": "ng test",
+ "lint": "ng lint",
+ "e2e": "ng e2e"
+ },
+ "private": true,
+ "dependencies": {
+ "@angular/animations": "^5.0.0",
+ "@angular/common": "^5.0.0",
+ "@angular/compiler": "^5.0.0",
+ "@angular/core": "^5.0.0",
+ "@angular/forms": "^5.0.0",
+ "@angular/http": "^5.0.0",
+ "@angular/platform-browser": "^5.0.0",
+ "@angular/platform-browser-dynamic": "^5.0.0",
+ "@angular/router": "^5.0.0",
+ "bootstrap": "^3.3.7",
+ "core-js": "^2.4.1",
+ "ngx-bootstrap": "^2.0.1",
+ "rxjs": "^5.5.2",
+ "zone.js": "^0.8.14"
+ },
+ "devDependencies": {
+ "@angular/cli": "^1.6.5",
+ "@angular/compiler-cli": "^5.0.0",
+ "@angular/language-service": "^5.0.0",
+ "@types/jasmine": "~2.5.53",
+ "@types/jasminewd2": "~2.0.2",
+ "@types/node": "~6.0.60",
+ "codelyzer": "^4.0.1",
+ "jasmine-core": "~2.6.2",
+ "jasmine-spec-reporter": "~4.1.0",
+ "karma": "~1.7.0",
+ "karma-chrome-launcher": "~2.1.1",
+ "karma-cli": "~1.0.1",
+ "karma-coverage-istanbul-reporter": "^1.2.1",
+ "karma-jasmine": "~1.1.0",
+ "karma-jasmine-html-reporter": "^0.2.2",
+ "protractor": "~5.1.2",
+ "ts-node": "~3.2.0",
+ "tslint": "~5.7.0",
+ "typescript": "~2.4.2"
+ }
+}
--- /dev/null
+// Protractor configuration file, see link for more information
+// https://github.com/angular/protractor/blob/master/lib/config.ts
+
+const { SpecReporter } = require('jasmine-spec-reporter');
+
+exports.config = {
+ allScriptsTimeout: 11000,
+ specs: [
+ './e2e/**/*.e2e-spec.ts'
+ ],
+ capabilities: {
+ 'browserName': 'chrome'
+ },
+ directConnect: true,
+ baseUrl: 'http://localhost:4200/',
+ framework: 'jasmine',
+ jasmineNodeOpts: {
+ showColors: true,
+ defaultTimeoutInterval: 30000,
+ print: function() {}
+ },
+ onPrepare() {
+ require('ts-node').register({
+ project: 'e2e/tsconfig.e2e.json'
+ });
+ jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
+ }
+};
--- /dev/null
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+const routes: Routes = [];
+
+@NgModule({
+ imports: [RouterModule.forRoot(routes)],
+ exports: [RouterModule]
+})
+export class AppRoutingModule { }
--- /dev/null
+<oa-navigation></oa-navigation>
+
+<div class="container-fluid">
+ <router-outlet></router-outlet>
+</div>
--- /dev/null
+import { TestBed, async } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { AppComponent } from './app.component';
+import { NavigationComponent } from './core/navigation/navigation/navigation.component';
+
+describe('AppComponent', () => {
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ RouterTestingModule
+ ],
+ declarations: [
+ AppComponent,
+ NavigationComponent
+ ],
+ }).compileComponents();
+ }));
+
+ it('should create the app', async(() => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app).toBeTruthy();
+ }));
+
+ it(`should have as title 'oa'`, async(() => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app.title).toEqual('oa');
+ }));
+});
--- /dev/null
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'oa-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.scss']
+})
+export class AppComponent {
+ title = 'oa';
+}
--- /dev/null
+import { BrowserModule } from '@angular/platform-browser';
+import { NgModule } from '@angular/core';
+
+import { AppRoutingModule } from './app-routing.module';
+
+import { AppComponent } from './app.component';
+import { CoreModule } from './core/core.module';
+import { SharedModule } from './shared/shared.module';
+import { CephModule } from './ceph/ceph.module';
+
+@NgModule({
+ declarations: [
+ AppComponent
+ ],
+ imports: [
+ BrowserModule,
+ AppRoutingModule,
+ CoreModule,
+ SharedModule,
+ CephModule
+ ],
+ exports: [SharedModule],
+ providers: [],
+ bootstrap: [AppComponent]
+})
+export class AppModule { }
--- /dev/null
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ imports: [
+ CommonModule
+ ],
+ declarations: []
+})
+export class CephModule { }
--- /dev/null
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+const routes: Routes = [];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class CoreRoutingModule { }
--- /dev/null
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { CoreRoutingModule } from './core-routing.module';
+import { NavigationModule } from './navigation/navigation.module';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ CoreRoutingModule,
+ NavigationModule
+ ],
+ exports: [NavigationModule],
+ declarations: []
+})
+export class CoreModule { }
--- /dev/null
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { NavigationComponent } from './navigation/navigation.component';
+
+@NgModule({
+ imports: [
+ CommonModule
+ ],
+ declarations: [NavigationComponent],
+ exports: [NavigationComponent]
+})
+export class NavigationModule { }
--- /dev/null
+<nav class="navbar navbar-default navbar-openattic">
+ <!-- Brand and toggle get grouped for better mobile display -->
+
+ <div class="navbar-header tc_logo_component">
+ <a class="navbar-brand"
+ href="#">
+ <img src="assets/Ceph_Logo_Standard_RGB_White_120411_fa.png"
+ alt="Ceph">
+ </a>
+
+ <button type="button"
+ class="navbar-toggle collapsed"
+ data-toggle="collapse"
+ data-target="#bs-example-navbar-collapse-1">
+ <span i18n
+ class="sr-only">Toggle navigation
+ </span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ </div>
+
+ <!-- Collect the nav links, forms, and other content for toggling -->
+ <div class="collapse navbar-collapse"
+ id="bs-example-navbar-collapse-1">
+ <ul class="nav navbar-nav navbar-primary">
+ <!-- <li data-ui-sref-active="active"
+ class="tc_menuitem tc_menuitem_dashboard">
+ <a i18n
+ routerLink="/dashboard">Dashboard
+ </a>
+ </li>
+ <li data-ui-sref-active="active"
+ class="tc_menuitem tc_menuitem_ceph_osds">
+ <a i18n
+ routerLink="/cephOsds">OSDs
+ </a>
+ </li>
+ <li data-ui-sref-active="active"
+ class="tc_menuitem tc_menuitem_ceph_rbds">
+ <a i18n
+ routerLink="/cephRbds">RBDs
+ </a>
+ </li>
+ <li data-ui-sref-active="active"
+ class="tc_menuitem tc_menuitem_ceph_pools">
+ <a i18n
+ routerLink="/cephPools">Pools
+ </a>
+ </li>
+ <li data-ui-sref-active="active"
+ class="tc_menuitem tc_menuitem_ceph_nodes">
+ <a i18n
+ routerLink="/cephNodes">Nodes
+ </a>
+ </li>
+ <li class="dropdown tc_menuitem tc_menuitem_ceph_rgw">
+ <a href=""
+ class="dropdown-toggle"
+ data-toggle="dropdown"><ng-container i18n>Object Gateway</ng-container> <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu">
+ <li data-ui-sref-active="active"
+ class="tc_submenuitem tc_submenuitem_ceph_rgw_users">
+ <a i18n
+ routerLink="/ceph-rgw-users">Users
+ </a>
+ </li>
+ <li data-ui-sref-active="active"
+ class="tc_submenuitem tc_submenuitem_ceph_rgw_buckets">
+ <a i18n
+ routerLink="/ceph-rgw-buckets">Buckets
+ </a>
+ </li>
+ </ul>
+ </li>
+ <li data-ui-sref-active="active"
+ class="tc_menuitem tc_submenuitem_settings">
+ <a i18n
+ routerLink="/settings">Settings
+ </a>
+ </li> -->
+ </ul>
+ <!-- /.navbar-primary -->
+
+ <ul class="nav navbar-nav navbar-utility">
+ </ul>
+ <!-- /.navbar-utility -->
+ </div>
+ <!-- /.navbar-collapse -->
+</nav>
--- /dev/null
+.navbar-openattic {
+ margin-bottom: 0;
+ background: #474544;
+ border: 0;
+ border-radius: 0;
+ border-top: 4px solid #288cea;
+ font-size: 1.2em;
+}
+.navbar-openattic .navbar-header {
+ display: flex;
+ float: none;
+}
+.navbar-openattic .navbar-toggle {
+ margin-left: auto;
+ border: 0;
+}
+.navbar-openattic .navbar-toggle:focus,
+.navbar-openattic .navbar-toggle:hover {
+ background-color: transparent;
+ outline: 0;
+}
+.navbar-openattic .navbar-toggle .icon-bar {
+ background-color: #ececec;
+}
+.navbar-openattic .navbar-toggle:focus .icon-bar,
+.navbar-openattic .navbar-toggle:hover .icon-bar {
+ -webkit-box-shadow: 0 0 3px #fff;
+ box-shadow: 0 0 3px #fff;
+}
+.navbar-openattic .navbar-collapse {
+ padding: 0;
+}
+.navbar-openattic .navbar-nav > li > a,
+.navbar-openattic .navbar-nav > li > .oa-navbar > a {
+ color: #ececec;
+ line-height: 1;
+ padding: 10px 20px;
+ position: relative;
+ display: block;
+ text-decoration: none;
+}
+.navbar-openattic .navbar-nav > li > a:focus,
+.navbar-openattic .navbar-nav > li > a:hover,
+.navbar-openattic .navbar-nav > li > .oa-navbar > a:focus,
+.navbar-openattic .navbar-nav > li > .oa-navbar > a:hover {
+ color: #ececec;
+}
+.navbar-openattic .navbar-nav > li > a:hover,
+.navbar-openattic .navbar-nav > li > .oa-navbar > a:hover {
+ background-color: #505050;
+}
+.navbar-openattic .navbar-nav > .open > a,
+.navbar-openattic .navbar-nav > .open > a:hover,
+.navbar-openattic .navbar-nav > .open > a:focus,
+.navbar-openattic .navbar-nav > .open > .oa-navbar > a,
+.navbar-openattic .navbar-nav > .open > .oa-navbar > a:hover,
+.navbar-openattic .navbar-nav > .open > .oa-navbar > a:focus {
+ color: #ececec;
+ border-color: transparent;
+ background-color: transparent;
+}
+.navbar-openattic .navbar-primary > li > a {
+ border: 0;
+}
+.navbar-openattic .navbar-primary > .active > a,
+.navbar-openattic .navbar-primary > .active > a:hover,
+.navbar-openattic .navbar-primary > .active > a:focus {
+ color: #ececec;
+ background-color: #288cea;
+ border: 0;
+}
+.navbar-openattic .navbar-utility a,
+.navbar-openattic .navbar-utility .fa {
+ font-size: 1em;
+}
+.navbar-openattic .navbar-utility > .active > a {
+ color: #ececec;
+ background-color: #505050;
+}
+.navbar-openattic .navbar-utility > li > .open > a,
+.navbar-openattic .navbar-utility > li > .open > a:hover,
+.navbar-openattic .navbar-utility > li > .open > a:focus {
+ color: #ececec;
+ border-color: transparent;
+ background-color: transparent;
+}
+@media (min-width: 768px) {
+ .navbar-openattic .navbar-primary > li > a {
+ border-bottom: 4px solid transparent;
+ }
+ .navbar-openattic .navbar-primary > .active > a,
+ .navbar-openattic .navbar-primary > .active > a:hover,
+ .navbar-openattic .navbar-primary > .active > a:focus {
+ background-color: transparent;
+ border-bottom: 4px solid #288cea;
+ }
+ .navbar-openattic .navbar-utility {
+ border-bottom: 0;
+ font-size: 11px;
+ position: absolute;
+ right: 0;
+ top: 0;
+ }
+}
+@media (max-width: 767px) {
+ .navbar-openattic .navbar-nav {
+ margin: 0;
+ }
+ .navbar-openattic .navbar-collapse,
+ .navbar-openattic .navbar-form {
+ border-color: #ececec;
+ }
+ .navbar-openattic .navbar-collapse {
+ padding: 0;
+ }
+ .navbar-nav .open .dropdown-menu {
+ padding-top: 0;
+ padding-bottom: 0;
+ background-color: #505050;
+ }
+ .navbar-nav .open .dropdown-menu .dropdown-header,
+ .navbar-nav .open .dropdown-menu > li > a {
+ padding: 5px 15px 5px 35px;
+ }
+ .navbar-openattic .navbar-nav .open .dropdown-menu > li > a {
+ color: #ececec;
+ }
+ .navbar-openattic .navbar-nav .open .dropdown-menu > .active > a {
+ color: #ececec;
+ background-color: #288cea;
+ }
+ .navbar-openattic .navbar-nav > li > a:hover {
+ background-color: #288cea;
+ }
+ .navbar-openattic .navbar-utility {
+ border-top: 1px solid #ececec;
+ }
+ .navbar-openattic .navbar-primary > .active > a,
+ .navbar-openattic .navbar-primary > .active > a:hover,
+ .navbar-openattic .navbar-primary > .active > a:focus {
+ background-color: #288cea;
+ }
+}
--- /dev/null
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NavigationComponent } from './navigation.component';
+
+describe('NavigationComponent', () => {
+ let component: NavigationComponent;
+ let fixture: ComponentFixture<NavigationComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ NavigationComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NavigationComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
--- /dev/null
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'oa-navigation',
+ templateUrl: './navigation.component.html',
+ styleUrls: ['./navigation.component.scss']
+})
+export class NavigationComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+}
--- /dev/null
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ imports: [
+ CommonModule
+ ],
+ declarations: []
+})
+export class SharedModule { }
--- /dev/null
+export const environment = {
+ production: true
+};
--- /dev/null
+// The file contents for the current environment will overwrite these during build.
+// The build system defaults to the dev environment which uses `environment.ts`, but if you do
+// `ng build --env=prod` then `environment.prod.ts` will be used instead.
+// The list of which env maps to which file can be found in `.angular-cli.json`.
+
+export const environment = {
+ production: false
+};
--- /dev/null
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Ceph</title>
+ <base href="/">
+
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="icon" type="image/x-icon" href="favicon.ico">
+</head>
+<body>
+ <noscript>
+ <div class="noscript container"
+ ng-if="false">
+ <div class="jumbotron alert alert-danger">
+ <h2>JavaScript required!</h2>
+ <p>A browser with JavaScript enabled is required in order to use this service.</p>
+ <p>When using Internet Explorer, please check your security settings and add this address to your trusted sites.</p>
+ </div>
+ </div>
+ </noscript>
+
+ <oa-root></oa-root>
+</body>
+</html>
--- /dev/null
+import { enableProdMode } from '@angular/core';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { AppModule } from './app/app.module';
+import { environment } from './environments/environment';
+
+if (environment.production) {
+ enableProdMode();
+}
+
+platformBrowserDynamic().bootstrapModule(AppModule)
+ .catch(err => console.log(err));
--- /dev/null
+/*
+ Basics
+ Branding
+ Breadcrumb
+ Buttons
+ Dropdown
+ Grid
+ Modal
+ Navbar
+ Navs
+ Notifications
+ Pagination
+ Panel
+ Table
+ Typo
+
+ Login
+ Statistics
+
+ ApiRecorder
+ Caret
+ Datatables
+ Feedback
+ FlexElement
+ Grafana
+ Graph
+ Progressbar
+ TagForm
+ Trees
+ CSS Fix
+/*
+
+/* Basics */
+html {
+ background-color: #ffffff;
+}
+html,
+body {
+ width: 100%;
+ height: 100%;
+ font-size: 12px;
+}
+optgroup {
+ font-weight: bold;
+ font-style: italic;
+}
+option {
+ font-weight: normal;
+ font-style: normal;
+}
+.full-height {
+ height: 100%;
+}
+.vertical-align {
+ display: flex;
+ align-items: center;
+}
+.loading {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+}
+.bg-color-darken {
+ background-color: #404040!important;
+}
+.bg-color-greenLight {
+ background-color: #71843f!important;
+}
+.bg-color-red {
+ background-color: #a90329!important;
+}
+.no-margin {
+ margin: 0;
+}
+.margin-left-md {
+ margin-left: 15px
+}
+.margin-right-md {
+ margin-right: 15px
+}
+.margin-right-sm {
+ margin-right: 10px
+}
+.margin-bottom-md {
+ margin-bottom: 15px
+}
+.no-padding {
+ padding: 0;
+}
+.small-padding {
+ padding: 5px;
+}
+.no-border {
+ border: 0px;
+ box-shadow: 0px 0px 0px !important;
+}
+.no-wrap {
+ white-space: nowrap;
+}
+.strikethrough {
+ text-decoration: line-through;
+}
+
+.italic {
+ font-style: italic;
+}
+
+/* Branding */
+.navbar-openattic .navbar-brand,
+.navbar-openattic .navbar-brand:hover{
+ color: #ececec;
+ height: auto;
+ margin: 15px 0 15px 20px;
+ padding: 0;
+ -webkit-align-self: flex-start;
+ align-self: flex-start;
+}
+.navbar-openattic .navbar-brand>img {
+ height: 25px;
+}
+
+/* Breadcrumb */
+.breadcrumb {
+ padding: 8px 0;
+ background-color: transparent;
+ border-radius: 0;
+}
+.breadcrumb>li+li:before {
+ padding: 0 5px 0 7px;
+ color: #474544;
+ font-family: "FontAwesome";
+ content: "\f101";
+}
+.breadcrumb>li>span {
+ color: #474544;
+}
+
+/* Icons */
+.icon-warning {
+ color: #f0ad4e;
+}
+.icon-danger {
+ color: #c9302c;
+}
+
+/* Buttons */
+.btn-openattic {
+ color: #ececec;
+ background-color: #288cea;
+ border-color: #288cea;
+}
+.btn-primary {
+ color: #ececec;
+ background-color: #288CEA;
+ border-color: #2172bf;
+}
+.btn-primary:hover,
+.btn-primary:focus,
+.btn-primary:active,
+.btn-primary.active,
+.open .dropdown-toggle.btn-primary {
+ color: #ececec;
+ background-color: #2582D9;
+ border-color: #2172bf;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+ background-color: #288CEA;
+ border-color: #2172bf;
+}
+.btn-primary .badge {
+ color: #288CEA;
+ background-color: #ececec;
+}
+.btn-primary .caret {
+ color: #ececec;
+}
+.btn-group>.btn>i.fa,
+button.btn.btn-label>i.fa {
+ /** Add space between icon and text */
+ padding-right: 5px;
+}
+
+/* Dropdown */
+.dropdown-menu {
+ min-width: 50px;
+}
+.dropdown-menu>li>a {
+ color: #474544;
+ cursor: pointer;
+}
+.dropdown-menu>li>a>i.fa {
+ /** Add space between icon and text */
+ padding-right: 5px;
+}
+.dropdown-menu>.active>a {
+ color: #ececec;
+ background-color: #288cea;
+}
+.dataTables_wrapper .dropdown-menu>li.divider {
+ cursor: auto;
+}
+
+/* Grid */
+.container,
+.container-fluid {
+ padding-left: 30px;
+ padding-right: 30px;
+}
+.row {
+ margin-left: -30px;
+ margin-right: -30px;
+}
+.col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9,
+.col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9,
+.col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9,
+.col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 {
+ padding-left: 30px;
+ padding-right: 30px;
+}
+
+/* Modal */
+.modal-dialog {
+ margin: 30px auto !important;
+}
+.modal .modal-content .openattic-modal-header,
+.modal .modal-content .openattic-modal-content,
+.modal .modal-content .openattic-modal-footer {
+ padding: 10px 20px;
+}
+.modal .modal-content .openattic-modal-header {
+ border-bottom: 1px solid #cccccc;
+ border-radius: 5px 5px 0 0;
+ background-color: #f5f5f5;
+}
+.modal .modal-content .openattic-modal-content {
+ padding: 20px 20px 10px 20px;
+ overflow-x: auto;
+ max-height: 70vh;
+}
+.modal .modal-content .openattic-modal-content p {
+ margin-bottom: 10px;
+}
+.modal .modal-content .openattic-modal-content legend {
+ font-size: 1.833em;
+}
+.modal .modal-content .openattic-modal-footer {
+ border-top: 1px solid #cccccc;
+ border-radius: 0 0 5px 5px;
+ background-color: #f5f5f5;
+}
+.modal .modal-content .openattic-modal-header span {
+ display: block;
+ font-size: 16px; /* Same as .panel-title */
+}
+
+/* Modal Table (Task Queue) */
+table.task-queue-table thead {
+ display: flex;
+ flex-flow: row;
+}
+table.task-queue-table thead tr {
+ display: flex;
+ align-items: stretch;
+ width: 100%;
+}
+table.task-queue-table tbody {
+ display: flex;
+ flex-flow: row wrap;
+}
+table.task-queue-table tbody tr {
+ display: flex;
+ width: 100%
+}
+table.task-queue-table > * > tr > * {
+ flex: 1;
+}
+table.task-queue-table > * > tr > .oadatatablecheckbox {
+ flex: 0;
+}
+div.task-queue-modal-content {
+ height: 40em;
+}
+div.openattic-modal-content div.modal-scroll {
+ max-height: 26em;
+ overflow: auto;
+ border-bottom: 1px solid #e1e1e1;
+}
+div.task-queue-modal-content div.dataTables_wrapper {
+ margin-bottom: 0;
+}
+div.task-queue-modal-content div.dataTables_wrapper th.oadatatablecheckbox {
+ width: 100%;
+}
+div.task-queue-modal-content div.dataTables_wrapper div.widget-toolbar.tc_refreshBtn{
+ width: 36px;
+}
+ul.task-queue-pagination {
+ display: table;
+ margin: auto;
+ padding-top: 10px;
+}
+
+/* Navs */
+.nav-tabs {
+ margin-bottom: 15px;
+}
+.nav-tabs-openattic {
+ margin-top: -15px;
+ margin-bottom: 15px;
+}
+.nav-tabs-openattic>li>a {
+ padding: 7px 15px 4px 15px;
+}
+.nav-tabs-openattic>li.active>a,
+.nav-tabs-openattic>li.active>a:active,
+.nav-tabs-openattic>li.active>a:focus,
+.nav-tabs-openattic>li.active>a:hover {
+ border: 0!important;
+ border-bottom: 3px solid #288cea!important;
+}
+
+/* Notifications */
+#toasty .toast.toasty-theme-bootstrap {
+ opacity: 1
+}
+
+/* Pagination */
+.pagination {
+ display: block;
+ margin: 0;
+}
+.pagination>.disabled>a,
+.pagination>.disabled>a:focus,
+.pagination>.disabled>a:hover,
+.pagination>.disabled>span,
+.pagination>.disabled>span:focus,
+.pagination>.disabled>span:hover {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ cursor: not-allowed;
+ background-image: -webkit-linear-gradient(top,#fafafa 0,#ededed 100%);
+ background-image: -o-linear-gradient(top,#fafafa 0,#ededed 100%);
+ background-image: linear-gradient(to bottom,#fafafa 0,#ededed 100%);
+}
+.pagination>.active>a,
+.pagination>.active>a:focus,
+.pagination>.active>a:hover,
+.pagination>.active>span,
+.pagination>.active>span:focus,
+.pagination>.active>span:hover,
+.pagination>.disabled>a,
+.pagination>.disabled>a:focus,
+.pagination>.disabled>a:hover,
+.pagination>.disabled>span,
+.pagination>.disabled>span:focus,
+.pagination>.disabled>span:hover,
+.pagination>li>a,
+.pagination>li>span,
+.panel-group
+.panel-heading {
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa', endColorstr='#ffededed', GradientType=0);
+}
+.pagination>li>a,
+.pagination>li>span {
+ background-color: #eee;
+ background-image: -webkit-linear-gradient(top,#fafafa 0,#ededed 100%);
+ background-image: -o-linear-gradient(top,#fafafa 0,#ededed 100%);
+ background-image: linear-gradient(to bottom,#fafafa 0,#ededed 100%);
+ border-color: #b7b7b7;
+ color: #4d5258;
+ cursor: pointer;
+ font-weight: 600;
+ padding: 2px 10px;
+}
+.pagination>.active>span,
+.pagination>.active>span:focus,
+.pagination>.active>span:hover {
+ color: #288cea;
+ border-color: #fff #e1e1e1 #f4f4f4;
+ border-width: 0 1px;
+}
+
+/* Panel */
+.panel .panel-toolbar {
+ float: right;
+}
+.panel .panel-toolbar div {
+ display: inline-block;
+}
+.panel .panel-toolbar>a,
+.panel .panel-toolbar>.dropdown>a {
+ padding-left: 5px;
+}
+.panel-dashboard {
+ height: 100%;
+ padding-top: 60px;
+}
+.panel-dashboard>.panel-heading {
+ cursor: move;
+ position: relative;
+ margin-top: -60px;
+ width: 100%;
+}
+.panel-dashboard>.panel-heading>.panel-title {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ -o-text-overflow: ellipsis;
+}
+.panel-dashboard>.panel-heading>.toolbar a {
+ text-decoration: none;
+}
+.panel-dashboard>.panel-body {
+ height: 100%;
+ overflow: auto;
+}
+.panel-dashboard>.panel-body .indent {
+ margin-top: 10px;
+ margin-left: 10px;
+}
+.panel-dashboard .overlay {
+ position: absolute;
+ bottom: 5px;
+ right: 5px;
+ z-index: 10;
+}
+.panel-dashboard .max-height {
+ height: 100%;
+}
+.panel-dashboard .max-height.alert-is-shown {
+ height: 85%;
+}
+.panel-dashboard .fa-2x{
+ vertical-align: middle;
+ margin-right: 0.5em;
+}
+.panel-dashboard .alert.bottom-margin-zero {
+ margin-bottom: 0;
+}
+.panel-openattic {
+ border: 1px solid #d1d1d1;
+ border-top: 0;
+ border-radius: 0;
+}
+.panel-openattic>.panel-heading {
+ border-top: 2px solid #288cea;
+ border-radius: 0;
+ padding: 20px 15px;
+}
+.panel-openattic>.panel-heading>.panel-title {
+ color: #333333;
+ font-size: 1.333em;
+ margin: 0;
+ padding: 0;
+}
+.panel-openattic>.panel-body {
+ background: #ffffff;
+ border-top: 1px solid #d1d1d1;
+ padding: 10px 15px;
+}
+.panel-openattic>.panel-footer {
+ background: #ffffff;
+ border-top: 1px solid #d1d1d1;
+}
+
+/* Table */
+table.datatable {
+ margin-bottom: 0;
+ max-width: none!important
+}
+table.dataTable thead .sorting_asc,
+table.dataTable thead .sorting_desc {
+ color: #288cea;
+}
+table.dataTable thead .sorting,
+table.dataTable thead .sorting_asc,
+table.dataTable thead .sorting_desc {
+ cursor: pointer;
+}
+table.datatable thead .sorting:after,
+table.datatable thead .sorting_asc:after,
+table.datatable thead .sorting_desc:after {
+ font-family: FontAwesome;
+ font-weight: 400;
+ height: 9px;
+ left: 10px;
+ line-height: 12px;
+ position: relative;
+ vertical-align: baseline;
+ width: 12px;
+}
+table.datatable thead .sorting:after {
+ content: "\f0dc";
+}
+table.datatable thead .sorting_asc:after {
+ content: "\f160";
+}
+table.datatable thead .sorting_desc:after {
+ content: "\f161";
+}
+.table>tbody>tr>td,
+.table>tbody>tr>th,
+.table>tfoot>tr>td,
+.table>tfoot>tr>th,
+.table>thead>tr>td,
+.table>thead>tr>th {
+ padding: 5px;
+}
+.table>tbody>tr>td>input,
+.table>tbody>tr>th>input,
+.table>tfoot>tr>td>input,
+.table>tfoot>tr>th>input,
+.table>thead>tr>td>input,
+.table>thead>tr>th>input {
+ display: block;
+}
+.table>thead {
+ background-clip: padding-box;
+ background-color: #f9f9f9;
+ background-image: -webkit-linear-gradient(top,#fafafa 0,#ededed 100%);
+ background-image: -o-linear-gradient(top,#fafafa 0,#ededed 100%);
+ background-image: linear-gradient(to bottom,#fafafa 0,#ededed 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa', endColorstr='#ffededed', GradientType=0);
+}
+
+.table.header-text-center>thead>tr>th {
+ text-align: center;
+}
+
+.table-bordered {
+ border: none;
+ border-top: 1px solid #d1d1d1;
+ border-right: 1px solid #d1d1d1;
+}
+
+.table-bordered>tbody>tr>td,
+.table-bordered>tbody>tr>th,
+.table-bordered>tfoot>tr>td,
+.table-bordered>tfoot>tr>th,
+.table-bordered>thead>tr>td,
+.table-bordered>thead>tr>th {
+ border: none;
+ border-left: 1px solid #d1d1d1;
+ border-bottom: 1px solid #d1d1d1;
+}
+.table-striped>tbody>tr:nth-of-type(odd) {
+ background-color: #ffffff;
+}
+.table-striped>tbody>tr:nth-of-type(even) {
+ background-color: #f6f6f6;
+}
+.table-responsive {
+ overflow-x: auto;
+ margin-bottom: 0;
+ min-height: .01%;
+}
+
+.table-no-background>thead {
+ background: none;
+}
+.table-no-background>thead>tr>th {
+ border-bottom: 1px solid #ddd;
+}
+.table-no-background>tbody>tr>td {
+ height: 50px;
+ vertical-align: middle;
+ border-top: 0px;
+ border-bottom: 1px solid #ddd;
+}
+
+.table-transparent>thead {
+ background: none;
+}
+.table-transparent>thead>tr>th {
+ border-bottom: 0px;
+}
+.table-transparent>tbody>tr>td {
+ height: 50px;
+ vertical-align: middle;
+ border-top: 0px;
+ border-bottom: 0px;
+}
+
+/* Typo */
+a {
+ color: #288cea;
+}
+a:hover,
+a:focus{
+ color: #474544;
+}
+h1 {
+ letter-spacing: -1px;
+ font-size: 2em;
+}
+h2 {
+ letter-spacing: -1px;
+ font-size: 1.833em;
+}
+h3{
+ display: block;
+ font-size: 1.583em;
+ font-weight: 400;
+}
+h3.sub-title {
+ color: #666666;
+ margin-left: 15px;
+}
+h4{
+ font-size: 1.5em;
+ line-height: normal
+}
+h5{
+ font-size: 1.417em;
+ font-weight: 300;
+ line-height: normal;
+}
+h6{
+ font-size: 1.25em;
+ font-weight: 700;
+ line-height: normal;
+}
+
+/*************************************************************/
+
+/* Login */
+.login {
+ height: 100%;
+}
+.login .utility-bar {
+ position: absolute;
+ margin: 0;
+ padding: 0;
+ top: 10px;
+ right: 10px;
+}
+.login .utility-bar>a {
+ color: #ececec;
+ line-height: 1;
+ padding: 10px 20px;
+ position: relative;
+ display: block;
+ text-decoration: none;
+}
+.login .utility-bar>a:focus,
+.login .utility-bar>a:hover {
+ color: #ffffff;
+}
+.login .utility-bar>a:hover {
+ background-color: #505050;
+}
+.login .open>a,
+.login .open>a:hover,
+.login .open>a:focus {
+ color: #ececec;
+ border-color: transparent;
+ background-color: transparent;
+}
+.login .utility-bar .dropdown-menu {
+ left: auto;
+ right: 0;
+}
+.login .icon-bar {
+ position: absolute;
+ margin: 0;
+ padding: 0;
+ bottom: 10px;
+ left: 10px;
+}
+.login .icon-bar>a {
+ color: #ececec;
+ text-decoration: none;
+}
+.login .icon-bar>a .fa-dark {
+ color: #474544;
+}
+.login .row {
+ color: #ececec;
+ background-color: #474544;
+}
+.login h1 {
+ margin-top: 0;
+ margin-bottom: 30px;
+}
+.login .btn-password,
+.login .form-control {
+ color: #ececec;
+ background-color: #555555;
+}
+.login .col-lg-1, .login .col-lg-10, .login .col-lg-11, .login .col-lg-12, .login .col-lg-2, .login .col-lg-3,
+.login .col-lg-4, .login .col-lg-5, .login .col-lg-6, .login .col-lg-7, .login .col-lg-8, .login .col-lg-9 {
+ padding-left: 35px;
+ padding-right: 35px;
+}
+.login .col-md-1, .login .col-md-10, .login .col-md-11, .login .col-md-12, .login .col-md-2, .login .col-md-3,
+.login .col-md-4, .login .col-md-5, .login .col-md-6, .login .col-md-7, .login .col-md-8, .login .col-md-9 {
+ padding-left: 30px;
+ padding-right: 30px;
+}
+.login .col-sm-1, .login .col-sm-10, .login .col-sm-11, .login .col-sm-12, .login .col-sm-2, .login .col-sm-3,
+.login .col-sm-4, .login .col-sm-5, .login .col-sm-6, .login .col-sm-7, .login .col-sm-8, .login .col-sm-9 {
+ padding-left: 25px;
+ padding-right: 25px;
+}
+.login .col-xs-1, .col-xs-10, .login .col-xs-11, .login .col-xs-12, .login .col-xs-2, .login .col-xs-3,
+.login .col-xs-4, .login .col-xs-5, .login .col-xs-6, .login .col-xs-7, .login .col-xs-8, .login .col-xs-9 {
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+/* Statistics */
+.statistics-content {
+ margin: 0 -20px;
+}
+
+/*************************************************************/
+
+/* ApiRecorder */
+.apirecorder {
+ resize: none;
+ width:100%;
+}
+.apirecorder-enabled {
+ color: red;
+}
+
+/* Caret */
+.caret {
+ color: #288cea;
+}
+
+/* Datatables */
+.dataTables_wrapper {
+ margin-bottom: 25px;
+}
+.dataTables_wrapper .separator {
+ height: 30px;
+ border-left: 1px solid rgba(0,0,0,.09);
+ padding-left: 5px;
+ margin-left: 5px;
+ display: inline-block;
+ vertical-align: middle;
+}
+.dataTables_wrapper .widget-toolbar {
+ display: inline-block;
+ float: right;
+ width: auto;
+ height: 30px;
+ line-height: 28px;
+ position: relative;
+ border-left: 1px solid rgba(0,0,0,.09);
+ cursor: pointer;
+ padding: 0 8px;
+ text-align: center;
+}
+.dataTables_wrapper .dropdown-menu {
+ white-space: nowrap;
+}
+.dataTables_wrapper .dropdown-menu>li {
+ cursor: pointer;
+}
+.dataTables_wrapper .dropdown-menu>li>label {
+ width: 100%;
+ margin-bottom: 0;
+ padding-left: 20px;
+ padding-right: 20px;
+ cursor: pointer;
+}
+.dataTables_wrapper .dropdown-menu>li>label:hover {
+ background-color: #f5f5f5;
+}
+.dataTables_wrapper .dropdown-menu>li>label>input {
+ cursor: pointer;
+}
+.dataTables_wrapper th.oadatatablecheckbox {
+ width: 16px;
+}
+.dataTables_header {
+ background-color: #f6f6f6;
+ border: 1px solid #d1d1d1;
+ border-bottom: none;
+ padding: 5px;
+ position: relative;
+}
+.dataTables_header .oadatatableactions {
+ display: inline-block;
+}
+.dataTables_header .input-group {
+ float: right;
+ border-left: 1px solid rgba(0,0,0,.09);
+ padding-left: 8px;
+ width: 40%;
+ max-width: 350px;
+}
+.dataTables_header .input-group .input-group-addon {
+}
+.dataTables_header .input-group .form-control {
+ height: 30px;
+}
+.dataTables_header .input-group .clear-input {
+ height: 30px;
+}
+.dataTables_header .input-group .clear-input i {
+ vertical-align: text-top;
+}
+.dataTables_no-match {
+ border: 1px solid #d1d1d1;
+ padding: 10px 0;
+ text-align: center;
+ font-weight: bold;
+ font-style: italic;
+}
+.dataTables_content .progress {
+ max-height: 16px;
+}
+.dataTables_content .progress span {
+ line-height: 16px;
+}
+.dataTables_footer {
+ background-color: #ffffff;
+ border: 1px solid #d1d1d1;
+ border-top: none;
+ padding: 0;
+ overflow: hidden;
+}
+.dataTables_footer .dataTables_info {
+ float: left;
+ padding-top: 6px;
+ padding-left: 5px;
+ font-style: italic;
+}
+.dataTables_paginate {
+ background: #fafafa;
+ float: right;
+ margin: 0;
+}
+.dataTables_paginate .pagination {
+ float: left;
+ margin: 0;
+}
+.dataTables_paginate .pagination.paginate-input {
+ line-height: 1em;
+ padding: 0.3em 0.5em;
+}
+.dataTables_paginate .pagination>li.disabled>span {
+ background: #f5f5f5;
+ border-left-color: #ececec;
+ border-right-color: #ececec;
+}
+.dataTables_paginate .pagination>li.disabled>span,
+.dataTables_paginate .pagination>li>span:focus,
+.dataTables_paginate .pagination>li>span:hover {
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+.dataTables_paginate .pagination>li>span {
+ border-color: #fff #e1e1e1 #f4f4f4;
+ border-width: 0 1px;
+ font-size: 1.2em;
+ font-weight: 400;
+ padding: 4px;
+ text-align: center;
+ width: 31px;
+}
+.dataTables_paginate .pagination .last>span {
+ border-right: 0;
+}
+.oadatatable div.overlay, div.oa-overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 10;
+ height: 100%;
+ width: 100%;
+ background-color: rgba(30, 30, 30, 0.2);
+}
+.oadatatable div.overlay-content, div.oa-overlay-content {
+ margin: 200px auto;
+ width: 50px;
+ height: 50px;
+ background-color: rgba(30, 30, 30, 0);
+}
+
+/* Feedback */
+#feedback .feedback-button {
+ position: fixed;
+ top: 50%;
+ right: 0;
+ padding: 2px 16px;
+ cursor: pointer;
+ color: #ffffff;
+ font-size: 1.2em;
+ font-weight: 700;
+ background-color: #288cea;
+ border-radius: 5px 5px 0 0;
+ z-index: 99999;
+}
+#feedback .feedback-button:hover {
+ background-color: #2172bf;
+}
+#feedback .feedback-button-transform {
+ -webkit-transform: rotate(-90deg) translate(50%, -100%);
+ -moz-transform: rotate(-90deg) translate(50%, -100%);
+ -ms-transform: rotate(-90deg) translate(50%, -100%);
+ -o-transform: rotate(-90deg) translate(50%, -100%);
+ transform: rotate(-90deg) translate(50%, -100%);
+ -webkit-transform-origin: top right;
+ -moz-transform-origin: top right;
+ -ms-transform-origin: top right;
+ -o-transform-origin: top right;
+ transform-origin: top right;
+}
+#feedback .feedback-button-active {
+ right: 299px;
+}
+#feedback .feedback-button .fa,
+#feedback .feedback-button .glyphicon{
+ padding-right: 6px;
+}
+#feedback .feedback-panel {
+ position: fixed;
+ top: 0;
+ right: -300px;
+ padding: 20px;
+ width: 300px;
+ height: 100%;
+ background-color: #ffffff;
+ border-left: 5px solid #288cea;
+ z-index: 99999;
+ overflow-y: auto;
+}
+#feedback .feedback-panel-active {
+ right: 0;
+}
+#feedback .feedback-transition {
+ transition: right 150ms cubic-bezier(0.0, 0.0, 0.2, 1);
+}
+
+/* FlexElement */
+/* Container */
+.flex-container {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+}
+.flex-wrap {
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+}
+.flex-nowrap {
+ -webkit-flex-wrap: nowrap;
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+}
+.flex-row {
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+}
+.flex-column {
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+}
+/* Items */
+.flex-item {
+ margin-bottom: 10px;
+ padding: 15px;
+}
+.flex-item-1 { -webkit-flex: 1; -moz-flex: 1; -ms-flex: 1; flex: 1; padding: 0 10px; }
+.flex-item-2 { -webkit-flex: 2; -moz-flex: 2; -ms-flex: 2; flex: 2; padding: 0 10px; }
+.flex-item-3 { -webkit-flex: 3; -moz-flex: 3; -ms-flex: 3; flex: 3; padding: 0 10px; }
+.flex-item-4 { -webkit-flex: 4; -moz-flex: 4; -ms-flex: 4; flex: 4; padding: 0 10px; }
+.flex-item-5 { -webkit-flex: 5; -moz-flex: 5; -ms-flex: 5; flex: 5; padding: 0 10px; }
+.flex-item-6 { -webkit-flex: 6; -moz-flex: 6; -ms-flex: 6; flex: 6; padding: 0 10px; }
+.flex-item-7 { -webkit-flex: 7; -moz-flex: 7; -ms-flex: 7; flex: 7; padding: 0 10px; }
+.flex-item-8 { -webkit-flex: 8; -moz-flex: 8; -ms-flex: 8; flex: 8; padding: 0 10px; }
+.flex-item-9 { -webkit-flex: 9; -moz-flex: 9; -ms-flex: 9; flex: 9; padding: 0 10px; }
+
+/* Grafana */
+.grafana-container {
+ margin-top: 20px;
+ height: 64px;
+ background:url(./assets/loading.gif) center center no-repeat;
+}
+.grafana {
+ width: 100%;
+ min-height: 600px;
+}
+
+/* Progressbar */
+.progress-bar {
+ background-image: none !important;
+}
+.progress-bar-info {
+ background-color: #288cea;
+}
+.progress-bar-freespace {
+ background-color: #ddd;
+}
+.progress-bar-stolenspace {
+ background-color: #aaa;
+}
+.progress-bar-outer{
+ margin-top: 5px !important;
+}
+.progress-bar-outer div {
+ border-radius: 31px;
+ background-color: #ffffff;
+ border: 1px solid #ccc;
+ box-shadow: 0 0 0 0;
+ -webkit-box-shadow: 0 0 0 0;
+ -moz-box-shadow: 0 0 0 0;
+ margin: 0;
+ height: 16px;
+}
+.progress-bar-outer div div {
+ background-color: #0091d9;
+}
+.progress-bar-outer div div span {
+ position: relative;
+ top: -3px;
+}
+.oaprogress {
+ position: relative;
+ margin-bottom: 0;
+}
+.oaprogress div.progress-bar {
+ position: static;
+}
+.oaprogress span {
+ position: absolute;
+ display: block;
+ width: 100%;
+ color: black;
+ font-weight: normal;
+}
+
+tags-input .tags {
+ border-radius: 4px;
+ border: 1px solid #ccc;
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
+}
+
+/* TagForm */
+.tag-form label {
+ display: block;
+ margin-bottom: 6px;
+ line-height: 19px;
+ font-weight: 400;
+ font-size: 13px;
+ color: #333;
+ text-align: left;
+ white-space: normal;
+}
+
+/* Trees */
+.tree {
+ min-height: 20px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+.tree>ul {
+ padding-left: 0;
+}
+.tree ul ul {
+ padding-left: 34px;
+ padding-top: 10px;
+}
+.tree li {
+ list-style-type: none;
+ margin: 0;
+ padding: 5px;
+ position: relative;
+}
+.tree li span {
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border: 1px dotted #999;
+ border-radius: 5px;
+ display: inline-block;
+ padding: 3px 8px;
+ text-decoration: none;
+ -webkit-transition: color .2s ease .1s,background-color .2s ease .1s,border-color .3s ease .2s;
+ -moz-transition: color .2s ease .1s,background-color .2s ease .1s,border-color .3s ease .2s;
+ -o-transition: color .2s ease .1s,background-color .2s ease .1s,border-color .3s ease .2s;
+ transition: color .2s ease .1s,background-color .2s ease .1s,border-color .3s ease .2s;
+}
+.tree>ul>li::after,
+.tree>ul>li:before {
+ border: 0;
+}
+.tree li:after,
+.tree li:before {
+ content: '';
+ left: -20px;
+ position: absolute;
+ right: auto;
+}
+.tree li:before {
+ border-left: 1px solid #999;
+ bottom: 50px;
+ height: 100%;
+ top: -11px;
+ width: 1px;
+ -webkit-transition: "border-color 0.1s ease 0.1s";
+ -moz-transition: "border-color 0.1s ease 0.1s";
+ -o-transition: "border-color 0.1s ease 0.1s";
+ transition: "border-color 0.1s ease 0.1s";
+}
+.tree li:after {
+ border-top: 1px solid #999;
+ height: 20px;
+ top: 18px;
+ width: 25px;
+}
+.tree li:last-child::before {
+ height: 30px;
+}
+
+.scrollable-menu {
+ height: auto;
+ max-height: 200px;
+ overflow-x: hidden;
+}
+
+.toggle, .toggle-on, .toggle-off {
+ border-radius: 20px;
+}
+
+.toggle .toggle-handle {
+ border-radius: 20px;
+}
+
+/* CSS Fix */
+a {
+ cursor: pointer;
+}
+form .input-group-addon {
+ color: #a2a2a2 !important;
+ background-color: transparent;
+}
+uib-accordion .panel-title,
+.panel .accordion-title {
+ font-size: 14px !important;
+}
+.panel-body h2:first-child {
+ margin-top: 0;
+}
+.actions {
+ padding-bottom: 10px;
+}
+.pull-left {
+ float: left;
+}
+.code-clogs {
+ display: block;
+ padding: 9px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #333;
+ word-break: break-all;
+ word-wrap: break-word;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
+}
+.degree-sign:after {
+ content: "\00B0 C"!important;
+}
+.formactions.well {
+ overflow: auto;
+ padding: 10px 20px;
+}
+.disabled {
+ pointer-events: none;
+}
+.clickable {
+ cursor: pointer;
+}
+.non-clickable {
+ cursor: initial;
+}
+.locked {
+ cursor: default!important;
+}
+.list-nomargin {
+ margin: 0;
+}
+
+.has-error .has-error-btn {
+ background-color: #f2dede;
+ border-color: #a94442;
+}
+
+.has-error .has-error-btn:disabled:hover {
+ background-color: #f2dede;
+ border-color: #a94442;
+}
+
+/* If javascript is disabled. */
+.noscript {
+ padding-top: 5em;
+}
+.noscript p {
+ color: #777;
+}
+
+/* Notifications */
+
+.notification div.img-circle {
+ width: 50px;
+ height: 50px;
+ position: relative;
+}
+.notification.info div.img-circle {
+ background-color: #5bc0de;
+}
+.notification.error div.img-circle {
+ background-color: #d9534f;
+}
+.notification.success div.img-circle {
+ background-color: #5cb85c;
+}
+.notification.warning div.img-circle {
+ background-color: #f0ad4e;
+}
+
+.notification .icon {
+ background-repeat: no-repeat;
+ background-image: url('./assets/notification-icons.png') !important;
+ height: 36px;
+ width: 36px;
+ position: absolute;
+ margin: 7px;
+}
+.notification.info .icon {
+ background-position: -36px 0;
+}
+.notification.error .icon {
+ background-position: -108px 0;
+}
+.notification.success .icon {
+ background-position: 0 0;
+}
+.notification.warning .icon {
+ background-position: -72px 0;
+}
+
+.required {
+ color: #d04437;
+}
+
+/* oa-helper */
+oa-helper i {
+ color: #288cea;
+ cursor: pointer;
+}
+
+.page-footer {
+ font-size: 12px;
+ color: #777;
+ text-align: center;
+ margin-left: 150px;
+ margin-right: 150px;
+ margin-top: 50px;
+ margin-bottom: 50px;
+}
+
+hr.oa-hr-small {
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+
+.table>thead>tr>th.rbd-striping-object{
+ min-width: 60px;
+}
+.table>thead>tr>th.rbd-striping-stripe {
+ min-width: 100px;
+}
+.rbd-striping-column-separator {
+ width: 1px;
+}
+
+.table>tbody>tr>td.rbd-striping-cell-top {
+ border-top: 1px solid #ccc;
+ border-left: 1px solid #ccc;
+ border-right: 1px solid #ccc;
+}
+.table>tbody>tr>td.rbd-striping-cell-center {
+ border-top: 1px dashed #ccc;
+ border-left: 1px solid #ccc;
+ border-right: 1px solid #ccc;
+}
+.table>tbody>tr>td.rbd-striping-cell-bottom {
+ border-bottom: 1px solid #ccc;
+ border-left: 1px solid #ccc;
+ border-right: 1px solid #ccc;
+}
--- /dev/null
+/**
+ * This file includes polyfills needed by Angular and is loaded before the app.
+ * You can add your own extra polyfills to this file.
+ *
+ * This file is divided into 2 sections:
+ * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
+ * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
+ * file.
+ *
+ * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
+ * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
+ * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
+ *
+ * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
+ */
+
+/***************************************************************************************************
+ * BROWSER POLYFILLS
+ */
+
+/** IE9, IE10 and IE11 requires all of the following polyfills. **/
+// import 'core-js/es6/symbol';
+// import 'core-js/es6/object';
+// import 'core-js/es6/function';
+// import 'core-js/es6/parse-int';
+// import 'core-js/es6/parse-float';
+// import 'core-js/es6/number';
+// import 'core-js/es6/math';
+// import 'core-js/es6/string';
+// import 'core-js/es6/date';
+// import 'core-js/es6/array';
+// import 'core-js/es6/regexp';
+// import 'core-js/es6/map';
+// import 'core-js/es6/weak-map';
+// import 'core-js/es6/set';
+
+/** IE10 and IE11 requires the following for NgClass support on SVG elements */
+// import 'classlist.js'; // Run `npm install --save classlist.js`.
+
+/** IE10 and IE11 requires the following for the Reflect API. */
+// import 'core-js/es6/reflect';
+
+
+/** Evergreen browsers require these. **/
+// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
+import 'core-js/es7/reflect';
+
+
+/**
+ * Required to support Web Animations `@angular/platform-browser/animations`.
+ * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
+ **/
+// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
+
+
+
+/***************************************************************************************************
+ * Zone JS is required by Angular itself.
+ */
+import 'zone.js/dist/zone'; // Included with Angular CLI.
+
+
+
+/***************************************************************************************************
+ * APPLICATION IMPORTS
+ */
+
+/**
+ * Date, currency, decimal and percent pipes.
+ * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
+ */
+// import 'intl'; // Run `npm install --save intl`.
+/**
+ * Need to import at least one locale-data with intl.
+ */
+// import 'intl/locale-data/jsonp/en';
--- /dev/null
+/* You can add global styles to this file, and also import other style files */
+@import './openattic-theme.scss';
--- /dev/null
+// This file is required by karma.conf.js and loads recursively all the .spec and framework files
+
+import 'zone.js/dist/long-stack-trace-zone';
+import 'zone.js/dist/proxy.js';
+import 'zone.js/dist/sync-test';
+import 'zone.js/dist/jasmine-patch';
+import 'zone.js/dist/async-test';
+import 'zone.js/dist/fake-async-test';
+import { getTestBed } from '@angular/core/testing';
+import {
+ BrowserDynamicTestingModule,
+ platformBrowserDynamicTesting
+} from '@angular/platform-browser-dynamic/testing';
+
+// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
+declare const __karma__: any;
+declare const require: any;
+
+// Prevent Karma from running prematurely.
+__karma__.loaded = function () {};
+
+// First, initialize the Angular testing environment.
+getTestBed().initTestEnvironment(
+ BrowserDynamicTestingModule,
+ platformBrowserDynamicTesting()
+);
+// Then we find all the tests.
+const context = require.context('./', true, /\.spec\.ts$/);
+// And load the modules.
+context.keys().map(context);
+// Finally, start Karma to run the tests.
+__karma__.start();
--- /dev/null
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../out-tsc/app",
+ "baseUrl": "./",
+ "module": "es2015",
+ "types": []
+ },
+ "exclude": [
+ "test.ts",
+ "**/*.spec.ts"
+ ]
+}
--- /dev/null
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../out-tsc/spec",
+ "baseUrl": "./",
+ "module": "commonjs",
+ "target": "es5",
+ "types": [
+ "jasmine",
+ "node"
+ ]
+ },
+ "files": [
+ "test.ts"
+ ],
+ "include": [
+ "**/*.spec.ts",
+ "**/*.d.ts"
+ ]
+}
--- /dev/null
+/* SystemJS module definition */
+declare var module: NodeModule;
+interface NodeModule {
+ id: string;
+}
--- /dev/null
+{
+ "compileOnSave": false,
+ "compilerOptions": {
+ "outDir": "./dist/out-tsc",
+ "sourceMap": true,
+ "declaration": false,
+ "moduleResolution": "node",
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "target": "es5",
+ "typeRoots": [
+ "node_modules/@types"
+ ],
+ "lib": [
+ "es2017",
+ "dom"
+ ]
+ }
+}
--- /dev/null
+{
+ "rulesDirectory": [
+ "node_modules/codelyzer"
+ ],
+ "rules": {
+ "arrow-return-shorthand": true,
+ "callable-types": true,
+ "class-name": true,
+ "comment-format": [
+ true,
+ "check-space"
+ ],
+ "curly": true,
+ "eofline": true,
+ "forin": true,
+ "import-blacklist": [
+ true,
+ "rxjs",
+ "rxjs/Rx"
+ ],
+ "import-spacing": true,
+ "indent": [
+ true,
+ "spaces"
+ ],
+ "interface-over-type-literal": true,
+ "label-position": true,
+ "max-line-length": [
+ true,
+ 140
+ ],
+ "member-access": false,
+ "member-ordering": [
+ true,
+ {
+ "order": [
+ "static-field",
+ "instance-field",
+ "static-method",
+ "instance-method"
+ ]
+ }
+ ],
+ "no-arg": true,
+ "no-bitwise": true,
+ "no-console": [
+ true,
+ "debug",
+ "info",
+ "time",
+ "timeEnd",
+ "trace"
+ ],
+ "no-construct": true,
+ "no-debugger": true,
+ "no-duplicate-super": true,
+ "no-empty": false,
+ "no-empty-interface": true,
+ "no-eval": true,
+ "no-inferrable-types": [
+ true,
+ "ignore-params"
+ ],
+ "no-misused-new": true,
+ "no-non-null-assertion": true,
+ "no-shadowed-variable": true,
+ "no-string-literal": false,
+ "no-string-throw": true,
+ "no-switch-case-fall-through": true,
+ "no-trailing-whitespace": true,
+ "no-unnecessary-initializer": true,
+ "no-unused-expression": true,
+ "no-use-before-declare": true,
+ "no-var-keyword": true,
+ "object-literal-sort-keys": false,
+ "one-line": [
+ true,
+ "check-open-brace",
+ "check-catch",
+ "check-else",
+ "check-whitespace"
+ ],
+ "prefer-const": true,
+ "quotemark": [
+ true,
+ "single"
+ ],
+ "radix": true,
+ "semicolon": [
+ true,
+ "always"
+ ],
+ "triple-equals": [
+ true,
+ "allow-null-check"
+ ],
+ "typedef-whitespace": [
+ true,
+ {
+ "call-signature": "nospace",
+ "index-signature": "nospace",
+ "parameter": "nospace",
+ "property-declaration": "nospace",
+ "variable-declaration": "nospace"
+ }
+ ],
+ "typeof-compare": true,
+ "unified-signatures": true,
+ "variable-name": true,
+ "whitespace": [
+ true,
+ "check-branch",
+ "check-decl",
+ "check-operator",
+ "check-separator",
+ "check-type"
+ ],
+ "directive-selector": [
+ true,
+ "attribute",
+ "oa",
+ "camelCase"
+ ],
+ "component-selector": [
+ true,
+ "element",
+ "oa",
+ "kebab-case"
+ ],
+ "angular-whitespace": [true, "check-interpolation"],
+ "no-output-on-prefix": true,
+ "use-input-property-decorator": true,
+ "use-output-property-decorator": true,
+ "use-host-property-decorator": true,
+ "no-input-rename": true,
+ "no-output-rename": true,
+ "use-life-cycle-interface": true,
+ "use-pipe-transform-interface": true,
+ "component-class-suffix": true,
+ "directive-class-suffix": true
+ }
+}
cherrypy.tools.autenticate = cherrypy.Tool('before_handler',
Auth.check_auth)
+ current_dir = os.path.dirname(os.path.abspath(__file__))
+ fe_dir = os.path.join(current_dir, 'frontend/dist')
+ config = {
+ '/': {
+ "tools.staticdir.on": True,
+ 'tools.staticdir.dir': fe_dir,
+ 'tools.staticdir.index': "index.html"
+ }
+ }
+
cherrypy.tree.mount(Module.ApiRoot(self), "/api")
+ cherrypy.tree.mount(Module.StaticRoot(), '/', config=config)
cherrypy.engine.start()
self.log.info("Waiting for engine...")
cherrypy.engine.block()
.format(ctrl.__name__, ctrl._cp_path_))
ins = ctrl()
setattr(Module.ApiRoot, ctrl._cp_path_, ins)
+
+ class StaticRoot(object):
+ pass