└── rbac ├── __init__.py ├── migrations └── __init__.py ├── admin.py ├── tests.py ├── apps.py ├── static └── assets │ ├── images │ ├── Ie.png │ ├── chrome.png │ ├── crop.png │ ├── logo.png │ ├── mobile.png │ ├── opera.png │ ├── safari.png │ ├── favicon.png │ ├── firefox.png │ ├── loading.gif │ ├── attachment1.jpg │ ├── attachment2.jpg │ ├── icon-close.png │ ├── logo-dark.png │ ├── logo-icon.png │ ├── reset-email.jpg │ ├── email-welcome.jpg │ ├── profile-cover.jpg │ ├── profile-picture.png │ ├── profile-picture2.png │ ├── profile-picture3.png │ ├── profile-widge-bg.png │ └── users │ │ ├── avatar-1.jpg │ │ ├── avatar-10.jpg │ │ ├── avatar-2.jpg │ │ ├── avatar-3.jpg │ │ ├── avatar-4.jpg │ │ ├── avatar-5.jpg │ │ ├── avatar-6.jpg │ │ ├── avatar-7.jpg │ │ ├── avatar-8.jpg │ │ └── avatar-9.jpg │ ├── pages │ ├── compose.js │ ├── gmap-customs.js │ ├── inbox.js │ ├── imagecrop-custom.js │ ├── maps-vector.js │ ├── multi-select-init.js │ ├── calendar-custom.js │ ├── dashboard2.js │ ├── jquery.charts-sparkline-custom.js │ ├── components-jqueryui-sliders.js │ ├── morris-custom.js │ ├── jquery.sweet-alert.custom.js │ ├── table-data.js │ ├── validation-custom.js │ ├── bootstrap-editable-custom.js │ ├── jquery.flot.init.js │ ├── dashboard.js │ ├── notifications.js │ └── toast-custom.js │ ├── css │ ├── icons │ │ ├── ion-icon │ │ │ └── fonts │ │ │ │ ├── ionicons.eot │ │ │ │ ├── ionicons.ttf │ │ │ │ ├── ionicons.woff │ │ │ │ └── bkp │ │ │ │ ├── ionicons.eot │ │ │ │ ├── ionicons.ttf │ │ │ │ └── ionicons.woff │ │ ├── themify-icon │ │ │ └── fonts │ │ │ │ ├── themify.eot │ │ │ │ ├── themify.ttf │ │ │ │ └── themify.woff │ │ ├── font-awesome │ │ │ └── fonts │ │ │ │ ├── FontAwesome.otf │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ └── fontawesome-webfont.woff2 │ │ ├── simple-line-icon │ │ │ └── fonts │ │ │ │ ├── Simple-Line-Icons.eot │ │ │ │ ├── Simple-Line-Icons.ttf │ │ │ │ ├── Simple-Line-Icons.woff │ │ │ │ └── Simple-Line-Icons.woff2 │ │ └── material-design-icon │ │ │ └── fonts │ │ │ ├── materialdesignicons-webfont.eot │ │ │ ├── materialdesignicons-webfont.ttf │ │ │ ├── materialdesignicons-webfont.woff │ │ │ └── materialdesignicons-webfont.woff2 │ └── icons.css │ ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.html │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ ├── glyphicons-halflings-regular.woff2 │ ├── glyphicons-halflings-regulard41d.eot │ └── glyphicons-halflings-regular.svg.readme │ ├── plugins │ ├── datatables │ │ └── images │ │ │ ├── sort_asc.png │ │ │ ├── sort_both.png │ │ │ ├── sort_desc.png │ │ │ ├── sort_asc_disabled.png │ │ │ └── sort_desc_disabled.png │ ├── bootstrap-editable │ │ └── img │ │ │ ├── clear.png │ │ │ └── loading.gif │ ├── jquery-multi-select │ │ ├── img │ │ │ └── switch.png │ │ ├── css │ │ │ └── multi-select.css │ │ └── js │ │ │ └── jquery.quicksearch.js │ ├── jquery-ui │ │ └── images │ │ │ ├── ui-icons_222222_256x240.png │ │ │ ├── ui-icons_228ef1_256x240.png │ │ │ ├── ui-icons_ef8c08_256x240.png │ │ │ ├── ui-icons_ffd27a_256x240.png │ │ │ ├── ui-icons_ffffff_256x240.png │ │ │ ├── ui-bg_flat_10_000000_40x100.png │ │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png │ │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png │ │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png │ │ │ └── ui-bg_highlight-soft_75_ffe45c_1x100.png │ ├── bootstrap-colorpicker │ │ ├── img │ │ │ └── bootstrap-colorpicker │ │ │ │ ├── hue.png │ │ │ │ ├── alpha.png │ │ │ │ ├── saturation.png │ │ │ │ ├── hue-horizontal.png │ │ │ │ └── alpha-horizontal.png │ │ └── css │ │ │ └── bootstrap-colorpicker.min.css │ ├── morris-chart │ │ └── morris.css │ ├── bootstrap-touchspin │ │ ├── css │ │ │ └── jquery.bootstrap-touchspin.min.css │ │ └── dist │ │ │ └── jquery.bootstrap-touchspin.min.css │ ├── bootstrap-wysihtml5 │ │ └── bootstrap-wysihtml5.css │ ├── clockpicker │ │ └── css │ │ │ └── bootstrap-clockpicker.min.css │ ├── flot-chart │ │ ├── jquery.flot.resize.js │ │ ├── jquery.flot.tooltip.min.js │ │ ├── jquery.flot.crosshair.js │ │ └── jquery.flot.orderBars.min.js │ ├── vector-map │ │ ├── gdp-data.js │ │ └── jquery-jvectormap-2.0.2.css │ ├── cropper-master │ │ └── cropper.min.css │ ├── timepicker │ │ └── bootstrap-timepicker.min.css │ ├── bootstrap-maxlength │ │ └── bootstrap-maxlength.min.js │ ├── jquery-quicksearch │ │ └── jquery.quicksearch.js │ ├── bootstrap-inputmask │ │ └── bootstrap-inputmask.min.js │ ├── jquery-toast │ │ └── jquery.toast.min.css │ └── inputmask │ │ └── jasny-bootstrap.min.js │ └── js │ ├── custom.js │ └── functions.js ├── templates └── rbac │ ├── static_menu.html │ ├── multi_menu.html │ ├── breadcrumb.html │ ├── delete.html │ ├── change.html │ ├── user_list.html │ ├── error-404.html │ ├── menu_change.html │ ├── role_list.html │ └── multi_permissions.html ├── forms ├── role.py ├── base.py └── user.py ├── service ├── urls.py ├── init_permission.py └── routes.py ├── models.py ├── templatetags └── rbac.py ├── urls.py ├── views ├── role.py └── user.py └── middlewares └── rbac.py /rbac/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rbac/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rbac/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /rbac/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /rbac/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class RbacConfig(AppConfig): 5 | name = 'rbac' 6 | -------------------------------------------------------------------------------- /rbac/static/assets/images/Ie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/Ie.png -------------------------------------------------------------------------------- /rbac/static/assets/images/chrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/chrome.png -------------------------------------------------------------------------------- /rbac/static/assets/images/crop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/crop.png -------------------------------------------------------------------------------- /rbac/static/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/logo.png -------------------------------------------------------------------------------- /rbac/static/assets/images/mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/mobile.png -------------------------------------------------------------------------------- /rbac/static/assets/images/opera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/opera.png -------------------------------------------------------------------------------- /rbac/static/assets/images/safari.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/safari.png -------------------------------------------------------------------------------- /rbac/static/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/favicon.png -------------------------------------------------------------------------------- /rbac/static/assets/images/firefox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/firefox.png -------------------------------------------------------------------------------- /rbac/static/assets/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/loading.gif -------------------------------------------------------------------------------- /rbac/static/assets/images/attachment1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/attachment1.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/attachment2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/attachment2.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/icon-close.png -------------------------------------------------------------------------------- /rbac/static/assets/images/logo-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/logo-dark.png -------------------------------------------------------------------------------- /rbac/static/assets/images/logo-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/logo-icon.png -------------------------------------------------------------------------------- /rbac/static/assets/images/reset-email.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/reset-email.jpg -------------------------------------------------------------------------------- /rbac/static/assets/pages/compose.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $('.summernote').summernote({ 3 | height: 350 4 | }); 5 | }); -------------------------------------------------------------------------------- /rbac/static/assets/images/email-welcome.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/email-welcome.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/profile-cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/profile-cover.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/profile-picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/profile-picture.png -------------------------------------------------------------------------------- /rbac/static/assets/images/profile-picture2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/profile-picture2.png -------------------------------------------------------------------------------- /rbac/static/assets/images/profile-picture3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/profile-picture3.png -------------------------------------------------------------------------------- /rbac/static/assets/images/profile-widge-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/profile-widge-bg.png -------------------------------------------------------------------------------- /rbac/static/assets/images/users/avatar-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/users/avatar-1.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/users/avatar-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/users/avatar-10.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/users/avatar-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/users/avatar-2.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/users/avatar-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/users/avatar-3.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/users/avatar-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/users/avatar-4.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/users/avatar-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/users/avatar-5.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/users/avatar-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/users/avatar-6.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/users/avatar-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/users/avatar-7.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/users/avatar-8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/users/avatar-8.jpg -------------------------------------------------------------------------------- /rbac/static/assets/images/users/avatar-9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/images/users/avatar-9.jpg -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/ion-icon/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/ion-icon/fonts/ionicons.eot -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/ion-icon/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/ion-icon/fonts/ionicons.ttf -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/ion-icon/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/ion-icon/fonts/ionicons.woff -------------------------------------------------------------------------------- /rbac/static/assets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /rbac/static/assets/fonts/glyphicons-halflings-regular.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/fonts/glyphicons-halflings-regular.html -------------------------------------------------------------------------------- /rbac/static/assets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /rbac/static/assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /rbac/static/assets/plugins/datatables/images/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/datatables/images/sort_asc.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/datatables/images/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/datatables/images/sort_both.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/datatables/images/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/datatables/images/sort_desc.png -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/ion-icon/fonts/bkp/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/ion-icon/fonts/bkp/ionicons.eot -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/ion-icon/fonts/bkp/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/ion-icon/fonts/bkp/ionicons.ttf -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/ion-icon/fonts/bkp/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/ion-icon/fonts/bkp/ionicons.woff -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/themify-icon/fonts/themify.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/themify-icon/fonts/themify.eot -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/themify-icon/fonts/themify.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/themify-icon/fonts/themify.ttf -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/themify-icon/fonts/themify.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/themify-icon/fonts/themify.woff -------------------------------------------------------------------------------- /rbac/static/assets/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /rbac/static/assets/fonts/glyphicons-halflings-regulard41d.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/fonts/glyphicons-halflings-regulard41d.eot -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-editable/img/clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/bootstrap-editable/img/clear.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-editable/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/bootstrap-editable/img/loading.gif -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-multi-select/img/switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-multi-select/img/switch.png -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /rbac/static/assets/plugins/datatables/images/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/datatables/images/sort_asc_disabled.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/datatables/images/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/datatables/images/sort_desc_disabled.png -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-icons_228ef1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-icons_228ef1_256x240.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-icons_ef8c08_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-icons_ef8c08_256x240.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-icons_ffd27a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-icons_ffd27a_256x240.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/simple-line-icon/fonts/Simple-Line-Icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/simple-line-icon/fonts/Simple-Line-Icons.eot -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/simple-line-icon/fonts/Simple-Line-Icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/simple-line-icon/fonts/Simple-Line-Icons.ttf -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/simple-line-icon/fonts/Simple-Line-Icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/simple-line-icon/fonts/Simple-Line-Icons.woff -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/simple-line-icon/fonts/Simple-Line-Icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/simple-line-icon/fonts/Simple-Line-Icons.woff2 -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-bg_flat_10_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-bg_flat_10_000000_40x100.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-bg_glass_100_f6f6f6_1x400.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-bg_glass_100_fdf5ce_1x400.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/hue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/hue.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/jquery-ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/material-design-icon/fonts/materialdesignicons-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/material-design-icon/fonts/materialdesignicons-webfont.eot -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/material-design-icon/fonts/materialdesignicons-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/material-design-icon/fonts/materialdesignicons-webfont.ttf -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/material-design-icon/fonts/materialdesignicons-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/material-design-icon/fonts/materialdesignicons-webfont.woff -------------------------------------------------------------------------------- /rbac/static/assets/css/icons/material-design-icon/fonts/materialdesignicons-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/css/icons/material-design-icon/fonts/materialdesignicons-webfont.woff2 -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/saturation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/saturation.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/hue-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/hue-horizontal.png -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnatkhQ/QPuuzle-RbacBlock/HEAD/rbac/static/assets/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha-horizontal.png -------------------------------------------------------------------------------- /rbac/templates/rbac/static_menu.html: -------------------------------------------------------------------------------- 1 |
2 | {% for item in menu_list %} 3 | 4 | {{ item.title }} 5 | {% endfor %} 6 |
-------------------------------------------------------------------------------- /rbac/static/assets/css/icons.css: -------------------------------------------------------------------------------- 1 | @import url("icons/font-awesome/font-awesome.css"); 2 | @import url("icons/simple-line-icon/simple-line-icons.css"); 3 | @import url("icons/themify-icon/themify-icons.css"); 4 | @import url("icons/material-design-icon/materialdesignicons.css"); 5 | @import url("icons/ion-icon/ionicons.css"); -------------------------------------------------------------------------------- /rbac/forms/role.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | from django import forms 5 | from rbac import models 6 | 7 | 8 | class RoleModelForm(forms.ModelForm): 9 | class Meta: 10 | model = models.Role 11 | fields = ['title', ] 12 | widgets = { 13 | 'title': forms.TextInput(attrs={'placeholder': '请输入角色名称', 'class': 'form-control'}) 14 | } 15 | 16 | -------------------------------------------------------------------------------- /rbac/forms/base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | from django import forms 5 | 6 | 7 | class BootStrapModelForm(forms.ModelForm): 8 | 9 | def __init__(self, *args, **kwargs): 10 | super(BootStrapModelForm, self).__init__(*args, **kwargs) 11 | # 统一给ModelForm生成字段添加样式 12 | for name, field in self.fields.items(): 13 | field.widget.attrs['class'] = 'form-control' 14 | -------------------------------------------------------------------------------- /rbac/static/assets/fonts/glyphicons-halflings-regular.svg.readme: -------------------------------------------------------------------------------- 1 | Info-file generated by HTTrack Website Copier 3.48-21+htsswf+htsjava 2 | 3 | The file D:/nabindu-work/demo/admin------/integral-admin/www.g-axon.com/integral/light/fonts/glyphicons-halflings-regular.svg has not been scanned by HTS 4 | Some links contained in it may be unreachable locally. 5 | If you want to get these files, you have to set an upper recurse level, and to rescan the URL. 6 | -------------------------------------------------------------------------------- /rbac/static/assets/pages/gmap-customs.js: -------------------------------------------------------------------------------- 1 | $( document ).ready(function() { 2 | // Simple map 3 | function initialize() { 4 | var mapOptions = { 5 | center: new google.maps.LatLng(40.741895,-73.989308), 6 | zoom: 9 7 | }; 8 | var map = new google.maps.Map(document.getElementById('map'), mapOptions); 9 | } 10 | google.maps.event.addDomListener(window, 'load', initialize); 11 | 12 | }); -------------------------------------------------------------------------------- /rbac/static/assets/js/custom.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 3 | //tooltip 4 | $(function() { 5 | $('[data-toggle="tooltip"]').tooltip() 6 | }) 7 | 8 | // Initialize Popovers 9 | jQuery('[data-toggle="popover"], .js-popover').popover({ 10 | container: 'body', 11 | animation: true, 12 | trigger: 'hover' 13 | }); 14 | 15 | }); 16 | 17 | 18 | -------------------------------------------------------------------------------- /rbac/templates/rbac/multi_menu.html: -------------------------------------------------------------------------------- 1 | {% for item in menu_dict.values %} 2 | {# 一级菜单 #} 3 | 11 | {% endfor %} -------------------------------------------------------------------------------- /rbac/templates/rbac/breadcrumb.html: -------------------------------------------------------------------------------- 1 |
2 |

{{ record_name }}

