@ -0,0 +1,2 @@ |
||||
data/ |
||||
docker-compose.yml |
@ -0,0 +1,277 @@ |
||||
html { |
||||
height: 100%; |
||||
} |
||||
|
||||
body { |
||||
background-color: #F9F9F9; |
||||
margin: 0; |
||||
padding: 0; |
||||
height: 100%; |
||||
} |
||||
|
||||
header .navbar { |
||||
margin-bottom: 0; |
||||
min-height: inherit; |
||||
} |
||||
|
||||
.header .container { |
||||
position: relative; |
||||
} |
||||
|
||||
.navbar-title { |
||||
background-image: url('../img/logo.png'); |
||||
height: 25px; |
||||
background-repeat: no-repeat; |
||||
width: 123px; |
||||
margin: 3px 10px 5px; |
||||
text-indent: -99999px; |
||||
} |
||||
|
||||
.navbar-pf .navbar-utility { |
||||
right: 20px; |
||||
top: -34px; |
||||
font-size: 12px; |
||||
} |
||||
|
||||
.navbar-pf .navbar-utility > li > a { |
||||
color: #fff !important; |
||||
padding-bottom: 12px; |
||||
padding-top: 11px; |
||||
border-left: medium none; |
||||
} |
||||
|
||||
.container { |
||||
height: 100%; |
||||
} |
||||
|
||||
.content-area { |
||||
background-color: #fff; |
||||
border-color: #CECECE; |
||||
border-style: solid; |
||||
border-width: 0 1px; |
||||
height: 100%; |
||||
padding: 0 30px; |
||||
} |
||||
|
||||
.margin-bottom { |
||||
margin-bottom: 10px; |
||||
} |
||||
|
||||
/* Sidebar */ |
||||
|
||||
.bs-sidebar { |
||||
background-color: #f9f9f9; |
||||
padding-top: 44px; |
||||
padding-right: 0; |
||||
padding-left: 0; |
||||
z-index: 20; |
||||
} |
||||
.bs-sidebar ul { |
||||
list-style: none; |
||||
padding-left: 12px; |
||||
} |
||||
|
||||
.bs-sidebar ul li { |
||||
margin-bottom: 0.5em; |
||||
margin-left: -1em; |
||||
} |
||||
.bs-sidebar ul li a { |
||||
font-size: 14px; |
||||
padding-left: 25px; |
||||
color: #4d5258; |
||||
line-height: 28px; |
||||
display: block; |
||||
border-width: 1px 0 1px 1px; |
||||
border-style: solid; |
||||
border-color: #f9f9f9; |
||||
} |
||||
.bs-sidebar ul li a:hover, |
||||
.bs-sidebar ul li a:focus { |
||||
text-decoration: none; |
||||
color: #777777; |
||||
border-right: 2px solid #aaa; |
||||
} |
||||
.bs-sidebar ul li.active a { |
||||
background-color: #c7e5f0; |
||||
border-color: #56bae0; |
||||
font-weight: bold; |
||||
background-image: url(../img/icon-sidebar-active.png); |
||||
background-repeat: no-repeat; |
||||
background-position: right center; |
||||
} |
||||
|
||||
.bs-sidebar ul li.active a:hover { |
||||
border-right: none; |
||||
} |
||||
|
||||
|
||||
.content-area h2 { |
||||
font-family: "Open Sans", sans-serif; |
||||
font-weight: 100; |
||||
font-size: 24px; |
||||
margin-bottom: 25px; |
||||
margin-top: 25px; |
||||
} |
||||
|
||||
.subtitle { |
||||
text-align: right; |
||||
margin-top: 30px; |
||||
color: #909090; |
||||
} |
||||
|
||||
.required { |
||||
color: #CB2915; |
||||
} |
||||
|
||||
|
||||
.alert { |
||||
margin-top: 30px; |
||||
margin-bottom: 0; |
||||
} |
||||
|
||||
.feedback-aligner .alert { |
||||
background-position: 1.27273em center; |
||||
background-repeat: no-repeat; |
||||
border-radius: 2px; |
||||
border-width: 1px; |
||||
color: #4D5258; |
||||
display: inline-block; |
||||
font-size: 1.1em; |
||||
line-height: 1.4em; |
||||
margin: 0; |
||||
padding: 0.909091em 3.63636em; |
||||
position: relative; |
||||
text-align: left; |
||||
} |
||||
.alert.alert-success { |
||||
background-color: #E4F1E1; |
||||
border-color: #4B9E39; |
||||
} |
||||
.alert.alert-error { |
||||
background-color: #F8E7E7; |
||||
border-color: #B91415; |
||||
} |
||||
.alert.alert-warning { |
||||
background-color: #FEF1E9; |
||||
border-color: #F17528; |
||||
} |
||||
.alert.alert-info { |
||||
background-color: #E4F3FA; |
||||
border-color: #5994B2; |
||||
} |
||||
|
||||
.form-horizontal { |
||||
border-top: 1px solid #E9E8E8; |
||||
padding-top: 23px; |
||||
} |
||||
|
||||
.form-horizontal .control-label { |
||||
color: #909090; |
||||
line-height: 1.4em; |
||||
padding-top: 5px; |
||||
position: relative; |
||||
text-align: right; |
||||
width: 100%; |
||||
} |
||||
|
||||
.form-group { |
||||
position: relative; |
||||
} |
||||
|
||||
.control-label + .required { |
||||
position: absolute; |
||||
right: -2px; |
||||
top: 0; |
||||
} |
||||
|
||||
#kc-form-buttons { |
||||
text-align: right; |
||||
margin-top: 10px; |
||||
} |
||||
|
||||
#kc-form-buttons .btn-primary { |
||||
float: right; |
||||
margin-left: 8px; |
||||
} |
||||
|
||||
/* Authenticator page */ |
||||
|
||||
ol { |
||||
padding-left: 40px; |
||||
} |
||||
|
||||
ol li { |
||||
font-size: 13px; |
||||
margin-bottom: 10px; |
||||
position: relative; |
||||
} |
||||
|
||||
ol li img { |
||||
margin-top: 15px; |
||||
margin-bottom: 5px; |
||||
border: 1px solid #eee; |
||||
} |
||||
|
||||
hr + .form-horizontal { |
||||
border: none; |
||||
padding-top: 0; |
||||
} |
||||
|
||||
.kc-dropdown{ |
||||
position: relative; |
||||
} |
||||
.kc-dropdown > a{ |
||||
display:block; |
||||
padding: 11px 10px 12px; |
||||
line-height: 12px; |
||||
font-size: 12px; |
||||
color: #fff !important; |
||||
text-decoration: none; |
||||
} |
||||
.kc-dropdown > a::after{ |
||||
content: "\2c5"; |
||||
margin-left: 4px; |
||||
} |
||||
.kc-dropdown:hover > a{ |
||||
background-color: rgba(0,0,0,0.2); |
||||
} |
||||
.kc-dropdown ul li a{ |
||||
padding: 1px 11px; |
||||
font-size: 12px; |
||||
color: #000 !important; |
||||
border: 1px solid #fff; |
||||
text-decoration: none; |
||||
display:block; |
||||
line-height: 20px; |
||||
} |
||||
.kc-dropdown ul li a:hover{ |
||||
color: #4d5258; |
||||
background-color: #d4edfa; |
||||
border-color: #b3d3e7; |
||||
} |
||||
.kc-dropdown ul{ |
||||
position: absolute; |
||||
z-index: 2000; |
||||
list-style:none; |
||||
display:none; |
||||
padding: 5px 0px; |
||||
margin: 0px; |
||||
background-color: #fff !important; |
||||
border: 1px solid #b6b6b6; |
||||
border-radius: 1px; |
||||
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); |
||||
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); |
||||
background-clip: padding-box; |
||||
min-width: 100px; |
||||
} |
||||
.kc-dropdown:hover ul{ |
||||
display:block; |
||||
} |
||||
|
||||
|
||||
#kc-totp-secret-key { |
||||
border: 1px solid #eee; |
||||
font-size: 16px; |
||||
padding: 10px; |
||||
margin: 50px 0; |
||||
} |
After Width: | Height: | Size: 202 B |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 4.1 KiB |
@ -0,0 +1,14 @@ |
||||
parent=base |
||||
import=common/keycloak |
||||
|
||||
styles=css/account.css |
||||
stylesCommon=node_modules/patternfly/dist/css/patternfly.min.css node_modules/patternfly/dist/css/patternfly-additions.min.css |
||||
|
||||
##### css classes for form buttons |
||||
# main class used for all buttons |
||||
kcButtonClass=btn |
||||
# classes defining priority of the button - primary or default (there is typically only one priority button for the form) |
||||
kcButtonPrimaryClass=btn-primary |
||||
kcButtonDefaultClass=btn-default |
||||
# classes defining size of the button |
||||
kcButtonLargeClass=btn-lg |
@ -0,0 +1,480 @@ |
||||
html,body { |
||||
height: 100%; |
||||
} |
||||
|
||||
form { |
||||
margin-top: 20px; |
||||
} |
||||
|
||||
table { |
||||
margin-top: 20px; |
||||
} |
||||
|
||||
.required { |
||||
color: #f00; |
||||
} |
||||
|
||||
.tooltip-inner { |
||||
min-width: 200px; |
||||
} |
||||
|
||||
.margin-top { |
||||
margin-top: 20px; |
||||
} |
||||
|
||||
.no-margin-top { |
||||
margin-top: 0px !important; |
||||
} |
||||
|
||||
table { |
||||
max-width: 100%; |
||||
} |
||||
|
||||
td.clip { |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
white-space: nowrap; |
||||
max-width: 0; |
||||
} |
||||
|
||||
th.w-10 { |
||||
width: 10%; |
||||
} |
||||
|
||||
th.w-15 { |
||||
width: 15%; |
||||
} |
||||
|
||||
th.w-20 { |
||||
width: 20%; |
||||
} |
||||
|
||||
|
||||
th.w-25 { |
||||
width: 25%; |
||||
} |
||||
|
||||
th.w-30 { |
||||
width: 30%; |
||||
} |
||||
|
||||
|
||||
th.w-35 { |
||||
width: 35%; |
||||
} |
||||
|
||||
th.w-40 { |
||||
width: 40%; |
||||
} |
||||
|
||||
/*********** Loading ***********/ |
||||
|
||||
.loading { |
||||
background-color: #f5f5f5; |
||||
border: 1px solid #eee; |
||||
position: absolute; |
||||
bottom: 0px; |
||||
left: 0px; |
||||
padding: 2px 200px 2px 5px; |
||||
} |
||||
|
||||
/*********** Feedback ***********/ |
||||
|
||||
.feedback-aligner { |
||||
position: fixed; |
||||
top: 15px; |
||||
text-align: center; |
||||
width: 100%; |
||||
height: 0; |
||||
z-index: 100; |
||||
} |
||||
.feedback-aligner .alert { |
||||
border-radius: 2px; |
||||
border-width: 1px; |
||||
display: inline-block; |
||||
position: relative; |
||||
} |
||||
|
||||
/*********** On-Off Switch ***********/ |
||||
|
||||
.onoffswitch { |
||||
-moz-user-select: none; |
||||
height: 26px; |
||||
position: relative; |
||||
width: 62px; |
||||
} |
||||
.onoffswitch .onoffswitch-checkbox { |
||||
display: none; |
||||
} |
||||
.onoffswitch .onoffswitch-label { |
||||
border: 1px solid #bbb; |
||||
border-radius: 2px; |
||||
cursor: pointer; |
||||
display: block; |
||||
overflow: hidden; |
||||
width: 62px; |
||||
} |
||||
.onoffswitch .onoffswitch-inner { |
||||
display: block; |
||||
margin-left: -100%; |
||||
transition: margin 0.3s ease-in 0s; |
||||
width: 200%; |
||||
} |
||||
.onoffswitch .onoffswitch-inner > span { |
||||
-moz-box-sizing: border-box; |
||||
color: white; |
||||
float: left; |
||||
font-size: 11px; |
||||
font-family: "Open Sans", sans-serif; |
||||
font-weight: bold; |
||||
height: 24px; |
||||
line-height: 24px; |
||||
padding: 0; |
||||
width: 50%; |
||||
} |
||||
.onoffswitch .onoffswitch-switch { |
||||
background-image: linear-gradient(top, #fafafa 0%, #ededed 100%); |
||||
background-image: -o-linear-gradient(top, #fafafa 0%, #ededed 100%); |
||||
background-image: -moz-linear-gradient(top, #fafafa 0%, #ededed 100%); |
||||
background-image: -webkit-linear-gradient(top, #fafafa 0%, #ededed 100%); |
||||
background-image: -ms-linear-gradient(top, #fafafa 0%, #ededed 100%); |
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fafafa), color-stop(1, 0, #ededed)); |
||||
border: 1px solid #aaa; |
||||
border-radius: 2px; |
||||
bottom: 0; |
||||
margin: 0; |
||||
position: absolute; |
||||
right: 39px; |
||||
top: 0; |
||||
transition: all 0.3s ease-in 0s; |
||||
-webkit-transition: all 0.3s ease-in 0s; |
||||
width: 23px; |
||||
} |
||||
.onoffswitch .onoffswitch-inner .onoffswitch-active { |
||||
background-image: linear-gradient(top, #00a9ec 0%, #009bd3 100%); |
||||
background-image: -o-linear-gradient(top, #00a9ec 0%, #009bd3 100%); |
||||
background-image: -moz-linear-gradient(top, #00a9ec 0%, #009bd3 100%); |
||||
background-image: -webkit-linear-gradient(top, #00a9ec 0%, #009bd3 100%); |
||||
background-image: -ms-linear-gradient(top, #00a9ec 0%, #009bd3 100%); |
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #00a9ec), color-stop(1, 0, #009bd3)); |
||||
color: #FFFFFF; |
||||
padding-left: 10px; |
||||
} |
||||
.onoffswitch-checkbox:disabled + .onoffswitch-label .onoffswitch-inner .onoffswitch-active, |
||||
.onoffswitch-checkbox:disabled + .onoffswitch-label .onoffswitch-inner .onoffswitch-inactive { |
||||
background-image: none; |
||||
background-color: #e5e5e5; |
||||
color: #9d9fa1; |
||||
} |
||||
.onoffswitch .onoffswitch-inner .onoffswitch-inactive { |
||||
background: linear-gradient(#fefefe, #e8e8e8) repeat scroll 0 0 transparent; |
||||
color: #4d5258; |
||||
padding-right: 10px; |
||||
text-align: right; |
||||
} |
||||
.onoffswitch .onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner { |
||||
margin-left: 0; |
||||
} |
||||
.onoffswitch .onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch { |
||||
right: 0; |
||||
} |
||||
|
||||
|
||||
/*********** Select 2 ***********/ |
||||
|
||||
.select2-container { |
||||
width: 100%; |
||||
} |
||||
|
||||
.select2-container-multi .select2-choices .select2-search-field { |
||||
height: 26px; |
||||
} |
||||
|
||||
/*********** html select ********/ |
||||
.overflow-select { |
||||
overflow: auto; |
||||
} |
||||
|
||||
|
||||
/*********** New Menu ***********/ |
||||
|
||||
|
||||
.sidebar-pf-left{ |
||||
background: #292e34; |
||||
} |
||||
|
||||
.sidebar-pf .nav-pills > li a i, .sidebar-pf .nav-pills > li a span{ |
||||
color: #72767b; |
||||
display: inline-block; |
||||
margin-right: 10px; |
||||
} |
||||
.sidebar-pf .nav-pills > li > a{ |
||||
color: #dbdada; |
||||
padding: 0px 20px 0 30px!important; |
||||
line-height: 30px; |
||||
border-left-width: 12px; |
||||
border-left-style: solid; |
||||
border-left-color: #292e34; |
||||
margin-left: -6px; |
||||
} |
||||
|
||||
.sidebar-pf .nav-pills > li > a:hover{ |
||||
background: #393f44; |
||||
border-color:#292e34; |
||||
border-left-color: #393f44; |
||||
color: #fff; |
||||
} |
||||
|
||||
.sidebar-pf .nav-pills > li > a:after{ |
||||
display: none!important; |
||||
} |
||||
|
||||
|
||||
.sidebar-pf .nav-pills > li.active > a { |
||||
color: #fff; |
||||
background: #393f44!important; |
||||
border-bottom: 1px solid #000!important; |
||||
border-top: 1px solid #000!important; |
||||
border-left-color: #39a5dc!important; |
||||
} |
||||
|
||||
.sidebar-pf .nav-pills > li.active a i, .sidebar-pf .nav-pills > li.active a span{ |
||||
color: #39a5dc; |
||||
} |
||||
|
||||
/*********** Realm selector ***********/ |
||||
|
||||
.realm-selector{ |
||||
color: #fff; |
||||
margin: 0 -20px; |
||||
position: relative; |
||||
} |
||||
|
||||
.realm-dropmenu{ |
||||
display: none; |
||||
cursor: pointer; |
||||
position: absolute; |
||||
top: 60px; |
||||
left: 0; |
||||
right: 0; |
||||
z-index: 999; |
||||
background: #fff; |
||||
} |
||||
|
||||
.realm-selector:hover .realm-dropmenu{ |
||||
display: block; |
||||
} |
||||
|
||||
.realm-add{ |
||||
padding: 10px; |
||||
} |
||||
|
||||
.realm-selector h2{ |
||||
font-size: 16px; |
||||
line-height: 60px; |
||||
padding: 0 20px; |
||||
margin: 0; |
||||
border-bottom: 1px solid #d5d5d6; |
||||
} |
||||
|
||||
.realm-selector h2 i{ |
||||
display: inline-block; |
||||
float: right; |
||||
line-height: 60px; |
||||
} |
||||
|
||||
|
||||
.realm-selector ul{ |
||||
padding-left: 0; |
||||
margin: 0; |
||||
list-style: none; |
||||
max-height: 200px; |
||||
overflow-y:auto; |
||||
} |
||||
|
||||
|
||||
.realm-selector ul li a{ |
||||
line-height: 60px; |
||||
padding: 0 20px; |
||||
border-bottom: 1px solid #d5d5d6; |
||||
line-height: 39px; |
||||
display: block; |
||||
font-size: 14px; |
||||
} |
||||
|
||||
|
||||
/*********** Overwrites header defaults ***********/ |
||||
|
||||
.navbar-pf{ |
||||
border-top: none!important; |
||||
} |
||||
|
||||
.navbar-pf .navbar-brand { |
||||
padding: 0; |
||||
height: 56px; |
||||
line-height: 56px; |
||||
background-position: center center; |
||||
background-image: url('../img/keyclok-logo.png'); |
||||
background-size: 148px 30px; |
||||
background-repeat: no-repeat; |
||||
width: 148px; |
||||
} |
||||
|
||||
.navbar-pf .navbar-utility .dropdown-toggle { |
||||
padding: 23px !important; |
||||
} |
||||
|
||||
.clickable { |
||||
cursor: pointer; |
||||
} |
||||
|
||||
h1 i { |
||||
color: #999999; |
||||
font-size: 18px; |
||||
margin-left: 10px; |
||||
} |
||||
|
||||
/* Action cell */ |
||||
.kc-action-cell { |
||||
background-color: #eeeeee; |
||||
background-image: linear-gradient(to bottom, #fafafa 0%, #ededed 100%); |
||||
background-repeat: repeat-x; |
||||
|
||||
text-align: center; |
||||
vertical-align: middle; |
||||
|
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
white-space: nowrap; |
||||
|
||||
cursor:pointer; |
||||
} |
||||
|
||||
.kc-action-cell:hover { |
||||
background-color: #eeeeee; |
||||
background-image: none; |
||||
} |
||||
|
||||
.kc-sorter span { |
||||
margin-left: 10px; |
||||
} |
||||
|
||||
|
||||
/* Time selector */ |
||||
|
||||
.time-selector input { |
||||
display: inline-block; |
||||
width: 120px; |
||||
padding-right: 0; |
||||
margin-right: 0; |
||||
} |
||||
|
||||
.time-selector select { |
||||
display: inline-block; |
||||
width: 80px; |
||||
margin-left: 0; |
||||
padding-left: 0; |
||||
} |
||||
|
||||
.ace_editor { |
||||
height: 600px; |
||||
width: 100%; |
||||
} |
||||
|
||||
.kc-button-input-file input { |
||||
float: left; |
||||
width: 73%; |
||||
} |
||||
|
||||
.kc-button-input-file label { |
||||
float: left; |
||||
margin-left: 2%; |
||||
width: 25%; |
||||
} |
||||
|
||||
table.kc-authz-table-expanded { |
||||
margin-top: 0px !important; |
||||
} |
||||
|
||||
.no-gutter > [class*='col-'] { |
||||
padding-right:0!important; |
||||
padding-left:0!important; |
||||
} |
||||
|
||||
.password-conceal { |
||||
font-family: 'text-security-disc'; |
||||
font-size: 14px; |
||||
} |
||||
|
||||
/* Deactivation styles for user-group membership tree models */ |
||||
|
||||
div[tree-model] li .deactivate { |
||||
color: #4a5053; |
||||
opacity: 0.4; |
||||
} |
||||
|
||||
div[tree-model] li .deactivate_selected { |
||||
background-color: #dcdcdc; |
||||
font-weight: bold; |
||||
padding: 1px 5px; |
||||
} |
||||
|
||||
/* search highlighting */ |
||||
|
||||
div[tree-model] li .highlight { |
||||
background-color: #aaddff; |
||||
} |
||||
|
||||
/* Manage credentials */ |
||||
table.credentials-table { |
||||
margin-top: 0; |
||||
margin-bottom: 20px; |
||||
} |
||||
|
||||
table.credentials-table td { |
||||
vertical-align: middle !important; |
||||
} |
||||
|
||||
table.credentials-table input[type='text'] { |
||||
width: 100%; |
||||
} |
||||
|
||||
td.credential-arrows-cell { |
||||
width: 75px; |
||||
} |
||||
|
||||
td.credential-label-cell { |
||||
padding: 5px !important; |
||||
} |
||||
|
||||
td.credential-action-cell { |
||||
padding: 0px !important; |
||||
} |
||||
|
||||
td.credential-action-cell div.kc-action-cell { |
||||
width: 100%; |
||||
height: 36px; |
||||
line-height: 34px; |
||||
} |
||||
|
||||
td.credential-action-cell.expanded div.kc-action-cell { |
||||
border-bottom: 1px solid #d1d1d1; |
||||
} |
||||
|
||||
table.credential-data-table td { |
||||
word-break: break-all; |
||||
} |
||||
|
||||
table.credential-data-table tr:first-child td { |
||||
border-top: 0; |
||||
} |
||||
|
||||
table.credential-data-table td:first-child { |
||||
width: 150px; |
||||
} |
||||
|
||||
table.credential-data-table td.key { |
||||
text-align: right; |
||||
font-weight: bold; |
||||
} |
||||
|
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,5 @@ |
||||
parent=base |
||||
import=common/keycloak |
||||
|
||||
styles=css/styles.css |
||||
stylesCommon=node_modules/patternfly/dist/css/patternfly.min.css node_modules/patternfly/dist/css/patternfly-additions.min.css node_modules/select2/select2.css lib/angular/treeview/css/angular.treeview.css node_modules/text-security/text-security.css |
After Width: | Height: | Size: 627 B |
@ -0,0 +1,20 @@ |
||||
The MIT License (MIT) |
||||
|
||||
Copyright (c) 2013 Steve |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of |
||||
this software and associated documentation files (the "Software"), to deal in |
||||
the Software without restriction, including without limitation the rights to |
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
||||
the Software, and to permit persons to whom the Software is furnished to do so, |
||||
subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,122 @@ |
||||
Angular Treeview |
||||
================ |
||||
|
||||
Pure [AngularJS](https://www.angularjs.org) based tree menu directive. |
||||
|
||||
[](https://jsfiddle.net/eu81273/8LWUc/) |
||||
|
||||
## Installation |
||||
|
||||
Copy the script and css into your project and add a script and link tag to your page. |
||||
|
||||
```html |
||||
<script type="text/javascript" src="/angular.treeview.js"></script> |
||||
<link rel="stylesheet" type="text/css" href="css/angular.treeview.css"> |
||||
``` |
||||
|
||||
Add a dependency to your application module. |
||||
|
||||
```javascript |
||||
angular.module('myApp', ['angularTreeview']); |
||||
``` |
||||
|
||||
Add a tree to your application. See [Usage](#usage). |
||||
|
||||
## Usage |
||||
|
||||
Attributes of angular treeview are below. |
||||
|
||||
- angular-treeview: the treeview directive. |
||||
- tree-id : each tree's unique id. |
||||
- tree-model : the tree model on $scope. |
||||
- node-id : each node's id. |
||||
- node-label : each node's label. |
||||
- node-children: each node's children. |
||||
|
||||
Here is a simple example. |
||||
|
||||
|
||||
```html |
||||
<div |
||||
data-angular-treeview="true" |
||||
data-tree-id="abc" |
||||
data-tree-model="treedata" |
||||
data-node-id="id" |
||||
data-node-label="label" |
||||
data-node-children="children" > |
||||
</div> |
||||
``` |
||||
|
||||
Example model: |
||||
|
||||
```javascript |
||||
$scope.treedata = |
||||
[ |
||||
{ "label" : "User", "id" : "role1", "children" : [ |
||||
{ "label" : "subUser1", "id" : "role11", "children" : [] }, |
||||
{ "label" : "subUser2", "id" : "role12", "children" : [ |
||||
{ "label" : "subUser2-1", "id" : "role121", "children" : [ |
||||
{ "label" : "subUser2-1-1", "id" : "role1211", "children" : [] }, |
||||
{ "label" : "subUser2-1-2", "id" : "role1212", "children" : [] } |
||||
]} |
||||
]} |
||||
]}, |
||||
{ "label" : "Admin", "id" : "role2", "children" : [] }, |
||||
{ "label" : "Guest", "id" : "role3", "children" : [] } |
||||
]; |
||||
``` |
||||
|
||||
## Selection |
||||
|
||||
If tree node is selected, then that selected tree node is saved to $scope."TREE ID".currentNode. By using $watch, the controller can recognize the tree selection. |
||||
|
||||
|
||||
```javascript |
||||
$scope.$watch( 'abc.currentNode', function( newObj, oldObj ) { |
||||
if( $scope.abc && angular.isObject($scope.abc.currentNode) ) { |
||||
console.log( 'Node Selected!!' ); |
||||
console.log( $scope.abc.currentNode ); |
||||
} |
||||
}, false); |
||||
``` |
||||
|
||||
## Examples |
||||
|
||||
#### Basic example |
||||
[](https://jsfiddle.net/eu81273/8LWUc/) |
||||
|
||||
[jsFiddle - http://jsfiddle.net/eu81273/8LWUc/](https://jsfiddle.net/eu81273/8LWUc/) |
||||
|
||||
#### Multiple treeview example |
||||
[](https://jsfiddle.net/eu81273/b9Pnw/) |
||||
|
||||
[jsFiddle - http://jsfiddle.net/eu81273/b9Pnw/](https://jsfiddle.net/eu81273/b9Pnw/) |
||||
|
||||
## Browser Compatibility |
||||
|
||||
Same with AngularJS. Safari, Chrome, Firefox, Opera, IE8, IE9 and mobile browsers (Android, Chrome Mobile, iOS Safari). |
||||
|
||||
## Changelogs |
||||
|
||||
#### version 0.1.6 |
||||
- Fixed the bug that 'null' string appears before each 'div' generated. (Thanks to Iaac) |
||||
|
||||
#### version 0.1.5 |
||||
- support multiple treeview. (Thanks to Axel Pesme) |
||||
|
||||
#### version 0.1.4 |
||||
- prevented memory leaks. |
||||
|
||||
#### version 0.1.3 |
||||
- removed unnecessary codes. |
||||
|
||||
#### version 0.1.2 |
||||
- removed some jQuery dependency. (Issue #2) |
||||
|
||||
## License |
||||
|
||||
The MIT License. |
||||
|
||||
Copyright โ 2013 AHN JAE-HA. |
||||
|
||||
See [LICENSE](https://github.com/eu81273/angular.treeview/blob/master/LICENSE) |
@ -0,0 +1,97 @@ |
||||
/* |
||||
@license Angular Treeview version 0.1.6 |
||||
โ 2013 AHN JAE-HA http://github.com/eu81273/angular.treeview
|
||||
License: MIT |
||||
|
||||
|
||||
[TREE attribute] |
||||
angular-treeview: the treeview directive |
||||
tree-id : each tree's unique id. |
||||
tree-model : the tree model on $scope. |
||||
node-id : each node's id |
||||
node-label : each node's label |
||||
node-children: each node's children |
||||
|
||||
<div |
||||
data-angular-treeview="true" |
||||
data-tree-id="tree" |
||||
data-tree-model="roleList" |
||||
data-node-id="roleId" |
||||
data-node-label="roleName" |
||||
data-node-children="children" > |
||||
</div> |
||||
*/ |
||||
|
||||
(function ( angular ) { |
||||
'use strict'; |
||||
|
||||
angular.module( 'angularTreeview', [] ).directive( 'treeModel', ['$compile', function( $compile ) { |
||||
return { |
||||
restrict: 'A', |
||||
link: function ( scope, element, attrs ) { |
||||
//tree id
|
||||
var treeId = attrs.treeId; |
||||
|
||||
//tree model
|
||||
var treeModel = attrs.treeModel; |
||||
|
||||
//node id
|
||||
var nodeId = attrs.nodeId || 'id'; |
||||
|
||||
//node label
|
||||
var nodeLabel = attrs.nodeLabel || 'label'; |
||||
|
||||
//children
|
||||
var nodeChildren = attrs.nodeChildren || 'children'; |
||||
|
||||
//tree template
|
||||
|
||||
var template = |
||||
'<ul>' + |
||||
'<li data-ng-repeat="node in ' + treeModel + '">' + |
||||
'<i ng-class="getGroupClass(node)" data-ng-click="' + treeId + '.selectNodeHead(node)"></i>' + |
||||
'<span data-ng-class="getSelectedClass(node)" ng-dblclick="edit(node)" data-ng-click="' + treeId + '.selectNodeLabel(node)">{{node.' + nodeLabel + '}}</span>' + |
||||
'<div data-ng-hide="node.collapsed" data-tree-id="' + treeId + '" data-tree-model="node.' + nodeChildren + '" data-node-id=' + nodeId + ' data-node-label=' + nodeLabel + ' data-node-children=' + nodeChildren + '></div>' + |
||||
'</li>' + |
||||
'</ul>'; |
||||
|
||||
|
||||
//check tree id, tree model
|
||||
if( treeId && treeModel ) { |
||||
//root node
|
||||
if( attrs.angularTreeview ) { |
||||
|
||||
//create tree object if not exists
|
||||
scope[treeId] = scope[treeId] || {}; |
||||
|
||||
//if node head clicks,
|
||||
scope[treeId].selectNodeHead = scope[treeId].selectNodeHead || function( selectedNode ){ |
||||
|
||||
//Collapse or Expand
|
||||
selectedNode.collapsed = !selectedNode.collapsed; |
||||
scope[treeId].selectNodeLabel(selectedNode); |
||||
}; |
||||
|
||||
//if node label clicks,
|
||||
scope[treeId].selectNodeLabel = scope[treeId].selectNodeLabel || function( selectedNode ){ |
||||
|
||||
//remove highlight from previous node
|
||||
if( scope[treeId].currentNode && scope[treeId].currentNode.selected ) { |
||||
scope[treeId].currentNode.selected = undefined; |
||||
} |
||||
|
||||
//set highlight to selected node
|
||||
selectedNode.selected = 'selected'; |
||||
|
||||
//set currentNode
|
||||
scope[treeId].currentNode = selectedNode; |
||||
}; |
||||
} |
||||
|
||||
//Rendering template.
|
||||
element.html('').append( $compile( template )( scope ) ); |
||||
} |
||||
} |
||||
}; |
||||
}]); |
||||
})( angular ); |
@ -0,0 +1,9 @@ |
||||
/* |
||||
@license Angular Treeview version 0.1.6 |
||||
โ 2013 AHN JAE-HA http://github.com/eu81273/angular.treeview
|
||||
License: MIT |
||||
*/ |
||||
|
||||
(function(f){f.module("angularTreeview",[]).directive("treeModel",function($compile){return{restrict:"A",link:function(b,h,c){var a=c.treeId,g=c.treeModel,e=c.nodeLabel||"label",d=c.nodeChildren||"children",e='<ul><li data-ng-repeat="node in '+g+'"><i class="collapsed" data-ng-show="node.'+d+'.length && node.collapsed" data-ng-click="'+a+'.selectNodeHead(node)"></i><i class="expanded" data-ng-show="node.'+d+'.length && !node.collapsed" data-ng-click="'+a+'.selectNodeHead(node)"></i><i class="normal" data-ng-hide="node.'+ |
||||
d+'.length"></i> <span data-ng-class="node.selected" data-ng-click="'+a+'.selectNodeLabel(node)">{{node.'+e+'}}</span><div data-ng-hide="node.collapsed" data-tree-id="'+a+'" data-tree-model="node.'+d+'" data-node-id='+(c.nodeId||"id")+" data-node-label="+e+" data-node-children="+d+"></div></li></ul>";a&&g&&(c.angularTreeview&&(b[a]=b[a]||{},b[a].selectNodeHead=b[a].selectNodeHead||function(a){a.collapsed=!a.collapsed},b[a].selectNodeLabel=b[a].selectNodeLabel||function(c){b[a].currentNode&&b[a].currentNode.selected&& |
||||
(b[a].currentNode.selected=void 0);c.selected="selected";b[a].currentNode=c}),h.html('').append($compile(e)(b)))}}})})(angular); |
@ -0,0 +1,99 @@ |
||||
div[angular-treeview] { |
||||
/* prevent user selection */ |
||||
-moz-user-select: -moz-none; |
||||
-khtml-user-select: none; |
||||
-webkit-user-select: none; |
||||
-ms-user-select: none; |
||||
user-select: none; |
||||
|
||||
/* default */ |
||||
font-family: Tahoma; |
||||
font-size:13px; |
||||
color: #555; |
||||
text-decoration: none; |
||||
} |
||||
|
||||
div[tree-model] ul { |
||||
margin: 0; |
||||
padding: 0; |
||||
list-style: none; |
||||
border: none; |
||||
overflow: hidden; |
||||
} |
||||
|
||||
div[tree-model] li { |
||||
position: relative; |
||||
padding: 0 0 0 20px; |
||||
line-height: 20px; |
||||
} |
||||
|
||||
div[tree-model] li .expanded { |
||||
padding: 1px 10px; |
||||
background-image: url("../img/folder.png"); |
||||
background-repeat: no-repeat; |
||||
} |
||||
|
||||
div[tree-model] li .collapsed { |
||||
padding: 1px 10px; |
||||
background-image: url("../img/folder-closed.png"); |
||||
background-repeat: no-repeat; |
||||
} |
||||
|
||||
div[tree-model] li .normal { |
||||
padding: 1px 10px; |
||||
background-image: url("../img/file.png"); |
||||
background-repeat: no-repeat; |
||||
} |
||||
|
||||
div[tree-model] li i, div[tree-model] li span { |
||||
cursor: pointer; |
||||
} |
||||
|
||||
div[tree-model] li .selected { |
||||
background-color: #aaddff; |
||||
font-weight: bold; |
||||
padding: 1px 5px; |
||||
} |
||||
|
||||
div[tree-model] li .cut { |
||||
font-weight: bold; |
||||
color: gray |
||||
} |
||||
|
||||
/* |
||||
.angular-ui-tree-handle { |
||||
cursor: grab; |
||||
text-decoration: none; |
||||
font-weight: bold; |
||||
-webkit-box-sizing: border-box; |
||||
-moz-box-sizing: border-box; |
||||
box-sizing: border-box; |
||||
min-height: 20px; |
||||
line-height: 20px; |
||||
} |
||||
*/ |
||||
|
||||
.angular-ui-tree-handle { |
||||
/* background: #f8faff; */ |
||||
/* |
||||
color: #7c9eb2; */ |
||||
border: 1px solid #dae2ea; |
||||
padding: 10px 10px; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
.expanded-folder { |
||||
padding: 1px 10px; |
||||
background-image: url("../img/folder.png"); |
||||
background-repeat: no-repeat; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
.collapsed-folder { |
||||
padding: 1px 10px; |
||||
background-image: url("../img/folder-closed.png"); |
||||
background-repeat: no-repeat; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
|
After Width: | Height: | Size: 263 B |
After Width: | Height: | Size: 281 B |
After Width: | Height: | Size: 289 B |
@ -0,0 +1 @@ |
||||
{"raw":"v1.4.4","major":1,"minor":4,"patch":4,"prerelease":[],"build":[],"version":"1.4.4","codeName":"pylon-requirement","full":"1.4.4","branch":"v1.4.x","cdn": |