Browse Source

first commit

Rafael Arce Nazario 4 years ago
parent
commit
61e387a9f7
100 changed files with 29753 additions and 0 deletions
  1. 5
    0
      .dockerignore
  2. 4
    0
      .env
  3. 3
    0
      .eslintignore
  4. 18
    0
      .eslintrc
  5. 26
    0
      .gitignore
  6. 23
    0
      .travis.yml
  7. 12
    0
      Dockerfile
  8. 21
    0
      LICENSE.md
  9. 84
    0
      app/__init__.py
  10. 15
    0
      app/base/__init__.py
  11. 20
    0
      app/base/forms.py
  12. 49
    0
      app/base/models.py
  13. 114
    0
      app/base/routes.py
  14. 20445
    0
      app/base/static/assets/css/black-dashboard.css
  15. 266
    0
      app/base/static/assets/css/black-dashboard.css.map
  16. 24
    0
      app/base/static/assets/css/black-dashboard.min.css
  17. 550
    0
      app/base/static/assets/css/nucleo-icons.css
  18. 63
    0
      app/base/static/assets/demo/demo.css
  19. 745
    0
      app/base/static/assets/demo/demo.js
  20. BIN
      app/base/static/assets/fonts/nucleo.eot
  21. BIN
      app/base/static/assets/fonts/nucleo.ttf
  22. BIN
      app/base/static/assets/fonts/nucleo.woff
  23. BIN
      app/base/static/assets/fonts/nucleo.woff2
  24. BIN
      app/base/static/assets/img/12345.png
  25. BIN
      app/base/static/assets/img/anime3.png
  26. BIN
      app/base/static/assets/img/anime6.png
  27. BIN
      app/base/static/assets/img/apple-icon.png
  28. BIN
      app/base/static/assets/img/bg5.jpg
  29. BIN
      app/base/static/assets/img/default-avatar.png
  30. BIN
      app/base/static/assets/img/emilyz.jpg
  31. BIN
      app/base/static/assets/img/favicon.png
  32. BIN
      app/base/static/assets/img/header.jpg
  33. BIN
      app/base/static/assets/img/img_3115.jpg
  34. BIN
      app/base/static/assets/img/james.jpg
  35. BIN
      app/base/static/assets/img/mike.jpg
  36. BIN
      app/base/static/assets/img/now-logo.png
  37. 255
    0
      app/base/static/assets/js/black-dashboard.js
  38. 1
    0
      app/base/static/assets/js/black-dashboard.js.map
  39. 2
    0
      app/base/static/assets/js/black-dashboard.min.js
  40. 6
    0
      app/base/static/assets/js/core/bootstrap.min.js
  41. 4
    0
      app/base/static/assets/js/core/jquery.min.js
  42. 4
    0
      app/base/static/assets/js/core/popper.min.js
  43. 432
    0
      app/base/static/assets/js/plugins/bootstrap-notify.js
  44. 10
    0
      app/base/static/assets/js/plugins/chartjs.min.js
  45. 6
    0
      app/base/static/assets/js/plugins/perfect-scrollbar.jquery.min.js
  46. 102
    0
      app/base/static/assets/scss/black-dashboard.scss
  47. 1
    0
      app/base/static/assets/scss/black-dashboard/_buttons.scss
  48. 1
    0
      app/base/static/assets/scss/black-dashboard/_typography.scss
  49. 51
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_alert.scss
  50. 54
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_badge.scss
  51. 41
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_breadcrumb.scss
  52. 163
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_button-group.scss
  53. 137
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_buttons.scss
  54. 289
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_card.scss
  55. 197
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_carousel.scss
  56. 41
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_close.scss
  57. 48
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_code.scss
  58. 507
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_custom-forms.scss
  59. 191
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_dropdown.scss
  60. 330
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_forms.scss
  61. 86
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_functions.scss
  62. 52
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_grid.scss
  63. 42
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_images.scss
  64. 193
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_input-group.scss
  65. 17
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_jumbotron.scss
  66. 149
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_list-group.scss
  67. 8
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_media.scss
  68. 47
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_mixins.scss
  69. 229
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_modal.scss
  70. 120
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_nav.scss
  71. 294
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_navbar.scss
  72. 73
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_pagination.scss
  73. 171
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_popover.scss
  74. 141
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_print.scss
  75. 43
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_progress.scss
  76. 483
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_reboot.scss
  77. 19
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_root.scss
  78. 55
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_spinners.scss
  79. 185
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_tables.scss
  80. 44
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_toasts.scss
  81. 115
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_tooltip.scss
  82. 20
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_transitions.scss
  83. 125
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_type.scss
  84. 17
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_utilities.scss
  85. 1123
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/_variables.scss
  86. 29
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/bootstrap-grid.scss
  87. 12
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/bootstrap-reboot.scss
  88. 44
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/bootstrap.scss
  89. 13
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_alert.scss
  90. 21
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_background-variant.scss
  91. 17
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_badge.scss
  92. 63
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_border-radius.scss
  93. 20
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_box-shadow.scss
  94. 123
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_breakpoints.scss
  95. 107
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_buttons.scss
  96. 62
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_caret.scss
  97. 7
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_clearfix.scss
  98. 10
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_deprecate.scss
  99. 14
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_float.scss
  100. 0
    0
      app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_forms.scss

+ 5
- 0
.dockerignore View File

@@ -0,0 +1,5 @@
1
+.git
2
+__pycache__
3
+*.pyc
4
+*.pyo
5
+*.pyd

+ 4
- 0
.env View File

@@ -0,0 +1,4 @@
1
+APPSEED_CONFIG_MODE=Debug
2
+POSTGRES_USER=appseed
3
+POSTGRES_PASSWORD=appseed
4
+POSTGRES_DB=appseed

+ 3
- 0
.eslintignore View File

@@ -0,0 +1,3 @@
1
+app/base/static/vendors
2
+app/base/static/build/js/custom.js
3
+app/base/static/build/js/custom.min.js

+ 18
- 0
.eslintrc View File

@@ -0,0 +1,18 @@
1
+{
2
+    "parserOptions": {
3
+        "ecmaVersion": 6,
4
+        "sourceType": "module",
5
+        "ecmaFeatures": {
6
+            "jsx": true
7
+        }
8
+    },
9
+    "env": {
10
+        "browser": true,
11
+        "jquery": true
12
+    },
13
+    "rules": {
14
+        "no-invalid-this": 0,
15
+        "linebreak-style": 0
16
+    },
17
+    "extends": ["eslint:recommended", "google"]
18
+}

+ 26
- 0
.gitignore View File

@@ -0,0 +1,26 @@
1
+# byte-compiled / optimized / DLL files
2
+__pycache__/
3
+*.py[cod]
4
+
5
+# tests and coverage
6
+*.pytest_cache
7
+.coverage
8
+
9
+# database & logs
10
+*.db
11
+*.log
12
+
13
+# venv
14
+env
15
+venv
16
+
17
+# other
18
+.DS_Store
19
+
20
+# sphinx docs 
21
+_build
22
+_static
23
+_templates
24
+
25
+# javascript
26
+package-lock.json

+ 23
- 0
.travis.yml View File

@@ -0,0 +1,23 @@
1
+matrix:
2
+  include:
3
+    - language: python
4
+      python:
5
+        - 3.4
6
+        - 3.5
7
+        - 3.6
8
+      install:
9
+        - pip install -r requirements_dev.txt
10
+      script:
11
+        - flake8
12
+        - sudo apt-get update
13
+        - sudo apt-get install google-chrome-stable
14
+        - sudo apt-get install chromium-browser
15
+        - sudo chmod a+x ./tests/chromedriver
16
+        - coverage run --source=./app -m pytest
17
+      after_success:
18
+        - coveralls
19
+    - language: node_js
20
+      node_js: 
21
+        - "node"
22
+      script: 
23
+        - npm run lint

+ 12
- 0
Dockerfile View File

@@ -0,0 +1,12 @@
1
+FROM python:3.6
2
+
3
+ENV FLASK_APP run.py
4
+
5
+COPY run.py gunicorn.py requirements-sqlite.txt config.py .env ./
6
+COPY app app
7
+COPY migrations migrations
8
+
9
+RUN pip install -r requirements-sqlite.txt
10
+
11
+EXPOSE 5000
12
+CMD ["gunicorn", "--config", "gunicorn.py", "run:app"]

+ 21
- 0
LICENSE.md View File

@@ -0,0 +1,21 @@
1
+MIT License
2
+
3
+Copyright (c) 2019 [AppSeed App Generator](https://appseed.us)
4
+
5
+Permission is hereby granted, free of charge, to any person obtaining a copy
6
+of this software and associated documentation files (the "Software"), to deal
7
+in the Software without restriction, including without limitation the rights
8
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+copies of the Software, and to permit persons to whom the Software is
10
+furnished to do so, subject to the following conditions:
11
+
12
+The above copyright notice and this permission notice shall be included in all
13
+copies or substantial portions of the Software.
14
+
15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+SOFTWARE.

+ 84
- 0
app/__init__.py View File

@@ -0,0 +1,84 @@
1
+# -*- encoding: utf-8 -*-
2
+"""
3
+License: MIT
4
+Copyright (c) 2019 - present AppSeed.us
5
+"""
6
+
7
+from flask import Flask, url_for
8
+from flask_login import LoginManager
9
+from flask_sqlalchemy import SQLAlchemy
10
+from importlib import import_module
11
+from logging import basicConfig, DEBUG, getLogger, StreamHandler
12
+from os import path
13
+
14
+db = SQLAlchemy()
15
+login_manager = LoginManager()
16
+
17
+def register_extensions(app):
18
+    db.init_app(app)
19
+    login_manager.init_app(app)
20
+
21
+def register_blueprints(app):
22
+    for module_name in ('base', 'home'):
23
+        module = import_module('app.{}.routes'.format(module_name))
24
+        app.register_blueprint(module.blueprint)
25
+
26
+def configure_database(app):
27
+
28
+    @app.before_first_request
29
+    def initialize_database():
30
+        db.create_all()
31
+
32
+    @app.teardown_request
33
+    def shutdown_session(exception=None):
34
+        db.session.remove()
35
+
36
+def configure_logs(app):
37
+    # soft logging
38
+    try:
39
+        basicConfig(filename='error.log', level=DEBUG)
40
+        logger = getLogger()
41
+        logger.addHandler(StreamHandler())
42
+    except:
43
+        pass
44
+
45
+def apply_themes(app):
46
+    """
47
+    Add support for themes.
48
+
49
+    If DEFAULT_THEME is set then all calls to
50
+      url_for('static', filename='')
51
+      will modfify the url to include the theme name
52
+
53
+    The theme parameter can be set directly in url_for as well:
54
+      ex. url_for('static', filename='', theme='')
55
+
56
+    If the file cannot be found in the /static/<theme>/ location then
57
+      the url will not be modified and the file is expected to be
58
+      in the default /static/ location
59
+    """
60
+    @app.context_processor
61
+    def override_url_for():
62
+        return dict(url_for=_generate_url_for_theme)
63
+
64
+    def _generate_url_for_theme(endpoint, **values):
65
+        if endpoint.endswith('static'):
66
+            themename = values.get('theme', None) or \
67
+                app.config.get('DEFAULT_THEME', None)
68
+            if themename:
69
+                theme_file = "{}/{}".format(themename, values.get('filename', ''))
70
+                if path.isfile(path.join(app.static_folder, theme_file)):
71
+                    values['filename'] = theme_file
72
+        return url_for(endpoint, **values)
73
+
74
+def create_app(config, selenium=False):
75
+    app = Flask(__name__, static_folder='base/static')
76
+    app.config.from_object(config)
77
+    if selenium:
78
+        app.config['LOGIN_DISABLED'] = True
79
+    register_extensions(app)
80
+    register_blueprints(app)
81
+    configure_database(app)
82
+    configure_logs(app)
83
+    apply_themes(app)
84
+    return app

+ 15
- 0
app/base/__init__.py View File

@@ -0,0 +1,15 @@
1
+# -*- encoding: utf-8 -*-
2
+"""
3
+License: MIT
4
+Copyright (c) 2019 - present AppSeed.us
5
+"""
6
+
7
+from flask import Blueprint
8
+
9
+blueprint = Blueprint(
10
+    'base_blueprint',
11
+    __name__,
12
+    url_prefix='',
13
+    template_folder='templates',
14
+    static_folder='static'
15
+)

+ 20
- 0
app/base/forms.py View File

@@ -0,0 +1,20 @@
1
+# -*- encoding: utf-8 -*-
2
+"""
3
+License: MIT
4
+Copyright (c) 2019 - present AppSeed.us
5
+"""
6
+
7
+from flask_wtf import FlaskForm
8
+from wtforms import TextField, PasswordField
9
+from wtforms.validators import InputRequired, Email, DataRequired
10
+
11
+## login and registration
12
+
13
+class LoginForm(FlaskForm):
14
+    username = TextField    ('Username', id='username_login'   , validators=[DataRequired()])
15
+    password = PasswordField('Password', id='pwd_login'        , validators=[DataRequired()])
16
+
17
+class CreateAccountForm(FlaskForm):
18
+    username = TextField('Username'     , id='username_create' , validators=[DataRequired()])
19
+    email    = TextField('Email'        , id='email_create'    , validators=[DataRequired(), Email()])
20
+    password = PasswordField('Password' , id='pwd_create'      , validators=[DataRequired()])

+ 49
- 0
app/base/models.py View File

@@ -0,0 +1,49 @@
1
+# -*- encoding: utf-8 -*-
2
+"""
3
+License: MIT
4
+Copyright (c) 2019 - present AppSeed.us
5
+"""
6
+
7
+from flask_login import UserMixin
8
+from sqlalchemy import Binary, Column, Integer, String
9
+
10
+from app import db, login_manager
11
+
12
+from app.base.util import hash_pass
13
+
14
+class User(db.Model, UserMixin):
15
+
16
+    __tablename__ = 'User'
17
+
18
+    id = Column(Integer, primary_key=True)
19
+    username = Column(String, unique=True)
20
+    email = Column(String, unique=True)
21
+    password = Column(Binary)
22
+
23
+    def __init__(self, **kwargs):
24
+        for property, value in kwargs.items():
25
+            # depending on whether value is an iterable or not, we must
26
+            # unpack it's value (when **kwargs is request.form, some values
27
+            # will be a 1-element list)
28
+            if hasattr(value, '__iter__') and not isinstance(value, str):
29
+                # the ,= unpack of a singleton fails PEP8 (travis flake8 test)
30
+                value = value[0]
31
+
32
+            if property == 'password':
33
+                value = hash_pass( value ) # we need bytes here (not plain str)
34
+                
35
+            setattr(self, property, value)
36
+
37
+    def __repr__(self):
38
+        return str(self.username)
39
+
40
+
41
+@login_manager.user_loader
42
+def user_loader(id):
43
+    return User.query.filter_by(id=id).first()
44
+
45
+@login_manager.request_loader
46
+def request_loader(request):
47
+    username = request.form.get('username')
48
+    user = User.query.filter_by(username=username).first()
49
+    return user if user else None

+ 114
- 0
app/base/routes.py View File

@@ -0,0 +1,114 @@
1
+# -*- encoding: utf-8 -*-
2
+"""
3
+License: MIT
4
+Copyright (c) 2019 - present AppSeed.us
5
+"""
6
+
7
+from flask import jsonify, render_template, redirect, request, url_for
8
+from flask_login import (
9
+    current_user,
10
+    login_required,
11
+    login_user,
12
+    logout_user
13
+)
14
+
15
+from app import db, login_manager
16
+from app.base import blueprint
17
+from app.base.forms import LoginForm, CreateAccountForm
18
+from app.base.models import User
19
+
20
+from app.base.util import verify_pass
21
+
22
+@blueprint.route('/')
23
+def route_default():
24
+    return redirect(url_for('base_blueprint.login'))
25
+
26
+@blueprint.route('/error-<error>')
27
+def route_errors(error):
28
+    return render_template('errors/{}.html'.format(error))
29
+
30
+## Login & Registration
31
+
32
+@blueprint.route('/login', methods=['GET', 'POST'])
33
+def login():
34
+    login_form = LoginForm(request.form)
35
+    if 'login' in request.form:
36
+        
37
+        # read form data
38
+        username = request.form['username']
39
+        password = request.form['password']
40
+
41
+        # Locate user
42
+        user = User.query.filter_by(username=username).first()
43
+        
44
+        # Check the password
45
+        if user and verify_pass( password, user.password):
46
+
47
+            login_user(user)
48
+            return redirect(url_for('base_blueprint.route_default'))
49
+
50
+        # Something (user or pass) is not ok
51
+        return render_template( 'login/login.html', msg='Wrong user or password', form=login_form)
52
+
53
+    if not current_user.is_authenticated:
54
+        return render_template( 'login/login.html',
55
+                                form=login_form)
56
+    return redirect(url_for('home_blueprint.index'))
57
+
58
+@blueprint.route('/create_user', methods=['GET', 'POST'])
59
+def create_user():
60
+    login_form = LoginForm(request.form)
61
+    create_account_form = CreateAccountForm(request.form)
62
+    if 'register' in request.form:
63
+
64
+        username  = request.form['username']
65
+        email     = request.form['email'   ]
66
+
67
+        user = User.query.filter_by(username=username).first()
68
+        if user:
69
+            return render_template( 'login/register.html', msg='Username already registered', form=create_account_form)
70
+
71
+        user = User.query.filter_by(email=email).first()
72
+        if user:
73
+            return render_template( 'login/register.html', msg='Email already registered', form=create_account_form)
74
+
75
+        # else we can create the user
76
+        user = User(**request.form)
77
+        db.session.add(user)
78
+        db.session.commit()
79
+
80
+        return render_template( 'login/register.html', msg='User created please <a href="/login">login</a>', form=create_account_form)
81
+
82
+    else:
83
+        return render_template( 'login/register.html', form=create_account_form)
84
+
85
+@blueprint.route('/logout')
86
+def logout():
87
+    logout_user()
88
+    return redirect(url_for('base_blueprint.login'))
89
+
90
+@blueprint.route('/shutdown')
91
+def shutdown():
92
+    func = request.environ.get('werkzeug.server.shutdown')
93
+    if func is None:
94
+        raise RuntimeError('Not running with the Werkzeug Server')
95
+    func()
96
+    return 'Server shutting down...'
97
+
98
+## Errors
99
+
100
+@login_manager.unauthorized_handler
101
+def unauthorized_handler():
102
+    return render_template('errors/403.html'), 403
103
+
104
+@blueprint.errorhandler(403)
105
+def access_forbidden(error):
106
+    return render_template('errors/403.html'), 403
107
+
108
+@blueprint.errorhandler(404)
109
+def not_found_error(error):
110
+    return render_template('errors/404.html'), 404
111
+
112
+@blueprint.errorhandler(500)
113
+def internal_error(error):
114
+    return render_template('errors/500.html'), 500

+ 20445
- 0
app/base/static/assets/css/black-dashboard.css
File diff suppressed because it is too large
View File


+ 266
- 0
app/base/static/assets/css/black-dashboard.css.map
File diff suppressed because it is too large
View File


+ 24
- 0
app/base/static/assets/css/black-dashboard.min.css
File diff suppressed because it is too large
View File


+ 550
- 0
app/base/static/assets/css/nucleo-icons.css View File

@@ -0,0 +1,550 @@
1
+/* --------------------------------
2
+
3
+Nucleo Outline Web Font - nucleoapp.com/
4
+License - nucleoapp.com/license/
5
+Created using IcoMoon - icomoon.io
6
+
7
+-------------------------------- */
8
+
9
+@font-face {
10
+  font-family: 'Nucleo';
11
+  src: url('../fonts/nucleo.eot');
12
+  src: url('../fonts/nucleo.eot') format('embedded-opentype'),
13
+    url('../fonts/nucleo.woff2') format('woff2'),
14
+    url('../fonts/nucleo.woff') format('woff'),
15
+    url('../fonts/nucleo.ttf') format('truetype'),
16
+    url('../fonts/nucleo.svg') format('svg');
17
+  font-weight: normal;
18
+  font-style: normal;
19
+}
20
+
21
+/*------------------------
22
+	base class definition
23
+-------------------------*/
24
+
25
+.tim-icons {
26
+  display: inline-block;
27
+  font: normal normal normal 1em/1 'Nucleo';
28
+  vertical-align: middle;
29
+  speak: none;
30
+  text-transform: none;
31
+  /* Better Font Rendering */
32
+  -webkit-font-smoothing: antialiased;
33
+  -moz-osx-font-smoothing: grayscale;
34
+}
35
+
36
+.font-icon-detail {
37
+  text-align: center;
38
+  padding: 45px 0 30px;
39
+  border: 1px solid #e44cc4;
40
+  border-radius: .1875rem;
41
+  margin: 15px 0;
42
+  min-height: 168px;
43
+}
44
+
45
+.font-icon-detail i {
46
+  color: #FFFFFF;
47
+  font-size: 1.5em;
48
+}
49
+
50
+.font-icon-detail p {
51
+  color: #e44cc4 !important;
52
+  margin-top: 30px;
53
+  padding: 0 10px;
54
+  font-size: .7142em;
55
+}
56
+
57
+/*------------------------
58
+  change icon size
59
+-------------------------*/
60
+
61
+.tim-icons-sm {
62
+  font-size: 0.8em;
63
+}
64
+
65
+.tim-icons-lg {
66
+  font-size: 1.2em;
67
+}
68
+
69
+/* absolute units */
70
+.tim-icons-16 {
71
+  font-size: 16px;
72
+}
73
+
74
+.tim-icons-32 {
75
+  font-size: 32px;
76
+}
77
+
78
+/*----------------------------------
79
+  add a square/circle background
80
+-----------------------------------*/
81
+
82
+.tim-icons-bg-square,
83
+.tim-icons-bg-circle {
84
+  padding: 0.35em;
85
+}
86
+
87
+.tim-icons-bg-circle {
88
+  border-radius: 50%;
89
+}
90
+
91
+/*------------------------
92
+  list icons
93
+-------------------------*/
94
+
95
+
96
+
97
+/*------------------------
98
+  spinning icons
99
+-------------------------*/
100
+
101
+.tim-icons-is-spinning {
102
+  -webkit-animation: tim-icons-spin 2s infinite linear;
103
+  -moz-animation: tim-icons-spin 2s infinite linear;
104
+  animation: tim-icons-spin 2s infinite linear;
105
+}
106
+
107
+@-webkit-keyframes tim-icons-spin {
108
+  0% {
109
+    -webkit-transform: rotate(0deg);
110
+  }
111
+
112
+  100% {
113
+    -webkit-transform: rotate(360deg);
114
+  }
115
+}
116
+
117
+@-moz-keyframes tim-icons-spin {
118
+  0% {
119
+    -moz-transform: rotate(0deg);
120
+  }
121
+
122
+  100% {
123
+    -moz-transform: rotate(360deg);
124
+  }
125
+}
126
+
127
+@keyframes tim-icons-spin {
128
+  0% {
129
+    -webkit-transform: rotate(0deg);
130
+    -moz-transform: rotate(0deg);
131
+    -ms-transform: rotate(0deg);
132
+    -o-transform: rotate(0deg);
133
+    transform: rotate(0deg);
134
+  }
135
+
136
+  100% {
137
+    -webkit-transform: rotate(360deg);
138
+    -moz-transform: rotate(360deg);
139
+    -ms-transform: rotate(360deg);
140
+    -o-transform: rotate(360deg);
141
+    transform: rotate(360deg);
142
+  }
143
+}
144
+
145
+/*------------------------
146
+  rotated/flipped icons
147
+-------------------------*/
148
+/*------------------------
149
+	icons
150
+-------------------------*/
151
+
152
+.icon-alert-circle-exc::before {
153
+  content: "\ea02";
154
+}
155
+
156
+.icon-align-center::before {
157
+  content: "\ea03";
158
+}
159
+
160
+.icon-align-left-2::before {
161
+  content: "\ea04";
162
+}
163
+
164
+.icon-app::before {
165
+  content: "\ea05";
166
+}
167
+
168
+.icon-atom::before {
169
+  content: "\ea06";
170
+}
171
+
172
+.icon-attach-87::before {
173
+  content: "\ea07";
174
+}
175
+
176
+.icon-badge::before {
177
+  content: "\ea08";
178
+}
179
+
180
+.icon-bag-16::before {
181
+  content: "\ea09";
182
+}
183
+
184
+.icon-bank::before {
185
+  content: "\ea0a";
186
+}
187
+
188
+.icon-basket-simple::before {
189
+  content: "\ea0b";
190
+}
191
+
192
+.icon-bell-55::before {
193
+  content: "\ea0c";
194
+}
195
+
196
+.icon-bold::before {
197
+  content: "\ea0d";
198
+}
199
+
200
+.icon-book-bookmark::before {
201
+  content: "\ea0e";
202
+}
203
+
204
+.icon-bulb-63::before {
205
+  content: "\ea0f";
206
+}
207
+
208
+.icon-bullet-list-67::before {
209
+  content: "\ea10";
210
+}
211
+
212
+.icon-bus-front-12::before {
213
+  content: "\ea11";
214
+}
215
+
216
+.icon-button-pause::before {
217
+  content: "\ea12";
218
+}
219
+
220
+.icon-button-power::before {
221
+  content: "\ea13";
222
+}
223
+
224
+.icon-calendar-60::before {
225
+  content: "\ea14";
226
+}
227
+
228
+.icon-camera-18::before {
229
+  content: "\ea15";
230
+}
231
+
232
+.icon-caps-small::before {
233
+  content: "\ea16";
234
+}
235
+
236
+.icon-cart::before {
237
+  content: "\ea17";
238
+}
239
+
240
+.icon-chart-bar-32::before {
241
+  content: "\ea18";
242
+}
243
+
244
+.icon-chart-pie-36::before {
245
+  content: "\ea19";
246
+}
247
+
248
+.icon-chat-33::before {
249
+  content: "\ea1a";
250
+}
251
+
252
+.icon-check-2::before {
253
+  content: "\ea1b";
254
+}
255
+
256
+.icon-cloud-download-93::before {
257
+  content: "\ea1c";
258
+}
259
+
260
+.icon-cloud-upload-94::before {
261
+  content: "\ea1d";
262
+}
263
+
264
+.icon-coins::before {
265
+  content: "\ea1e";
266
+}
267
+
268
+.icon-compass-05::before {
269
+  content: "\ea1f";
270
+}
271
+
272
+.icon-controller::before {
273
+  content: "\ea20";
274
+}
275
+
276
+.icon-credit-card::before {
277
+  content: "\ea21";
278
+}
279
+
280
+.icon-delivery-fast::before {
281
+  content: "\ea22";
282
+}
283
+
284
+.icon-double-left::before {
285
+  content: "\ea23";
286
+}
287
+
288
+.icon-double-right::before {
289
+  content: "\ea24";
290
+}
291
+
292
+.icon-email-85::before {
293
+  content: "\ea25";
294
+}
295
+
296
+.icon-gift-2::before {
297
+  content: "\ea26";
298
+}
299
+
300
+.icon-globe-2::before {
301
+  content: "\ea27";
302
+}
303
+
304
+.icon-headphones::before {
305
+  content: "\ea28";
306
+}
307
+
308
+.icon-heart-2::before {
309
+  content: "\ea29";
310
+}
311
+
312
+.icon-html5::before {
313
+  content: "\ea2a";
314
+}
315
+
316
+.icon-image-02::before {
317
+  content: "\ea2b";
318
+}
319
+
320
+.icon-istanbul::before {
321
+  content: "\ea2c";
322
+}
323
+
324
+.icon-key-25::before {
325
+  content: "\ea2d";
326
+}
327
+
328
+.icon-laptop::before {
329
+  content: "\ea2e";
330
+}
331
+
332
+.icon-light-3::before {
333
+  content: "\ea2f";
334
+}
335
+
336
+.icon-link-72::before {
337
+  content: "\ea30";
338
+}
339
+
340
+.icon-lock-circle::before {
341
+  content: "\ea31";
342
+}
343
+
344
+.icon-map-big::before {
345
+  content: "\ea32";
346
+}
347
+
348
+.icon-minimal-down::before {
349
+  content: "\ea33";
350
+}
351
+
352
+.icon-minimal-left::before {
353
+  content: "\ea34";
354
+}
355
+
356
+.icon-minimal-right::before {
357
+  content: "\ea35";
358
+}
359
+
360
+.icon-minimal-up::before {
361
+  content: "\ea36";
362
+}
363
+
364
+.icon-mobile::before {
365
+  content: "\ea37";
366
+}
367
+
368
+.icon-molecule-40::before {
369
+  content: "\ea38";
370
+}
371
+
372
+.icon-money-coins::before {
373
+  content: "\ea39";
374
+}
375
+
376
+.icon-notes::before {
377
+  content: "\ea3a";
378
+}
379
+
380
+.icon-palette::before {
381
+  content: "\ea3b";
382
+}
383
+
384
+.icon-paper::before {
385
+  content: "\ea3c";
386
+}
387
+
388
+.icon-pencil::before {
389
+  content: "\ea3d";
390
+}
391
+
392
+.icon-pin::before {
393
+  content: "\ea3e";
394
+}
395
+
396
+.icon-planet::before {
397
+  content: "\ea3f";
398
+}
399
+
400
+.icon-puzzle-10::before {
401
+  content: "\ea40";
402
+}
403
+
404
+.icon-satisfied::before {
405
+  content: "\ea41";
406
+}
407
+
408
+.icon-scissors::before {
409
+  content: "\ea42";
410
+}
411
+
412
+.icon-send::before {
413
+  content: "\ea43";
414
+}
415
+
416
+.icon-settings-gear-63::before {
417
+  content: "\ea44";
418
+}
419
+
420
+.icon-settings::before {
421
+  content: "\ea45";
422
+}
423
+
424
+.icon-simple-add::before {
425
+  content: "\ea46";
426
+}
427
+
428
+.icon-simple-delete::before {
429
+  content: "\ea47";
430
+}
431
+
432
+.icon-simple-remove::before {
433
+  content: "\ea48";
434
+}
435
+
436
+.icon-single-02::before {
437
+  content: "\ea49";
438
+}
439
+
440
+.icon-single-copy-04::before {
441
+  content: "\ea4a";
442
+}
443
+
444
+.icon-sound-wave::before {
445
+  content: "\ea4b";
446
+}
447
+
448
+.icon-spaceship::before {
449
+  content: "\ea4c";
450
+}
451
+
452
+.icon-square-pin::before {
453
+  content: "\ea4d";
454
+}
455
+
456
+.icon-support-17::before {
457
+  content: "\ea4e";
458
+}
459
+
460
+.icon-tablet-2::before {
461
+  content: "\ea4f";
462
+}
463
+
464
+.icon-tag::before {
465
+  content: "\ea50";
466
+}
467
+
468
+.icon-tap-02::before {
469
+  content: "\ea51";
470
+}
471
+
472
+.icon-tie-bow::before {
473
+  content: "\ea52";
474
+}
475
+
476
+.icon-time-alarm::before {
477
+  content: "\ea53";
478
+}
479
+
480
+.icon-trash-simple::before {
481
+  content: "\ea54";
482
+}
483
+
484
+.icon-triangle-right-17::before {
485
+  content: "\ea55";
486
+}
487
+
488
+.icon-trophy::before {
489
+  content: "\ea56";
490
+}
491
+
492
+.icon-tv-2::before {
493
+  content: "\ea57";
494
+}
495
+
496
+.icon-upload::before {
497
+  content: "\ea58";
498
+}
499
+
500
+.icon-user-run::before {
501
+  content: "\ea59";
502
+}
503
+
504
+.icon-vector::before {
505
+  content: "\ea5a";
506
+}
507
+
508
+.icon-video-66::before {
509
+  content: "\ea5b";
510
+}
511
+
512
+.icon-volume-98::before {
513
+  content: "\ea5c";
514
+}
515
+
516
+.icon-wallet-43::before {
517
+  content: "\ea5d";
518
+}
519
+
520
+.icon-watch-time::before {
521
+  content: "\ea5e";
522
+}
523
+
524
+.icon-wifi::before {
525
+  content: "\ea5f";
526
+}
527
+
528
+.icon-world::before {
529
+  content: "\ea60";
530
+}
531
+
532
+.icon-zoom-split::before {
533
+  content: "\ea61";
534
+}
535
+
536
+.icon-refresh-01::before {
537
+  content: "\ea62";
538
+}
539
+
540
+.icon-refresh-02::before {
541
+  content: "\ea63";
542
+}
543
+
544
+.icon-shape-star::before {
545
+  content: "\ea64";
546
+}
547
+
548
+.icon-components::before {
549
+  content: "\ea65";
550
+}

+ 63
- 0
app/base/static/assets/demo/demo.css View File

@@ -0,0 +1,63 @@
1
+.tim-row {
2
+  margin-bottom: 20px;
3
+}
4
+
5
+.tim-white-buttons {
6
+  background-color: #777777;
7
+}
8
+
9
+.typography-line {
10
+  padding-left: 25%;
11
+  margin-bottom: 35px;
12
+  position: relative;
13
+  display: block;
14
+  width: 100%;
15
+}
16
+
17
+.typography-line span {
18
+  bottom: 10px;
19
+  color: #c0c1c2;
20
+  display: block;
21
+  font-weight: 400;
22
+  font-size: 13px;
23
+  line-height: 13px;
24
+  left: 0;
25
+  position: absolute;
26
+  width: 260px;
27
+  text-transform: none;
28
+}
29
+
30
+.tim-row {
31
+  padding-top: 60px;
32
+}
33
+
34
+.tim-row h3 {
35
+  margin-top: 0;
36
+}
37
+
38
+.offline-doc .page-header {
39
+  display: flex;
40
+  align-items: center;
41
+}
42
+
43
+.offline-doc .footer {
44
+  position: absolute;
45
+  width: 100%;
46
+  background: transparent;
47
+  bottom: 0;
48
+  color: #fff;
49
+  z-index: 1;
50
+}
51
+
52
+@media all and (min-width: 992px) {
53
+  .sidebar .nav>li.active-pro {
54
+    position: absolute;
55
+    width: 100%;
56
+    bottom: 10px;
57
+  }
58
+}
59
+
60
+.card.card-upgrade .card-category {
61
+  max-width: 530px;
62
+  margin: 0 auto;
63
+}

+ 745
- 0
app/base/static/assets/demo/demo.js View File

@@ -0,0 +1,745 @@
1
+type = ['primary', 'info', 'success', 'warning', 'danger'];
2
+
3
+demo = {
4
+  initPickColor: function() {
5
+    $('.pick-class-label').click(function() {
6
+      var new_class = $(this).attr('new-class');
7
+      var old_class = $('#display-buttons').attr('data-class');
8
+      var display_div = $('#display-buttons');
9
+      if (display_div.length) {
10
+        var display_buttons = display_div.find('.btn');
11
+        display_buttons.removeClass(old_class);
12
+        display_buttons.addClass(new_class);
13
+        display_div.attr('data-class', new_class);
14
+      }
15
+    });
16
+  },
17
+
18
+  initDocChart: function() {
19
+    chartColor = "#FFFFFF";
20
+
21
+    // General configuration for the charts with Line gradientStroke
22
+    gradientChartOptionsConfiguration = {
23
+      maintainAspectRatio: false,
24
+      legend: {
25
+        display: false
26
+      },
27
+      tooltips: {
28
+        bodySpacing: 4,
29
+        mode: "nearest",
30
+        intersect: 0,
31
+        position: "nearest",
32
+        xPadding: 10,
33
+        yPadding: 10,
34
+        caretPadding: 10
35
+      },
36
+      responsive: true,
37
+      scales: {
38
+        yAxes: [{
39
+          display: 0,
40
+          gridLines: 0,
41
+          ticks: {
42
+            display: false
43
+          },
44
+          gridLines: {
45
+            zeroLineColor: "transparent",
46
+            drawTicks: false,
47
+            display: false,
48
+            drawBorder: false
49
+          }
50
+        }],
51
+        xAxes: [{
52
+          display: 0,
53
+          gridLines: 0,
54
+          ticks: {
55
+            display: false
56
+          },
57
+          gridLines: {
58
+            zeroLineColor: "transparent",
59
+            drawTicks: false,
60
+            display: false,
61
+            drawBorder: false
62
+          }
63
+        }]
64
+      },
65
+      layout: {
66
+        padding: {
67
+          left: 0,
68
+          right: 0,
69
+          top: 15,
70
+          bottom: 15
71
+        }
72
+      }
73
+    };
74
+
75
+    ctx = document.getElementById('lineChartExample').getContext("2d");
76
+
77
+    gradientStroke = ctx.createLinearGradient(500, 0, 100, 0);
78
+    gradientStroke.addColorStop(0, '#80b6f4');
79
+    gradientStroke.addColorStop(1, chartColor);
80
+
81
+    gradientFill = ctx.createLinearGradient(0, 170, 0, 50);
82
+    gradientFill.addColorStop(0, "rgba(128, 182, 244, 0)");
83
+    gradientFill.addColorStop(1, "rgba(249, 99, 59, 0.40)");
84
+
85
+    myChart = new Chart(ctx, {
86
+      type: 'line',
87
+      responsive: true,
88
+      data: {
89
+        labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
90
+        datasets: [{
91
+          label: "Active Users",
92
+          borderColor: "#f96332",
93
+          pointBorderColor: "#FFF",
94
+          pointBackgroundColor: "#f96332",
95
+          pointBorderWidth: 2,
96
+          pointHoverRadius: 4,
97
+          pointHoverBorderWidth: 1,
98
+          pointRadius: 4,
99
+          fill: true,
100
+          backgroundColor: gradientFill,
101
+          borderWidth: 2,
102
+          data: [542, 480, 430, 550, 530, 453, 380, 434, 568, 610, 700, 630]
103
+        }]
104
+      },
105
+      options: gradientChartOptionsConfiguration
106
+    });
107
+  },
108
+
109
+  initDashboardPageCharts: function(barData) {
110
+
111
+    gradientChartOptionsConfigurationWithTooltipBlue = {
112
+      maintainAspectRatio: false,
113
+      legend: {
114
+        display: false
115
+      },
116
+
117
+      tooltips: {
118
+        backgroundColor: '#f5f5f5',
119
+        titleFontColor: '#333',
120
+        bodyFontColor: '#666',
121
+        bodySpacing: 4,
122
+        xPadding: 12,
123
+        mode: "nearest",
124
+        intersect: 0,
125
+        position: "nearest"
126
+      },
127
+      responsive: true,
128
+      scales: {
129
+        yAxes: [{
130
+          barPercentage: 1.6,
131
+          gridLines: {
132
+            drawBorder: false,
133
+            color: 'rgba(29,140,248,0.0)',
134
+            zeroLineColor: "transparent",
135
+          },
136
+          ticks: {
137
+            suggestedMin: 60,
138
+            suggestedMax: 125,
139
+            padding: 20,
140
+            fontColor: "#2380f7"
141
+          }
142
+        }],
143
+
144
+        xAxes: [{
145
+          barPercentage: 1.6,
146
+          gridLines: {
147
+            drawBorder: false,
148
+            color: 'rgba(29,140,248,0.1)',
149
+            zeroLineColor: "transparent",
150
+          },
151
+          ticks: {
152
+            padding: 20,
153
+            fontColor: "#2380f7"
154
+          }
155
+        }]
156
+      }
157
+    };
158
+
159
+    gradientChartOptionsConfigurationWithTooltipPurple = {
160
+      maintainAspectRatio: false,
161
+      legend: {
162
+        display: false
163
+      },
164
+
165
+      tooltips: {
166
+        backgroundColor: '#f5f5f5',
167
+        titleFontColor: '#333',
168
+        bodyFontColor: '#666',
169
+        bodySpacing: 4,
170
+        xPadding: 12,
171
+        mode: "nearest",
172
+        intersect: 0,
173
+        position: "nearest"
174
+      },
175
+      responsive: true,
176
+      scales: {
177
+        yAxes: [{
178
+          barPercentage: 1.6,
179
+          gridLines: {
180
+            drawBorder: false,
181
+            color: 'rgba(29,140,248,0.0)',
182
+            zeroLineColor: "transparent",
183
+          },
184
+          ticks: {
185
+            suggestedMin: 60,
186
+            suggestedMax: 125,
187
+            padding: 20,
188
+            fontColor: "#9a9a9a"
189
+          }
190
+        }],
191
+
192
+        xAxes: [{
193
+          barPercentage: 1.6,
194
+          gridLines: {
195
+            drawBorder: false,
196
+            color: 'rgba(225,78,202,0.1)',
197
+            zeroLineColor: "transparent",
198
+          },
199
+          ticks: {
200
+            padding: 20,
201
+            fontColor: "#9a9a9a"
202
+          }
203
+        }]
204
+      }
205
+    };
206
+
207
+    gradientChartOptionsConfigurationWithTooltipOrange = {
208
+      maintainAspectRatio: false,
209
+      legend: {
210
+        display: false
211
+      },
212
+
213
+      tooltips: {
214
+        backgroundColor: '#f5f5f5',
215
+        titleFontColor: '#333',
216
+        bodyFontColor: '#666',
217
+        bodySpacing: 4,
218
+        xPadding: 12,
219
+        mode: "nearest",
220
+        intersect: 0,
221
+        position: "nearest"
222
+      },
223
+      responsive: true,
224
+      scales: {
225
+        yAxes: [{
226
+          barPercentage: 1.6,
227
+          gridLines: {
228
+            drawBorder: false,
229
+            color: 'rgba(29,140,248,0.0)',
230
+            zeroLineColor: "transparent",
231
+          },
232
+          ticks: {
233
+            suggestedMin: 50,
234
+            suggestedMax: 110,
235
+            padding: 20,
236
+            fontColor: "#ff8a76"
237
+          }
238
+        }],
239
+
240
+        xAxes: [{
241
+          barPercentage: 1.6,
242
+          gridLines: {
243
+            drawBorder: false,
244
+            color: 'rgba(220,53,69,0.1)',
245
+            zeroLineColor: "transparent",
246
+          },
247
+          ticks: {
248
+            padding: 20,
249
+            fontColor: "#ff8a76"
250
+          }
251
+        }]
252
+      }
253
+    };
254
+
255
+    gradientChartOptionsConfigurationWithTooltipGreen = {
256
+      maintainAspectRatio: false,
257
+      legend: {
258
+        display: false
259
+      },
260
+
261
+      tooltips: {
262
+        backgroundColor: '#f5f5f5',
263
+        titleFontColor: '#333',
264
+        bodyFontColor: '#666',
265
+        bodySpacing: 4,
266
+        xPadding: 12,
267
+        mode: "nearest",
268
+        intersect: 0,
269
+        position: "nearest"
270
+      },
271
+      responsive: true,
272
+      scales: {
273
+        yAxes: [{
274
+          barPercentage: 1.6,
275
+          gridLines: {
276
+            drawBorder: false,
277
+            color: 'rgba(29,140,248,0.0)',
278
+            zeroLineColor: "transparent",
279
+          },
280
+          ticks: {
281
+            suggestedMin: 50,
282
+            suggestedMax: 125,
283
+            padding: 20,
284
+            fontColor: "#9e9e9e"
285
+          }
286
+        }],
287
+
288
+        xAxes: [{
289
+          barPercentage: 1.6,
290
+          gridLines: {
291
+            drawBorder: false,
292
+            color: 'rgba(0,242,195,0.1)',
293
+            zeroLineColor: "transparent",
294
+          },
295
+          ticks: {
296
+            padding: 20,
297
+            fontColor: "#9e9e9e"
298
+          }
299
+        }]
300
+      }
301
+    };
302
+
303
+
304
+    gradientBarChartConfiguration = {
305
+      maintainAspectRatio: false,
306
+      legend: {
307
+        display: false
308
+      },
309
+
310
+      tooltips: {
311
+        backgroundColor: '#f5f5f5',
312
+        titleFontColor: '#333',
313
+        bodyFontColor: '#666',
314
+        bodySpacing: 4,
315
+        xPadding: 12,
316
+        mode: "nearest",
317
+        intersect: 0,
318
+        position: "nearest"
319
+      },
320
+      responsive: true,
321
+      scales: {
322
+        yAxes: [{
323
+
324
+          gridLines: {
325
+            drawBorder: false,
326
+            color: 'rgba(29,140,248,0.1)',
327
+            zeroLineColor: "transparent",
328
+          },
329
+          ticks: {
330
+            suggestedMin: 3,
331
+            suggestedMax: 6,
332
+            padding: 20,
333
+            fontColor: "#9e9e9e"
334
+          }
335
+        }],
336
+
337
+        xAxes: [{
338
+
339
+          gridLines: {
340
+            drawBorder: false,
341
+            color: 'rgba(29,140,248,0.1)',
342
+            zeroLineColor: "transparent",
343
+          },
344
+          ticks: {
345
+            padding: 20,
346
+            fontColor: "#9e9e9e"
347
+          }
348
+        }]
349
+      }
350
+    };
351
+
352
+    var ctx = document.getElementById("chartLinePurple").getContext("2d");
353
+
354
+    var gradientStroke = ctx.createLinearGradient(0, 230, 0, 50);
355
+
356
+    gradientStroke.addColorStop(1, 'rgba(72,72,176,0.2)');
357
+    gradientStroke.addColorStop(0.2, 'rgba(72,72,176,0.0)');
358
+    gradientStroke.addColorStop(0, 'rgba(119,52,169,0)'); //purple colors
359
+
360
+    var data = {
361
+      labels: ['JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'],
362
+      datasets: [{
363
+        label: "Data",
364
+        fill: true,
365
+        backgroundColor: gradientStroke,
366
+        borderColor: '#d048b6',
367
+        borderWidth: 2,
368
+        borderDash: [],
369
+        borderDashOffset: 0.0,
370
+        pointBackgroundColor: '#d048b6',
371
+        pointBorderColor: 'rgba(255,255,255,0)',
372
+        pointHoverBackgroundColor: '#d048b6',
373
+        pointBorderWidth: 20,
374
+        pointHoverRadius: 4,
375
+        pointHoverBorderWidth: 15,
376
+        pointRadius: 4,
377
+        data: [80, 100, 70, 80, 120, 80],
378
+      }]
379
+    };
380
+
381
+    var myChart = new Chart(ctx, {
382
+      type: 'line',
383
+      data: data,
384
+      options: gradientChartOptionsConfigurationWithTooltipPurple
385
+    });
386
+
387
+
388
+    var ctxGreen = document.getElementById("chartLineGreen").getContext("2d");
389
+
390
+    var gradientStroke = ctx.createLinearGradient(0, 230, 0, 50);
391
+
392
+    gradientStroke.addColorStop(1, 'rgba(66,134,121,0.15)');
393
+    gradientStroke.addColorStop(0.4, 'rgba(66,134,121,0.0)'); //green colors
394
+    gradientStroke.addColorStop(0, 'rgba(66,134,121,0)'); //green colors
395
+
396
+    var data = {
397
+      labels: ['JUL', 'AUG', 'SEP', 'OCT', 'NOV'],
398
+      datasets: [{
399
+        label: "My First dataset",
400
+        fill: true,
401
+        backgroundColor: gradientStroke,
402
+        borderColor: '#00d6b4',
403
+        borderWidth: 2,
404
+        borderDash: [],
405
+        borderDashOffset: 0.0,
406
+        pointBackgroundColor: '#00d6b4',
407
+        pointBorderColor: 'rgba(255,255,255,0)',
408
+        pointHoverBackgroundColor: '#00d6b4',
409
+        pointBorderWidth: 20,
410
+        pointHoverRadius: 4,
411
+        pointHoverBorderWidth: 15,
412
+        pointRadius: 4,
413
+        data: [90, 27, 60, 12, 80],
414
+      }]
415
+    };
416
+
417
+    var myChart = new Chart(ctxGreen, {
418
+      type: 'line',
419
+      data: data,
420
+      options: gradientChartOptionsConfigurationWithTooltipGreen
421
+
422
+    });
423
+
424
+
425
+
426
+    var chart_labels = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];
427
+    var chart_data = [150, 70, 90, 70, 85, 60, 75, 60, 90, 80, 110, 100];
428
+
429
+
430
+    var ctx = document.getElementById("chartBig1").getContext('2d');
431
+
432
+    var gradientStroke = ctx.createLinearGradient(0, 230, 0, 50);
433
+
434
+    gradientStroke.addColorStop(1, 'rgba(72,72,176,0.1)');
435
+    gradientStroke.addColorStop(0.4, 'rgba(72,72,176,0.0)');
436
+    gradientStroke.addColorStop(0, 'rgba(119,52,169,0)'); //purple colors
437
+    var config = {
438
+      type: 'line',
439
+      data: {
440
+        labels: chart_labels,
441
+        datasets: [{
442
+          label: "My First dataset",
443
+          fill: true,
444
+          backgroundColor: gradientStroke,
445
+          borderColor: '#d346b1',
446
+          borderWidth: 2,
447
+          borderDash: [],
448
+          borderDashOffset: 0.0,
449
+          pointBackgroundColor: '#d346b1',
450
+          pointBorderColor: 'rgba(255,255,255,0)',
451
+          pointHoverBackgroundColor: '#d346b1',
452
+          pointBorderWidth: 20,
453
+          pointHoverRadius: 4,
454
+          pointHoverBorderWidth: 15,
455
+          pointRadius: 4,
456
+          data: chart_data,
457
+        }]
458
+      },
459
+      options: gradientChartOptionsConfigurationWithTooltipPurple
460
+    };
461
+    var myChartData = new Chart(ctx, config);
462
+
463
+    $("#0").click(function() {
464
+      var data = myChartData.config.data;
465
+      data.datasets[0].data = chart_data;
466
+      data.labels = chart_labels;
467
+      
468
+      myChartData.update();
469
+    });
470
+    $("#1").click(function() {
471
+      var chart_data = [80, 120, 105, 110, 95, 105, 90, 100, 80, 95, 70, 120];
472
+      var data = myChartData.config.data;
473
+      data.datasets[0].data = chart_data;
474
+      data.labels = chart_labels;
475
+   
476
+      myChartData.update();
477
+    });
478
+
479
+    $("#2").click(function() {
480
+      var chart_data = [60, 80, 65, 130, 80, 105, 90, 130, 70, 115, 60, 130];
481
+      var data = myChartData.config.data;
482
+      data.datasets[0].data = chart_data;
483
+      data.labels = chart_labels;
484
+      myChartData.update();
485
+    });
486
+
487
+
488
+    var ctx = document.getElementById("CountryChart").getContext("2d");
489
+
490
+    var gradientStroke = ctx.createLinearGradient(0, 230, 0, 50);
491
+
492
+    gradientStroke.addColorStop(1, 'rgba(29,140,248,0.2)');
493
+    gradientStroke.addColorStop(0.4, 'rgba(29,140,248,0.0)');
494
+    gradientStroke.addColorStop(0, 'rgba(29,140,248,0)'); //blue colors
495
+
496
+
497
+    var myChart = new Chart(ctx, {
498
+      type: 'bar',
499
+      responsive: true,
500
+      legend: {
501
+        display: false
502
+      },
503
+      data: {
504
+        labels:JSON.parse(barData)['x'], // ['USA', 'GER', 'AUS', 'UK', 'RO', 'BR'],
505
+        datasets: [{
506
+          label: "Intensity",
507
+          fill: true,
508
+          backgroundColor: gradientStroke,
509
+          hoverBackgroundColor: gradientStroke,
510
+          borderColor: '#1f8ef1',
511
+          borderWidth: 2,
512
+          borderDash: [],
513
+          borderDashOffset: 0.0,
514
+          data: JSON.parse(barData)['y'],
515
+        }]
516
+      },
517
+      options: gradientBarChartConfiguration
518
+    });
519
+
520
+  },
521
+
522
+  initGoogleMaps: function() {
523
+    var myLatlng = new google.maps.LatLng(40.748817, -73.985428);
524
+    var mapOptions = {
525
+      zoom: 13,
526
+      center: myLatlng,
527
+      scrollwheel: false, //we disable de scroll over the map, it is a really annoing when you scroll through page
528
+      styles: [{
529
+          "elementType": "geometry",
530
+          "stylers": [{
531
+            "color": "#1d2c4d"
532
+          }]
533
+        },
534
+        {
535
+          "elementType": "labels.text.fill",
536
+          "stylers": [{
537
+            "color": "#8ec3b9"
538
+          }]
539
+        },
540
+        {
541
+          "elementType": "labels.text.stroke",
542
+          "stylers": [{
543
+            "color": "#1a3646"
544
+          }]
545
+        },
546
+        {
547
+          "featureType": "administrative.country",
548
+          "elementType": "geometry.stroke",
549
+          "stylers": [{
550
+            "color": "#4b6878"
551
+          }]
552
+        },
553
+        {
554
+          "featureType": "administrative.land_parcel",
555
+          "elementType": "labels.text.fill",
556
+          "stylers": [{
557
+            "color": "#64779e"
558
+          }]
559
+        },
560
+        {
561
+          "featureType": "administrative.province",
562
+          "elementType": "geometry.stroke",
563
+          "stylers": [{
564
+            "color": "#4b6878"
565
+          }]
566
+        },
567
+        {
568
+          "featureType": "landscape.man_made",
569
+          "elementType": "geometry.stroke",
570
+          "stylers": [{
571
+            "color": "#334e87"
572
+          }]
573
+        },
574
+        {
575
+          "featureType": "landscape.natural",
576
+          "elementType": "geometry",
577
+          "stylers": [{
578
+            "color": "#023e58"
579
+          }]
580
+        },
581
+        {
582
+          "featureType": "poi",
583
+          "elementType": "geometry",
584
+          "stylers": [{
585
+            "color": "#283d6a"
586
+          }]
587
+        },
588
+        {
589
+          "featureType": "poi",
590
+          "elementType": "labels.text.fill",
591
+          "stylers": [{
592
+            "color": "#6f9ba5"
593
+          }]
594
+        },
595
+        {
596
+          "featureType": "poi",
597
+          "elementType": "labels.text.stroke",
598
+          "stylers": [{
599
+            "color": "#1d2c4d"
600
+          }]
601
+        },
602
+        {
603
+          "featureType": "poi.park",
604
+          "elementType": "geometry.fill",
605
+          "stylers": [{
606
+            "color": "#023e58"
607
+          }]
608
+        },
609
+        {
610
+          "featureType": "poi.park",
611
+          "elementType": "labels.text.fill",
612
+          "stylers": [{
613
+            "color": "#3C7680"
614
+          }]
615
+        },
616
+        {
617
+          "featureType": "road",
618
+          "elementType": "geometry",
619
+          "stylers": [{
620
+            "color": "#304a7d"
621
+          }]
622
+        },
623
+        {
624
+          "featureType": "road",
625
+          "elementType": "labels.text.fill",
626
+          "stylers": [{
627
+            "color": "#98a5be"
628
+          }]
629
+        },
630
+        {
631
+          "featureType": "road",
632
+          "elementType": "labels.text.stroke",
633
+          "stylers": [{
634
+            "color": "#1d2c4d"
635
+          }]
636
+        },
637
+        {
638
+          "featureType": "road.highway",
639
+          "elementType": "geometry",
640
+          "stylers": [{
641
+            "color": "#2c6675"
642
+          }]
643
+        },
644
+        {
645
+          "featureType": "road.highway",
646
+          "elementType": "geometry.fill",
647
+          "stylers": [{
648
+            "color": "#9d2a80"
649
+          }]
650
+        },
651
+        {
652
+          "featureType": "road.highway",
653
+          "elementType": "geometry.stroke",
654
+          "stylers": [{
655
+            "color": "#9d2a80"
656
+          }]
657
+        },
658
+        {
659
+          "featureType": "road.highway",
660
+          "elementType": "labels.text.fill",
661
+          "stylers": [{
662
+            "color": "#b0d5ce"
663
+          }]
664
+        },
665
+        {
666
+          "featureType": "road.highway",
667
+          "elementType": "labels.text.stroke",
668
+          "stylers": [{
669
+            "color": "#023e58"
670
+          }]
671
+        },
672
+        {
673
+          "featureType": "transit",
674
+          "elementType": "labels.text.fill",
675
+          "stylers": [{
676
+            "color": "#98a5be"
677
+          }]
678
+        },
679
+        {
680
+          "featureType": "transit",
681
+          "elementType": "labels.text.stroke",
682
+          "stylers": [{
683
+            "color": "#1d2c4d"
684
+          }]
685
+        },
686
+        {
687
+          "featureType": "transit.line",
688
+          "elementType": "geometry.fill",
689
+          "stylers": [{
690
+            "color": "#283d6a"
691
+          }]
692
+        },
693
+        {
694
+          "featureType": "transit.station",
695
+          "elementType": "geometry",
696
+          "stylers": [{
697
+            "color": "#3a4762"
698
+          }]
699
+        },
700
+        {
701
+          "featureType": "water",
702
+          "elementType": "geometry",
703
+          "stylers": [{
704
+            "color": "#0e1626"
705
+          }]
706
+        },
707
+        {
708
+          "featureType": "water",
709
+          "elementType": "labels.text.fill",
710
+          "stylers": [{
711
+            "color": "#4e6d70"
712
+          }]
713
+        }
714
+      ]
715
+    };
716
+
717
+    var map = new google.maps.Map(document.getElementById("map"), mapOptions);
718
+
719
+    var marker = new google.maps.Marker({
720
+      position: myLatlng,
721
+      title: "Hello World!"
722
+    });
723
+
724
+    // To add the marker to the map, call setMap();
725
+    marker.setMap(map);
726
+  },
727
+
728
+  showNotification: function(from, align) {
729
+    color = Math.floor((Math.random() * 4) + 1);
730
+
731
+    $.notify({
732
+      icon: "tim-icons icon-bell-55",
733
+      message: "Welcome to <b>Black Dashboard</b> - a beautiful freebie for every web developer."
734
+
735
+    }, {
736
+      type: type[color],
737
+      timer: 8000,
738
+      placement: {
739
+        from: from,
740
+        align: align
741
+      }
742
+    });
743
+  }
744
+
745
+};

