diff --git a/apps/dashboard-app/src/main/js/src/app/diagnostic/views/bootcordion.js b/apps/dashboard-app/src/main/js/src/app/diagnostic/views/bootcordion.js index 6f692b8ff..943880541 100644 --- a/apps/dashboard-app/src/main/js/src/app/diagnostic/views/bootcordion.js +++ b/apps/dashboard-app/src/main/js/src/app/diagnostic/views/bootcordion.js @@ -1,106 +1,165 @@ ( function () { // -- register directive with angular -- // angular.module('shrine-tools') .directive('bootcordion', Bootcordion); var compileRef; /** * * @returns {{restict: string, replace: boolean, controller: BootcordionController, * controllerAs: string, link: BootcordionLinker, scope: {bootData: string}}} * @constructor */ function Bootcordion ($compile) { compileRef = $compile; return { restict: 'E', replace: true, - link: BootcordionLinker, + link: BootcordionLinker, controller: BootcordionController, controllerAs: 'vm', scope: { data: '=' } } } /** * * @constructor */ BootcordionController.$inject = ['$scope']; function BootcordionController ($scope) { var vm = this; vm.data = $scope.data } + //https://jsfiddle.net/GpdgF/5535/ + /** * * @type {string[]} */ BootcordionLinker.$inject = ['scope', 'element', 'attributes']; function BootcordionLinker (s, e, a) { var vm = s.vm; + var htmlStart = '
'; + + vm.testClick = function ($event, $element) { + var children = $($event.target).parent().find(' > ul > li '); + if (children.is(":visible")) { + children.hide('fast'); + $($event.target).attr('title', 'Expand this branch').find(' > i').addClass('icon-plus-sign').removeClass('icon-minus-sign'); + } else { + children.show('fast'); + $($event.target).attr('title', 'Collapse this branch').find(' > i').addClass('icon-minus-sign').removeClass('icon-plus-sign'); + } + } + var html = buildHtmlFromJson(vm.data); - e.append(html); + e.append(htmlStart + html + htmlEnd); compileRef(e.contents())(s); } /** * This is a very 'un-angular' way to do this, but for-in behavior is intrinsically un-angular as * directives do not play nicely with for-in object traversal when using the ng-repeat/nested directive * recursive approach. Trust me...this is most pain-free way to do this. * @param json * @param spaces * @returns {string} */ - function buildHtmlFromJson (json, spaces) { + function buildHtmlFromJson (json) { // -- local vars -- // var html = ''; var indent = '    '; - // -- set tab to indicate hierarchy -- // - spaces = spaces || ''; - spaces += indent; + for(var el in json){ + var openingTag = '' - for(var el in json){ if(json.hasOwnProperty(el)){ //open tag and append name if it is not an array element. + if(isNaN(el)){ - html += '
' + el; + + if(isPrimitive(json[el])) { + openingTag = '' + } + + html += '
  • ' + el + '' + openingTag; + } + //if value is a leaf. if(typeof(json[el]) !== 'object'){ - html += json[el]; + html += indent + json[el]; } //if value is not a leaf else { - html += buildHtmlFromJson(json[el], spaces); + html += buildHtmlFromJson(json[el]); } - //close tag if it is not an arra element. + //close tag if it is not an array element. if(isNaN(el)){ - html += '
  • '; + html += closingTag; } } } return html; } + function isPrimitive (element) { + return typeof(element) !== 'object' + } + })(); + +/* +
    + +
    + */ diff --git a/apps/dashboard-app/src/main/js/src/app/diagnostic/views/config.controller.js b/apps/dashboard-app/src/main/js/src/app/diagnostic/views/config.controller.js index 306bdc003..3225d22b2 100644 --- a/apps/dashboard-app/src/main/js/src/app/diagnostic/views/config.controller.js +++ b/apps/dashboard-app/src/main/js/src/app/diagnostic/views/config.controller.js @@ -1,33 +1,33 @@ (function () { 'use strict'; // -- register controller with angular -- // angular.module('shrine-tools') .controller('ShrineConfigurationController', ShrineConfigurationController); ShrineConfigurationController.$inject = ['$scope','$app', '$element', '$compile']; function ShrineConfigurationController ($scope, $app, $element, $compile) { var vm = this; $scope.ready = 'false'; init(); /** * */ function init () { $app.model.getConfig() .then(setConfig) } /** * * @param configuration */ function setConfig (config) { $scope.config = config vm.config = config; - $element.append($compile("")($scope)); + $element.append($compile('')($scope)); } } })(); diff --git a/apps/dashboard-app/src/main/js/src/app/diagnostic/views/config.tpl.html b/apps/dashboard-app/src/main/js/src/app/diagnostic/views/config.tpl.html index 3a6cce8d1..094418b68 100644 --- a/apps/dashboard-app/src/main/js/src/app/diagnostic/views/config.tpl.html +++ b/apps/dashboard-app/src/main/js/src/app/diagnostic/views/config.tpl.html @@ -1,3 +1,2 @@
    -
    \ No newline at end of file diff --git a/apps/dashboard-app/src/main/js/src/app/shrine-tools.configuration.js b/apps/dashboard-app/src/main/js/src/app/shrine-tools.configuration.js index 8335f1c42..c29d33d3a 100644 --- a/apps/dashboard-app/src/main/js/src/app/shrine-tools.configuration.js +++ b/apps/dashboard-app/src/main/js/src/app/shrine-tools.configuration.js @@ -1,242 +1,241 @@ (function () { 'use strict'; angular .module('shrine-tools') .config(ShrineToolsConfiguration); // -- todo: move to service or constant -- // var stateConfig = { 'login': { name:'login', files:[ 'src/app/common/authentication/authentication.module.js', 'src/app/common/authentication/authentication.service.js', 'src/app/login/login.controller.js' ] }, 'diagnostic': { name:'diagnostic', files:[ 'src/app/diagnostic/sidebar/sidebar.model.js', 'src/app/diagnostic/sidebar/sidebar.service.js', 'src/app/diagnostic/sidebar/node-menu.js', 'src/app/diagnostic/sidebar/downstream-node.js', 'src/app/diagnostic/sidebar/sidebar.js' ] }, 'diagnostic.summary': { name:'diagnostic.summary', files:[ 'src/app/diagnostic/views/summary.controller.js' ] }, 'diagnostic.i2b2-connections': { name:'diagnostic.i2b2-connections', files:[ 'src/app/diagnostic/views/i2b2-connections.controller.js' ] }, 'diagnostic.keystore': { name:'diagnostic.keystore', files:[ 'src/app/diagnostic/views/keystore.controller.js' ] }, 'diagnostic.hub': { name:'diagnostic.keystore', files:[ 'src/app/diagnostic/views/hub.controller.js' ] }, 'diagnostic.adapter': { name:'diagnostic.adapter', files:[ 'src/app/diagnostic/views/adapter.controller.js' ] }, 'diagnostic.qep': { name:'diagnostic.qep', files:[ 'src/app/diagnostic/views/qep.controller.js' ] }, 'diagnostic.config': { name: 'diagnostic.config', files: [ 'src/app/diagnostic/views/config.controller.js', 'src/app/diagnostic/views/bootcordion.js' ] } }; ShrineToolsConfiguration.$inject = ['$stateProvider', '$urlRouterProvider', '$ocLazyLoadProvider', '$httpProvider']; function ShrineToolsConfiguration ($stateProvider, $urlRouterProvider, $ocLazyLoadProvider, $httpProvider) { // -- set default view -- // $urlRouterProvider.otherwise('/diagnostic/summary'); configureLazyLoader($ocLazyLoadProvider); - configureHttpProvider($httpProvider); $stateProvider .state('login',{ url: '/login', controller: 'LoginController', controllerAs: 'vm', templateUrl: 'src/app/login/login.tpl.html', resolve: { loadFiles:function($ocLazyLoad) { return $ocLazyLoad.load(stateConfig['login']); } } }) .state('diagnostic', { url: '/diagnostic', controller: 'STCtrl', templateUrl: 'src/app/diagnostic/diagnostic.tpl.html', resolve: { loadFiles:function($ocLazyLoad){ return $ocLazyLoad.load(stateConfig['diagnostic']) } } }) .state('diagnostic.summary',{ url: '/summary', controller: 'SummaryController', controllerAs: 'vm', templateUrl: 'src/app/diagnostic/views/summary.tpl.html', resolve: { loadMyFiles:function($ocLazyLoad) { return $ocLazyLoad.load(stateConfig['diagnostic.summary']); } } }) .state('diagnostic.i2b2-connections',{ url: '/i2b2-connections', controller: 'I2B2ConnectionsController', controllerAs: 'vm', templateUrl: 'src/app/diagnostic/views/i2b2-connections.tpl.html', resolve: { loadMyFiles:function($ocLazyLoad) { return $ocLazyLoad.load(stateConfig['diagnostic.i2b2-connections']); } } }) .state('diagnostic.keystore',{ url: '/keystore', templateUrl: 'src/app/diagnostic/views/keystore.tpl.html', controller: 'KeystoreController', controllerAs: 'vm', resolve: { loadMyFiles: function ($ocLazyLoad) { return $ocLazyLoad.load(stateConfig['diagnostic.keystore']); } } //@todo: load files }) .state('diagnostic.hub',{ url:'/hub', templateUrl: 'src/app/diagnostic/views/hub.tpl.html', controller: 'HubController', controllerAs: 'vm', resolve: { loadMyFiles: function ($ocLazyLoad) { return $ocLazyLoad.load(stateConfig['diagnostic.hub']) } } //@todo: load files }) .state('diagnostic.adapter',{ url: '/adapter', templateUrl: 'src/app/diagnostic/views/adapter.tpl.html', controller: 'AdapterController', controllerAs: 'vm', resolve: { loadMyFiles:function($ocLazyLoad) { return $ocLazyLoad.load(stateConfig['diagnostic.adapter']); } } }) .state('diagnostic.qep',{ url: '/qep', templateUrl: 'src/app/diagnostic/views/qep.tpl.html', controller: 'QEPController', controllerAs: 'vm', resolve: { loadMyFiles: function ($ocLazyLoad) { return $ocLazyLoad.load(stateConfig['diagnostic.qep']); } } }) .state('diagnostic.config',{ url: '/config', controller: 'ShrineConfigurationController', controllerAs: 'vm', templateUrl: 'src/app/diagnostic/views/config.tpl.html', resolve: { loadFiles: function ($ocLazyLoad) { return $ocLazyLoad.load(stateConfig['diagnostic.config']); } } }) .state('diagnostic.downstream-nodes',{ url:'/downstream-nodes' //@todo: load files }); } /** * Configure lazy loader to log all errors to console, broadcast event when file, * module or component loads * @param lazyLoader * @todo: configure module dependencies here. * @see: https://oclazyload.readme.io/docs/oclazyloadprovider */ function configureLazyLoader(lazyLoader) { var lazyLoadConfig = { debug: true, events:true } lazyLoader.config(lazyLoadConfig); return lazyLoader; } /** * Set up cross domain voodoo, if running from deployment, No IE Cache * @param httpProvider * @returns {*} * @see: http://stackoverflow.com/questions/16098430/angular-ie-caching-issue-for-http */ function configureHttpProvider (httpProvider) { // -- set up cross domain -- // httpProvider.defaults.useXDomain = true; delete httpProvider.defaults.headers.common['X-Requested-With']; // -- If running from deployment, No IE Cache -- // if (window.location.origin.indexOf('http://localhost:63342') === -1) { //initialize get if not there if (!httpProvider.defaults.headers.get) { httpProvider.defaults.headers.get = {}; } //disable IE ajax request caching httpProvider.defaults.headers.get['If-Modified-Since'] = 'Sat, 26 Jul 1997 05:00:00 GMT'; httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache'; httpProvider.defaults.headers.get['Pragma'] = 'no-cache'; } return httpProvider; } })(); diff --git a/apps/dashboard-app/src/main/js/src/assets/css/shrine.css b/apps/dashboard-app/src/main/js/src/assets/css/shrine.css index 8968729c6..e1223b2f5 100644 --- a/apps/dashboard-app/src/main/js/src/assets/css/shrine.css +++ b/apps/dashboard-app/src/main/js/src/assets/css/shrine.css @@ -1,780 +1,848 @@ @font-face { font-family: 'Nexa'; src: url('../fnt/nexa/nexa-light-webfont.eot'); src: url('../fnt/nexa/nexa-light-webfont.eot?#iefix') format('embedded-opentype'), url('../fnt/nexa/nexa-light-webfont.woff2') format('woff2'), url('../fnt/nexa/nexa-light-webfont.woff') format('woff'), url('../fnt/nexa/nexa-light-webfont.ttf') format('truetype'), url('../fnt/nexa/nexa-light-webfont.svg#nexa_lightregular') format('svg'); font-weight: normal; font-style: normal; } @font-face { font-family: 'Nexa Bold'; src: url('../fnt/nexa/nexa-bold-webfont.eot'); src: url('../fnt/nexa/nexa-bold-webfont.eot?#iefix') format('embedded-opentype'), url('../fnt/nexa/nexa-bold-webfont.woff2') format('woff2'), url('../fnt/nexa/nexa-bold-webfont.woff') format('woff'), url('../fnt/nexa/nexa-bold-webfont.ttf') format('truetype'), url('../fnt/nexa/nexa-bold-webfont.svg#nexa_boldregular') format('svg'); font-weight: normal; font-style: normal; } @font-face { font-family: 'Open Sans Regular'; src: url('../fnt/open-sans/opensans-regular-webfont.eot'); src: url('../fnt/open-sans/opensans-regular-webfont.eot?#iefix') format('embedded-opentype'), url('../fnt/open-sans/opensans-regular-webfont.woff2') format('woff2'), url('../fnt/open-sans/opensans-regular-webfont.woff') format('woff'), url('../fnt/open-sans/opensans-regular-webfont.ttf') format('truetype'), url('../fnt/open-sans/opensans-regular-webfont.svg#open_sansregular') format('svg'); font-weight: normal; font-style: normal; } @font-face { font-family: 'Open Sans Semibold'; src: url('../fnt/open-sans/opensans-semibold-webfont.eot'); src: url('../fnt/open-sans/opensans-semibold-webfont.eot?#iefix') format('embedded-opentype'), url('../fnt/open-sans/opensans-semibold-webfont.woff2') format('woff2'), url('../fnt/open-sans/opensans-semibold-webfont.woff') format('woff'), url('../fnt/open-sans/opensans-semibold-webfont.ttf') format('truetype'), url('../fnt/open-sans/opensans-semibold-webfont.svg#open_sanssemibold') format('svg'); font-weight: normal; font-style: normal; } @font-face { font-family: 'Roboto Bold'; src: url('../fnt/roboto/roboto-bold-webfont.eot'); src: url('../fnt/roboto/roboto-bold-webfont.eot?#iefix') format('embedded-opentype'), url('../fnt/roboto/roboto-bold-webfont.woff2') format('woff2'), url('../fnt/roboto/roboto-bold-webfont.woff') format('woff'), url('../fnt/roboto/roboto-bold-webfont.ttf') format('truetype'), url('../fnt/roboto/roboto-bold-webfont.svg#robotobold') format('svg'); font-weight: normal; font-style: normal; } @font-face { font-family: 'Roboto Regular'; src: url('../fnt/roboto/roboto-regular-webfont.eot'); src: url('../fnt/roboto/roboto-regular-webfont.eot?#iefix') format('embedded-opentype'), url('../fnt/roboto/roboto-regular-webfont.woff2') format('woff2'), url('../fnt/roboto/roboto-regular-webfont.woff') format('woff'), url('../fnt/roboto/roboto-regular-webfont.ttf') format('truetype'), url('../fnt/roboto/roboto-regular-webfont.svg#robotoregular') format('svg'); font-weight: normal; font-style: normal; } .main-app{ background-image: url('../img/Background_Shrine.jpg'); background-size: cover; background-color: transparent; background-attachment: fixed; width: 100%; height:100%; width: calc(100vw); height: calc(100vh); min-width: 100%; min-height: 100%; } .shrine-navbar { background-color: rgba(255, 255, 255, 0.62); border-color: transparent; font-family: "Nexa"; color: #5d5d5d; min-height: 60px; width: 100%; height: 4.8em; } .shrine-brand { float: left; padding: 22px 15px; font-size: 30px; line-height: 30px; height: 30px; } .shrine-brand strong { font-family: "Nexa Bold"; color: #2c5566; } .shrine-navbar .shrine-institution-logo { background-image: url('/static/logo.png'); background-size: contain; background-color: transparent; background-color: rgba(255,255,255,0.1); background-repeat: no-repeat; background-position: right top; margin: 5px; width: 4em; height: 4em; max-height: 4em; max-width: 4em; } .shrine-button { cursor: pointer !important; background-color: transparent; border: none; } .shrine-button span { position: relative; bottom: 5px; } .shrine-btn-default { margin-right: 6px; border:none; } .shrine-btn-on { padding: 12px 12px; border-radius: 0; font-family: "Roboto Bold" !important; color: #FFFFFF !important; background: linear-gradient(rgba(4, 141, 190, .80), rgba(2, 89, 120, .80)), url('../img/bckg_diagonal_lines_no_border.png') !important; } .shrine-btn-off { padding: 6px 12px !important; border-radius: 4px !important; font-family: "Open Sans Semibold" !important; background-color: #8896A4 !important; color: #FFFFFF !important; } .shrine-on, .shrine-on a { font-family: "Roboto Bold" !important; color: #FFFFFF !important; background: linear-gradient(#048DBE, #025978) !important; } .shrine-off { font-family: "Roboto Regular" !important; color: #2C5566 !important; background-color: #ECEEEE !important; } .shrine-button.disabled, .shrine-button[disabled] { cursor: default !important; opacity: 0.2 !important; } .shrine-copy-bold { font-family: "Nexa Bold"; color: #64818e; } .shrine-copy { font-family: "Nexa"; color: #000000; } .row { margin-right: 0; margin-left: 0; } td.error, span.error { color: red; } td.error a, td.error a:hover, span.error a, span.error a:hover{ color: inherit; text-decoration: underline !important; cursor: pointer; } td.ok, span.ok { color:green; } .form-group span { font-family: "Open Sans Semibold"; color: #2c5566; } fieldset button { color: #2E5366; } fieldset button:hover, form a:hover { color: #008CBA; text-decoration: none; cursor: pointer; } form a { font-family: "Open Sans Regular"; color: #647d8d; text-decoration: none; } footer img { margin-left: 10px; margin-top: 2px; } footer { background-color: rgba(50, 62, 74, 0.48); position: fixed; bottom: 0; left: 0; width: 100%; height: 83px; min-height: 83px; max-width: 100%; } table { background-image: url('../img/bckg_diagonal_lines_no_border.png'); border: 1px solid #CCD8DF; } .table tr>td:first-child { width: 20%; min-width: 140px; } .table tr>td.thin-col { width: 6%; min-width: 35px; } .table-striped>tbody>tr:nth-of-type(odd) { background-color: #EFF6F9; } .table-striped>tbody>tr:nth-of-type(even) { background-color: #FFFFFF; } thead tr{ border: 1px solid #CCD8DF; } td{ border-right: 1px solid #CCD8DF; overflow: hidden; max-width: 450px; word-break: break-all; } thead tr td, thead tr td label, tfoot tr td span{ font-family: "Open Sans Semibold"; color: #003153; } td a, td a:hover{ text-decoration: none !important; cursor: pointer; font-family: "Open Sans Semibold"; color: #003153; } .shrine-panel{ background-image: url('../img/bckg_diagonal_lines.png'); background-size: 100% 100%; padding-right: 20px; padding-left: 20px; padding-top: 30px; padding-bottom: 30px; } /*! * Start Bootstrap - SB Admin 2 Bootstrap Admin Theme (http://startbootstrap.com) * Code licensed under the Apache License v2.0. * For details, see http://www.apache.org/licenses/LICENSE-2.0. */ body { background-image: url('../img/Background_Shrine.jpg'); background-repeat:no-repeat; background-size:100% 100%; } #wrapper { width: 100%; padding-bottom: 83px; /* clearance space for footer at bottom of long page */ } .login-wrapper{ margin-top: 51px; margin-right: 20px; } #page-wrapper { background-color: transparent; margin-top: 54px; margin-right: 20px; } .navbar-top-links li { display: inline-block; } .navbar-top-links li:last-child { margin-right: 15px; } .navbar-top-links li a { padding: 15px; min-height: 50px; font-family: "Open Sans Semibold"; color: #2c5566; } .navbar-top-links .dropdown-menu li { font-family: "Open Sans Semibold"; color: #2c5566; display: block; } .navbar-top-links .dropdown-menu li:last-child { margin-right: 0; } .navbar-top-links .dropdown-menu li a { padding: 3px 20px; min-height: 0; } .navbar-top-links .dropdown-menu li a div { white-space: normal; } .navbar-top-links .dropdown-messages, .navbar-top-links .dropdown-tasks, .navbar-top-links .dropdown-alerts { width: 310px; min-width: 0; } .navbar-top-links .dropdown-messages { margin-left: 5px; } .navbar-top-links .dropdown-tasks { margin-left: -59px; } .navbar-top-links .dropdown-alerts { margin-left: -123px; } .navbar-top-links{ right: 0; left: auto; } .sidebar .sidebar-nav.navbar-collapse { padding-right: 0; padding-left: 0; } .sidebar .sidebar-search { padding: 15px; } .sidebar ul li { border-bottom: 1px solid #e7e7e7; } .sidebar ul li a.active { background-color: #eee; } .sidebar .arrow { float: right; } .sidebar .fa.arrow:before { content: "\f104"; } .sidebar .active>a>.fa.arrow:before { content: "\f107"; } .sidebar .nav-second-level li, .sidebar .nav-third-level li { border-bottom: 0!important; } .sidebar .nav-second-level li a { padding-left: 37px; } .sidebar .nav-third-level li a { padding-left: 52px; } @media(min-width:768px) { .sidebar { z-index: 1; margin-top: 51px; } .navbar-top-links .dropdown-messages, .navbar-top-links .dropdown-tasks, .navbar-top-links .dropdown-alerts { margin-left: auto; } } .btn-outline { color: inherit; background-color: transparent; transition: all .5s; } .btn-primary.btn-outline { color: #428bca; } .btn-success.btn-outline { color: #5cb85c; } .btn-info.btn-outline { color: #5bc0de; } .btn-warning.btn-outline { color: #f0ad4e; } .btn-danger.btn-outline { color: #d9534f; } .btn-primary.btn-outline:hover, .btn-success.btn-outline:hover, .btn-info.btn-outline:hover, .btn-warning.btn-outline:hover, .btn-danger.btn-outline:hover { color: #fff; } .chat { margin: 0; padding: 0; list-style: none; } .chat li { margin-bottom: 10px; padding-bottom: 5px; border-bottom: 1px dotted #999; } .chat li.left .chat-body { margin-left: 60px; } .chat li.right .chat-body { margin-right: 60px; } .chat li .chat-body p { margin: 0; } .panel .slidedown .glyphicon, .chat .glyphicon { margin-right: 5px; } .chat-panel .panel-body { height: 350px; overflow-y: scroll; } .login-panel { margin-top: 25%; } .flot-chart { display: block; height: 400px; } .flot-chart-content { width: 100%; height: 100%; } .dataTables_wrapper { position: relative; clear: both; } table.dataTable thead .sorting, table.dataTable thead .sorting_asc, table.dataTable thead .sorting_desc, table.dataTable thead .sorting_asc_disabled, table.dataTable thead .sorting_desc_disabled { background: 0 0; } table.dataTable thead .sorting_asc:after { content: "\f0de"; float: right; font-family: fontawesome; } table.dataTable thead .sorting_desc:after { content: "\f0dd"; float: right; font-family: fontawesome; } table.dataTable thead .sorting:after { content: "\f0dc"; float: right; font-family: fontawesome; color: rgba(50,50,50,.5); } .btn-circle { width: 30px; height: 30px; padding: 6px 0; border-radius: 15px; text-align: center; font-size: 12px; line-height: 1.428571429; } .btn-circle.btn-lg { width: 50px; height: 50px; padding: 10px 16px; border-radius: 25px; font-size: 18px; line-height: 1.33; } .btn-circle.btn-xl { width: 70px; height: 70px; padding: 10px 16px; border-radius: 35px; font-size: 24px; line-height: 1.33; } .show-grid [class^=col-] { padding-top: 10px; padding-bottom: 10px; border: 1px solid #ddd; background-color: #eee!important; } .show-grid { margin: 15px 0; } .huge { font-size: 40px; } .panel-green { border-color: #5cb85c; } .panel-green .panel-heading { border-color: #5cb85c; color: #fff; background-color: #5cb85c; } .panel-green a { color: #5cb85c; } .panel-green a:hover { color: #3d8b3d; } .panel-red { border-color: #d9534f; } .panel-red .panel-heading { border-color: #d9534f; color: #fff; background-color: #d9534f; } .panel-red a { color: #d9534f; } .panel-red a:hover { color: #b52b27; } .panel-yellow { border-color: #f0ad4e; } .panel-yellow .panel-heading { border-color: #f0ad4e; color: #fff; background-color: #f0ad4e; } .panel-yellow a { color: #f0ad4e; } .panel-yellow a:hover { color: #df8a13; } .modal-content{ border: none; } .shrine-modal{ background-color: white; border: 1px solid #2c5566; font-family: "Open Sans Semibold"; color: #2e5366; padding: 15px; } .shrine-modal form div.col-sm-12{ border: 1px solid rgba(2, 89, 120, .80); } .shrine-modal input, .shrine-modal textarea{ border-radius: 0px; border: 1px solid #2c5566; } .shrine-modal span{ font-family: "Nexa Bold"; color: #2e5366; } .shrine-modal span:hover{ font-family: "Nexa Bold"; color: #008CBA; } .shrine-modal button{ background-color: white; border: none; font-family: "Nexa Bold"; color: #2e5366; } .shrine-modal button span{ position: relative; bottom: 6px; } .shrine-modal button:hover, .btn-success{ font-family: "Nexa Bold"; color: #008CBA; background-color: transparent; border: none; } .shrine-login{ margin-top: 8%; margin-left: 1%; } .shrine-content{ overflow: auto; } /*Fix for resizeable text area.*/ textarea{ resize: none; } @media (min-width: 768px) { .shrine-content { padding: 0; } } .shrine-calendar-input{ margin-right: 1px; max-width:50%; } i.shrine-close{ float:right; margin-top:-40px; margin-right:-40px; cursor:pointer; color: #fff; border: 2px solid #C8CED1; border-radius: 30px; background: #8896a4; font-size: 31px; font-weight: normal; display: inline-block; line-height: 0px; padding: 11px 3px; font-style:normal; } i.shrine-close:hover{ background: #008cba; } .shrine-close:before { content: "×"; } .list-group.panel > .list-group-item { border-bottom-right-radius: 4px; border-bottom-left-radius: 4px } .downstream-node > .list-group-item{ margin-left: 15px; } .list-group-submenu { margin-left:30px; } +.tree { + min-height:20px; + padding:19px; + margin-bottom:20px; + background-color:#fbfbfb; + border:1px solid #999; + -webkit-border-radius:4px; + -moz-border-radius:4px; + border-radius:4px; + -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05) +} +.tree li { + list-style-type:none; + margin:0; + padding:10px 5px 0 5px; + position:relative +} +.tree li::before, .tree li::after { + content:''; + left:-20px; + position:absolute; + right:auto +} +.tree li::before { + border-left:1px solid #999; + bottom:50px; + height:100%; + top:0; + width:1px +} +.tree li::after { + border-top:1px solid #999; + height:20px; + top:25px; + width:25px +} + +.tree li span:hover{ + background:#eee; + border:1px solid #94a0b4; + color:#000 +} +.tree li span { + cursor: pointer; + -moz-border-radius:5px; + -webkit-border-radius:5px; + border:1px solid #999; + border-radius:5px; + display:inline-block; + padding:3px 8px; + text-decoration:none +} +.tree li.parent_li>span { + cursor:pointer +} +.tree>ul>li::before, .tree>ul>li::after { + border:0 +} +.tree li:last-child::before { + height:30px +} +.tree li.parent_li>span:hover, .tree li.parent_li>span:hover+ul li span { + background:#eee; + border:1px solid #94a0b4; + color:#000 +} \ No newline at end of file