3 | 12 |
13 |
-------------------------------------------------------------------------------- /rbac/static/assets/plugins/morris-chart/morris.css: -------------------------------------------------------------------------------- 1 | .morris-hover { 2 | position:absolute; 3 | z-index:1; 4 | } 5 | 6 | .morris-hover.morris-default-style .morris-hover-row-label { 7 | font-weight:bold; 8 | margin:0.25em 0 9 | } 10 | .morris-hover.morris-default-style .morris-hover-point { 11 | white-space:nowrap; 12 | margin:0.1em 0 13 | } 14 | .morris-hover.morris-default-style { 15 | border-radius: 10px; 16 | padding: 10px 12px; 17 | color: #666; 18 | background: rgba(0, 0, 0, 0.78); 19 | border: none; 20 | color: #fff !important; 21 | } 22 | .morris-hover-point { 23 | color: rgba(257, 257, 257, 0.8)!important ; 24 | } 25 | -------------------------------------------------------------------------------- /rbac/templates/rbac/delete.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout_plus.html' %} 2 | 3 | {% block content %} 4 |
5 | 18 |
19 | 20 | {% endblock %} 21 | -------------------------------------------------------------------------------- /rbac/static/assets/pages/inbox.js: -------------------------------------------------------------------------------- 1 | $( document ).ready(function() { 2 | 3 | $('.check-mail-all').click(function () { 4 | $('.checkbox-mail').click(); 5 | }); 6 | 7 | $('.checkbox-mail').each(function() { 8 | $(this).click(function() { 9 | if($(this).closest('tr').hasClass("checked")){ 10 | $(this).closest('tr').removeClass('checked'); 11 | hiddenMailOptions(); 12 | } else { 13 | $(this).closest('tr').addClass('checked'); 14 | hiddenMailOptions(); 15 | } 16 | }); 17 | }); 18 | 19 | $('.mailbox-content table tr td').not(":first-child").on('click', function(e) { 20 | e.stopPropagation(); 21 | e.preventDefault(); 22 | 23 | window.location = "message-view.html"; 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /rbac/static/assets/pages/imagecrop-custom.js: -------------------------------------------------------------------------------- 1 | $( document ).ready(function() { 2 | var $image = $(".image-crop > img"); 3 | 4 | $image.cropper({ 5 | aspectRatio: 7 / 5, 6 | preview: ".img-preview" 7 | }); 8 | 9 | $("#zoomIn").click(function() { 10 | $image.cropper('zoom', 0.1); 11 | }); 12 | 13 | $("#zoomOut").click(function() { 14 | $image.cropper('zoom', -0.1); 15 | }); 16 | 17 | $("#rotateLeft").click(function() { 18 | $image.cropper('rotate', 45); 19 | }); 20 | 21 | $("#rotateRight").click(function() { 22 | $image.cropper('rotate', -45); 23 | }); 24 | 25 | $("#clear").click(function() { 26 | $image.cropper('clear'); 27 | }); 28 | 29 | var $replaceWith = $('#replaceWith'); 30 | $('#replace').click(function () { 31 | $image.cropper('replace', $replaceWith.val()); 32 | }); 33 | 34 | }); -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-touchspin/css/jquery.bootstrap-touchspin.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Bootstrap TouchSpin - v3.0.1 3 | * A mobile and touch friendly input spinner component for Bootstrap 3. 4 | * http://www.virtuosoft.eu/code/bootstrap-touchspin/ 5 | * 6 | * Made by István Ujj-Mészáros 7 | * Under Apache License v2.0 License 8 | */ 9 | 10 | .bootstrap-touchspin .input-group-btn-vertical{position:relative;white-space:nowrap;width:1%;vertical-align:middle;display:table-cell}.bootstrap-touchspin .input-group-btn-vertical>.btn{display:block;float:none;width:100%;max-width:100%;padding:8px 10px;margin-left:-1px;position:relative}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up{border-radius:0;border-top-right-radius:4px}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down{margin-top:-2px;border-radius:0;border-bottom-right-radius:4px}.bootstrap-touchspin .input-group-btn-vertical i{position:absolute;top:3px;left:5px;font-size:9px;font-weight:400} -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Bootstrap TouchSpin - v3.0.1 3 | * A mobile and touch friendly input spinner component for Bootstrap 3. 4 | * http://www.virtuosoft.eu/code/bootstrap-touchspin/ 5 | * 6 | * Made by István Ujj-Mészáros 7 | * Under Apache License v2.0 License 8 | */ 9 | 10 | .bootstrap-touchspin .input-group-btn-vertical{position:relative;white-space:nowrap;width:1%;vertical-align:middle;display:table-cell}.bootstrap-touchspin .input-group-btn-vertical>.btn{display:block;float:none;width:100%;max-width:100%;padding:8px 10px;margin-left:-1px;position:relative}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up{border-radius:0;border-top-right-radius:4px}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down{margin-top:-2px;border-radius:0;border-bottom-right-radius:4px}.bootstrap-touchspin .input-group-btn-vertical i{position:absolute;top:3px;left:5px;font-size:9px;font-weight:400} -------------------------------------------------------------------------------- /rbac/service/urls.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | from django.urls import reverse 4 | from django.http import QueryDict 5 | 6 | 7 | def memory_url(request, name, *args, **kwargs): 8 | """ 9 | 生成带有原搜索条件的URL(替代了模板中的url) 10 | :param request: 11 | :param name: 反向生成URL的name 12 | :return: 13 | """ 14 | basic_url = reverse(name, args=args, kwargs=kwargs) 15 | 16 | 17 | if not request.GET: 18 | return basic_url 19 | 20 | query_dict = QueryDict(mutable=True) 21 | query_dict['_filter'] = request.GET.urlencode() # mid=2&age=99 22 | 23 | return "%s?%s" % (basic_url, query_dict.urlencode()) 24 | 25 | 26 | def memory_reverse(request, name, *args, **kwargs): 27 | """ 28 | 反向生成URL 29 | http://127.0.0.1:8001/rbac/menu/add/?_filter=mid%3D2 30 | 1. 在url中讲原来搜索条件,如filter后的值 31 | 2. reverse生成原来的URL,如:/menu/list/ 32 | 3. /menu/list/?mid%3D2 33 | """ 34 | url = reverse(name, args=args, kwargs=kwargs) 35 | origin_params = request.GET.get('_filter') 36 | if origin_params: 37 | url = "%s?%s" % (url, origin_params,) 38 | 39 | return url 40 | -------------------------------------------------------------------------------- /rbac/templates/rbac/change.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout_plus.html' %} 2 | {% block content %} 3 |
4 | 5 |
6 | {% csrf_token %} 7 |
8 |
9 |
10 |

{{ request.menu_name }}

11 | {% for field in form %} 12 |
13 | 14 |
15 | {{ field }} 16 | {{ field.errors.0 }} 17 |
18 |
19 | {% endfor %} 20 |
21 |
22 | 23 |
24 |
25 | 26 |
27 |
28 |
29 | 30 | 31 |
32 | 33 | 34 |
35 | 36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /rbac/static/assets/pages/maps-vector.js: -------------------------------------------------------------------------------- 1 | //------------- maps-vector.js -------------// 2 | $(document).ready(function() { 3 | 4 | 5 | 6 | //------------- Vector maps -------------// 7 | $('#world-map-markers').vectorMap({ 8 | map: 'world_mill_en', 9 | scaleColors: ['#f7f9fe', '#29b6d8'], 10 | normalizeFunction: 'polynomial', 11 | hoverOpacity: 0.7, 12 | hoverColor: false, 13 | focusOn:{ 14 | x: 0.5, 15 | y: 0.5, 16 | scale: 2.0 17 | }, 18 | zoomMin:0.85, 19 | markerStyle: { 20 | initial: { 21 | fill: '#df6a78', 22 | stroke: '#df6a78' 23 | } 24 | }, 25 | backgroundColor: '#fff', 26 | regionStyle:{ 27 | initial: { 28 | fill: '#dde1e7', 29 | "fill-opacity": 1, 30 | stroke: '#f7f9fe', 31 | "stroke-width": 0, 32 | "stroke-opacity": 0 33 | }, 34 | hover: { 35 | "fill-opacity": 0.8 36 | }, 37 | selected: { 38 | fill: 'yellow' 39 | } 40 | }, 41 | markers: [ 42 | //http://www.latlong.net/ 43 | {latLng: [51.507351, -0.127758], name: 'London'}, 44 | {latLng: [41.385064, 2.173403], name: 'Barcelona'}, 45 | {latLng: [40.712784, -74.005941], name: 'New York'}, 46 | {latLng: [-22.911632, -43.188286], name: 'Rio De Janeiro'}, 47 | {latLng: [49.282729, -123.120738], name: 'Vancuver'}, 48 | {latLng: [35.689487, 139.691706], name: 'Tokio'}, 49 | {latLng: [55.755826, 37.617300], name: 'Moskva'}, 50 | {latLng: [43.214050, 27.914733], name: 'Varna'}, 51 | {latLng: [30.044420, 31.235712], name: 'Cairo'} 52 | ] 53 | }); 54 | 55 | }); -------------------------------------------------------------------------------- /rbac/templates/rbac/user_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout_plus.html' %} 2 | 3 | 4 | {% block content %} 5 |
6 |
7 | 8 | 9 | 添加用户 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | {% for row in users %} 26 | 27 | 28 | 29 | 30 | 33 | 43 | 44 | {% endfor %} 45 | 46 |
序号用户名邮箱重置密码操作
{{ forloop.counter }}{{ row.name }}{{ row.email }} 31 | 重置密码 32 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 |
47 |
48 | 49 | {% endblock %} 50 | -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | ul.wysihtml5-toolbar { 4 | margin: 0; 5 | padding: 0; 6 | display: block; 7 | background:transparent; 8 | border: 1px solid #BDC4C9; 9 | border-top-left-radius: 3px; 10 | border-top-right-radius: 3px; 11 | 12 | } 13 | 14 | ul.wysihtml5-toolbar::after { 15 | clear: both; 16 | display: table; 17 | content: ""; 18 | } 19 | 20 | ul.wysihtml5-toolbar > li { 21 | float: left; 22 | display: list-item; 23 | list-style: none; 24 | padding: 0; 25 | margin: 0px 5px 0px 0px; 26 | } 27 | 28 | ul.wysihtml5-toolbar a{ 29 | margin: 0px; 30 | } 31 | 32 | 33 | ul.wysihtml5-toolbar a.btn{ 34 | padding: 12px 15px; 35 | background: inherit; 36 | font-size: inherit; 37 | border-radius: 0; 38 | color: inherit; 39 | } 40 | ul.wysihtml5-toolbar a:hover.btn{ 41 | color: #333; 42 | } 43 | 44 | ul.wysihtml5-toolbar a[data-wysihtml5-command=bold] { 45 | font-weight: bold; 46 | } 47 | 48 | ul.wysihtml5-toolbar a[data-wysihtml5-command=italic] { 49 | font-style: italic; 50 | } 51 | 52 | ul.wysihtml5-toolbar a[data-wysihtml5-command=underline] { 53 | text-decoration: underline; 54 | } 55 | 56 | ul.wysihtml5-toolbar a.btn.wysihtml5-command-active { 57 | background-image: none; 58 | background: #CECECE; 59 | box-shadow: none; 60 | color: #333; 61 | outline: 0; 62 | } 63 | 64 | ul.wysihtml5-commands-disabled .dropdown-menu { 65 | display: none !important; 66 | } 67 | 68 | ul.wysihtml5-toolbar .fa{ 69 | margin: 0; 70 | font-size: 14px; 71 | } 72 | .wysihtml5-textarea{ 73 | border-top-left-radius: 0; 74 | border-top-right-radius: 0; 75 | border-top: none; 76 | } 77 | .wysihtml5-textarea:focus{ 78 | border-top: none; 79 | background: #fff; 80 | } 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /rbac/static/assets/pages/multi-select-init.js: -------------------------------------------------------------------------------- 1 | //multiselect start 2 | 3 | 4 | $('#my_multi_select1').multiSelect(); 5 | $('#my_multi_select2').multiSelect({ 6 | selectableOptgroup: true 7 | }); 8 | 9 | $('#my_multi_select3').multiSelect({ 10 | selectableHeader: "", 11 | selectionHeader: "", 12 | afterInit: function (ms) { 13 | var that = this, 14 | $selectableSearch = that.$selectableUl.prev(), 15 | $selectionSearch = that.$selectionUl.prev(), 16 | selectableSearchString = '#' + that.$container.attr('id') + ' .ms-elem-selectable:not(.ms-selected)', 17 | selectionSearchString = '#' + that.$container.attr('id') + ' .ms-elem-selection.ms-selected'; 18 | 19 | that.qs1 = $selectableSearch.quicksearch(selectableSearchString) 20 | .on('keydown', function (e) { 21 | if (e.which === 40) { 22 | that.$selectableUl.focus(); 23 | return false; 24 | } 25 | }); 26 | 27 | that.qs2 = $selectionSearch.quicksearch(selectionSearchString) 28 | .on('keydown', function (e) { 29 | if (e.which == 40) { 30 | that.$selectionUl.focus(); 31 | return false; 32 | } 33 | }); 34 | }, 35 | afterSelect: function () { 36 | this.qs1.cache(); 37 | this.qs2.cache(); 38 | }, 39 | afterDeselect: function () { 40 | this.qs1.cache(); 41 | this.qs2.cache(); 42 | } 43 | }); 44 | 45 | 46 | //multiselect end -------------------------------------------------------------------------------- /rbac/templates/rbac/error-404.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% comment %}{% endcomment %} 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
32 |
33 |
34 |

404

35 |

糟糕,该页面未找到

36 |

请访问正确路径

37 | 回到首页 38 |
39 |
40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /rbac/templates/rbac/menu_change.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout_plus.html' %} 2 | {% block css %} 3 | 4 | {% endblock %} 5 | 6 | {% block content %} 7 | 8 | 9 |
10 |
11 |
12 |

{{ request.menu_name }}

13 |
14 | {% csrf_token %} 15 |
16 |
17 |

19 |
20 | {{ form.title }} 21 | {{ title.errors.0 }} 22 |
23 |
24 | 25 | {{ form.title.errors.0 }} 26 | 27 |
28 |
29 |
30 |
31 |
32 |

图标:

33 |

{{ form.icon.errors.0 }}

34 | {% for foo in form.icon %} 35 |
{{ foo }}
36 | {% endfor %} 37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | 45 | {% endblock %} -------------------------------------------------------------------------------- /rbac/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Menu(models.Model): 5 | """ 6 | 菜单表 7 | """ 8 | title = models.CharField(verbose_name='菜单名称', max_length=32) 9 | icon = models.CharField(verbose_name='图标', max_length=32) 10 | 11 | def __str__(self): 12 | return self.title 13 | 14 | 15 | class Permission(models.Model): 16 | """ 17 | 权限表 18 | """ 19 | title = models.CharField(verbose_name='标题', max_length=32) 20 | url = models.CharField(verbose_name='含正则的URL', max_length=128) 21 | 22 | name = models.CharField(verbose_name='URL别名', max_length=32, unique=True) 23 | menu = models.ForeignKey(verbose_name='所属菜单', to='Menu', null=True, blank=True, help_text='null表示不是一级菜单;非null表示是二级菜单', 24 | on_delete=models.CASCADE) 25 | 26 | pid = models.ForeignKey(verbose_name='关联的权限', to='Permission', null=True, blank=True, related_name='parents', 27 | help_text='对于非菜单权限需要选择一个可以成为菜单的权限,用户做默认展开和选中菜单', on_delete=models.CASCADE) 28 | 29 | def __str__(self): 30 | return self.title 31 | 32 | 33 | class Role(models.Model): 34 | """ 35 | 角色 36 | """ 37 | title = models.CharField(verbose_name='角色名称', max_length=32) 38 | permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission', blank=True) 39 | 40 | def __str__(self): 41 | return self.title 42 | 43 | 44 | class UserInfo(models.Model): 45 | """ 46 | 用户表 47 | """ 48 | name = models.CharField(verbose_name='用户名', max_length=32) 49 | password = models.CharField(verbose_name='密码', max_length=64) 50 | email = models.CharField(verbose_name='邮箱', max_length=32) 51 | # to=Role不加引号,因为该类被继承后如果加了引号则找不到Role,'Role'找的是该py文件中的类,不能跨文件 52 | roles = models.ManyToManyField(verbose_name='拥有的所有角色', to=Role, blank=True) 53 | 54 | def __str__(self): 55 | return self.name 56 | 57 | class Meta: 58 | # django以后再做数据库迁移时,不再为UserInfo类创建相关的表以及表结构了。 59 | # 此类可以当做"父类",被其他Model类继承。 60 | # 相当于抽象类,只能作为接口,自身不能产生数据 61 | abstract = True 62 | -------------------------------------------------------------------------------- /rbac/templatetags/rbac.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | import re 4 | from django.template import Library 5 | from django.conf import settings 6 | from collections import OrderedDict 7 | from rbac.service import urls 8 | 9 | register = Library() 10 | 11 | 12 | @register.inclusion_tag('rbac/static_menu.html') 13 | def static_menu(request): 14 | """ 15 | 创建一级菜单 16 | :return: 17 | """ 18 | menu_list = request.session[settings.MENU_SESSION_KEY] 19 | return {'menu_list': menu_list} 20 | 21 | 22 | @register.inclusion_tag('rbac/multi_menu.html') 23 | def multi_menu(request): 24 | """ 25 | 创建二级菜单 26 | :return: 27 | """ 28 | 29 | # menu_dict是一个字典,使用menu_dict渲染menu会让模板变得无序 30 | # 需要使用有序字典,让menu每次都是固定的顺序 31 | menu_dict = request.session[settings.MENU_SESSION_KEY] 32 | 33 | key_list = sorted(menu_dict) 34 | 35 | ordered_dict = OrderedDict() 36 | 37 | for key in key_list: 38 | val = menu_dict[key] 39 | val['class'] = '' # 默认每一个1级菜单不展开,隐藏二级菜单 40 | 41 | for per in val['children']: 42 | 43 | if per['id'] == request.current_selected_permission: # 二级菜单ID = 当前选中菜单对应的ID/PID,用于判断展开哪个一级菜单 44 | per['class'] = 'active' 45 | val['class'] = 'nav-active' # 让1级菜单的class由hide--->空 46 | ordered_dict[key] = val 47 | 48 | return {'menu_dict': ordered_dict} 49 | 50 | 51 | @register.inclusion_tag('rbac/breadcrumb.html') 52 | def breadcrumb(request): 53 | """ 54 | 路径导航 55 | :param request: 56 | :return: 57 | """ 58 | 59 | return {'record_list': request.breadcrumb, 'record_name': request.menu_name} 60 | 61 | 62 | @register.filter 63 | def has_permission(request, name): 64 | """ 65 | 判断是否有权限,register.filter最多可传2个参数 66 | {% request|has_permission:name %} 67 | :param request: 68 | :param name: 69 | :return: 70 | """ 71 | if name in request.session[settings.PERMISSION_SESSION_KEY]: 72 | return True 73 | 74 | 75 | @register.simple_tag 76 | def memory_url(request, name, *args, **kwargs): 77 | """ 78 | 生成带有原搜索条件的URL(替代了模板中的url) 79 | :param request: 80 | :param name: 81 | :return: 82 | """ 83 | return urls.memory_url(request, name, *args, **kwargs) 84 | -------------------------------------------------------------------------------- /rbac/forms/user.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | from django import forms 5 | from django.core.exceptions import ValidationError 6 | from rbac import models 7 | 8 | 9 | class UserModelForm(forms.ModelForm): 10 | confirm_password = forms.CharField(label='确认密码') 11 | 12 | class Meta: 13 | model = models.UserInfo 14 | fields = ['name', 'email', 'password', 'confirm_password'] 15 | 16 | def __init__(self, *args, **kwargs): 17 | super(UserModelForm, self).__init__(*args, **kwargs) 18 | for name, field in self.fields.items(): 19 | field.widget.attrs['class'] = 'form-control' 20 | 21 | def clean_confirm_password(self): 22 | """ 23 | 检测密码是否一致 24 | :return: 25 | """ 26 | password = self.cleaned_data['password'] 27 | confirm_password = self.cleaned_data['confirm_password'] 28 | if password != confirm_password: 29 | raise ValidationError('两次密码输入不一致') 30 | return confirm_password 31 | 32 | 33 | class UpdateUserModelForm(forms.ModelForm): 34 | class Meta: 35 | model = models.UserInfo 36 | fields = ['name', 'email', ] 37 | 38 | def __init__(self, *args, **kwargs): 39 | super(UpdateUserModelForm, self).__init__(*args, **kwargs) 40 | for name, field in self.fields.items(): 41 | field.widget.attrs['class'] = 'form-control' 42 | 43 | 44 | class ResetPasswordUserModelForm(forms.ModelForm): 45 | confirm_password = forms.CharField(label='确认密码') 46 | 47 | class Meta: 48 | model = models.UserInfo 49 | fields = ['password', 'confirm_password'] 50 | 51 | def __init__(self, *args, **kwargs): 52 | super(ResetPasswordUserModelForm, self).__init__(*args, **kwargs) 53 | for name, field in self.fields.items(): 54 | field.widget.attrs['class'] = 'form-control' 55 | 56 | def clean_confirm_password(self): 57 | """ 58 | 检测密码是否一致 59 | :return: 60 | """ 61 | password = self.cleaned_data['password'] 62 | confirm_password = self.cleaned_data['confirm_password'] 63 | if password != confirm_password: 64 | raise ValidationError('两次密码输入不一致') 65 | return confirm_password 66 | -------------------------------------------------------------------------------- /rbac/urls.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | from django.conf.urls import url, include 4 | from django.contrib import admin 5 | from rbac.views import role 6 | from rbac.views import user 7 | from rbac.views import menu 8 | 9 | urlpatterns = [ 10 | 11 | url(r'^role/list/$', role.role_list, name='role_list'), # rbac:role_list 12 | url(r'^role/add/$', role.role_add, name='role_add'), # rbac:role_add 13 | url(r'^role/edit/(?P\d+)/$', role.role_edit, name='role_edit'), # rbac:role_edit 14 | # 跳转式删除 15 | # url(r'^role/del/(?P\d+)/$', role.role_del, name='role_del'), # rbac:role_del 16 | # 弹出框删除 17 | url(r'^role/del/$', role.role_del, name='role_del'), # rbac:role_del 18 | 19 | # url(r'^user/list/$', user.user_list, name='user_list'), 20 | # url(r'^user/add/$', user.user_add, name='user_add'), 21 | # url(r'^user/edit/(?P\d+)/$', user.user_edit, name='user_edit'), # rbac:user_edit 22 | # url(r'^user/del/(?P\d+)/$', user.user_del, name='user_del'), 23 | # url(r'^user/reset/password/(?P\d+)/$', user.user_reset_pwd, name='user_reset_pwd'), 24 | 25 | url(r'^menu/list/$', menu.menu_list, name='menu_list'), 26 | url(r'^menu/add/$', menu.menu_add, name='menu_add'), 27 | url(r'^menu/edit/(?P\d+)/$', menu.menu_edit, name='menu_edit'), 28 | url(r'^menu/del/(?P\d+)/$', menu.menu_del, name='menu_del'), 29 | 30 | url(r'^second/menu/add/(?P\d+)$', menu.second_menu_add, name='second_menu_add'), 31 | url(r'^second/menu/edit/(?P\d+)/$', menu.second_menu_edit, name='second_menu_edit'), 32 | url(r'^second/menu/del/(?P\d+)/$', menu.second_menu_del, name='second_menu_del'), 33 | 34 | url(r'^permission/add/(?P\d+)/$', menu.permission_add, name='permission_add'), 35 | url(r'^permission/edit/(?P\d+)/$', menu.permission_edit, name='permission_edit'), 36 | url(r'^permission/del/(?P\d+)/$', menu.permission_del, name='permission_del'), 37 | 38 | url(r'^multi/permissions/$', menu.multi_permissions, name='multi_permissions'), 39 | url(r'^multi/permissions/del/(?P\d+)/$', menu.multi_permissions_del, name='multi_permissions_del'), 40 | 41 | url(r'^distribute/permissions/$', menu.distribute_permissions, name='distribute_permissions'), 42 | 43 | ] 44 | -------------------------------------------------------------------------------- /rbac/static/assets/pages/calendar-custom.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 3 | $('#external-events .fc-event').each(function() { 4 | 5 | // store data so the calendar knows to render an event upon drop 6 | $(this).data('event', { 7 | title: $.trim($(this).text()), // use the element's text as the event title 8 | stick: true // maintain when user navigates (see docs on the renderEvent method) 9 | }); 10 | 11 | // make the event draggable using jQuery UI 12 | $(this).draggable({ 13 | zIndex: 999, 14 | revert: true, // will cause the event to go back to its 15 | revertDuration: 0 // original position after the drag 16 | }); 17 | 18 | }); 19 | 20 | 21 | /* initialize the calendar 22 | -----------------------------------------------------------------*/ 23 | $('#calendar').fullCalendar({ 24 | header: { 25 | left: 'prev,next today', 26 | center: 'title', 27 | right: 'month,basicWeek,basicDay' 28 | }, 29 | defaultDate: '2017-01-15', 30 | editable: true, 31 | droppable: true, 32 | eventLimit: true, 33 | events: [ 34 | { 35 | title: 'Event Meeting 1', 36 | start: '2017-01-15', 37 | color: '#FFBD4A' 38 | }, 39 | { 40 | title: 'Birthday Party', 41 | start: '2017-01-05', 42 | color: '#FC8AB1' 43 | }, 44 | { 45 | title: 'Birthday Party', 46 | start: '2017-01-09', 47 | color: '#668CFF' 48 | }, 49 | { 50 | title: 'Birthday Party', 51 | start: '2017-01-11', 52 | color: '#F05050' 53 | }, 54 | { 55 | title: 'Birthday Party', 56 | start: '2017-01-13', 57 | color: '#81C868' 58 | }, 59 | { 60 | title: 'Birthday Party', 61 | start: '2017-01-14', 62 | color: '#F05050' 63 | } 64 | 65 | 66 | ] 67 | }); 68 | 69 | }); 70 | -------------------------------------------------------------------------------- /rbac/views/role.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | 角色管理 5 | """ 6 | from django.shortcuts import render, redirect, HttpResponse 7 | from django.urls import reverse 8 | from django.http import JsonResponse 9 | from rbac import models 10 | from rbac.forms.role import RoleModelForm 11 | from django.views.decorators.csrf import csrf_exempt 12 | 13 | 14 | def role_list(request): 15 | """ 16 | 角色列表 17 | :param request: 18 | :return: 19 | """ 20 | role_queryset = models.Role.objects.all() 21 | 22 | return render(request, 'rbac/role_list.html', {'roles': role_queryset}) 23 | 24 | 25 | def role_add(request): 26 | """ 27 | 添加角色 28 | :param request: 29 | :return: 30 | """ 31 | if request.method == 'GET': 32 | form = RoleModelForm() 33 | return render(request, 'rbac/change.html', {'form': form}) 34 | 35 | form = RoleModelForm(data=request.POST) 36 | if form.is_valid(): 37 | form.save() 38 | return redirect(reverse('rbac:role_list')) 39 | 40 | return render(request, 'rbac/change.html', {'form': form}) 41 | 42 | 43 | def role_edit(request, pk): 44 | """ 45 | 编辑角色 46 | :param request: 47 | :param pk: 要修改的角色ID 48 | :return: 49 | """ 50 | obj = models.Role.objects.filter(id=pk).first() 51 | if not obj: 52 | return HttpResponse('角色不存在') 53 | if request.method == 'GET': 54 | form = RoleModelForm(instance=obj) 55 | return render(request, 'rbac/change.html', {'form': form}) 56 | 57 | form = RoleModelForm(instance=obj, data=request.POST) 58 | if form.is_valid(): 59 | form.save() 60 | return redirect(reverse('rbac:role_list')) 61 | 62 | return render(request, 'rbac/change.html', {'form': form}) 63 | 64 | 65 | # 跳转删除需要修改url接收pk 66 | # def role_del(request, pk): 67 | # """ 68 | # 删除角色 69 | # :param request: 70 | # :param pk: 71 | # :return: 72 | # """ 73 | # origin_url = reverse('rbac:role_list') 74 | # if request.method == 'GET': 75 | # return render(request, 'rbac/delete.html', {'cancel': origin_url}) 76 | # 77 | # models.Role.objects.filter(id=pk).delete() 78 | # return redirect(origin_url) 79 | 80 | # 弹出框删除使用该函数,并且修改此函数的url为不接收pk 81 | @csrf_exempt 82 | def role_del(request): 83 | """ 84 | 删除角色v2.0 85 | :return: 86 | """ 87 | status = {"msg": None} 88 | pk = request.POST.get("pk") 89 | print(pk) 90 | if pk: 91 | models.Role.objects.filter(id=pk).delete() 92 | status["msg"] = True 93 | else: 94 | return render(request, "rbac/error-404.html") 95 | 96 | return JsonResponse(status) 97 | -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-multi-select/css/multi-select.css: -------------------------------------------------------------------------------- 1 | .ms-container{ 2 | background: transparent url('../img/switch.png') no-repeat 50% 50%; 3 | width: 370px; 4 | } 5 | 6 | .ms-container:after{ 7 | content: "."; 8 | display: block; 9 | height: 0; 10 | line-height: 0; 11 | font-size: 0; 12 | clear: both; 13 | min-height: 0; 14 | visibility: hidden; 15 | } 16 | 17 | .ms-container .ms-selectable, .ms-container .ms-selection{ 18 | background: #fff; 19 | color: #555555; 20 | float: left; 21 | width: 45%; 22 | } 23 | .ms-container .ms-selection{ 24 | float: right; 25 | } 26 | 27 | .ms-container .ms-list{ 28 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); 29 | -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); 30 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); 31 | -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; 32 | -moz-transition: border linear 0.2s, box-shadow linear 0.2s; 33 | -ms-transition: border linear 0.2s, box-shadow linear 0.2s; 34 | -o-transition: border linear 0.2s, box-shadow linear 0.2s; 35 | transition: border linear 0.2s, box-shadow linear 0.2s; 36 | border: 1px solid #ccc; 37 | -webkit-border-radius: 3px; 38 | -moz-border-radius: 3px; 39 | border-radius: 3px; 40 | position: relative; 41 | height: 200px; 42 | padding: 0; 43 | overflow-y: auto; 44 | } 45 | 46 | .ms-container .ms-list.ms-focus{ 47 | border-color: rgba(82, 168, 236, 0.8); 48 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); 49 | -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); 50 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); 51 | outline: 0; 52 | outline: thin dotted \9; 53 | } 54 | 55 | .ms-container ul{ 56 | margin: 0; 57 | list-style-type: none; 58 | padding: 0; 59 | } 60 | 61 | .ms-container .ms-optgroup-container{ 62 | width: 100%; 63 | } 64 | 65 | .ms-container .ms-optgroup-label{ 66 | margin: 0; 67 | padding: 5px 0px 0px 5px; 68 | cursor: pointer; 69 | color: #999; 70 | } 71 | 72 | .ms-container .ms-selectable li.ms-elem-selectable, 73 | .ms-container .ms-selection li.ms-elem-selection{ 74 | border-bottom: 1px #eee solid; 75 | padding: 2px 10px; 76 | color: #555; 77 | font-size: 14px; 78 | } 79 | 80 | .ms-container .ms-selectable li.ms-hover, 81 | .ms-container .ms-selection li.ms-hover{ 82 | cursor: pointer; 83 | color: #fff; 84 | text-decoration: none; 85 | background-color: #08c; 86 | } 87 | 88 | .ms-container .ms-selectable li.disabled, 89 | .ms-container .ms-selection li.disabled{ 90 | background-color: #eee; 91 | color: #aaa; 92 | cursor: text; 93 | } -------------------------------------------------------------------------------- /rbac/views/user.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | """ 4 | 用户管理 5 | """ 6 | from django.shortcuts import render, redirect, HttpResponse 7 | from django.urls import reverse 8 | from rbac import models 9 | from rbac.forms.user import UserModelForm, UpdateUserModelForm, ResetPasswordUserModelForm 10 | 11 | 12 | def user_list(request): 13 | """ 14 | 角色列表 15 | :param request: 16 | :return: 17 | """ 18 | user_queryset = models.UserInfo.objects.all() 19 | 20 | return render(request, 'rbac/user_list.html', {'users': user_queryset}) 21 | 22 | 23 | def user_add(request): 24 | """ 25 | 添加角色 26 | :param request: 27 | :return: 28 | """ 29 | if request.method == 'GET': 30 | form = UserModelForm() 31 | return render(request, 'rbac/change.html', {'form': form}) 32 | 33 | form = UserModelForm(data=request.POST) 34 | if form.is_valid(): 35 | form.save() 36 | return redirect(reverse('rbac:user_list')) 37 | 38 | return render(request, 'rbac/change.html', {'form': form}) 39 | 40 | 41 | def user_edit(request, pk): 42 | """ 43 | 编辑用户 44 | :param request: 45 | :param pk: 要修改的用户ID 46 | :return: 47 | """ 48 | obj = models.UserInfo.objects.filter(id=pk).first() 49 | if not obj: 50 | return HttpResponse('用户不存在') 51 | if request.method == 'GET': 52 | form = UpdateUserModelForm(instance=obj) 53 | return render(request, 'rbac/change.html', {'form': form}) 54 | 55 | form = UpdateUserModelForm(instance=obj, data=request.POST) 56 | if form.is_valid(): 57 | form.save() 58 | return redirect(reverse('rbac:user_list')) 59 | 60 | return render(request, 'rbac/change.html', {'form': form}) 61 | 62 | 63 | def user_reset_pwd(request, pk): 64 | """ 65 | 重置密码 66 | :param request: 67 | :param pk: 68 | :return: 69 | """ 70 | obj = models.UserInfo.objects.filter(id=pk).first() 71 | if not obj: 72 | return HttpResponse('用户不存在') 73 | if request.method == 'GET': 74 | form = ResetPasswordUserModelForm() 75 | return render(request, 'rbac/change.html', {'form': form}) 76 | 77 | form = ResetPasswordUserModelForm(instance=obj, data=request.POST) 78 | if form.is_valid(): 79 | form.save() 80 | return redirect(reverse('rbac:user_list')) 81 | 82 | return render(request, 'rbac/change.html', {'form': form}) 83 | 84 | 85 | def user_del(request, pk): 86 | """ 87 | 删除用户 88 | :param request: 89 | :param pk: 90 | :return: 91 | """ 92 | origin_url = reverse('rbac:user_list') 93 | if request.method == 'GET': 94 | return render(request, 'rbac/delete.html', {'cancel': origin_url}) 95 | 96 | models.UserInfo.objects.filter(id=pk).delete() 97 | return redirect(origin_url) 98 | -------------------------------------------------------------------------------- /rbac/middlewares/rbac.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | import re 4 | from django.utils.deprecation import MiddlewareMixin 5 | from django.shortcuts import HttpResponse, reverse, redirect 6 | from django.conf import settings 7 | 8 | 9 | class RbacMiddleware(MiddlewareMixin): 10 | """ 11 | 用户权限信息校验 12 | """ 13 | 14 | def process_request(self, request): 15 | """ 16 | 当用户请求刚进入时候执行 17 | :param request: 18 | :return: 19 | """ 20 | 21 | """ 22 | 1. 获取当前用户请求的URL 23 | 2. 获取当前用户在session中保存的权限列表 ['/customer/list/','/customer/list/(?P\\d+)/'] 24 | 3. 权限信息匹配(匹配路径这种有正则符号的字符串不能使用==,需要使用re.match(样本,比较的素材)进行正则匹配) 25 | """ 26 | 27 | # 1.白名单中的URL无需权限验证即可访问 28 | current_url = request.path_info 29 | for valid_url in settings.VALID_URL_LIST: 30 | if re.match(valid_url, current_url): 31 | return None 32 | 33 | # 2.获取当前用户权限列表 34 | permission_dict = request.session.get(settings.PERMISSION_SESSION_KEY) 35 | if not permission_dict: 36 | return HttpResponse('未获取到用户权限信息,请登录!') 37 | # return redirect(reverse('login')) # 可自行根据name进行反向生成 38 | 39 | # 3.定义路径导航格式 40 | url_record = [ 41 | {'title': '首页', 'url': '#'} 42 | ] 43 | 44 | # 4.需要登录,但无需权限校验的URL 45 | for url in settings.NO_PERMISSION_LIST: 46 | if re.match(url, current_url): 47 | request.current_selected_permission = 0 # 给request注册一个全局属性:当前选中的URL,0为没有选中任何菜单URL 48 | request.breadcrumb = url_record # 注册全局属性breadcrumb用来更方便获取路径导航数据url_record 49 | request.menu_name = '首页' # 当前路径导航名称 50 | return None 51 | 52 | flag = False 53 | 54 | for item in permission_dict.values(): 55 | reg = "^%s$" % item['url'] # 匹配URL的完整路径,防止出现多个匹配 56 | if re.match(reg, current_url): 57 | flag = True 58 | request.current_selected_permission = item['pid'] or item['id'] # 当前菜单选中的URL的id,如果有pid则为pid,没有pid则为id 59 | if not item['pid']: # 没有pid,则为二级菜单 60 | # extend列表,拼接该权限的路径导航,class:active选中该路径 61 | url_record.extend([{'title': item['title'], 'url': item['url'], 'class': 'active'}]) 62 | else: # 有pid则为pid二级菜单所属的普通权限 63 | url_record.extend([ 64 | {'title': item['p_title'], 'url': item['p_url']}, # 该权限对应的二级菜单 65 | {'title': item['title'], 'url': item['url'], 'class': 'active'}, 66 | ]) 67 | request.breadcrumb = url_record 68 | break 69 | 70 | # 获取路径导航对应的目录名 71 | for url in url_record: 72 | if "class" in url: 73 | request.menu_name = url.get("title") 74 | 75 | 76 | if not flag: # 没有匹配的权限,则无权访问 77 | return HttpResponse('无权访问') # 可进行自定制,例如返回404页面 78 | -------------------------------------------------------------------------------- /rbac/templates/rbac/role_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout_plus.html' %} 2 | {% load static %} 3 | {% block content %} 4 | 5 |
6 |
7 |
8 |

{{ request.menu_name }}

9 | 10 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | {% for row in roles %} 26 | 27 | 28 | 29 | 30 | 38 | 45 | 46 | {% endfor %} 47 | 48 |
ID名称权限数量编辑删除
{{ row.id }}{{ row.title }}{{ row.permissions.count }} 31 | 32 | 35 | 36 | 37 | 39 |
40 | 43 |
44 |
49 |
50 |
51 |
52 |
53 | 54 | 55 | {% endblock %} 56 | 57 | {% block js %} 58 | 59 | 60 | {% endblock %} -------------------------------------------------------------------------------- /rbac/static/assets/plugins/clockpicker/css/bootstrap-clockpicker.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * ClockPicker v0.0.7 for Bootstrap (http://weareoutman.github.io/clockpicker/) 3 | * Copyright 2014 Wang Shenwei. 4 | * Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/master/LICENSE) 5 | */.clockpicker .input-group-addon{cursor:pointer}.clockpicker-moving{cursor:move}.clockpicker-align-left.popover>.arrow{left:25px}.clockpicker-align-top.popover>.arrow{top:17px}.clockpicker-align-right.popover>.arrow{left:auto;right:25px}.clockpicker-align-bottom.popover>.arrow{top:auto;bottom:6px}.clockpicker-popover .popover-title{background-color:#fff;color:#999;font-size:24px;font-weight:700;line-height:30px;text-align:center}.clockpicker-popover .popover-title span{cursor:pointer}.clockpicker-popover .popover-content{background-color:#f8f8f8;padding:12px}.popover-content:last-child{border-bottom-left-radius:5px;border-bottom-right-radius:5px}.clockpicker-plate{background-color:#fff;border:1px solid #ccc;border-radius:50%;width:200px;height:200px;overflow:visible;position:relative;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.clockpicker-canvas,.clockpicker-dial{width:200px;height:200px;position:absolute;left:-1px;top:-1px}.clockpicker-minutes{visibility:hidden}.clockpicker-tick{border-radius:50%;color:#666;line-height:26px;text-align:center;width:26px;height:26px;position:absolute;cursor:pointer}.clockpicker-tick.active,.clockpicker-tick:hover{background-color:#c0e5f7;background-color:rgba(0,149,221,.25)}.clockpicker-button{background-image:none;background-color:#fff;border-width:1px 0 0;border-top-left-radius:0;border-top-right-radius:0;margin:0;padding:10px 0}.clockpicker-button:hover{background-image:none;background-color:#ebebeb}.clockpicker-button:focus{outline:0!important}.clockpicker-dial{-webkit-transition:-webkit-transform 350ms,opacity 350ms;-moz-transition:-moz-transform 350ms,opacity 350ms;-ms-transition:-ms-transform 350ms,opacity 350ms;-o-transition:-o-transform 350ms,opacity 350ms;transition:transform 350ms,opacity 350ms}.clockpicker-dial-out{opacity:0}.clockpicker-hours.clockpicker-dial-out{-webkit-transform:scale(1.2,1.2);-moz-transform:scale(1.2,1.2);-ms-transform:scale(1.2,1.2);-o-transform:scale(1.2,1.2);transform:scale(1.2,1.2)}.clockpicker-minutes.clockpicker-dial-out{-webkit-transform:scale(.8,.8);-moz-transform:scale(.8,.8);-ms-transform:scale(.8,.8);-o-transform:scale(.8,.8);transform:scale(.8,.8)}.clockpicker-canvas{-webkit-transition:opacity 175ms;-moz-transition:opacity 175ms;-ms-transition:opacity 175ms;-o-transition:opacity 175ms;transition:opacity 175ms}.clockpicker-canvas-out{opacity:.25}.clockpicker-canvas-bearing,.clockpicker-canvas-fg{stroke:none;fill:#0095dd}.clockpicker-canvas-bg{stroke:none;fill:#c0e5f7}.clockpicker-canvas-bg-trans{fill:rgba(0,149,221,.25)}.clockpicker-canvas line{stroke:#0095dd;stroke-width:1;stroke-linecap:round}.clockpicker-button.am-button{margin:1px;padding:5px;border:1px solid rgba(0,0,0,.2);border-radius:4px}.clockpicker-button.pm-button{margin:1px 1px 1px 136px;padding:5px;border:1px solid rgba(0,0,0,.2);border-radius:4px} -------------------------------------------------------------------------------- /rbac/service/init_permission.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | from django.conf import settings 4 | 5 | 6 | def init_permission(current_user, request): 7 | """ 8 | 用户权限的初始化 9 | :param current_user: 当前用户对象 10 | :param request: 请求相关所有数据 11 | :return: 12 | """ 13 | # 2. 权限信息初始化 14 | # 根据当前用户信息获取此用户所拥有的所有权限,并放入session。 15 | # 根据角色获取所有权限 16 | # permissions__id__isnull=False为了防止新增加了职位,但是没有数据为null,需要对该数据进行排除 17 | # distinct()防止同一个用户有多个职位,多个职位有相同的权限,而出现重复数据,需要进行去重处理 18 | permission_queryset = current_user.roles.filter(permissions__isnull=False).values("permissions__id", 19 | "permissions__title", 20 | "permissions__url", 21 | "permissions__name", 22 | "permissions__pid_id", 23 | "permissions__pid__title", 24 | "permissions__pid__url", 25 | "permissions__menu_id", 26 | "permissions__menu__title", 27 | "permissions__menu__icon" 28 | ).distinct() 29 | 30 | # 3. 获取权限+菜单信息 31 | permission_dict = {} 32 | 33 | menu_dict = {} 34 | 35 | for item in permission_queryset: 36 | ###### 处理权限 ###### 37 | permission_dict[item['permissions__name']] = { 38 | 'id': item['permissions__id'], 39 | 'title': item['permissions__title'], 40 | 'url': item['permissions__url'], 41 | 'pid': item['permissions__pid_id'], 42 | 'p_title': item['permissions__pid__title'], 43 | 'p_url': item['permissions__pid__url'], 44 | } 45 | 46 | ###### 处理菜单 ###### 47 | menu_id = item['permissions__menu_id'] # 拿到menu_id用于确认1级菜单 48 | if not menu_id: 49 | continue 50 | 51 | # menu_id有值,则该权限为menu_id的1级菜单所属的2级菜单 52 | node = {'id': item['permissions__id'], 53 | 'title': item['permissions__title'], 54 | 'url': item['permissions__url']} 55 | 56 | if menu_id in menu_dict: 57 | menu_dict[menu_id]['children'].append(node) 58 | else: 59 | menu_dict[menu_id] = { 60 | 'title': item['permissions__menu__title'], 61 | 'icon': item['permissions__menu__icon'], 62 | 'children': [node, ] 63 | } 64 | 65 | # 将权限信息和菜单信息 放入session 66 | request.session[settings.PERMISSION_SESSION_KEY] = permission_dict 67 | request.session[settings.MENU_SESSION_KEY] = menu_dict 68 | -------------------------------------------------------------------------------- /rbac/static/assets/pages/dashboard2.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | 3 | 4 | /*Sales Statics chart*/ 5 | 6 | $(function () { 7 | 8 | var sharpLineData = { 9 | labels: ["January", "February", "March", "April", "May", "June", "July"], 10 | datasets: [ 11 | { 12 | label: "Example dataset", 13 | fillColor: "rgba(3,169,243,0.7)", 14 | strokeColor: "rgba(23,112,233,0.7)", 15 | pointColor: "rgba(23,112,233,1)", 16 | pointStrokeColor: "#fff", 17 | pointHighlightFill: "#fff", 18 | pointHighlightStroke: "rgba(23,112,233,1)", 19 | data: [30, 55, 45, 20, 55, 30, 60] 20 | } 21 | ] 22 | }; 23 | 24 | var sharpLineOptions = { 25 | scaleShowGridLines: true, 26 | scaleGridLineColor: "rgba(0,0,0,.00)", 27 | scaleGridLineWidth: 1, 28 | bezierCurve: false, 29 | pointDot: true, 30 | pointDotRadius: 4, 31 | pointDotStrokeWidth: 1, 32 | pointHitDetectionRadius: 20, 33 | datasetStroke: false, 34 | datasetStrokeWidth: 1, 35 | datasetFill: true, 36 | responsive: true, 37 | resize: true 38 | }; 39 | 40 | var ctx = document.getElementById("sharpLinechart").getContext("2d"); 41 | var myNewChart = new Chart(ctx).Line(sharpLineData, sharpLineOptions); 42 | 43 | 44 | }); 45 | 46 | 47 | 48 | /* Sparkline chart */ 49 | 50 | var sparklineLogin = function() { 51 | 52 | 53 | $('#sparklinestats1').sparkline([ 7, 9, 11, 10, 11, 12, 9, 12], { 54 | type: 'bar', 55 | height: '30', 56 | barWidth: '4', 57 | resize: true, 58 | barSpacing: '5', 59 | barColor: '#E5051F' 60 | }); 61 | 62 | 63 | $('#sparklinestats2').sparkline([ 7, 9, 11, 10, 11, 12, 9, 12], { 64 | type: 'bar', 65 | height: '30', 66 | barWidth: '4', 67 | resize: true, 68 | barSpacing: '5', 69 | barColor: '#BA0C83' 70 | }); 71 | 72 | 73 | 74 | 75 | $('#sparklinestats3').sparkline([ 7, 9, 11, 10, 11, 12, 9, 12], { 76 | type: 'bar', 77 | height: '30', 78 | barWidth: '4', 79 | resize: true, 80 | barSpacing: '5', 81 | barColor: '#E05316' 82 | }); 83 | $('#sparklinestats4').sparkline([ 7, 9, 11, 10, 11, 12, 9, 12], { 84 | type: 'bar', 85 | height: '30', 86 | barWidth: '4', 87 | resize: true, 88 | barSpacing: '5', 89 | barColor: '#7134E3' 90 | }); 91 | 92 | 93 | 94 | } 95 | var sparkResize; 96 | 97 | $(window).resize(function(e) { 98 | clearTimeout(sparkResize); 99 | sparkResize = setTimeout(sparklineLogin, 500); 100 | }); 101 | sparklineLogin(); 102 | 103 | }); 104 | 105 | 106 | 107 | /*To do list*/ 108 | 109 | $(".list-task li label").click(function() { 110 | $(this).toggleClass("task-done"); 111 | }); 112 | 113 | 114 | -------------------------------------------------------------------------------- /rbac/static/assets/plugins/flot-chart/jquery.flot.resize.js: -------------------------------------------------------------------------------- 1 | /* Flot plugin for automatically redrawing plots as the placeholder resizes. 2 | 3 | Copyright (c) 2007-2014 IOLA and Ole Laursen. 4 | Licensed under the MIT license. 5 | 6 | It works by listening for changes on the placeholder div (through the jQuery 7 | resize event plugin) - if the size changes, it will redraw the plot. 8 | 9 | There are no options. If you need to disable the plugin for some plots, you 10 | can just fix the size of their placeholders. 11 | 12 | */ 13 | 14 | /* Inline dependency: 15 | * jQuery resize event - v1.1 - 3/14/2010 16 | * http://benalman.com/projects/jquery-resize-plugin/ 17 | * 18 | * Copyright (c) 2010 "Cowboy" Ben Alman 19 | * Dual licensed under the MIT and GPL licenses. 20 | * http://benalman.com/about/license/ 21 | */ 22 | (function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this); 23 | 24 | (function ($) { 25 | var options = { }; // no options 26 | 27 | function init(plot) { 28 | function onResize() { 29 | var placeholder = plot.getPlaceholder(); 30 | 31 | // somebody might have hidden us and we can't plot 32 | // when we don't have the dimensions 33 | if (placeholder.width() == 0 || placeholder.height() == 0) 34 | return; 35 | 36 | plot.resize(); 37 | plot.setupGrid(); 38 | plot.draw(); 39 | } 40 | 41 | function bindEvents(plot, eventHolder) { 42 | plot.getPlaceholder().resize(onResize); 43 | } 44 | 45 | function shutdown(plot, eventHolder) { 46 | plot.getPlaceholder().unbind("resize", onResize); 47 | } 48 | 49 | plot.hooks.bindEvents.push(bindEvents); 50 | plot.hooks.shutdown.push(shutdown); 51 | } 52 | 53 | $.plot.plugins.push({ 54 | init: init, 55 | options: options, 56 | name: 'resize', 57 | version: '1.0' 58 | }); 59 | })(jQuery); 60 | -------------------------------------------------------------------------------- /rbac/static/assets/pages/jquery.charts-sparkline-custom.js: -------------------------------------------------------------------------------- 1 | 2 | $(document).ready(function() { 3 | var sparklineChart = function() { 4 | 5 | 6 | 7 | $('#sparkline1').sparkline([22, 24, 45, 36,46, 55, 65, 55, 40], { 8 | type: 'line', 9 | width: '100%', 10 | height: '170', 11 | chartRangeMax: 50, 12 | resize: true, 13 | lineColor: '#13dafe', 14 | fillColor: 'rgba(3, 169, 243, 0.6)', 15 | highlightLineColor: 'rgba(0,0,0,.1)', 16 | highlightSpotColor: 'rgba(0,0,0,.2)', 17 | }); 18 | 19 | $('#sparkline1').sparkline([20, 25, 26, 24, 25, 33, 30, 22, 19], { 20 | type: 'line',height: '165', 21 | chartRangeMax: 40, 22 | lineColor: '#03A9F3', 23 | fillColor: 'rgba(150, 117, 206, 0.3)', 24 | composite: true, 25 | highlightLineColor: 'rgba(0,0,0,.1)', 26 | highlightSpotColor: 'rgba(0,0,0,.2)', 27 | }); 28 | 29 | $('#sparkline2').sparkline([6, 6, 7, 8, 6, 4, 7,12, 7, 12, 8, 9, 12, 13, 11, 12], { 30 | type: 'bar', 31 | height: '170', 32 | barWidth: '10', 33 | barSpacing: '3', 34 | barColor: '#5CB85C' 35 | }); 36 | 37 | $('#sparkline3').sparkline([25, 20, 25, 30], { 38 | type: 'pie', 39 | width: '170', 40 | height: '170', 41 | sliceColors: ['#03A9F3', '#FFAA00', '#EF5350', '#9675CE'] 42 | }); 43 | 44 | $('#sparkline4').sparkline([0, 24, 40, 32, 40, 45, 55, 36, 40], { 45 | type: 'line',height: '165', 46 | width: '100%', 47 | chartRangeMax: 50, 48 | lineColor: '#fb6d9d', 49 | fillColor: 'transparent', 50 | highlightLineColor: 'rgba(0,0,0,.1)', 51 | highlightSpotColor: 'rgba(0,0,0,.2)' 52 | }); 53 | 54 | $('#sparkline4').sparkline([20, 25, 27, 22, 25, 30, 35, 20,24], { 55 | type: 'line',height: '165', 56 | chartRangeMax: 40, 57 | lineColor: '#5d9cec', 58 | fillColor: 'transparent', 59 | composite: true, 60 | highlightLineColor: 'rgba(0,0,0,1)', 61 | highlightSpotColor: 'rgba(0,0,0,1)' 62 | }); 63 | 64 | 65 | $("#sparkline5").sparkline([4, 6, 7, 7, 4, 3, 2, 1, 4, 4, 5, 6, 3, 4, 5, 8, 7, 6, 9, 3, 2, 4, 1, 5, 6, 4, 3, 7, ], { 66 | type: 'discrete', 67 | lineColor: '#6059ee',height: '170', 68 | width: $('#sparkline4').width(), 69 | }); 70 | 71 | $('#sparkline6').sparkline([4, 7, 8, 5, 8, 9, 4, 10, 12, 7, 4, 6, 11, 12, 7, 12], { 72 | type: 'bar', 73 | height: '170', 74 | barWidth: '10', 75 | barSpacing: '3', 76 | barColor: '#03A9F3' 77 | }); 78 | 79 | $('#sparkline6').sparkline([4, 7, 8, 5, 8, 9, 4, 10, 12, 7, 4, 6, 11, 12, 7, 12],{ 80 | type: 'line',height: '165', 81 | lineColor: '#FB6D9D', 82 | fillColor: 'transparent', 83 | composite: true, 84 | highlightLineColor: 'rgba(0,0,0,.1)', 85 | highlightSpotColor: '#03A9F3' 86 | }); 87 | 88 | 89 | 90 | 91 | } 92 | var sparkResize; 93 | 94 | $(window).resize(function(e) { 95 | clearTimeout(sparkResize); 96 | sparkResize = setTimeout(sparklineChart, 500); 97 | }); 98 | sparklineChart(); 99 | 100 | }); -------------------------------------------------------------------------------- /rbac/static/assets/pages/components-jqueryui-sliders.js: -------------------------------------------------------------------------------- 1 | 2 | var ComponentsjQueryUISliders = function () { 3 | 4 | return { 5 | //main function to initiate the module 6 | init: function () { 7 | // basic 8 | $(".slider-basic").slider(); // basic sliders 9 | 10 | // vertical range sliders 11 | $("#slider-range").slider({ 12 | /**/ 13 | range: true, 14 | values: [23, 43], 15 | slide: function (event, ui) { 16 | $("#slider-range-amount").text("$" + ui.values[0] + " - $" + ui.values[1]); 17 | } 18 | }); 19 | 20 | // snap inc 21 | $("#slider-snap-inc").slider({value: 100, 22 | min: 0, 23 | max: 1000, 24 | step: 100, 25 | slide: function (event, ui) { 26 | $("#slider-snap-inc-amount").text("$" + ui.value); 27 | } 28 | }); 29 | 30 | $("#slider-snap-inc-amount").text("$" + $("#slider-snap-inc").slider("value")); 31 | 32 | // range slider 33 | $("#slider-range").slider({range: true, 34 | min: 0, 35 | max: 500, 36 | values: [34, 200], 37 | slide: function (event, ui) { 38 | $("#slider-range-amount").text("$" + ui.values[0] + " - $" + ui.values[1]); 39 | } 40 | }); 41 | 42 | $("#slider-range-amount").text("$" + $("#slider-range").slider("values", 0) + " - $" + $("#slider-range").slider("values", 1)); 43 | 44 | //range max 45 | 46 | $("#slider-range-max").slider({range: "max", 47 | min: 1, 48 | max: 10, 49 | value: 2, 50 | slide: function (event, ui) { 51 | $("#slider-range-max-amount").text(ui.value); 52 | } 53 | }); 54 | 55 | $("#slider-range-max-amount").text($("#slider-range-max").slider("value")); 56 | 57 | // range min 58 | $("#slider-range-min").slider({range: "min", 59 | value: 33, 60 | min: 1, 61 | max: 700, 62 | slide: function (event, ui) { 63 | $("#slider-range-min-amount").text("$" + ui.value); 64 | } 65 | }); 66 | 67 | $("#slider-range-min-amount").text("$" + $("#slider-range-min").slider("value")); 68 | 69 | // vertical slider 70 | $("#slider-vertical").slider({orientation: "vertical", 71 | range: "min", 72 | min: 0, 73 | max: 100, 74 | value: 40, 75 | slide: function (event, ui) { 76 | $("#slider-vertical-amount").text(ui.value); 77 | } 78 | }); 79 | $("#slider-vertical-amount").text($("#slider-vertical").slider("value")); 80 | 81 | // vertical range sliders 82 | $("#slider-range-vertical").slider({orientation: "vertical", 83 | range: true, 84 | values: [55, 80], 85 | slide: function (event, ui) { 86 | $("#slider-range-vertical-amount").text("$" + ui.values[0] + " - $" + ui.values[1]); 87 | } 88 | }); 89 | 90 | $("#slider-range-vertical-amount").text("$" + $("#slider-range-vertical").slider("values", 0) + " - $" + $("#slider-range-vertical").slider("values", 1)); 91 | 92 | } 93 | 94 | }; 95 | 96 | }(); -------------------------------------------------------------------------------- /rbac/static/assets/pages/morris-custom.js: -------------------------------------------------------------------------------- 1 | /*$( document ).ready(function() {*/ 2 | 3 | Morris.Area({ 4 | element: 'morris1', 5 | data: [{ 6 | period: '2010', 7 | iphone: 0, 8 | ipad: 0, 9 | itouch: 0 10 | }, { 11 | period: '2011', 12 | iphone: 50, 13 | ipad: 40, 14 | itouch: 30 15 | }, { 16 | period: '2012', 17 | iphone:90, 18 | ipad: 70, 19 | itouch: 60 20 | }, { 21 | period: '2013', 22 | iphone:50, 23 | ipad: 40, 24 | itouch:30 25 | }, { 26 | period: '2014', 27 | iphone:70, 28 | ipad: 50, 29 | itouch: 30 30 | }, { 31 | period: '2015', 32 | iphone:120, 33 | ipad: 90, 34 | itouch: 60 35 | }, { 36 | period: '2016', 37 | iphone:70, 38 | ipad: 50, 39 | itouch:30 40 | } 41 | 42 | 43 | ], 44 | lineColors: ['#F9C851', '#01c0c8', '#D5EEE9'], 45 | xkey: 'period', 46 | ykeys: ['iphone', 'ipad', 'itouch'], 47 | labels: ['iphone', 'ipad', 'itouch'], 48 | pointSize: 0, 49 | lineWidth: 0, 50 | resize:true, 51 | fillOpacity: 0.9, 52 | behaveLikeLine: true, 53 | gridLineColor: '#e0e0e0', 54 | hideHover: 'auto' 55 | 56 | }); 57 | 58 | 59 | 60 | Morris.Bar({ 61 | element: 'morris2', 62 | data: [ 63 | { year: '2010', a: 30, b: 60 }, 64 | { year: '2011', a:80, b: 120 }, 65 | { year: '2012', a: 130, b:150 }, 66 | { year: '2013', a: 90, b: 110 }, 67 | { year: '2014', a: 130, b: 150 }, 68 | { year: '2015', a: 120, b: 140 }, 69 | { year: '2016', a: 165, b: 190 } 70 | ], 71 | xkey: 'year', 72 | ykeys: ['a', 'b'], 73 | labels: ['a', 'b'], 74 | barRatio: 0.4, 75 | hideHover: 'auto', 76 | barColors: ['#03A9F3','#FFAA00'], 77 | resize: true 78 | }); 79 | 80 | Morris.Line({ 81 | element: 'morris3', 82 | data: [ 83 | { year: '2010', a: 25, b: 15, c:2 }, 84 | { year: '2011', a: 50, b: 40 , c:25}, 85 | { year: '2012', a: 75, b: 65, c:55 }, 86 | { year: '2013', a: 100, b: 90, c:75 }, 87 | { year: '2014', a: 60, b: 50, c:35 }, 88 | { year: '2015', a: 75, b: 65 , c:55}, 89 | { year: '2016', a: 100, b: 90, c:75 } 90 | ], 91 | xkey: 'year', 92 | ykeys: ['a', 'b','c'], 93 | labels: ['a', 'b','c'], 94 | resize: true, 95 | lineColors: ['#03a9f3','#03a9f3','#03a9f3'] 96 | }); 97 | 98 | Morris.Donut({ 99 | element: 'morris4', 100 | data: [ 101 | {label: 'Javascript', value: 45 }, 102 | {label: 'HTML5', value: 60 }, 103 | {label: 'CSS3', value: 90 }, 104 | {label: 'PHP', value: 55 } 105 | ], 106 | resize: true, 107 | colors: ['#6E8CD7', '#34D3EB', '#7266BA','#5DDCEF'], 108 | }); 109 | /*});*/ -------------------------------------------------------------------------------- /rbac/service/routes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | import re 4 | from collections import OrderedDict 5 | from django.conf import settings 6 | from django.utils.module_loading import import_string 7 | 8 | # Django1.*只需导入以下模块 9 | from django.urls import RegexURLResolver, RegexURLPattern # Django1.* urlpatterns类型 10 | 11 | 12 | # Django2.* 需要导入以下模块 13 | # from django.urls import URLResolver, URLPattern # Django2.* urlpatterns类型 14 | # from pro_crm import urls # Django2.* 获取项目全部URL,需要获取根urlpatterns 15 | 16 | 17 | def check_url_exclude(url): 18 | """ 19 | 自定制排除一些特定的URL 20 | :param url: 21 | :return: 22 | """ 23 | for regex in settings.AUTO_DISCOVER_EXCLUDE: 24 | if re.match(regex, url): # 如果在白名单内的URL,则不需要进行全局URL展示 25 | return True 26 | 27 | 28 | def recursion_urls(pre_namespace, pre_url, urlpatterns, url_ordered_dict): 29 | """ 30 | 递归的去获取URL 31 | :param pre_namespace: namespace前缀,以后用户拼接name 32 | :param pre_url: url前缀,以后用于拼接url 33 | :param urlpatterns: 路由关系列表 34 | :param url_ordered_dict: 用于保存递归中获取的所有路由 35 | :return: 36 | """ 37 | for item in urlpatterns: 38 | if isinstance(item, RegexURLPattern): # 非路由分发,将路由添加到url_ordered_dict 39 | if not item.name: # 如果没有name则无法添加到全局URL内 40 | continue 41 | 42 | if pre_namespace: 43 | name = "%s:%s" % (pre_namespace, item.name) 44 | else: 45 | name = item.name 46 | 47 | ######### Django1.* 获取regex路径方法 item._regex获取当前URL前缀 ######### 48 | url = pre_url + item._regex # /^rbac/^user/edit/(?P\d+)$/ 49 | 50 | ######### Django2.* 获取regex路径方法 item.pattern.regex.pattern######### 51 | # url = pre_url + item.pattern.regex.pattern # /rbac/user/edit/(?P\d+)/ 52 | 53 | url = url.replace('^', '').replace('$', '') # 去除正则匹配符号 54 | 55 | if check_url_exclude(url): # 如果是白名单的路由,则不需要匹配出来 56 | continue 57 | 58 | url_ordered_dict[name] = {'name': name, 'url': url} 59 | 60 | elif isinstance(item, RegexURLResolver): # 路由分发,递归操作 61 | 62 | if pre_namespace: 63 | if item.namespace: 64 | namespace = "%s:%s" % (pre_namespace, item.namespace,) 65 | else: 66 | namespace = item.namespace 67 | else: 68 | if item.namespace: 69 | namespace = item.namespace 70 | else: 71 | namespace = None 72 | ######### Django1.* 有两种获取获取正则路径的方式######### 73 | # 递归进入更深层的include路由,第二个参数前缀的URL需要把上一层的URL和这一层的URL加起来 74 | # 方法一: 75 | recursion_urls(namespace, pre_url + item.regex.pattern, item.url_patterns, url_ordered_dict) 76 | # 方法二: 77 | # recursion_urls(namespace, pre_url + item._regex, item.url_patterns, url_ordered_dict) 78 | 79 | ######### Django2.* ######### 80 | # recursion_urls(namespace, pre_url + item.pattern.regex.pattern, item.url_patterns, url_ordered_dict) 81 | 82 | 83 | def get_all_url_dict(): 84 | """ 85 | 获取项目中所有的URL(必须有name别名) 86 | :return: 87 | """ 88 | url_ordered_dict = OrderedDict() 89 | 90 | ##### Django1.*使用import_string获取urlpatterns ##### 91 | md = import_string(settings.ROOT_URLCONF) # from luff.. import urls 获取到项目根路由ROOT_URLCONF 92 | recursion_urls(None, '/', md.urlpatterns, url_ordered_dict) # 递归去获取所有的路由,根路由前缀namespace为None,默认URL路径前缀为/ 93 | 94 | ##### Django2.*需导入urlpatterns获取 ##### 95 | # print(urls.urlpatterns) 96 | # recursion_urls(None, '/', urls.urlpatterns, url_ordered_dict) # 递归去获取所有的路由 97 | 98 | return url_ordered_dict 99 | -------------------------------------------------------------------------------- /rbac/static/assets/plugins/vector-map/gdp-data.js: -------------------------------------------------------------------------------- 1 | var gdpData = { 2 | "AF": 16.63, 3 | "AL": 11.58, 4 | "DZ": 158.97, 5 | "AO": 85.81, 6 | "AG": 1.1, 7 | "AR": 351.02, 8 | "AM": 8.83, 9 | "AU": 1219.72, 10 | "AT": 366.26, 11 | "AZ": 52.17, 12 | "BS": 7.54, 13 | "BH": 21.73, 14 | "BD": 105.4, 15 | "BB": 3.96, 16 | "BY": 52.89, 17 | "BE": 461.33, 18 | "BZ": 1.43, 19 | "BJ": 6.49, 20 | "BT": 1.4, 21 | "BO": 19.18, 22 | "BA": 16.2, 23 | "BW": 12.5, 24 | "BR": 2023.53, 25 | "BN": 11.96, 26 | "BG": 44.84, 27 | "BF": 8.67, 28 | "BI": 1.47, 29 | "KH": 11.36, 30 | "CM": 21.88, 31 | "CA": 1563.66, 32 | "CV": 1.57, 33 | "CF": 2.11, 34 | "TD": 7.59, 35 | "CL": 199.18, 36 | "CN": 5745.13, 37 | "CO": 283.11, 38 | "KM": 0.56, 39 | "CD": 12.6, 40 | "CG": 11.88, 41 | "CR": 35.02, 42 | "CI": 22.38, 43 | "HR": 59.92, 44 | "CY": 22.75, 45 | "CZ": 195.23, 46 | "DK": 304.56, 47 | "DJ": 1.14, 48 | "DM": 0.38, 49 | "DO": 50.87, 50 | "EC": 61.49, 51 | "EG": 216.83, 52 | "SV": 21.8, 53 | "GQ": 14.55, 54 | "ER": 2.25, 55 | "EE": 19.22, 56 | "ET": 30.94, 57 | "FJ": 3.15, 58 | "FI": 231.98, 59 | "FR": 2555.44, 60 | "GA": 12.56, 61 | "GM": 1.04, 62 | "GE": 11.23, 63 | "DE": 3305.9, 64 | "GH": 18.06, 65 | "GR": 305.01, 66 | "GD": 0.65, 67 | "GT": 40.77, 68 | "GN": 4.34, 69 | "GW": 0.83, 70 | "GY": 2.2, 71 | "HT": 6.5, 72 | "HN": 15.34, 73 | "HK": 226.49, 74 | "HU": 132.28, 75 | "IS": 12.77, 76 | "IN": 1430.02, 77 | "ID": 695.06, 78 | "IR": 337.9, 79 | "IQ": 84.14, 80 | "IE": 204.14, 81 | "IL": 201.25, 82 | "IT": 2036.69, 83 | "JM": 13.74, 84 | "JP": 5390.9, 85 | "JO": 27.13, 86 | "KZ": 129.76, 87 | "KE": 32.42, 88 | "KI": 0.15, 89 | "KR": 986.26, 90 | "UNDEFINED": 5.73, 91 | "KW": 117.32, 92 | "KG": 4.44, 93 | "LA": 6.34, 94 | "LV": 23.39, 95 | "LB": 39.15, 96 | "LS": 1.8, 97 | "LR": 0.98, 98 | "LY": 77.91, 99 | "LT": 35.73, 100 | "LU": 52.43, 101 | "MK": 9.58, 102 | "MG": 8.33, 103 | "MW": 5.04, 104 | "MY": 218.95, 105 | "MV": 1.43, 106 | "ML": 9.08, 107 | "MT": 7.8, 108 | "MR": 3.49, 109 | "MU": 9.43, 110 | "MX": 1004.04, 111 | "MD": 5.36, 112 | "MN": 5.81, 113 | "ME": 3.88, 114 | "MA": 91.7, 115 | "MZ": 10.21, 116 | "MM": 35.65, 117 | "NA": 11.45, 118 | "NP": 15.11, 119 | "NL": 770.31, 120 | "NZ": 138, 121 | "NI": 6.38, 122 | "NE": 5.6, 123 | "NG": 206.66, 124 | "NO": 413.51, 125 | "OM": 53.78, 126 | "PK": 174.79, 127 | "PA": 27.2, 128 | "PG": 8.81, 129 | "PY": 17.17, 130 | "PE": 153.55, 131 | "PH": 189.06, 132 | "PL": 438.88, 133 | "PT": 223.7, 134 | "QA": 126.52, 135 | "RO": 158.39, 136 | "RU": 1476.91, 137 | "RW": 5.69, 138 | "WS": 0.55, 139 | "ST": 0.19, 140 | "SA": 434.44, 141 | "SN": 12.66, 142 | "RS": 38.92, 143 | "SC": 0.92, 144 | "SL": 1.9, 145 | "SG": 217.38, 146 | "SK": 86.26, 147 | "SI": 46.44, 148 | "SB": 0.67, 149 | "ZA": 354.41, 150 | "ES": 1374.78, 151 | "LK": 48.24, 152 | "KN": 0.56, 153 | "LC": 1, 154 | "VC": 0.58, 155 | "SD": 65.93, 156 | "SR": 3.3, 157 | "SZ": 3.17, 158 | "SE": 444.59, 159 | "CH": 522.44, 160 | "SY": 59.63, 161 | "TW": 426.98, 162 | "TJ": 5.58, 163 | "TZ": 22.43, 164 | "TH": 312.61, 165 | "TL": 0.62, 166 | "TG": 3.07, 167 | "TO": 0.3, 168 | "TT": 21.2, 169 | "TN": 43.86, 170 | "TR": 729.05, 171 | "TM": 0, 172 | "UG": 17.12, 173 | "UA": 136.56, 174 | "AE": 239.65, 175 | "GB": 2258.57, 176 | "US": 14624.18, 177 | "UY": 40.71, 178 | "UZ": 37.72, 179 | "VU": 0.72, 180 | "VE": 285.21, 181 | "VN": 101.99, 182 | "YE": 30.02, 183 | "ZM": 15.69, 184 | "ZW": 5.57 185 | }; -------------------------------------------------------------------------------- /rbac/static/assets/pages/jquery.sweet-alert.custom.js: -------------------------------------------------------------------------------- 1 | 2 | !function($) { 3 | "use strict"; 4 | 5 | var SweetAlert = function() {}; 6 | 7 | //examples 8 | SweetAlert.prototype.init = function() { 9 | 10 | //Basic 11 | $('#sa-basic').click(function(){ 12 | swal("Here's a message!"); 13 | }); 14 | 15 | //A title with a text under 16 | $('#sa-title').click(function(){ 17 | swal("Here's a message!", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed lorem erat eleifend ex semper, lobortis purus sed.") 18 | }); 19 | 20 | //Success Message 21 | $('#sa-success').click(function(){ 22 | swal("Good job!", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed lorem erat eleifend ex semper, lobortis purus sed.", "success") 23 | }); 24 | 25 | //Warning Message 26 | $('.sa-warning').click(function(){ 27 | var pk = $(this).attr('id'); 28 | console.log(pk); 29 | swal({ 30 | title: "你确定要删除吗?", 31 | text: "你将无法恢复它!", 32 | type: "warning", 33 | showCancelButton: true, 34 | confirmButtonColor: "#DD6B55", 35 | confirmButtonText: "确认删除!", 36 | closeOnConfirm: false , 37 | showLoaderOnConfirm: true 38 | }, function(){ 39 | $.ajax( 40 | { 41 | type: "post", 42 | url: "/rbac/role/del/", 43 | data: { 44 | pk:pk 45 | }, 46 | success: function(data){ 47 | console.log(data); 48 | if(data.msg){ 49 | swal("成功删除!", "所选记录以删除", "success"); 50 | window.location.reload(); 51 | }else{ 52 | swal("删除失败!", "所选记录未删除", "error") 53 | } 54 | } 55 | } 56 | ); 57 | 58 | }); 59 | }); 60 | 61 | //Parameter 62 | $('#sa-params').click(function(){ 63 | swal({ 64 | title: "Are you sure?", 65 | text: "You will not be able to recover this imaginary file!", 66 | type: "warning", 67 | showCancelButton: true, 68 | confirmButtonColor: "#DD6B55", 69 | confirmButtonText: "Yes, delete it!", 70 | cancelButtonText: "No, cancel plx!", 71 | closeOnConfirm: false, 72 | closeOnCancel: false 73 | }, function(isConfirm){ 74 | if (isConfirm) { 75 | swal("Deleted!", "Your imaginary file has been deleted.", "success"); 76 | } else { 77 | swal("Cancelled", "Your imaginary file is safe :)", "error"); 78 | } 79 | }); 80 | }); 81 | 82 | //Custom Image 83 | $('#sa-image').click(function(){ 84 | swal({ 85 | title: "Title", 86 | text: "Lorem ipsum dolor sit amet, consectetur", 87 | imageUrl: "assets/images/users/avatar-1.jpg" 88 | }); 89 | }); 90 | 91 | //Auto Close Timer 92 | $('#sa-close').click(function(){ 93 | swal({ 94 | title: "Auto close alert!", 95 | text: "I will close in 2 seconds.", 96 | timer: 2000, 97 | showConfirmButton: false 98 | }); 99 | }); 100 | 101 | 102 | }, 103 | //init 104 | $.SweetAlert = new SweetAlert, $.SweetAlert.Constructor = SweetAlert 105 | }(window.jQuery), 106 | 107 | //initializing 108 | function($) { 109 | "use strict"; 110 | $.SweetAlert.init() 111 | }(window.jQuery); -------------------------------------------------------------------------------- /rbac/static/assets/plugins/cropper-master/cropper.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Cropper v2.3.4 3 | * https://github.com/fengyuanchen/cropper 4 | * 5 | * Copyright (c) 2014-2016 Fengyuan Chen and contributors 6 | * Released under the MIT license 7 | * 8 | * Date: 2016-09-03T05:50:45.412Z 9 | */.cropper-container{font-size:0;line-height:0;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;direction:ltr!important}.cropper-container img{display:block;width:100%;min-width:0!important;max-width:none!important;height:100%;min-height:0!important;max-height:none!important;image-orientation:0deg!important}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{position:absolute;top:0;right:0;bottom:0;left:0}.cropper-wrap-box{overflow:hidden}.cropper-drag-box{opacity:0;background-color:#fff;filter:alpha(opacity=0)}.cropper-dashed,.cropper-modal{opacity:.5;filter:alpha(opacity=50)}.cropper-modal{background-color:#000}.cropper-view-box{display:block;overflow:hidden;width:100%;height:100%;outline:#39f solid 1px;outline-color:rgba(51,153,255,.75)}.cropper-dashed{position:absolute;display:block;border:0 dashed #eee}.cropper-dashed.dashed-h{top:33.33333%;left:0;width:100%;height:33.33333%;border-top-width:1px;border-bottom-width:1px}.cropper-dashed.dashed-v{top:0;left:33.33333%;width:33.33333%;height:100%;border-right-width:1px;border-left-width:1px}.cropper-center{position:absolute;top:50%;left:50%;display:block;width:0;height:0;opacity:.75;filter:alpha(opacity=75)}.cropper-center:after,.cropper-center:before{position:absolute;display:block;content:' ';background-color:#eee}.cropper-center:before{top:0;left:-3px;width:7px;height:1px}.cropper-center:after{top:-3px;left:0;width:1px;height:7px}.cropper-face,.cropper-line,.cropper-point{position:absolute;display:block;width:100%;height:100%;opacity:.1;filter:alpha(opacity=10)}.cropper-face{top:0;left:0;background-color:#fff}.cropper-line,.cropper-point{background-color:#39f}.cropper-line.line-e{top:0;right:-3px;width:5px;cursor:e-resize}.cropper-line.line-n{top:-3px;left:0;height:5px;cursor:n-resize}.cropper-line.line-w{top:0;left:-3px;width:5px;cursor:w-resize}.cropper-line.line-s{bottom:-3px;left:0;height:5px;cursor:s-resize}.cropper-point{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}.cropper-point.point-e{top:50%;right:-3px;margin-top:-3px;cursor:e-resize}.cropper-point.point-n{top:-3px;left:50%;margin-left:-3px;cursor:n-resize}.cropper-point.point-w{top:50%;left:-3px;margin-top:-3px;cursor:w-resize}.cropper-point.point-s{bottom:-3px;left:50%;margin-left:-3px;cursor:s-resize}.cropper-point.point-ne{top:-3px;right:-3px;cursor:ne-resize}.cropper-point.point-nw{top:-3px;left:-3px;cursor:nw-resize}.cropper-point.point-sw{bottom:-3px;left:-3px;cursor:sw-resize}.cropper-point.point-se{right:-3px;bottom:-3px;width:20px;height:20px;cursor:se-resize;opacity:1;filter:alpha(opacity=100)}.cropper-point.point-se:before{position:absolute;right:-50%;bottom:-50%;display:block;width:200%;height:200%;content:' ';opacity:0;background-color:#39f;filter:alpha(opacity=0)}@media (min-width:768px){.cropper-point.point-se{width:15px;height:15px}}@media (min-width:992px){.cropper-point.point-se{width:10px;height:10px}}@media (min-width:1200px){.cropper-point.point-se{width:5px;height:5px;opacity:.75;filter:alpha(opacity=75)}}.cropper-invisible{opacity:0;filter:alpha(opacity=0)}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-hide{position:absolute;display:block;width:0;height:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed} -------------------------------------------------------------------------------- /rbac/static/assets/pages/table-data.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 3 | //ajax mocks 4 | /* $.mockjaxSettings.responseTime = 500; 5 | 6 | $.mockjax({ 7 | url: '/post', 8 | response: function(settings) { 9 | log(settings, this); 10 | } 11 | });*/ 12 | 13 | /*$.mockjax({ 14 | url: '/error', 15 | status: 400, 16 | statusText: 'Bad Request', 17 | response: function(settings) { 18 | this.responseText = 'Please input correct value'; 19 | log(settings, this); 20 | } 21 | });*/ 22 | 23 | /* $.mockjax({ 24 | url: '/status', 25 | status: 500, 26 | response: function(settings) { 27 | this.responseText = 'Internal Server Error'; 28 | log(settings, this); 29 | } 30 | });*/ 31 | /* 32 | $.mockjax({ 33 | url: '/groups', 34 | response: function(settings) { 35 | this.responseText = [ 36 | {value: 0, text: 'Guest'}, 37 | {value: 1, text: 'Service'}, 38 | {value: 2, text: 'Customer'}, 39 | {value: 3, text: 'Operator'}, 40 | {value: 4, text: 'Support'}, 41 | {value: 5, text: 'Admin'} 42 | ]; 43 | log(settings, this); 44 | } 45 | });*/ 46 | 47 | 48 | 49 | // Datatables 50 | 51 | $('#example').dataTable(); 52 | $('#example-editable').DataTable(); 53 | 54 | var table = $('#example2').DataTable({ 55 | "columnDefs": [ 56 | { "visible": false, "targets": 2 } 57 | ], 58 | "order": [[ 2, 'asc' ]], 59 | "displayLength": 25, 60 | "drawCallback": function ( settings ) { 61 | var api = this.api(); 62 | var rows = api.rows( {page:'current'} ).nodes(); 63 | var last=null; 64 | 65 | api.column(2, {page:'current'} ).data().each( function ( group, i ) { 66 | if ( last !== group ) { 67 | $(rows).eq( i ).before( 68 | ''+group+'' 69 | ); 70 | 71 | last = group; 72 | } 73 | } ); 74 | } 75 | } ); 76 | 77 | // Order by the grouping 78 | $('#example2 tbody').on( 'click', 'tr.group', function () { 79 | var currentOrder = table.order()[0]; 80 | if ( currentOrder[0] === 2 && currentOrder[1] === 'asc' ) { 81 | table.order( [ 2, 'desc' ] ).draw(); 82 | } 83 | else { 84 | table.order( [ 2, 'asc' ] ).draw(); 85 | } 86 | } ); 87 | 88 | $.fn.isValid = function(){ 89 | return this[0].checkValidity() 90 | } 91 | 92 | var t = $('#example3').DataTable(); 93 | 94 | $('#add-row').on( 'click', function () { 95 | if($("#add-row-form").isValid()) { 96 | var name = $('#name-input').val(), 97 | position = $('#position-input').val(), 98 | age = $('#age-input').val(), 99 | date = $('#date-input').val(), 100 | salary = $('#salary-input').val(); 101 | t.row.add( [ 102 | name, 103 | position, 104 | age, 105 | date, 106 | '$' + salary 107 | ] ).draw(); 108 | 109 | $('.modal').modal('hide'); 110 | 111 | return false; 112 | } 113 | }); 114 | 115 | /* $('.date-picker').datepicker({ 116 | orientation: "top auto", 117 | autoclose: true 118 | });*/ 119 | }); 120 | 121 | // jQuery(document).ready(function() { 122 | // ComponentsjQueryUISliders.init(); 123 | // }); -------------------------------------------------------------------------------- /rbac/static/assets/plugins/flot-chart/jquery.flot.tooltip.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jquery.flot.tooltip 3 | * 4 | * description: easy-to-use tooltips for Flot charts 5 | * version: 0.6.2 6 | * author: Krzysztof Urbas @krzysu [myviews.pl] 7 | * website: https://github.com/krzysu/flot.tooltip 8 | * 9 | * build on 2013-09-30 10 | * released under MIT License, 2012 11 | */ 12 | (function(t){var o={tooltip:!1,tooltipOpts:{content:"%s | X: %x | Y: %y",xDateFormat:null,yDateFormat:null,shifts:{x:10,y:20},defaultTheme:!0,onHover:function(){}}},i=function(t){this.tipPosition={x:0,y:0},this.init(t)};i.prototype.init=function(o){function i(t){var o={};o.x=t.pageX,o.y=t.pageY,s.updateTooltipPosition(o)}function e(t,o,i){var e=s.getDomElement();if(i){var n;n=s.stringFormat(s.tooltipOptions.content,i),e.html(n),s.updateTooltipPosition({x:o.pageX,y:o.pageY}),e.css({left:s.tipPosition.x+s.tooltipOptions.shifts.x,top:s.tipPosition.y+s.tooltipOptions.shifts.y}).show(),"function"==typeof s.tooltipOptions.onHover&&s.tooltipOptions.onHover(i,e)}else e.hide().html("")}var s=this;o.hooks.bindEvents.push(function(o,n){s.plotOptions=o.getOptions(),s.plotOptions.tooltip!==!1&&void 0!==s.plotOptions.tooltip&&(s.tooltipOptions=s.plotOptions.tooltipOpts,s.getDomElement(),t(o.getPlaceholder()).bind("plothover",e),t(n).bind("mousemove",i))}),o.hooks.shutdown.push(function(o,s){t(o.getPlaceholder()).unbind("plothover",e),t(s).unbind("mousemove",i)})},i.prototype.getDomElement=function(){var o;return t("#flotTip").length>0?o=t("#flotTip"):(o=t("
").attr("id","flotTip"),o.appendTo("body").hide().css({position:"absolute"}),this.tooltipOptions.defaultTheme&&o.css({background:"#fff","z-index":"100",padding:"0.4em 0.6em","border-radius":"0.5em","font-size":"0.8em",border:"1px solid #111",display:"none","white-space":"nowrap"})),o},i.prototype.updateTooltipPosition=function(o){var i=t("#flotTip").outerWidth()+this.tooltipOptions.shifts.x,e=t("#flotTip").outerHeight()+this.tooltipOptions.shifts.y;o.x-t(window).scrollLeft()>t(window).innerWidth()-i&&(o.x-=i),o.y-t(window).scrollTop()>t(window).innerHeight()-e&&(o.y-=e),this.tipPosition.x=o.x,this.tipPosition.y=o.y},i.prototype.stringFormat=function(t,o){var i=/%p\.{0,1}(\d{0,})/,e=/%s/,s=/%x\.{0,1}(?:\d{0,})/,n=/%y\.{0,1}(?:\d{0,})/;return"function"==typeof t&&(t=t(o.series.label,o.series.data[o.dataIndex][0],o.series.data[o.dataIndex][1],o)),o.series.percent!==void 0&&(t=this.adjustValPrecision(i,t,o.series.percent)),o.series.label!==void 0&&(t=t.replace(e,o.series.label)),this.isTimeMode("xaxis",o)&&this.isXDateFormat(o)&&(t=t.replace(s,this.timestampToDate(o.series.data[o.dataIndex][0],this.tooltipOptions.xDateFormat))),this.isTimeMode("yaxis",o)&&this.isYDateFormat(o)&&(t=t.replace(n,this.timestampToDate(o.series.data[o.dataIndex][1],this.tooltipOptions.yDateFormat))),"number"==typeof o.series.data[o.dataIndex][0]&&(t=this.adjustValPrecision(s,t,o.series.data[o.dataIndex][0])),"number"==typeof o.series.data[o.dataIndex][1]&&(t=this.adjustValPrecision(n,t,o.series.data[o.dataIndex][1])),o.series.xaxis.tickFormatter!==void 0&&(t=t.replace(s,o.series.xaxis.tickFormatter(o.series.data[o.dataIndex][0],o.series.xaxis))),o.series.yaxis.tickFormatter!==void 0&&(t=t.replace(n,o.series.yaxis.tickFormatter(o.series.data[o.dataIndex][1],o.series.yaxis))),t},i.prototype.isTimeMode=function(t,o){return o.series[t].options.mode!==void 0&&"time"===o.series[t].options.mode},i.prototype.isXDateFormat=function(){return this.tooltipOptions.xDateFormat!==void 0&&null!==this.tooltipOptions.xDateFormat},i.prototype.isYDateFormat=function(){return this.tooltipOptions.yDateFormat!==void 0&&null!==this.tooltipOptions.yDateFormat},i.prototype.timestampToDate=function(o,i){var e=new Date(o);return t.plot.formatDate(e,i)},i.prototype.adjustValPrecision=function(t,o,i){var e,s=o.match(t);return null!==s&&""!==RegExp.$1&&(e=RegExp.$1,i=i.toFixed(e),o=o.replace(t,i)),o};var e=function(t){new i(t)};t.plot.plugins.push({init:e,options:o,name:"tooltip",version:"0.6.1"})})(jQuery); -------------------------------------------------------------------------------- /rbac/static/assets/pages/validation-custom.js: -------------------------------------------------------------------------------- 1 | 2 | var BaseFormValidation = function() { 3 | var initValidationBootstrap = function(){ 4 | jQuery('.js-validation-bootstrap').validate({ 5 | errorClass: 'help-block animated fadeInDown', 6 | errorElement: 'div', 7 | errorPlacement: function(error, e) { 8 | jQuery(e).parents('.form-group > div').append(error); 9 | }, 10 | highlight: function(e) { 11 | jQuery(e).closest('.form-group').removeClass('has-error').addClass('has-error'); 12 | jQuery(e).closest('.help-block').remove(); 13 | }, 14 | success: function(e) { 15 | jQuery(e).closest('.form-group').removeClass('has-error'); 16 | jQuery(e).closest('.help-block').remove(); 17 | }, 18 | rules: { 19 | 'val-username': { 20 | required: true, 21 | minlength: 3 22 | }, 23 | 'val-email': { 24 | required: true, 25 | email: true 26 | }, 27 | 'val-password': { 28 | required: true, 29 | minlength: 5 30 | }, 31 | 'val-confirm-password': { 32 | required: true, 33 | equalTo: '#val-password' 34 | }, 35 | 'val-suggestions': { 36 | required: true, 37 | minlength: 5 38 | }, 39 | 'val-skill': { 40 | required: true 41 | }, 42 | 'val-website': { 43 | required: true, 44 | url: true 45 | }, 46 | 'val-digits': { 47 | required: true, 48 | digits: true 49 | }, 50 | 'val-number': { 51 | required: true, 52 | number: true 53 | }, 54 | 'val-range': { 55 | required: true, 56 | range: [1, 10] 57 | }, 58 | 'val-terms': { 59 | required: true 60 | } 61 | }, 62 | messages: { 63 | 'val-username': { 64 | required: 'Please enter a username', 65 | minlength: 'Your username must consist of at least 3 characters' 66 | }, 67 | 'val-email': 'Please enter a valid email address', 68 | 'val-password': { 69 | required: 'Please provide a password', 70 | minlength: 'Your password must be at least 5 characters long' 71 | }, 72 | 'val-confirm-password': { 73 | required: 'Please provide a password', 74 | minlength: 'Your password must be at least 5 characters long', 75 | equalTo: 'Please enter the same password as above' 76 | }, 77 | 'val-suggestions': 'What can we do to become better?', 78 | 'val-skill': 'Please select a skill!', 79 | 'val-website': 'Please enter your website!', 80 | 'val-digits': 'Please enter only digits!', 81 | 'val-number': 'Please enter a number!', 82 | 'val-range': 'Please enter a number between 1 and 10!', 83 | 'val-terms': 'You must agree to the service terms!' 84 | } 85 | }); 86 | }; 87 | 88 | return { 89 | init: function () { 90 | // Init Bootstrap Forms Validation 91 | initValidationBootstrap(); 92 | } 93 | }; 94 | }(); 95 | 96 | // Initialize when page loads 97 | jQuery(function(){ BaseFormValidation.init(); }); -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Colorpicker v2.3.3 3 | * http://mjolnic.github.io/bootstrap-colorpicker/ 4 | * 5 | * Originally written by (c) 2012 Stefan Petre 6 | * Licensed under the Apache License v2.0 7 | * http://www.apache.org/licenses/LICENSE-2.0.txt 8 | * 9 | */.colorpicker-saturation{width:100px;height:100px;background-image:url(../img/bootstrap-colorpicker/saturation.png);cursor:crosshair;float:left}.colorpicker-saturation i{display:block;height:5px;width:5px;border:1px solid #000;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;position:absolute;top:0;left:0;margin:-4px 0 0 -4px}.colorpicker-saturation i b{display:block;height:5px;width:5px;border:1px solid #fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-alpha,.colorpicker-hue{width:15px;height:100px;float:left;cursor:row-resize;margin-left:4px;margin-bottom:4px}.colorpicker-alpha i,.colorpicker-hue i{display:block;height:1px;background:#000;border-top:1px solid #fff;position:absolute;top:0;left:0;width:100%;margin-top:-1px}.colorpicker-hue{background-image:url(../img/bootstrap-colorpicker/hue.png)}.colorpicker-alpha{background-image:url(../img/bootstrap-colorpicker/alpha.png);display:none}.colorpicker-alpha,.colorpicker-hue,.colorpicker-saturation{background-size:contain}.colorpicker{padding:4px;min-width:130px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;z-index:2500}.colorpicker:after,.colorpicker:before{display:table;content:"";line-height:0}.colorpicker:after{clear:both}.colorpicker:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,.2);position:absolute;top:-7px;left:6px}.colorpicker:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:7px}.colorpicker div{position:relative}.colorpicker.colorpicker-with-alpha{min-width:140px}.colorpicker.colorpicker-with-alpha .colorpicker-alpha{display:block}.colorpicker-color{height:10px;margin-top:5px;clear:both;background-image:url(../img/bootstrap-colorpicker/alpha.png);background-position:0 100%}.colorpicker-color div{height:10px}.colorpicker-selectors{display:none;height:10px;margin-top:5px;clear:both}.colorpicker-selectors i{cursor:pointer;float:left;height:10px;width:10px}.colorpicker-selectors i+i{margin-left:3px}.colorpicker-element .add-on i,.colorpicker-element .input-group-addon i{display:inline-block;cursor:pointer;height:16px;vertical-align:text-top;width:16px}.colorpicker.colorpicker-inline{position:relative;display:inline-block;float:none;z-index:auto}.colorpicker.colorpicker-horizontal{width:110px;min-width:110px;height:auto}.colorpicker.colorpicker-horizontal .colorpicker-saturation{margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-color{width:100px}.colorpicker.colorpicker-horizontal .colorpicker-alpha,.colorpicker.colorpicker-horizontal .colorpicker-hue{width:100px;height:15px;float:left;cursor:col-resize;margin-left:0;margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-alpha i,.colorpicker.colorpicker-horizontal .colorpicker-hue i{display:block;height:15px;background:#fff;position:absolute;top:0;left:0;width:1px;border:none;margin-top:0}.colorpicker.colorpicker-horizontal .colorpicker-hue{background-image:url(../img/bootstrap-colorpicker/hue-horizontal.png)}.colorpicker.colorpicker-horizontal .colorpicker-alpha{background-image:url(../img/bootstrap-colorpicker/alpha-horizontal.png)}.colorpicker.colorpicker-hidden{display:none}.colorpicker.colorpicker-visible{display:block}.colorpicker-inline.colorpicker-visible{display:inline-block}.colorpicker-right:before{left:auto;right:6px}.colorpicker-right:after{left:auto;right:7px}.colorpicker-no-arrow:before{border-right:0;border-left:0}.colorpicker-no-arrow:after{border-right:0;border-left:0} 10 | /*# sourceMappingURL=bootstrap-colorpicker.min.css.map */ -------------------------------------------------------------------------------- /rbac/static/assets/plugins/timepicker/bootstrap-timepicker.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Timepicker Component for Twitter Bootstrap 3 | * 4 | * Copyright 2013 Joris de Wit 5 | * 6 | * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | .bootstrap-timepicker { 13 | position: relative; 14 | } 15 | .bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu { 16 | left: auto; 17 | right: 0; 18 | } 19 | .bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:before { 20 | left: auto; 21 | right: 12px; 22 | } 23 | .bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:after { 24 | left: auto; 25 | right: 13px; 26 | } 27 | .bootstrap-timepicker .input-group-addon { 28 | cursor: pointer; 29 | } 30 | .bootstrap-timepicker .input-group-addon i { 31 | display: inline-block; 32 | width: 16px; 33 | height: 16px; 34 | } 35 | .bootstrap-timepicker-widget.dropdown-menu { 36 | padding: 4px; 37 | } 38 | .bootstrap-timepicker-widget.dropdown-menu.open { 39 | display: inline-block; 40 | } 41 | .bootstrap-timepicker-widget.dropdown-menu:before { 42 | border-bottom: 7px solid rgba(0, 0, 0, 0.2); 43 | border-left: 7px solid transparent; 44 | border-right: 7px solid transparent; 45 | content: ""; 46 | display: inline-block; 47 | position: absolute; 48 | } 49 | .bootstrap-timepicker-widget.dropdown-menu:after { 50 | border-bottom: 6px solid #FFFFFF; 51 | border-left: 6px solid transparent; 52 | border-right: 6px solid transparent; 53 | content: ""; 54 | display: inline-block; 55 | position: absolute; 56 | } 57 | .bootstrap-timepicker-widget.timepicker-orient-left:before { 58 | left: 6px; 59 | } 60 | .bootstrap-timepicker-widget.timepicker-orient-left:after { 61 | left: 7px; 62 | } 63 | .bootstrap-timepicker-widget.timepicker-orient-right:before { 64 | right: 6px; 65 | } 66 | .bootstrap-timepicker-widget.timepicker-orient-right:after { 67 | right: 7px; 68 | } 69 | .bootstrap-timepicker-widget.timepicker-orient-top:before { 70 | top: -7px; 71 | } 72 | .bootstrap-timepicker-widget.timepicker-orient-top:after { 73 | top: -6px; 74 | } 75 | .bootstrap-timepicker-widget.timepicker-orient-bottom:before { 76 | bottom: -7px; 77 | border-bottom: 0; 78 | border-top: 7px solid #999; 79 | } 80 | .bootstrap-timepicker-widget.timepicker-orient-bottom:after { 81 | bottom: -6px; 82 | border-bottom: 0; 83 | border-top: 6px solid #ffffff; 84 | } 85 | .bootstrap-timepicker-widget a.btn, 86 | .bootstrap-timepicker-widget input { 87 | border-radius: 4px; 88 | } 89 | .bootstrap-timepicker-widget table { 90 | width: 100%; 91 | margin: 0; 92 | } 93 | .bootstrap-timepicker-widget table td { 94 | text-align: center; 95 | height: 30px; 96 | margin: 0; 97 | padding: 2px; 98 | } 99 | .bootstrap-timepicker-widget table td:not(.separator) { 100 | min-width: 30px; 101 | } 102 | .bootstrap-timepicker-widget table td span { 103 | width: 100%; 104 | } 105 | .bootstrap-timepicker-widget table td a { 106 | border: 1px transparent solid; 107 | width: 100%; 108 | display: inline-block; 109 | margin: 0; 110 | padding: 8px 0; 111 | outline: 0; 112 | color: #333; 113 | } 114 | .bootstrap-timepicker-widget table td a:hover { 115 | text-decoration: none; 116 | background-color: #eee; 117 | -webkit-border-radius: 4px; 118 | -moz-border-radius: 4px; 119 | border-radius: 4px; 120 | border-color: #ddd; 121 | } 122 | .bootstrap-timepicker-widget table td a i { 123 | margin-top: 2px; 124 | font-size: 18px; 125 | } 126 | .bootstrap-timepicker-widget table td input { 127 | width: 25px; 128 | margin: 0; 129 | text-align: center; 130 | border: 0; 131 | } 132 | .bootstrap-timepicker-widget .modal-content { 133 | padding: 4px; 134 | } 135 | @media (min-width: 767px) { 136 | .bootstrap-timepicker-widget.modal { 137 | width: 200px; 138 | margin-left: -100px; 139 | } 140 | } 141 | @media (max-width: 767px) { 142 | .bootstrap-timepicker { 143 | width: 100%; 144 | } 145 | .bootstrap-timepicker .dropdown-menu { 146 | width: 100%; 147 | } 148 | } -------------------------------------------------------------------------------- /rbac/static/assets/pages/bootstrap-editable-custom.js: -------------------------------------------------------------------------------- 1 | $(function(){ 2 | 3 | //editables 4 | $('#username').editable({ 5 | url: '/post', 6 | type: 'text', 7 | pk: 1, 8 | name: 'username', 9 | title: 'Enter username' 10 | }); 11 | 12 | $('#firstname').editable({ 13 | validate: function(value) { 14 | if($.trim(value) == '') return 'This field is required'; 15 | } 16 | }); 17 | 18 | $('#sex').editable({ 19 | prepend: "not selected", 20 | source: [ 21 | {value: 1, text: 'Male'}, 22 | {value: 2, text: 'Female'} 23 | ], 24 | display: function(value, sourceData) { 25 | var colors = {"": "gray", 1: "green", 2: "blue"}, 26 | elem = $.grep(sourceData, function(o){return o.value == value;}); 27 | 28 | if(elem.length) { 29 | $(this).text(elem[0].text).css("color", colors[value]); 30 | } else { 31 | $(this).empty(); 32 | } 33 | } 34 | }); 35 | 36 | 37 | $('#status').editable(); 38 | 39 | $('#group').editable({ 40 | showbuttons: false 41 | }); 42 | 43 | /* $('#vacation').editable({ 44 | datepicker: { 45 | todayBtn: 'linked' 46 | } 47 | }); */ 48 | 49 | $('#dob').editable(); 50 | 51 | $('#event').editable({ 52 | placement: 'right', 53 | combodate: { 54 | firstItem: 'name' 55 | } 56 | }); 57 | 58 | /*$('#meeting_start').editable({ 59 | format: 'yyyy-mm-dd hh:ii', 60 | viewformat: 'dd/mm/yyyy hh:ii', 61 | validate: function(v) { 62 | if(v && v.getDate() == 10) return 'Day cant be 10!'; 63 | }, 64 | datetimepicker: { 65 | todayBtn: 'linked', 66 | weekStart: 1 67 | } 68 | }); */ 69 | 70 | $('#comments').editable({ 71 | showbuttons: 'bottom' 72 | }); 73 | 74 | 75 | //inline editables 76 | $('#inline-username').editable({ 77 | mode: 'inline', 78 | url: '/post', 79 | type: 'text', 80 | pk: 1, 81 | name: 'username', 82 | title: 'Enter username' 83 | }); 84 | 85 | $('#inline-firstname').editable({ 86 | mode: 'inline', 87 | validate: function(value) { 88 | if($.trim(value) == '') return 'This field is required'; 89 | } 90 | }); 91 | 92 | $('#inline-sex').editable({ 93 | mode: 'inline', 94 | prepend: "not selected", 95 | source: [ 96 | {value: 1, text: 'Male'}, 97 | {value: 2, text: 'Female'} 98 | ], 99 | display: function(value, sourceData) { 100 | var colors = {"": "gray", 1: "green", 2: "blue"}, 101 | elem = $.grep(sourceData, function(o){return o.value == value;}); 102 | 103 | if(elem.length) { 104 | $(this).text(elem[0].text).css("color", colors[value]); 105 | } else { 106 | $(this).empty(); 107 | } 108 | } 109 | }); 110 | 111 | 112 | $('#inline-status').editable({ 113 | mode: 'inline', 114 | }); 115 | 116 | $('#inline-group').editable({ 117 | mode: 'inline', 118 | showbuttons: false 119 | }); 120 | 121 | $('#inline-vacation').editable({ 122 | mode: 'inline', 123 | datepicker: { 124 | todayBtn: 'linked' 125 | } 126 | }); 127 | 128 | $('#inline-dob').editable({ 129 | mode: 'inline', 130 | }); 131 | 132 | $('#inline-event').editable({ 133 | mode: 'inline', 134 | placement: 'right', 135 | combodate: { 136 | firstItem: 'name' 137 | } 138 | }); 139 | 140 | /* $('#inline-meeting_start').editable({ 141 | mode: 'inline', 142 | format: 'yyyy-mm-dd hh:ii', 143 | viewformat: 'dd/mm/yyyy hh:ii', 144 | validate: function(v) { 145 | if(v && v.getDate() == 10) return 'Day cant be 10!'; 146 | }, 147 | datetimepicker: { 148 | todayBtn: 'linked', 149 | weekStart: 1, 150 | 151 | } 152 | }); */ 153 | 154 | $('#inline-comments').editable({ 155 | showbuttons: 'bottom', 156 | mode: 'inline' 157 | }); 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | }); -------------------------------------------------------------------------------- /rbac/static/assets/pages/jquery.flot.init.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | 3 | var flot1 = function () { 4 | var data = [[0, 11], [1, 15], [2, 25], [3, 24], [4, 13], [5, 18]]; 5 | var dataset = [{ 6 | data: data, 7 | color: "#3B8DD5" 8 | }]; 9 | var ticks = [[0, "1"], [1, "2"], [2, "3"], [3, "4"], [4, "5"], [5, "6"]]; 10 | 11 | var options = { 12 | series: { 13 | bars: { 14 | show: true 15 | } 16 | }, 17 | bars: { 18 | align: "center", 19 | barWidth: 0.5 20 | }, 21 | xaxis: { 22 | ticks: ticks 23 | }, 24 | legend: { 25 | show: false 26 | }, 27 | grid: { 28 | color: "#AFAFAF", 29 | hoverable: true, 30 | borderWidth: 0, 31 | backgroundColor: '#FFF' 32 | }, 33 | tooltip: true, 34 | tooltipOpts: { 35 | content: "X: %x, Y: %y", 36 | defaultTheme: false 37 | } 38 | }; 39 | $.plot($("#flot1"), dataset, options); 40 | }; 41 | 42 | var flot2 = function () { 43 | var data = [[0, 11], [1, 15], [2, 25], [3, 24], [4, 13], [5, 18]]; 44 | var dataset = [{ 45 | data: data, 46 | color: "#03A9F3" 47 | }]; 48 | var ticks = [[0, "1"], [1, "2"], [2, "3"], [3, "4"], [4, "5"], [5, "6"]]; 49 | 50 | var options = { 51 | series: { 52 | lines: { 53 | show: true 54 | } 55 | }, 56 | bars: { 57 | align: "center", 58 | barWidth: 0.5 59 | }, 60 | xaxis: { 61 | ticks: ticks 62 | }, 63 | legend: { 64 | show: false 65 | }, 66 | grid: { 67 | color: "#AFAFAF", 68 | hoverable: true, 69 | borderWidth: 0, 70 | backgroundColor: '#FFF' 71 | }, 72 | tooltip: true, 73 | tooltipOpts: { 74 | content: "X: %x, Y: %y", 75 | defaultTheme: false 76 | } 77 | }; 78 | $.plot($("#flot2"), dataset, options); 79 | }; 80 | 81 | 82 | var dataSet = [ 83 | { label: "Mobile", data: 41196300, color: "#3FB7EE" }, 84 | { label: "Laptop", data: 10129600, color: "#727CB6" }, 85 | { label: "App", data: 72708000, color: "#00ACAC" }, 86 | { label: "Ipad", data: 344120, color: "#FF6384" } 87 | ]; 88 | 89 | $.plot('#flot3', dataSet, { 90 | series: { 91 | pie: { 92 | show: true, 93 | combine: { 94 | color: '#3B8DD5', 95 | threshold: 0.1 96 | } 97 | } 98 | }, 99 | legend: { 100 | show: false 101 | } 102 | }); 103 | 104 | 105 | var flot4 = function () { 106 | 107 | var data = [], 108 | totalPoints = 300; 109 | 110 | function getRandomData() { 111 | 112 | if (data.length > 0) 113 | data = data.slice(1); 114 | 115 | // Do a random walk 116 | 117 | while (data.length < totalPoints) { 118 | 119 | var prev = data.length > 0 ? data[data.length - 1] : 50, 120 | y = prev + Math.random() * 10 - 5; 121 | 122 | if (y < 0) { 123 | y = 0; 124 | } else if (y > 100) { 125 | y = 100; 126 | } 127 | 128 | data.push(y); 129 | } 130 | 131 | // Zip the generated y values with the x values 132 | 133 | var res = []; 134 | for (var i = 0; i < data.length; ++i) { 135 | res.push([i, data[i]]) 136 | } 137 | 138 | return res; 139 | } 140 | 141 | var plot4 = $.plot("#flot4", [ getRandomData() ], { 142 | series: { 143 | shadowSize: 0 // Drawing is faster without shadows 144 | }, 145 | yaxis: { 146 | min: 0, 147 | max: 100 148 | }, 149 | xaxis: { 150 | show: false 151 | }, 152 | colors: ["#03A9F3"], 153 | legend: { 154 | show: false 155 | }, 156 | grid: { 157 | color: "#AFAFAF", 158 | hoverable: true, 159 | borderWidth: 0, 160 | backgroundColor: '#FFF' 161 | }, 162 | tooltip: true, 163 | tooltipOpts: { 164 | content: "Y: %y", 165 | defaultTheme: false 166 | } 167 | }); 168 | 169 | function update() { 170 | plot4.setData([getRandomData()]); 171 | 172 | plot4.draw(); 173 | setTimeout(update, 30); 174 | } 175 | 176 | update(); 177 | 178 | }; 179 | 180 | flot1(); 181 | flot2(); 182 | flot4(); 183 | }); -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-maxlength/bootstrap-maxlength.min.js: -------------------------------------------------------------------------------- 1 | /* ========================================================== 2 | * 3 | * bootstrap-maxlength.js v 1.6.0 4 | * Copyright 2015 Maurizio Napoleoni @mimonap 5 | * Licensed under MIT License 6 | * URL: https://github.com/mimo84/bootstrap-maxlength/blob/master/LICENSE 7 | * 8 | * ========================================================== */ 9 | 10 | !function(a){"use strict";a.event.special.destroyed||(a.event.special.destroyed={remove:function(a){a.handler&&a.handler()}}),a.fn.extend({maxlength:function(b,c){function d(a){var c=a.val();c=b.twoCharLinebreak?c.replace(/\r(?!\n)|\n(?!\r)/g,"\r\n"):c.replace(new RegExp("\r?\n","g"),"\n");var d=0;return d=b.utf8?f(c):c.length}function e(a,c){var d=a.val(),e=0;b.twoCharLinebreak&&(d=d.replace(/\r(?!\n)|\n(?!\r)/g,"\r\n"),"\n"===d.substr(d.length-1)&&d.length%2===1&&(e=1)),a.val(d.substr(0,c-e))}function f(a){for(var b=0,c=0;cd?b++:b+=d>127&&2048>d?2:3}return b}function g(a,c,e){var f=!0;return!b.alwaysShow&&e-d(a)>c&&(f=!1),f}function h(a,b){var c=b-d(a);return c}function i(a,b){b.css({display:"block"}),a.trigger("maxlength.shown")}function j(a,b){b.css({display:"none"}),a.trigger("maxlength.hidden")}function k(a,c,d){var e="";return b.message?e="function"==typeof b.message?b.message(a,c):b.message.replace("%charsTyped%",d).replace("%charsRemaining%",c-d).replace("%charsTotal%",c):(b.preText&&(e+=b.preText),e+=b.showCharsTyped?d:c-d,b.showMaxLength&&(e+=b.separator+c),b.postText&&(e+=b.postText)),e}function l(a,c,d,e){e&&(e.html(k(c.val(),d,d-a)),a>0?g(c,b.threshold,d)?i(c,e.removeClass(b.limitReachedClass).addClass(b.warningClass)):j(c,e):i(c,e.removeClass(b.warningClass).addClass(b.limitReachedClass))),b.allowOverMax&&(0>a?c.addClass("overmax"):c.removeClass("overmax"))}function m(b){var c=b[0];return a.extend({},"function"==typeof c.getBoundingClientRect?c.getBoundingClientRect():{width:c.offsetWidth,height:c.offsetHeight},b.offset())}function n(c,d){var e=m(c);if("function"===a.type(b.placement))return void b.placement(c,d,e);if(a.isPlainObject(b.placement))return void o(b.placement,d);var f=c.outerWidth(),g=d.outerWidth(),h=d.width(),i=d.height();switch(b.appendToParent&&(e.top-=c.parent().offset().top,e.left-=c.parent().offset().left),b.placement){case"bottom":d.css({top:e.top+e.height,left:e.left+e.width/2-h/2});break;case"top":d.css({top:e.top-i,left:e.left+e.width/2-h/2});break;case"left":d.css({top:e.top+e.height/2-i/2,left:e.left-h});break;case"right":d.css({top:e.top+e.height/2-i/2,left:e.left+e.width});break;case"bottom-right":d.css({top:e.top+e.height,left:e.left+e.width});break;case"top-right":d.css({top:e.top-i,left:e.left+f});break;case"top-left":d.css({top:e.top-i,left:e.left-g});break;case"bottom-left":d.css({top:e.top+c.outerHeight(),left:e.left-g});break;case"centered-right":d.css({top:e.top+i/2,left:e.left+f-g-3});break;case"bottom-right-inside":d.css({top:e.top+e.height,left:e.left+e.width-g});break;case"top-right-inside":d.css({top:e.top-i,left:e.left+f-g});break;case"top-left-inside":d.css({top:e.top-i,left:e.left});break;case"bottom-left-inside":d.css({top:e.top+c.outerHeight(),left:e.left})}}function o(c,d){if(c&&d){var e=["top","bottom","left","right","position"],f={};a.each(e,function(a,c){var d=b.placement[c];"undefined"!=typeof d&&(f[c]=d)}),d.css(f)}}function p(a){var c="maxlength";return b.allowOverMax&&(c="data-bs-mxl"),a.attr(c)||a.attr("size")}var q=a("body"),r={showOnReady:!1,alwaysShow:!1,threshold:10,warningClass:"label label-success",limitReachedClass:"label label-important label-danger",separator:" / ",preText:"",postText:"",showMaxLength:!0,placement:"bottom",message:null,showCharsTyped:!0,validate:!1,utf8:!1,appendToParent:!1,twoCharLinebreak:!0,allowOverMax:!1};return a.isFunction(b)&&!c&&(c=b,b={}),b=a.extend(r,b),this.each(function(){function c(){var c=k(g.val(),d,"0");d=p(g),f||(f=a('').css({display:"none",position:"absolute",whiteSpace:"nowrap",zIndex:1099}).html(c)),g.is("textarea")&&(g.data("maxlenghtsizex",g.outerWidth()),g.data("maxlenghtsizey",g.outerHeight()),g.mouseup(function(){(g.outerWidth()!==g.data("maxlenghtsizex")||g.outerHeight()!==g.data("maxlenghtsizey"))&&n(g,f),g.data("maxlenghtsizex",g.outerWidth()),g.data("maxlenghtsizey",g.outerHeight())})),b.appendToParent?(g.parent().append(f),g.parent().css("position","relative")):q.append(f);var e=h(g,p(g));l(e,g,d,f),n(g,f)}var d,f,g=a(this);a(window).resize(function(){f&&n(g,f)}),b.allowOverMax&&(a(this).attr("data-bs-mxl",a(this).attr("maxlength")),a(this).removeAttr("maxlength")),b.showOnReady?g.ready(function(){c()}):g.focus(function(){c()}),g.on("maxlength.reposition",function(){n(g,f)}),g.on("destroyed",function(){f&&f.remove()}),g.on("blur",function(){f&&!b.showOnReady&&f.remove()}),g.on("input",function(){var a=p(g),c=h(g,a),i=!0;return b.validate&&0>c?(e(g,a),i=!1):l(c,g,d,f),("bottom-right-inside"===b.placement||"top-right-inside"===b.placement)&&n(g,f),i})})}})}(jQuery); -------------------------------------------------------------------------------- /rbac/static/assets/pages/dashboard.js: -------------------------------------------------------------------------------- 1 | 2 | $(document).ready(function() { 3 | 4 | Morris.Bar({ 5 | element: 'morris2', 6 | data: [ 7 | { year: '2010', a: 30, b: 25 }, 8 | { year: '2011', a: 60, b: 40 }, 9 | { year: '2012', a: 85, b: 65 }, 10 | { year: '2013', a: 100, b: 90 }, 11 | { year: '2014', a: 60, b: 50 }, 12 | { year: '2015', a: 75, b: 65 }, 13 | { year: '2016', a: 100, b: 90 } 14 | ], 15 | xkey: 'year', 16 | ykeys: ['a', 'b'], 17 | labels: ['Section A', 'Section B'], 18 | barRatio: 0.4, 19 | xLabelAngle: 0, 20 | hideHover: 'auto', 21 | barColors: ['#03A9F3','#FFAA00'], 22 | resize: true 23 | }); 24 | 25 | 26 | 27 | 28 | }); 29 | Morris.Area({ 30 | element: 'morris-area-chart', 31 | data: [{ 32 | period: '2010', 33 | iphone: 0, 34 | ipad: 0, 35 | itouch: 0 36 | }, { 37 | period: '2011', 38 | iphone: 50, 39 | ipad: 40, 40 | itouch: 30 41 | }, { 42 | period: '2012', 43 | iphone:90, 44 | ipad: 70, 45 | itouch: 60 46 | }, { 47 | period: '2013', 48 | iphone:50, 49 | ipad: 40, 50 | itouch:30 51 | }, { 52 | period: '2014', 53 | iphone:70, 54 | ipad: 50, 55 | itouch: 30 56 | }, { 57 | period: '2015', 58 | iphone:120, 59 | ipad: 90, 60 | itouch: 60 61 | }, { 62 | period: '2016', 63 | iphone:70, 64 | ipad: 50, 65 | itouch:30 66 | } 67 | 68 | 69 | ], 70 | lineColors: ['#F9C851', '#01c0c8', '#D5EEE9'], 71 | xkey: 'period', 72 | ykeys: ['iphone', 'ipad', 'itouch'], 73 | labels: ['iphone', 'ipad', 'itouch'], 74 | pointSize: 0, 75 | lineWidth: 0, 76 | resize:true, 77 | fillOpacity: 0.9, 78 | behaveLikeLine: true, 79 | gridLineColor: '#e0e0e0', 80 | hideHover: 'auto' 81 | 82 | }); 83 | Morris.Area({ 84 | element: 'morris-area-chart2', 85 | data: [{ 86 | period: '2010', 87 | SiteA: 0, 88 | SiteB: 0, 89 | 90 | }, { 91 | period: '2011', 92 | SiteA: 130, 93 | SiteB: 100, 94 | 95 | }, { 96 | period: '2012', 97 | SiteA: 120, 98 | SiteB: 60, 99 | 100 | }, { 101 | period: '2013', 102 | SiteA: 70, 103 | SiteB: 200, 104 | 105 | }, { 106 | period: '2014', 107 | SiteA: 180, 108 | SiteB: 150, 109 | 110 | }, { 111 | period: '2015', 112 | SiteA: 105, 113 | SiteB: 90, 114 | 115 | }, 116 | { 117 | period: '2016', 118 | SiteA: 250, 119 | SiteB: 150, 120 | 121 | }], 122 | xkey: 'period', 123 | ykeys: ['SiteA', 'SiteB'], 124 | labels: ['Site A', 'Site B'], 125 | 126 | pointSize: 0, 127 | fillOpacity: 0.4, 128 | pointStrokeColors:['#b4becb', '#01c0c8'], 129 | behaveLikeLine: true, 130 | gridLineColor: '#e0e0e0', 131 | lineWidth: 0, 132 | smooth: false, 133 | hideHover: 'auto', 134 | lineColors: ['#b4becb', '#01c0c8'], 135 | resize: true 136 | 137 | }); 138 | $(document).ready(function() { 139 | 140 | var sparklineLogin = function() { 141 | $('#sales1').sparkline([20, 40, 30], { 142 | type: 'pie', 143 | height: '100', 144 | resize: true, 145 | sliceColors: ['#808f8f', '#fecd36', '#f1f2f7'] 146 | }); 147 | $('#sales2').sparkline([6, 10, 9, 11, 9, 10, 12], { 148 | type: 'bar', 149 | height: '154', 150 | barWidth: '4', 151 | resize: true, 152 | barSpacing: '10', 153 | barColor: '#25a6f7' 154 | }); 155 | 156 | } 157 | var sparkResize; 158 | 159 | $(window).resize(function(e) { 160 | clearTimeout(sparkResize); 161 | sparkResize = setTimeout(sparklineLogin, 500); 162 | }); 163 | sparklineLogin(); 164 | 165 | }); 166 | 167 | -------------------------------------------------------------------------------- /rbac/static/assets/js/functions.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | (function() { 4 | "use strict"; 5 | 6 | // custom scrollbar 7 | 8 | $(".left-side").niceScroll({styler:"fb",cursorcolor:"#ccc", cursorwidth: '5', cursorborderradius: '0px', background: '#ccc', spacebarenabled:false, cursorborder: '2'}); 9 | 10 | 11 | $(".left-side").getNiceScroll(); 12 | if ($('body').hasClass('left-side-collapsed')) { 13 | $(".left-side").getNiceScroll().hide(); 14 | } 15 | 16 | 17 | 18 | // Toggle Left Menu 19 | jQuery('.menu-list > a').click(function() { 20 | 21 | var parent = jQuery(this).parent(); 22 | var sub = parent.find('> ul'); 23 | 24 | if(!jQuery('body').hasClass('left-side-collapsed')) { 25 | if(sub.is(':visible')) { 26 | sub.slideUp(200, function(){ 27 | parent.removeClass('nav-active'); 28 | jQuery('.main-content').css({height: ''}); 29 | mainContentHeightAdjust(); 30 | }); 31 | } else { 32 | visibleSubMenuClose(); 33 | parent.addClass('nav-active'); 34 | sub.slideDown(200, function(){ 35 | mainContentHeightAdjust(); 36 | }); 37 | } 38 | } 39 | return false; 40 | }); 41 | 42 | function visibleSubMenuClose() { 43 | jQuery('.menu-list').each(function() { 44 | var t = jQuery(this); 45 | if(t.hasClass('nav-active')) { 46 | t.find('> ul').slideUp(200, function(){ 47 | t.removeClass('nav-active'); 48 | }); 49 | } 50 | }); 51 | } 52 | 53 | function mainContentHeightAdjust() { 54 | // Adjust main content height 55 | var docHeight = jQuery(document).height(); 56 | if(docHeight > jQuery('.main-content').height()) 57 | jQuery('.main-content').height(docHeight); 58 | } 59 | 60 | // class add mouse hover 61 | jQuery('.custom-nav > li').hover(function(){ 62 | jQuery(this).addClass('nav-hover'); 63 | }, function(){ 64 | jQuery(this).removeClass('nav-hover'); 65 | }); 66 | 67 | 68 | // Menu Toggle 69 | jQuery('.toggle-btn').click(function(){ 70 | $(".left-side").getNiceScroll().hide(); 71 | 72 | if ($('body').hasClass('left-side-collapsed')) { 73 | $(".left-side").getNiceScroll().hide(); 74 | } 75 | var body = jQuery('body'); 76 | var bodyposition = body.css('position'); 77 | 78 | if(bodyposition != 'relative') { 79 | 80 | if(!body.hasClass('left-side-collapsed')) { 81 | body.addClass('left-side-collapsed'); 82 | jQuery('.custom-nav ul').attr('style',''); 83 | 84 | jQuery(this).addClass('menu-collapsed'); 85 | 86 | } else { 87 | body.removeClass('left-side-collapsed chat-view'); 88 | jQuery('.custom-nav li.active ul').css({display: 'block'}); 89 | 90 | jQuery(this).removeClass('menu-collapsed'); 91 | 92 | } 93 | } else { 94 | 95 | if(body.hasClass('left-side-show')) 96 | body.removeClass('left-side-show'); 97 | else 98 | body.addClass('left-side-show'); 99 | 100 | mainContentHeightAdjust(); 101 | } 102 | 103 | }); 104 | 105 | 106 | /*searchform_reposition();*/ 107 | 108 | jQuery(window).resize(function(){ 109 | 110 | if(jQuery('body').css('position') == 'relative') { 111 | 112 | jQuery('body').removeClass('left-side-collapsed'); 113 | 114 | } else { 115 | 116 | jQuery('body').css({left: '', marginRight: ''}); 117 | } 118 | 119 | 120 | }); 121 | 122 | 123 | 124 | })(jQuery); 125 | 126 | 127 | 128 | 129 | 130 | $(function(){ 131 | $('.notification-scroll-list').slimScroll({ 132 | height: '220px', 133 | allowPageScroll: true, 134 | alwaysVisible: true 135 | }); 136 | }); 137 | 138 | 139 | 140 | $(function(){ 141 | $('.message-scroll-list').slimScroll({ 142 | height: '220px', 143 | allowPageScroll: true, 144 | alwaysVisible: true 145 | }); 146 | }); 147 | 148 | 149 | 150 | $(".inbox-scroll-list").niceScroll({styler:"fb",cursorcolor:"#ccc", cursorwidth: '5', cursorborderradius: '0px', background: '#ccc', spacebarenabled:false, cursorborder: '2'}); 151 | 152 | 153 | $(".chat-scroll-list").niceScroll({styler:"fb",cursorcolor:"#ccc", cursorwidth: '5', cursorborderradius: '0px', background: '#ccc', spacebarenabled:false, cursorborder: '2'}); 154 | 155 | 156 | //tooltip 157 | $(function() { 158 | $('[data-toggle="tooltip"]').tooltip() 159 | }) 160 | 161 | // Initialize Popovers 162 | jQuery('[data-toggle="popover"], .js-popover').popover({ 163 | container: 'body', 164 | animation: true, 165 | trigger: 'hover' 166 | }); 167 | 168 | 169 | 170 | $(document).ready(function () { 171 | function setHeight() { 172 | windowHeight = $(window).innerHeight()-100; 173 | $('.wrapper').css('min-height', windowHeight); 174 | }; 175 | setHeight(); 176 | 177 | $(window).resize(function () { 178 | setHeight(); 179 | }); 180 | }); 181 | -------------------------------------------------------------------------------- /rbac/static/assets/pages/notifications.js: -------------------------------------------------------------------------------- 1 | 2 | $(document).ready(function() { 3 | "use strict"; 4 | 5 | 6 | $('.notification-info').on('click',function(e){ 7 | $.toast().reset('all'); 8 | $("body").removeAttr('class'); 9 | $.toast({ 10 | heading: 'simply dummy text', 11 | text: 'Lorem Ipsum is simply dummy text of the printing and typesetting ', 12 | position: 'top-right', 13 | loaderBg:'#FFBD4A', 14 | icon: 'info', 15 | hideAfter: 3000, 16 | stack: 6 17 | }); 18 | return false; 19 | }); 20 | 21 | $('.notification-warning').on('click',function(e){ 22 | $.toast().reset('all'); 23 | $("body").removeAttr('class'); 24 | $.toast({ 25 | heading: 'simply dummy text', 26 | text: 'Lorem Ipsum is simply dummy text of the printing and typesetting ', 27 | position: 'top-right', 28 | loaderBg:'#FFBD4A', 29 | icon: 'warning', 30 | hideAfter: 3500, 31 | stack: 6 32 | }); 33 | return false; 34 | }); 35 | 36 | // $('.notification-success').on('click',function(e){ 37 | // $.toast().reset('all'); 38 | // $("body").removeAttr('class'); 39 | // $.toast({ 40 | // heading: '操作执行成功', 41 | // // text: 'Lorem Ipsum is simply dummy text of the printing and typesetting ', 42 | // position: 'top-right', 43 | // loaderBg:'#FFBD4A', 44 | // icon: 'success', 45 | // hideAfter: 3500, 46 | // stack: 6 47 | // }); 48 | // return false; 49 | // }); 50 | 51 | $('.notification-danger').on('click',function(e){ 52 | $.toast().reset('all'); 53 | $("body").removeAttr('class'); 54 | $.toast({ 55 | heading: 'simply dummy text', 56 | text: 'Lorem Ipsum is simply dummy text of the printing and typesetting ', 57 | position: 'top-right', 58 | loaderBg:'#FFBD4A', 59 | icon: 'error', 60 | hideAfter: 3500 61 | }); 62 | return false; 63 | }); 64 | 65 | $('.notification-tleft').on('click',function(e){ 66 | $.toast().reset('all'); 67 | $("body").removeAttr('class'); 68 | $.toast({ 69 | heading: 'top left', 70 | text: 'Lorem Ipsum is simply dummy text of the printing and typesetting ', 71 | position: 'top-left', 72 | loaderBg:'#FFBD4A', 73 | icon: 'error', 74 | hideAfter: 3500 75 | }); 76 | return false; 77 | }); 78 | 79 | $('.notification-tright').on('click',function(e){ 80 | $.toast().reset('all'); 81 | $("body").removeAttr('class'); 82 | $.toast({ 83 | heading: 'top right', 84 | text: 'Lorem Ipsum is simply dummy text of the printing and typesetting ', 85 | position: 'top-right', 86 | loaderBg:'#FFBD4A', 87 | icon: 'error', 88 | hideAfter: 3500 89 | }); 90 | return false; 91 | }); 92 | 93 | $('.notification-bleft').on('click',function(e){ 94 | $.toast().reset('all'); 95 | $("body").removeAttr('class'); 96 | $.toast({ 97 | heading: 'bottom left', 98 | text: 'Lorem Ipsum is simply dummy text of the printing and typesetting ', 99 | position: 'bottom-left', 100 | loaderBg:'#FFBD4A', 101 | icon: 'error', 102 | hideAfter: 3500 103 | }); 104 | return false; 105 | }); 106 | 107 | $('.notification-bright').on('click',function(e){ 108 | $.toast().reset('all'); 109 | $("body").removeAttr('class'); 110 | $.toast({ 111 | heading: 'bottom right', 112 | text: 'Lorem Ipsum is simply dummy text of the printing and typesetting ', 113 | position: 'bottom-right', 114 | loaderBg:'#FFBD4A', 115 | icon: 'error', 116 | hideAfter: 3500 117 | }); 118 | return false; 119 | }); 120 | 121 | $('.notification-tfull').on('click',function(e){ 122 | $.toast().reset('all'); 123 | $("body").removeAttr('class').removeClass("bottom-center-fullwidth").addClass("top-center-fullwidth"); 124 | $.toast({ 125 | heading: 'top center', 126 | text: 'Lorem Ipsum is simply dummy text of the printing and typesetting ', 127 | position: 'top-center', 128 | loaderBg:'#FFBD4A', 129 | icon: 'error', 130 | hideAfter: 3500 131 | }); 132 | return false; 133 | }); 134 | 135 | $('.notification-btfull').on('click',function(e){ 136 | $.toast().reset('all'); 137 | $("body").removeAttr('class').addClass("bottom-center-fullwidth"); 138 | $.toast({ 139 | heading: 'bottom right', 140 | text: 'Lorem Ipsum is simply dummy text of the printing and typesetting ', 141 | position: 'bottom-center', 142 | loaderBg:'#FFBD4A', 143 | icon: 'error', 144 | hideAfter: 3500 145 | }); 146 | return false; 147 | }); 148 | }); 149 | 150 | -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-multi-select/js/jquery.quicksearch.js: -------------------------------------------------------------------------------- 1 | (function($, window, document, undefined) { 2 | $.fn.quicksearch = function (target, opt) { 3 | 4 | var timeout, cache, rowcache, jq_results, val = '', e = this, options = $.extend({ 5 | delay: 100, 6 | selector: null, 7 | stripeRows: null, 8 | loader: null, 9 | noResults: '', 10 | matchedResultsCount: 0, 11 | bind: 'keyup', 12 | onBefore: function () { 13 | return; 14 | }, 15 | onAfter: function () { 16 | return; 17 | }, 18 | show: function () { 19 | this.style.display = ""; 20 | }, 21 | hide: function () { 22 | this.style.display = "none"; 23 | }, 24 | prepareQuery: function (val) { 25 | return val.toLowerCase().split(' '); 26 | }, 27 | testQuery: function (query, txt, _row) { 28 | for (var i = 0; i < query.length; i += 1) { 29 | if (txt.indexOf(query[i]) === -1) { 30 | return false; 31 | } 32 | } 33 | return true; 34 | } 35 | }, opt); 36 | 37 | this.go = function () { 38 | 39 | var i = 0, 40 | numMatchedRows = 0, 41 | noresults = true, 42 | query = options.prepareQuery(val), 43 | val_empty = (val.replace(' ', '').length === 0); 44 | 45 | for (var i = 0, len = rowcache.length; i < len; i++) { 46 | if (val_empty || options.testQuery(query, cache[i], rowcache[i])) { 47 | options.show.apply(rowcache[i]); 48 | noresults = false; 49 | numMatchedRows++; 50 | } else { 51 | options.hide.apply(rowcache[i]); 52 | } 53 | } 54 | 55 | if (noresults) { 56 | this.results(false); 57 | } else { 58 | this.results(true); 59 | this.stripe(); 60 | } 61 | 62 | this.matchedResultsCount = numMatchedRows; 63 | this.loader(false); 64 | options.onAfter(); 65 | 66 | return this; 67 | }; 68 | 69 | /* 70 | * External API so that users can perform search programatically. 71 | * */ 72 | this.search = function (submittedVal) { 73 | val = submittedVal; 74 | e.trigger(); 75 | }; 76 | 77 | /* 78 | * External API to get the number of matched results as seen in 79 | * https://github.com/ruiz107/quicksearch/commit/f78dc440b42d95ce9caed1d087174dd4359982d6 80 | * */ 81 | this.currentMatchedResults = function() { 82 | return this.matchedResultsCount; 83 | }; 84 | 85 | this.stripe = function () { 86 | 87 | if (typeof options.stripeRows === "object" && options.stripeRows !== null) 88 | { 89 | var joined = options.stripeRows.join(' '); 90 | var stripeRows_length = options.stripeRows.length; 91 | 92 | jq_results.not(':hidden').each(function (i) { 93 | $(this).removeClass(joined).addClass(options.stripeRows[i % stripeRows_length]); 94 | }); 95 | } 96 | 97 | return this; 98 | }; 99 | 100 | this.strip_html = function (input) { 101 | var output = input.replace(new RegExp('<[^<]+\>', 'g'), ""); 102 | output = $.trim(output.toLowerCase()); 103 | return output; 104 | }; 105 | 106 | this.results = function (bool) { 107 | if (typeof options.noResults === "string" && options.noResults !== "") { 108 | if (bool) { 109 | $(options.noResults).hide(); 110 | } else { 111 | $(options.noResults).show(); 112 | } 113 | } 114 | return this; 115 | }; 116 | 117 | this.loader = function (bool) { 118 | if (typeof options.loader === "string" && options.loader !== "") { 119 | (bool) ? $(options.loader).show() : $(options.loader).hide(); 120 | } 121 | return this; 122 | }; 123 | 124 | this.cache = function () { 125 | 126 | jq_results = $(target); 127 | 128 | if (typeof options.noResults === "string" && options.noResults !== "") { 129 | jq_results = jq_results.not(options.noResults); 130 | } 131 | 132 | var t = (typeof options.selector === "string") ? jq_results.find(options.selector) : $(target).not(options.noResults); 133 | cache = t.map(function () { 134 | return e.strip_html(this.innerHTML); 135 | }); 136 | 137 | rowcache = jq_results.map(function () { 138 | return this; 139 | }); 140 | 141 | /* 142 | * Modified fix for sync-ing "val". 143 | * Original fix https://github.com/michaellwest/quicksearch/commit/4ace4008d079298a01f97f885ba8fa956a9703d1 144 | * */ 145 | val = val || this.val() || ""; 146 | 147 | return this.go(); 148 | }; 149 | 150 | this.trigger = function () { 151 | this.loader(true); 152 | options.onBefore(); 153 | 154 | window.clearTimeout(timeout); 155 | timeout = window.setTimeout(function () { 156 | e.go(); 157 | }, options.delay); 158 | 159 | return this; 160 | }; 161 | 162 | this.cache(); 163 | this.results(true); 164 | this.stripe(); 165 | this.loader(false); 166 | 167 | return this.each(function () { 168 | 169 | /* 170 | * Changed from .bind to .on. 171 | * */ 172 | $(this).on(options.bind, function () { 173 | 174 | val = $(this).val(); 175 | e.trigger(); 176 | }); 177 | }); 178 | 179 | }; 180 | 181 | }(jQuery, this, document)); 182 | -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-quicksearch/jquery.quicksearch.js: -------------------------------------------------------------------------------- 1 | (function($, window, document, undefined) { 2 | $.fn.quicksearch = function (target, opt) { 3 | 4 | var timeout, cache, rowcache, jq_results, val = '', e = this, options = $.extend({ 5 | delay: 100, 6 | selector: null, 7 | stripeRows: null, 8 | loader: null, 9 | noResults: '', 10 | matchedResultsCount: 0, 11 | bind: 'keyup', 12 | onBefore: function () { 13 | return; 14 | }, 15 | onAfter: function () { 16 | return; 17 | }, 18 | show: function () { 19 | this.style.display = ""; 20 | }, 21 | hide: function () { 22 | this.style.display = "none"; 23 | }, 24 | prepareQuery: function (val) { 25 | return val.toLowerCase().split(' '); 26 | }, 27 | testQuery: function (query, txt, _row) { 28 | for (var i = 0; i < query.length; i += 1) { 29 | if (txt.indexOf(query[i]) === -1) { 30 | return false; 31 | } 32 | } 33 | return true; 34 | } 35 | }, opt); 36 | 37 | this.go = function () { 38 | 39 | var i = 0, 40 | numMatchedRows = 0, 41 | noresults = true, 42 | query = options.prepareQuery(val), 43 | val_empty = (val.replace(' ', '').length === 0); 44 | 45 | for (var i = 0, len = rowcache.length; i < len; i++) { 46 | if (val_empty || options.testQuery(query, cache[i], rowcache[i])) { 47 | options.show.apply(rowcache[i]); 48 | noresults = false; 49 | numMatchedRows++; 50 | } else { 51 | options.hide.apply(rowcache[i]); 52 | } 53 | } 54 | 55 | if (noresults) { 56 | this.results(false); 57 | } else { 58 | this.results(true); 59 | this.stripe(); 60 | } 61 | 62 | this.matchedResultsCount = numMatchedRows; 63 | this.loader(false); 64 | options.onAfter(); 65 | 66 | return this; 67 | }; 68 | 69 | /* 70 | * External API so that users can perform search programatically. 71 | * */ 72 | this.search = function (submittedVal) { 73 | val = submittedVal; 74 | e.trigger(); 75 | }; 76 | 77 | /* 78 | * External API to get the number of matched results as seen in 79 | * https://github.com/ruiz107/quicksearch/commit/f78dc440b42d95ce9caed1d087174dd4359982d6 80 | * */ 81 | this.currentMatchedResults = function() { 82 | return this.matchedResultsCount; 83 | }; 84 | 85 | this.stripe = function () { 86 | 87 | if (typeof options.stripeRows === "object" && options.stripeRows !== null) 88 | { 89 | var joined = options.stripeRows.join(' '); 90 | var stripeRows_length = options.stripeRows.length; 91 | 92 | jq_results.not(':hidden').each(function (i) { 93 | $(this).removeClass(joined).addClass(options.stripeRows[i % stripeRows_length]); 94 | }); 95 | } 96 | 97 | return this; 98 | }; 99 | 100 | this.strip_html = function (input) { 101 | var output = input.replace(new RegExp('<[^<]+\>', 'g'), ""); 102 | output = $.trim(output.toLowerCase()); 103 | return output; 104 | }; 105 | 106 | this.results = function (bool) { 107 | if (typeof options.noResults === "string" && options.noResults !== "") { 108 | if (bool) { 109 | $(options.noResults).hide(); 110 | } else { 111 | $(options.noResults).show(); 112 | } 113 | } 114 | return this; 115 | }; 116 | 117 | this.loader = function (bool) { 118 | if (typeof options.loader === "string" && options.loader !== "") { 119 | (bool) ? $(options.loader).show() : $(options.loader).hide(); 120 | } 121 | return this; 122 | }; 123 | 124 | this.cache = function () { 125 | 126 | jq_results = $(target); 127 | 128 | if (typeof options.noResults === "string" && options.noResults !== "") { 129 | jq_results = jq_results.not(options.noResults); 130 | } 131 | 132 | var t = (typeof options.selector === "string") ? jq_results.find(options.selector) : $(target).not(options.noResults); 133 | cache = t.map(function () { 134 | return e.strip_html(this.innerHTML); 135 | }); 136 | 137 | rowcache = jq_results.map(function () { 138 | return this; 139 | }); 140 | 141 | /* 142 | * Modified fix for sync-ing "val". 143 | * Original fix https://github.com/michaellwest/quicksearch/commit/4ace4008d079298a01f97f885ba8fa956a9703d1 144 | * */ 145 | val = val || this.val() || ""; 146 | 147 | return this.go(); 148 | }; 149 | 150 | this.trigger = function () { 151 | this.loader(true); 152 | options.onBefore(); 153 | 154 | window.clearTimeout(timeout); 155 | timeout = window.setTimeout(function () { 156 | e.go(); 157 | }, options.delay); 158 | 159 | return this; 160 | }; 161 | 162 | this.cache(); 163 | this.results(true); 164 | this.stripe(); 165 | this.loader(false); 166 | 167 | return this.each(function () { 168 | 169 | /* 170 | * Changed from .bind to .on. 171 | * */ 172 | $(this).on(options.bind, function () { 173 | 174 | val = $(this).val(); 175 | e.trigger(); 176 | }); 177 | }); 178 | 179 | }; 180 | 181 | }(jQuery, this, document)); 182 | -------------------------------------------------------------------------------- /rbac/static/assets/pages/toast-custom.js: -------------------------------------------------------------------------------- 1 | /*Toast Init*/ 2 | 3 | 4 | $(document).ready(function() { 5 | "use strict"; 6 | 7 | $.toast({ 8 | heading: 'Welcome to kenny', 9 | text: 'Use the predefined ones, or specify a custom position object.', 10 | position: 'top-right', 11 | loaderBg:'#3cb878', 12 | icon: 'error', 13 | hideAfter: 3000, 14 | stack: 6 15 | }); 16 | 17 | $('.tst1').on('click',function(e){ 18 | $.toast().reset('all'); 19 | $("body").removeAttr('class'); 20 | $.toast({ 21 | heading: 'Welcome to kenny', 22 | text: 'Use the predefined ones, or specify a custom position object.', 23 | position: 'top-right', 24 | loaderBg:'#3cb878', 25 | icon: 'info', 26 | hideAfter: 3000, 27 | stack: 6 28 | }); 29 | return false; 30 | }); 31 | 32 | $('.tst2').on('click',function(e){ 33 | $.toast().reset('all'); 34 | $("body").removeAttr('class'); 35 | $.toast({ 36 | heading: 'Welcome to kenny', 37 | text: 'Use the predefined ones, or specify a custom position object.', 38 | position: 'top-right', 39 | loaderBg:'#3cb878', 40 | icon: 'warning', 41 | hideAfter: 3500, 42 | stack: 6 43 | }); 44 | return false; 45 | }); 46 | 47 | $('.tst3').on('click',function(e){ 48 | $.toast().reset('all'); 49 | $("body").removeAttr('class'); 50 | $.toast({ 51 | heading: 'Welcome to kenny', 52 | text: 'Use the predefined ones, or specify a custom position object.', 53 | position: 'top-right', 54 | loaderBg:'#3cb878', 55 | icon: 'success', 56 | hideAfter: 3500, 57 | stack: 6 58 | }); 59 | return false; 60 | }); 61 | 62 | $('.tst4').on('click',function(e){ 63 | $.toast().reset('all'); 64 | $("body").removeAttr('class'); 65 | $.toast({ 66 | heading: 'Welcome to kenny', 67 | text: 'Use the predefined ones, or specify a custom position object.', 68 | position: 'top-right', 69 | loaderBg:'#3cb878', 70 | icon: 'error', 71 | hideAfter: 3500 72 | }); 73 | return false; 74 | }); 75 | 76 | $('.tst5').on('click',function(e){ 77 | $.toast().reset('all'); 78 | $("body").removeAttr('class'); 79 | $.toast({ 80 | heading: 'top left', 81 | text: 'Use the predefined ones, or specify a custom position object.', 82 | position: 'top-left', 83 | loaderBg:'#3cb878', 84 | icon: 'error', 85 | hideAfter: 3500 86 | }); 87 | return false; 88 | }); 89 | 90 | $('.tst6').on('click',function(e){ 91 | $.toast().reset('all'); 92 | $("body").removeAttr('class'); 93 | $.toast({ 94 | heading: 'top right', 95 | text: 'Use the predefined ones, or specify a custom position object.', 96 | position: 'top-right', 97 | loaderBg:'#3cb878', 98 | icon: 'error', 99 | hideAfter: 3500 100 | }); 101 | return false; 102 | }); 103 | 104 | $('.tst7').on('click',function(e){ 105 | $.toast().reset('all'); 106 | $("body").removeAttr('class'); 107 | $.toast({ 108 | heading: 'bottom left', 109 | text: 'Use the predefined ones, or specify a custom position object.', 110 | position: 'bottom-left', 111 | loaderBg:'#3cb878', 112 | icon: 'error', 113 | hideAfter: 3500 114 | }); 115 | return false; 116 | }); 117 | 118 | $('.tst8').on('click',function(e){ 119 | $.toast().reset('all'); 120 | $("body").removeAttr('class'); 121 | $.toast({ 122 | heading: 'bottom right', 123 | text: 'Use the predefined ones, or specify a custom position object.', 124 | position: 'bottom-right', 125 | loaderBg:'#3cb878', 126 | icon: 'error', 127 | hideAfter: 3500 128 | }); 129 | return false; 130 | }); 131 | 132 | $('.tst9').on('click',function(e){ 133 | $.toast().reset('all'); 134 | $("body").removeAttr('class').removeClass("bottom-center-fullwidth").addClass("top-center-fullwidth"); 135 | $.toast({ 136 | heading: 'top center', 137 | text: 'Use the predefined ones, or specify a custom position object.', 138 | position: 'top-center', 139 | loaderBg:'#3cb878', 140 | icon: 'error', 141 | hideAfter: 3500 142 | }); 143 | return false; 144 | }); 145 | 146 | $('.tst10').on('click',function(e){ 147 | $.toast().reset('all'); 148 | $("body").removeAttr('class').addClass("bottom-center-fullwidth"); 149 | $.toast({ 150 | heading: 'bottom right', 151 | text: 'Use the predefined ones, or specify a custom position object.', 152 | position: 'bottom-center', 153 | loaderBg:'#3cb878', 154 | icon: 'error', 155 | hideAfter: 3500 156 | }); 157 | return false; 158 | }); 159 | }); 160 | 161 | -------------------------------------------------------------------------------- /rbac/static/assets/plugins/bootstrap-inputmask/bootstrap-inputmask.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Bootstrap.js by @mdo and @fat, extended by @ArnoldDaniels. 3 | * plugins: bootstrap-inputmask.js 4 | * Copyright 2012 Twitter, Inc. 5 | * http://www.apache.org/licenses/LICENSE-2.0.txt 6 | */ 7 | !function(e){var t=window.orientation!==undefined,n=navigator.userAgent.toLowerCase().indexOf("android")>-1,r=function(t,r){if(n)return;this.$element=e(t),this.options=e.extend({},e.fn.inputmask.defaults,r),this.mask=String(r.mask),this.init(),this.listen(),this.checkVal()};r.prototype={init:function(){var t=this.options.definitions,n=this.mask.length;this.tests=[],this.partialPosition=this.mask.length,this.firstNonMaskPos=null,e.each(this.mask.split(""),e.proxy(function(e,r){r=="?"?(n--,this.partialPosition=e):t[r]?(this.tests.push(new RegExp(t[r])),this.firstNonMaskPos===null&&(this.firstNonMaskPos=this.tests.length-1)):this.tests.push(null)},this)),this.buffer=e.map(this.mask.split(""),e.proxy(function(e,n){if(e!="?")return t[e]?this.options.placeholder:e},this)),this.focusText=this.$element.val(),this.$element.data("rawMaskFn",e.proxy(function(){return e.map(this.buffer,function(e,t){return this.tests[t]&&e!=this.options.placeholder?e:null}).join("")},this))},listen:function(){if(this.$element.attr("readonly"))return;var t=(navigator.userAgent.match(/msie/i)?"paste":"input")+".mask";this.$element.on("unmask",e.proxy(this.unmask,this)).on("focus.mask",e.proxy(this.focusEvent,this)).on("blur.mask",e.proxy(this.blurEvent,this)).on("keydown.mask",e.proxy(this.keydownEvent,this)).on("keypress.mask",e.proxy(this.keypressEvent,this)).on(t,e.proxy(this.pasteEvent,this))},caret:function(e,t){if(this.$element.length===0)return;if(typeof e=="number")return t=typeof t=="number"?t:e,this.$element.each(function(){if(this.setSelectionRange)this.setSelectionRange(e,t);else if(this.createTextRange){var n=this.createTextRange();n.collapse(!0),n.moveEnd("character",t),n.moveStart("character",e),n.select()}});if(this.$element[0].setSelectionRange)e=this.$element[0].selectionStart,t=this.$element[0].selectionEnd;else if(document.selection&&document.selection.createRange){var n=document.selection.createRange();e=0-n.duplicate().moveStart("character",-1e5),t=e+n.text.length}return{begin:e,end:t}},seekNext:function(e){var t=this.mask.length;while(++e<=t&&!this.tests[e]);return e},seekPrev:function(e){while(--e>=0&&!this.tests[e]);return e},shiftL:function(e,t){var n=this.mask.length;if(e<0)return;for(var r=e,i=this.seekNext(t);rn.length)break}else this.buffer[i]==n.charAt(s)&&i!=this.partialPosition&&(s++,r=i);if(!e&&r+1=this.partialPosition)this.writeBuffer(),e||this.$element.val(this.$element.val().substring(0,r+1));return this.partialPosition?i:this.firstNonMaskPos}},e.fn.inputmask=function(t){return this.each(function(){var n=e(this),i=n.data("inputmask");i||n.data("inputmask",i=new r(this,t))})},e.fn.inputmask.defaults={mask:"",placeholder:"_",definitions:{9:"[0-9]",a:"[A-Za-z]","?":"[A-Za-z0-9]","*":"."}},e.fn.inputmask.Constructor=r,e(document).on("focus.inputmask.data-api","[data-mask]",function(t){var n=e(this);if(n.data("inputmask"))return;t.preventDefault(),n.inputmask(n.data())})}(window.jQuery) -------------------------------------------------------------------------------- /rbac/static/assets/plugins/jquery-toast/jquery.toast.min.css: -------------------------------------------------------------------------------- 1 | .jq-toast-wrap, .jq-toast-wrap * { 2 | margin:0; 3 | padding:0 4 | } 5 | .jq-toast-wrap { 6 | display:block; 7 | position:fixed; 8 | width:250px; 9 | pointer-events:none!important; 10 | letter-spacing:normal; 11 | z-index:9000!important 12 | } 13 | .jq-toast-wrap.bottom-left { 14 | bottom:20px; 15 | left:20px 16 | } 17 | .jq-toast-wrap.bottom-right { 18 | bottom:20px; 19 | right:40px 20 | } 21 | .jq-toast-wrap.top-left { 22 | top:20px; 23 | left:20px 24 | } 25 | .jq-toast-wrap.top-right { 26 | top:20px; 27 | right:40px 28 | } 29 | .jq-toast-single { 30 | display:block; 31 | width:100% !important; 32 | padding:10px; 33 | margin:0 0 5px; 34 | border-radius:4px; 35 | font-size:12px; 36 | font-family:arial, sans-serif; 37 | line-height:17px; 38 | position:relative; 39 | pointer-events:all!important; 40 | background-color:#444; 41 | color:#fff 42 | } 43 | .jq-toast-single h2 { 44 | font-family:arial, sans-serif; 45 | font-size:14px; 46 | margin:0 0 7px; 47 | background:0 0; 48 | color:inherit; 49 | line-height:inherit; 50 | letter-spacing:normal 51 | } 52 | .jq-toast-single a { 53 | color:#eee; 54 | text-decoration:none; 55 | font-weight:700; 56 | border-bottom:1px solid #fff; 57 | padding-bottom:3px; 58 | font-size:12px 59 | } 60 | .jq-toast-single ul { 61 | margin:0 0 0 15px; 62 | background:0 0; 63 | padding:0 64 | } 65 | .jq-toast-single ul li { 66 | list-style-type:disc!important; 67 | line-height:17px; 68 | background:0 0; 69 | margin:0; 70 | padding:0; 71 | letter-spacing:normal 72 | } 73 | .close-jq-toast-single { 74 | position:absolute; 75 | top:3px; 76 | right:7px; 77 | font-size:14px; 78 | cursor:pointer 79 | } 80 | .jq-toast-loader { 81 | display:block; 82 | position:absolute; 83 | top:-2px; 84 | height:5px; 85 | width:0; 86 | left:0; 87 | border-radius:5px; 88 | background:red 89 | } 90 | .jq-toast-loaded { 91 | width:100% 92 | } 93 | .jq-has-icon { 94 | padding:10px 10px 10px 50px; 95 | background-repeat:no-repeat; 96 | background-position:10px 97 | } 98 | .jq-icon-info { 99 | background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=); 100 | background-color:#34d3eb; 101 | color:#d9edf7; 102 | border-color:#34d3eb 103 | } 104 | .jq-icon-warning { 105 | background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=); 106 | background-color:#ffbd4a; 107 | color:#fcf8e3; 108 | border-color:#ffbd4a 109 | } 110 | .jq-icon-error { 111 | background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=); 112 | background-color:#f05050; 113 | color:#f2dede; 114 | border-color:#f05050 115 | } 116 | .jq-icon-success { 117 | background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==); 118 | color:#dff0d8; 119 | background-color:#81c868; 120 | border-color:#81c868 121 | } 122 | -------------------------------------------------------------------------------- /rbac/static/assets/plugins/inputmask/jasny-bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Jasny Bootstrap v3.1.0 (http://jasny.github.com/bootstrap) 3 | * Copyright 2011-2014 Arnold Daniels. 4 | * Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | +function(a){"use strict";var b=window.orientation!==undefined,c=navigator.userAgent.toLowerCase().indexOf("android")>-1,d=window.navigator.appName=="Microsoft Internet Explorer",e=function(b,d){if(c)return;this.$element=a(b),this.options=a.extend({},e.DEFAULTS,d),this.mask=String(this.options.mask),this.init(),this.listen(),this.checkVal()};e.DEFAULTS={mask:"",placeholder:"_",definitions:{9:"[0-9]",a:"[A-Za-z]",w:"[A-Za-z0-9]","*":"."}},e.prototype.init=function(){var b=this.options.definitions,c=this.mask.length;this.tests=[],this.partialPosition=this.mask.length,this.firstNonMaskPos=null,a.each(this.mask.split(""),a.proxy(function(a,d){d=="?"?(c--,this.partialPosition=a):b[d]?(this.tests.push(new RegExp(b[d])),this.firstNonMaskPos===null&&(this.firstNonMaskPos=this.tests.length-1)):this.tests.push(null)},this)),this.buffer=a.map(this.mask.split(""),a.proxy(function(a,c){if(a!="?")return b[a]?this.options.placeholder:a},this)),this.focusText=this.$element.val(),this.$element.data("rawMaskFn",a.proxy(function(){return a.map(this.buffer,function(a,b){return this.tests[b]&&a!=this.options.placeholder?a:null}).join("")},this))},e.prototype.listen=function(){if(this.$element.attr("readonly"))return;var b=(d?"paste":"input")+".bs.inputmask";this.$element.on("unmask.bs.inputmask",a.proxy(this.unmask,this)).on("focus.bs.inputmask",a.proxy(this.focusEvent,this)).on("blur.bs.inputmask",a.proxy(this.blurEvent,this)).on("keydown.bs.inputmask",a.proxy(this.keydownEvent,this)).on("keypress.bs.inputmask",a.proxy(this.keypressEvent,this)).on(b,a.proxy(this.pasteEvent,this))},e.prototype.caret=function(a,b){if(this.$element.length===0)return;if(typeof a=="number")return b=typeof b=="number"?b:a,this.$element.each(function(){if(this.setSelectionRange)this.setSelectionRange(a,b);else if(this.createTextRange){var c=this.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",a),c.select()}});if(this.$element[0].setSelectionRange)a=this.$element[0].selectionStart,b=this.$element[0].selectionEnd;else if(document.selection&&document.selection.createRange){var c=document.selection.createRange();a=0-c.duplicate().moveStart("character",-1e5),b=a+c.text.length}return{begin:a,end:b}},e.prototype.seekNext=function(a){var b=this.mask.length;while(++a<=b&&!this.tests[a]);return a},e.prototype.seekPrev=function(a){while(--a>=0&&!this.tests[a]);return a},e.prototype.shiftL=function(a,b){var c=this.mask.length;if(a<0)return;for(var d=a,e=this.seekNext(b);dc.length)break}else this.buffer[e]==c.charAt(f)&&e!=this.partialPosition&&(f++,d=e);if(!a&&d+1=this.partialPosition)this.writeBuffer(),a||this.$element.val(this.$element.val().substring(0,d+1));return this.partialPosition?e:this.firstNonMaskPos};var f=a.fn.inputmask;a.fn.inputmask=function(b){return this.each(function(){var c=a(this),d=c.data("bs.inputmask");d||c.data("bs.inputmask",d=new e(this,b))})},a.fn.inputmask.Constructor=e,a.fn.inputmask.noConflict=function(){return a.fn.inputmask=f,this},a(document).on("focus.bs.inputmask.data-api","[data-mask]",function(b){var c=a(this);if(c.data("bs.inputmask"))return;c.inputmask(c.data())})}(window.jQuery) -------------------------------------------------------------------------------- /rbac/templates/rbac/multi_permissions.html: -------------------------------------------------------------------------------- 1 | {% extends 'layout_plus.html' %} 2 | {% block content %} 3 |
4 | 5 |
6 | {% csrf_token %} 7 | {{ generate_formset.management_form }} 8 |
9 | 10 |
11 | 待新建权限列表 12 | 17 |
18 |
19 | 注意:路由系统中自动发现且数据库中不存在的路由。 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | {% for form in generate_formset %} 35 | 36 | 37 | {% for field in form %} 38 | 39 | {% endfor %} 40 | 41 | {% endfor %} 42 | 43 | 44 |
序号名称URL别名菜单父权限
{{ forloop.counter }}{{ field }}{{ field.errors.0 }}
45 |
46 |
47 | 48 |
49 | 50 |
51 | 已失效的URL权限列表 52 |
53 |
54 | 注意:数据库中存在,但路由系统中不存在的路由。 55 |
56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | {% for row in delete_row_list %} 69 | 70 | 71 | 72 | 73 | 74 | 79 | 80 | {% endfor %} 81 | 82 | 83 |
序号名称URL别名删除
{{ forloop.counter }}{{ row.title }}{{ row.url }}{{ row.name }} 75 | 76 | 77 | 78 |
84 |
85 | 86 |
{# 根据URLtype的不同用于区别同一个页面不同的post请求 #} 87 | {% csrf_token %} 88 | {{ update_formset.management_form }}{# 使用formset必须引入formset名.management_form #} 89 |
90 | 91 |
92 | 待更新权限列表 93 | 98 |
99 |
100 | 注意:数据库和路由系统都存在的路由。 101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | {% for form in update_formset %} 116 | 117 | 118 | {% for field in form %} 119 | {% if forloop.first %}{# 如果是第一个字段(ID) #} 120 | {{ field }}{# 直接生成该input type=hidden 隐藏起来,有了id就能在修改页面找到对应id进行修改 #} 121 | {% else %} 122 | 123 | {% endif %} 124 | {% endfor %} 125 | 126 | {% endfor %} 127 | 128 | 129 |
序号名称URL别名菜单父权限
{{ forloop.counter }}{{ field }}{{ field.errors.0 }}
130 |
131 |
132 |
133 | 134 | {% endblock %} 135 | -------------------------------------------------------------------------------- /rbac/static/assets/plugins/flot-chart/jquery.flot.crosshair.js: -------------------------------------------------------------------------------- 1 | /* Flot plugin for showing crosshairs when the mouse hovers over the plot. 2 | 3 | Copyright (c) 2007-2014 IOLA and Ole Laursen. 4 | Licensed under the MIT license. 5 | 6 | The plugin supports these options: 7 | 8 | crosshair: { 9 | mode: null or "x" or "y" or "xy" 10 | color: color 11 | lineWidth: number 12 | } 13 | 14 | Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical 15 | crosshair that lets you trace the values on the x axis, "y" enables a 16 | horizontal crosshair and "xy" enables them both. "color" is the color of the 17 | crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of 18 | the drawn lines (default is 1). 19 | 20 | The plugin also adds four public methods: 21 | 22 | - setCrosshair( pos ) 23 | 24 | Set the position of the crosshair. Note that this is cleared if the user 25 | moves the mouse. "pos" is in coordinates of the plot and should be on the 26 | form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple 27 | axes), which is coincidentally the same format as what you get from a 28 | "plothover" event. If "pos" is null, the crosshair is cleared. 29 | 30 | - clearCrosshair() 31 | 32 | Clear the crosshair. 33 | 34 | - lockCrosshair(pos) 35 | 36 | Cause the crosshair to lock to the current location, no longer updating if 37 | the user moves the mouse. Optionally supply a position (passed on to 38 | setCrosshair()) to move it to. 39 | 40 | Example usage: 41 | 42 | var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } }; 43 | $("#graph").bind( "plothover", function ( evt, position, item ) { 44 | if ( item ) { 45 | // Lock the crosshair to the data point being hovered 46 | myFlot.lockCrosshair({ 47 | x: item.datapoint[ 0 ], 48 | y: item.datapoint[ 1 ] 49 | }); 50 | } else { 51 | // Return normal crosshair operation 52 | myFlot.unlockCrosshair(); 53 | } 54 | }); 55 | 56 | - unlockCrosshair() 57 | 58 | Free the crosshair to move again after locking it. 59 | */ 60 | 61 | (function ($) { 62 | var options = { 63 | crosshair: { 64 | mode: null, // one of null, "x", "y" or "xy", 65 | color: "rgba(170, 0, 0, 0.80)", 66 | lineWidth: 1 67 | } 68 | }; 69 | 70 | function init(plot) { 71 | // position of crosshair in pixels 72 | var crosshair = { x: -1, y: -1, locked: false }; 73 | 74 | plot.setCrosshair = function setCrosshair(pos) { 75 | if (!pos) 76 | crosshair.x = -1; 77 | else { 78 | var o = plot.p2c(pos); 79 | crosshair.x = Math.max(0, Math.min(o.left, plot.width())); 80 | crosshair.y = Math.max(0, Math.min(o.top, plot.height())); 81 | } 82 | 83 | plot.triggerRedrawOverlay(); 84 | }; 85 | 86 | plot.clearCrosshair = plot.setCrosshair; // passes null for pos 87 | 88 | plot.lockCrosshair = function lockCrosshair(pos) { 89 | if (pos) 90 | plot.setCrosshair(pos); 91 | crosshair.locked = true; 92 | }; 93 | 94 | plot.unlockCrosshair = function unlockCrosshair() { 95 | crosshair.locked = false; 96 | }; 97 | 98 | function onMouseOut(e) { 99 | if (crosshair.locked) 100 | return; 101 | 102 | if (crosshair.x != -1) { 103 | crosshair.x = -1; 104 | plot.triggerRedrawOverlay(); 105 | } 106 | } 107 | 108 | function onMouseMove(e) { 109 | if (crosshair.locked) 110 | return; 111 | 112 | if (plot.getSelection && plot.getSelection()) { 113 | crosshair.x = -1; // hide the crosshair while selecting 114 | return; 115 | } 116 | 117 | var offset = plot.offset(); 118 | crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width())); 119 | crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height())); 120 | plot.triggerRedrawOverlay(); 121 | } 122 | 123 | plot.hooks.bindEvents.push(function (plot, eventHolder) { 124 | if (!plot.getOptions().crosshair.mode) 125 | return; 126 | 127 | eventHolder.mouseout(onMouseOut); 128 | eventHolder.mousemove(onMouseMove); 129 | }); 130 | 131 | plot.hooks.drawOverlay.push(function (plot, ctx) { 132 | var c = plot.getOptions().crosshair; 133 | if (!c.mode) 134 | return; 135 | 136 | var plotOffset = plot.getPlotOffset(); 137 | 138 | ctx.save(); 139 | ctx.translate(plotOffset.left, plotOffset.top); 140 | 141 | if (crosshair.x != -1) { 142 | var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0; 143 | 144 | ctx.strokeStyle = c.color; 145 | ctx.lineWidth = c.lineWidth; 146 | ctx.lineJoin = "round"; 147 | 148 | ctx.beginPath(); 149 | if (c.mode.indexOf("x") != -1) { 150 | var drawX = Math.floor(crosshair.x) + adj; 151 | ctx.moveTo(drawX, 0); 152 | ctx.lineTo(drawX, plot.height()); 153 | } 154 | if (c.mode.indexOf("y") != -1) { 155 | var drawY = Math.floor(crosshair.y) + adj; 156 | ctx.moveTo(0, drawY); 157 | ctx.lineTo(plot.width(), drawY); 158 | } 159 | ctx.stroke(); 160 | } 161 | ctx.restore(); 162 | }); 163 | 164 | plot.hooks.shutdown.push(function (plot, eventHolder) { 165 | eventHolder.unbind("mouseout", onMouseOut); 166 | eventHolder.unbind("mousemove", onMouseMove); 167 | }); 168 | } 169 | 170 | $.plot.plugins.push({ 171 | init: init, 172 | options: options, 173 | name: 'crosshair', 174 | version: '1.0' 175 | }); 176 | })(jQuery); 177 | -------------------------------------------------------------------------------- /rbac/static/assets/plugins/flot-chart/jquery.flot.orderBars.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Flot plugin to order bars side by side. 3 | * 4 | * Released under the MIT license by Benjamin BUFFET, 20-Sep-2010. 5 | * 6 | * This plugin is an alpha version. 7 | * 8 | * To activate the plugin you must specify the parameter "order" for the specific serie : 9 | * 10 | * $.plot($("#placeholder"), [{ data: [ ... ], bars :{ order = null or integer }]) 11 | * 12 | * If 2 series have the same order param, they are ordered by the position in the array; 13 | * 14 | * The plugin adjust the point by adding a value depanding of the barwidth 15 | * Exemple for 3 series (barwidth : 0.1) : 16 | * 17 | * first bar décalage : -0.15 18 | * second bar décalage : -0.05 19 | * third bar décalage : 0.05 20 | * 21 | */ 22 | 23 | (function($){ 24 | function init(plot){ 25 | var orderedBarSeries; 26 | var nbOfBarsToOrder; 27 | var borderWidth; 28 | var borderWidthInXabsWidth; 29 | var pixelInXWidthEquivalent = 1; 30 | var isHorizontal = false; 31 | 32 | /* 33 | * This method add shift to x values 34 | */ 35 | function reOrderBars(plot, serie, datapoints){ 36 | var shiftedPoints = null; 37 | 38 | if(serieNeedToBeReordered(serie)){ 39 | checkIfGraphIsHorizontal(serie); 40 | calculPixel2XWidthConvert(plot); 41 | retrieveBarSeries(plot); 42 | calculBorderAndBarWidth(serie); 43 | 44 | if(nbOfBarsToOrder >= 2){ 45 | var position = findPosition(serie); 46 | var decallage = 0; 47 | 48 | var centerBarShift = calculCenterBarShift(); 49 | 50 | if (isBarAtLeftOfCenter(position)){ 51 | decallage = -1*(sumWidth(orderedBarSeries,position-1,Math.floor(nbOfBarsToOrder / 2)-1)) - centerBarShift; 52 | }else{ 53 | decallage = sumWidth(orderedBarSeries,Math.ceil(nbOfBarsToOrder / 2),position-2) + centerBarShift + borderWidthInXabsWidth*2; 54 | } 55 | 56 | shiftedPoints = shiftPoints(datapoints,serie,decallage); 57 | datapoints.points = shiftedPoints; 58 | } 59 | } 60 | return shiftedPoints; 61 | } 62 | 63 | function serieNeedToBeReordered(serie){ 64 | return serie.bars != null 65 | && serie.bars.show 66 | && serie.bars.order != null; 67 | } 68 | 69 | function calculPixel2XWidthConvert(plot){ 70 | var gridDimSize = isHorizontal ? plot.getPlaceholder().innerHeight() : plot.getPlaceholder().innerWidth(); 71 | var minMaxValues = isHorizontal ? getAxeMinMaxValues(plot.getData(),1) : getAxeMinMaxValues(plot.getData(),0); 72 | var AxeSize = minMaxValues[1] - minMaxValues[0]; 73 | pixelInXWidthEquivalent = AxeSize / gridDimSize; 74 | } 75 | 76 | function getAxeMinMaxValues(series,AxeIdx){ 77 | var minMaxValues = new Array(); 78 | for(var i = 0; i < series.length; i++){ 79 | minMaxValues[0] = series[i].data[0][AxeIdx]; 80 | minMaxValues[1] = series[i].data[series[i].data.length - 1][AxeIdx]; 81 | } 82 | return minMaxValues; 83 | } 84 | 85 | function retrieveBarSeries(plot){ 86 | orderedBarSeries = findOthersBarsToReOrders(plot.getData()); 87 | nbOfBarsToOrder = orderedBarSeries.length; 88 | } 89 | 90 | function findOthersBarsToReOrders(series){ 91 | var retSeries = new Array(); 92 | 93 | for(var i = 0; i < series.length; i++){ 94 | if(series[i].bars.order != null && series[i].bars.show){ 95 | retSeries.push(series[i]); 96 | } 97 | } 98 | 99 | return retSeries.sort(sortByOrder); 100 | } 101 | 102 | function sortByOrder(serie1,serie2){ 103 | var x = serie1.bars.order; 104 | var y = serie2.bars.order; 105 | return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 106 | } 107 | 108 | function calculBorderAndBarWidth(serie){ 109 | borderWidth = serie.bars.lineWidth ? serie.bars.lineWidth : 2; 110 | borderWidthInXabsWidth = borderWidth * pixelInXWidthEquivalent; 111 | } 112 | 113 | function checkIfGraphIsHorizontal(serie){ 114 | if(serie.bars.horizontal){ 115 | isHorizontal = true; 116 | } 117 | } 118 | 119 | function findPosition(serie){ 120 | var pos = 0 121 | for (var i = 0; i < orderedBarSeries.length; ++i) { 122 | if (serie == orderedBarSeries[i]){ 123 | pos = i; 124 | break; 125 | } 126 | } 127 | 128 | return pos+1; 129 | } 130 | 131 | function calculCenterBarShift(){ 132 | var width = 0; 133 | 134 | if(nbOfBarsToOrder%2 != 0) 135 | width = (orderedBarSeries[Math.ceil(nbOfBarsToOrder / 2)].bars.barWidth)/2; 136 | 137 | return width; 138 | } 139 | 140 | function isBarAtLeftOfCenter(position){ 141 | return position <= Math.ceil(nbOfBarsToOrder / 2); 142 | } 143 | 144 | function sumWidth(series,start,end){ 145 | var totalWidth = 0; 146 | 147 | for(var i = start; i <= end; i++){ 148 | totalWidth += series[i].bars.barWidth+borderWidthInXabsWidth*2; 149 | } 150 | 151 | return totalWidth; 152 | } 153 | 154 | function shiftPoints(datapoints,serie,dx){ 155 | var ps = datapoints.pointsize; 156 | var points = datapoints.points; 157 | var j = 0; 158 | for(var i = isHorizontal ? 1 : 0;i < points.length; i += ps){ 159 | points[i] += dx; 160 | //Adding the new x value in the serie to be abble to display the right tooltip value, 161 | //using the index 3 to not overide the third index. 162 | serie.data[j][3] = points[i]; 163 | j++; 164 | } 165 | 166 | return points; 167 | } 168 | 169 | plot.hooks.processDatapoints.push(reOrderBars); 170 | 171 | } 172 | 173 | var options = { 174 | series : { 175 | bars: {order: null} // or number/string 176 | } 177 | }; 178 | 179 | $.plot.plugins.push({ 180 | init: init, 181 | options: options, 182 | name: "orderBars", 183 | version: "0.2" 184 | }); 185 | 186 | })(jQuery); -------------------------------------------------------------------------------- /rbac/static/assets/plugins/vector-map/jquery-jvectormap-2.0.2.css: -------------------------------------------------------------------------------- 1 | .jvectormap-container { 2 | width: 100%; 3 | height: 100%; 4 | position: relative; 5 | overflow: hidden; 6 | } 7 | 8 | .jvectormap-tip { 9 | position: absolute; 10 | display: none; 11 | border: solid 1px #CDCDCD; 12 | border-radius: 3px; 13 | background: #292929; 14 | color: white; 15 | font-family: sans-serif, Verdana; 16 | font-size: smaller; 17 | padding: 3px; 18 | } 19 | 20 | .jvectormap-zoomin, .jvectormap-zoomout, .jvectormap-goback { 21 | position: absolute; 22 | left: 10px; 23 | border-radius: 3px; 24 | background: #292929; 25 | padding: 5px; 26 | color: white; 27 | cursor: pointer; 28 | line-height: 20px; 29 | text-align: center; 30 | box-sizing: content-box; 31 | } 32 | 33 | .jvectormap-zoomin, .jvectormap-zoomout { 34 | width: 20px; 35 | height: 20px; 36 | } 37 | 38 | .jvectormap-zoomin { 39 | top: 10px; 40 | } 41 | 42 | .jvectormap-zoomout { 43 | top: 50px; 44 | } 45 | 46 | .jvectormap-goback { 47 | bottom: 10px; 48 | z-index: 1000; 49 | padding: 6px; 50 | } 51 | 52 | .jvectormap-spinner { 53 | position: absolute; 54 | left: 0; 55 | top: 0; 56 | right: 0; 57 | bottom: 0; 58 | background: center no-repeat url(data:image/gif;base64,R0lGODlhIAAgAPMAAP///wAAAMbGxoSEhLa2tpqamjY2NlZWVtjY2OTk5Ly8vB4eHgQEBAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ/V/nmOM82XiHRLYKhKP1oZmADdEAAAh+QQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY/CZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB+A4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6+Ho7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq+B6QDtuetcaBPnW6+O7wDHpIiK9SaVK5GgV543tzjgGcghAgAh+QQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK++G+w48edZPK+M6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE+G+cD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm+FNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk+aV+oJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0/VNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc+XiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30/iI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE/jiuL04RGEBgwWhShRgQExHBAAh+QQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR+ipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY+Yip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd+MFCN6HAAIKgNggY0KtEBAAh+QQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1+vsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d+jYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg+ygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0+bm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h+Kr0SJ8MFihpNbx+4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX+BP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA==); 59 | } 60 | 61 | .jvectormap-legend-title { 62 | font-weight: bold; 63 | font-size: 14px; 64 | text-align: center; 65 | } 66 | 67 | .jvectormap-legend-cnt { 68 | position: absolute; 69 | } 70 | 71 | .jvectormap-legend-cnt-h { 72 | bottom: 0; 73 | right: 0; 74 | } 75 | 76 | .jvectormap-legend-cnt-v { 77 | top: 0; 78 | right: 0; 79 | } 80 | 81 | .jvectormap-legend { 82 | background: black; 83 | color: white; 84 | border-radius: 3px; 85 | } 86 | 87 | .jvectormap-legend-cnt-h .jvectormap-legend { 88 | float: left; 89 | margin: 0 10px 10px 0; 90 | padding: 3px 3px 1px 3px; 91 | } 92 | 93 | .jvectormap-legend-cnt-h .jvectormap-legend .jvectormap-legend-tick { 94 | float: left; 95 | } 96 | 97 | .jvectormap-legend-cnt-v .jvectormap-legend { 98 | margin: 10px 10px 0 0; 99 | padding: 3px; 100 | } 101 | 102 | .jvectormap-legend-cnt-h .jvectormap-legend-tick { 103 | width: 40px; 104 | } 105 | 106 | .jvectormap-legend-cnt-h .jvectormap-legend-tick-sample { 107 | height: 15px; 108 | } 109 | 110 | .jvectormap-legend-cnt-v .jvectormap-legend-tick-sample { 111 | height: 20px; 112 | width: 20px; 113 | display: inline-block; 114 | vertical-align: middle; 115 | } 116 | 117 | .jvectormap-legend-tick-text { 118 | font-size: 12px; 119 | } 120 | 121 | .jvectormap-legend-cnt-h .jvectormap-legend-tick-text { 122 | text-align: center; 123 | } 124 | 125 | .jvectormap-legend-cnt-v .jvectormap-legend-tick-text { 126 | display: inline-block; 127 | vertical-align: middle; 128 | line-height: 20px; 129 | padding-left: 3px; 130 | } --------------------------------------------------------------------------------