BIN
app/base/static/assets/fonts/nucleo.eot View File


BIN
app/base/static/assets/fonts/nucleo.ttf View File


BIN
app/base/static/assets/fonts/nucleo.woff View File


BIN
app/base/static/assets/fonts/nucleo.woff2 View File


BIN
app/base/static/assets/img/12345.png View File


BIN
app/base/static/assets/img/anime3.png View File


BIN
app/base/static/assets/img/anime6.png View File


BIN
app/base/static/assets/img/apple-icon.png View File


BIN
app/base/static/assets/img/bg5.jpg View File


BIN
app/base/static/assets/img/default-avatar.png View File


BIN
app/base/static/assets/img/emilyz.jpg View File


BIN
app/base/static/assets/img/favicon.png View File


BIN
app/base/static/assets/img/header.jpg View File


BIN
app/base/static/assets/img/img_3115.jpg View File


BIN
app/base/static/assets/img/james.jpg View File


BIN
app/base/static/assets/img/mike.jpg View File


BIN
app/base/static/assets/img/now-logo.png View File


+ 255
- 0
app/base/static/assets/js/black-dashboard.js View File

@@ -0,0 +1,255 @@
1
+/*!
2
+
3
+=========================================================
4
+* Black Dashboard - v1.0.1
5
+=========================================================
6
+
7
+* Product Page: https://www.creative-tim.com/product/black-dashboard
8
+* Copyright 2019 Creative Tim (https://www.creative-tim.com)
9
+
10
+
11
+* Coded by Creative Tim
12
+
13
+=========================================================
14
+
15
+* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
16
+
17
+*/
18
+
19
+var transparent = true;
20
+var transparentDemo = true;
21
+var fixedTop = false;
22
+
23
+var navbar_initialized = false;
24
+var backgroundOrange = false;
25
+var sidebar_mini_active = false;
26
+var toggle_initialized = false;
27
+
28
+var $html = $('html');
29
+var $body = $('body');
30
+var $navbar_minimize_fixed = $('.navbar-minimize-fixed');
31
+var $collapse = $('.collapse');
32
+var $navbar = $('.navbar');
33
+var $tagsinput = $('.tagsinput');
34
+var $selectpicker = $('.selectpicker');
35
+var $navbar_color = $('.navbar[color-on-scroll]');
36
+var $full_screen_map = $('.full-screen-map');
37
+var $datetimepicker = $('.datetimepicker');
38
+var $datepicker = $('.datepicker');
39
+var $timepicker = $('.timepicker');
40
+
41
+var seq = 0,
42
+  delays = 80,
43
+  durations = 500;
44
+var seq2 = 0,
45
+  delays2 = 80,
46
+  durations2 = 500;
47
+
48
+(function() {
49
+  var isWindows = navigator.platform.indexOf('Win') > -1 ? true : false;
50
+
51
+  if (isWindows) {
52
+    // if we are on windows OS we activate the perfectScrollbar function
53
+    if ($('.main-panel').length != 0) {
54
+      var ps = new PerfectScrollbar('.main-panel', {
55
+        wheelSpeed: 2,
56
+        wheelPropagation: true,
57
+        minScrollbarLength: 20,
58
+        suppressScrollX: true
59
+      });
60
+    }
61
+
62
+    if ($('.sidebar .sidebar-wrapper').length != 0) {
63
+
64
+      var ps1 = new PerfectScrollbar('.sidebar .sidebar-wrapper');
65
+      $('.table-responsive').each(function() {
66
+        var ps2 = new PerfectScrollbar($(this)[0]);
67
+      });
68
+    }
69
+
70
+
71
+
72
+    $html.addClass('perfect-scrollbar-on');
73
+  } else {
74
+    $html.addClass('perfect-scrollbar-off');
75
+  }
76
+})();
77
+
78
+$(document).ready(function() {
79
+
80
+  var scroll_start = 0;
81
+  var startchange = $('.row');
82
+  var offset = startchange.offset();
83
+  var scrollElement = navigator.platform.indexOf('Win') > -1 ? $(".ps") : $(window);
84
+  scrollElement.scroll(function() {
85
+
86
+    scroll_start = $(this).scrollTop();
87
+
88
+    if (scroll_start > 50) {
89
+      $(".navbar-minimize-fixed").css('opacity', '1');
90
+    } else {
91
+      $(".navbar-minimize-fixed").css('opacity', '0');
92
+    }
93
+  });
94
+
95
+
96
+  $(document).scroll(function() {
97
+    scroll_start = $(this).scrollTop();
98
+    if (scroll_start > offset.top) {
99
+      $(".navbar-minimize-fixed").css('opacity', '1');
100
+    } else {
101
+      $(".navbar-minimize-fixed").css('opacity', '0');
102
+    }
103
+  });
104
+
105
+  if ($('.full-screen-map').length == 0 && $('.bd-docs').length == 0) {
106
+    // On click navbar-collapse the menu will be white not transparent
107
+    $('.collapse').on('show.bs.collapse', function() {
108
+      $(this).closest('.navbar').removeClass('navbar-transparent').addClass('bg-white');
109
+    }).on('hide.bs.collapse', function() {
110
+      $(this).closest('.navbar').addClass('navbar-transparent').removeClass('bg-white');
111
+    });
112
+  }
113
+
114
+  blackDashboard.initMinimizeSidebar();
115
+
116
+  $navbar = $('.navbar[color-on-scroll]');
117
+  scroll_distance = $navbar.attr('color-on-scroll') || 500;
118
+
119
+  // Check if we have the class "navbar-color-on-scroll" then add the function to remove the class "navbar-transparent" so it will transform to a plain color.
120
+  if ($('.navbar[color-on-scroll]').length != 0) {
121
+    blackDashboard.checkScrollForTransparentNavbar();
122
+    $(window).on('scroll', blackDashboard.checkScrollForTransparentNavbar)
123
+  }
124
+
125
+  $('.form-control').on("focus", function() {
126
+    $(this).parent('.input-group').addClass("input-group-focus");
127
+  }).on("blur", function() {
128
+    $(this).parent(".input-group").removeClass("input-group-focus");
129
+  });
130
+
131
+  // Activate bootstrapSwitch
132
+  $('.bootstrap-switch').each(function() {
133
+    $this = $(this);
134
+    data_on_label = $this.data('on-label') || '';
135
+    data_off_label = $this.data('off-label') || '';
136
+
137
+    $this.bootstrapSwitch({
138
+      onText: data_on_label,
139
+      offText: data_off_label
140
+    });
141
+  });
142
+});
143
+
144
+$(document).on('click', '.navbar-toggle', function() {
145
+  var $toggle = $(this);
146
+
147
+  if (blackDashboard.misc.navbar_menu_visible == 1) {
148
+    $html.removeClass('nav-open');
149
+    blackDashboard.misc.navbar_menu_visible = 0;
150
+    setTimeout(function() {
151
+      $toggle.removeClass('toggled');
152
+      $('.bodyClick').remove();
153
+    }, 550);
154
+
155
+  } else {
156
+    setTimeout(function() {
157
+      $toggle.addClass('toggled');
158
+    }, 580);
159
+
160
+    var div = '<div class="bodyClick"></div>';
161
+    $(div).appendTo('body').click(function() {
162
+      $html.removeClass('nav-open');
163
+      blackDashboard.misc.navbar_menu_visible = 0;
164
+      setTimeout(function() {
165
+        $toggle.removeClass('toggled');
166
+        $('.bodyClick').remove();
167
+      }, 550);
168
+    });
169
+
170
+    $html.addClass('nav-open');
171
+    blackDashboard.misc.navbar_menu_visible = 1;
172
+  }
173
+});
174
+
175
+$(window).resize(function() {
176
+  // reset the seq for charts drawing animations
177
+  seq = seq2 = 0;
178
+
179
+  if ($full_screen_map.length == 0 && $('.bd-docs').length == 0) {
180
+    var isExpanded = $navbar.find('[data-toggle="collapse"]').attr("aria-expanded");
181
+    if ($navbar.hasClass('bg-white') && $(window).width() > 991) {
182
+      $navbar.removeClass('bg-white').addClass('navbar-transparent');
183
+    } else if ($navbar.hasClass('navbar-transparent') && $(window).width() < 991 && isExpanded != "false") {
184
+      $navbar.addClass('bg-white').removeClass('navbar-transparent');
185
+    }
186
+  }
187
+});
188
+
189
+blackDashboard = {
190
+  misc: {
191
+    navbar_menu_visible: 0
192
+  },
193
+
194
+  initMinimizeSidebar: function() {
195
+    if ($('.sidebar-mini').length != 0) {
196
+      sidebar_mini_active = true;
197
+    }
198
+
199
+    $('#minimizeSidebar').click(function() {
200
+      var $btn = $(this);
201
+
202
+      if (sidebar_mini_active == true) {
203
+        $('body').removeClass('sidebar-mini');
204
+        sidebar_mini_active = false;
205
+        blackDashboard.showSidebarMessage('Sidebar mini deactivated...');
206
+      } else {
207
+        $('body').addClass('sidebar-mini');
208
+        sidebar_mini_active = true;
209
+        blackDashboard.showSidebarMessage('Sidebar mini activated...');
210
+      }
211
+
212
+      // we simulate the window Resize so the charts will get updated in realtime.
213
+      var simulateWindowResize = setInterval(function() {
214
+        window.dispatchEvent(new Event('resize'));
215
+      }, 180);
216
+
217
+      // we stop the simulation of Window Resize after the animations are completed
218
+      setTimeout(function() {
219
+        clearInterval(simulateWindowResize);
220
+      }, 1000);
221
+    });
222
+  },
223
+
224
+  showSidebarMessage: function(message) {
225
+    try {
226
+      $.notify({
227
+        icon: "tim-icons ui-1_bell-53",
228
+        message: message
229
+      }, {
230
+        type: 'info',
231
+        timer: 4000,
232
+        placement: {
233
+          from: 'top',
234
+          align: 'right'
235
+        }
236
+      });
237
+    } catch (e) {
238
+      console.log('Notify library is missing, please make sure you have the notifications library added.');
239
+    }
240
+
241
+  }
242
+
243
+};
244
+
245
+function hexToRGB(hex, alpha) {
246
+  var r = parseInt(hex.slice(1, 3), 16),
247
+    g = parseInt(hex.slice(3, 5), 16),
248
+    b = parseInt(hex.slice(5, 7), 16);
249
+
250
+  if (alpha) {
251
+    return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
252
+  } else {
253
+    return "rgb(" + r + ", " + g + ", " + b + ")";
254
+  }
255
+}

+ 1
- 0
app/base/static/assets/js/black-dashboard.js.map View File

@@ -0,0 +1 @@
1
+{"version":3,"sources":["_site_dashboard_free/assets/js/dashboard-free.js"],"names":["transparent","transparentDemo","fixedTop","navbar_initialized","backgroundOrange","sidebar_mini_active","toggle_initialized","$html","$","$body","$navbar_minimize_fixed","$collapse","$navbar","$tagsinput","$selectpicker","$navbar_color","$full_screen_map","$datetimepicker","$datepicker","$timepicker","seq","delays","durations","seq2","delays2","durations2","hexToRGB","hex","alpha","r","parseInt","slice","g","b","navigator","platform","indexOf","length","PerfectScrollbar","wheelSpeed","wheelPropagation","minScrollbarLength","suppressScrollX","each","this","addClass","document","ready","offset","window","scroll","scrollTop","css","top","on","closest","removeClass","blackDashboard","initMinimizeSidebar","scroll_distance","attr","checkScrollForTransparentNavbar","parent","$this","data_on_label","data","data_off_label","bootstrapSwitch","onText","offText","$toggle","misc","navbar_menu_visible","setTimeout","remove","appendTo","click","resize","isExpanded","find","hasClass","width","showSidebarMessage","simulateWindowResize","setInterval","dispatchEvent","Event","clearInterval","message","notify","icon","type","timer","placement","from","align","e","console","log"],"mappings":"AAkBA,IAAIA,aAAc,EACdC,iBAAkB,EAClBC,UAAW,EAEXC,oBAAqB,EACrBC,kBAAmB,EACnBC,qBAAsB,EACtBC,oBAAqB,EAErBC,MAAQC,EAAE,QACVC,MAAQD,EAAE,QACVE,uBAAyBF,EAAE,0BAC3BG,UAAYH,EAAE,aACdI,QAAUJ,EAAE,WACZK,WAAaL,EAAE,cACfM,cAAgBN,EAAE,iBAClBO,cAAgBP,EAAE,4BAClBQ,iBAAmBR,EAAE,oBACrBS,gBAAkBT,EAAE,mBACpBU,YAAcV,EAAE,eAChBW,YAAcX,EAAE,eAEhBY,IAAM,EAAGC,OAAS,GAAIC,UAAY,IAClCC,KAAO,EAAGC,QAAU,GAAIC,WAAa,IAuMzC,SAASC,SAASC,EAAKC,GACnB,IAAIC,EAAIC,SAASH,EAAII,MAAM,EAAG,GAAI,IAC9BC,EAAIF,SAASH,EAAII,MAAM,EAAG,GAAI,IAC9BE,EAAIH,SAASH,EAAII,MAAM,EAAG,GAAI,IAElC,OAAIH,EACO,QAAUC,EAAI,KAAOG,EAAI,KAAOC,EAAI,KAAOL,EAAQ,IAEnD,OAASC,EAAI,KAAOG,EAAI,KAAOC,EAAI,KA7MlD,WAGI,IAFqD,EAArCC,UAAUC,SAASC,QAAQ,OAE7B,CAEX,GAA8B,GAA3B5B,EAAE,eAAe6B,OACX,IAAIC,iBAAiB,cAAc,CAC1CC,WAAY,EACZC,kBAAkB,EAClBC,mBAAoB,GACpBC,iBAAiB,IAIrB,GAA4C,GAAzClC,EAAE,6BAA6B6B,OAAY,CAElC,IAAIC,iBAAiB,6BAC/B9B,EAAE,qBAAqBmC,KAAK,WAChB,IAAIL,iBAAiB9B,EAAEoC,MAAM,MAMzCrC,MAAMsC,SAAS,6BAEftC,MAAMsC,SAAS,yBA1BtB,GA8BArC,EAAEsC,UAAUC,MAAM,WAEhB,IAEIC,EADYxC,EAAE,QACOwC,WACgC,EAArCd,UAAUC,SAASC,QAAQ,OAAc5B,EAAE,OAAOA,EAAEyC,SAC1DC,OAAO,WAID,GAFH1C,EAAEoC,MAAMO,YAGrB3C,EAAE,0BAA0B4C,IAAI,UAAW,KAE3C5C,EAAE,0BAA0B4C,IAAI,UAAW,OAK/C5C,EAAEsC,UAAUI,OAAO,WACF1C,EAAEoC,MAAMO,YACLH,EAAOK,IACvB7C,EAAE,0BAA0B4C,IAAI,UAAW,KAE3C5C,EAAE,0BAA0B4C,IAAI,UAAW,OAIX,GAAhC5C,EAAE,oBAAoB6B,QAAuC,GAAxB7B,EAAE,YAAY6B,QAErD7B,EAAE,aAAa8C,GAAG,mBAAoB,WAClC9C,EAAEoC,MAAMW,QAAQ,WAAWC,YAAY,sBAAsBX,SAAS,cACvES,GAAG,mBAAoB,WACtB9C,EAAEoC,MAAMW,QAAQ,WAAWV,SAAS,sBAAsBW,YAAY,cAI5EC,eAAeC,sBAEf9C,QAAUJ,EAAE,4BACZmD,gBAAkB/C,QAAQgD,KAAK,oBAAsB,IAGV,GAAxCpD,EAAE,4BAA4B6B,SAC7BoB,eAAeI,kCACfrD,EAAEyC,QAAQK,GAAG,SAAUG,eAAeI,kCAG1CrD,EAAE,iBAAiB8C,GAAG,QAAS,WAC3B9C,EAAEoC,MAAMkB,OAAO,gBAAgBjB,SAAS,uBACzCS,GAAG,OAAQ,WACV9C,EAAEoC,MAAMkB,OAAO,gBAAgBN,YAAY,uBAI/ChD,EAAE,qBAAqBmC,KAAK,WACxBoB,MAAQvD,EAAEoC,MACVoB,cAAgBD,MAAME,KAAK,aAAe,GAC1CC,eAAiBH,MAAME,KAAK,cAAgB,GAE5CF,MAAMI,gBAAgB,CAClBC,OAAQJ,cACRK,QAASH,qBAKnB1D,EAAEsC,UAAUQ,GAAG,QAAS,iBAAkB,WACtC,IAAIgB,EAAU9D,EAAEoC,MAEhB,GAA8C,GAA3Ca,eAAec,KAAKC,oBACnBjE,MAAMiD,YAAY,YAClBC,eAAec,KAAKC,oBAAsB,EAC1CC,WAAW,WACPH,EAAQd,YAAY,WACpBhD,EAAE,cAAckE,UACjB,SAEA,CACHD,WAAW,WACPH,EAAQzB,SAAS,YAClB,KAGHrC,EADU,iCACHmE,SAAS,QAAQC,MAAM,WAC1BrE,MAAMiD,YAAY,YAClBC,eAAec,KAAKC,oBAAsB,EACtCC,WAAW,WACPH,EAAQd,YAAY,WACpBhD,EAAE,cAAckE,UAClB,OAGVnE,MAAMsC,SAAS,YACfY,eAAec,KAAKC,oBAAsB,KAIlDhE,EAAEyC,QAAQ4B,OAAO,WAIb,GAFAzD,IAAMG,KAAO,EAEiB,GAA3BP,iBAAiBqB,QAAuC,GAAxB7B,EAAE,YAAY6B,OAAY,CAC3D,IAAIyC,EAAalE,QAAQmE,KAAK,4BAA4BnB,KAAK,iBAC3DhD,QAAQoE,SAAS,aAAmC,IAApBxE,EAAEyC,QAAQgC,QAC5CrE,QAAQ4C,YAAY,YAAYX,SAAS,sBAChCjC,QAAQoE,SAAS,uBAAyBxE,EAAEyC,QAAQgC,QAAU,KAAqB,SAAdH,GAC9ElE,QAAQiC,SAAS,YAAYW,YAAY,yBAKjDC,eAAiB,CACfc,KAAK,CACDC,oBAAqB,GAGzBd,oBAAoB,WACgB,GAA7BlD,EAAE,iBAAiB6B,SACpBhC,qBAAsB,GAGxBG,EAAE,oBAAoBoE,MAAM,WACbpE,EAAEoC,MAEa,GAAvBvC,qBACCG,EAAE,QAAQgD,YAAY,gBACtBnD,qBAAsB,EACtBoD,eAAeyB,mBAAmB,iCAElC1E,EAAE,QAAQqC,SAAS,gBACnBxC,qBAAsB,EACtBoD,eAAeyB,mBAAmB,8BAItC,IAAIC,EAAuBC,YAAY,WACnCnC,OAAOoC,cAAc,IAAIC,MAAM,YACjC,KAGFb,WAAW,WACPc,cAAcJ,IAChB,QAIVD,mBAAoB,SAASM,GAC3B,IACEhF,EAAEiF,OAAO,CACLC,KAAM,yBACNF,QAASA,GACT,CACEG,KAAM,OACNC,MAAO,IACPC,UAAW,CACPC,KAAM,MACNC,MAAO,WAGjB,MAAOC,GACPC,QAAQC,IAAI"}

+ 2
- 0
app/base/static/assets/js/black-dashboard.min.js View File

@@ -0,0 +1,2 @@
1
+var transparent=!0,transparentDemo=!0,fixedTop=!1,navbar_initialized=!1,backgroundOrange=!1,sidebar_mini_active=!1,toggle_initialized=!1,$html=$("html"),$body=$("body"),$navbar_minimize_fixed=$(".navbar-minimize-fixed"),$collapse=$(".collapse"),$navbar=$(".navbar"),$tagsinput=$(".tagsinput"),$selectpicker=$(".selectpicker"),$navbar_color=$(".navbar[color-on-scroll]"),$full_screen_map=$(".full-screen-map"),$datetimepicker=$(".datetimepicker"),$datepicker=$(".datepicker"),$timepicker=$(".timepicker"),seq=0,delays=80,durations=500,seq2=0,delays2=80,durations2=500;function hexToRGB(a,e){var i=parseInt(a.slice(1,3),16),n=parseInt(a.slice(3,5),16),s=parseInt(a.slice(5,7),16);return e?"rgba("+i+", "+n+", "+s+", "+e+")":"rgb("+i+", "+n+", "+s+")"}!function(){if(-1<navigator.platform.indexOf("Win")){if(0!=$(".main-panel").length)new PerfectScrollbar(".main-panel",{wheelSpeed:2,wheelPropagation:!0,minScrollbarLength:20,suppressScrollX:!0});if(0!=$(".sidebar .sidebar-wrapper").length){new PerfectScrollbar(".sidebar .sidebar-wrapper");$(".table-responsive").each(function(){new PerfectScrollbar($(this)[0])})}$html.addClass("perfect-scrollbar-on")}else $html.addClass("perfect-scrollbar-off")}(),$(document).ready(function(){var a=$(".row").offset();(-1<navigator.platform.indexOf("Win")?$(".ps"):$(window)).scroll(function(){50<$(this).scrollTop()?$(".navbar-minimize-fixed").css("opacity","1"):$(".navbar-minimize-fixed").css("opacity","0")}),$(document).scroll(function(){$(this).scrollTop()>a.top?$(".navbar-minimize-fixed").css("opacity","1"):$(".navbar-minimize-fixed").css("opacity","0")}),0==$(".full-screen-map").length&&0==$(".bd-docs").length&&$(".collapse").on("show.bs.collapse",function(){$(this).closest(".navbar").removeClass("navbar-transparent").addClass("bg-white")}).on("hide.bs.collapse",function(){$(this).closest(".navbar").addClass("navbar-transparent").removeClass("bg-white")}),blackDashboard.initMinimizeSidebar(),$navbar=$(".navbar[color-on-scroll]"),scroll_distance=$navbar.attr("color-on-scroll")||500,0!=$(".navbar[color-on-scroll]").length&&(blackDashboard.checkScrollForTransparentNavbar(),$(window).on("scroll",blackDashboard.checkScrollForTransparentNavbar)),$(".form-control").on("focus",function(){$(this).parent(".input-group").addClass("input-group-focus")}).on("blur",function(){$(this).parent(".input-group").removeClass("input-group-focus")}),$(".bootstrap-switch").each(function(){$this=$(this),data_on_label=$this.data("on-label")||"",data_off_label=$this.data("off-label")||"",$this.bootstrapSwitch({onText:data_on_label,offText:data_off_label})})}),$(document).on("click",".navbar-toggle",function(){var a=$(this);if(1==blackDashboard.misc.navbar_menu_visible)$html.removeClass("nav-open"),blackDashboard.misc.navbar_menu_visible=0,setTimeout(function(){a.removeClass("toggled"),$(".bodyClick").remove()},550);else{setTimeout(function(){a.addClass("toggled")},580);$('<div class="bodyClick"></div>').appendTo("body").click(function(){$html.removeClass("nav-open"),blackDashboard.misc.navbar_menu_visible=0,setTimeout(function(){a.removeClass("toggled"),$(".bodyClick").remove()},550)}),$html.addClass("nav-open"),blackDashboard.misc.navbar_menu_visible=1}}),$(window).resize(function(){if(seq=seq2=0,0==$full_screen_map.length&&0==$(".bd-docs").length){var a=$navbar.find('[data-toggle="collapse"]').attr("aria-expanded");$navbar.hasClass("bg-white")&&991<$(window).width()?$navbar.removeClass("bg-white").addClass("navbar-transparent"):$navbar.hasClass("navbar-transparent")&&$(window).width()<991&&"false"!=a&&$navbar.addClass("bg-white").removeClass("navbar-transparent")}}),blackDashboard={misc:{navbar_menu_visible:0},initMinimizeSidebar:function(){0!=$(".sidebar-mini").length&&(sidebar_mini_active=!0),$("#minimizeSidebar").click(function(){$(this);1==sidebar_mini_active?($("body").removeClass("sidebar-mini"),sidebar_mini_active=!1,blackDashboard.showSidebarMessage("Sidebar mini deactivated...")):($("body").addClass("sidebar-mini"),sidebar_mini_active=!0,blackDashboard.showSidebarMessage("Sidebar mini activated..."));var a=setInterval(function(){window.dispatchEvent(new Event("resize"))},180);setTimeout(function(){clearInterval(a)},1e3)})},showSidebarMessage:function(a){try{$.notify({icon:"tim-icons ui-1_bell-53",message:a},{type:"info",timer:4e3,placement:{from:"top",align:"right"}})}catch(a){console.log("Notify library is missing, please make sure you have the notifications library added.")}}};
2
+//# sourceMappingURL=_site_dashboard_free/assets/js/dashboard-free.js.map

+ 6
- 0
app/base/static/assets/js/core/bootstrap.min.js
File diff suppressed because it is too large
View File


+ 4
- 0
app/base/static/assets/js/core/jquery.min.js
File diff suppressed because it is too large
View File


+ 4
- 0
app/base/static/assets/js/core/popper.min.js
File diff suppressed because it is too large
View File


+ 432
- 0
app/base/static/assets/js/plugins/bootstrap-notify.js View File

@@ -0,0 +1,432 @@
1
+/*
2
+
3
+
4
+
5
+     Creative Tim Modifications
6
+
7
+     Lines: 238, 239 was changed from top: 5px to top: 50% and we added margin-top: -13px. In this way the close button will be aligned vertically
8
+     Line:222 - modified when the icon is set, we add the class "alert-with-icon", so there will be enough space for the icon.
9
+
10
+
11
+
12
+
13
+*/
14
+
15
+
16
+/*
17
+ * Project: Bootstrap Notify = v3.1.5
18
+ * Description: Turns standard Bootstrap alerts into "Growl-like" notifications.
19
+ * Author: Mouse0270 aka Robert McIntosh
20
+ * License: MIT License
21
+ * Website: https://github.com/mouse0270/bootstrap-growl
22
+ */
23
+
24
+/* global define:false, require: false, jQuery:false */
25
+
26
+(function(factory) {
27
+  if (typeof define === 'function' && define.amd) {
28
+    // AMD. Register as an anonymous module.
29
+    define(['jquery'], factory);
30
+  } else if (typeof exports === 'object') {
31
+    // Node/CommonJS
32
+    factory(require('jquery'));
33
+  } else {
34
+    // Browser globals
35
+    factory(jQuery);
36
+  }
37
+}(function($) {
38
+  // Create the defaults once
39
+  var defaults = {
40
+    element: 'body',
41
+    position: null,
42
+    type: "info",
43
+    allow_dismiss: true,
44
+    allow_duplicates: true,
45
+    newest_on_top: false,
46
+    showProgressbar: false,
47
+    placement: {
48
+      from: "top",
49
+      align: "right"
50
+    },
51
+    offset: 20,
52
+    spacing: 10,
53
+    z_index: 1060,
54
+    delay: 5000,
55
+    timer: 1000,
56
+    url_target: '_blank',
57
+    mouse_over: null,
58
+    animate: {
59
+      enter: 'animated fadeInDown',
60
+      exit: 'animated fadeOutUp'
61
+    },
62
+    onShow: null,
63
+    onShown: null,
64
+    onClose: null,
65
+    onClosed: null,
66
+    onClick: null,
67
+    icon_type: 'class',
68
+    template: '<div data-notify="container" class="col-xs-11 col-sm-4 alert alert-{0}" role="alert"><button type="button" aria-hidden="true" class="close" data-notify="dismiss"><i class="tim-icons icon-simple-remove"></i></button><span data-notify="icon"></span> <span data-notify="title">{1}</span> <span data-notify="message">{2}</span><div class="progress" data-notify="progressbar"><div class="progress-bar progress-bar-{0}" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div></div><a href="{3}" target="{4}" data-notify="url"></a></div>'
69
+  };
70
+
71
+  String.format = function() {
72
+    var args = arguments;
73
+    var str = arguments[0];
74
+    return str.replace(/(\{\{\d\}\}|\{\d\})/g, function(str) {
75
+      if (str.substring(0, 2) === "{{") return str;
76
+      var num = parseInt(str.match(/\d/)[0]);
77
+      return args[num + 1];
78
+    });
79
+  };
80
+
81
+  function isDuplicateNotification(notification) {
82
+    var isDupe = false;
83
+
84
+    $('[data-notify="container"]').each(function(i, el) {
85
+      var $el = $(el);
86
+      var title = $el.find('[data-notify="title"]').html().trim();
87
+      var message = $el.find('[data-notify="message"]').html().trim();
88
+
89
+      // The input string might be different than the actual parsed HTML string!
90
+      // (<br> vs <br /> for example)
91
+      // So we have to force-parse this as HTML here!
92
+      var isSameTitle = title === $("<div>" + notification.settings.content.title + "</div>").html().trim();
93
+      var isSameMsg = message === $("<div>" + notification.settings.content.message + "</div>").html().trim();
94
+      var isSameType = $el.hasClass('alert-' + notification.settings.type);
95
+
96
+      if (isSameTitle && isSameMsg && isSameType) {
97
+        //we found the dupe. Set the var and stop checking.
98
+        isDupe = true;
99
+      }
100
+      return !isDupe;
101
+    });
102
+
103
+    return isDupe;
104
+  }
105
+
106
+  function Notify(element, content, options) {
107
+    // Setup Content of Notify
108
+    var contentObj = {
109
+      content: {
110
+        message: typeof content === 'object' ? content.message : content,
111
+        title: content.title ? content.title : '',
112
+        icon: content.icon ? content.icon : '',
113
+        url: content.url ? content.url : '#',
114
+        target: content.target ? content.target : '-'
115
+      }
116
+    };
117
+
118
+    options = $.extend(true, {}, contentObj, options);
119
+    this.settings = $.extend(true, {}, defaults, options);
120
+    this._defaults = defaults;
121
+    if (this.settings.content.target === "-") {
122
+      this.settings.content.target = this.settings.url_target;
123
+    }
124
+    this.animations = {
125
+      start: 'webkitAnimationStart oanimationstart MSAnimationStart animationstart',
126
+      end: 'webkitAnimationEnd oanimationend MSAnimationEnd animationend'
127
+    };
128
+
129
+    if (typeof this.settings.offset === 'number') {
130
+      this.settings.offset = {
131
+        x: this.settings.offset,
132
+        y: this.settings.offset
133
+      };
134
+    }
135
+
136
+    //if duplicate messages are not allowed, then only continue if this new message is not a duplicate of one that it already showing
137
+    if (this.settings.allow_duplicates || (!this.settings.allow_duplicates && !isDuplicateNotification(this))) {
138
+      this.init();
139
+    }
140
+  }
141
+
142
+  $.extend(Notify.prototype, {
143
+    init: function() {
144
+      var self = this;
145
+
146
+      this.buildNotify();
147
+      if (this.settings.content.icon) {
148
+        this.setIcon();
149
+      }
150
+      if (this.settings.content.url != "#") {
151
+        this.styleURL();
152
+      }
153
+      this.styleDismiss();
154
+      this.placement();
155
+      this.bind();
156
+
157
+      this.notify = {
158
+        $ele: this.$ele,
159
+        update: function(command, update) {
160
+          var commands = {};
161
+          if (typeof command === "string") {
162
+            commands[command] = update;
163
+          } else {
164
+            commands = command;
165
+          }
166
+          for (var cmd in commands) {
167
+            switch (cmd) {
168
+              case "type":
169
+                this.$ele.removeClass('alert-' + self.settings.type);
170
+                this.$ele.find('[data-notify="progressbar"] > .progress-bar').removeClass('progress-bar-' + self.settings.type);
171
+                self.settings.type = commands[cmd];
172
+                this.$ele.addClass('alert-' + commands[cmd]).find('[data-notify="progressbar"] > .progress-bar').addClass('progress-bar-' + commands[cmd]);
173
+                break;
174
+              case "icon":
175
+                var $icon = this.$ele.find('[data-notify="icon"]');
176
+                if (self.settings.icon_type.toLowerCase() === 'class') {
177
+                  $icon.removeClass(self.settings.content.icon).addClass(commands[cmd]);
178
+                } else {
179
+                  if (!$icon.is('img')) {
180
+                    $icon.find('img');
181
+                  }
182
+                  $icon.attr('src', commands[cmd]);
183
+                }
184
+                self.settings.content.icon = commands[command];
185
+                break;
186
+              case "progress":
187
+                var newDelay = self.settings.delay - (self.settings.delay * (commands[cmd] / 100));
188
+                this.$ele.data('notify-delay', newDelay);
189
+                this.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', commands[cmd]).css('width', commands[cmd] + '%');
190
+                break;
191
+              case "url":
192
+                this.$ele.find('[data-notify="url"]').attr('href', commands[cmd]);
193
+                break;
194
+              case "target":
195
+                this.$ele.find('[data-notify="url"]').attr('target', commands[cmd]);
196
+                break;
197
+              default:
198
+                this.$ele.find('[data-notify="' + cmd + '"]').html(commands[cmd]);
199
+            }
200
+          }
201
+          var posX = this.$ele.outerHeight() + parseInt(self.settings.spacing) + parseInt(self.settings.offset.y);
202
+          self.reposition(posX);
203
+        },
204
+        close: function() {
205
+          self.close();
206
+        }
207
+      };
208
+
209
+    },
210
+    buildNotify: function() {
211
+      var content = this.settings.content;
212
+      this.$ele = $(String.format(this.settings.template, this.settings.type, content.title, content.message, content.url, content.target));
213
+      this.$ele.attr('data-notify-position', this.settings.placement.from + '-' + this.settings.placement.align);
214
+      if (!this.settings.allow_dismiss) {
215
+        this.$ele.find('[data-notify="dismiss"]').css('display', 'none');
216
+      }
217
+      if ((this.settings.delay <= 0 && !this.settings.showProgressbar) || !this.settings.showProgressbar) {
218
+        this.$ele.find('[data-notify="progressbar"]').remove();
219
+      }
220
+    },
221
+    setIcon: function() {
222
+      this.$ele.addClass('alert-with-icon');
223
+
224
+      if (this.settings.icon_type.toLowerCase() === 'class') {
225
+        this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon);
226
+      } else {
227
+        if (this.$ele.find('[data-notify="icon"]').is('img')) {
228
+          this.$ele.find('[data-notify="icon"]').attr('src', this.settings.content.icon);
229
+        } else {
230
+          this.$ele.find('[data-notify="icon"]').append('<img src="' + this.settings.content.icon + '" alt="Notify Icon" />');
231
+        }
232
+      }
233
+    },
234
+    styleDismiss: function() {
235
+      this.$ele.find('[data-notify="dismiss"]').css({
236
+        position: 'absolute',
237
+        right: '10px',
238
+        top: '50%',
239
+        marginTop: '-13px',
240
+        zIndex: this.settings.z_index + 2
241
+      });
242
+    },
243
+    styleURL: function() {
244
+      this.$ele.find('[data-notify="url"]').css({
245
+        backgroundImage: 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)',
246
+        height: '100%',
247
+        left: 0,
248
+        position: 'absolute',
249
+        top: 0,
250
+        width: '100%',
251
+        zIndex: this.settings.z_index + 1
252
+      });
253
+    },
254
+    placement: function() {
255
+      var self = this,
256
+        offsetAmt = this.settings.offset.y,
257
+        css = {
258
+          display: 'inline-block',
259
+          margin: '0px auto',
260
+          position: this.settings.position ? this.settings.position : (this.settings.element === 'body' ? 'fixed' : 'absolute'),
261
+          transition: 'all .5s ease-in-out',
262
+          zIndex: this.settings.z_index
263
+        },
264
+        hasAnimation = false,
265
+        settings = this.settings;
266
+
267
+      $('[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])').each(function() {
268
+        offsetAmt = Math.max(offsetAmt, parseInt($(this).css(settings.placement.from)) + parseInt($(this).outerHeight()) + parseInt(settings.spacing));
269
+      });
270
+      if (this.settings.newest_on_top === true) {
271
+        offsetAmt = this.settings.offset.y;
272
+      }
273
+      css[this.settings.placement.from] = offsetAmt + 'px';
274
+
275
+      switch (this.settings.placement.align) {
276
+        case "left":
277
+        case "right":
278
+          css[this.settings.placement.align] = this.settings.offset.x + 'px';
279
+          break;
280
+        case "center":
281
+          css.left = 0;
282
+          css.right = 0;
283
+          break;
284
+      }
285
+      this.$ele.css(css).addClass(this.settings.animate.enter);
286
+      $.each(Array('webkit-', 'moz-', 'o-', 'ms-', ''), function(index, prefix) {
287
+        self.$ele[0].style[prefix + 'AnimationIterationCount'] = 1;
288
+      });
289
+
290
+      $(this.settings.element).append(this.$ele);
291
+
292
+      if (this.settings.newest_on_top === true) {
293
+        offsetAmt = (parseInt(offsetAmt) + parseInt(this.settings.spacing)) + this.$ele.outerHeight();
294
+        this.reposition(offsetAmt);
295
+      }
296
+
297
+      if ($.isFunction(self.settings.onShow)) {
298
+        self.settings.onShow.call(this.$ele);
299
+      }
300
+
301
+      this.$ele.one(this.animations.start, function() {
302
+        hasAnimation = true;
303
+      }).one(this.animations.end, function() {
304
+        self.$ele.removeClass(self.settings.animate.enter);
305
+        if ($.isFunction(self.settings.onShown)) {
306
+          self.settings.onShown.call(this);
307
+        }
308
+      });
309
+
310
+      setTimeout(function() {
311
+        if (!hasAnimation) {
312
+          if ($.isFunction(self.settings.onShown)) {
313
+            self.settings.onShown.call(this);
314
+          }
315
+        }
316
+      }, 600);
317
+    },
318
+    bind: function() {
319
+      var self = this;
320
+
321
+      this.$ele.find('[data-notify="dismiss"]').on('click', function() {
322
+        self.close();
323
+      });
324
+
325
+      if ($.isFunction(self.settings.onClick)) {
326
+        this.$ele.on('click', function(event) {
327
+          if (event.target != self.$ele.find('[data-notify="dismiss"]')[0]) {
328
+            self.settings.onClick.call(this, event);
329
+          }
330
+        });
331
+      }
332
+
333
+      this.$ele.mouseover(function() {
334
+        $(this).data('data-hover', "true");
335
+      }).mouseout(function() {
336
+        $(this).data('data-hover', "false");
337
+      });
338
+      this.$ele.data('data-hover', "false");
339
+
340
+      if (this.settings.delay > 0) {
341
+        self.$ele.data('notify-delay', self.settings.delay);
342
+        var timer = setInterval(function() {
343
+          var delay = parseInt(self.$ele.data('notify-delay')) - self.settings.timer;
344
+          if ((self.$ele.data('data-hover') === 'false' && self.settings.mouse_over === "pause") || self.settings.mouse_over != "pause") {
345
+            var percent = ((self.settings.delay - delay) / self.settings.delay) * 100;
346
+            self.$ele.data('notify-delay', delay);
347
+            self.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', percent).css('width', percent + '%');
348
+          }
349
+          if (delay <= -(self.settings.timer)) {
350
+            clearInterval(timer);
351
+            self.close();
352
+          }
353
+        }, self.settings.timer);
354
+      }
355
+    },
356
+    close: function() {
357
+      var self = this,
358
+        posX = parseInt(this.$ele.css(this.settings.placement.from)),
359
+        hasAnimation = false;
360
+
361
+      this.$ele.attr('data-closing', 'true').addClass(this.settings.animate.exit);
362
+      self.reposition(posX);
363
+
364
+      if ($.isFunction(self.settings.onClose)) {
365
+        self.settings.onClose.call(this.$ele);
366
+      }
367
+
368
+      this.$ele.one(this.animations.start, function() {
369
+        hasAnimation = true;
370
+      }).one(this.animations.end, function() {
371
+        $(this).remove();
372
+        if ($.isFunction(self.settings.onClosed)) {
373
+          self.settings.onClosed.call(this);
374
+        }
375
+      });
376
+
377
+      setTimeout(function() {
378
+        if (!hasAnimation) {
379
+          self.$ele.remove();
380
+          if (self.settings.onClosed) {
381
+            self.settings.onClosed(self.$ele);
382
+          }
383
+        }
384
+      }, 600);
385
+    },
386
+    reposition: function(posX) {
387
+      var self = this,
388
+        notifies = '[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])',
389
+        $elements = this.$ele.nextAll(notifies);
390
+      if (this.settings.newest_on_top === true) {
391
+        $elements = this.$ele.prevAll(notifies);
392
+      }
393
+      $elements.each(function() {
394
+        $(this).css(self.settings.placement.from, posX);
395
+        posX = (parseInt(posX) + parseInt(self.settings.spacing)) + $(this).outerHeight();
396
+      });
397
+    }
398
+  });
399
+
400
+  $.notify = function(content, options) {
401
+    var plugin = new Notify(this, content, options);
402
+    return plugin.notify;
403
+  };
404
+  $.notifyDefaults = function(options) {
405
+    defaults = $.extend(true, {}, defaults, options);
406
+    return defaults;
407
+  };
408
+
409
+  $.notifyClose = function(selector) {
410
+
411
+    if (typeof selector === "undefined" || selector === "all") {
412
+      $('[data-notify]').find('[data-notify="dismiss"]').trigger('click');
413
+    } else if (selector === 'success' || selector === 'info' || selector === 'warning' || selector === 'danger') {
414
+      $('.alert-' + selector + '[data-notify]').find('[data-notify="dismiss"]').trigger('click');
415
+    } else if (selector) {
416
+      $(selector + '[data-notify]').find('[data-notify="dismiss"]').trigger('click');
417
+    } else {
418
+      $('[data-notify-position="' + selector + '"]').find('[data-notify="dismiss"]').trigger('click');
419
+    }
420
+  };
421
+
422
+  $.notifyCloseExcept = function(selector) {
423
+
424
+    if (selector === 'success' || selector === 'info' || selector === 'warning' || selector === 'danger') {
425
+      $('[data-notify]').not('.alert-' + selector).find('[data-notify="dismiss"]').trigger('click');
426
+    } else {
427
+      $('[data-notify]').not(selector).find('[data-notify="dismiss"]').trigger('click');
428
+    }
429
+  };
430
+
431
+
432
+}));

+ 10
- 0
app/base/static/assets/js/plugins/chartjs.min.js
File diff suppressed because it is too large
View File


+ 6
- 0
app/base/static/assets/js/plugins/perfect-scrollbar.jquery.min.js
File diff suppressed because it is too large
View File


+ 102
- 0
app/base/static/assets/scss/black-dashboard.scss View File

@@ -0,0 +1,102 @@
1
+
2
+/*!
3
+
4
+=========================================================
5
+* Black Dashboard - v1.0.1
6
+=========================================================
7
+
8
+* Product Page: https://www.creative-tim.com/product/black-dashboard
9
+* Copyright 2019 Creative Tim (https://www.creative-tim.com)
10
+
11
+
12
+* Coded by Creative Tim
13
+
14
+=========================================================
15
+
16
+* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
17
+
18
+*/
19
+
20
+ // Core
21
+
22
+@import "black-dashboard/custom/functions";
23
+@import "black-dashboard/bootstrap/functions";
24
+
25
+@import "black-dashboard/custom/variables";
26
+@import "black-dashboard/bootstrap/variables";
27
+
28
+@import "black-dashboard/custom/mixins";
29
+@import "black-dashboard/bootstrap/mixins";
30
+
31
+ // Bootstrap components
32
+
33
+@import "black-dashboard/bootstrap/root";
34
+@import "black-dashboard/bootstrap/reboot";
35
+@import "black-dashboard/bootstrap/type";
36
+@import "black-dashboard/bootstrap/images";
37
+@import "black-dashboard/bootstrap/code";
38
+@import "black-dashboard/bootstrap/grid";
39
+@import "black-dashboard/bootstrap/tables";
40
+@import "black-dashboard/bootstrap/forms";
41
+@import "black-dashboard/bootstrap/buttons";
42
+@import "black-dashboard/bootstrap/transitions";
43
+@import "black-dashboard/bootstrap/dropdown";
44
+@import "black-dashboard/bootstrap/button-group";
45
+@import "black-dashboard/bootstrap/input-group";
46
+@import "black-dashboard/bootstrap/custom-forms";
47
+@import "black-dashboard/bootstrap/nav";
48
+@import "black-dashboard/bootstrap/navbar";
49
+@import "black-dashboard/bootstrap/card";
50
+@import "black-dashboard/bootstrap/breadcrumb";
51
+@import "black-dashboard/bootstrap/pagination";
52
+@import "black-dashboard/bootstrap/badge";
53
+@import "black-dashboard/bootstrap/jumbotron";
54
+@import "black-dashboard/bootstrap/alert";
55
+@import "black-dashboard/bootstrap/progress";
56
+@import "black-dashboard/bootstrap/media";
57
+@import "black-dashboard/bootstrap/list-group";
58
+@import "black-dashboard/bootstrap/close";
59
+@import "black-dashboard/bootstrap/modal";
60
+@import "black-dashboard/bootstrap/tooltip";
61
+@import "black-dashboard/bootstrap/popover";
62
+@import "black-dashboard/bootstrap/carousel";
63
+@import "black-dashboard/bootstrap/utilities";
64
+@import "black-dashboard/bootstrap/print";
65
+
66
+ // Custom components
67
+
68
+ @import "black-dashboard/custom/alerts.scss";
69
+ @import "black-dashboard/custom/buttons.scss";
70
+ @import "black-dashboard/custom/dropdown.scss";
71
+ @import "black-dashboard/custom/footer.scss";
72
+ @import "black-dashboard/custom/forms.scss";
73
+ @import "black-dashboard/custom/images.scss";
74
+ @import "black-dashboard/custom/modal.scss";
75
+ @import "black-dashboard/custom/navbar.scss";
76
+ @import "black-dashboard/custom/type.scss";
77
+ @import "black-dashboard/custom/tables";
78
+ @import "black-dashboard/custom/checkboxes-radio";
79
+ @import "black-dashboard/custom/fixed-plugin";
80
+ @import "black-dashboard/custom/sidebar-and-main-panel.scss";
81
+ @import "black-dashboard/custom/misc.scss";
82
+ @import "black-dashboard/custom/rtl.scss";
83
+ @import "black-dashboard/custom/input-group.scss";
84
+
85
+
86
+ // Vendor / Plugins
87
+
88
+@import "black-dashboard/custom/vendor/plugin-perfect-scrollbar.scss";
89
+@import "black-dashboard/custom/vendor/plugin-animate-bootstrap-notify.scss";
90
+
91
+// light mode
92
+
93
+@import "black-dashboard/custom/white-content.scss";
94
+
95
+// Cards
96
+
97
+@import 'black-dashboard/custom/card';
98
+@import "black-dashboard/custom/cards/card-chart";
99
+@import "black-dashboard/custom/cards/card-map";
100
+@import "black-dashboard/custom/cards/card-user";
101
+@import "black-dashboard/custom/cards/card-task";
102
+@import "black-dashboard/custom/cards/card-plain";

+ 1
- 0
app/base/static/assets/scss/black-dashboard/_buttons.scss View File

@@ -0,0 +1 @@
1
+// mixins comune kit dash etc

+ 1
- 0
app/base/static/assets/scss/black-dashboard/_typography.scss View File

@@ -0,0 +1 @@
1
+// ce e comun intre kit-uri si dash-uri

+ 51
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_alert.scss View File

@@ -0,0 +1,51 @@
1
+//
2
+// Base styles
3
+//
4
+
5
+.alert {
6
+  position: relative;
7
+  padding: $alert-padding-y $alert-padding-x;
8
+  margin-bottom: $alert-margin-bottom;
9
+  border: $alert-border-width solid transparent;
10
+  @include border-radius($alert-border-radius);
11
+}
12
+
13
+// Headings for larger alerts
14
+.alert-heading {
15
+  // Specified to prevent conflicts of changing $headings-color
16
+  color: inherit;
17
+}
18
+
19
+// Provide class for links that match alerts
20
+.alert-link {
21
+  font-weight: $alert-link-font-weight;
22
+}
23
+
24
+
25
+// Dismissible alerts
26
+//
27
+// Expand the right padding and account for the close button's positioning.
28
+
29
+.alert-dismissible {
30
+  padding-right: $close-font-size + $alert-padding-x * 2;
31
+
32
+  // Adjust close link position
33
+  .close {
34
+    position: absolute;
35
+    top: 0;
36
+    right: 0;
37
+    padding: $alert-padding-y $alert-padding-x;
38
+    color: inherit;
39
+  }
40
+}
41
+
42
+
43
+// Alternate styles
44
+//
45
+// Generate contextual modifier classes for colorizing the alert.
46
+
47
+@each $color, $value in $theme-colors {
48
+  .alert-#{$color} {
49
+    @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
50
+  }
51
+}

+ 54
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_badge.scss View File

@@ -0,0 +1,54 @@
1
+// Base class
2
+//
3
+// Requires one of the contextual, color modifier classes for `color` and
4
+// `background-color`.
5
+
6
+.badge {
7
+  display: inline-block;
8
+  padding: $badge-padding-y $badge-padding-x;
9
+  @include font-size($badge-font-size);
10
+  font-weight: $badge-font-weight;
11
+  line-height: 1;
12
+  text-align: center;
13
+  white-space: nowrap;
14
+  vertical-align: baseline;
15
+  @include border-radius($badge-border-radius);
16
+  @include transition($badge-transition);
17
+
18
+  @at-root a#{&} {
19
+    @include hover-focus {
20
+      text-decoration: none;
21
+    }
22
+  }
23
+
24
+  // Empty badges collapse automatically
25
+  &:empty {
26
+    display: none;
27
+  }
28
+}
29
+
30
+// Quick fix for badges in buttons
31
+.btn .badge {
32
+  position: relative;
33
+  top: -1px;
34
+}
35
+
36
+// Pill badges
37
+//
38
+// Make them extra rounded with a modifier to replace v3's badges.
39
+
40
+.badge-pill {
41
+  padding-right: $badge-pill-padding-x;
42
+  padding-left: $badge-pill-padding-x;
43
+  @include border-radius($badge-pill-border-radius);
44
+}
45
+
46
+// Colors
47
+//
48
+// Contextual variations (linked badges get darker on :hover).
49
+
50
+@each $color, $value in $theme-colors {
51
+  .badge-#{$color} {
52
+    @include badge-variant($value);
53
+  }
54
+}

+ 41
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_breadcrumb.scss View File

@@ -0,0 +1,41 @@
1
+.breadcrumb {
2
+  display: flex;
3
+  flex-wrap: wrap;
4
+  padding: $breadcrumb-padding-y $breadcrumb-padding-x;
5
+  margin-bottom: $breadcrumb-margin-bottom;
6
+  list-style: none;
7
+  background-color: $breadcrumb-bg;
8
+  @include border-radius($breadcrumb-border-radius);
9
+}
10
+
11
+.breadcrumb-item {
12
+  // The separator between breadcrumbs (by default, a forward-slash: "/")
13
+  + .breadcrumb-item {
14
+    padding-left: $breadcrumb-item-padding;
15
+
16
+    &::before {
17
+      display: inline-block; // Suppress underlining of the separator in modern browsers
18
+      padding-right: $breadcrumb-item-padding;
19
+      color: $breadcrumb-divider-color;
20
+      content: $breadcrumb-divider;
21
+    }
22
+  }
23
+
24
+  // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
25
+  // without `<ul>`s. The `::before` pseudo-element generates an element
26
+  // *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
27
+  //
28
+  // To trick IE into suppressing the underline, we give the pseudo-element an
29
+  // underline and then immediately remove it.
30
+  + .breadcrumb-item:hover::before {
31
+    text-decoration: underline;
32
+  }
33
+  // stylelint-disable-next-line no-duplicate-selectors
34
+  + .breadcrumb-item:hover::before {
35
+    text-decoration: none;
36
+  }
37
+
38
+  &.active {
39
+    color: $breadcrumb-active-color;
40
+  }
41
+}

+ 163
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_button-group.scss View File

@@ -0,0 +1,163 @@
1
+// stylelint-disable selector-no-qualifying-type
2
+
3
+// Make the div behave like a button
4
+.btn-group,
5
+.btn-group-vertical {
6
+  position: relative;
7
+  display: inline-flex;
8
+  vertical-align: middle; // match .btn alignment given font-size hack above
9
+
10
+  > .btn {
11
+    position: relative;
12
+    flex: 1 1 auto;
13
+
14
+    // Bring the hover, focused, and "active" buttons to the front to overlay
15
+    // the borders properly
16
+    @include hover {
17
+      z-index: 1;
18
+    }
19
+    &:focus,
20
+    &:active,
21
+    &.active {
22
+      z-index: 1;
23
+    }
24
+  }
25
+}
26
+
27
+// Optional: Group multiple button groups together for a toolbar
28
+.btn-toolbar {
29
+  display: flex;
30
+  flex-wrap: wrap;
31
+  justify-content: flex-start;
32
+
33
+  .input-group {
34
+    width: auto;
35
+  }
36
+}
37
+
38
+.btn-group {
39
+  // Prevent double borders when buttons are next to each other
40
+  > .btn:not(:first-child),
41
+  > .btn-group:not(:first-child) {
42
+    margin-left: -$btn-border-width;
43
+  }
44
+
45
+  // Reset rounded corners
46
+  > .btn:not(:last-child):not(.dropdown-toggle),
47
+  > .btn-group:not(:last-child) > .btn {
48
+    @include border-right-radius(0);
49
+  }
50
+
51
+  > .btn:not(:first-child),
52
+  > .btn-group:not(:first-child) > .btn {
53
+    @include border-left-radius(0);
54
+  }
55
+}
56
+
57
+// Sizing
58
+//
59
+// Remix the default button sizing classes into new ones for easier manipulation.
60
+
61
+.btn-group-sm > .btn { @extend .btn-sm; }
62
+.btn-group-lg > .btn { @extend .btn-lg; }
63
+
64
+
65
+//
66
+// Split button dropdowns
67
+//
68
+
69
+.dropdown-toggle-split {
70
+  padding-right: $btn-padding-x * .75;
71
+  padding-left: $btn-padding-x * .75;
72
+
73
+  &::after,
74
+  .dropup &::after,
75
+  .dropright &::after {
76
+    margin-left: 0;
77
+  }
78
+
79
+  .dropleft &::before {
80
+    margin-right: 0;
81
+  }
82
+}
83
+
84
+.btn-sm + .dropdown-toggle-split {
85
+  padding-right: $btn-padding-x-sm * .75;
86
+  padding-left: $btn-padding-x-sm * .75;
87
+}
88
+
89
+.btn-lg + .dropdown-toggle-split {
90
+  padding-right: $btn-padding-x-lg * .75;
91
+  padding-left: $btn-padding-x-lg * .75;
92
+}
93
+
94
+
95
+// The clickable button for toggling the menu
96
+// Set the same inset shadow as the :active state
97
+.btn-group.show .dropdown-toggle {
98
+  @include box-shadow($btn-active-box-shadow);
99
+
100
+  // Show no shadow for `.btn-link` since it has no other button styles.
101
+  &.btn-link {
102
+    @include box-shadow(none);
103
+  }
104
+}
105
+
106
+
107
+//
108
+// Vertical button groups
109
+//
110
+
111
+.btn-group-vertical {
112
+  flex-direction: column;
113
+  align-items: flex-start;
114
+  justify-content: center;
115
+
116
+  > .btn,
117
+  > .btn-group {
118
+    width: 100%;
119
+  }
120
+
121
+  > .btn:not(:first-child),
122
+  > .btn-group:not(:first-child) {
123
+    margin-top: -$btn-border-width;
124
+  }
125
+
126
+  // Reset rounded corners
127
+  > .btn:not(:last-child):not(.dropdown-toggle),
128
+  > .btn-group:not(:last-child) > .btn {
129
+    @include border-bottom-radius(0);
130
+  }
131
+
132
+  > .btn:not(:first-child),
133
+  > .btn-group:not(:first-child) > .btn {
134
+    @include border-top-radius(0);
135
+  }
136
+}
137
+
138
+
139
+// Checkbox and radio options
140
+//
141
+// In order to support the browser's form validation feedback, powered by the
142
+// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
143
+// `display: none;` or `visibility: hidden;` as that also hides the popover.
144
+// Simply visually hiding the inputs via `opacity` would leave them clickable in
145
+// certain cases which is prevented by using `clip` and `pointer-events`.
146
+// This way, we ensure a DOM element is visible to position the popover from.
147
+//
148
+// See https://github.com/twbs/bootstrap/pull/12794 and
149
+// https://github.com/twbs/bootstrap/pull/14559 for more information.
150
+
151
+.btn-group-toggle {
152
+  > .btn,
153
+  > .btn-group > .btn {
154
+    margin-bottom: 0; // Override default `<label>` value
155
+
156
+    input[type="radio"],
157
+    input[type="checkbox"] {
158
+      position: absolute;
159
+      clip: rect(0, 0, 0, 0);
160
+      pointer-events: none;
161
+    }
162
+  }
163
+}

+ 137
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_buttons.scss View File

@@ -0,0 +1,137 @@
1
+// stylelint-disable selector-no-qualifying-type
2
+
3
+//
4
+// Base styles
5
+//
6
+
7
+.btn {
8
+  display: inline-block;
9
+  font-family: $btn-font-family;
10
+  font-weight: $btn-font-weight;
11
+  color: $body-color;
12
+  text-align: center;
13
+  vertical-align: middle;
14
+  user-select: none;
15
+  background-color: transparent;
16
+  border: $btn-border-width solid transparent;
17
+  @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);
18
+  @include transition($btn-transition);
19
+
20
+  @include hover {
21
+    color: $body-color;
22
+    text-decoration: none;
23
+  }
24
+
25
+  &:focus,
26
+  &.focus {
27
+    outline: 0;
28
+    box-shadow: $btn-focus-box-shadow;
29
+  }
30
+
31
+  // Disabled comes first so active can properly restyle
32
+  &.disabled,
33
+  &:disabled {
34
+    opacity: $btn-disabled-opacity;
35
+    @include box-shadow(none);
36
+  }
37
+
38
+  &:not(:disabled):not(.disabled):active,
39
+  &:not(:disabled):not(.disabled).active {
40
+    @include box-shadow($btn-active-box-shadow);
41
+
42
+    &:focus {
43
+      @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
44
+    }
45
+  }
46
+}
47
+
48
+// Future-proof disabling of clicks on `<a>` elements
49
+a.btn.disabled,
50
+fieldset:disabled a.btn {
51
+  pointer-events: none;
52
+}
53
+
54
+
55
+//
56
+// Alternate buttons
57
+//
58
+
59
+@each $color, $value in $theme-colors {
60
+  .btn-#{$color} {
61
+    @include button-variant($value, $value);
62
+  }
63
+}
64
+
65
+@each $color, $value in $theme-colors {
66
+  .btn-outline-#{$color} {
67
+    @include button-outline-variant($value);
68
+  }
69
+}
70
+
71
+
72
+//
73
+// Link buttons
74
+//
75
+
76
+// Make a button look and behave like a link
77
+.btn-link {
78
+  font-weight: $font-weight-normal;
79
+  color: $link-color;
80
+  text-decoration: $link-decoration;
81
+
82
+  @include hover {
83
+    color: $link-hover-color;
84
+    text-decoration: $link-hover-decoration;
85
+  }
86
+
87
+  &:focus,
88
+  &.focus {
89
+    text-decoration: $link-hover-decoration;
90
+    box-shadow: none;
91
+  }
92
+
93
+  &:disabled,
94
+  &.disabled {
95
+    color: $btn-link-disabled-color;
96
+    pointer-events: none;
97
+  }
98
+
99
+  // No need for an active state here
100
+}
101
+
102
+
103
+//
104
+// Button Sizes
105
+//
106
+
107
+.btn-lg {
108
+  @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);
109
+}
110
+
111
+.btn-sm {
112
+  @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);
113
+}
114
+
115
+
116
+//
117
+// Block button
118
+//
119
+
120
+.btn-block {
121
+  display: block;
122
+  width: 100%;
123
+
124
+  // Vertically space out multiple block buttons
125
+  + .btn-block {
126
+    margin-top: $btn-block-spacing-y;
127
+  }
128
+}
129
+
130
+// Specificity overrides
131
+input[type="submit"],
132
+input[type="reset"],
133
+input[type="button"] {
134
+  &.btn-block {
135
+    width: 100%;
136
+  }
137
+}

+ 289
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_card.scss View File

@@ -0,0 +1,289 @@
1
+//
2
+// Base styles
3
+//
4
+
5
+.card {
6
+  position: relative;
7
+  display: flex;
8
+  flex-direction: column;
9
+  min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
10
+  word-wrap: break-word;
11
+  background-color: $card-bg;
12
+  background-clip: border-box;
13
+  border: $card-border-width solid $card-border-color;
14
+  @include border-radius($card-border-radius);
15
+
16
+  > hr {
17
+    margin-right: 0;
18
+    margin-left: 0;
19
+  }
20
+
21
+  > .list-group:first-child {
22
+    .list-group-item:first-child {
23
+      @include border-top-radius($card-border-radius);
24
+    }
25
+  }
26
+
27
+  > .list-group:last-child {
28
+    .list-group-item:last-child {
29
+      @include border-bottom-radius($card-border-radius);
30
+    }
31
+  }
32
+}
33
+
34
+.card-body {
35
+  // Enable `flex-grow: 1` for decks and groups so that card blocks take up
36
+  // as much space as possible, ensuring footers are aligned to the bottom.
37
+  flex: 1 1 auto;
38
+  padding: $card-spacer-x;
39
+  color: $card-color;
40
+}
41
+
42
+.card-title {
43
+  margin-bottom: $card-spacer-y;
44
+}
45
+
46
+.card-subtitle {
47
+  margin-top: -$card-spacer-y / 2;
48
+  margin-bottom: 0;
49
+}
50
+
51
+.card-text:last-child {
52
+  margin-bottom: 0;
53
+}
54
+
55
+.card-link {
56
+  @include hover {
57
+    text-decoration: none;
58
+  }
59
+
60
+  + .card-link {
61
+    margin-left: $card-spacer-x;
62
+  }
63
+}
64
+
65
+//
66
+// Optional textual caps
67
+//
68
+
69
+.card-header {
70
+  padding: $card-spacer-y $card-spacer-x;
71
+  margin-bottom: 0; // Removes the default margin-bottom of <hN>
72
+  color: $card-cap-color;
73
+  background-color: $card-cap-bg;
74
+  border-bottom: $card-border-width solid $card-border-color;
75
+
76
+  &:first-child {
77
+    @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
78
+  }
79
+
80
+  + .list-group {
81
+    .list-group-item:first-child {
82
+      border-top: 0;
83
+    }
84
+  }
85
+}
86
+
87
+.card-footer {
88
+  padding: $card-spacer-y $card-spacer-x;
89
+  background-color: $card-cap-bg;
90
+  border-top: $card-border-width solid $card-border-color;
91
+
92
+  &:last-child {
93
+    @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);
94
+  }
95
+}
96
+
97
+
98
+//
99
+// Header navs
100
+//
101
+
102
+.card-header-tabs {
103
+  margin-right: -$card-spacer-x / 2;
104
+  margin-bottom: -$card-spacer-y;
105
+  margin-left: -$card-spacer-x / 2;
106
+  border-bottom: 0;
107
+}
108
+
109
+.card-header-pills {
110
+  margin-right: -$card-spacer-x / 2;
111
+  margin-left: -$card-spacer-x / 2;
112
+}
113
+
114
+// Card image
115
+.card-img-overlay {
116
+  position: absolute;
117
+  top: 0;
118
+  right: 0;
119
+  bottom: 0;
120
+  left: 0;
121
+  padding: $card-img-overlay-padding;
122
+}
123
+
124
+.card-img {
125
+  width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
126
+  @include border-radius($card-inner-border-radius);
127
+}
128
+
129
+// Card image caps
130
+.card-img-top {
131
+  width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
132
+  @include border-top-radius($card-inner-border-radius);
133
+}
134
+
135
+.card-img-bottom {
136
+  width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
137
+  @include border-bottom-radius($card-inner-border-radius);
138
+}
139
+
140
+
141
+// Card deck
142
+
143
+.card-deck {
144
+  display: flex;
145
+  flex-direction: column;
146
+
147
+  .card {
148
+    margin-bottom: $card-deck-margin;
149
+  }
150
+
151
+  @include media-breakpoint-up(sm) {
152
+    flex-flow: row wrap;
153
+    margin-right: -$card-deck-margin;
154
+    margin-left: -$card-deck-margin;
155
+
156
+    .card {
157
+      display: flex;
158
+      // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
159
+      flex: 1 0 0%;
160
+      flex-direction: column;
161
+      margin-right: $card-deck-margin;
162
+      margin-bottom: 0; // Override the default
163
+      margin-left: $card-deck-margin;
164
+    }
165
+  }
166
+}
167
+
168
+
169
+//
170
+// Card groups
171
+//
172
+
173
+.card-group {
174
+  display: flex;
175
+  flex-direction: column;
176
+
177
+  // The child selector allows nested `.card` within `.card-group`
178
+  // to display properly.
179
+  > .card {
180
+    margin-bottom: $card-group-margin;
181
+  }
182
+
183
+  @include media-breakpoint-up(sm) {
184
+    flex-flow: row wrap;
185
+    // The child selector allows nested `.card` within `.card-group`
186
+    // to display properly.
187
+    > .card {
188
+      // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
189
+      flex: 1 0 0%;
190
+      margin-bottom: 0;
191
+
192
+      + .card {
193
+        margin-left: 0;
194
+        border-left: 0;
195
+      }
196
+
197
+      // Handle rounded corners
198
+      @if $enable-rounded {
199
+        &:not(:last-child) {
200
+          @include border-right-radius(0);
201
+
202
+          .card-img-top,
203
+          .card-header {
204
+            // stylelint-disable-next-line property-blacklist
205
+            border-top-right-radius: 0;
206
+          }
207
+          .card-img-bottom,
208
+          .card-footer {
209
+            // stylelint-disable-next-line property-blacklist
210
+            border-bottom-right-radius: 0;
211
+          }
212
+        }
213
+
214
+        &:not(:first-child) {
215
+          @include border-left-radius(0);
216
+
217
+          .card-img-top,
218
+          .card-header {
219
+            // stylelint-disable-next-line property-blacklist
220
+            border-top-left-radius: 0;
221
+          }
222
+          .card-img-bottom,
223
+          .card-footer {
224
+            // stylelint-disable-next-line property-blacklist
225
+            border-bottom-left-radius: 0;
226
+          }
227
+        }
228
+      }
229
+    }
230
+  }
231
+}
232
+
233
+
234
+//
235
+// Columns
236
+//
237
+
238
+.card-columns {
239
+  .card {
240
+    margin-bottom: $card-columns-margin;
241
+  }
242
+
243
+  @include media-breakpoint-up(sm) {
244
+    column-count: $card-columns-count;
245
+    column-gap: $card-columns-gap;
246
+    orphans: 1;
247
+    widows: 1;
248
+
249
+    .card {
250
+      display: inline-block; // Don't let them vertically span multiple columns
251
+      width: 100%; // Don't let their width change
252
+    }
253
+  }
254
+}
255
+
256
+
257
+//
258
+// Accordion
259
+//
260
+
261
+.accordion {
262
+  > .card {
263
+    overflow: hidden;
264
+
265
+    &:not(:first-of-type) {
266
+      .card-header:first-child {
267
+        @include border-radius(0);
268
+      }
269
+
270
+      &:not(:last-of-type) {
271
+        border-bottom: 0;
272
+        @include border-radius(0);
273
+      }
274
+    }
275
+
276
+    &:first-of-type {
277
+      border-bottom: 0;
278
+      @include border-bottom-radius(0);
279
+    }
280
+
281
+    &:last-of-type {
282
+      @include border-top-radius(0);
283
+    }
284
+
285
+    .card-header {
286
+      margin-bottom: -$card-border-width;
287
+    }
288
+  }
289
+}

+ 197
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_carousel.scss View File

@@ -0,0 +1,197 @@
1
+// Notes on the classes:
2
+//
3
+// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)
4
+//    even when their scroll action started on a carousel, but for compatibility (with Firefox)
5
+//    we're preventing all actions instead
6
+// 2. The .carousel-item-left and .carousel-item-right is used to indicate where
7
+//    the active slide is heading.
8
+// 3. .active.carousel-item is the current slide.
9
+// 4. .active.carousel-item-left and .active.carousel-item-right is the current
10
+//    slide in its in-transition state. Only one of these occurs at a time.
11
+// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right
12
+//    is the upcoming slide in transition.
13
+
14
+.carousel {
15
+  position: relative;
16
+}
17
+
18
+.carousel.pointer-event {
19
+  touch-action: pan-y;
20
+}
21
+
22
+.carousel-inner {
23
+  position: relative;
24
+  width: 100%;
25
+  overflow: hidden;
26
+  @include clearfix();
27
+}
28
+
29
+.carousel-item {
30
+  position: relative;
31
+  display: none;
32
+  float: left;
33
+  width: 100%;
34
+  margin-right: -100%;
35
+  backface-visibility: hidden;
36
+  @include transition($carousel-transition);
37
+}
38
+
39
+.carousel-item.active,
40
+.carousel-item-next,
41
+.carousel-item-prev {
42
+  display: block;
43
+}
44
+
45
+.carousel-item-next:not(.carousel-item-left),
46
+.active.carousel-item-right {
47
+  transform: translateX(100%);
48
+}
49
+
50
+.carousel-item-prev:not(.carousel-item-right),
51
+.active.carousel-item-left {
52
+  transform: translateX(-100%);
53
+}
54
+
55
+
56
+//
57
+// Alternate transitions
58
+//
59
+
60
+.carousel-fade {
61
+  .carousel-item {
62
+    opacity: 0;
63
+    transition-property: opacity;
64
+    transform: none;
65
+  }
66
+
67
+  .carousel-item.active,
68
+  .carousel-item-next.carousel-item-left,
69
+  .carousel-item-prev.carousel-item-right {
70
+    z-index: 1;
71
+    opacity: 1;
72
+  }
73
+
74
+  .active.carousel-item-left,
75
+  .active.carousel-item-right {
76
+    z-index: 0;
77
+    opacity: 0;
78
+    @include transition(0s $carousel-transition-duration opacity);
79
+  }
80
+}
81
+
82
+
83
+//
84
+// Left/right controls for nav
85
+//
86
+
87
+.carousel-control-prev,
88
+.carousel-control-next {
89
+  position: absolute;
90
+  top: 0;
91
+  bottom: 0;
92
+  z-index: 1;
93
+  // Use flex for alignment (1-3)
94
+  display: flex; // 1. allow flex styles
95
+  align-items: center; // 2. vertically center contents
96
+  justify-content: center; // 3. horizontally center contents
97
+  width: $carousel-control-width;
98
+  color: $carousel-control-color;
99
+  text-align: center;
100
+  opacity: $carousel-control-opacity;
101
+  @include transition($carousel-control-transition);
102
+
103
+  // Hover/focus state
104
+  @include hover-focus {
105
+    color: $carousel-control-color;
106
+    text-decoration: none;
107
+    outline: 0;
108
+    opacity: $carousel-control-hover-opacity;
109
+  }
110
+}
111
+.carousel-control-prev {
112
+  left: 0;
113
+  @if $enable-gradients {
114
+    background: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));
115
+  }
116
+}
117
+.carousel-control-next {
118
+  right: 0;
119
+  @if $enable-gradients {
120
+    background: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));
121
+  }
122
+}
123
+
124
+// Icons for within
125
+.carousel-control-prev-icon,
126
+.carousel-control-next-icon {
127
+  display: inline-block;
128
+  width: $carousel-control-icon-width;
129
+  height: $carousel-control-icon-width;
130
+  background: no-repeat 50% / 100% 100%;
131
+}
132
+.carousel-control-prev-icon {
133
+  background-image: $carousel-control-prev-icon-bg;
134
+}
135
+.carousel-control-next-icon {
136
+  background-image: $carousel-control-next-icon-bg;
137
+}
138
+
139
+
140
+// Optional indicator pips
141
+//
142
+// Add an ordered list with the following class and add a list item for each
143
+// slide your carousel holds.
144
+
145
+.carousel-indicators {
146
+  position: absolute;
147
+  right: 0;
148
+  bottom: 0;
149
+  left: 0;
150
+  z-index: 15;
151
+  display: flex;
152
+  justify-content: center;
153
+  padding-left: 0; // override <ol> default
154
+  // Use the .carousel-control's width as margin so we don't overlay those
155
+  margin-right: $carousel-control-width;
156
+  margin-left: $carousel-control-width;
157
+  list-style: none;
158
+
159
+  li {
160
+    box-sizing: content-box;
161
+    flex: 0 1 auto;
162
+    width: $carousel-indicator-width;
163
+    height: $carousel-indicator-height;
164
+    margin-right: $carousel-indicator-spacer;
165
+    margin-left: $carousel-indicator-spacer;
166
+    text-indent: -999px;
167
+    cursor: pointer;
168
+    background-color: $carousel-indicator-active-bg;
169
+    background-clip: padding-box;
170
+    // Use transparent borders to increase the hit area by 10px on top and bottom.
171
+    border-top: $carousel-indicator-hit-area-height solid transparent;
172
+    border-bottom: $carousel-indicator-hit-area-height solid transparent;
173
+    opacity: .5;
174
+    @include transition($carousel-indicator-transition);
175
+  }
176
+
177
+  .active {
178
+    opacity: 1;
179
+  }
180
+}
181
+
182
+
183
+// Optional captions
184
+//
185
+//
186
+
187
+.carousel-caption {
188
+  position: absolute;
189
+  right: (100% - $carousel-caption-width) / 2;
190
+  bottom: 20px;
191
+  left: (100% - $carousel-caption-width) / 2;
192
+  z-index: 10;
193
+  padding-top: 20px;
194
+  padding-bottom: 20px;
195
+  color: $carousel-caption-color;
196
+  text-align: center;
197
+}

+ 41
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_close.scss View File

@@ -0,0 +1,41 @@
1
+.close {
2
+  float: right;
3
+  @include font-size($close-font-size);
4
+  font-weight: $close-font-weight;
5
+  line-height: 1;
6
+  color: $close-color;
7
+  text-shadow: $close-text-shadow;
8
+  opacity: .5;
9
+
10
+  // Override <a>'s hover style
11
+  @include hover {
12
+    color: $close-color;
13
+    text-decoration: none;
14
+  }
15
+
16
+  &:not(:disabled):not(.disabled) {
17
+    @include hover-focus {
18
+      opacity: .75;
19
+    }
20
+  }
21
+}
22
+
23
+// Additional properties for button version
24
+// iOS requires the button element instead of an anchor tag.
25
+// If you want the anchor version, it requires `href="#"`.
26
+// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
27
+
28
+// stylelint-disable-next-line selector-no-qualifying-type
29
+button.close {
30
+  padding: 0;
31
+  background-color: transparent;
32
+  border: 0;
33
+  appearance: none;
34
+}
35
+
36
+// Future-proof disabling of clicks on `<a>` elements
37
+
38
+// stylelint-disable-next-line selector-no-qualifying-type
39
+a.close.disabled {
40
+  pointer-events: none;
41
+}

+ 48
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_code.scss View File

@@ -0,0 +1,48 @@
1
+// Inline code
2
+code {
3
+  @include font-size($code-font-size);
4
+  color: $code-color;
5
+  word-break: break-word;
6
+
7
+  // Streamline the style when inside anchors to avoid broken underline and more
8
+  a > & {
9
+    color: inherit;
10
+  }
11
+}
12
+
13
+// User input typically entered via keyboard
14
+kbd {
15
+  padding: $kbd-padding-y $kbd-padding-x;
16
+  @include font-size($kbd-font-size);
17
+  color: $kbd-color;
18
+  background-color: $kbd-bg;
19
+  @include border-radius($border-radius-sm);
20
+  @include box-shadow($kbd-box-shadow);
21
+
22
+  kbd {
23
+    padding: 0;
24
+    @include font-size(100%);
25
+    font-weight: $nested-kbd-font-weight;
26
+    @include box-shadow(none);
27
+  }
28
+}
29
+
30
+// Blocks of code
31
+pre {
32
+  display: block;
33
+  @include font-size($code-font-size);
34
+  color: $pre-color;
35
+
36
+  // Account for some code outputs that place code tags in pre tags
37
+  code {
38
+    @include font-size(inherit);
39
+    color: inherit;
40
+    word-break: normal;
41
+  }
42
+}
43
+
44
+// Enable scrollable blocks of code
45
+.pre-scrollable {
46
+  max-height: $pre-scrollable-max-height;
47
+  overflow-y: scroll;
48
+}

+ 507
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_custom-forms.scss View File

@@ -0,0 +1,507 @@
1
+// Embedded icons from Open Iconic.
2
+// Released under MIT and copyright 2014 Waybury.
3
+// https://useiconic.com/open
4
+
5
+
6
+// Checkboxes and radios
7
+//
8
+// Base class takes care of all the key behavioral aspects.
9
+
10
+.custom-control {
11
+  position: relative;
12
+  display: block;
13
+  min-height: $font-size-base * $line-height-base;
14
+  padding-left: $custom-control-gutter + $custom-control-indicator-size;
15
+}
16
+
17
+.custom-control-inline {
18
+  display: inline-flex;
19
+  margin-right: $custom-control-spacer-x;
20
+}
21
+
22
+.custom-control-input {
23
+  position: absolute;
24
+  z-index: -1; // Put the input behind the label so it doesn't overlay text
25
+  opacity: 0;
26
+
27
+  &:checked ~ .custom-control-label::before {
28
+    color: $custom-control-indicator-checked-color;
29
+    border-color: $custom-control-indicator-checked-border-color;
30
+    @include gradient-bg($custom-control-indicator-checked-bg);
31
+    @include box-shadow($custom-control-indicator-checked-box-shadow);
32
+  }
33
+
34
+  &:focus ~ .custom-control-label::before {
35
+    // the mixin is not used here to make sure there is feedback
36
+    @if $enable-shadows {
37
+      box-shadow: $input-box-shadow, $input-focus-box-shadow;
38
+    } @else {
39
+      box-shadow: $custom-control-indicator-focus-box-shadow;
40
+    }
41
+  }
42
+
43
+  &:focus:not(:checked) ~ .custom-control-label::before {
44
+    border-color: $custom-control-indicator-focus-border-color;
45
+  }
46
+
47
+  &:not(:disabled):active ~ .custom-control-label::before {
48
+    color: $custom-control-indicator-active-color;
49
+    background-color: $custom-control-indicator-active-bg;
50
+    border-color: $custom-control-indicator-active-border-color;
51
+    @include box-shadow($custom-control-indicator-active-box-shadow);
52
+  }
53
+
54
+  &:disabled {
55
+    ~ .custom-control-label {
56
+      color: $custom-control-label-disabled-color;
57
+
58
+      &::before {
59
+        background-color: $custom-control-indicator-disabled-bg;
60
+      }
61
+    }
62
+  }
63
+}
64
+
65
+// Custom control indicators
66
+//
67
+// Build the custom controls out of pseudo-elements.
68
+
69
+.custom-control-label {
70
+  position: relative;
71
+  margin-bottom: 0;
72
+  vertical-align: top;
73
+
74
+  // Background-color and (when enabled) gradient
75
+  &::before {
76
+    position: absolute;
77
+    top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
78
+    left: -($custom-control-gutter + $custom-control-indicator-size);
79
+    display: block;
80
+    width: $custom-control-indicator-size;
81
+    height: $custom-control-indicator-size;
82
+    pointer-events: none;
83
+    content: "";
84
+    background-color: $custom-control-indicator-bg;
85
+    border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;
86
+    @include box-shadow($custom-control-indicator-box-shadow);
87
+  }
88
+
89
+  // Foreground (icon)
90
+  &::after {
91
+    position: absolute;
92
+    top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
93
+    left: -($custom-control-gutter + $custom-control-indicator-size);
94
+    display: block;
95
+    width: $custom-control-indicator-size;
96
+    height: $custom-control-indicator-size;
97
+    content: "";
98
+    background: no-repeat 50% / #{$custom-control-indicator-bg-size};
99
+  }
100
+}
101
+
102
+
103
+// Checkboxes
104
+//
105
+// Tweak just a few things for checkboxes.
106
+
107
+.custom-checkbox {
108
+  .custom-control-label::before {
109
+    @include border-radius($custom-checkbox-indicator-border-radius);
110
+  }
111
+
112
+  .custom-control-input:checked ~ .custom-control-label {
113
+    &::after {
114
+      background-image: $custom-checkbox-indicator-icon-checked;
115
+    }
116
+  }
117
+
118
+  .custom-control-input:indeterminate ~ .custom-control-label {
119
+    &::before {
120
+      border-color: $custom-checkbox-indicator-indeterminate-border-color;
121
+      @include gradient-bg($custom-checkbox-indicator-indeterminate-bg);
122
+      @include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);
123
+    }
124
+    &::after {
125
+      background-image: $custom-checkbox-indicator-icon-indeterminate;
126
+    }
127
+  }
128
+
129
+  .custom-control-input:disabled {
130
+    &:checked ~ .custom-control-label::before {
131
+      background-color: $custom-control-indicator-checked-disabled-bg;
132
+    }
133
+    &:indeterminate ~ .custom-control-label::before {
134
+      background-color: $custom-control-indicator-checked-disabled-bg;
135
+    }
136
+  }
137
+}
138
+
139
+// Radios
140
+//
141
+// Tweak just a few things for radios.
142
+
143
+.custom-radio {
144
+  .custom-control-label::before {
145
+    // stylelint-disable-next-line property-blacklist
146
+    border-radius: $custom-radio-indicator-border-radius;
147
+  }
148
+
149
+  .custom-control-input:checked ~ .custom-control-label {
150
+    &::after {
151
+      background-image: $custom-radio-indicator-icon-checked;
152
+    }
153
+  }
154
+
155
+  .custom-control-input:disabled {
156
+    &:checked ~ .custom-control-label::before {
157
+      background-color: $custom-control-indicator-checked-disabled-bg;
158
+    }
159
+  }
160
+}
161
+
162
+
163
+// switches
164
+//
165
+// Tweak a few things for switches
166
+
167
+.custom-switch {
168
+  padding-left: $custom-switch-width + $custom-control-gutter;
169
+
170
+  .custom-control-label {
171
+    &::before {
172
+      left: -($custom-switch-width + $custom-control-gutter);
173
+      width: $custom-switch-width;
174
+      pointer-events: all;
175
+      // stylelint-disable-next-line property-blacklist
176
+      border-radius: $custom-switch-indicator-border-radius;
177
+    }
178
+
179
+    &::after {
180
+      top: calc(#{(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2)} + #{$custom-control-indicator-border-width * 2});
181
+      left: calc(#{-($custom-switch-width + $custom-control-gutter)} + #{$custom-control-indicator-border-width * 2});
182
+      width: $custom-switch-indicator-size;
183
+      height: $custom-switch-indicator-size;
184
+      background-color: $custom-control-indicator-border-color;
185
+      // stylelint-disable-next-line property-blacklist
186
+      border-radius: $custom-switch-indicator-border-radius;
187
+      @include transition(transform .15s ease-in-out, $custom-forms-transition);
188
+    }
189
+  }
190
+
191
+  .custom-control-input:checked ~ .custom-control-label {
192
+    &::after {
193
+      background-color: $custom-control-indicator-bg;
194
+      transform: translateX($custom-switch-width - $custom-control-indicator-size);
195
+    }
196
+  }
197
+
198
+  .custom-control-input:disabled {
199
+    &:checked ~ .custom-control-label::before {
200
+      background-color: $custom-control-indicator-checked-disabled-bg;
201
+    }
202
+  }
203
+}
204
+
205
+
206
+// Select
207
+//
208
+// Replaces the browser default select with a custom one, mostly pulled from
209
+// https://primer.github.io/.
210
+//
211
+
212
+.custom-select {
213
+  display: inline-block;
214
+  width: 100%;
215
+  height: $custom-select-height;
216
+  padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;
217
+  font-family: $custom-select-font-family;
218
+  @include font-size($custom-select-font-size);
219
+  font-weight: $custom-select-font-weight;
220
+  line-height: $custom-select-line-height;
221
+  color: $custom-select-color;
222
+  vertical-align: middle;
223
+  background: $custom-select-background;
224
+  background-color: $custom-select-bg;
225
+  border: $custom-select-border-width solid $custom-select-border-color;
226
+  @include border-radius($custom-select-border-radius, 0);
227
+  @include box-shadow($custom-select-box-shadow);
228
+  appearance: none;
229
+
230
+  &:focus {
231
+    border-color: $custom-select-focus-border-color;
232
+    outline: 0;
233
+    @if $enable-shadows {
234
+      box-shadow: $custom-select-box-shadow, $custom-select-focus-box-shadow;
235
+    } @else {
236
+      box-shadow: $custom-select-focus-box-shadow;
237
+    }
238
+
239
+    &::-ms-value {
240
+      // For visual consistency with other platforms/browsers,
241
+      // suppress the default white text on blue background highlight given to
242
+      // the selected option text when the (still closed) <select> receives focus
243
+      // in IE and (under certain conditions) Edge.
244
+      // See https://github.com/twbs/bootstrap/issues/19398.
245
+      color: $input-color;
246
+      background-color: $input-bg;
247
+    }
248
+  }
249
+
250
+  &[multiple],
251
+  &[size]:not([size="1"]) {
252
+    height: auto;
253
+    padding-right: $custom-select-padding-x;
254
+    background-image: none;
255
+  }
256
+
257
+  &:disabled {
258
+    color: $custom-select-disabled-color;
259
+    background-color: $custom-select-disabled-bg;
260
+  }
261
+
262
+  // Hides the default caret in IE11
263
+  &::-ms-expand {
264
+    display: none;
265
+  }
266
+}
267
+
268
+.custom-select-sm {
269
+  height: $custom-select-height-sm;
270
+  padding-top: $custom-select-padding-y-sm;
271
+  padding-bottom: $custom-select-padding-y-sm;
272
+  padding-left: $custom-select-padding-x-sm;
273
+  @include font-size($custom-select-font-size-sm);
274
+}
275
+
276
+.custom-select-lg {
277
+  height: $custom-select-height-lg;
278
+  padding-top: $custom-select-padding-y-lg;
279
+  padding-bottom: $custom-select-padding-y-lg;
280
+  padding-left: $custom-select-padding-x-lg;
281
+  @include font-size($custom-select-font-size-lg);
282
+}
283
+
284
+
285
+// File
286
+//
287
+// Custom file input.
288
+
289
+.custom-file {
290
+  position: relative;
291
+  display: inline-block;
292
+  width: 100%;
293
+  height: $custom-file-height;
294
+  margin-bottom: 0;
295
+}
296
+
297
+.custom-file-input {
298
+  position: relative;
299
+  z-index: 2;
300
+  width: 100%;
301
+  height: $custom-file-height;
302
+  margin: 0;
303
+  opacity: 0;
304
+
305
+  &:focus ~ .custom-file-label {
306
+    border-color: $custom-file-focus-border-color;
307
+    box-shadow: $custom-file-focus-box-shadow;
308
+  }
309
+
310
+  &:disabled ~ .custom-file-label {
311
+    background-color: $custom-file-disabled-bg;
312
+  }
313
+
314
+  @each $lang, $value in $custom-file-text {
315
+    &:lang(#{$lang}) ~ .custom-file-label::after {
316
+      content: $value;
317
+    }
318
+  }
319
+
320
+  ~ .custom-file-label[data-browse]::after {
321
+    content: attr(data-browse);
322
+  }
323
+}
324
+
325
+.custom-file-label {
326
+  position: absolute;
327
+  top: 0;
328
+  right: 0;
329
+  left: 0;
330
+  z-index: 1;
331
+  height: $custom-file-height;
332
+  padding: $custom-file-padding-y $custom-file-padding-x;
333
+  font-family: $custom-file-font-family;
334
+  font-weight: $custom-file-font-weight;
335
+  line-height: $custom-file-line-height;
336
+  color: $custom-file-color;
337
+  background-color: $custom-file-bg;
338
+  border: $custom-file-border-width solid $custom-file-border-color;
339
+  @include border-radius($custom-file-border-radius);
340
+  @include box-shadow($custom-file-box-shadow);
341
+
342
+  &::after {
343
+    position: absolute;
344
+    top: 0;
345
+    right: 0;
346
+    bottom: 0;
347
+    z-index: 3;
348
+    display: block;
349
+    height: $custom-file-height-inner;
350
+    padding: $custom-file-padding-y $custom-file-padding-x;
351
+    line-height: $custom-file-line-height;
352
+    color: $custom-file-button-color;
353
+    content: "Browse";
354
+    @include gradient-bg($custom-file-button-bg);
355
+    border-left: inherit;
356
+    @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);
357
+  }
358
+}
359
+
360
+// Range
361
+//
362
+// Style range inputs the same across browsers. Vendor-specific rules for pseudo
363
+// elements cannot be mixed. As such, there are no shared styles for focus or
364
+// active states on prefixed selectors.
365
+
366
+.custom-range {
367
+  width: 100%;
368
+  height: calc(#{$custom-range-thumb-height} + #{$custom-range-thumb-focus-box-shadow-width * 2});
369
+  padding: 0; // Need to reset padding
370
+  background-color: transparent;
371
+  appearance: none;
372
+
373
+  &:focus {
374
+    outline: none;
375
+
376
+    // Pseudo-elements must be split across multiple rulesets to have an effect.
377
+    // No box-shadow() mixin for focus accessibility.
378
+    &::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
379
+    &::-moz-range-thumb     { box-shadow: $custom-range-thumb-focus-box-shadow; }
380
+    &::-ms-thumb            { box-shadow: $custom-range-thumb-focus-box-shadow; }
381
+  }
382
+
383
+  &::-moz-focus-outer {
384
+    border: 0;
385
+  }
386
+
387
+  &::-webkit-slider-thumb {
388
+    width: $custom-range-thumb-width;
389
+    height: $custom-range-thumb-height;
390
+    margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific
391
+    @include gradient-bg($custom-range-thumb-bg);
392
+    border: $custom-range-thumb-border;
393
+    @include border-radius($custom-range-thumb-border-radius);
394
+    @include box-shadow($custom-range-thumb-box-shadow);
395
+    @include transition($custom-forms-transition);
396
+    appearance: none;
397
+
398
+    &:active {
399
+      @include gradient-bg($custom-range-thumb-active-bg);
400
+    }
401
+  }
402
+
403
+  &::-webkit-slider-runnable-track {
404
+    width: $custom-range-track-width;
405
+    height: $custom-range-track-height;
406
+    color: transparent; // Why?
407
+    cursor: $custom-range-track-cursor;
408
+    background-color: $custom-range-track-bg;
409
+    border-color: transparent;
410
+    @include border-radius($custom-range-track-border-radius);
411
+    @include box-shadow($custom-range-track-box-shadow);
412
+  }
413
+
414
+  &::-moz-range-thumb {
415
+    width: $custom-range-thumb-width;
416
+    height: $custom-range-thumb-height;
417
+    @include gradient-bg($custom-range-thumb-bg);
418
+    border: $custom-range-thumb-border;
419
+    @include border-radius($custom-range-thumb-border-radius);
420
+    @include box-shadow($custom-range-thumb-box-shadow);
421
+    @include transition($custom-forms-transition);
422
+    appearance: none;
423
+
424
+    &:active {
425
+      @include gradient-bg($custom-range-thumb-active-bg);
426
+    }
427
+  }
428
+
429
+  &::-moz-range-track {
430
+    width: $custom-range-track-width;
431
+    height: $custom-range-track-height;
432
+    color: transparent;
433
+    cursor: $custom-range-track-cursor;
434
+    background-color: $custom-range-track-bg;
435
+    border-color: transparent; // Firefox specific?
436
+    @include border-radius($custom-range-track-border-radius);
437
+    @include box-shadow($custom-range-track-box-shadow);
438
+  }
439
+
440
+  &::-ms-thumb {
441
+    width: $custom-range-thumb-width;
442
+    height: $custom-range-thumb-height;
443
+    margin-top: 0; // Edge specific
444
+    margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
445
+    margin-left: $custom-range-thumb-focus-box-shadow-width;  // Workaround that overflowed box-shadow is hidden.
446
+    @include gradient-bg($custom-range-thumb-bg);
447
+    border: $custom-range-thumb-border;
448
+    @include border-radius($custom-range-thumb-border-radius);
449
+    @include box-shadow($custom-range-thumb-box-shadow);
450
+    @include transition($custom-forms-transition);
451
+    appearance: none;
452
+
453
+    &:active {
454
+      @include gradient-bg($custom-range-thumb-active-bg);
455
+    }
456
+  }
457
+
458
+  &::-ms-track {
459
+    width: $custom-range-track-width;
460
+    height: $custom-range-track-height;
461
+    color: transparent;
462
+    cursor: $custom-range-track-cursor;
463
+    background-color: transparent;
464
+    border-color: transparent;
465
+    border-width: $custom-range-thumb-height / 2;
466
+    @include box-shadow($custom-range-track-box-shadow);
467
+  }
468
+
469
+  &::-ms-fill-lower {
470
+    background-color: $custom-range-track-bg;
471
+    @include border-radius($custom-range-track-border-radius);
472
+  }
473
+
474
+  &::-ms-fill-upper {
475
+    margin-right: 15px; // arbitrary?
476
+    background-color: $custom-range-track-bg;
477
+    @include border-radius($custom-range-track-border-radius);
478
+  }
479
+
480
+  &:disabled {
481
+    &::-webkit-slider-thumb {
482
+      background-color: $custom-range-thumb-disabled-bg;
483
+    }
484
+
485
+    &::-webkit-slider-runnable-track {
486
+      cursor: default;
487
+    }
488
+
489
+    &::-moz-range-thumb {
490
+      background-color: $custom-range-thumb-disabled-bg;
491
+    }
492
+
493
+    &::-moz-range-track {
494
+      cursor: default;
495
+    }
496
+
497
+    &::-ms-thumb {
498
+      background-color: $custom-range-thumb-disabled-bg;
499
+    }
500
+  }
501
+}
502
+
503
+.custom-control-label::before,
504
+.custom-file-label,
505
+.custom-select {
506
+  @include transition($custom-forms-transition);
507
+}

+ 191
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_dropdown.scss View File

@@ -0,0 +1,191 @@
1
+// The dropdown wrapper (`<div>`)
2
+.dropup,
3
+.dropright,
4
+.dropdown,
5
+.dropleft {
6
+  position: relative;
7
+}
8
+
9
+.dropdown-toggle {
10
+  white-space: nowrap;
11
+
12
+  // Generate the caret automatically
13
+  @include caret;
14
+}
15
+
16
+// The dropdown menu
17
+.dropdown-menu {
18
+  position: absolute;
19
+  top: 100%;
20
+  left: 0;
21
+  z-index: $zindex-dropdown;
22
+  display: none; // none by default, but block on "open" of the menu
23
+  float: left;
24
+  min-width: $dropdown-min-width;
25
+  padding: $dropdown-padding-y 0;
26
+  margin: $dropdown-spacer 0 0; // override default ul
27
+  @include font-size($dropdown-font-size);
28
+  color: $dropdown-color;
29
+  text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
30
+  list-style: none;
31
+  background-color: $dropdown-bg;
32
+  background-clip: padding-box;
33
+  border: $dropdown-border-width solid $dropdown-border-color;
34
+  @include border-radius($dropdown-border-radius);
35
+  @include box-shadow($dropdown-box-shadow);
36
+}
37
+
38
+@each $breakpoint in map-keys($grid-breakpoints) {
39
+  @include media-breakpoint-up($breakpoint) {
40
+    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
41
+
42
+    .dropdown-menu#{$infix}-left {
43
+      right: auto;
44
+      left: 0;
45
+    }
46
+
47
+    .dropdown-menu#{$infix}-right {
48
+      right: 0;
49
+      left: auto;
50
+    }
51
+  }
52
+}
53
+
54
+// Allow for dropdowns to go bottom up (aka, dropup-menu)
55
+// Just add .dropup after the standard .dropdown class and you're set.
56
+.dropup {
57
+  .dropdown-menu {
58
+    top: auto;
59
+    bottom: 100%;
60
+    margin-top: 0;
61
+    margin-bottom: $dropdown-spacer;
62
+  }
63
+
64
+  .dropdown-toggle {
65
+    @include caret(up);
66
+  }
67
+}
68
+
69
+.dropright {
70
+  .dropdown-menu {
71
+    top: 0;
72
+    right: auto;
73
+    left: 100%;
74
+    margin-top: 0;
75
+    margin-left: $dropdown-spacer;
76
+  }
77
+
78
+  .dropdown-toggle {
79
+    @include caret(right);
80
+    &::after {
81
+      vertical-align: 0;
82
+    }
83
+  }
84
+}
85
+
86
+.dropleft {
87
+  .dropdown-menu {
88
+    top: 0;
89
+    right: 100%;
90
+    left: auto;
91
+    margin-top: 0;
92
+    margin-right: $dropdown-spacer;
93
+  }
94
+
95
+  .dropdown-toggle {
96
+    @include caret(left);
97
+    &::before {
98
+      vertical-align: 0;
99
+    }
100
+  }
101
+}
102
+
103
+// When enabled Popper.js, reset basic dropdown position
104
+// stylelint-disable-next-line no-duplicate-selectors
105
+.dropdown-menu {
106
+  &[x-placement^="top"],
107
+  &[x-placement^="right"],
108
+  &[x-placement^="bottom"],
109
+  &[x-placement^="left"] {
110
+    right: auto;
111
+    bottom: auto;
112
+  }
113
+}
114
+
115
+// Dividers (basically an `<hr>`) within the dropdown
116
+.dropdown-divider {
117
+  @include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y);
118
+}
119
+
120
+// Links, buttons, and more within the dropdown menu
121
+//
122
+// `<button>`-specific styles are denoted with `// For <button>s`
123
+.dropdown-item {
124
+  display: block;
125
+  width: 100%; // For `<button>`s
126
+  padding: $dropdown-item-padding-y $dropdown-item-padding-x;
127
+  clear: both;
128
+  font-weight: $font-weight-normal;
129
+  color: $dropdown-link-color;
130
+  text-align: inherit; // For `<button>`s
131
+  white-space: nowrap; // prevent links from randomly breaking onto new lines
132
+  background-color: transparent; // For `<button>`s
133
+  border: 0; // For `<button>`s
134
+
135
+  // Prevent dropdown overflow if there's no padding
136
+  // See https://github.com/twbs/bootstrap/pull/27703
137
+  @if $dropdown-padding-y == 0 {
138
+    &:first-child {
139
+      @include border-top-radius($dropdown-inner-border-radius);
140
+    }
141
+
142
+    &:last-child {
143
+      @include border-bottom-radius($dropdown-inner-border-radius);
144
+    }
145
+  }
146
+
147
+  @include hover-focus {
148
+    color: $dropdown-link-hover-color;
149
+    text-decoration: none;
150
+    @include gradient-bg($dropdown-link-hover-bg);
151
+  }
152
+
153
+  &.active,
154
+  &:active {
155
+    color: $dropdown-link-active-color;
156
+    text-decoration: none;
157
+    @include gradient-bg($dropdown-link-active-bg);
158
+  }
159
+
160
+  &.disabled,
161
+  &:disabled {
162
+    color: $dropdown-link-disabled-color;
163
+    pointer-events: none;
164
+    background-color: transparent;
165
+    // Remove CSS gradients if they're enabled
166
+    @if $enable-gradients {
167
+      background-image: none;
168
+    }
169
+  }
170
+}
171
+
172
+.dropdown-menu.show {
173
+  display: block;
174
+}
175
+
176
+// Dropdown section headers
177
+.dropdown-header {
178
+  display: block;
179
+  padding: $dropdown-padding-y $dropdown-item-padding-x;
180
+  margin-bottom: 0; // for use with heading elements
181
+  @include font-size($font-size-sm);
182
+  color: $dropdown-header-color;
183
+  white-space: nowrap; // as with > li > a
184
+}
185
+
186
+// Dropdown text
187
+.dropdown-item-text {
188
+  display: block;
189
+  padding: $dropdown-item-padding-y $dropdown-item-padding-x;
190
+  color: $dropdown-link-color;
191
+}

+ 330
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_forms.scss View File

@@ -0,0 +1,330 @@
1
+// stylelint-disable selector-no-qualifying-type
2
+
3
+//
4
+// Textual form controls
5
+//
6
+
7
+.form-control {
8
+  display: block;
9
+  width: 100%;
10
+  height: $input-height;
11
+  padding: $input-padding-y $input-padding-x;
12
+  font-family: $input-font-family;
13
+  @include font-size($input-font-size);
14
+  font-weight: $input-font-weight;
15
+  line-height: $input-line-height;
16
+  color: $input-color;
17
+  background-color: $input-bg;
18
+  background-clip: padding-box;
19
+  border: $input-border-width solid $input-border-color;
20
+
21
+  // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
22
+  @include border-radius($input-border-radius, 0);
23
+
24
+  @include box-shadow($input-box-shadow);
25
+  @include transition($input-transition);
26
+
27
+  // Unstyle the caret on `<select>`s in IE10+.
28
+  &::-ms-expand {
29
+    background-color: transparent;
30
+    border: 0;
31
+  }
32
+
33
+  // Customize the `:focus` state to imitate native WebKit styles.
34
+  @include form-control-focus();
35
+
36
+  // Placeholder
37
+  &::placeholder {
38
+    color: $input-placeholder-color;
39
+    // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
40
+    opacity: 1;
41
+  }
42
+
43
+  // Disabled and read-only inputs
44
+  //
45
+  // HTML5 says that controls under a fieldset > legend:first-child won't be
46
+  // disabled if the fieldset is disabled. Due to implementation difficulty, we
47
+  // don't honor that edge case; we style them as disabled anyway.
48
+  &:disabled,
49
+  &[readonly] {
50
+    background-color: $input-disabled-bg;
51
+    // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
52
+    opacity: 1;
53
+  }
54
+}
55
+
56
+select.form-control {
57
+  &:focus::-ms-value {
58
+    // Suppress the nested default white text on blue background highlight given to
59
+    // the selected option text when the (still closed) <select> receives focus
60
+    // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to
61
+    // match the appearance of the native widget.
62
+    // See https://github.com/twbs/bootstrap/issues/19398.
63
+    color: $input-color;
64
+    background-color: $input-bg;
65
+  }
66
+}
67
+
68
+// Make file inputs better match text inputs by forcing them to new lines.
69
+.form-control-file,
70
+.form-control-range {
71
+  display: block;
72
+  width: 100%;
73
+}
74
+
75
+
76
+//
77
+// Labels
78
+//
79
+
80
+// For use with horizontal and inline forms, when you need the label (or legend)
81
+// text to align with the form controls.
82
+.col-form-label {
83
+  padding-top: calc(#{$input-padding-y} + #{$input-border-width});
84
+  padding-bottom: calc(#{$input-padding-y} + #{$input-border-width});
85
+  margin-bottom: 0; // Override the `<label>/<legend>` default
86
+  @include font-size(inherit); // Override the `<legend>` default
87
+  line-height: $input-line-height;
88
+}
89
+
90
+.col-form-label-lg {
91
+  padding-top: calc(#{$input-padding-y-lg} + #{$input-border-width});
92
+  padding-bottom: calc(#{$input-padding-y-lg} + #{$input-border-width});
93
+  @include font-size($input-font-size-lg);
94
+  line-height: $input-line-height-lg;
95
+}
96
+
97
+.col-form-label-sm {
98
+  padding-top: calc(#{$input-padding-y-sm} + #{$input-border-width});
99
+  padding-bottom: calc(#{$input-padding-y-sm} + #{$input-border-width});
100
+  @include font-size($input-font-size-sm);
101
+  line-height: $input-line-height-sm;
102
+}
103
+
104
+
105
+// Readonly controls as plain text
106
+//
107
+// Apply class to a readonly input to make it appear like regular plain
108
+// text (without any border, background color, focus indicator)
109
+
110
+.form-control-plaintext {
111
+  display: block;
112
+  width: 100%;
113
+  padding-top: $input-padding-y;
114
+  padding-bottom: $input-padding-y;
115
+  margin-bottom: 0; // match inputs if this class comes on inputs with default margins
116
+  line-height: $input-line-height;
117
+  color: $input-plaintext-color;
118
+  background-color: transparent;
119
+  border: solid transparent;
120
+  border-width: $input-border-width 0;
121
+
122
+  &.form-control-sm,
123
+  &.form-control-lg {
124
+    padding-right: 0;
125
+    padding-left: 0;
126
+  }
127
+}
128
+
129
+
130
+// Form control sizing
131
+//
132
+// Build on `.form-control` with modifier classes to decrease or increase the
133
+// height and font-size of form controls.
134
+//
135
+// Repeated in `_input_group.scss` to avoid Sass extend issues.
136
+
137
+.form-control-sm {
138
+  height: $input-height-sm;
139
+  padding: $input-padding-y-sm $input-padding-x-sm;
140
+  @include font-size($input-font-size-sm);
141
+  line-height: $input-line-height-sm;
142
+  @include border-radius($input-border-radius-sm);
143
+}
144
+
145
+.form-control-lg {
146
+  height: $input-height-lg;
147
+  padding: $input-padding-y-lg $input-padding-x-lg;
148
+  @include font-size($input-font-size-lg);
149
+  line-height: $input-line-height-lg;
150
+  @include border-radius($input-border-radius-lg);
151
+}
152
+
153
+// stylelint-disable-next-line no-duplicate-selectors
154
+select.form-control {
155
+  &[size],
156
+  &[multiple] {
157
+    height: auto;
158
+  }
159
+}
160
+
161
+textarea.form-control {
162
+  height: auto;
163
+}
164
+
165
+// Form groups
166
+//
167
+// Designed to help with the organization and spacing of vertical forms. For
168
+// horizontal forms, use the predefined grid classes.
169
+
170
+.form-group {
171
+  margin-bottom: $form-group-margin-bottom;
172
+}
173
+
174
+.form-text {
175
+  display: block;
176
+  margin-top: $form-text-margin-top;
177
+}
178
+
179
+
180
+// Form grid
181
+//
182
+// Special replacement for our grid system's `.row` for tighter form layouts.
183
+
184
+.form-row {
185
+  display: flex;
186
+  flex-wrap: wrap;
187
+  margin-right: -$form-grid-gutter-width / 2;
188
+  margin-left: -$form-grid-gutter-width / 2;
189
+
190
+  > .col,
191
+  > [class*="col-"] {
192
+    padding-right: $form-grid-gutter-width / 2;
193
+    padding-left: $form-grid-gutter-width / 2;
194
+  }
195
+}
196
+
197
+
198
+// Checkboxes and radios
199
+//
200
+// Indent the labels to position radios/checkboxes as hanging controls.
201
+
202
+.form-check {
203
+  position: relative;
204
+  display: block;
205
+  padding-left: $form-check-input-gutter;
206
+}
207
+
208
+.form-check-input {
209
+  position: absolute;
210
+  margin-top: $form-check-input-margin-y;
211
+  margin-left: -$form-check-input-gutter;
212
+
213
+  &:disabled ~ .form-check-label {
214
+    color: $text-muted;
215
+  }
216
+}
217
+
218
+.form-check-label {
219
+  margin-bottom: 0; // Override default `<label>` bottom margin
220
+}
221
+
222
+.form-check-inline {
223
+  display: inline-flex;
224
+  align-items: center;
225
+  padding-left: 0; // Override base .form-check
226
+  margin-right: $form-check-inline-margin-x;
227
+
228
+  // Undo .form-check-input defaults and add some `margin-right`.
229
+  .form-check-input {
230
+    position: static;
231
+    margin-top: 0;
232
+    margin-right: $form-check-inline-input-margin-x;
233
+    margin-left: 0;
234
+  }
235
+}
236
+
237
+
238
+// Form validation
239
+//
240
+// Provide feedback to users when form field values are valid or invalid. Works
241
+// primarily for client-side validation via scoped `:invalid` and `:valid`
242
+// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
243
+// server side validation.
244
+
245
+@each $state, $data in $form-validation-states {
246
+  @include form-validation-state($state, map-get($data, color), map-get($data, icon));
247
+}
248
+
249
+// Inline forms
250
+//
251
+// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
252
+// forms begin stacked on extra small (mobile) devices and then go inline when
253
+// viewports reach <768px.
254
+//
255
+// Requires wrapping inputs and labels with `.form-group` for proper display of
256
+// default HTML form controls and our custom form controls (e.g., input groups).
257
+
258
+.form-inline {
259
+  display: flex;
260
+  flex-flow: row wrap;
261
+  align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)
262
+
263
+  // Because we use flex, the initial sizing of checkboxes is collapsed and
264
+  // doesn't occupy the full-width (which is what we want for xs grid tier),
265
+  // so we force that here.
266
+  .form-check {
267
+    width: 100%;
268
+  }
269
+
270
+  // Kick in the inline
271
+  @include media-breakpoint-up(sm) {
272
+    label {
273
+      display: flex;
274
+      align-items: center;
275
+      justify-content: center;
276
+      margin-bottom: 0;
277
+    }
278
+
279
+    // Inline-block all the things for "inline"
280
+    .form-group {
281
+      display: flex;
282
+      flex: 0 0 auto;
283
+      flex-flow: row wrap;
284
+      align-items: center;
285
+      margin-bottom: 0;
286
+    }
287
+
288
+    // Allow folks to *not* use `.form-group`
289
+    .form-control {
290
+      display: inline-block;
291
+      width: auto; // Prevent labels from stacking above inputs in `.form-group`
292
+      vertical-align: middle;
293
+    }
294
+
295
+    // Make static controls behave like regular ones
296
+    .form-control-plaintext {
297
+      display: inline-block;
298
+    }
299
+
300
+    .input-group,
301
+    .custom-select {
302
+      width: auto;
303
+    }
304
+
305
+    // Remove default margin on radios/checkboxes that were used for stacking, and
306
+    // then undo the floating of radios and checkboxes to match.
307
+    .form-check {
308
+      display: flex;
309
+      align-items: center;
310
+      justify-content: center;
311
+      width: auto;
312
+      padding-left: 0;
313
+    }
314
+    .form-check-input {
315
+      position: relative;
316
+      flex-shrink: 0;
317
+      margin-top: 0;
318
+      margin-right: $form-check-input-margin-x;
319
+      margin-left: 0;
320
+    }
321
+
322
+    .custom-control {
323
+      align-items: center;
324
+      justify-content: center;
325
+    }
326
+    .custom-control-label {
327
+      margin-bottom: 0;
328
+    }
329
+  }
330
+}

+ 86
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_functions.scss View File

@@ -0,0 +1,86 @@
1
+// Bootstrap functions
2
+//
3
+// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.
4
+
5
+// Ascending
6
+// Used to evaluate Sass maps like our grid breakpoints.
7
+@mixin _assert-ascending($map, $map-name) {
8
+  $prev-key: null;
9
+  $prev-num: null;
10
+  @each $key, $num in $map {
11
+    @if $prev-num == null or unit($num) == "%" {
12
+      // Do nothing
13
+    } @else if not comparable($prev-num, $num) {
14
+      @warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
15
+    } @else if $prev-num >= $num {
16
+      @warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
17
+    }
18
+    $prev-key: $key;
19
+    $prev-num: $num;
20
+  }
21
+}
22
+
23
+// Starts at zero
24
+// Used to ensure the min-width of the lowest breakpoint starts at 0.
25
+@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") {
26
+  $values: map-values($map);
27
+  $first-value: nth($values, 1);
28
+  @if $first-value != 0 {
29
+    @warn "First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.";
30
+  }
31
+}
32
+
33
+// Replace `$search` with `$replace` in `$string`
34
+// Used on our SVG icon backgrounds for custom forms.
35
+//
36
+// @author Hugo Giraudel
37
+// @param {String} $string - Initial string
38
+// @param {String} $search - Substring to replace
39
+// @param {String} $replace ('') - New value
40
+// @return {String} - Updated string
41
+@function str-replace($string, $search, $replace: "") {
42
+  $index: str-index($string, $search);
43
+
44
+  @if $index {
45
+    @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
46
+  }
47
+
48
+  @return $string;
49
+}
50
+
51
+// Color contrast
52
+@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {
53
+  $r: red($color);
54
+  $g: green($color);
55
+  $b: blue($color);
56
+
57
+  $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
58
+
59
+  @if ($yiq >= $yiq-contrasted-threshold) {
60
+    @return $dark;
61
+  } @else {
62
+    @return $light;
63
+  }
64
+}
65
+
66
+// Retrieve color Sass maps
67
+@function color($key: "blue") {
68
+  @return map-get($colors, $key);
69
+}
70
+
71
+@function theme-color($key: "primary") {
72
+  @return map-get($theme-colors, $key);
73
+}
74
+
75
+@function gray($key: "100") {
76
+  @return map-get($grays, $key);
77
+}
78
+
79
+// Request a theme color level
80
+@function theme-color-level($color-name: "primary", $level: 0) {
81
+  $color: theme-color($color-name);
82
+  $color-base: if($level > 0, $black, $white);
83
+  $level: abs($level);
84
+
85
+  @return mix($color-base, $color, $level * $theme-color-interval);
86
+}

+ 52
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_grid.scss View File

@@ -0,0 +1,52 @@
1
+// Container widths
2
+//
3
+// Set the container width, and override it for fixed navbars in media queries.
4
+
5
+@if $enable-grid-classes {
6
+  .container {
7
+    @include make-container();
8
+    @include make-container-max-widths();
9
+  }
10
+}
11
+
12
+// Fluid container
13
+//
14
+// Utilizes the mixin meant for fixed width containers, but with 100% width for
15
+// fluid, full width layouts.
16
+
17
+@if $enable-grid-classes {
18
+  .container-fluid {
19
+    @include make-container();
20
+  }
21
+}
22
+
23
+// Row
24
+//
25
+// Rows contain and clear the floats of your columns.
26
+
27
+@if $enable-grid-classes {
28
+  .row {
29
+    @include make-row();
30
+  }
31
+
32
+  // Remove the negative margin from default .row, then the horizontal padding
33
+  // from all immediate children columns (to prevent runaway style inheritance).
34
+  .no-gutters {
35
+    margin-right: 0;
36
+    margin-left: 0;
37
+
38
+    > .col,
39
+    > [class*="col-"] {
40
+      padding-right: 0;
41
+      padding-left: 0;
42
+    }
43
+  }
44
+}
45
+
46
+// Columns
47
+//
48
+// Common styles for small and large grid columns
49
+
50
+@if $enable-grid-classes {
51
+  @include make-grid-columns();
52
+}

+ 42
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_images.scss View File

@@ -0,0 +1,42 @@
1
+// Responsive images (ensure images don't scale beyond their parents)
2
+//
3
+// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
4
+// We previously tried the "images are responsive by default" approach in Bootstrap v2,
5
+// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
6
+// which weren't expecting the images within themselves to be involuntarily resized.
7
+// See also https://github.com/twbs/bootstrap/issues/18178
8
+.img-fluid {
9
+  @include img-fluid;
10
+}
11
+
12
+
13
+// Image thumbnails
14
+.img-thumbnail {
15
+  padding: $thumbnail-padding;
16
+  background-color: $thumbnail-bg;
17
+  border: $thumbnail-border-width solid $thumbnail-border-color;
18
+  @include border-radius($thumbnail-border-radius);
19
+  @include box-shadow($thumbnail-box-shadow);
20
+
21
+  // Keep them at most 100% wide
22
+  @include img-fluid;
23
+}
24
+
25
+//
26
+// Figures
27
+//
28
+
29
+.figure {
30
+  // Ensures the caption's text aligns with the image.
31
+  display: inline-block;
32
+}
33
+
34
+.figure-img {
35
+  margin-bottom: $spacer / 2;
36
+  line-height: 1;
37
+}
38
+
39
+.figure-caption {
40
+  @include font-size($figure-caption-font-size);
41
+  color: $figure-caption-color;
42
+}

+ 193
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_input-group.scss View File

@@ -0,0 +1,193 @@
1
+// stylelint-disable selector-no-qualifying-type
2
+
3
+//
4
+// Base styles
5
+//
6
+
7
+.input-group {
8
+  position: relative;
9
+  display: flex;
10
+  flex-wrap: wrap; // For form validation feedback
11
+  align-items: stretch;
12
+  width: 100%;
13
+
14
+  > .form-control,
15
+  > .form-control-plaintext,
16
+  > .custom-select,
17
+  > .custom-file {
18
+    position: relative; // For focus state's z-index
19
+    flex: 1 1 auto;
20
+    // Add width 1% and flex-basis auto to ensure that button will not wrap out
21
+    // the column. Applies to IE Edge+ and Firefox. Chrome does not require this.
22
+    width: 1%;
23
+    margin-bottom: 0;
24
+
25
+    + .form-control,
26
+    + .custom-select,
27
+    + .custom-file {
28
+      margin-left: -$input-border-width;
29
+    }
30
+  }
31
+
32
+  // Bring the "active" form control to the top of surrounding elements
33
+  > .form-control:focus,
34
+  > .custom-select:focus,
35
+  > .custom-file .custom-file-input:focus ~ .custom-file-label {
36
+    z-index: 3;
37
+  }
38
+
39
+  // Bring the custom file input above the label
40
+  > .custom-file .custom-file-input:focus {
41
+    z-index: 4;
42
+  }
43
+
44
+  > .form-control,
45
+  > .custom-select {
46
+    &:not(:last-child) { @include border-right-radius(0); }
47
+    &:not(:first-child) { @include border-left-radius(0); }
48
+  }
49
+
50
+  // Custom file inputs have more complex markup, thus requiring different
51
+  // border-radius overrides.
52
+  > .custom-file {
53
+    display: flex;
54
+    align-items: center;
55
+
56
+    &:not(:last-child) .custom-file-label,
57
+    &:not(:last-child) .custom-file-label::after { @include border-right-radius(0); }
58
+    &:not(:first-child) .custom-file-label { @include border-left-radius(0); }
59
+  }
60
+}
61
+
62
+
63
+// Prepend and append
64
+//
65
+// While it requires one extra layer of HTML for each, dedicated prepend and
66
+// append elements allow us to 1) be less clever, 2) simplify our selectors, and
67
+// 3) support HTML5 form validation.
68
+
69
+.input-group-prepend,
70
+.input-group-append {
71
+  display: flex;
72
+
73
+  // Ensure buttons are always above inputs for more visually pleasing borders.
74
+  // This isn't needed for `.input-group-text` since it shares the same border-color
75
+  // as our inputs.
76
+  .btn {
77
+    position: relative;
78
+    z-index: 2;
79
+
80
+    &:focus {
81
+      z-index: 3;
82
+    }
83
+  }
84
+
85
+  .btn + .btn,
86
+  .btn + .input-group-text,
87
+  .input-group-text + .input-group-text,
88
+  .input-group-text + .btn {
89
+    margin-left: -$input-border-width;
90
+  }
91
+}
92
+
93
+.input-group-prepend { margin-right: -$input-border-width; }
94
+.input-group-append { margin-left: -$input-border-width; }
95
+
96
+
97
+// Textual addons
98
+//
99
+// Serves as a catch-all element for any text or radio/checkbox input you wish
100
+// to prepend or append to an input.
101
+
102
+.input-group-text {
103
+  display: flex;
104
+  align-items: center;
105
+  padding: $input-padding-y $input-padding-x;
106
+  margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom
107
+  @include font-size($input-font-size); // Match inputs
108
+  font-weight: $font-weight-normal;
109
+  line-height: $input-line-height;
110
+  color: $input-group-addon-color;
111
+  text-align: center;
112
+  white-space: nowrap;
113
+  background-color: $input-group-addon-bg;
114
+  border: $input-border-width solid $input-group-addon-border-color;
115
+  @include border-radius($input-border-radius);
116
+
117
+  // Nuke default margins from checkboxes and radios to vertically center within.
118
+  input[type="radio"],
119
+  input[type="checkbox"] {
120
+    margin-top: 0;
121
+  }
122
+}
123
+
124
+
125
+// Sizing
126
+//
127
+// Remix the default form control sizing classes into new ones for easier
128
+// manipulation.
129
+
130
+.input-group-lg > .form-control:not(textarea),
131
+.input-group-lg > .custom-select {
132
+  height: $input-height-lg;
133
+}
134
+
135
+.input-group-lg > .form-control,
136
+.input-group-lg > .custom-select,
137
+.input-group-lg > .input-group-prepend > .input-group-text,
138
+.input-group-lg > .input-group-append > .input-group-text,
139
+.input-group-lg > .input-group-prepend > .btn,
140
+.input-group-lg > .input-group-append > .btn {
141
+  padding: $input-padding-y-lg $input-padding-x-lg;
142
+  @include font-size($input-font-size-lg);
143
+  line-height: $input-line-height-lg;
144
+  @include border-radius($input-border-radius-lg);
145
+}
146
+
147
+.input-group-sm > .form-control:not(textarea),
148
+.input-group-sm > .custom-select {
149
+  height: $input-height-sm;
150
+}
151
+
152
+.input-group-sm > .form-control,
153
+.input-group-sm > .custom-select,
154
+.input-group-sm > .input-group-prepend > .input-group-text,
155
+.input-group-sm > .input-group-append > .input-group-text,
156
+.input-group-sm > .input-group-prepend > .btn,
157
+.input-group-sm > .input-group-append > .btn {
158
+  padding: $input-padding-y-sm $input-padding-x-sm;
159
+  @include font-size($input-font-size-sm);
160
+  line-height: $input-line-height-sm;
161
+  @include border-radius($input-border-radius-sm);
162
+}
163
+
164
+.input-group-lg > .custom-select,
165
+.input-group-sm > .custom-select {
166
+  padding-right: $custom-select-padding-x + $custom-select-indicator-padding;
167
+}
168
+
169
+
170
+// Prepend and append rounded corners
171
+//
172
+// These rulesets must come after the sizing ones to properly override sm and lg
173
+// border-radius values when extending. They're more specific than we'd like
174
+// with the `.input-group >` part, but without it, we cannot override the sizing.
175
+
176
+
177
+.input-group > .input-group-prepend > .btn,
178
+.input-group > .input-group-prepend > .input-group-text,
179
+.input-group > .input-group-append:not(:last-child) > .btn,
180
+.input-group > .input-group-append:not(:last-child) > .input-group-text,
181
+.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
182
+.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
183
+  @include border-right-radius(0);
184
+}
185
+
186
+.input-group > .input-group-append > .btn,
187
+.input-group > .input-group-append > .input-group-text,
188
+.input-group > .input-group-prepend:not(:first-child) > .btn,
189
+.input-group > .input-group-prepend:not(:first-child) > .input-group-text,
190
+.input-group > .input-group-prepend:first-child > .btn:not(:first-child),
191
+.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {
192
+  @include border-left-radius(0);
193
+}

+ 17
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_jumbotron.scss View File

@@ -0,0 +1,17 @@
1
+.jumbotron {
2
+  padding: $jumbotron-padding ($jumbotron-padding / 2);
3
+  margin-bottom: $jumbotron-padding;
4
+  color: $jumbotron-color;
5
+  background-color: $jumbotron-bg;
6
+  @include border-radius($border-radius-lg);
7
+
8
+  @include media-breakpoint-up(sm) {
9
+    padding: ($jumbotron-padding * 2) $jumbotron-padding;
10
+  }
11
+}
12
+
13
+.jumbotron-fluid {
14
+  padding-right: 0;
15
+  padding-left: 0;
16
+  @include border-radius(0);
17
+}

+ 149
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_list-group.scss View File

@@ -0,0 +1,149 @@
1
+// Base class
2
+//
3
+// Easily usable on <ul>, <ol>, or <div>.
4
+
5
+.list-group {
6
+  display: flex;
7
+  flex-direction: column;
8
+
9
+  // No need to set list-style: none; since .list-group-item is block level
10
+  padding-left: 0; // reset padding because ul and ol
11
+  margin-bottom: 0;
12
+}
13
+
14
+
15
+// Interactive list items
16
+//
17
+// Use anchor or button elements instead of `li`s or `div`s to create interactive
18
+// list items. Includes an extra `.active` modifier class for selected items.
19
+
20
+.list-group-item-action {
21
+  width: 100%; // For `<button>`s (anchors become 100% by default though)
22
+  color: $list-group-action-color;
23
+  text-align: inherit; // For `<button>`s (anchors inherit)
24
+
25
+  // Hover state
26
+  @include hover-focus {
27
+    z-index: 1; // Place hover/focus items above their siblings for proper border styling
28
+    color: $list-group-action-hover-color;
29
+    text-decoration: none;
30
+    background-color: $list-group-hover-bg;
31
+  }
32
+
33
+  &:active {
34
+    color: $list-group-action-active-color;
35
+    background-color: $list-group-action-active-bg;
36
+  }
37
+}
38
+
39
+
40
+// Individual list items
41
+//
42
+// Use on `li`s or `div`s within the `.list-group` parent.
43
+
44
+.list-group-item {
45
+  position: relative;
46
+  display: block;
47
+  padding: $list-group-item-padding-y $list-group-item-padding-x;
48
+  // Place the border on the list items and negative margin up for better styling
49
+  margin-bottom: -$list-group-border-width;
50
+  color: $list-group-color;
51
+  background-color: $list-group-bg;
52
+  border: $list-group-border-width solid $list-group-border-color;
53
+
54
+  &:first-child {
55
+    @include border-top-radius($list-group-border-radius);
56
+  }
57
+
58
+  &:last-child {
59
+    margin-bottom: 0;
60
+    @include border-bottom-radius($list-group-border-radius);
61
+  }
62
+
63
+  &.disabled,
64
+  &:disabled {
65
+    color: $list-group-disabled-color;
66
+    pointer-events: none;
67
+    background-color: $list-group-disabled-bg;
68
+  }
69
+
70
+  // Include both here for `<a>`s and `<button>`s
71
+  &.active {
72
+    z-index: 2; // Place active items above their siblings for proper border styling
73
+    color: $list-group-active-color;
74
+    background-color: $list-group-active-bg;
75
+    border-color: $list-group-active-border-color;
76
+  }
77
+}
78
+
79
+
80
+// Horizontal
81
+//
82
+// Change the layout of list group items from vertical (default) to horizontal.
83
+
84
+@each $breakpoint in map-keys($grid-breakpoints) {
85
+  @include media-breakpoint-up($breakpoint) {
86
+    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
87
+
88
+    .list-group-horizontal#{$infix} {
89
+      flex-direction: row;
90
+
91
+      .list-group-item {
92
+        margin-right: -$list-group-border-width;
93
+        margin-bottom: 0;
94
+
95
+        &:first-child {
96
+          @include border-left-radius($list-group-border-radius);
97
+          @include border-top-right-radius(0);
98
+        }
99
+
100
+        &:last-child {
101
+          margin-right: 0;
102
+          @include border-right-radius($list-group-border-radius);
103
+          @include border-bottom-left-radius(0);
104
+        }
105
+      }
106
+    }
107
+  }
108
+}
109
+
110
+
111
+// Flush list items
112
+//
113
+// Remove borders and border-radius to keep list group items edge-to-edge. Most
114
+// useful within other components (e.g., cards).
115
+
116
+.list-group-flush {
117
+  .list-group-item {
118
+    border-right: 0;
119
+    border-left: 0;
120
+    @include border-radius(0);
121
+
122
+    &:last-child {
123
+      margin-bottom: -$list-group-border-width;
124
+    }
125
+  }
126
+
127
+  &:first-child {
128
+    .list-group-item:first-child {
129
+      border-top: 0;
130
+    }
131
+  }
132
+
133
+  &:last-child {
134
+    .list-group-item:last-child {
135
+      margin-bottom: 0;
136
+      border-bottom: 0;
137
+    }
138
+  }
139
+}
140
+
141
+
142
+// Contextual variants
143
+//
144
+// Add modifier classes to change text and background color on individual items.
145
+// Organizationally, this must come after the `:hover` states.
146
+
147
+@each $color, $value in $theme-colors {
148
+  @include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));
149
+}

+ 8
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_media.scss View File

@@ -0,0 +1,8 @@
1
+.media {
2
+  display: flex;
3
+  align-items: flex-start;
4
+}
5
+
6
+.media-body {
7
+  flex: 1;
8
+}

+ 47
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_mixins.scss View File

@@ -0,0 +1,47 @@
1
+// Toggles
2
+//
3
+// Used in conjunction with global variables to enable certain theme features.
4
+
5
+// Vendor
6
+@import "vendor/rfs";
7
+
8
+// Deprecate
9
+@import "mixins/deprecate";
10
+
11
+// Utilities
12
+@import "mixins/breakpoints";
13
+@import "mixins/hover";
14
+@import "mixins/image";
15
+@import "mixins/badge";
16
+@import "mixins/resize";
17
+@import "mixins/screen-reader";
18
+@import "mixins/size";
19
+@import "mixins/reset-text";
20
+@import "mixins/text-emphasis";
21
+@import "mixins/text-hide";
22
+@import "mixins/text-truncate";
23
+@import "mixins/visibility";
24
+
25
+// // Components
26
+@import "mixins/alert";
27
+@import "mixins/buttons";
28
+@import "mixins/caret";
29
+@import "mixins/pagination";
30
+@import "mixins/lists";
31
+@import "mixins/list-group";
32
+@import "mixins/nav-divider";
33
+@import "mixins/forms";
34
+@import "mixins/table-row";
35
+
36
+// // Skins
37
+@import "mixins/background-variant";
38
+@import "mixins/border-radius";
39
+@import "mixins/box-shadow";
40
+@import "mixins/gradients";
41
+@import "mixins/transition";
42
+
43
+// // Layout
44
+@import "mixins/clearfix";
45
+@import "mixins/grid-framework";
46
+@import "mixins/grid";
47
+@import "mixins/float";

+ 229
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_modal.scss View File

@@ -0,0 +1,229 @@
1
+// .modal-open      - body class for killing the scroll
2
+// .modal           - container to scroll within
3
+// .modal-dialog    - positioning shell for the actual modal
4
+// .modal-content   - actual modal w/ bg and corners and stuff
5
+
6
+
7
+.modal-open {
8
+  // Kill the scroll on the body
9
+  overflow: hidden;
10
+
11
+  .modal {
12
+    overflow-x: hidden;
13
+    overflow-y: auto;
14
+  }
15
+}
16
+
17
+// Container that the modal scrolls within
18
+.modal {
19
+  position: fixed;
20
+  top: 0;
21
+  left: 0;
22
+  z-index: $zindex-modal;
23
+  display: none;
24
+  width: 100%;
25
+  height: 100%;
26
+  overflow: hidden;
27
+  // Prevent Chrome on Windows from adding a focus outline. For details, see
28
+  // https://github.com/twbs/bootstrap/pull/10951.
29
+  outline: 0;
30
+  // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
31
+  // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
32
+  // See also https://github.com/twbs/bootstrap/issues/17695
33
+}
34
+
35
+// Shell div to position the modal with bottom padding
36
+.modal-dialog {
37
+  position: relative;
38
+  width: auto;
39
+  margin: $modal-dialog-margin;
40
+  // allow clicks to pass through for custom click handling to close modal
41
+  pointer-events: none;
42
+
43
+  // When fading in the modal, animate it to slide down
44
+  .modal.fade & {
45
+    @include transition($modal-transition);
46
+    transform: $modal-fade-transform;
47
+  }
48
+  .modal.show & {
49
+    transform: $modal-show-transform;
50
+  }
51
+}
52
+
53
+.modal-dialog-scrollable {
54
+  display: flex; // IE10/11
55
+  max-height: calc(100% - #{$modal-dialog-margin * 2});
56
+
57
+  .modal-content {
58
+    max-height: calc(100vh - #{$modal-dialog-margin * 2}); // IE10/11
59
+    overflow: hidden;
60
+  }
61
+
62
+  .modal-header,
63
+  .modal-footer {
64
+    flex-shrink: 0;
65
+  }
66
+
67
+  .modal-body {
68
+    overflow-y: auto;
69
+  }
70
+}
71
+
72
+.modal-dialog-centered {
73
+  display: flex;
74
+  align-items: center;
75
+  min-height: calc(100% - #{$modal-dialog-margin * 2});
76
+
77
+  // Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)
78
+  &::before {
79
+    display: block; // IE10
80
+    height: calc(100vh - #{$modal-dialog-margin * 2});
81
+    content: "";
82
+  }
83
+
84
+  // Ensure `.modal-body` shows scrollbar (IE10/11)
85
+  &.modal-dialog-scrollable {
86
+    flex-direction: column;
87
+    justify-content: center;
88
+    height: 100%;
89
+
90
+    .modal-content {
91
+      max-height: none;
92
+    }
93
+
94
+    &::before {
95
+      content: none;
96
+    }
97
+  }
98
+}
99
+
100
+// Actual modal
101
+.modal-content {
102
+  position: relative;
103
+  display: flex;
104
+  flex-direction: column;
105
+  width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
106
+  // counteract the pointer-events: none; in the .modal-dialog
107
+  color: $modal-content-color;
108
+  pointer-events: auto;
109
+  background-color: $modal-content-bg;
110
+  background-clip: padding-box;
111
+  border: $modal-content-border-width solid $modal-content-border-color;
112
+  @include border-radius($modal-content-border-radius);
113
+  @include box-shadow($modal-content-box-shadow-xs);
114
+  // Remove focus outline from opened modal
115
+  outline: 0;
116
+}
117
+
118
+// Modal background
119
+.modal-backdrop {
120
+  position: fixed;
121
+  top: 0;
122
+  left: 0;
123
+  z-index: $zindex-modal-backdrop;
124
+  width: 100vw;
125
+  height: 100vh;
126
+  background-color: $modal-backdrop-bg;
127
+
128
+  // Fade for backdrop
129
+  &.fade { opacity: 0; }
130
+  &.show { opacity: $modal-backdrop-opacity; }
131
+}
132
+
133
+// Modal header
134
+// Top section of the modal w/ title and dismiss
135
+.modal-header {
136
+  display: flex;
137
+  align-items: flex-start; // so the close btn always stays on the upper right corner
138
+  justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends
139
+  padding: $modal-header-padding;
140
+  border-bottom: $modal-header-border-width solid $modal-header-border-color;
141
+  @include border-top-radius($modal-content-border-radius);
142
+
143
+  .close {
144
+    padding: $modal-header-padding;
145
+    // auto on the left force icon to the right even when there is no .modal-title
146
+    margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto;
147
+  }
148
+}
149
+
150
+// Title text within header
151
+.modal-title {
152
+  margin-bottom: 0;
153
+  line-height: $modal-title-line-height;
154
+}
155
+
156
+// Modal body
157
+// Where all modal content resides (sibling of .modal-header and .modal-footer)
158
+.modal-body {
159
+  position: relative;
160
+  // Enable `flex-grow: 1` so that the body take up as much space as possible
161
+  // when should there be a fixed height on `.modal-dialog`.
162
+  flex: 1 1 auto;
163
+  padding: $modal-inner-padding;
164
+}
165
+
166
+// Footer (for actions)
167
+.modal-footer {
168
+  display: flex;
169
+  align-items: center; // vertically center
170
+  justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
171
+  padding: $modal-inner-padding;
172
+  border-top: $modal-footer-border-width solid $modal-footer-border-color;
173
+  @include border-bottom-radius($modal-content-border-radius);
174
+
175
+  // Easily place margin between footer elements
176
+  > :not(:first-child) { margin-left: .25rem; }
177
+  > :not(:last-child) { margin-right: .25rem; }
178
+}
179
+
180
+// Measure scrollbar width for padding body during modal show/hide
181
+.modal-scrollbar-measure {
182
+  position: absolute;
183
+  top: -9999px;
184
+  width: 50px;
185
+  height: 50px;
186
+  overflow: scroll;
187
+}
188
+
189
+// Scale up the modal
190
+@include media-breakpoint-up(sm) {
191
+  // Automatically set modal's width for larger viewports
192
+  .modal-dialog {
193
+    max-width: $modal-md;
194
+    margin: $modal-dialog-margin-y-sm-up auto;
195
+  }
196
+
197
+  .modal-dialog-scrollable {
198
+    max-height: calc(100% - #{$modal-dialog-margin-y-sm-up * 2});
199
+
200
+    .modal-content {
201
+      max-height: calc(100vh - #{$modal-dialog-margin-y-sm-up * 2});
202
+    }
203
+  }
204
+
205
+  .modal-dialog-centered {
206
+    min-height: calc(100% - #{$modal-dialog-margin-y-sm-up * 2});
207
+
208
+    &::before {
209
+      height: calc(100vh - #{$modal-dialog-margin-y-sm-up * 2});
210
+    }
211
+  }
212
+
213
+  .modal-content {
214
+    @include box-shadow($modal-content-box-shadow-sm-up);
215
+  }
216
+
217
+  .modal-sm { max-width: $modal-sm; }
218
+}
219
+
220
+@include media-breakpoint-up(lg) {
221
+  .modal-lg,
222
+  .modal-xl {
223
+    max-width: $modal-lg;
224
+  }
225
+}
226
+
227
+@include media-breakpoint-up(xl) {
228
+  .modal-xl { max-width: $modal-xl; }
229
+}

+ 120
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_nav.scss View File

@@ -0,0 +1,120 @@
1
+// Base class
2
+//
3
+// Kickstart any navigation component with a set of style resets. Works with
4
+// `<nav>`s or `<ul>`s.
5
+
6
+.nav {
7
+  display: flex;
8
+  flex-wrap: wrap;
9
+  padding-left: 0;
10
+  margin-bottom: 0;
11
+  list-style: none;
12
+}
13
+
14
+.nav-link {
15
+  display: block;
16
+  padding: $nav-link-padding-y $nav-link-padding-x;
17
+
18
+  @include hover-focus {
19
+    text-decoration: none;
20
+  }
21
+
22
+  // Disabled state lightens text
23
+  &.disabled {
24
+    color: $nav-link-disabled-color;
25
+    pointer-events: none;
26
+    cursor: default;
27
+  }
28
+}
29
+
30
+//
31
+// Tabs
32
+//
33
+
34
+.nav-tabs {
35
+  border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
36
+
37
+  .nav-item {
38
+    margin-bottom: -$nav-tabs-border-width;
39
+  }
40
+
41
+  .nav-link {
42
+    border: $nav-tabs-border-width solid transparent;
43
+    @include border-top-radius($nav-tabs-border-radius);
44
+
45
+    @include hover-focus {
46
+      border-color: $nav-tabs-link-hover-border-color;
47
+    }
48
+
49
+    &.disabled {
50
+      color: $nav-link-disabled-color;
51
+      background-color: transparent;
52
+      border-color: transparent;
53
+    }
54
+  }
55
+
56
+  .nav-link.active,
57
+  .nav-item.show .nav-link {
58
+    color: $nav-tabs-link-active-color;
59
+    background-color: $nav-tabs-link-active-bg;
60
+    border-color: $nav-tabs-link-active-border-color;
61
+  }
62
+
63
+  .dropdown-menu {
64
+    // Make dropdown border overlap tab border
65
+    margin-top: -$nav-tabs-border-width;
66
+    // Remove the top rounded corners here since there is a hard edge above the menu
67
+    @include border-top-radius(0);
68
+  }
69
+}
70
+
71
+
72
+//
73
+// Pills
74
+//
75
+
76
+.nav-pills {
77
+  .nav-link {
78
+    @include border-radius($nav-pills-border-radius);
79
+  }
80
+
81
+  .nav-link.active,
82
+  .show > .nav-link {
83
+    color: $nav-pills-link-active-color;
84
+    background-color: $nav-pills-link-active-bg;
85
+  }
86
+}
87
+
88
+
89
+//
90
+// Justified variants
91
+//
92
+
93
+.nav-fill {
94
+  .nav-item {
95
+    flex: 1 1 auto;
96
+    text-align: center;
97
+  }
98
+}
99
+
100
+.nav-justified {
101
+  .nav-item {
102
+    flex-basis: 0;
103
+    flex-grow: 1;
104
+    text-align: center;
105
+  }
106
+}
107
+
108
+
109
+// Tabbable tabs
110
+//
111
+// Hide tabbable panes to start, show them when `.active`
112
+
113
+.tab-content {
114
+  > .tab-pane {
115
+    display: none;
116
+  }
117
+  > .active {
118
+    display: block;
119
+  }
120
+}

+ 294
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_navbar.scss View File

@@ -0,0 +1,294 @@
1
+// Contents
2
+//
3
+// Navbar
4
+// Navbar brand
5
+// Navbar nav
6
+// Navbar text
7
+// Navbar divider
8
+// Responsive navbar
9
+// Navbar position
10
+// Navbar themes
11
+
12
+
13
+// Navbar
14
+//
15
+// Provide a static navbar from which we expand to create full-width, fixed, and
16
+// other navbar variations.
17
+
18
+.navbar {
19
+  position: relative;
20
+  display: flex;
21
+  flex-wrap: wrap; // allow us to do the line break for collapsing content
22
+  align-items: center;
23
+  justify-content: space-between; // space out brand from logo
24
+  padding: $navbar-padding-y $navbar-padding-x;
25
+
26
+  // Because flex properties aren't inherited, we need to redeclare these first
27
+  // few properties so that content nested within behave properly.
28
+  > .container,
29
+  > .container-fluid {
30
+    display: flex;
31
+    flex-wrap: wrap;
32
+    align-items: center;
33
+    justify-content: space-between;
34
+  }
35
+}
36
+
37
+
38
+// Navbar brand
39
+//
40
+// Used for brand, project, or site names.
41
+
42
+.navbar-brand {
43
+  display: inline-block;
44
+  padding-top: $navbar-brand-padding-y;
45
+  padding-bottom: $navbar-brand-padding-y;
46
+  margin-right: $navbar-padding-x;
47
+  @include font-size($navbar-brand-font-size);
48
+  line-height: inherit;
49
+  white-space: nowrap;
50
+
51
+  @include hover-focus {
52
+    text-decoration: none;
53
+  }
54
+}
55
+
56
+
57
+// Navbar nav
58
+//
59
+// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).
60
+
61
+.navbar-nav {
62
+  display: flex;
63
+  flex-direction: column; // cannot use `inherit` to get the `.navbar`s value
64
+  padding-left: 0;
65
+  margin-bottom: 0;
66
+  list-style: none;
67
+
68
+  .nav-link {
69
+    padding-right: 0;
70
+    padding-left: 0;
71
+  }
72
+
73
+  .dropdown-menu {
74
+    position: static;
75
+    float: none;
76
+  }
77
+}
78
+
79
+
80
+// Navbar text
81
+//
82
+//
83
+
84
+.navbar-text {
85
+  display: inline-block;
86
+  padding-top: $nav-link-padding-y;
87
+  padding-bottom: $nav-link-padding-y;
88
+}
89
+
90
+
91
+// Responsive navbar
92
+//
93
+// Custom styles for responsive collapsing and toggling of navbar contents.
94
+// Powered by the collapse Bootstrap JavaScript plugin.
95
+
96
+// When collapsed, prevent the toggleable navbar contents from appearing in
97
+// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`
98
+// on the `.navbar` parent.
99
+.navbar-collapse {
100
+  flex-basis: 100%;
101
+  flex-grow: 1;
102
+  // For always expanded or extra full navbars, ensure content aligns itself
103
+  // properly vertically. Can be easily overridden with flex utilities.
104
+  align-items: center;
105
+}
106
+
107
+// Button for toggling the navbar when in its collapsed state
108
+.navbar-toggler {
109
+  padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;
110
+  @include font-size($navbar-toggler-font-size);
111
+  line-height: 1;
112
+  background-color: transparent; // remove default button style
113
+  border: $border-width solid transparent; // remove default button style
114
+  @include border-radius($navbar-toggler-border-radius);
115
+
116
+  @include hover-focus {
117
+    text-decoration: none;
118
+  }
119
+}
120
+
121
+// Keep as a separate element so folks can easily override it with another icon
122
+// or image file as needed.
123
+.navbar-toggler-icon {
124
+  display: inline-block;
125
+  width: 1.5em;
126
+  height: 1.5em;
127
+  vertical-align: middle;
128
+  content: "";
129
+  background: no-repeat center center;
130
+  background-size: 100% 100%;
131
+}
132
+
133
+// Generate series of `.navbar-expand-*` responsive classes for configuring
134
+// where your navbar collapses.
135
+.navbar-expand {
136
+  @each $breakpoint in map-keys($grid-breakpoints) {
137
+    $next: breakpoint-next($breakpoint, $grid-breakpoints);
138
+    $infix: breakpoint-infix($next, $grid-breakpoints);
139
+
140
+    &#{$infix} {
141
+      @include media-breakpoint-down($breakpoint) {
142
+        > .container,
143
+        > .container-fluid {
144
+          padding-right: 0;
145
+          padding-left: 0;
146
+        }
147
+      }
148
+
149
+      @include media-breakpoint-up($next) {
150
+        flex-flow: row nowrap;
151
+        justify-content: flex-start;
152
+
153
+        .navbar-nav {
154
+          flex-direction: row;
155
+
156
+          .dropdown-menu {
157
+            position: absolute;
158
+          }
159
+
160
+          .nav-link {
161
+            padding-right: $navbar-nav-link-padding-x;
162
+            padding-left: $navbar-nav-link-padding-x;
163
+          }
164
+        }
165
+
166
+        // For nesting containers, have to redeclare for alignment purposes
167
+        > .container,
168
+        > .container-fluid {
169
+          flex-wrap: nowrap;
170
+        }
171
+
172
+        .navbar-collapse {
173
+          display: flex !important; // stylelint-disable-line declaration-no-important
174
+
175
+          // Changes flex-bases to auto because of an IE10 bug
176
+          flex-basis: auto;
177
+        }
178
+
179
+        .navbar-toggler {
180
+          display: none;
181
+        }
182
+      }
183
+    }
184
+  }
185
+}
186
+
187
+
188
+// Navbar themes
189
+//
190
+// Styles for switching between navbars with light or dark background.
191
+
192
+// Dark links against a light background
193
+.navbar-light {
194
+  .navbar-brand {
195
+    color: $navbar-light-brand-color;
196
+
197
+    @include hover-focus {
198
+      color: $navbar-light-brand-hover-color;
199
+    }
200
+  }
201
+
202
+  .navbar-nav {
203
+    .nav-link {
204
+      color: $navbar-light-color;
205
+
206
+      @include hover-focus {
207
+        color: $navbar-light-hover-color;
208
+      }
209
+
210
+      &.disabled {
211
+        color: $navbar-light-disabled-color;
212
+      }
213
+    }
214
+
215
+    .show > .nav-link,
216
+    .active > .nav-link,
217
+    .nav-link.show,
218
+    .nav-link.active {
219
+      color: $navbar-light-active-color;
220
+    }
221
+  }
222
+
223
+  .navbar-toggler {
224
+    color: $navbar-light-color;
225
+    border-color: $navbar-light-toggler-border-color;
226
+  }
227
+
228
+  .navbar-toggler-icon {
229
+    background-image: $navbar-light-toggler-icon-bg;
230
+  }
231
+
232
+  .navbar-text {
233
+    color: $navbar-light-color;
234
+    a {
235
+      color: $navbar-light-active-color;
236
+
237
+      @include hover-focus {
238
+        color: $navbar-light-active-color;
239
+      }
240
+    }
241
+  }
242
+}
243
+
244
+// White links against a dark background
245
+.navbar-dark {
246
+  .navbar-brand {
247
+    color: $navbar-dark-brand-color;
248
+
249
+    @include hover-focus {
250
+      color: $navbar-dark-brand-hover-color;
251
+    }
252
+  }
253
+
254
+  .navbar-nav {
255
+    .nav-link {
256
+      color: $navbar-dark-color;
257
+
258
+      @include hover-focus {
259
+        color: $navbar-dark-hover-color;
260
+      }
261
+
262
+      &.disabled {
263
+        color: $navbar-dark-disabled-color;
264
+      }
265
+    }
266
+
267
+    .show > .nav-link,
268
+    .active > .nav-link,
269
+    .nav-link.show,
270
+    .nav-link.active {
271
+      color: $navbar-dark-active-color;
272
+    }
273
+  }
274
+
275
+  .navbar-toggler {
276
+    color: $navbar-dark-color;
277
+    border-color: $navbar-dark-toggler-border-color;
278
+  }
279
+
280
+  .navbar-toggler-icon {
281
+    background-image: $navbar-dark-toggler-icon-bg;
282
+  }
283
+
284
+  .navbar-text {
285
+    color: $navbar-dark-color;
286
+    a {
287
+      color: $navbar-dark-active-color;
288
+
289
+      @include hover-focus {
290
+        color: $navbar-dark-active-color;
291
+      }
292
+    }
293
+  }
294
+}

+ 73
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_pagination.scss View File

@@ -0,0 +1,73 @@
1
+.pagination {
2
+  display: flex;
3
+  @include list-unstyled();
4
+  @include border-radius();
5
+}
6
+
7
+.page-link {
8
+  position: relative;
9
+  display: block;
10
+  padding: $pagination-padding-y $pagination-padding-x;
11
+  margin-left: -$pagination-border-width;
12
+  line-height: $pagination-line-height;
13
+  color: $pagination-color;
14
+  background-color: $pagination-bg;
15
+  border: $pagination-border-width solid $pagination-border-color;
16
+
17
+  &:hover {
18
+    z-index: 2;
19
+    color: $pagination-hover-color;
20
+    text-decoration: none;
21
+    background-color: $pagination-hover-bg;
22
+    border-color: $pagination-hover-border-color;
23
+  }
24
+
25
+  &:focus {
26
+    z-index: 2;
27
+    outline: $pagination-focus-outline;
28
+    box-shadow: $pagination-focus-box-shadow;
29
+  }
30
+}
31
+
32
+.page-item {
33
+  &:first-child {
34
+    .page-link {
35
+      margin-left: 0;
36
+      @include border-left-radius($border-radius);
37
+    }
38
+  }
39
+  &:last-child {
40
+    .page-link {
41
+      @include border-right-radius($border-radius);
42
+    }
43
+  }
44
+
45
+  &.active .page-link {
46
+    z-index: 1;
47
+    color: $pagination-active-color;
48
+    background-color: $pagination-active-bg;
49
+    border-color: $pagination-active-border-color;
50
+  }
51
+
52
+  &.disabled .page-link {
53
+    color: $pagination-disabled-color;
54
+    pointer-events: none;
55
+    // Opinionated: remove the "hand" cursor set previously for .page-link
56
+    cursor: auto;
57
+    background-color: $pagination-disabled-bg;
58
+    border-color: $pagination-disabled-border-color;
59
+  }
60
+}
61
+
62
+
63
+//
64
+// Sizing
65
+//
66
+
67
+.pagination-lg {
68
+  @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);
69
+}
70
+
71
+.pagination-sm {
72
+  @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);
73
+}

+ 171
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_popover.scss View File

@@ -0,0 +1,171 @@
1
+.popover {
2
+  position: absolute;
3
+  top: 0;
4
+  left: 0;
5
+  z-index: $zindex-popover;
6
+  display: block;
7
+  max-width: $popover-max-width;
8
+  // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
9
+  // So reset our font and text properties to avoid inheriting weird values.
10
+  @include reset-text();
11
+  @include font-size($popover-font-size);
12
+  // Allow breaking very long words so they don't overflow the popover's bounds
13
+  word-wrap: break-word;
14
+  background-color: $popover-bg;
15
+  background-clip: padding-box;
16
+  border: $popover-border-width solid $popover-border-color;
17
+  @include border-radius($popover-border-radius);
18
+  @include box-shadow($popover-box-shadow);
19
+
20
+  .arrow {
21
+    position: absolute;
22
+    display: block;
23
+    width: $popover-arrow-width;
24
+    height: $popover-arrow-height;
25
+    margin: 0 $border-radius-lg;
26
+
27
+    &::before,
28
+    &::after {
29
+      position: absolute;
30
+      display: block;
31
+      content: "";
32
+      border-color: transparent;
33
+      border-style: solid;
34
+    }
35
+  }
36
+}
37
+
38
+.bs-popover-top {
39
+  margin-bottom: $popover-arrow-height;
40
+
41
+  > .arrow {
42
+    bottom: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
43
+
44
+    &::before {
45
+      bottom: 0;
46
+      border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;
47
+      border-top-color: $popover-arrow-outer-color;
48
+    }
49
+
50
+    &::after {
51
+      bottom: $popover-border-width;
52
+      border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;
53
+      border-top-color: $popover-arrow-color;
54
+    }
55
+  }
56
+}
57
+
58
+.bs-popover-right {
59
+  margin-left: $popover-arrow-height;
60
+
61
+  > .arrow {
62
+    left: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
63
+    width: $popover-arrow-height;
64
+    height: $popover-arrow-width;
65
+    margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners
66
+
67
+    &::before {
68
+      left: 0;
69
+      border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;
70
+      border-right-color: $popover-arrow-outer-color;
71
+    }
72
+
73
+    &::after {
74
+      left: $popover-border-width;
75
+      border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;
76
+      border-right-color: $popover-arrow-color;
77
+    }
78
+  }
79
+}
80
+
81
+.bs-popover-bottom {
82
+  margin-top: $popover-arrow-height;
83
+
84
+  > .arrow {
85
+    top: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
86
+
87
+    &::before {
88
+      top: 0;
89
+      border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);
90
+      border-bottom-color: $popover-arrow-outer-color;
91
+    }
92
+
93
+    &::after {
94
+      top: $popover-border-width;
95
+      border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);
96
+      border-bottom-color: $popover-arrow-color;
97
+    }
98
+  }
99
+
100
+  // This will remove the popover-header's border just below the arrow
101
+  .popover-header::before {
102
+    position: absolute;
103
+    top: 0;
104
+    left: 50%;
105
+    display: block;
106
+    width: $popover-arrow-width;
107
+    margin-left: -$popover-arrow-width / 2;
108
+    content: "";
109
+    border-bottom: $popover-border-width solid $popover-header-bg;
110
+  }
111
+}
112
+
113
+.bs-popover-left {
114
+  margin-right: $popover-arrow-height;
115
+
116
+  > .arrow {
117
+    right: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
118
+    width: $popover-arrow-height;
119
+    height: $popover-arrow-width;
120
+    margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners
121
+
122
+    &::before {
123
+      right: 0;
124
+      border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;
125
+      border-left-color: $popover-arrow-outer-color;
126
+    }
127
+
128
+    &::after {
129
+      right: $popover-border-width;
130
+      border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;
131
+      border-left-color: $popover-arrow-color;
132
+    }
133
+  }
134
+}
135
+
136
+.bs-popover-auto {
137
+  &[x-placement^="top"] {
138
+    @extend .bs-popover-top;
139
+  }
140
+  &[x-placement^="right"] {
141
+    @extend .bs-popover-right;
142
+  }
143
+  &[x-placement^="bottom"] {
144
+    @extend .bs-popover-bottom;
145
+  }
146
+  &[x-placement^="left"] {
147
+    @extend .bs-popover-left;
148
+  }
149
+}
150
+
151
+
152
+// Offset the popover to account for the popover arrow
153
+.popover-header {
154
+  padding: $popover-header-padding-y $popover-header-padding-x;
155
+  margin-bottom: 0; // Reset the default from Reboot
156
+  @include font-size($font-size-base);
157
+  color: $popover-header-color;
158
+  background-color: $popover-header-bg;
159
+  border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);
160
+  $offset-border-width: calc(#{$border-radius-lg} - #{$popover-border-width});
161
+  @include border-top-radius($offset-border-width);
162
+
163
+  &:empty {
164
+    display: none;
165
+  }
166
+}
167
+
168
+.popover-body {
169
+  padding: $popover-body-padding-y $popover-body-padding-x;
170
+  color: $popover-body-color;
171
+}

+ 141
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_print.scss View File

@@ -0,0 +1,141 @@
1
+// stylelint-disable declaration-no-important, selector-no-qualifying-type
2
+
3
+// Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css
4
+
5
+// ==========================================================================
6
+// Print styles.
7
+// Inlined to avoid the additional HTTP request:
8
+// https://www.phpied.com/delay-loading-your-print-css/
9
+// ==========================================================================
10
+
11
+@if $enable-print-styles {
12
+  @media print {
13
+    *,
14
+    *::before,
15
+    *::after {
16
+      // Bootstrap specific; comment out `color` and `background`
17
+      //color: $black !important; // Black prints faster
18
+      text-shadow: none !important;
19
+      //background: transparent !important;
20
+      box-shadow: none !important;
21
+    }
22
+
23
+    a {
24
+      &:not(.btn) {
25
+        text-decoration: underline;
26
+      }
27
+    }
28
+
29
+    // Bootstrap specific; comment the following selector out
30
+    //a[href]::after {
31
+    //  content: " (" attr(href) ")";
32
+    //}
33
+
34
+    abbr[title]::after {
35
+      content: " (" attr(title) ")";
36
+    }
37
+
38
+    // Bootstrap specific; comment the following selector out
39
+    //
40
+    // Don't show links that are fragment identifiers,
41
+    // or use the `javascript:` pseudo protocol
42
+    //
43
+
44
+    //a[href^="#"]::after,
45
+    //a[href^="javascript:"]::after {
46
+    // content: "";
47
+    //}
48
+
49
+    pre {
50
+      white-space: pre-wrap !important;
51
+    }
52
+    pre,
53
+    blockquote {
54
+      border: $border-width solid $gray-500; // Bootstrap custom code; using `$border-width` instead of 1px
55
+      page-break-inside: avoid;
56
+    }
57
+
58
+    //
59
+    // Printing Tables:
60
+    // http://css-discuss.incutio.com/wiki/Printing_Tables
61
+    //
62
+
63
+    thead {
64
+      display: table-header-group;
65
+    }
66
+
67
+    tr,
68
+    img {
69
+      page-break-inside: avoid;
70
+    }
71
+
72
+    p,
73
+    h2,
74
+    h3 {
75
+      orphans: 3;
76
+      widows: 3;
77
+    }
78
+
79
+    h2,
80
+    h3 {
81
+      page-break-after: avoid;
82
+    }
83
+
84
+    // Bootstrap specific changes start
85
+
86
+    // Specify a size and min-width to make printing closer across browsers.
87
+    // We don't set margin here because it breaks `size` in Chrome. We also
88
+    // don't use `!important` on `size` as it breaks in Chrome.
89
+    @page {
90
+      size: $print-page-size;
91
+    }
92
+    body {
93
+      min-width: $print-body-min-width !important;
94
+    }
95
+    .container {
96
+      min-width: $print-body-min-width !important;
97
+    }
98
+
99
+    // Bootstrap components
100
+    .navbar {
101
+      display: none;
102
+    }
103
+    .badge {
104
+      border: $border-width solid $black;
105
+    }
106
+
107
+    .table {
108
+      border-collapse: collapse !important;
109
+
110
+      td,
111
+      th {
112
+        background-color: $white !important;
113
+      }
114
+    }
115
+
116
+    .table-bordered {
117
+      th,
118
+      td {
119
+        border: 1px solid $gray-300 !important;
120
+      }
121
+    }
122
+
123
+    .table-dark {
124
+      color: inherit;
125
+
126
+      th,
127
+      td,
128
+      thead th,
129
+      tbody + tbody {
130
+        border-color: $table-border-color;
131
+      }
132
+    }
133
+
134
+    .table .thead-dark th {
135
+      color: inherit;
136
+      border-color: $table-border-color;
137
+    }
138
+
139
+    // Bootstrap specific changes end
140
+  }
141
+}

+ 43
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_progress.scss View File

@@ -0,0 +1,43 @@
1
+// Disable animation if transitions are disabled
2
+@if $enable-transitions {
3
+  @keyframes progress-bar-stripes {
4
+    from { background-position: $progress-height 0; }
5
+    to { background-position: 0 0; }
6
+  }
7
+}
8
+
9
+.progress {
10
+  display: flex;
11
+  height: $progress-height;
12
+  overflow: hidden; // force rounded corners by cropping it
13
+  @include font-size($progress-font-size);
14
+  background-color: $progress-bg;
15
+  @include border-radius($progress-border-radius);
16
+  @include box-shadow($progress-box-shadow);
17
+}
18
+
19
+.progress-bar {
20
+  display: flex;
21
+  flex-direction: column;
22
+  justify-content: center;
23
+  color: $progress-bar-color;
24
+  text-align: center;
25
+  white-space: nowrap;
26
+  background-color: $progress-bar-bg;
27
+  @include transition($progress-bar-transition);
28
+}
29
+
30
+.progress-bar-striped {
31
+  @include gradient-striped();
32
+  background-size: $progress-height $progress-height;
33
+}
34
+
35
+@if $enable-transitions {
36
+  .progress-bar-animated {
37
+    animation: progress-bar-stripes $progress-bar-animation-timing;
38
+
39
+    @media (prefers-reduced-motion: reduce) {
40
+      animation: none;
41
+    }
42
+  }
43
+}

+ 483
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_reboot.scss View File

@@ -0,0 +1,483 @@
1
+// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
2
+
3
+// Reboot
4
+//
5
+// Normalization of HTML elements, manually forked from Normalize.css to remove
6
+// styles targeting irrelevant browsers while applying new styles.
7
+//
8
+// Normalize is licensed MIT. https://github.com/necolas/normalize.css
9
+
10
+
11
+// Document
12
+//
13
+// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
14
+// 2. Change the default font family in all browsers.
15
+// 3. Correct the line height in all browsers.
16
+// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.
17
+// 5. Change the default tap highlight to be completely transparent in iOS.
18
+
19
+*,
20
+*::before,
21
+*::after {
22
+  box-sizing: border-box; // 1
23
+}
24
+
25
+html {
26
+  font-family: sans-serif; // 2
27
+  line-height: 1.15; // 3
28
+  -webkit-text-size-adjust: 100%; // 4
29
+  -webkit-tap-highlight-color: rgba($black, 0); // 5
30
+}
31
+
32
+// Shim for "new" HTML5 structural elements to display correctly (IE10, older browsers)
33
+// TODO: remove in v5
34
+// stylelint-disable-next-line selector-list-comma-newline-after
35
+article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
36
+  display: block;
37
+}
38
+
39
+// Body
40
+//
41
+// 1. Remove the margin in all browsers.
42
+// 2. As a best practice, apply a default `background-color`.
43
+// 3. Set an explicit initial text-align value so that we can later use
44
+//    the `inherit` value on things like `<th>` elements.
45
+
46
+body {
47
+  margin: 0; // 1
48
+  font-family: $font-family-base;
49
+  @include font-size($font-size-base);
50
+  font-weight: $font-weight-base;
51
+  line-height: $line-height-base;
52
+  color: $body-color;
53
+  text-align: left; // 3
54
+  background-color: $body-bg; // 2
55
+}
56
+
57
+// Suppress the focus outline on elements that cannot be accessed via keyboard.
58
+// This prevents an unwanted focus outline from appearing around elements that
59
+// might still respond to pointer events.
60
+//
61
+// Credit: https://github.com/suitcss/base
62
+[tabindex="-1"]:focus {
63
+  outline: 0 !important;
64
+}
65
+
66
+
67
+// Content grouping
68
+//
69
+// 1. Add the correct box sizing in Firefox.
70
+// 2. Show the overflow in Edge and IE.
71
+
72
+hr {
73
+  box-sizing: content-box; // 1
74
+  height: 0; // 1
75
+  overflow: visible; // 2
76
+}
77
+
78
+
79
+//
80
+// Typography
81
+//
82
+
83
+// Remove top margins from headings
84
+//
85
+// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top
86
+// margin for easier control within type scales as it avoids margin collapsing.
87
+// stylelint-disable-next-line selector-list-comma-newline-after
88
+h1, h2, h3, h4, h5, h6 {
89
+  margin-top: 0;
90
+  margin-bottom: $headings-margin-bottom;
91
+}
92
+
93
+// Reset margins on paragraphs
94
+//
95
+// Similarly, the top margin on `<p>`s get reset. However, we also reset the
96
+// bottom margin to use `rem` units instead of `em`.
97
+p {
98
+  margin-top: 0;
99
+  margin-bottom: $paragraph-margin-bottom;
100
+}
101
+
102
+// Abbreviations
103
+//
104
+// 1. Duplicate behavior to the data-* attribute for our tooltip plugin
105
+// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
106
+// 3. Add explicit cursor to indicate changed behavior.
107
+// 4. Remove the bottom border in Firefox 39-.
108
+// 5. Prevent the text-decoration to be skipped.
109
+
110
+abbr[title],
111
+abbr[data-original-title] { // 1
112
+  text-decoration: underline; // 2
113
+  text-decoration: underline dotted; // 2
114
+  cursor: help; // 3
115
+  border-bottom: 0; // 4
116
+  text-decoration-skip-ink: none; // 5
117
+}
118
+
119
+address {
120
+  margin-bottom: 1rem;
121
+  font-style: normal;
122
+  line-height: inherit;
123
+}
124
+
125
+ol,
126
+ul,
127
+dl {
128
+  margin-top: 0;
129
+  margin-bottom: 1rem;
130
+}
131
+
132
+ol ol,
133
+ul ul,
134
+ol ul,
135
+ul ol {
136
+  margin-bottom: 0;
137
+}
138
+
139
+dt {
140
+  font-weight: $dt-font-weight;
141
+}
142
+
143
+dd {
144
+  margin-bottom: .5rem;
145
+  margin-left: 0; // Undo browser default
146
+}
147
+
148
+blockquote {
149
+  margin: 0 0 1rem;
150
+}
151
+
152
+b,
153
+strong {
154
+  font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari
155
+}
156
+
157
+small {
158
+  @include font-size(80%); // Add the correct font size in all browsers
159
+}
160
+
161
+//
162
+// Prevent `sub` and `sup` elements from affecting the line height in
163
+// all browsers.
164
+//
165
+
166
+sub,
167
+sup {
168
+  position: relative;
169
+  @include font-size(75%);
170
+  line-height: 0;
171
+  vertical-align: baseline;
172
+}
173
+
174
+sub { bottom: -.25em; }
175
+sup { top: -.5em; }
176
+
177
+
178
+//
179
+// Links
180
+//
181
+
182
+a {
183
+  color: $link-color;
184
+  text-decoration: $link-decoration;
185
+  background-color: transparent; // Remove the gray background on active links in IE 10.
186
+
187
+  @include hover {
188
+    color: $link-hover-color;
189
+    text-decoration: $link-hover-decoration;
190
+  }
191
+}
192
+
193
+// And undo these styles for placeholder links/named anchors (without href)
194
+// which have not been made explicitly keyboard-focusable (without tabindex).
195
+// It would be more straightforward to just use a[href] in previous block, but that
196
+// causes specificity issues in many other styles that are too complex to fix.
197
+// See https://github.com/twbs/bootstrap/issues/19402
198
+
199
+a:not([href]):not([tabindex]) {
200
+  color: inherit;
201
+  text-decoration: none;
202
+
203
+  @include hover-focus {
204
+    color: inherit;
205
+    text-decoration: none;
206
+  }
207
+
208
+  &:focus {
209
+    outline: 0;
210
+  }
211
+}
212
+
213
+
214
+//
215
+// Code
216
+//
217
+
218
+pre,
219
+code,
220
+kbd,
221
+samp {
222
+  font-family: $font-family-monospace;
223
+  @include font-size(1em); // Correct the odd `em` font sizing in all browsers.
224
+}
225
+
226
+pre {
227
+  // Remove browser default top margin
228
+  margin-top: 0;
229
+  // Reset browser default of `1em` to use `rem`s
230
+  margin-bottom: 1rem;
231
+  // Don't allow content to break outside
232
+  overflow: auto;
233
+}
234
+
235
+
236
+//
237
+// Figures
238
+//
239
+
240
+figure {
241
+  // Apply a consistent margin strategy (matches our type styles).
242
+  margin: 0 0 1rem;
243
+}
244
+
245
+
246
+//
247
+// Images and content
248
+//
249
+
250
+img {
251
+  vertical-align: middle;
252
+  border-style: none; // Remove the border on images inside links in IE 10-.
253
+}
254
+
255
+svg {
256
+  // Workaround for the SVG overflow bug in IE10/11 is still required.
257
+  // See https://github.com/twbs/bootstrap/issues/26878
258
+  overflow: hidden;
259
+  vertical-align: middle;
260
+}
261
+
262
+
263
+//
264
+// Tables
265
+//
266
+
267
+table {
268
+  border-collapse: collapse; // Prevent double borders
269
+}
270
+
271
+caption {
272
+  padding-top: $table-cell-padding;
273
+  padding-bottom: $table-cell-padding;
274
+  color: $table-caption-color;
275
+  text-align: left;
276
+  caption-side: bottom;
277
+}
278
+
279
+th {
280
+  // Matches default `<td>` alignment by inheriting from the `<body>`, or the
281
+  // closest parent with a set `text-align`.
282
+  text-align: inherit;
283
+}
284
+
285
+
286
+//
287
+// Forms
288
+//
289
+
290
+label {
291
+  // Allow labels to use `margin` for spacing.
292
+  display: inline-block;
293
+  margin-bottom: $label-margin-bottom;
294
+}
295
+
296
+// Remove the default `border-radius` that macOS Chrome adds.
297
+//
298
+// Details at https://github.com/twbs/bootstrap/issues/24093
299
+button {
300
+  // stylelint-disable-next-line property-blacklist
301
+  border-radius: 0;
302
+}
303
+
304
+// Work around a Firefox/IE bug where the transparent `button` background
305
+// results in a loss of the default `button` focus styles.
306
+//
307
+// Credit: https://github.com/suitcss/base/
308
+button:focus {
309
+  outline: 1px dotted;
310
+  outline: 5px auto -webkit-focus-ring-color;
311
+}
312
+
313
+input,
314
+button,
315
+select,
316
+optgroup,
317
+textarea {
318
+  margin: 0; // Remove the margin in Firefox and Safari
319
+  font-family: inherit;
320
+  @include font-size(inherit);
321
+  line-height: inherit;
322
+}
323
+
324
+button,
325
+input {
326
+  overflow: visible; // Show the overflow in Edge
327
+}
328
+
329
+button,
330
+select {
331
+  text-transform: none; // Remove the inheritance of text transform in Firefox
332
+}
333
+
334
+// Remove the inheritance of word-wrap in Safari.
335
+//
336
+// Details at https://github.com/twbs/bootstrap/issues/24990
337
+select {
338
+  word-wrap: normal;
339
+}
340
+
341
+
342
+// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
343
+//    controls in Android 4.
344
+// 2. Correct the inability to style clickable types in iOS and Safari.
345
+button,
346
+[type="button"], // 1
347
+[type="reset"],
348
+[type="submit"] {
349
+  -webkit-appearance: button; // 2
350
+}
351
+
352
+// Opinionated: add "hand" cursor to non-disabled button elements.
353
+@if $enable-pointer-cursor-for-buttons {
354
+  button,
355
+  [type="button"],
356
+  [type="reset"],
357
+  [type="submit"] {
358
+    &:not(:disabled) {
359
+      cursor: pointer;
360
+    }
361
+  }
362
+}
363
+
364
+// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.
365
+button::-moz-focus-inner,
366
+[type="button"]::-moz-focus-inner,
367
+[type="reset"]::-moz-focus-inner,
368
+[type="submit"]::-moz-focus-inner {
369
+  padding: 0;
370
+  border-style: none;
371
+}
372
+
373
+input[type="radio"],
374
+input[type="checkbox"] {
375
+  box-sizing: border-box; // 1. Add the correct box sizing in IE 10-
376
+  padding: 0; // 2. Remove the padding in IE 10-
377
+}
378
+
379
+
380
+input[type="date"],
381
+input[type="time"],
382
+input[type="datetime-local"],
383
+input[type="month"] {
384
+  // Remove the default appearance of temporal inputs to avoid a Mobile Safari
385
+  // bug where setting a custom line-height prevents text from being vertically
386
+  // centered within the input.
387
+  // See https://bugs.webkit.org/show_bug.cgi?id=139848
388
+  // and https://github.com/twbs/bootstrap/issues/11266
389
+  -webkit-appearance: listbox;
390
+}
391
+
392
+textarea {
393
+  overflow: auto; // Remove the default vertical scrollbar in IE.
394
+  // Textareas should really only resize vertically so they don't break their (horizontal) containers.
395
+  resize: vertical;
396
+}
397
+
398
+fieldset {
399
+  // Browsers set a default `min-width: min-content;` on fieldsets,
400
+  // unlike e.g. `<div>`s, which have `min-width: 0;` by default.
401
+  // So we reset that to ensure fieldsets behave more like a standard block element.
402
+  // See https://github.com/twbs/bootstrap/issues/59
403
+  // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
404
+  min-width: 0;
405
+  // Reset the default outline behavior of fieldsets so they don't affect page layout.
406
+  padding: 0;
407
+  margin: 0;
408
+  border: 0;
409
+}
410
+
411
+// 1. Correct the text wrapping in Edge and IE.
412
+// 2. Correct the color inheritance from `fieldset` elements in IE.
413
+legend {
414
+  display: block;
415
+  width: 100%;
416
+  max-width: 100%; // 1
417
+  padding: 0;
418
+  margin-bottom: .5rem;
419
+  @include font-size(1.5rem);
420
+  line-height: inherit;
421
+  color: inherit; // 2
422
+  white-space: normal; // 1
423
+}
424
+
425
+progress {
426
+  vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.
427
+}
428
+
429
+// Correct the cursor style of increment and decrement buttons in Chrome.
430
+[type="number"]::-webkit-inner-spin-button,
431
+[type="number"]::-webkit-outer-spin-button {
432
+  height: auto;
433
+}
434
+
435
+[type="search"] {
436
+  // This overrides the extra rounded corners on search inputs in iOS so that our
437
+  // `.form-control` class can properly style them. Note that this cannot simply
438
+  // be added to `.form-control` as it's not specific enough. For details, see
439
+  // https://github.com/twbs/bootstrap/issues/11586.
440
+  outline-offset: -2px; // 2. Correct the outline style in Safari.
441
+  -webkit-appearance: none;
442
+}
443
+
444
+//
445
+// Remove the inner padding in Chrome and Safari on macOS.
446
+//
447
+
448
+[type="search"]::-webkit-search-decoration {
449
+  -webkit-appearance: none;
450
+}
451
+
452
+//
453
+// 1. Correct the inability to style clickable types in iOS and Safari.
454
+// 2. Change font properties to `inherit` in Safari.
455
+//
456
+
457
+::-webkit-file-upload-button {
458
+  font: inherit; // 2
459
+  -webkit-appearance: button; // 1
460
+}
461
+
462
+//
463
+// Correct element displays
464
+//
465
+
466
+output {
467
+  display: inline-block;
468
+}
469
+
470
+summary {
471
+  display: list-item; // Add the correct display in all browsers
472
+  cursor: pointer;
473
+}
474
+
475
+template {
476
+  display: none; // Add the correct display in IE
477
+}
478
+
479
+// Always hide an element with the `hidden` HTML attribute (from PureCSS).
480
+// Needed for proper display in IE 10-.
481
+[hidden] {
482
+  display: none !important;
483
+}

+ 19
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_root.scss View File

@@ -0,0 +1,19 @@
1
+:root {
2
+  // Custom variable values only support SassScript inside `#{}`.
3
+  @each $color, $value in $colors {
4
+    --#{$color}: #{$value};
5
+  }
6
+
7
+  @each $color, $value in $theme-colors {
8
+    --#{$color}: #{$value};
9
+  }
10
+
11
+  @each $bp, $value in $grid-breakpoints {
12
+    --breakpoint-#{$bp}: #{$value};
13
+  }
14
+
15
+  // Use `inspect` for lists so that quoted items keep the quotes.
16
+  // See https://github.com/sass/sass/issues/2383#issuecomment-336349172
17
+  --font-family-sans-serif: #{inspect($font-family-sans-serif)};
18
+  --font-family-monospace: #{inspect($font-family-monospace)};
19
+}

+ 55
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_spinners.scss View File

@@ -0,0 +1,55 @@
1
+//
2
+// Rotating border
3
+//
4
+
5
+@keyframes spinner-border {
6
+  to { transform: rotate(360deg); }
7
+}
8
+
9
+.spinner-border {
10
+  display: inline-block;
11
+  width: $spinner-width;
12
+  height: $spinner-height;
13
+  vertical-align: text-bottom;
14
+  border: $spinner-border-width solid currentColor;
15
+  border-right-color: transparent;
16
+  // stylelint-disable-next-line property-blacklist
17
+  border-radius: 50%;
18
+  animation: spinner-border .75s linear infinite;
19
+}
20
+
21
+.spinner-border-sm {
22
+  width: $spinner-width-sm;
23
+  height: $spinner-height-sm;
24
+  border-width: $spinner-border-width-sm;
25
+}
26
+
27
+//
28
+// Growing circle
29
+//
30
+
31
+@keyframes spinner-grow {
32
+  0% {
33
+    transform: scale(0);
34
+  }
35
+  50% {
36
+    opacity: 1;
37
+  }
38
+}
39
+
40
+.spinner-grow {
41
+  display: inline-block;
42
+  width: $spinner-width;
43
+  height: $spinner-height;
44
+  vertical-align: text-bottom;
45
+  background-color: currentColor;
46
+  // stylelint-disable-next-line property-blacklist
47
+  border-radius: 50%;
48
+  opacity: 0;
49
+  animation: spinner-grow .75s linear infinite;
50
+}
51
+
52
+.spinner-grow-sm {
53
+  width: $spinner-width-sm;
54
+  height: $spinner-height-sm;
55
+}

+ 185
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_tables.scss View File

@@ -0,0 +1,185 @@
1
+//
2
+// Basic Bootstrap table
3
+//
4
+
5
+.table {
6
+  width: 100%;
7
+  margin-bottom: $spacer;
8
+  color: $table-color;
9
+  background-color: $table-bg; // Reset for nesting within parents with `background-color`.
10
+
11
+  th,
12
+  td {
13
+    padding: $table-cell-padding;
14
+    vertical-align: top;
15
+    border-top: $table-border-width solid $table-border-color;
16
+  }
17
+
18
+  thead th {
19
+    vertical-align: bottom;
20
+    border-bottom: (2 * $table-border-width) solid $table-border-color;
21
+  }
22
+
23
+  tbody + tbody {
24
+    border-top: (2 * $table-border-width) solid $table-border-color;
25
+  }
26
+}
27
+
28
+
29
+//
30
+// Condensed table w/ half padding
31
+//
32
+
33
+.table-sm {
34
+  th,
35
+  td {
36
+    padding: $table-cell-padding-sm;
37
+  }
38
+}
39
+
40
+
41
+// Border versions
42
+//
43
+// Add or remove borders all around the table and between all the columns.
44
+
45
+.table-bordered {
46
+  border: $table-border-width solid $table-border-color;
47
+
48
+  th,
49
+  td {
50
+    border: $table-border-width solid $table-border-color;
51
+  }
52
+
53
+  thead {
54
+    th,
55
+    td {
56
+      border-bottom-width: 2 * $table-border-width;
57
+    }
58
+  }
59
+}
60
+
61
+.table-borderless {
62
+  th,
63
+  td,
64
+  thead th,
65
+  tbody + tbody {
66
+    border: 0;
67
+  }
68
+}
69
+
70
+// Zebra-striping
71
+//
72
+// Default zebra-stripe styles (alternating gray and transparent backgrounds)
73
+
74
+.table-striped {
75
+  tbody tr:nth-of-type(#{$table-striped-order}) {
76
+    background-color: $table-accent-bg;
77
+  }
78
+}
79
+
80
+
81
+// Hover effect
82
+//
83
+// Placed here since it has to come after the potential zebra striping
84
+
85
+.table-hover {
86
+  tbody tr {
87
+    @include hover {
88
+      color: $table-hover-color;
89
+      background-color: $table-hover-bg;
90
+    }
91
+  }
92
+}
93
+
94
+
95
+// Table backgrounds
96
+//
97
+// Exact selectors below required to override `.table-striped` and prevent
98
+// inheritance to nested tables.
99
+
100
+@each $color, $value in $theme-colors {
101
+  @include table-row-variant($color, theme-color-level($color, $table-bg-level), theme-color-level($color, $table-border-level));
102
+}
103
+
104
+@include table-row-variant(active, $table-active-bg);
105
+
106
+
107
+// Dark styles
108
+//
109
+// Same table markup, but inverted color scheme: dark background and light text.
110
+
111
+// stylelint-disable-next-line no-duplicate-selectors
112
+.table {
113
+  .thead-dark {
114
+    th {
115
+      color: $table-dark-color;
116
+      background-color: $table-dark-bg;
117
+      border-color: $table-dark-border-color;
118
+    }
119
+  }
120
+
121
+  .thead-light {
122
+    th {
123
+      color: $table-head-color;
124
+      background-color: $table-head-bg;
125
+      border-color: $table-border-color;
126
+    }
127
+  }
128
+}
129
+
130
+.table-dark {
131
+  color: $table-dark-color;
132
+  background-color: $table-dark-bg;
133
+
134
+  th,
135
+  td,
136
+  thead th {
137
+    border-color: $table-dark-border-color;
138
+  }
139
+
140
+  &.table-bordered {
141
+    border: 0;
142
+  }
143
+
144
+  &.table-striped {
145
+    tbody tr:nth-of-type(odd) {
146
+      background-color: $table-dark-accent-bg;
147
+    }
148
+  }
149
+
150
+  &.table-hover {
151
+    tbody tr {
152
+      @include hover {
153
+        color: $table-dark-hover-color;
154
+        background-color: $table-dark-hover-bg;
155
+      }
156
+    }
157
+  }
158
+}
159
+
160
+
161
+// Responsive tables
162
+//
163
+// Generate series of `.table-responsive-*` classes for configuring the screen
164
+// size of where your table will overflow.
165
+
166
+.table-responsive {
167
+  @each $breakpoint in map-keys($grid-breakpoints) {
168
+    $next: breakpoint-next($breakpoint, $grid-breakpoints);
169
+    $infix: breakpoint-infix($next, $grid-breakpoints);
170
+
171
+    &#{$infix} {
172
+      @include media-breakpoint-down($breakpoint) {
173
+        display: block;
174
+        width: 100%;
175
+        overflow-x: auto;
176
+        -webkit-overflow-scrolling: touch;
177
+
178
+        // Prevent double border on horizontal scroll due to use of `display: block;`
179
+        > .table-bordered {
180
+          border: 0;
181
+        }
182
+      }
183
+    }
184
+  }
185
+}

+ 44
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_toasts.scss View File

@@ -0,0 +1,44 @@
1
+.toast {
2
+  max-width: $toast-max-width;
3
+  overflow: hidden; // cheap rounded corners on nested items
4
+  @include font-size($toast-font-size);
5
+  color: $toast-color;
6
+  background-color: $toast-background-color;
7
+  background-clip: padding-box;
8
+  border: $toast-border-width solid $toast-border-color;
9
+  box-shadow: $toast-box-shadow;
10
+  backdrop-filter: blur(10px);
11
+  opacity: 0;
12
+  @include border-radius($toast-border-radius);
13
+
14
+  &:not(:last-child) {
15
+    margin-bottom: $toast-padding-x;
16
+  }
17
+
18
+  &.showing {
19
+    opacity: 1;
20
+  }
21
+
22
+  &.show {
23
+    display: block;
24
+    opacity: 1;
25
+  }
26
+
27
+  &.hide {
28
+    display: none;
29
+  }
30
+}
31
+
32
+.toast-header {
33
+  display: flex;
34
+  align-items: center;
35
+  padding: $toast-padding-y $toast-padding-x;
36
+  color: $toast-header-color;
37
+  background-color: $toast-header-background-color;
38
+  background-clip: padding-box;
39
+  border-bottom: $toast-border-width solid $toast-header-border-color;
40
+}
41
+
42
+.toast-body {
43
+  padding: $toast-padding-x; // apply to both vertical and horizontal
44
+}

+ 115
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_tooltip.scss View File

@@ -0,0 +1,115 @@
1
+// Base class
2
+.tooltip {
3
+  position: absolute;
4
+  z-index: $zindex-tooltip;
5
+  display: block;
6
+  margin: $tooltip-margin;
7
+  // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
8
+  // So reset our font and text properties to avoid inheriting weird values.
9
+  @include reset-text();
10
+  @include font-size($tooltip-font-size);
11
+  // Allow breaking very long words so they don't overflow the tooltip's bounds
12
+  word-wrap: break-word;
13
+  opacity: 0;
14
+
15
+  &.show { opacity: $tooltip-opacity; }
16
+
17
+  .arrow {
18
+    position: absolute;
19
+    display: block;
20
+    width: $tooltip-arrow-width;
21
+    height: $tooltip-arrow-height;
22
+
23
+    &::before {
24
+      position: absolute;
25
+      content: "";
26
+      border-color: transparent;
27
+      border-style: solid;
28
+    }
29
+  }
30
+}
31
+
32
+.bs-tooltip-top {
33
+  padding: $tooltip-arrow-height 0;
34
+
35
+  .arrow {
36
+    bottom: 0;
37
+
38
+    &::before {
39
+      top: 0;
40
+      border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;
41
+      border-top-color: $tooltip-arrow-color;
42
+    }
43
+  }
44
+}
45
+
46
+.bs-tooltip-right {
47
+  padding: 0 $tooltip-arrow-height;
48
+
49
+  .arrow {
50
+    left: 0;
51
+    width: $tooltip-arrow-height;
52
+    height: $tooltip-arrow-width;
53
+
54
+    &::before {
55
+      right: 0;
56
+      border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;
57
+      border-right-color: $tooltip-arrow-color;
58
+    }
59
+  }
60
+}
61
+
62
+.bs-tooltip-bottom {
63
+  padding: $tooltip-arrow-height 0;
64
+
65
+  .arrow {
66
+    top: 0;
67
+
68
+    &::before {
69
+      bottom: 0;
70
+      border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;
71
+      border-bottom-color: $tooltip-arrow-color;
72
+    }
73
+  }
74
+}
75
+
76
+.bs-tooltip-left {
77
+  padding: 0 $tooltip-arrow-height;
78
+
79
+  .arrow {
80
+    right: 0;
81
+    width: $tooltip-arrow-height;
82
+    height: $tooltip-arrow-width;
83
+
84
+    &::before {
85
+      left: 0;
86
+      border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;
87
+      border-left-color: $tooltip-arrow-color;
88
+    }
89
+  }
90
+}
91
+
92
+.bs-tooltip-auto {
93
+  &[x-placement^="top"] {
94
+    @extend .bs-tooltip-top;
95
+  }
96
+  &[x-placement^="right"] {
97
+    @extend .bs-tooltip-right;
98
+  }
99
+  &[x-placement^="bottom"] {
100
+    @extend .bs-tooltip-bottom;
101
+  }
102
+  &[x-placement^="left"] {
103
+    @extend .bs-tooltip-left;
104
+  }
105
+}
106
+
107
+// Wrapper for the tooltip content
108
+.tooltip-inner {
109
+  max-width: $tooltip-max-width;
110
+  padding: $tooltip-padding-y $tooltip-padding-x;
111
+  color: $tooltip-color;
112
+  text-align: center;
113
+  background-color: $tooltip-bg;
114
+  @include border-radius($tooltip-border-radius);
115
+}

+ 20
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_transitions.scss View File

@@ -0,0 +1,20 @@
1
+.fade {
2
+  @include transition($transition-fade);
3
+
4
+  &:not(.show) {
5
+    opacity: 0;
6
+  }
7
+}
8
+
9
+.collapse {
10
+  &:not(.show) {
11
+    display: none;
12
+  }
13
+}
14
+
15
+.collapsing {
16
+  position: relative;
17
+  height: 0;
18
+  overflow: hidden;
19
+  @include transition($transition-collapse);
20
+}

+ 125
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_type.scss View File

@@ -0,0 +1,125 @@
1
+// stylelint-disable declaration-no-important, selector-list-comma-newline-after
2
+
3
+//
4
+// Headings
5
+//
6
+
7
+h1, h2, h3, h4, h5, h6,
8
+.h1, .h2, .h3, .h4, .h5, .h6 {
9
+  margin-bottom: $headings-margin-bottom;
10
+  font-family: $headings-font-family;
11
+  font-weight: $headings-font-weight;
12
+  line-height: $headings-line-height;
13
+  color: $headings-color;
14
+}
15
+
16
+h1, .h1 { @include font-size($h1-font-size); }
17
+h2, .h2 { @include font-size($h2-font-size); }
18
+h3, .h3 { @include font-size($h3-font-size); }
19
+h4, .h4 { @include font-size($h4-font-size); }
20
+h5, .h5 { @include font-size($h5-font-size); }
21
+h6, .h6 { @include font-size($h6-font-size); }
22
+
23
+.lead {
24
+  @include font-size($lead-font-size);
25
+  font-weight: $lead-font-weight;
26
+}
27
+
28
+// Type display classes
29
+.display-1 {
30
+  @include font-size($display1-size);
31
+  font-weight: $display1-weight;
32
+  line-height: $display-line-height;
33
+}
34
+.display-2 {
35
+  @include font-size($display2-size);
36
+  font-weight: $display2-weight;
37
+  line-height: $display-line-height;
38
+}
39
+.display-3 {
40
+  @include font-size($display3-size);
41
+  font-weight: $display3-weight;
42
+  line-height: $display-line-height;
43
+}
44
+.display-4 {
45
+  @include font-size($display4-size);
46
+  font-weight: $display4-weight;
47
+  line-height: $display-line-height;
48
+}
49
+
50
+
51
+//
52
+// Horizontal rules
53
+//
54
+
55
+hr {
56
+  margin-top: $hr-margin-y;
57
+  margin-bottom: $hr-margin-y;
58
+  border: 0;
59
+  border-top: $hr-border-width solid $hr-border-color;
60
+}
61
+
62
+
63
+//
64
+// Emphasis
65
+//
66
+
67
+small,
68
+.small {
69
+  @include font-size($small-font-size);
70
+  font-weight: $font-weight-normal;
71
+}
72
+
73
+mark,
74
+.mark {
75
+  padding: $mark-padding;
76
+  background-color: $mark-bg;
77
+}
78
+
79
+
80
+//
81
+// Lists
82
+//
83
+
84
+.list-unstyled {
85
+  @include list-unstyled;
86
+}
87
+
88
+// Inline turns list items into inline-block
89
+.list-inline {
90
+  @include list-unstyled;
91
+}
92
+.list-inline-item {
93
+  display: inline-block;
94
+
95
+  &:not(:last-child) {
96
+    margin-right: $list-inline-padding;
97
+  }
98
+}
99
+
100
+
101
+//
102
+// Misc
103
+//
104
+
105
+// Builds on `abbr`
106
+.initialism {
107
+  @include font-size(90%);
108
+  text-transform: uppercase;
109
+}
110
+
111
+// Blockquotes
112
+.blockquote {
113
+  margin-bottom: $spacer;
114
+  @include font-size($blockquote-font-size);
115
+}
116
+
117
+.blockquote-footer {
118
+  display: block;
119
+  @include font-size($blockquote-small-font-size);
120
+  color: $blockquote-small-color;
121
+
122
+  &::before {
123
+    content: "\2014\00A0"; // em dash, nbsp
124
+  }
125
+}

+ 17
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_utilities.scss View File

@@ -0,0 +1,17 @@
1
+@import "utilities/align";
2
+@import "utilities/background";
3
+@import "utilities/borders";
4
+@import "utilities/clearfix";
5
+@import "utilities/display";
6
+@import "utilities/embed";
7
+@import "utilities/flex";
8
+@import "utilities/float";
9
+@import "utilities/overflow";
10
+@import "utilities/position";
11
+@import "utilities/screenreaders";
12
+@import "utilities/shadows";
13
+@import "utilities/sizing";
14
+@import "utilities/stretched-link";
15
+@import "utilities/spacing";
16
+@import "utilities/text";
17
+@import "utilities/visibility";

+ 1123
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/_variables.scss
File diff suppressed because it is too large
View File


+ 29
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/bootstrap-grid.scss View File

@@ -0,0 +1,29 @@
1
+/*!
2
+ * Bootstrap Grid v4.3.1 (https://getbootstrap.com/)
3
+ * Copyright 2011-2019 The Bootstrap Authors
4
+ * Copyright 2011-2019 Twitter, Inc.
5
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
6
+ */
7
+
8
+html {
9
+  box-sizing: border-box;
10
+  -ms-overflow-style: scrollbar;
11
+}
12
+
13
+*,
14
+*::before,
15
+*::after {
16
+  box-sizing: inherit;
17
+}
18
+
19
+@import "functions";
20
+@import "variables";
21
+
22
+@import "mixins/breakpoints";
23
+@import "mixins/grid-framework";
24
+@import "mixins/grid";
25
+
26
+@import "grid";
27
+@import "utilities/display";
28
+@import "utilities/flex";
29
+@import "utilities/spacing";

+ 12
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/bootstrap-reboot.scss View File

@@ -0,0 +1,12 @@
1
+/*!
2
+ * Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
3
+ * Copyright 2011-2019 The Bootstrap Authors
4
+ * Copyright 2011-2019 Twitter, Inc.
5
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
6
+ * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
7
+ */
8
+
9
+@import "functions";
10
+@import "variables";
11
+@import "mixins";
12
+@import "reboot";

+ 44
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/bootstrap.scss View File

@@ -0,0 +1,44 @@
1
+/*!
2
+ * Bootstrap v4.3.1 (https://getbootstrap.com/)
3
+ * Copyright 2011-2019 The Bootstrap Authors
4
+ * Copyright 2011-2019 Twitter, Inc.
5
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
6
+ */
7
+
8
+@import "functions";
9
+@import "variables";
10
+@import "mixins";
11
+@import "root";
12
+@import "reboot";
13
+@import "type";
14
+@import "images";
15
+@import "code";
16
+@import "grid";
17
+@import "tables";
18
+@import "forms";
19
+@import "buttons";
20
+@import "transitions";
21
+@import "dropdown";
22
+@import "button-group";
23
+@import "input-group";
24
+@import "custom-forms";
25
+@import "nav";
26
+@import "navbar";
27
+@import "card";
28
+@import "breadcrumb";
29
+@import "pagination";
30
+@import "badge";
31
+@import "jumbotron";
32
+@import "alert";
33
+@import "progress";
34
+@import "media";
35
+@import "list-group";
36
+@import "close";
37
+@import "toasts";
38
+@import "modal";
39
+@import "tooltip";
40
+@import "popover";
41
+@import "carousel";
42
+@import "spinners";
43
+@import "utilities";
44
+@import "print";

+ 13
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_alert.scss View File

@@ -0,0 +1,13 @@
1
+@mixin alert-variant($background, $border, $color) {
2
+  color: $color;
3
+  @include gradient-bg($background);
4
+  border-color: $border;
5
+
6
+  hr {
7
+    border-top-color: darken($border, 5%);
8
+  }
9
+
10
+  .alert-link {
11
+    color: darken($color, 10%);
12
+  }
13
+}

+ 21
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_background-variant.scss View File

@@ -0,0 +1,21 @@
1
+// stylelint-disable declaration-no-important
2
+
3
+// Contextual backgrounds
4
+
5
+@mixin bg-variant($parent, $color) {
6
+  #{$parent} {
7
+    background-color: $color !important;
8
+  }
9
+  a#{$parent},
10
+  button#{$parent} {
11
+    @include hover-focus {
12
+      background-color: darken($color, 10%) !important;
13
+    }
14
+  }
15
+}
16
+
17
+@mixin bg-gradient-variant($parent, $color) {
18
+  #{$parent} {
19
+    background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;
20
+  }
21
+}

+ 17
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_badge.scss View File

@@ -0,0 +1,17 @@
1
+@mixin badge-variant($bg) {
2
+  color: color-yiq($bg);
3
+  background-color: $bg;
4
+
5
+  @at-root a#{&} {
6
+    @include hover-focus {
7
+      color: color-yiq($bg);
8
+      background-color: darken($bg, 10%);
9
+    }
10
+
11
+    &:focus,
12
+    &.focus {
13
+      outline: 0;
14
+      box-shadow: 0 0 0 $badge-focus-width rgba($bg, .5);
15
+    }
16
+  }
17
+}

+ 63
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_border-radius.scss View File

@@ -0,0 +1,63 @@
1
+// stylelint-disable property-blacklist
2
+// Single side border-radius
3
+
4
+@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {
5
+  @if $enable-rounded {
6
+    border-radius: $radius;
7
+  }
8
+  @else if $fallback-border-radius != false {
9
+    border-radius: $fallback-border-radius;
10
+  }
11
+}
12
+
13
+@mixin border-top-radius($radius) {
14
+  @if $enable-rounded {
15
+    border-top-left-radius: $radius;
16
+    border-top-right-radius: $radius;
17
+  }
18
+}
19
+
20
+@mixin border-right-radius($radius) {
21
+  @if $enable-rounded {
22
+    border-top-right-radius: $radius;
23
+    border-bottom-right-radius: $radius;
24
+  }
25
+}
26
+
27
+@mixin border-bottom-radius($radius) {
28
+  @if $enable-rounded {
29
+    border-bottom-right-radius: $radius;
30
+    border-bottom-left-radius: $radius;
31
+  }
32
+}
33
+
34
+@mixin border-left-radius($radius) {
35
+  @if $enable-rounded {
36
+    border-top-left-radius: $radius;
37
+    border-bottom-left-radius: $radius;
38
+  }
39
+}
40
+
41
+@mixin border-top-left-radius($radius) {
42
+  @if $enable-rounded {
43
+    border-top-left-radius: $radius;
44
+  }
45
+}
46
+
47
+@mixin border-top-right-radius($radius) {
48
+  @if $enable-rounded {
49
+    border-top-right-radius: $radius;
50
+  }
51
+}
52
+
53
+@mixin border-bottom-right-radius($radius) {
54
+  @if $enable-rounded {
55
+    border-bottom-right-radius: $radius;
56
+  }
57
+}
58
+
59
+@mixin border-bottom-left-radius($radius) {
60
+  @if $enable-rounded {
61
+    border-bottom-left-radius: $radius;
62
+  }
63
+}

+ 20
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_box-shadow.scss View File

@@ -0,0 +1,20 @@
1
+@mixin box-shadow($shadow...) {
2
+  @if $enable-shadows {
3
+    $result: ();
4
+
5
+    @if (length($shadow) == 1) {
6
+      // We can pass `@include box-shadow(none);`
7
+      $result: $shadow;
8
+    } @else {
9
+      // Filter to avoid invalid properties for example `box-shadow: none, 1px 1px black;`
10
+      @for $i from 1 through length($shadow) {
11
+        @if nth($shadow, $i) != "none" {
12
+          $result: append($result, nth($shadow, $i), "comma");
13
+        }
14
+      }
15
+    }
16
+    @if (length($result) > 0) {
17
+      box-shadow: $result;
18
+    }
19
+  }
20
+}

+ 123
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_breakpoints.scss View File

@@ -0,0 +1,123 @@
1
+// Breakpoint viewport sizes and media queries.
2
+//
3
+// Breakpoints are defined as a map of (name: minimum width), order from small to large:
4
+//
5
+//    (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)
6
+//
7
+// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
8
+
9
+// Name of the next breakpoint, or null for the last breakpoint.
10
+//
11
+//    >> breakpoint-next(sm)
12
+//    md
13
+//    >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
14
+//    md
15
+//    >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))
16
+//    md
17
+@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
18
+  $n: index($breakpoint-names, $name);
19
+  @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
20
+}
21
+
22
+// Minimum breakpoint width. Null for the smallest (first) breakpoint.
23
+//
24
+//    >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
25
+//    576px
26
+@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
27
+  $min: map-get($breakpoints, $name);
28
+  @return if($min != 0, $min, null);
29
+}
30
+
31
+// Maximum breakpoint width. Null for the largest (last) breakpoint.
32
+// The maximum value is calculated as the minimum of the next one less 0.02px
33
+// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.
34
+// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max
35
+// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.
36
+// See https://bugs.webkit.org/show_bug.cgi?id=178261
37
+//
38
+//    >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
39
+//    767.98px
40
+@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
41
+  $next: breakpoint-next($name, $breakpoints);
42
+  @return if($next, breakpoint-min($next, $breakpoints) - .02, null);
43
+}
44
+
45
+// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.
46
+// Useful for making responsive utilities.
47
+//
48
+//    >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
49
+//    ""  (Returns a blank string)
50
+//    >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
51
+//    "-sm"
52
+@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
53
+  @return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
54
+}
55
+
56
+// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
57
+// Makes the @content apply to the given breakpoint and wider.
58
+@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
59
+  $min: breakpoint-min($name, $breakpoints);
60
+  @if $min {
61
+    @media (min-width: $min) {
62
+      @content;
63
+    }
64
+  } @else {
65
+    @content;
66
+  }
67
+}
68
+
69
+// Media of at most the maximum breakpoint width. No query for the largest breakpoint.
70
+// Makes the @content apply to the given breakpoint and narrower.
71
+@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {
72
+  $max: breakpoint-max($name, $breakpoints);
73
+  @if $max {
74
+    @media (max-width: $max) {
75
+      @content;
76
+    }
77
+  } @else {
78
+    @content;
79
+  }
80
+}
81
+
82
+// Media that spans multiple breakpoint widths.
83
+// Makes the @content apply between the min and max breakpoints
84
+@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {
85
+  $min: breakpoint-min($lower, $breakpoints);
86
+  $max: breakpoint-max($upper, $breakpoints);
87
+
88
+  @if $min != null and $max != null {
89
+    @media (min-width: $min) and (max-width: $max) {
90
+      @content;
91
+    }
92
+  } @else if $max == null {
93
+    @include media-breakpoint-up($lower, $breakpoints) {
94
+      @content;
95
+    }
96
+  } @else if $min == null {
97
+    @include media-breakpoint-down($upper, $breakpoints) {
98
+      @content;
99
+    }
100
+  }
101
+}
102
+
103
+// Media between the breakpoint's minimum and maximum widths.
104
+// No minimum for the smallest breakpoint, and no maximum for the largest one.
105
+// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.
106
+@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {
107
+  $min: breakpoint-min($name, $breakpoints);
108
+  $max: breakpoint-max($name, $breakpoints);
109
+
110
+  @if $min != null and $max != null {
111
+    @media (min-width: $min) and (max-width: $max) {
112
+      @content;
113
+    }
114
+  } @else if $max == null {
115
+    @include media-breakpoint-up($name, $breakpoints) {
116
+      @content;
117
+    }
118
+  } @else if $min == null {
119
+    @include media-breakpoint-down($name, $breakpoints) {
120
+      @content;
121
+    }
122
+  }
123
+}

+ 107
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_buttons.scss View File

@@ -0,0 +1,107 @@
1
+// Button variants
2
+//
3
+// Easily pump out default styles, as well as :hover, :focus, :active,
4
+// and disabled options for all buttons
5
+
6
+@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {
7
+  color: color-yiq($background);
8
+  @include gradient-bg($background);
9
+  border-color: $border;
10
+  @include box-shadow($btn-box-shadow);
11
+
12
+  @include hover {
13
+    color: color-yiq($hover-background);
14
+    @include gradient-bg($hover-background);
15
+    border-color: $hover-border;
16
+  }
17
+
18
+  &:focus,
19
+  &.focus {
20
+    // Avoid using mixin so we can pass custom focus shadow properly
21
+    @if $enable-shadows {
22
+      box-shadow: $btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
23
+    } @else {
24
+      box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
25
+    }
26
+  }
27
+
28
+  // Disabled comes first so active can properly restyle
29
+  &.disabled,
30
+  &:disabled {
31
+    color: color-yiq($background);
32
+    background-color: $background;
33
+    border-color: $border;
34
+    // Remove CSS gradients if they're enabled
35
+    @if $enable-gradients {
36
+      background-image: none;
37
+    }
38
+  }
39
+
40
+  &:not(:disabled):not(.disabled):active,
41
+  &:not(:disabled):not(.disabled).active,
42
+  .show > &.dropdown-toggle {
43
+    color: color-yiq($active-background);
44
+    background-color: $active-background;
45
+    @if $enable-gradients {
46
+      background-image: none; // Remove the gradient for the pressed/active state
47
+    }
48
+    border-color: $active-border;
49
+
50
+    &:focus {
51
+      // Avoid using mixin so we can pass custom focus shadow properly
52
+      @if $enable-shadows and $btn-active-box-shadow != none {
53
+        box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
54
+      } @else {
55
+        box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
56
+      }
57
+    }
58
+  }
59
+}
60
+
61
+@mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {
62
+  color: $color;
63
+  border-color: $color;
64
+
65
+  @include hover {
66
+    color: $color-hover;
67
+    background-color: $active-background;
68
+    border-color: $active-border;
69
+  }
70
+
71
+  &:focus,
72
+  &.focus {
73
+    box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
74
+  }
75
+
76
+  &.disabled,
77
+  &:disabled {
78
+    color: $color;
79
+    background-color: transparent;
80
+  }
81
+
82
+  &:not(:disabled):not(.disabled):active,
83
+  &:not(:disabled):not(.disabled).active,
84
+  .show > &.dropdown-toggle {
85
+    color: color-yiq($active-background);
86
+    background-color: $active-background;
87
+    border-color: $active-border;
88
+
89
+    &:focus {
90
+      // Avoid using mixin so we can pass custom focus shadow properly
91
+      @if $enable-shadows and $btn-active-box-shadow != none {
92
+        box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5);
93
+      } @else {
94
+        box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
95
+      }
96
+    }
97
+  }
98
+}
99
+
100
+// Button sizes
101
+@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
102
+  padding: $padding-y $padding-x;
103
+  @include font-size($font-size);
104
+  line-height: $line-height;
105
+  // Manually declare to provide an override to the browser default
106
+  @include border-radius($border-radius, 0);
107
+}

+ 62
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_caret.scss View File

@@ -0,0 +1,62 @@
1
+@mixin caret-down {
2
+  border-top: $caret-width solid;
3
+  border-right: $caret-width solid transparent;
4
+  border-bottom: 0;
5
+  border-left: $caret-width solid transparent;
6
+}
7
+
8
+@mixin caret-up {
9
+  border-top: 0;
10
+  border-right: $caret-width solid transparent;
11
+  border-bottom: $caret-width solid;
12
+  border-left: $caret-width solid transparent;
13
+}
14
+
15
+@mixin caret-right {
16
+  border-top: $caret-width solid transparent;
17
+  border-right: 0;
18
+  border-bottom: $caret-width solid transparent;
19
+  border-left: $caret-width solid;
20
+}
21
+
22
+@mixin caret-left {
23
+  border-top: $caret-width solid transparent;
24
+  border-right: $caret-width solid;
25
+  border-bottom: $caret-width solid transparent;
26
+}
27
+
28
+@mixin caret($direction: down) {
29
+  @if $enable-caret {
30
+    &::after {
31
+      display: inline-block;
32
+      margin-left: $caret-spacing;
33
+      vertical-align: $caret-vertical-align;
34
+      content: "";
35
+      @if $direction == down {
36
+        @include caret-down;
37
+      } @else if $direction == up {
38
+        @include caret-up;
39
+      } @else if $direction == right {
40
+        @include caret-right;
41
+      }
42
+    }
43
+
44
+    @if $direction == left {
45
+      &::after {
46
+        display: none;
47
+      }
48
+
49
+      &::before {
50
+        display: inline-block;
51
+        margin-right: $caret-spacing;
52
+        vertical-align: $caret-vertical-align;
53
+        content: "";
54
+        @include caret-left;
55
+      }
56
+    }
57
+
58
+    &:empty::after {
59
+      margin-left: 0;
60
+    }
61
+  }
62
+}

+ 7
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_clearfix.scss View File

@@ -0,0 +1,7 @@
1
+@mixin clearfix() {
2
+  &::after {
3
+    display: block;
4
+    clear: both;
5
+    content: "";
6
+  }
7
+}

+ 10
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_deprecate.scss View File

@@ -0,0 +1,10 @@
1
+// Deprecate mixin
2
+//
3
+// This mixin can be used to deprecate mixins or functions.
4
+// `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to
5
+// some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap)
6
+@mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) {
7
+  @if ($enable-deprecation-messages != false and $ignore-warning != true) {
8
+    @warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}.";
9
+  }
10
+}

+ 14
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_float.scss View File

@@ -0,0 +1,14 @@
1
+// stylelint-disable declaration-no-important
2
+
3
+@mixin float-left {
4
+  float: left !important;
5
+  @include deprecate("The `float-left` mixin", "v4.3.0", "v5");
6
+}
7
+@mixin float-right {
8
+  float: right !important;
9
+  @include deprecate("The `float-right` mixin", "v4.3.0", "v5");
10
+}
11
+@mixin float-none {
12
+  float: none !important;
13
+  @include deprecate("The `float-none` mixin", "v4.3.0", "v5");
14
+}

+ 0
- 0
app/base/static/assets/scss/black-dashboard/bootstrap/mixins/_forms.scss View File


Some files were not shown because too many files changed in this diff