Dung Diego

up

Showing 1000 changed files with 4984 additions and 0 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

1 +<?php
2 +
3 +namespace App\Http\Controllers;
4 +use Illuminate\Http\Request;
5 +use Carbon\Carbon;
6 +use Illuminate\Support\Facades\Storage;
7 +use Illuminate\Support\Facades\Log;
8 +
9 +class OcrController extends Controller
10 +{
11 + public function index(Request $request){
12 + return view('dashboard',['ocr'=>[]]);
13 + }
14 + public function show_pdf(Request $request)
15 + {
16 + return response()->file($request->file_path);
17 + }
18 + public function preview_pdf(Request $request){
19 + return view('ocr.ocr_pdf', ['disable'=>$request->disable??0]);
20 + }
21 + public function import_pdf(Request $request){
22 + try {
23 + [$image_path,$js_path] = $this->ocr_process($request);
24 + $json_data = json_decode(file_get_contents($js_path), true);
25 + $ocr=[];
26 + $ocr['json_data']=$json_data;
27 + $ocr['js_path'] = $js_path;
28 + $ocr['image_path'] = $image_path;
29 + return response()->json(['status' => true,'data' => $ocr,]);
30 + } catch (\Throwable $e){
31 + report($e);
32 + return response()->json(['status' => false]);
33 + }
34 + }
35 + public function ocr_process($request){
36 + set_time_limit(0);
37 + ini_set('max_execution_time', 0);
38 + $mount_path=env('PYTHON_SERVICE_MOUNT_PATH','');
39 + $ocr_serve_path=env('OCR_SERVER_PATH','');
40 + $ocr_storage='ocr_results';
41 + if($ocr_serve_path) $ocr_storage='ocr_results_sftp';
42 +
43 + $now=Carbon::now()->format('YmdHis');
44 + umask(0002);
45 + Storage::disk($ocr_storage)->makeDirectory($now);
46 + $input_file_name=$request->file('attached_file')->getClientOriginalName();
47 + Log::info('upload ocr '.$input_file_name);
48 + Storage::disk($ocr_storage)->putFileAs($now, $request->file('attached_file'),$input_file_name);
49 + $file_path=Storage::disk($ocr_storage)->path($now.DIRECTORY_SEPARATOR.$input_file_name);
50 + $ch = curl_init();
51 + Storage::disk('ocr_results')->makeDirectory($now);
52 + chmod(Storage::disk('ocr_results')->path($now), 0777);
53 +
54 + if(!empty($mount_path)){
55 + $file_path = str_replace('/', '\\', str_replace(
56 + '/mnt/ocr',
57 + $mount_path,
58 + $file_path
59 + ));
60 + }
61 +
62 + $params = [
63 + 'file_path' => $file_path,
64 + ];
65 + foreach (($request->option ?? []) as $key => $value) {
66 + $params[$key] = $value;
67 + }
68 + $url = env('PYTHON_SERVICE_ENDPOINT', "http://127.0.0.1:8000/"). '?'. http_build_query($params);
69 +
70 + curl_setopt($ch, CURLOPT_URL, $url);
71 + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
72 + $response = curl_exec($ch);
73 + if(curl_errno($ch)){
74 + throw new Exception('Curl error: ' . curl_error($ch));
75 + }
76 + curl_close($ch);
77 + $data = json_decode($response, true);
78 + if (empty($data['success'])){
79 + throw new Exception($data['message']);
80 + }
81 +
82 + if($ocr_serve_path){
83 + $files = Storage::disk('ocr_results_sftp')->files($now);
84 +
85 + foreach ($files as $file) {
86 + Storage::disk('ocr_results')->put(
87 + $file,
88 + Storage::disk('ocr_results_sftp')->get($file)
89 + );
90 + }
91 + }
92 +
93 +
94 + if (!Storage::disk('ocr_results')->exists($now.DIRECTORY_SEPARATOR.'rs.json'))
95 + throw new Exception('file rs ocr not found');
96 + Log::info('read ocr successfully');
97 +
98 + return [Storage::disk('ocr_results')->path($now.DIRECTORY_SEPARATOR.'rs.jpg'), Storage::disk('ocr_results')->path($now.DIRECTORY_SEPARATOR.'rs.json')];
99 + }
100 + public function ocr_db(&$ocr){
101 + $json_data=json_decode(file_get_contents($ocr['js_path']), true);
102 + $json_data['chars']=[];
103 + $ocr['json_data']=$json_data;
104 + if(!empty($ocr['tpl'])){
105 + if(!empty($ocr['tpl']['tpl_id'])) $ocr['mst_template']=OcrMstTemplate::where('tpl_id', $ocr['tpl']['tpl_id'])->first()?->toArray()??[];
106 + else $ocr['mst_template']=$ocr['tpl'];
107 + }
108 +
109 + if(empty($ocr['mst_template'])) $ocr['mst_template']=['tpl_text'=>'','tpl_xy'=>'','tpl_id'=>'','image'=>$json_data['image']];
110 + $ocr['mst_template_field']=OcrMstTemplateField::get()->keyBy('field_name');
111 + $ocr['dt_template_field']=!empty($ocr['tpl'])?OcrDtTemplate::where('tpl_id', $ocr['tpl']['tpl_id'])->get():[];
112 + }
113 +}
...@@ -53,6 +53,11 @@ ...@@ -53,6 +53,11 @@
53 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), 53 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
54 ], 54 ],
55 55
56 + 'ocr_results' => [
57 + 'driver' => 'local',
58 + 'root' => storage_path('ocr'),
59 + ],
60 +
56 ], 61 ],
57 62
58 /* 63 /*
......
1 +
2 +# Contributing to AdminLTE
3 +
4 +Contributions are always **welcome and recommended**! Here is how for beginner's: [Get started with open source click here](https://youtu.be/GbqSvJs-6W4)
5 +
6 +1. Contribution Requirements :
7 + * When you contribute, you agree to give a non-exclusive license to AdminLTE.io to use that contribution in any context as we (AdminLTE.io) see appropriate.
8 + * If you use content provided by another party, it must be appropriately licensed using an [open source](https://opensource.org/licenses) license.
9 + * Contributions are only accepted through GitHub pull requests.
10 + * Finally, contributed code must work in all supported browsers (see above for browser support).
11 +2. Installation :
12 + * Fork the repository ([here is the guide](https://help.github.com/articles/fork-a-repo/)).
13 + * Clone to your machine
14 +
15 + ```bash
16 + git clone https://github.com/YOUR_USERNAME/AdminLTE.git
17 + ```
18 + * Create a new branch
19 +3. Compile dist files (Development) :
20 + * To compile the dist files you need Node.js 10 or higher/npm (node package manager)
21 + * Delete ./package-lock.json file
22 + * `npm install` (install npm deps)
23 + * `npm run dev` (developer mode, autocompile with browsersync support for live demo)
24 + * Make your changes only in ./build Folder OR package.json OR ./dist/js/demo.js OR package-lock.json OR ./dist/js/pages/ OR ./docs OR in any html files which are necessary for contribution
25 + * Do not make changes in ./dist/css/ AND ./dist/js/ AND ./plugins Because it contains compiled files and do not include in PR (Pull Request)
26 + * `npm run production` (compile css/js files and test all pages are perfectly working fine, before creating a pull request)
27 +4. Create a pull request
28 +
29 +## Online one-click setup for contributing
30 +
31 +You can use Gitpod(an online IDE which is free for Open Source) for working on issues or making PRs (Pull Requests). With a single click it will launch a workspace and automatically:
32 +
33 +- clone the `AdminLTE` repo.
34 +- install the dependencies.
35 +- run `npm run dev` to start the server.
36 +
37 +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/)
1 +---
2 +name: Bug report for AdminLTE v3.x
3 +about: Create a report to help us improve AdminLTE v3.x
4 +title: "[BUG]"
5 +labels: type:bug, version:3.1.x
6 +assignees: ''
7 +
8 +---
9 +
10 +**Describe the bug**
11 +A clear and concise description of what the bug is.
12 +
13 +**To Reproduce**
14 +Steps to reproduce the behavior:
15 +1. Go to '...'
16 +2. Click on '....'
17 +3. Scroll down to '....'
18 +4. See error
19 +
20 +**Expected behavior**
21 +A clear and concise description of what you expected to happen.
22 +
23 +**Screenshots**
24 +If applicable, add screenshots to help explain your problem.
25 +
26 +**Environment (please complete the following information):**
27 +- AdminLTE Version: [e.g. v3.0.0]
28 +- Operating System: [e.g. macOS Catalina]
29 +- Browser (Version): [e.g. Chrome (Latest)]
30 +
31 +**Additional context**
32 +Add any other context about the problem here.
1 +---
2 +name: Feature request for AdminLTE v4.x
3 +about: Suggest an idea for this project
4 +title: "[FEATURE]"
5 +labels: type:enhancement, version:4.x
6 +assignees: ''
7 +
8 +---
9 +
10 +**Is your feature request related to a problem? Please describe.**
11 +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 +
13 +**Describe the solution you'd like**
14 +A clear and concise description of what you want to happen.
15 +
16 +**Describe alternatives you've considered**
17 +A clear and concise description of any alternative solutions or features you've considered.
18 +
19 +**Additional context**
20 +Add any other context or screenshots about the feature request here.
1 +name: "CodeQL config"
2 +
3 +paths-ignore:
4 + - docs/assets/plugins/
5 + - plugins/
1 +version: 2
2 +updates:
3 + - package-ecosystem: npm
4 + directory: "/"
5 + schedule:
6 + interval: weekly
7 + day: monday
8 + time: "03:00"
9 + open-pull-requests-limit: 10
10 + versioning-strategy: increase
11 + - package-ecosystem: bundler
12 + directory: "/docs/"
13 + schedule:
14 + interval: weekly
15 + day: monday
16 + time: "03:00"
17 + open-pull-requests-limit: 10
18 + versioning-strategy: increase
1 +name: CI
2 +
3 +on:
4 + push:
5 + branches:
6 + - master
7 + - v4-dev
8 + pull_request:
9 + branches:
10 + - "**"
11 +
12 +env:
13 + FORCE_COLOR: 2
14 +
15 +jobs:
16 + run:
17 + runs-on: ${{ matrix.os }}
18 +
19 + strategy:
20 + fail-fast: false
21 + matrix:
22 + node:
23 + - "10.x"
24 + - "12.x"
25 + - "14.x"
26 + os:
27 + - "ubuntu-latest"
28 + - "macos-latest"
29 + - "windows-latest"
30 +
31 + steps:
32 + - name: Clone repository
33 + uses: actions/checkout@v2
34 +
35 + - name: Use Node.js ${{ matrix.node }}
36 + uses: actions/setup-node@v2
37 + with:
38 + node-version: ${{ matrix.node }}
39 +
40 + - name: Get npm cache directory
41 + id: npm-cache
42 + run: |
43 + echo "::set-output name=dir::$(npm config get cache)"
44 +
45 + - name: Set up npm cache
46 + uses: actions/cache@v2
47 + with:
48 + path: ${{ steps.npm-cache.outputs.dir }}
49 + key: ${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}}
50 + restore-keys: |
51 + ${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
52 + ${{ runner.os }}-node-v${{ matrix.node }}-
53 +
54 + - name: Install npm dependencies
55 + run: npm ci
56 +
57 + - name: Build files
58 + run: npm run compile
59 +
60 + - name: Run bundlewatch
61 + run: npm run bundlewatch
62 + if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.node, '14')
63 + env:
64 + BUNDLEWATCH_GITHUB_TOKEN: "${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}"
1 +name: "CodeQL"
2 +
3 +on:
4 + push:
5 + branches:
6 + - master
7 + - v4-dev
8 + - "!dependabot/**"
9 + pull_request:
10 + # The branches below must be a subset of the branches above
11 + branches:
12 + - master
13 + schedule:
14 + - cron: "0 0 * * 0"
15 +
16 +jobs:
17 + analyze:
18 + name: Analyze
19 + runs-on: ubuntu-latest
20 +
21 + steps:
22 + - name: Checkout repository
23 + uses: actions/checkout@v2
24 +
25 + # Initializes the CodeQL tools for scanning.
26 + - name: Initialize CodeQL
27 + uses: github/codeql-action/init@v1
28 + with:
29 + languages: "javascript"
30 + config-file: ./.github/codeql/codeql-config.yml
31 +
32 + - name: Autobuild
33 + uses: github/codeql-action/autobuild@v1
34 +
35 + - name: Perform CodeQL Analysis
36 + uses: github/codeql-action/analyze@v1
1 +name: Docs
2 +
3 +on:
4 + push:
5 + branches:
6 + - master
7 + - v4-dev
8 + pull_request:
9 + branches:
10 + - "**"
11 +
12 +env:
13 + FORCE_COLOR: 2
14 + NODE: 14.x
15 + RUBY: 2.7
16 +
17 +jobs:
18 + run:
19 + runs-on: ubuntu-latest
20 +
21 + steps:
22 + - name: Clone repository
23 + uses: actions/checkout@v2
24 +
25 + - name: Set up Node.js
26 + uses: actions/setup-node@v2
27 + with:
28 + node-version: "${{ env.NODE }}"
29 +
30 + - name: Set up Ruby
31 + uses: ruby/setup-ruby@v1
32 + with:
33 + ruby-version: "${{ env.RUBY }}"
34 + bundler-cache: true
35 + working-directory: docs
36 +
37 + - name: Version info
38 + run: |
39 + ruby --version
40 + gem --version
41 + bundle --version
42 + java -version
43 +
44 + - name: Set up npm cache
45 + uses: actions/cache@v2
46 + with:
47 + path: ~/.npm
48 + key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}}
49 + restore-keys: |
50 + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
51 + ${{ runner.os }}-node-v${{ env.NODE }}-
52 +
53 + - name: Install npm dependencies
54 + run: npm ci
55 +
56 + - name: Build docs
57 + run: npm run docs-compile
58 +
59 + - name: Run HTML validator
60 + run: npm run docs-lint
1 +name: Lint
2 +
3 +on:
4 + push:
5 + branches:
6 + - master
7 + - v4-dev
8 + pull_request:
9 + branches:
10 + - "**"
11 +
12 +env:
13 + FORCE_COLOR: 2
14 + NODE: 14.x
15 +
16 +jobs:
17 + run:
18 + runs-on: ubuntu-latest
19 +
20 + steps:
21 + - name: Clone repository
22 + uses: actions/checkout@v2
23 +
24 + - name: Set up Node.js
25 + uses: actions/setup-node@v2
26 + with:
27 + node-version: "${{ env.NODE }}"
28 +
29 + - name: Set up npm cache
30 + uses: actions/cache@v2
31 + with:
32 + path: ~/.npm
33 + key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}}
34 + restore-keys: |
35 + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
36 + ${{ runner.os }}-node-v${{ env.NODE }}-
37 +
38 + - name: Install npm dependencies
39 + run: npm ci
40 +
41 + - name: Run lint
42 + run: npm run lint
1 +{
2 + "env": {
3 + "browser": false,
4 + "node": true
5 + },
6 + "parserOptions": {
7 + "sourceType": "script"
8 + },
9 + "extends": "../../.eslintrc.json",
10 + "rules": {
11 + "no-console": "off",
12 + "strict": "error",
13 + "unicorn/prefer-module": "off"
14 + }
15 +}
1 +'use strict'
2 +
3 +module.exports = {
4 + map: {
5 + inline: false,
6 + annotation: true,
7 + sourcesContent: true
8 + },
9 + plugins: [
10 + require('autoprefixer')({
11 + cascade: false
12 + })
13 + ]
14 +}
1 +'use strict'
2 +
3 +const { babel } = require('@rollup/plugin-babel')
4 +
5 +const pkg = require('../../package')
6 +const year = new Date().getFullYear()
7 +const banner = `/*!
8 + * AdminLTE v${pkg.version} (${pkg.homepage})
9 + * Copyright 2014-${year} ${pkg.author}
10 + * Licensed under MIT (https://github.com/ColorlibHQ/AdminLTE/blob/master/LICENSE)
11 + */`
12 +
13 +module.exports = {
14 + input: 'build/js/AdminLTE.js',
15 + output: {
16 + banner,
17 + file: 'dist/js/adminlte.js',
18 + format: 'umd',
19 + globals: {
20 + jquery: 'jQuery'
21 + },
22 + name: 'adminlte'
23 + },
24 + external: ['jquery'],
25 + plugins: [
26 + babel({
27 + exclude: 'node_modules/**',
28 + // Include the helpers in the bundle, at most one copy of each
29 + babelHelpers: 'bundled'
30 + })
31 + ]
32 +}
1 +import CardRefresh from './CardRefresh'
2 +import CardWidget from './CardWidget'
3 +import ControlSidebar from './ControlSidebar'
4 +import DirectChat from './DirectChat'
5 +import Dropdown from './Dropdown'
6 +import ExpandableTable from './ExpandableTable'
7 +import Fullscreen from './Fullscreen'
8 +import IFrame from './IFrame'
9 +import Layout from './Layout'
10 +import PushMenu from './PushMenu'
11 +import SidebarSearch from './SidebarSearch'
12 +import NavbarSearch from './NavbarSearch'
13 +import Toasts from './Toasts'
14 +import TodoList from './TodoList'
15 +import Treeview from './Treeview'
16 +
17 +export {
18 + CardRefresh,
19 + CardWidget,
20 + ControlSidebar,
21 + DirectChat,
22 + Dropdown,
23 + ExpandableTable,
24 + Fullscreen,
25 + IFrame,
26 + Layout,
27 + PushMenu,
28 + SidebarSearch,
29 + NavbarSearch,
30 + Toasts,
31 + TodoList,
32 + Treeview
33 +}
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE CardRefresh.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'CardRefresh'
16 +const DATA_KEY = 'lte.cardrefresh'
17 +const EVENT_KEY = `.${DATA_KEY}`
18 +const JQUERY_NO_CONFLICT = $.fn[NAME]
19 +
20 +const EVENT_LOADED = `loaded${EVENT_KEY}`
21 +const EVENT_OVERLAY_ADDED = `overlay.added${EVENT_KEY}`
22 +const EVENT_OVERLAY_REMOVED = `overlay.removed${EVENT_KEY}`
23 +
24 +const CLASS_NAME_CARD = 'card'
25 +
26 +const SELECTOR_CARD = `.${CLASS_NAME_CARD}`
27 +const SELECTOR_DATA_REFRESH = '[data-card-widget="card-refresh"]'
28 +
29 +const Default = {
30 + source: '',
31 + sourceSelector: '',
32 + params: {},
33 + trigger: SELECTOR_DATA_REFRESH,
34 + content: '.card-body',
35 + loadInContent: true,
36 + loadOnInit: true,
37 + loadErrorTemplate: true,
38 + responseType: '',
39 + overlayTemplate: '<div class="overlay"><i class="fas fa-2x fa-sync-alt fa-spin"></i></div>',
40 + errorTemplate: '<span class="text-danger"></span>',
41 + onLoadStart() {},
42 + onLoadDone(response) {
43 + return response
44 + },
45 + onLoadFail(_jqXHR, _textStatus, _errorThrown) {}
46 +}
47 +
48 +class CardRefresh {
49 + constructor(element, settings) {
50 + this._element = element
51 + this._parent = element.parents(SELECTOR_CARD).first()
52 + this._settings = $.extend({}, Default, settings)
53 + this._overlay = $(this._settings.overlayTemplate)
54 +
55 + if (element.hasClass(CLASS_NAME_CARD)) {
56 + this._parent = element
57 + }
58 +
59 + if (this._settings.source === '') {
60 + throw new Error('Source url was not defined. Please specify a url in your CardRefresh source option.')
61 + }
62 + }
63 +
64 + load() {
65 + this._addOverlay()
66 + this._settings.onLoadStart.call($(this))
67 +
68 + $.get(this._settings.source, this._settings.params, response => {
69 + if (this._settings.loadInContent) {
70 + if (this._settings.sourceSelector !== '') {
71 + response = $(response).find(this._settings.sourceSelector).html()
72 + }
73 +
74 + this._parent.find(this._settings.content).html(response)
75 + }
76 +
77 + this._settings.onLoadDone.call($(this), response)
78 + this._removeOverlay()
79 + }, this._settings.responseType !== '' && this._settings.responseType)
80 + .fail((jqXHR, textStatus, errorThrown) => {
81 + this._removeOverlay()
82 +
83 + if (this._settings.loadErrorTemplate) {
84 + const msg = $(this._settings.errorTemplate).text(errorThrown)
85 + this._parent.find(this._settings.content).empty().append(msg)
86 + }
87 +
88 + this._settings.onLoadFail.call($(this), jqXHR, textStatus, errorThrown)
89 + })
90 +
91 + $(this._element).trigger($.Event(EVENT_LOADED))
92 + }
93 +
94 + _addOverlay() {
95 + this._parent.append(this._overlay)
96 + $(this._element).trigger($.Event(EVENT_OVERLAY_ADDED))
97 + }
98 +
99 + _removeOverlay() {
100 + this._parent.find(this._overlay).remove()
101 + $(this._element).trigger($.Event(EVENT_OVERLAY_REMOVED))
102 + }
103 +
104 + // Private
105 +
106 + _init() {
107 + $(this).find(this._settings.trigger).on('click', () => {
108 + this.load()
109 + })
110 +
111 + if (this._settings.loadOnInit) {
112 + this.load()
113 + }
114 + }
115 +
116 + // Static
117 +
118 + static _jQueryInterface(config) {
119 + let data = $(this).data(DATA_KEY)
120 + const _options = $.extend({}, Default, $(this).data())
121 +
122 + if (!data) {
123 + data = new CardRefresh($(this), _options)
124 + $(this).data(DATA_KEY, typeof config === 'string' ? data : config)
125 + }
126 +
127 + if (typeof config === 'string' && /load/.test(config)) {
128 + data[config]()
129 + } else {
130 + data._init($(this))
131 + }
132 + }
133 +}
134 +
135 +/**
136 + * Data API
137 + * ====================================================
138 + */
139 +
140 +$(document).on('click', SELECTOR_DATA_REFRESH, function (event) {
141 + if (event) {
142 + event.preventDefault()
143 + }
144 +
145 + CardRefresh._jQueryInterface.call($(this), 'load')
146 +})
147 +
148 +$(() => {
149 + $(SELECTOR_DATA_REFRESH).each(function () {
150 + CardRefresh._jQueryInterface.call($(this))
151 + })
152 +})
153 +
154 +/**
155 + * jQuery API
156 + * ====================================================
157 + */
158 +
159 +$.fn[NAME] = CardRefresh._jQueryInterface
160 +$.fn[NAME].Constructor = CardRefresh
161 +$.fn[NAME].noConflict = function () {
162 + $.fn[NAME] = JQUERY_NO_CONFLICT
163 + return CardRefresh._jQueryInterface
164 +}
165 +
166 +export default CardRefresh
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE CardWidget.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'CardWidget'
16 +const DATA_KEY = 'lte.cardwidget'
17 +const EVENT_KEY = `.${DATA_KEY}`
18 +const JQUERY_NO_CONFLICT = $.fn[NAME]
19 +
20 +const EVENT_EXPANDED = `expanded${EVENT_KEY}`
21 +const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
22 +const EVENT_MAXIMIZED = `maximized${EVENT_KEY}`
23 +const EVENT_MINIMIZED = `minimized${EVENT_KEY}`
24 +const EVENT_REMOVED = `removed${EVENT_KEY}`
25 +
26 +const CLASS_NAME_CARD = 'card'
27 +const CLASS_NAME_COLLAPSED = 'collapsed-card'
28 +const CLASS_NAME_COLLAPSING = 'collapsing-card'
29 +const CLASS_NAME_EXPANDING = 'expanding-card'
30 +const CLASS_NAME_WAS_COLLAPSED = 'was-collapsed'
31 +const CLASS_NAME_MAXIMIZED = 'maximized-card'
32 +
33 +const SELECTOR_DATA_REMOVE = '[data-card-widget="remove"]'
34 +const SELECTOR_DATA_COLLAPSE = '[data-card-widget="collapse"]'
35 +const SELECTOR_DATA_MAXIMIZE = '[data-card-widget="maximize"]'
36 +const SELECTOR_CARD = `.${CLASS_NAME_CARD}`
37 +const SELECTOR_CARD_HEADER = '.card-header'
38 +const SELECTOR_CARD_BODY = '.card-body'
39 +const SELECTOR_CARD_FOOTER = '.card-footer'
40 +
41 +const Default = {
42 + animationSpeed: 'normal',
43 + collapseTrigger: SELECTOR_DATA_COLLAPSE,
44 + removeTrigger: SELECTOR_DATA_REMOVE,
45 + maximizeTrigger: SELECTOR_DATA_MAXIMIZE,
46 + collapseIcon: 'fa-minus',
47 + expandIcon: 'fa-plus',
48 + maximizeIcon: 'fa-expand',
49 + minimizeIcon: 'fa-compress'
50 +}
51 +
52 +class CardWidget {
53 + constructor(element, settings) {
54 + this._element = element
55 + this._parent = element.parents(SELECTOR_CARD).first()
56 +
57 + if (element.hasClass(CLASS_NAME_CARD)) {
58 + this._parent = element
59 + }
60 +
61 + this._settings = $.extend({}, Default, settings)
62 + }
63 +
64 + collapse() {
65 + this._parent.addClass(CLASS_NAME_COLLAPSING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
66 + .slideUp(this._settings.animationSpeed, () => {
67 + this._parent.addClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_COLLAPSING)
68 + })
69 +
70 + this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.collapseIcon}`)
71 + .addClass(this._settings.expandIcon)
72 + .removeClass(this._settings.collapseIcon)
73 +
74 + this._element.trigger($.Event(EVENT_COLLAPSED), this._parent)
75 + }
76 +
77 + expand() {
78 + this._parent.addClass(CLASS_NAME_EXPANDING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
79 + .slideDown(this._settings.animationSpeed, () => {
80 + this._parent.removeClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_EXPANDING)
81 + })
82 +
83 + this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.expandIcon}`)
84 + .addClass(this._settings.collapseIcon)
85 + .removeClass(this._settings.expandIcon)
86 +
87 + this._element.trigger($.Event(EVENT_EXPANDED), this._parent)
88 + }
89 +
90 + remove() {
91 + this._parent.slideUp()
92 + this._element.trigger($.Event(EVENT_REMOVED), this._parent)
93 + }
94 +
95 + toggle() {
96 + if (this._parent.hasClass(CLASS_NAME_COLLAPSED)) {
97 + this.expand()
98 + return
99 + }
100 +
101 + this.collapse()
102 + }
103 +
104 + maximize() {
105 + this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.maximizeIcon}`)
106 + .addClass(this._settings.minimizeIcon)
107 + .removeClass(this._settings.maximizeIcon)
108 + this._parent.css({
109 + height: this._parent.height(),
110 + width: this._parent.width(),
111 + transition: 'all .15s'
112 + }).delay(150).queue(function () {
113 + const $element = $(this)
114 +
115 + $element.addClass(CLASS_NAME_MAXIMIZED)
116 + $('html').addClass(CLASS_NAME_MAXIMIZED)
117 + if ($element.hasClass(CLASS_NAME_COLLAPSED)) {
118 + $element.addClass(CLASS_NAME_WAS_COLLAPSED)
119 + }
120 +
121 + $element.dequeue()
122 + })
123 +
124 + this._element.trigger($.Event(EVENT_MAXIMIZED), this._parent)
125 + }
126 +
127 + minimize() {
128 + this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.minimizeIcon}`)
129 + .addClass(this._settings.maximizeIcon)
130 + .removeClass(this._settings.minimizeIcon)
131 + this._parent.css('cssText', `height: ${this._parent[0].style.height} !important; width: ${this._parent[0].style.width} !important; transition: all .15s;`
132 + ).delay(10).queue(function () {
133 + const $element = $(this)
134 +
135 + $element.removeClass(CLASS_NAME_MAXIMIZED)
136 + $('html').removeClass(CLASS_NAME_MAXIMIZED)
137 + $element.css({
138 + height: 'inherit',
139 + width: 'inherit'
140 + })
141 + if ($element.hasClass(CLASS_NAME_WAS_COLLAPSED)) {
142 + $element.removeClass(CLASS_NAME_WAS_COLLAPSED)
143 + }
144 +
145 + $element.dequeue()
146 + })
147 +
148 + this._element.trigger($.Event(EVENT_MINIMIZED), this._parent)
149 + }
150 +
151 + toggleMaximize() {
152 + if (this._parent.hasClass(CLASS_NAME_MAXIMIZED)) {
153 + this.minimize()
154 + return
155 + }
156 +
157 + this.maximize()
158 + }
159 +
160 + // Private
161 +
162 + _init(card) {
163 + this._parent = card
164 +
165 + $(this).find(this._settings.collapseTrigger).click(() => {
166 + this.toggle()
167 + })
168 +
169 + $(this).find(this._settings.maximizeTrigger).click(() => {
170 + this.toggleMaximize()
171 + })
172 +
173 + $(this).find(this._settings.removeTrigger).click(() => {
174 + this.remove()
175 + })
176 + }
177 +
178 + // Static
179 +
180 + static _jQueryInterface(config) {
181 + let data = $(this).data(DATA_KEY)
182 + const _options = $.extend({}, Default, $(this).data())
183 +
184 + if (!data) {
185 + data = new CardWidget($(this), _options)
186 + $(this).data(DATA_KEY, typeof config === 'string' ? data : config)
187 + }
188 +
189 + if (typeof config === 'string' && /collapse|expand|remove|toggle|maximize|minimize|toggleMaximize/.test(config)) {
190 + data[config]()
191 + } else if (typeof config === 'object') {
192 + data._init($(this))
193 + }
194 + }
195 +}
196 +
197 +/**
198 + * Data API
199 + * ====================================================
200 + */
201 +
202 +$(document).on('click', SELECTOR_DATA_COLLAPSE, function (event) {
203 + if (event) {
204 + event.preventDefault()
205 + }
206 +
207 + CardWidget._jQueryInterface.call($(this), 'toggle')
208 +})
209 +
210 +$(document).on('click', SELECTOR_DATA_REMOVE, function (event) {
211 + if (event) {
212 + event.preventDefault()
213 + }
214 +
215 + CardWidget._jQueryInterface.call($(this), 'remove')
216 +})
217 +
218 +$(document).on('click', SELECTOR_DATA_MAXIMIZE, function (event) {
219 + if (event) {
220 + event.preventDefault()
221 + }
222 +
223 + CardWidget._jQueryInterface.call($(this), 'toggleMaximize')
224 +})
225 +
226 +/**
227 + * jQuery API
228 + * ====================================================
229 + */
230 +
231 +$.fn[NAME] = CardWidget._jQueryInterface
232 +$.fn[NAME].Constructor = CardWidget
233 +$.fn[NAME].noConflict = function () {
234 + $.fn[NAME] = JQUERY_NO_CONFLICT
235 + return CardWidget._jQueryInterface
236 +}
237 +
238 +export default CardWidget
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE ControlSidebar.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'ControlSidebar'
16 +const DATA_KEY = 'lte.controlsidebar'
17 +const EVENT_KEY = `.${DATA_KEY}`
18 +const JQUERY_NO_CONFLICT = $.fn[NAME]
19 +
20 +const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
21 +const EVENT_EXPANDED = `expanded${EVENT_KEY}`
22 +
23 +const SELECTOR_CONTROL_SIDEBAR = '.control-sidebar'
24 +const SELECTOR_CONTROL_SIDEBAR_CONTENT = '.control-sidebar-content'
25 +const SELECTOR_DATA_TOGGLE = '[data-widget="control-sidebar"]'
26 +const SELECTOR_HEADER = '.main-header'
27 +const SELECTOR_FOOTER = '.main-footer'
28 +
29 +const CLASS_NAME_CONTROL_SIDEBAR_ANIMATE = 'control-sidebar-animate'
30 +const CLASS_NAME_CONTROL_SIDEBAR_OPEN = 'control-sidebar-open'
31 +const CLASS_NAME_CONTROL_SIDEBAR_SLIDE = 'control-sidebar-slide-open'
32 +const CLASS_NAME_LAYOUT_FIXED = 'layout-fixed'
33 +const CLASS_NAME_NAVBAR_FIXED = 'layout-navbar-fixed'
34 +const CLASS_NAME_NAVBAR_SM_FIXED = 'layout-sm-navbar-fixed'
35 +const CLASS_NAME_NAVBAR_MD_FIXED = 'layout-md-navbar-fixed'
36 +const CLASS_NAME_NAVBAR_LG_FIXED = 'layout-lg-navbar-fixed'
37 +const CLASS_NAME_NAVBAR_XL_FIXED = 'layout-xl-navbar-fixed'
38 +const CLASS_NAME_FOOTER_FIXED = 'layout-footer-fixed'
39 +const CLASS_NAME_FOOTER_SM_FIXED = 'layout-sm-footer-fixed'
40 +const CLASS_NAME_FOOTER_MD_FIXED = 'layout-md-footer-fixed'
41 +const CLASS_NAME_FOOTER_LG_FIXED = 'layout-lg-footer-fixed'
42 +const CLASS_NAME_FOOTER_XL_FIXED = 'layout-xl-footer-fixed'
43 +
44 +const Default = {
45 + controlsidebarSlide: true,
46 + scrollbarTheme: 'os-theme-light',
47 + scrollbarAutoHide: 'l',
48 + target: SELECTOR_CONTROL_SIDEBAR
49 +}
50 +
51 +/**
52 + * Class Definition
53 + * ====================================================
54 + */
55 +
56 +class ControlSidebar {
57 + constructor(element, config) {
58 + this._element = element
59 + this._config = config
60 + }
61 +
62 + // Public
63 +
64 + collapse() {
65 + const $body = $('body')
66 + const $html = $('html')
67 + const { target } = this._config
68 +
69 + // Show the control sidebar
70 + if (this._config.controlsidebarSlide) {
71 + $html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
72 + $body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () {
73 + $(target).hide()
74 + $html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
75 + $(this).dequeue()
76 + })
77 + } else {
78 + $body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN)
79 + }
80 +
81 + $(this._element).trigger($.Event(EVENT_COLLAPSED))
82 + }
83 +
84 + show() {
85 + const $body = $('body')
86 + const $html = $('html')
87 +
88 + // Collapse the control sidebar
89 + if (this._config.controlsidebarSlide) {
90 + $html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
91 + $(this._config.target).show().delay(10).queue(function () {
92 + $body.addClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () {
93 + $html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
94 + $(this).dequeue()
95 + })
96 + $(this).dequeue()
97 + })
98 + } else {
99 + $body.addClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN)
100 + }
101 +
102 + this._fixHeight()
103 + this._fixScrollHeight()
104 +
105 + $(this._element).trigger($.Event(EVENT_EXPANDED))
106 + }
107 +
108 + toggle() {
109 + const $body = $('body')
110 + const shouldClose = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
111 + $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE)
112 +
113 + if (shouldClose) {
114 + // Close the control sidebar
115 + this.collapse()
116 + } else {
117 + // Open the control sidebar
118 + this.show()
119 + }
120 + }
121 +
122 + // Private
123 +
124 + _init() {
125 + const $body = $('body')
126 + const shouldNotHideAll = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
127 + $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE)
128 +
129 + if (shouldNotHideAll) {
130 + $(SELECTOR_CONTROL_SIDEBAR).not(this._config.target).hide()
131 + $(this._config.target).css('display', 'block')
132 + } else {
133 + $(SELECTOR_CONTROL_SIDEBAR).hide()
134 + }
135 +
136 + this._fixHeight()
137 + this._fixScrollHeight()
138 +
139 + $(window).resize(() => {
140 + this._fixHeight()
141 + this._fixScrollHeight()
142 + })
143 +
144 + $(window).scroll(() => {
145 + const $body = $('body')
146 + const shouldFixHeight = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
147 + $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE)
148 +
149 + if (shouldFixHeight) {
150 + this._fixScrollHeight()
151 + }
152 + })
153 + }
154 +
155 + _isNavbarFixed() {
156 + const $body = $('body')
157 + return (
158 + $body.hasClass(CLASS_NAME_NAVBAR_FIXED) ||
159 + $body.hasClass(CLASS_NAME_NAVBAR_SM_FIXED) ||
160 + $body.hasClass(CLASS_NAME_NAVBAR_MD_FIXED) ||
161 + $body.hasClass(CLASS_NAME_NAVBAR_LG_FIXED) ||
162 + $body.hasClass(CLASS_NAME_NAVBAR_XL_FIXED)
163 + )
164 + }
165 +
166 + _isFooterFixed() {
167 + const $body = $('body')
168 + return (
169 + $body.hasClass(CLASS_NAME_FOOTER_FIXED) ||
170 + $body.hasClass(CLASS_NAME_FOOTER_SM_FIXED) ||
171 + $body.hasClass(CLASS_NAME_FOOTER_MD_FIXED) ||
172 + $body.hasClass(CLASS_NAME_FOOTER_LG_FIXED) ||
173 + $body.hasClass(CLASS_NAME_FOOTER_XL_FIXED)
174 + )
175 + }
176 +
177 + _fixScrollHeight() {
178 + const $body = $('body')
179 + const $controlSidebar = $(this._config.target)
180 +
181 + if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
182 + return
183 + }
184 +
185 + const heights = {
186 + scroll: $(document).height(),
187 + window: $(window).height(),
188 + header: $(SELECTOR_HEADER).outerHeight(),
189 + footer: $(SELECTOR_FOOTER).outerHeight()
190 + }
191 + const positions = {
192 + bottom: Math.abs((heights.window + $(window).scrollTop()) - heights.scroll),
193 + top: $(window).scrollTop()
194 + }
195 +
196 + const navbarFixed = this._isNavbarFixed() && $(SELECTOR_HEADER).css('position') === 'fixed'
197 +
198 + const footerFixed = this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed'
199 +
200 + const $controlsidebarContent = $(`${this._config.target}, ${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`)
201 +
202 + if (positions.top === 0 && positions.bottom === 0) {
203 + $controlSidebar.css({
204 + bottom: heights.footer,
205 + top: heights.header
206 + })
207 + $controlsidebarContent.css('height', heights.window - (heights.header + heights.footer))
208 + } else if (positions.bottom <= heights.footer) {
209 + if (footerFixed === false) {
210 + const top = heights.header - positions.top
211 + $controlSidebar.css('bottom', heights.footer - positions.bottom).css('top', top >= 0 ? top : 0)
212 + $controlsidebarContent.css('height', heights.window - (heights.footer - positions.bottom))
213 + } else {
214 + $controlSidebar.css('bottom', heights.footer)
215 + }
216 + } else if (positions.top <= heights.header) {
217 + if (navbarFixed === false) {
218 + $controlSidebar.css('top', heights.header - positions.top)
219 + $controlsidebarContent.css('height', heights.window - (heights.header - positions.top))
220 + } else {
221 + $controlSidebar.css('top', heights.header)
222 + }
223 + } else if (navbarFixed === false) {
224 + $controlSidebar.css('top', 0)
225 + $controlsidebarContent.css('height', heights.window)
226 + } else {
227 + $controlSidebar.css('top', heights.header)
228 + }
229 +
230 + if (footerFixed && navbarFixed) {
231 + $controlsidebarContent.css('height', '100%')
232 + $controlSidebar.css('height', '')
233 + } else if (footerFixed || navbarFixed) {
234 + $controlsidebarContent.css('height', '100%')
235 + $controlsidebarContent.css('height', '')
236 + }
237 + }
238 +
239 + _fixHeight() {
240 + const $body = $('body')
241 + const $controlSidebar = $(`${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`)
242 +
243 + if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
244 + $controlSidebar.attr('style', '')
245 + return
246 + }
247 +
248 + const heights = {
249 + window: $(window).height(),
250 + header: $(SELECTOR_HEADER).outerHeight(),
251 + footer: $(SELECTOR_FOOTER).outerHeight()
252 + }
253 +
254 + let sidebarHeight = heights.window - heights.header
255 +
256 + if (this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed') {
257 + sidebarHeight = heights.window - heights.header - heights.footer
258 + }
259 +
260 + $controlSidebar.css('height', sidebarHeight)
261 +
262 + if (typeof $.fn.overlayScrollbars !== 'undefined') {
263 + $controlSidebar.overlayScrollbars({
264 + className: this._config.scrollbarTheme,
265 + sizeAutoCapable: true,
266 + scrollbars: {
267 + autoHide: this._config.scrollbarAutoHide,
268 + clickScrolling: true
269 + }
270 + })
271 + }
272 + }
273 +
274 + // Static
275 +
276 + static _jQueryInterface(operation) {
277 + return this.each(function () {
278 + let data = $(this).data(DATA_KEY)
279 + const _options = $.extend({}, Default, $(this).data())
280 +
281 + if (!data) {
282 + data = new ControlSidebar(this, _options)
283 + $(this).data(DATA_KEY, data)
284 + }
285 +
286 + if (data[operation] === 'undefined') {
287 + throw new Error(`${operation} is not a function`)
288 + }
289 +
290 + data[operation]()
291 + })
292 + }
293 +}
294 +
295 +/**
296 + *
297 + * Data Api implementation
298 + * ====================================================
299 + */
300 +$(document).on('click', SELECTOR_DATA_TOGGLE, function (event) {
301 + event.preventDefault()
302 +
303 + ControlSidebar._jQueryInterface.call($(this), 'toggle')
304 +})
305 +
306 +$(document).ready(() => {
307 + ControlSidebar._jQueryInterface.call($(SELECTOR_DATA_TOGGLE), '_init')
308 +})
309 +
310 +/**
311 + * jQuery API
312 + * ====================================================
313 + */
314 +
315 +$.fn[NAME] = ControlSidebar._jQueryInterface
316 +$.fn[NAME].Constructor = ControlSidebar
317 +$.fn[NAME].noConflict = function () {
318 + $.fn[NAME] = JQUERY_NO_CONFLICT
319 + return ControlSidebar._jQueryInterface
320 +}
321 +
322 +export default ControlSidebar
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE DirectChat.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'DirectChat'
16 +const DATA_KEY = 'lte.directchat'
17 +const EVENT_KEY = `.${DATA_KEY}`
18 +const JQUERY_NO_CONFLICT = $.fn[NAME]
19 +
20 +const EVENT_TOGGLED = `toggled${EVENT_KEY}`
21 +
22 +const SELECTOR_DATA_TOGGLE = '[data-widget="chat-pane-toggle"]'
23 +const SELECTOR_DIRECT_CHAT = '.direct-chat'
24 +
25 +const CLASS_NAME_DIRECT_CHAT_OPEN = 'direct-chat-contacts-open'
26 +
27 +/**
28 + * Class Definition
29 + * ====================================================
30 + */
31 +
32 +class DirectChat {
33 + constructor(element) {
34 + this._element = element
35 + }
36 +
37 + toggle() {
38 + $(this._element).parents(SELECTOR_DIRECT_CHAT).first().toggleClass(CLASS_NAME_DIRECT_CHAT_OPEN)
39 + $(this._element).trigger($.Event(EVENT_TOGGLED))
40 + }
41 +
42 + // Static
43 +
44 + static _jQueryInterface(config) {
45 + return this.each(function () {
46 + let data = $(this).data(DATA_KEY)
47 +
48 + if (!data) {
49 + data = new DirectChat($(this))
50 + $(this).data(DATA_KEY, data)
51 + }
52 +
53 + data[config]()
54 + })
55 + }
56 +}
57 +
58 +/**
59 + *
60 + * Data Api implementation
61 + * ====================================================
62 + */
63 +
64 +$(document).on('click', SELECTOR_DATA_TOGGLE, function (event) {
65 + if (event) {
66 + event.preventDefault()
67 + }
68 +
69 + DirectChat._jQueryInterface.call($(this), 'toggle')
70 +})
71 +
72 +/**
73 + * jQuery API
74 + * ====================================================
75 + */
76 +
77 +$.fn[NAME] = DirectChat._jQueryInterface
78 +$.fn[NAME].Constructor = DirectChat
79 +$.fn[NAME].noConflict = function () {
80 + $.fn[NAME] = JQUERY_NO_CONFLICT
81 + return DirectChat._jQueryInterface
82 +}
83 +
84 +export default DirectChat
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE Dropdown.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'Dropdown'
16 +const DATA_KEY = 'lte.dropdown'
17 +const JQUERY_NO_CONFLICT = $.fn[NAME]
18 +
19 +const SELECTOR_NAVBAR = '.navbar'
20 +const SELECTOR_DROPDOWN_MENU = '.dropdown-menu'
21 +const SELECTOR_DROPDOWN_MENU_ACTIVE = '.dropdown-menu.show'
22 +const SELECTOR_DROPDOWN_TOGGLE = '[data-toggle="dropdown"]'
23 +
24 +const CLASS_NAME_DROPDOWN_RIGHT = 'dropdown-menu-right'
25 +const CLASS_NAME_DROPDOWN_SUBMENU = 'dropdown-submenu'
26 +
27 +// TODO: this is unused; should be removed along with the extend?
28 +const Default = {}
29 +
30 +/**
31 + * Class Definition
32 + * ====================================================
33 + */
34 +
35 +class Dropdown {
36 + constructor(element, config) {
37 + this._config = config
38 + this._element = element
39 + }
40 +
41 + // Public
42 +
43 + toggleSubmenu() {
44 + this._element.siblings().show().toggleClass('show')
45 +
46 + if (!this._element.next().hasClass('show')) {
47 + this._element.parents(SELECTOR_DROPDOWN_MENU).first().find('.show').removeClass('show').hide()
48 + }
49 +
50 + this._element.parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', () => {
51 + $('.dropdown-submenu .show').removeClass('show').hide()
52 + })
53 + }
54 +
55 + fixPosition() {
56 + const $element = $(SELECTOR_DROPDOWN_MENU_ACTIVE)
57 +
58 + if ($element.length === 0) {
59 + return
60 + }
61 +
62 + if ($element.hasClass(CLASS_NAME_DROPDOWN_RIGHT)) {
63 + $element.css({
64 + left: 'inherit',
65 + right: 0
66 + })
67 + } else {
68 + $element.css({
69 + left: 0,
70 + right: 'inherit'
71 + })
72 + }
73 +
74 + const offset = $element.offset()
75 + const width = $element.width()
76 + const visiblePart = $(window).width() - offset.left
77 +
78 + if (offset.left < 0) {
79 + $element.css({
80 + left: 'inherit',
81 + right: offset.left - 5
82 + })
83 + } else if (visiblePart < width) {
84 + $element.css({
85 + left: 'inherit',
86 + right: 0
87 + })
88 + }
89 + }
90 +
91 + // Static
92 +
93 + static _jQueryInterface(config) {
94 + return this.each(function () {
95 + let data = $(this).data(DATA_KEY)
96 + const _config = $.extend({}, Default, $(this).data())
97 +
98 + if (!data) {
99 + data = new Dropdown($(this), _config)
100 + $(this).data(DATA_KEY, data)
101 + }
102 +
103 + if (config === 'toggleSubmenu' || config === 'fixPosition') {
104 + data[config]()
105 + }
106 + })
107 + }
108 +}
109 +
110 +/**
111 + * Data API
112 + * ====================================================
113 + */
114 +
115 +$(`${SELECTOR_DROPDOWN_MENU} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', function (event) {
116 + event.preventDefault()
117 + event.stopPropagation()
118 +
119 + Dropdown._jQueryInterface.call($(this), 'toggleSubmenu')
120 +})
121 +
122 +$(`${SELECTOR_NAVBAR} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', event => {
123 + event.preventDefault()
124 +
125 + if ($(event.target).parent().hasClass(CLASS_NAME_DROPDOWN_SUBMENU)) {
126 + return
127 + }
128 +
129 + setTimeout(function () {
130 + Dropdown._jQueryInterface.call($(this), 'fixPosition')
131 + }, 1)
132 +})
133 +
134 +/**
135 + * jQuery API
136 + * ====================================================
137 + */
138 +
139 +$.fn[NAME] = Dropdown._jQueryInterface
140 +$.fn[NAME].Constructor = Dropdown
141 +$.fn[NAME].noConflict = function () {
142 + $.fn[NAME] = JQUERY_NO_CONFLICT
143 + return Dropdown._jQueryInterface
144 +}
145 +
146 +export default Dropdown
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE ExpandableTable.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'ExpandableTable'
16 +const DATA_KEY = 'lte.expandableTable'
17 +const EVENT_KEY = `.${DATA_KEY}`
18 +const JQUERY_NO_CONFLICT = $.fn[NAME]
19 +
20 +const EVENT_EXPANDED = `expanded${EVENT_KEY}`
21 +const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
22 +
23 +const SELECTOR_TABLE = '.expandable-table'
24 +const SELECTOR_EXPANDABLE_BODY = '.expandable-body'
25 +const SELECTOR_DATA_TOGGLE = '[data-widget="expandable-table"]'
26 +const SELECTOR_ARIA_ATTR = 'aria-expanded'
27 +
28 +/**
29 + * Class Definition
30 + * ====================================================
31 + */
32 +class ExpandableTable {
33 + constructor(element, options) {
34 + this._options = options
35 + this._element = element
36 + }
37 +
38 + // Public
39 +
40 + init() {
41 + $(SELECTOR_DATA_TOGGLE).each((_, $header) => {
42 + const $type = $($header).attr(SELECTOR_ARIA_ATTR)
43 + const $body = $($header).next(SELECTOR_EXPANDABLE_BODY).children().first().children()
44 + if ($type === 'true') {
45 + $body.show()
46 + } else if ($type === 'false') {
47 + $body.hide()
48 + $body.parent().parent().addClass('d-none')
49 + }
50 + })
51 + }
52 +
53 + toggleRow() {
54 + const $element = this._element
55 + const time = 500
56 + const $type = $element.attr(SELECTOR_ARIA_ATTR)
57 + const $body = $element.next(SELECTOR_EXPANDABLE_BODY).children().first().children()
58 +
59 + $body.stop()
60 + if ($type === 'true') {
61 + $body.slideUp(time, () => {
62 + $element.next(SELECTOR_EXPANDABLE_BODY).addClass('d-none')
63 + })
64 + $element.attr(SELECTOR_ARIA_ATTR, 'false')
65 + $element.trigger($.Event(EVENT_COLLAPSED))
66 + } else if ($type === 'false') {
67 + $element.next(SELECTOR_EXPANDABLE_BODY).removeClass('d-none')
68 + $body.slideDown(time)
69 + $element.attr(SELECTOR_ARIA_ATTR, 'true')
70 + $element.trigger($.Event(EVENT_EXPANDED))
71 + }
72 + }
73 +
74 + // Static
75 +
76 + static _jQueryInterface(operation) {
77 + return this.each(function () {
78 + let data = $(this).data(DATA_KEY)
79 +
80 + if (!data) {
81 + data = new ExpandableTable($(this))
82 + $(this).data(DATA_KEY, data)
83 + }
84 +
85 + if (typeof operation === 'string' && /init|toggleRow/.test(operation)) {
86 + data[operation]()
87 + }
88 + })
89 + }
90 +}
91 +
92 +/**
93 + * Data API
94 + * ====================================================
95 + */
96 +$(SELECTOR_TABLE).ready(function () {
97 + ExpandableTable._jQueryInterface.call($(this), 'init')
98 +})
99 +
100 +$(document).on('click', SELECTOR_DATA_TOGGLE, function () {
101 + ExpandableTable._jQueryInterface.call($(this), 'toggleRow')
102 +})
103 +
104 +/**
105 + * jQuery API
106 + * ====================================================
107 + */
108 +
109 +$.fn[NAME] = ExpandableTable._jQueryInterface
110 +$.fn[NAME].Constructor = ExpandableTable
111 +$.fn[NAME].noConflict = function () {
112 + $.fn[NAME] = JQUERY_NO_CONFLICT
113 + return ExpandableTable._jQueryInterface
114 +}
115 +
116 +export default ExpandableTable
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE Fullscreen.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'Fullscreen'
16 +const DATA_KEY = 'lte.fullscreen'
17 +const JQUERY_NO_CONFLICT = $.fn[NAME]
18 +
19 +const SELECTOR_DATA_WIDGET = '[data-widget="fullscreen"]'
20 +const SELECTOR_ICON = `${SELECTOR_DATA_WIDGET} i`
21 +
22 +const EVENT_FULLSCREEN_CHANGE = 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange'
23 +
24 +const Default = {
25 + minimizeIcon: 'fa-compress-arrows-alt',
26 + maximizeIcon: 'fa-expand-arrows-alt'
27 +}
28 +
29 +/**
30 + * Class Definition
31 + * ====================================================
32 + */
33 +
34 +class Fullscreen {
35 + constructor(_element, _options) {
36 + this.element = _element
37 + this.options = $.extend({}, Default, _options)
38 + }
39 +
40 + // Public
41 +
42 + toggle() {
43 + if (document.fullscreenElement ||
44 + document.mozFullScreenElement ||
45 + document.webkitFullscreenElement ||
46 + document.msFullscreenElement) {
47 + this.windowed()
48 + } else {
49 + this.fullscreen()
50 + }
51 + }
52 +
53 + toggleIcon() {
54 + if (document.fullscreenElement ||
55 + document.mozFullScreenElement ||
56 + document.webkitFullscreenElement ||
57 + document.msFullscreenElement) {
58 + $(SELECTOR_ICON).removeClass(this.options.maximizeIcon).addClass(this.options.minimizeIcon)
59 + } else {
60 + $(SELECTOR_ICON).removeClass(this.options.minimizeIcon).addClass(this.options.maximizeIcon)
61 + }
62 + }
63 +
64 + fullscreen() {
65 + if (document.documentElement.requestFullscreen) {
66 + document.documentElement.requestFullscreen()
67 + } else if (document.documentElement.webkitRequestFullscreen) {
68 + document.documentElement.webkitRequestFullscreen()
69 + } else if (document.documentElement.msRequestFullscreen) {
70 + document.documentElement.msRequestFullscreen()
71 + }
72 + }
73 +
74 + windowed() {
75 + if (document.exitFullscreen) {
76 + document.exitFullscreen()
77 + } else if (document.webkitExitFullscreen) {
78 + document.webkitExitFullscreen()
79 + } else if (document.msExitFullscreen) {
80 + document.msExitFullscreen()
81 + }
82 + }
83 +
84 + // Static
85 +
86 + static _jQueryInterface(config) {
87 + let data = $(this).data(DATA_KEY)
88 +
89 + if (!data) {
90 + data = $(this).data()
91 + }
92 +
93 + const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
94 + const plugin = new Fullscreen($(this), _options)
95 +
96 + $(this).data(DATA_KEY, typeof config === 'object' ? config : data)
97 +
98 + if (typeof config === 'string' && /toggle|toggleIcon|fullscreen|windowed/.test(config)) {
99 + plugin[config]()
100 + } else {
101 + plugin.init()
102 + }
103 + }
104 +}
105 +
106 +/**
107 + * Data API
108 + * ====================================================
109 + */
110 +$(document).on('click', SELECTOR_DATA_WIDGET, function () {
111 + Fullscreen._jQueryInterface.call($(this), 'toggle')
112 +})
113 +
114 +$(document).on(EVENT_FULLSCREEN_CHANGE, () => {
115 + Fullscreen._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'toggleIcon')
116 +})
117 +
118 +/**
119 + * jQuery API
120 + * ====================================================
121 + */
122 +
123 +$.fn[NAME] = Fullscreen._jQueryInterface
124 +$.fn[NAME].Constructor = Fullscreen
125 +$.fn[NAME].noConflict = function () {
126 + $.fn[NAME] = JQUERY_NO_CONFLICT
127 + return Fullscreen._jQueryInterface
128 +}
129 +
130 +export default Fullscreen
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE Layout.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'Layout'
16 +const DATA_KEY = 'lte.layout'
17 +const JQUERY_NO_CONFLICT = $.fn[NAME]
18 +
19 +const SELECTOR_HEADER = '.main-header'
20 +const SELECTOR_MAIN_SIDEBAR = '.main-sidebar'
21 +const SELECTOR_SIDEBAR = '.main-sidebar .sidebar'
22 +const SELECTOR_CONTENT = '.content-wrapper'
23 +const SELECTOR_CONTROL_SIDEBAR_CONTENT = '.control-sidebar-content'
24 +const SELECTOR_CONTROL_SIDEBAR_BTN = '[data-widget="control-sidebar"]'
25 +const SELECTOR_FOOTER = '.main-footer'
26 +const SELECTOR_PUSHMENU_BTN = '[data-widget="pushmenu"]'
27 +const SELECTOR_LOGIN_BOX = '.login-box'
28 +const SELECTOR_REGISTER_BOX = '.register-box'
29 +const SELECTOR_PRELOADER = '.preloader'
30 +
31 +const CLASS_NAME_SIDEBAR_COLLAPSED = 'sidebar-collapse'
32 +const CLASS_NAME_SIDEBAR_FOCUSED = 'sidebar-focused'
33 +const CLASS_NAME_LAYOUT_FIXED = 'layout-fixed'
34 +const CLASS_NAME_CONTROL_SIDEBAR_SLIDE_OPEN = 'control-sidebar-slide-open'
35 +const CLASS_NAME_CONTROL_SIDEBAR_OPEN = 'control-sidebar-open'
36 +const CLASS_NAME_IFRAME_MODE = 'iframe-mode'
37 +
38 +const Default = {
39 + scrollbarTheme: 'os-theme-light',
40 + scrollbarAutoHide: 'l',
41 + panelAutoHeight: true,
42 + panelAutoHeightMode: 'min-height',
43 + preloadDuration: 200,
44 + loginRegisterAutoHeight: true
45 +}
46 +
47 +/**
48 + * Class Definition
49 + * ====================================================
50 + */
51 +
52 +class Layout {
53 + constructor(element, config) {
54 + this._config = config
55 + this._element = element
56 + }
57 +
58 + // Public
59 +
60 + fixLayoutHeight(extra = null) {
61 + const $body = $('body')
62 + let controlSidebar = 0
63 +
64 + if ($body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE_OPEN) || $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || extra === 'control_sidebar') {
65 + controlSidebar = $(SELECTOR_CONTROL_SIDEBAR_CONTENT).outerHeight()
66 + }
67 +
68 + const heights = {
69 + window: $(window).height(),
70 + header: $(SELECTOR_HEADER).length > 0 ? $(SELECTOR_HEADER).outerHeight() : 0,
71 + footer: $(SELECTOR_FOOTER).length > 0 ? $(SELECTOR_FOOTER).outerHeight() : 0,
72 + sidebar: $(SELECTOR_SIDEBAR).length > 0 ? $(SELECTOR_SIDEBAR).height() : 0,
73 + controlSidebar
74 + }
75 +
76 + const max = this._max(heights)
77 + let offset = this._config.panelAutoHeight
78 +
79 + if (offset === true) {
80 + offset = 0
81 + }
82 +
83 + const $contentSelector = $(SELECTOR_CONTENT)
84 +
85 + if (offset !== false) {
86 + if (max === heights.controlSidebar) {
87 + $contentSelector.css(this._config.panelAutoHeightMode, (max + offset))
88 + } else if (max === heights.window) {
89 + $contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header - heights.footer)
90 + } else {
91 + $contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header)
92 + }
93 +
94 + if (this._isFooterFixed()) {
95 + $contentSelector.css(this._config.panelAutoHeightMode, parseFloat($contentSelector.css(this._config.panelAutoHeightMode)) + heights.footer)
96 + }
97 + }
98 +
99 + if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
100 + return
101 + }
102 +
103 + if (typeof $.fn.overlayScrollbars !== 'undefined') {
104 + $(SELECTOR_SIDEBAR).overlayScrollbars({
105 + className: this._config.scrollbarTheme,
106 + sizeAutoCapable: true,
107 + scrollbars: {
108 + autoHide: this._config.scrollbarAutoHide,
109 + clickScrolling: true
110 + }
111 + })
112 + } else {
113 + $(SELECTOR_SIDEBAR).css('overflow-y', 'auto')
114 + }
115 + }
116 +
117 + fixLoginRegisterHeight() {
118 + const $body = $('body')
119 + const $selector = $(`${SELECTOR_LOGIN_BOX}, ${SELECTOR_REGISTER_BOX}`)
120 +
121 + if ($body.hasClass(CLASS_NAME_IFRAME_MODE)) {
122 + $body.css('height', '100%')
123 + $('.wrapper').css('height', '100%')
124 + $('html').css('height', '100%')
125 + } else if ($selector.length === 0) {
126 + $body.css('height', 'auto')
127 + $('html').css('height', 'auto')
128 + } else {
129 + const boxHeight = $selector.height()
130 +
131 + if ($body.css(this._config.panelAutoHeightMode) !== boxHeight) {
132 + $body.css(this._config.panelAutoHeightMode, boxHeight)
133 + }
134 + }
135 + }
136 +
137 + // Private
138 +
139 + _init() {
140 + // Activate layout height watcher
141 + this.fixLayoutHeight()
142 +
143 + if (this._config.loginRegisterAutoHeight === true) {
144 + this.fixLoginRegisterHeight()
145 + } else if (this._config.loginRegisterAutoHeight === parseInt(this._config.loginRegisterAutoHeight, 10)) {
146 + setInterval(this.fixLoginRegisterHeight, this._config.loginRegisterAutoHeight)
147 + }
148 +
149 + $(SELECTOR_SIDEBAR)
150 + .on('collapsed.lte.treeview expanded.lte.treeview', () => {
151 + this.fixLayoutHeight()
152 + })
153 +
154 + $(SELECTOR_MAIN_SIDEBAR)
155 + .on('mouseenter mouseleave', () => {
156 + if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) {
157 + this.fixLayoutHeight()
158 + }
159 + })
160 +
161 + $(SELECTOR_PUSHMENU_BTN)
162 + .on('collapsed.lte.pushmenu shown.lte.pushmenu', () => {
163 + setTimeout(() => {
164 + this.fixLayoutHeight()
165 + }, 300)
166 + })
167 +
168 + $(SELECTOR_CONTROL_SIDEBAR_BTN)
169 + .on('collapsed.lte.controlsidebar', () => {
170 + this.fixLayoutHeight()
171 + })
172 + .on('expanded.lte.controlsidebar', () => {
173 + this.fixLayoutHeight('control_sidebar')
174 + })
175 +
176 + $(window).resize(() => {
177 + this.fixLayoutHeight()
178 + })
179 +
180 + setTimeout(() => {
181 + $('body.hold-transition').removeClass('hold-transition')
182 + }, 50)
183 +
184 + setTimeout(() => {
185 + const $preloader = $(SELECTOR_PRELOADER)
186 + if ($preloader) {
187 + $preloader.css('height', 0)
188 + setTimeout(() => {
189 + $preloader.children().hide()
190 + }, 200)
191 + }
192 + }, this._config.preloadDuration)
193 + }
194 +
195 + _max(numbers) {
196 + // Calculate the maximum number in a list
197 + let max = 0
198 +
199 + Object.keys(numbers).forEach(key => {
200 + if (numbers[key] > max) {
201 + max = numbers[key]
202 + }
203 + })
204 +
205 + return max
206 + }
207 +
208 + _isFooterFixed() {
209 + return $(SELECTOR_FOOTER).css('position') === 'fixed'
210 + }
211 +
212 + // Static
213 +
214 + static _jQueryInterface(config = '') {
215 + return this.each(function () {
216 + let data = $(this).data(DATA_KEY)
217 + const _options = $.extend({}, Default, $(this).data())
218 +
219 + if (!data) {
220 + data = new Layout($(this), _options)
221 + $(this).data(DATA_KEY, data)
222 + }
223 +
224 + if (config === 'init' || config === '') {
225 + data._init()
226 + } else if (config === 'fixLayoutHeight' || config === 'fixLoginRegisterHeight') {
227 + data[config]()
228 + }
229 + })
230 + }
231 +}
232 +
233 +/**
234 + * Data API
235 + * ====================================================
236 + */
237 +
238 +$(window).on('load', () => {
239 + Layout._jQueryInterface.call($('body'))
240 +})
241 +
242 +$(`${SELECTOR_SIDEBAR} a`)
243 + .on('focusin', () => {
244 + $(SELECTOR_MAIN_SIDEBAR).addClass(CLASS_NAME_SIDEBAR_FOCUSED)
245 + })
246 + .on('focusout', () => {
247 + $(SELECTOR_MAIN_SIDEBAR).removeClass(CLASS_NAME_SIDEBAR_FOCUSED)
248 + })
249 +
250 +/**
251 + * jQuery API
252 + * ====================================================
253 + */
254 +
255 +$.fn[NAME] = Layout._jQueryInterface
256 +$.fn[NAME].Constructor = Layout
257 +$.fn[NAME].noConflict = function () {
258 + $.fn[NAME] = JQUERY_NO_CONFLICT
259 + return Layout._jQueryInterface
260 +}
261 +
262 +export default Layout
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE NavbarSearch.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'NavbarSearch'
16 +const DATA_KEY = 'lte.navbar-search'
17 +const JQUERY_NO_CONFLICT = $.fn[NAME]
18 +
19 +const SELECTOR_TOGGLE_BUTTON = '[data-widget="navbar-search"]'
20 +const SELECTOR_SEARCH_BLOCK = '.navbar-search-block'
21 +const SELECTOR_SEARCH_INPUT = '.form-control'
22 +
23 +const CLASS_NAME_OPEN = 'navbar-search-open'
24 +
25 +const Default = {
26 + resetOnClose: true,
27 + target: SELECTOR_SEARCH_BLOCK
28 +}
29 +
30 +/**
31 + * Class Definition
32 + * ====================================================
33 + */
34 +
35 +class NavbarSearch {
36 + constructor(_element, _options) {
37 + this._element = _element
38 + this._config = $.extend({}, Default, _options)
39 + }
40 +
41 + // Public
42 +
43 + open() {
44 + $(this._config.target).css('display', 'flex').hide().fadeIn().addClass(CLASS_NAME_OPEN)
45 + $(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).focus()
46 + }
47 +
48 + close() {
49 + $(this._config.target).fadeOut().removeClass(CLASS_NAME_OPEN)
50 +
51 + if (this._config.resetOnClose) {
52 + $(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).val('')
53 + }
54 + }
55 +
56 + toggle() {
57 + if ($(this._config.target).hasClass(CLASS_NAME_OPEN)) {
58 + this.close()
59 + } else {
60 + this.open()
61 + }
62 + }
63 +
64 + // Static
65 +
66 + static _jQueryInterface(options) {
67 + return this.each(function () {
68 + let data = $(this).data(DATA_KEY)
69 + const _options = $.extend({}, Default, $(this).data())
70 +
71 + if (!data) {
72 + data = new NavbarSearch(this, _options)
73 + $(this).data(DATA_KEY, data)
74 + }
75 +
76 + if (!/toggle|close|open/.test(options)) {
77 + throw new Error(`Undefined method ${options}`)
78 + }
79 +
80 + data[options]()
81 + })
82 + }
83 +}
84 +
85 +/**
86 + * Data API
87 + * ====================================================
88 + */
89 +$(document).on('click', SELECTOR_TOGGLE_BUTTON, event => {
90 + event.preventDefault()
91 +
92 + let button = $(event.currentTarget)
93 +
94 + if (button.data('widget') !== 'navbar-search') {
95 + button = button.closest(SELECTOR_TOGGLE_BUTTON)
96 + }
97 +
98 + NavbarSearch._jQueryInterface.call(button, 'toggle')
99 +})
100 +
101 +/**
102 + * jQuery API
103 + * ====================================================
104 + */
105 +
106 +$.fn[NAME] = NavbarSearch._jQueryInterface
107 +$.fn[NAME].Constructor = NavbarSearch
108 +$.fn[NAME].noConflict = function () {
109 + $.fn[NAME] = JQUERY_NO_CONFLICT
110 + return NavbarSearch._jQueryInterface
111 +}
112 +
113 +export default NavbarSearch
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE PushMenu.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'PushMenu'
16 +const DATA_KEY = 'lte.pushmenu'
17 +const EVENT_KEY = `.${DATA_KEY}`
18 +const JQUERY_NO_CONFLICT = $.fn[NAME]
19 +
20 +const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
21 +const EVENT_SHOWN = `shown${EVENT_KEY}`
22 +
23 +const SELECTOR_TOGGLE_BUTTON = '[data-widget="pushmenu"]'
24 +const SELECTOR_BODY = 'body'
25 +const SELECTOR_OVERLAY = '#sidebar-overlay'
26 +const SELECTOR_WRAPPER = '.wrapper'
27 +
28 +const CLASS_NAME_COLLAPSED = 'sidebar-collapse'
29 +const CLASS_NAME_OPEN = 'sidebar-open'
30 +const CLASS_NAME_IS_OPENING = 'sidebar-is-opening'
31 +const CLASS_NAME_CLOSED = 'sidebar-closed'
32 +
33 +const Default = {
34 + autoCollapseSize: 992,
35 + enableRemember: false,
36 + noTransitionAfterReload: true
37 +}
38 +
39 +/**
40 + * Class Definition
41 + * ====================================================
42 + */
43 +
44 +class PushMenu {
45 + constructor(element, options) {
46 + this._element = element
47 + this._options = $.extend({}, Default, options)
48 +
49 + if ($(SELECTOR_OVERLAY).length === 0) {
50 + this._addOverlay()
51 + }
52 +
53 + this._init()
54 + }
55 +
56 + // Public
57 +
58 + expand() {
59 + const $bodySelector = $(SELECTOR_BODY)
60 +
61 + if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) {
62 + $bodySelector.addClass(CLASS_NAME_OPEN)
63 + }
64 +
65 + $bodySelector.addClass(CLASS_NAME_IS_OPENING).removeClass(`${CLASS_NAME_COLLAPSED} ${CLASS_NAME_CLOSED}`).delay(50).queue(function () {
66 + $bodySelector.removeClass(CLASS_NAME_IS_OPENING)
67 + $(this).dequeue()
68 + })
69 +
70 + if (this._options.enableRemember) {
71 + localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_OPEN)
72 + }
73 +
74 + $(this._element).trigger($.Event(EVENT_SHOWN))
75 + }
76 +
77 + collapse() {
78 + const $bodySelector = $(SELECTOR_BODY)
79 +
80 + if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) {
81 + $bodySelector.removeClass(CLASS_NAME_OPEN).addClass(CLASS_NAME_CLOSED)
82 + }
83 +
84 + $bodySelector.addClass(CLASS_NAME_COLLAPSED)
85 +
86 + if (this._options.enableRemember) {
87 + localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_COLLAPSED)
88 + }
89 +
90 + $(this._element).trigger($.Event(EVENT_COLLAPSED))
91 + }
92 +
93 + toggle() {
94 + if ($(SELECTOR_BODY).hasClass(CLASS_NAME_COLLAPSED)) {
95 + this.expand()
96 + } else {
97 + this.collapse()
98 + }
99 + }
100 +
101 + autoCollapse(resize = false) {
102 + if (!this._options.autoCollapseSize) {
103 + return
104 + }
105 +
106 + const $bodySelector = $(SELECTOR_BODY)
107 +
108 + if ($(window).width() <= this._options.autoCollapseSize) {
109 + if (!$bodySelector.hasClass(CLASS_NAME_OPEN)) {
110 + this.collapse()
111 + }
112 + } else if (resize === true) {
113 + if ($bodySelector.hasClass(CLASS_NAME_OPEN)) {
114 + $bodySelector.removeClass(CLASS_NAME_OPEN)
115 + } else if ($bodySelector.hasClass(CLASS_NAME_CLOSED)) {
116 + this.expand()
117 + }
118 + }
119 + }
120 +
121 + remember() {
122 + if (!this._options.enableRemember) {
123 + return
124 + }
125 +
126 + const $body = $('body')
127 + const toggleState = localStorage.getItem(`remember${EVENT_KEY}`)
128 +
129 + if (toggleState === CLASS_NAME_COLLAPSED) {
130 + if (this._options.noTransitionAfterReload) {
131 + $body.addClass('hold-transition').addClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () {
132 + $(this).removeClass('hold-transition')
133 + $(this).dequeue()
134 + })
135 + } else {
136 + $body.addClass(CLASS_NAME_COLLAPSED)
137 + }
138 + } else if (this._options.noTransitionAfterReload) {
139 + $body.addClass('hold-transition').removeClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () {
140 + $(this).removeClass('hold-transition')
141 + $(this).dequeue()
142 + })
143 + } else {
144 + $body.removeClass(CLASS_NAME_COLLAPSED)
145 + }
146 + }
147 +
148 + // Private
149 +
150 + _init() {
151 + this.remember()
152 + this.autoCollapse()
153 +
154 + $(window).resize(() => {
155 + this.autoCollapse(true)
156 + })
157 + }
158 +
159 + _addOverlay() {
160 + const overlay = $('<div />', {
161 + id: 'sidebar-overlay'
162 + })
163 +
164 + overlay.on('click', () => {
165 + this.collapse()
166 + })
167 +
168 + $(SELECTOR_WRAPPER).append(overlay)
169 + }
170 +
171 + // Static
172 +
173 + static _jQueryInterface(operation) {
174 + return this.each(function () {
175 + let data = $(this).data(DATA_KEY)
176 + const _options = $.extend({}, Default, $(this).data())
177 +
178 + if (!data) {
179 + data = new PushMenu(this, _options)
180 + $(this).data(DATA_KEY, data)
181 + }
182 +
183 + if (typeof operation === 'string' && /collapse|expand|toggle/.test(operation)) {
184 + data[operation]()
185 + }
186 + })
187 + }
188 +}
189 +
190 +/**
191 + * Data API
192 + * ====================================================
193 + */
194 +
195 +$(document).on('click', SELECTOR_TOGGLE_BUTTON, event => {
196 + event.preventDefault()
197 +
198 + let button = event.currentTarget
199 +
200 + if ($(button).data('widget') !== 'pushmenu') {
201 + button = $(button).closest(SELECTOR_TOGGLE_BUTTON)
202 + }
203 +
204 + PushMenu._jQueryInterface.call($(button), 'toggle')
205 +})
206 +
207 +$(window).on('load', () => {
208 + PushMenu._jQueryInterface.call($(SELECTOR_TOGGLE_BUTTON))
209 +})
210 +
211 +/**
212 + * jQuery API
213 + * ====================================================
214 + */
215 +
216 +$.fn[NAME] = PushMenu._jQueryInterface
217 +$.fn[NAME].Constructor = PushMenu
218 +$.fn[NAME].noConflict = function () {
219 + $.fn[NAME] = JQUERY_NO_CONFLICT
220 + return PushMenu._jQueryInterface
221 +}
222 +
223 +export default PushMenu
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE SidebarSearch.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $, { trim } from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'SidebarSearch'
16 +const DATA_KEY = 'lte.sidebar-search'
17 +const JQUERY_NO_CONFLICT = $.fn[NAME]
18 +
19 +const CLASS_NAME_OPEN = 'sidebar-search-open'
20 +const CLASS_NAME_ICON_SEARCH = 'fa-search'
21 +const CLASS_NAME_ICON_CLOSE = 'fa-times'
22 +const CLASS_NAME_HEADER = 'nav-header'
23 +const CLASS_NAME_SEARCH_RESULTS = 'sidebar-search-results'
24 +const CLASS_NAME_LIST_GROUP = 'list-group'
25 +
26 +const SELECTOR_DATA_WIDGET = '[data-widget="sidebar-search"]'
27 +const SELECTOR_SIDEBAR = '.main-sidebar .nav-sidebar'
28 +const SELECTOR_NAV_LINK = '.nav-link'
29 +const SELECTOR_NAV_TREEVIEW = '.nav-treeview'
30 +const SELECTOR_SEARCH_INPUT = `${SELECTOR_DATA_WIDGET} .form-control`
31 +const SELECTOR_SEARCH_BUTTON = `${SELECTOR_DATA_WIDGET} .btn`
32 +const SELECTOR_SEARCH_ICON = `${SELECTOR_SEARCH_BUTTON} i`
33 +const SELECTOR_SEARCH_LIST_GROUP = `.${CLASS_NAME_LIST_GROUP}`
34 +const SELECTOR_SEARCH_RESULTS = `.${CLASS_NAME_SEARCH_RESULTS}`
35 +const SELECTOR_SEARCH_RESULTS_GROUP = `${SELECTOR_SEARCH_RESULTS} .${CLASS_NAME_LIST_GROUP}`
36 +
37 +const Default = {
38 + arrowSign: '->',
39 + minLength: 3,
40 + maxResults: 7,
41 + highlightName: true,
42 + highlightPath: false,
43 + highlightClass: 'text-light',
44 + notFoundText: 'No element found!'
45 +}
46 +
47 +const SearchItems = []
48 +
49 +/**
50 + * Class Definition
51 + * ====================================================
52 + */
53 +
54 +class SidebarSearch {
55 + constructor(_element, _options) {
56 + this.element = _element
57 + this.options = $.extend({}, Default, _options)
58 + this.items = []
59 + }
60 +
61 + // Public
62 +
63 + init() {
64 + if ($(SELECTOR_DATA_WIDGET).length === 0) {
65 + return
66 + }
67 +
68 + if ($(SELECTOR_DATA_WIDGET).next(SELECTOR_SEARCH_RESULTS).length === 0) {
69 + $(SELECTOR_DATA_WIDGET).after(
70 + $('<div />', { class: CLASS_NAME_SEARCH_RESULTS })
71 + )
72 + }
73 +
74 + if ($(SELECTOR_SEARCH_RESULTS).children(SELECTOR_SEARCH_LIST_GROUP).length === 0) {
75 + $(SELECTOR_SEARCH_RESULTS).append(
76 + $('<div />', { class: CLASS_NAME_LIST_GROUP })
77 + )
78 + }
79 +
80 + this._addNotFound()
81 +
82 + $(SELECTOR_SIDEBAR).children().each((i, child) => {
83 + this._parseItem(child)
84 + })
85 + }
86 +
87 + search() {
88 + const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase()
89 + if (searchValue.length < this.options.minLength) {
90 + $(SELECTOR_SEARCH_RESULTS_GROUP).empty()
91 + this._addNotFound()
92 + this.close()
93 + return
94 + }
95 +
96 + const searchResults = SearchItems.filter(item => (item.name).toLowerCase().includes(searchValue))
97 + const endResults = $(searchResults.slice(0, this.options.maxResults))
98 + $(SELECTOR_SEARCH_RESULTS_GROUP).empty()
99 +
100 + if (endResults.length === 0) {
101 + this._addNotFound()
102 + } else {
103 + endResults.each((i, result) => {
104 + $(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(escape(result.name), encodeURI(result.link), result.path))
105 + })
106 + }
107 +
108 + this.open()
109 + }
110 +
111 + open() {
112 + $(SELECTOR_DATA_WIDGET).parent().addClass(CLASS_NAME_OPEN)
113 + $(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_SEARCH).addClass(CLASS_NAME_ICON_CLOSE)
114 + }
115 +
116 + close() {
117 + $(SELECTOR_DATA_WIDGET).parent().removeClass(CLASS_NAME_OPEN)
118 + $(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_CLOSE).addClass(CLASS_NAME_ICON_SEARCH)
119 + }
120 +
121 + toggle() {
122 + if ($(SELECTOR_DATA_WIDGET).parent().hasClass(CLASS_NAME_OPEN)) {
123 + this.close()
124 + } else {
125 + this.open()
126 + }
127 + }
128 +
129 + // Private
130 +
131 + _parseItem(item, path = []) {
132 + if ($(item).hasClass(CLASS_NAME_HEADER)) {
133 + return
134 + }
135 +
136 + const itemObject = {}
137 + const navLink = $(item).clone().find(`> ${SELECTOR_NAV_LINK}`)
138 + const navTreeview = $(item).clone().find(`> ${SELECTOR_NAV_TREEVIEW}`)
139 +
140 + const link = navLink.attr('href')
141 + const name = navLink.find('p').children().remove().end().text()
142 +
143 + itemObject.name = this._trimText(name)
144 + itemObject.link = link
145 + itemObject.path = path
146 +
147 + if (navTreeview.length === 0) {
148 + SearchItems.push(itemObject)
149 + } else {
150 + const newPath = itemObject.path.concat([itemObject.name])
151 + navTreeview.children().each((i, child) => {
152 + this._parseItem(child, newPath)
153 + })
154 + }
155 + }
156 +
157 + _trimText(text) {
158 + return trim(text.replace(/(\r\n|\n|\r)/gm, ' '))
159 + }
160 +
161 + _renderItem(name, link, path) {
162 + path = path.join(` ${this.options.arrowSign} `)
163 + name = unescape(name)
164 + link = decodeURI(link)
165 +
166 + if (this.options.highlightName || this.options.highlightPath) {
167 + const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase()
168 + const regExp = new RegExp(searchValue, 'gi')
169 +
170 + if (this.options.highlightName) {
171 + name = name.replace(
172 + regExp,
173 + str => {
174 + return `<strong class="${this.options.highlightClass}">${str}</strong>`
175 + }
176 + )
177 + }
178 +
179 + if (this.options.highlightPath) {
180 + path = path.replace(
181 + regExp,
182 + str => {
183 + return `<strong class="${this.options.highlightClass}">${str}</strong>`
184 + }
185 + )
186 + }
187 + }
188 +
189 + const groupItemElement = $('<a/>', {
190 + href: link,
191 + class: 'list-group-item'
192 + })
193 + const searchTitleElement = $('<div/>', {
194 + class: 'search-title'
195 + }).html(name)
196 + const searchPathElement = $('<div/>', {
197 + class: 'search-path'
198 + }).html(path)
199 +
200 + groupItemElement.append(searchTitleElement).append(searchPathElement)
201 +
202 + return groupItemElement
203 + }
204 +
205 + _addNotFound() {
206 + $(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(this.options.notFoundText, '#', []))
207 + }
208 +
209 + // Static
210 +
211 + static _jQueryInterface(config) {
212 + let data = $(this).data(DATA_KEY)
213 +
214 + if (!data) {
215 + data = $(this).data()
216 + }
217 +
218 + const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
219 + const plugin = new SidebarSearch($(this), _options)
220 +
221 + $(this).data(DATA_KEY, typeof config === 'object' ? config : data)
222 +
223 + if (typeof config === 'string' && /init|toggle|close|open|search/.test(config)) {
224 + plugin[config]()
225 + } else {
226 + plugin.init()
227 + }
228 + }
229 +}
230 +
231 +/**
232 + * Data API
233 + * ====================================================
234 + */
235 +$(document).on('click', SELECTOR_SEARCH_BUTTON, event => {
236 + event.preventDefault()
237 +
238 + SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'toggle')
239 +})
240 +
241 +$(document).on('keyup', SELECTOR_SEARCH_INPUT, event => {
242 + if (event.keyCode == 38) {
243 + event.preventDefault()
244 + $(SELECTOR_SEARCH_RESULTS_GROUP).children().last().focus()
245 + return
246 + }
247 +
248 + if (event.keyCode == 40) {
249 + event.preventDefault()
250 + $(SELECTOR_SEARCH_RESULTS_GROUP).children().first().focus()
251 + return
252 + }
253 +
254 + setTimeout(() => {
255 + SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'search')
256 + }, 100)
257 +})
258 +
259 +$(document).on('keydown', SELECTOR_SEARCH_RESULTS_GROUP, event => {
260 + const $focused = $(':focus')
261 +
262 + if (event.keyCode == 38) {
263 + event.preventDefault()
264 +
265 + if ($focused.is(':first-child')) {
266 + $focused.siblings().last().focus()
267 + } else {
268 + $focused.prev().focus()
269 + }
270 + }
271 +
272 + if (event.keyCode == 40) {
273 + event.preventDefault()
274 +
275 + if ($focused.is(':last-child')) {
276 + $focused.siblings().first().focus()
277 + } else {
278 + $focused.next().focus()
279 + }
280 + }
281 +})
282 +
283 +$(window).on('load', () => {
284 + SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'init')
285 +})
286 +
287 +/**
288 + * jQuery API
289 + * ====================================================
290 + */
291 +
292 +$.fn[NAME] = SidebarSearch._jQueryInterface
293 +$.fn[NAME].Constructor = SidebarSearch
294 +$.fn[NAME].noConflict = function () {
295 + $.fn[NAME] = JQUERY_NO_CONFLICT
296 + return SidebarSearch._jQueryInterface
297 +}
298 +
299 +export default SidebarSearch
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE Toasts.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'Toasts'
16 +const DATA_KEY = 'lte.toasts'
17 +const EVENT_KEY = `.${DATA_KEY}`
18 +const JQUERY_NO_CONFLICT = $.fn[NAME]
19 +
20 +const EVENT_INIT = `init${EVENT_KEY}`
21 +const EVENT_CREATED = `created${EVENT_KEY}`
22 +const EVENT_REMOVED = `removed${EVENT_KEY}`
23 +
24 +const SELECTOR_CONTAINER_TOP_RIGHT = '#toastsContainerTopRight'
25 +const SELECTOR_CONTAINER_TOP_LEFT = '#toastsContainerTopLeft'
26 +const SELECTOR_CONTAINER_BOTTOM_RIGHT = '#toastsContainerBottomRight'
27 +const SELECTOR_CONTAINER_BOTTOM_LEFT = '#toastsContainerBottomLeft'
28 +
29 +const CLASS_NAME_TOP_RIGHT = 'toasts-top-right'
30 +const CLASS_NAME_TOP_LEFT = 'toasts-top-left'
31 +const CLASS_NAME_BOTTOM_RIGHT = 'toasts-bottom-right'
32 +const CLASS_NAME_BOTTOM_LEFT = 'toasts-bottom-left'
33 +
34 +const POSITION_TOP_RIGHT = 'topRight'
35 +const POSITION_TOP_LEFT = 'topLeft'
36 +const POSITION_BOTTOM_RIGHT = 'bottomRight'
37 +const POSITION_BOTTOM_LEFT = 'bottomLeft'
38 +
39 +const Default = {
40 + position: POSITION_TOP_RIGHT,
41 + fixed: true,
42 + autohide: false,
43 + autoremove: true,
44 + delay: 1000,
45 + fade: true,
46 + icon: null,
47 + image: null,
48 + imageAlt: null,
49 + imageHeight: '25px',
50 + title: null,
51 + subtitle: null,
52 + close: true,
53 + body: null,
54 + class: null
55 +}
56 +
57 +/**
58 + * Class Definition
59 + * ====================================================
60 + */
61 +class Toasts {
62 + constructor(element, config) {
63 + this._config = config
64 + this._prepareContainer()
65 +
66 + $('body').trigger($.Event(EVENT_INIT))
67 + }
68 +
69 + // Public
70 +
71 + create() {
72 + const toast = $('<div class="toast" role="alert" aria-live="assertive" aria-atomic="true"/>')
73 +
74 + toast.data('autohide', this._config.autohide)
75 + toast.data('animation', this._config.fade)
76 +
77 + if (this._config.class) {
78 + toast.addClass(this._config.class)
79 + }
80 +
81 + if (this._config.delay && this._config.delay != 500) {
82 + toast.data('delay', this._config.delay)
83 + }
84 +
85 + const toastHeader = $('<div class="toast-header">')
86 +
87 + if (this._config.image != null) {
88 + const toastImage = $('<img />').addClass('rounded mr-2').attr('src', this._config.image).attr('alt', this._config.imageAlt)
89 +
90 + if (this._config.imageHeight != null) {
91 + toastImage.height(this._config.imageHeight).width('auto')
92 + }
93 +
94 + toastHeader.append(toastImage)
95 + }
96 +
97 + if (this._config.icon != null) {
98 + toastHeader.append($('<i />').addClass('mr-2').addClass(this._config.icon))
99 + }
100 +
101 + if (this._config.title != null) {
102 + toastHeader.append($('<strong />').addClass('mr-auto').html(this._config.title))
103 + }
104 +
105 + if (this._config.subtitle != null) {
106 + toastHeader.append($('<small />').html(this._config.subtitle))
107 + }
108 +
109 + if (this._config.close == true) {
110 + const toastClose = $('<button data-dismiss="toast" />').attr('type', 'button').addClass('ml-2 mb-1 close').attr('aria-label', 'Close').append('<span aria-hidden="true">&times;</span>')
111 +
112 + if (this._config.title == null) {
113 + toastClose.toggleClass('ml-2 ml-auto')
114 + }
115 +
116 + toastHeader.append(toastClose)
117 + }
118 +
119 + toast.append(toastHeader)
120 +
121 + if (this._config.body != null) {
122 + toast.append($('<div class="toast-body" />').html(this._config.body))
123 + }
124 +
125 + $(this._getContainerId()).prepend(toast)
126 +
127 + const $body = $('body')
128 +
129 + $body.trigger($.Event(EVENT_CREATED))
130 + toast.toast('show')
131 +
132 + if (this._config.autoremove) {
133 + toast.on('hidden.bs.toast', function () {
134 + $(this).delay(200).remove()
135 + $body.trigger($.Event(EVENT_REMOVED))
136 + })
137 + }
138 + }
139 +
140 + // Static
141 +
142 + _getContainerId() {
143 + if (this._config.position == POSITION_TOP_RIGHT) {
144 + return SELECTOR_CONTAINER_TOP_RIGHT
145 + }
146 +
147 + if (this._config.position == POSITION_TOP_LEFT) {
148 + return SELECTOR_CONTAINER_TOP_LEFT
149 + }
150 +
151 + if (this._config.position == POSITION_BOTTOM_RIGHT) {
152 + return SELECTOR_CONTAINER_BOTTOM_RIGHT
153 + }
154 +
155 + if (this._config.position == POSITION_BOTTOM_LEFT) {
156 + return SELECTOR_CONTAINER_BOTTOM_LEFT
157 + }
158 + }
159 +
160 + _prepareContainer() {
161 + if ($(this._getContainerId()).length === 0) {
162 + const container = $('<div />').attr('id', this._getContainerId().replace('#', ''))
163 + if (this._config.position == POSITION_TOP_RIGHT) {
164 + container.addClass(CLASS_NAME_TOP_RIGHT)
165 + } else if (this._config.position == POSITION_TOP_LEFT) {
166 + container.addClass(CLASS_NAME_TOP_LEFT)
167 + } else if (this._config.position == POSITION_BOTTOM_RIGHT) {
168 + container.addClass(CLASS_NAME_BOTTOM_RIGHT)
169 + } else if (this._config.position == POSITION_BOTTOM_LEFT) {
170 + container.addClass(CLASS_NAME_BOTTOM_LEFT)
171 + }
172 +
173 + $('body').append(container)
174 + }
175 +
176 + if (this._config.fixed) {
177 + $(this._getContainerId()).addClass('fixed')
178 + } else {
179 + $(this._getContainerId()).removeClass('fixed')
180 + }
181 + }
182 +
183 + // Static
184 +
185 + static _jQueryInterface(option, config) {
186 + return this.each(function () {
187 + const _options = $.extend({}, Default, config)
188 + const toast = new Toasts($(this), _options)
189 +
190 + if (option === 'create') {
191 + toast[option]()
192 + }
193 + })
194 + }
195 +}
196 +
197 +/**
198 + * jQuery API
199 + * ====================================================
200 + */
201 +
202 +$.fn[NAME] = Toasts._jQueryInterface
203 +$.fn[NAME].Constructor = Toasts
204 +$.fn[NAME].noConflict = function () {
205 + $.fn[NAME] = JQUERY_NO_CONFLICT
206 + return Toasts._jQueryInterface
207 +}
208 +
209 +export default Toasts
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE TodoList.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'TodoList'
16 +const DATA_KEY = 'lte.todolist'
17 +const JQUERY_NO_CONFLICT = $.fn[NAME]
18 +
19 +const SELECTOR_DATA_TOGGLE = '[data-widget="todo-list"]'
20 +const CLASS_NAME_TODO_LIST_DONE = 'done'
21 +
22 +const Default = {
23 + onCheck(item) {
24 + return item
25 + },
26 + onUnCheck(item) {
27 + return item
28 + }
29 +}
30 +
31 +/**
32 + * Class Definition
33 + * ====================================================
34 + */
35 +
36 +class TodoList {
37 + constructor(element, config) {
38 + this._config = config
39 + this._element = element
40 +
41 + this._init()
42 + }
43 +
44 + // Public
45 +
46 + toggle(item) {
47 + item.parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE)
48 + if (!$(item).prop('checked')) {
49 + this.unCheck($(item))
50 + return
51 + }
52 +
53 + this.check(item)
54 + }
55 +
56 + check(item) {
57 + this._config.onCheck.call(item)
58 + }
59 +
60 + unCheck(item) {
61 + this._config.onUnCheck.call(item)
62 + }
63 +
64 + // Private
65 +
66 + _init() {
67 + const $toggleSelector = this._element
68 +
69 + $toggleSelector.find('input:checkbox:checked').parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE)
70 + $toggleSelector.on('change', 'input:checkbox', event => {
71 + this.toggle($(event.target))
72 + })
73 + }
74 +
75 + // Static
76 +
77 + static _jQueryInterface(config) {
78 + return this.each(function () {
79 + let data = $(this).data(DATA_KEY)
80 +
81 + if (!data) {
82 + data = $(this).data()
83 + }
84 +
85 + const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
86 + const plugin = new TodoList($(this), _options)
87 +
88 + $(this).data(DATA_KEY, typeof config === 'object' ? config : data)
89 +
90 + if (config === 'init') {
91 + plugin[config]()
92 + }
93 + })
94 + }
95 +}
96 +
97 +/**
98 + * Data API
99 + * ====================================================
100 + */
101 +
102 +$(window).on('load', () => {
103 + TodoList._jQueryInterface.call($(SELECTOR_DATA_TOGGLE))
104 +})
105 +
106 +/**
107 + * jQuery API
108 + * ====================================================
109 + */
110 +
111 +$.fn[NAME] = TodoList._jQueryInterface
112 +$.fn[NAME].Constructor = TodoList
113 +$.fn[NAME].noConflict = function () {
114 + $.fn[NAME] = JQUERY_NO_CONFLICT
115 + return TodoList._jQueryInterface
116 +}
117 +
118 +export default TodoList
1 +/**
2 + * --------------------------------------------
3 + * AdminLTE Treeview.js
4 + * License MIT
5 + * --------------------------------------------
6 + */
7 +
8 +import $ from 'jquery'
9 +
10 +/**
11 + * Constants
12 + * ====================================================
13 + */
14 +
15 +const NAME = 'Treeview'
16 +const DATA_KEY = 'lte.treeview'
17 +const EVENT_KEY = `.${DATA_KEY}`
18 +const JQUERY_NO_CONFLICT = $.fn[NAME]
19 +
20 +const EVENT_EXPANDED = `expanded${EVENT_KEY}`
21 +const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
22 +const EVENT_LOAD_DATA_API = `load${EVENT_KEY}`
23 +
24 +const SELECTOR_LI = '.nav-item'
25 +const SELECTOR_LINK = '.nav-link'
26 +const SELECTOR_TREEVIEW_MENU = '.nav-treeview'
27 +const SELECTOR_OPEN = '.menu-open'
28 +const SELECTOR_DATA_WIDGET = '[data-widget="treeview"]'
29 +
30 +const CLASS_NAME_OPEN = 'menu-open'
31 +const CLASS_NAME_IS_OPENING = 'menu-is-opening'
32 +const CLASS_NAME_SIDEBAR_COLLAPSED = 'sidebar-collapse'
33 +
34 +const Default = {
35 + trigger: `${SELECTOR_DATA_WIDGET} ${SELECTOR_LINK}`,
36 + animationSpeed: 300,
37 + accordion: true,
38 + expandSidebar: false,
39 + sidebarButtonSelector: '[data-widget="pushmenu"]'
40 +}
41 +
42 +/**
43 + * Class Definition
44 + * ====================================================
45 + */
46 +class Treeview {
47 + constructor(element, config) {
48 + this._config = config
49 + this._element = element
50 + }
51 +
52 + // Public
53 +
54 + init() {
55 + $(`${SELECTOR_LI}${SELECTOR_OPEN} ${SELECTOR_TREEVIEW_MENU}${SELECTOR_OPEN}`).css('display', 'block')
56 + this._setupListeners()
57 + }
58 +
59 + expand(treeviewMenu, parentLi) {
60 + const expandedEvent = $.Event(EVENT_EXPANDED)
61 +
62 + if (this._config.accordion) {
63 + const openMenuLi = parentLi.siblings(SELECTOR_OPEN).first()
64 + const openTreeview = openMenuLi.find(SELECTOR_TREEVIEW_MENU).first()
65 + this.collapse(openTreeview, openMenuLi)
66 + }
67 +
68 + parentLi.addClass(CLASS_NAME_IS_OPENING)
69 + treeviewMenu.stop().slideDown(this._config.animationSpeed, () => {
70 + parentLi.addClass(CLASS_NAME_OPEN)
71 + $(this._element).trigger(expandedEvent)
72 + })
73 +
74 + if (this._config.expandSidebar) {
75 + this._expandSidebar()
76 + }
77 + }
78 +
79 + collapse(treeviewMenu, parentLi) {
80 + const collapsedEvent = $.Event(EVENT_COLLAPSED)
81 +
82 + parentLi.removeClass(`${CLASS_NAME_IS_OPENING} ${CLASS_NAME_OPEN}`)
83 + treeviewMenu.stop().slideUp(this._config.animationSpeed, () => {
84 + $(this._element).trigger(collapsedEvent)
85 + treeviewMenu.find(`${SELECTOR_OPEN} > ${SELECTOR_TREEVIEW_MENU}`).slideUp()
86 + treeviewMenu.find(SELECTOR_OPEN).removeClass(CLASS_NAME_OPEN)
87 + })
88 + }
89 +
90 + toggle(event) {
91 + const $relativeTarget = $(event.currentTarget)
92 + const $parent = $relativeTarget.parent()
93 +
94 + let treeviewMenu = $parent.find(`> ${SELECTOR_TREEVIEW_MENU}`)
95 +
96 + if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) {
97 + if (!$parent.is(SELECTOR_LI)) {
98 + treeviewMenu = $parent.parent().find(`> ${SELECTOR_TREEVIEW_MENU}`)
99 + }
100 +
101 + if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) {
102 + return
103 + }
104 + }
105 +
106 + event.preventDefault()
107 +
108 + const parentLi = $relativeTarget.parents(SELECTOR_LI).first()
109 + const isOpen = parentLi.hasClass(CLASS_NAME_OPEN)
110 +
111 + if (isOpen) {
112 + this.collapse($(treeviewMenu), parentLi)
113 + } else {
114 + this.expand($(treeviewMenu), parentLi)
115 + }
116 + }
117 +
118 + // Private
119 +
120 + _setupListeners() {
121 + const elementId = this._element.attr('id') !== undefined ? `#${this._element.attr('id')}` : ''
122 + $(document).on('click', `${elementId}${this._config.trigger}`, event => {
123 + this.toggle(event)
124 + })
125 + }
126 +
127 + _expandSidebar() {
128 + if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) {
129 + $(this._config.sidebarButtonSelector).PushMenu('expand')
130 + }
131 + }
132 +
133 + // Static
134 +
135 + static _jQueryInterface(config) {
136 + return this.each(function () {
137 + let data = $(this).data(DATA_KEY)
138 + const _options = $.extend({}, Default, $(this).data())
139 +
140 + if (!data) {
141 + data = new Treeview($(this), _options)
142 + $(this).data(DATA_KEY, data)
143 + }
144 +
145 + if (config === 'init') {
146 + data[config]()
147 + }
148 + })
149 + }
150 +}
151 +
152 +/**
153 + * Data API
154 + * ====================================================
155 + */
156 +
157 +$(window).on(EVENT_LOAD_DATA_API, () => {
158 + $(SELECTOR_DATA_WIDGET).each(function () {
159 + Treeview._jQueryInterface.call($(this), 'init')
160 + })
161 +})
162 +
163 +/**
164 + * jQuery API
165 + * ====================================================
166 + */
167 +
168 +$.fn[NAME] = Treeview._jQueryInterface
169 +$.fn[NAME].Constructor = Treeview
170 +$.fn[NAME].noConflict = function () {
171 + $.fn[NAME] = JQUERY_NO_CONFLICT
172 + return Treeview._jQueryInterface
173 +}
174 +
175 +export default Treeview
1 +{
2 + "env": {
3 + "browser": false,
4 + "node": true
5 + },
6 + "parserOptions": {
7 + "sourceType": "script"
8 + },
9 + "extends": "../../.eslintrc.json",
10 + "rules": {
11 + "no-console": "off",
12 + "strict": "error",
13 + "unicorn/prefer-module": "off"
14 + }
15 +}
1 +'use strict'
2 +
3 +const Plugins = [
4 + // AdminLTE Dist
5 + {
6 + from: 'dist/css/',
7 + to: 'docs/assets/css/'
8 + },
9 + {
10 + from: 'dist/js/',
11 + to: 'docs/assets/js/'
12 + },
13 + // jQuery
14 + {
15 + from: 'node_modules/jquery/dist/',
16 + to: 'docs/assets/plugins/jquery/'
17 + },
18 + // Popper
19 + {
20 + from: 'node_modules/popper.js/dist/',
21 + to: 'docs/assets/plugins/popper/'
22 + },
23 + // Bootstrap
24 + {
25 + from: 'node_modules/bootstrap/dist/js/',
26 + to: 'docs/assets/plugins/bootstrap/js/'
27 + },
28 + // Font Awesome
29 + {
30 + from: 'node_modules/@fortawesome/fontawesome-free/css/',
31 + to: 'docs/assets/plugins/fontawesome-free/css/'
32 + },
33 + {
34 + from: 'node_modules/@fortawesome/fontawesome-free/webfonts/',
35 + to: 'docs/assets/plugins/fontawesome-free/webfonts/'
36 + },
37 + // overlayScrollbars
38 + {
39 + from: 'node_modules/overlayscrollbars/js/',
40 + to: 'docs/assets/plugins/overlayScrollbars/js/'
41 + },
42 + {
43 + from: 'node_modules/overlayscrollbars/css/',
44 + to: 'docs/assets/plugins/overlayScrollbars/css/'
45 + }
46 +]
47 +
48 +module.exports = Plugins
1 +#!/usr/bin/env node
2 +
3 +'use strict'
4 +
5 +const path = require('path')
6 +const fse = require('fs-extra')
7 +const fs = require('fs')
8 +const Plugins = require('./DocsPlugins')
9 +
10 +class Publish {
11 + constructor() {
12 + this.options = {
13 + verbose: false
14 + }
15 +
16 + this.getArguments()
17 + }
18 +
19 + getArguments() {
20 + if (process.argv.length > 2) {
21 + const arg = process.argv[2]
22 + switch (arg) {
23 + case '-v':
24 + case '--verbose':
25 + this.options.verbose = true
26 + break
27 + default:
28 + throw new Error(`Unknown option ${arg}`)
29 + }
30 + }
31 + }
32 +
33 + run() {
34 + // Publish files
35 + Plugins.forEach(module => {
36 + try {
37 + fse.copySync(module.from, module.to, {
38 + // Skip copying dot files
39 + filter(src) {
40 + return !path.basename(src).startsWith('.')
41 + }
42 + })
43 +
44 + if (this.options.verbose) {
45 + console.log(`Copied ${module.from} to ${module.to}`)
46 + }
47 + } catch (error) {
48 + console.error(`Error: ${error}`)
49 + }
50 + })
51 +
52 + const insertText = '---\r\nlayout: page\r\ntitle: \r\n---\r\n'
53 +
54 + fs.writeFileSync('docs/how-to-contribute.md', insertText + fs.readFileSync('.github/CONTRIBUTING.md', 'utf8'))
55 + }
56 +}
57 +
58 +(new Publish()).run()
1 +#!/usr/bin/env node
2 +
3 +'use strict'
4 +
5 +const path = require('path')
6 +const fse = require('fs-extra')
7 +const Plugins = require('./Plugins')
8 +
9 +class Publish {
10 + constructor() {
11 + this.options = {
12 + verbose: false
13 + }
14 +
15 + this.getArguments()
16 + }
17 +
18 + getArguments() {
19 + if (process.argv.length > 2) {
20 + const arg = process.argv[2]
21 + switch (arg) {
22 + case '-v':
23 + case '--verbose':
24 + this.options.verbose = true
25 + break
26 + default:
27 + throw new Error(`Unknown option ${arg}`)
28 + }
29 + }
30 + }
31 +
32 + run() {
33 + // Publish files
34 + Plugins.forEach(module => {
35 + const fseOptions = {
36 + // Skip copying dot files
37 + filter(src) {
38 + return !path.basename(src).startsWith('.')
39 + }
40 + }
41 +
42 + try {
43 + if (fse.existsSync(module.from)) {
44 + fse.copySync(module.from, module.to, fseOptions)
45 + } else {
46 + fse.copySync(module.from.replace('node_modules/', '../'), module.to, fseOptions)
47 + }
48 +
49 + if (this.options.verbose) {
50 + console.log(`Copied ${module.from} to ${module.to}`)
51 + }
52 + } catch (error) {
53 + console.error(`Error: ${error}`)
54 + }
55 + })
56 + }
57 +}
58 +
59 +(new Publish()).run()
1 +#!/usr/bin/env node
2 +
3 +/*!
4 + * Script to run vnu-jar if Java is available.
5 + * Copyright 2017-2021 The Bootstrap Authors
6 + * Copyright 2017-2021 Twitter, Inc.
7 + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
8 + */
9 +
10 +'use strict'
11 +
12 +const childProcess = require('child_process')
13 +const vnu = require('vnu-jar')
14 +
15 +childProcess.exec('java -version', (error, stdout, stderr) => {
16 + if (error) {
17 + console.error('Skipping vnu-jar test; Java is missing.')
18 + return
19 + }
20 +
21 + const is32bitJava = !/64-Bit/.test(stderr)
22 +
23 + // vnu-jar accepts multiple ignores joined with a `|`.
24 + // Also note that the ignores are regular expressions.
25 + const ignores = [
26 + // "autocomplete" is included in <button> and checkboxes and radio <input>s due to
27 + // Firefox's non-standard autocomplete behavior - see https://bugzilla.mozilla.org/show_bug.cgi?id=654072
28 + 'Attribute “autocomplete” is only allowed when the input type is.*'
29 + ].join('|')
30 +
31 + const args = [
32 + '-jar',
33 + vnu,
34 + '--asciiquotes',
35 + '--skip-non-html',
36 + // Ignore the language code warnings
37 + '--no-langdetect',
38 + '--Werror',
39 + `--filterpattern "${ignores}"`,
40 + './*.html',
41 + 'docs_html/',
42 + 'pages/'
43 + ]
44 +
45 + // For the 32-bit Java we need to pass `-Xss512k`
46 + if (is32bitJava) {
47 + args.splice(0, 0, '-Xss512k')
48 + }
49 +
50 + return childProcess.spawn('java', args, {
51 + shell: true,
52 + stdio: 'inherit'
53 + })
54 + .on('exit', process.exit)
55 +})
1 +/*!
2 + * AdminLTE v3.1.0
3 + * Author: Colorlib
4 + * Website: AdminLTE.io <https://adminlte.io>
5 + * License: Open source - MIT <https://opensource.org/licenses/MIT>
6 + */
7 +
8 +//
9 +// ------------------------------------------------------------------
10 +// This file is to be included in your custom SCSS. Before importing
11 +// this file, you should include your custom AdminLTE and Bootstrap
12 +// variables followed by bootstrap.scss and then this file. It's
13 +// ok to import this file without custom variables too!
14 +// NOTE: be sure to keep the license notice in the generated css.
15 +// ------------------------------------------------------------------
16 +
17 +//
18 +// Variables and Mixins
19 +// ---------------------------------------------------
20 +@import "bootstrap-variables";
21 +@import "variables";
22 +@import "variables-alt";
23 +@import "mixins";
24 +
25 +@import "parts/core";
26 +@import "parts/components";
27 +@import "parts/extra-components";
28 +@import "parts/pages";
29 +@import "parts/plugins";
30 +@import "parts/miscellaneous";
1 +//
2 +// Component: Alert
3 +//
4 +
5 +.alert {
6 + .icon {
7 + margin-right: 10px;
8 + }
9 +
10 + .close {
11 + color: $black;
12 + opacity: .2;
13 +
14 + &:hover {
15 + opacity: .5;
16 + }
17 + }
18 +
19 + a {
20 + color: $white;
21 + text-decoration: underline;
22 + }
23 +}
24 +
25 +//Alert Variants
26 +@each $color, $value in $theme-colors {
27 + .alert-#{$color} {
28 + color: color-yiq($value);
29 + background-color: $value;
30 + border-color: darken($value, 5%);
31 + }
32 +
33 + .alert-default-#{$color} {
34 + @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
35 + }
36 +}
37 +
38 +@include dark-mode () {
39 + @each $color, $value in $theme-colors-alt {
40 + .alert-#{$color} {
41 + color: color-yiq($value);
42 + background-color: $value;
43 + border-color: darken($value, 5%);
44 + }
45 +
46 + .alert-default-#{$color} {
47 + @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
48 + }
49 + }
50 +}
51 +
52 +//
1 +//
2 +// Component: Animation
3 +//
4 +
5 +.animation {
6 + &__shake {
7 + animation: shake 1500ms;
8 + }
9 + &__wobble {
10 + animation: wobble 1500ms;
11 + }
12 +}
13 +
14 +//
1 +//
2 +// Component: Brand
3 +//
4 +
5 +.brand-link {
6 + $brand-link-padding-y: $navbar-brand-padding-y + $navbar-padding-y;
7 + display: block;
8 + font-size: $navbar-brand-font-size;
9 + line-height: $line-height-lg;
10 + padding: $brand-link-padding-y $sidebar-padding-x;
11 + transition: width $transition-speed $transition-fn;
12 + white-space: nowrap;
13 +
14 + &:hover {
15 + color: $white;
16 + text-decoration: none;
17 + }
18 +
19 + .text-sm & {
20 + font-size: inherit;
21 + }
22 +
23 + [class*="sidebar-dark"] & {
24 + border-bottom: 1px solid lighten($dark, 10%);
25 +
26 + &,
27 + .pushmenu {
28 + color: rgba($white, .8);
29 +
30 + &:hover {
31 + color: $white;
32 + }
33 + }
34 + }
35 +
36 + [class*="sidebar-light"] & {
37 + border-bottom: 1px solid $gray-300;
38 +
39 + &,
40 + .pushmenu {
41 + color: rgba($black, .8);
42 +
43 + &:hover {
44 + color: $black;
45 + }
46 + }
47 + }
48 +
49 + .pushmenu {
50 + margin-right: $sidebar-padding-x;
51 + font-size: $font-size-base;
52 + }
53 +
54 + .brand-link {
55 + padding: 0;
56 + border-bottom: none;
57 + }
58 +
59 + .brand-image {
60 + float: left;
61 + line-height: .8;
62 + margin-left: .8rem;
63 + margin-right: .5rem;
64 + margin-top: -3px;
65 + max-height: 33px;
66 + width: auto;
67 + }
68 +
69 + .brand-image-xs {
70 + float: left;
71 + line-height: .8;
72 + margin-top: -.1rem;
73 + max-height: 33px;
74 + width: auto;
75 + }
76 +
77 + .brand-image-xl {
78 + line-height: .8;
79 + max-height: 40px;
80 + width: auto;
81 +
82 + &.single {
83 + margin-top: -.3rem;
84 + }
85 + }
86 +
87 + &.text-sm,
88 + .text-sm & {
89 + .brand-image {
90 + height: 29px;
91 + margin-bottom: -.25rem;
92 + margin-left: .95rem;
93 + margin-top: -.25rem;
94 + }
95 +
96 + .brand-image-xs {
97 + margin-top: -.2rem;
98 + max-height: 29px;
99 + }
100 +
101 + .brand-image-xl {
102 + margin-top: -.225rem;
103 + max-height: 38px;
104 + }
105 + }
106 +}
1 +//
2 +// Component: Button
3 +//
4 +
5 +.btn {
6 + &.disabled,
7 + &:disabled {
8 + cursor: not-allowed;
9 + }
10 +
11 + // Flat buttons
12 + &.btn-flat {
13 + @include border-radius(0);
14 + border-width: 1px;
15 + box-shadow: none;
16 + }
17 +
18 + // input file btn
19 + &.btn-file {
20 + overflow: hidden;
21 + position: relative;
22 +
23 + > input[type="file"] {
24 + background-color: $white;
25 + cursor: inherit;
26 + display: block;
27 + font-size: 100px;
28 + min-height: 100%;
29 + min-width: 100%;
30 + opacity: 0;
31 + outline: none;
32 + position: absolute;
33 + right: 0;
34 + text-align: right;
35 + top: 0;
36 + }
37 + }
38 +
39 + .text-sm & {
40 + font-size: $font-size-sm !important;
41 + }
42 +}
43 +
44 +// Button color variations
45 +.btn-default {
46 + background-color: $button-default-background-color;
47 + border-color: $button-default-border-color;
48 + color: $button-default-color;
49 +
50 + &:hover,
51 + &:active,
52 + &.hover {
53 + background-color: darken($button-default-background-color, 5%);
54 + color: darken($button-default-color, 10%);
55 + }
56 +}
57 +
58 +// Application buttons
59 +.btn-app {
60 + @include border-radius(3px);
61 + background-color: $button-default-background-color;
62 + border: 1px solid $button-default-border-color;
63 + color: $gray-600;
64 + font-size: 12px;
65 + height: 60px;
66 + margin: 0 0 10px 10px;
67 + min-width: 80px;
68 + padding: 15px 5px;
69 + position: relative;
70 + text-align: center;
71 +
72 + // Icons within the btn
73 + > .fa,
74 + > .fas,
75 + > .far,
76 + > .fab,
77 + > .fal,
78 + > .fad,
79 + > .svg-inline--fa,
80 + > .ion {
81 + display: block;
82 + font-size: 20px;
83 + }
84 +
85 + > .svg-inline--fa {
86 + margin: 0 auto;
87 + }
88 +
89 + &:hover {
90 + background-color: $button-default-background-color;
91 + border-color: darken($button-default-border-color, 20%);
92 + color: $button-default-color;
93 + }
94 +
95 + &:active,
96 + &:focus {
97 + @include box-shadow(inset 0 3px 5px rgba($black, .125));
98 + }
99 +
100 + // The badge
101 + > .badge {
102 + font-size: 10px;
103 + font-weight: 400;
104 + position: absolute;
105 + right: -10px;
106 + top: -3px;
107 + }
108 +}
109 +
110 +// Extra Button Size
111 +
112 +.btn-xs {
113 + @include button-size($button-padding-y-xs, $button-padding-x-xs, $button-font-size-xs, $button-line-height-xs, $button-border-radius-xs);
114 +}
115 +
116 +@include dark-mode () {
117 + .btn-default,
118 + .btn-app {
119 + background-color: lighten($dark, 2.5%);
120 + color: $white;
121 + border-color: $gray-600;
122 +
123 + &:hover,
124 + &:focus {
125 + background-color: lighten($dark, 5%);
126 + color: $gray-300;
127 + border-color: lighten($gray-600, 2.5%);
128 + }
129 + }
130 + .btn-light {
131 + background-color: lighten($dark, 7.5%);
132 + color: $white;
133 + border-color: $gray-600;
134 +
135 + &:hover,
136 + &:focus {
137 + background-color: lighten($dark, 10%);
138 + color: $gray-300;
139 + border-color: lighten($gray-600, 5%);
140 + }
141 + }
142 +
143 + @each $color, $value in $theme-colors-alt {
144 + .btn-#{$color} {
145 + @include button-variant($value, $value);
146 + }
147 + }
148 +
149 + @each $color, $value in $theme-colors-alt {
150 + .btn-outline-#{$color} {
151 + @include button-outline-variant($value);
152 + }
153 + }
154 +}
1 +//
2 +// Component: Callout
3 +//
4 +
5 +// Base styles (regardless of theme)
6 +.callout {
7 + @if $enable-rounded {
8 + @include border-radius($border-radius);
9 + }
10 +
11 + @if $enable-shadows {
12 + box-shadow: map-get($elevations, 1);
13 + } @else {
14 + border: 1px solid $gray-300;
15 + }
16 +
17 + background-color: $white;
18 + border-left: 5px solid $gray-200;
19 + margin-bottom: map-get($spacers, 3);
20 + padding: 1rem;
21 +
22 + a {
23 + color: $gray-700;
24 + text-decoration: underline;
25 +
26 + &:hover {
27 + color: $gray-200;
28 + }
29 + }
30 +
31 + p:last-child {
32 + margin-bottom: 0;
33 + }
34 +
35 + // Themes for different contexts
36 + &.callout-danger {
37 + border-left-color: darken(theme-color("danger"), 10%);
38 + }
39 +
40 + &.callout-warning {
41 + border-left-color: darken(theme-color("warning"), 10%);
42 + }
43 +
44 + &.callout-info {
45 + border-left-color: darken(theme-color("info"), 10%);
46 + }
47 +
48 + &.callout-success {
49 + border-left-color: darken(theme-color("success"), 10%);
50 + }
51 +}
52 +
53 +@include dark-mode () {
54 + .callout {
55 + background-color: lighten($dark, 5%);
56 +
57 + &.callout-danger {
58 + border-left-color: lighten($danger-alt, 10%);
59 + }
60 +
61 + &.callout-warning {
62 + border-left-color: lighten($warning-alt, 10%);
63 + }
64 +
65 + &.callout-info {
66 + border-left-color: lighten($info-alt, 10%);
67 + }
68 +
69 + &.callout-success {
70 + border-left-color: lighten($success-alt, 10%);
71 + }
72 + }
73 +}
1 +//
2 +// Component: Cards
3 +//
4 +
5 +// Color variants
6 +@each $name, $color in $theme-colors {
7 + @include cards-variant($name, $color);
8 +}
9 +
10 +@each $name, $color in $colors {
11 + @include cards-variant($name, $color);
12 +}
13 +
14 +.card {
15 + @include box-shadow($card-shadow);
16 + margin-bottom: map-get($spacers, 3);
17 +
18 + &.bg-dark {
19 + .card-header {
20 + border-color: $card-dark-border-color;
21 + }
22 +
23 + &,
24 + .card-body {
25 + color: $white;
26 + }
27 + }
28 +
29 + &.maximized-card {
30 + height: 100% !important;
31 + left: 0;
32 + max-height: 100% !important;
33 + max-width: 100% !important;
34 + position: fixed;
35 + top: 0;
36 + width: 100% !important;
37 + z-index: $zindex-modal-backdrop;
38 +
39 + &.was-collapsed .card-body {
40 + display: block !important;
41 + }
42 +
43 + .card-body {
44 + overflow: auto;
45 + }
46 +
47 + [data-card-widgett="collapse"] {
48 + display: none;
49 + }
50 +
51 + .card-header,
52 + .card-footer {
53 + @include border-radius(0 !important);
54 + }
55 + }
56 +
57 + // collapsed mode
58 + &.collapsed-card {
59 + .card-body,
60 + .card-footer {
61 + display: none;
62 + }
63 + }
64 +
65 + .nav.flex-column {
66 + > li {
67 + border-bottom: 1px solid $card-border-color;
68 + margin: 0;
69 +
70 + &:last-of-type {
71 + border-bottom: 0;
72 + }
73 + }
74 + }
75 +
76 + // fixed height to 300px
77 + &.height-control {
78 + .card-body {
79 + max-height: 300px;
80 + overflow: auto;
81 + }
82 + }
83 +
84 + .border-right {
85 + border-right: 1px solid $card-border-color;
86 + }
87 +
88 + .border-left {
89 + border-left: 1px solid $card-border-color;
90 + }
91 +
92 + &.card-tabs {
93 + &:not(.card-outline) {
94 + > .card-header {
95 + border-bottom: 0;
96 +
97 + .nav-item {
98 + &:first-child .nav-link {
99 + border-left-color: transparent;
100 + }
101 + }
102 + }
103 + }
104 +
105 + &.card-outline {
106 + .nav-item {
107 + border-bottom: 0;
108 +
109 + &:first-child .nav-link {
110 + border-left: 0;
111 + margin-left: 0;
112 + }
113 + }
114 + }
115 +
116 + .card-tools {
117 + margin: .3rem .5rem;
118 + }
119 +
120 + &:not(.expanding-card).collapsed-card {
121 + .card-header {
122 + border-bottom: 0;
123 +
124 + .nav-tabs {
125 + border-bottom: 0;
126 +
127 + .nav-item {
128 + margin-bottom: 0;
129 + }
130 + }
131 + }
132 + }
133 +
134 + &.expanding-card {
135 + .card-header {
136 + .nav-tabs {
137 + .nav-item {
138 + margin-bottom: -1px;
139 + }
140 + }
141 + }
142 + }
143 + }
144 +
145 + &.card-outline-tabs {
146 + border-top: 0;
147 +
148 + .card-header {
149 + .nav-item {
150 + &:first-child .nav-link {
151 + border-left: 0;
152 + margin-left: 0;
153 + }
154 + }
155 +
156 + a {
157 + border-top: 3px solid transparent;
158 +
159 + &:hover {
160 + border-top: 3px solid $nav-tabs-border-color;
161 + }
162 +
163 + &.active {
164 + &:hover {
165 + margin-top: 0;
166 + }
167 + }
168 + }
169 + }
170 +
171 + .card-tools {
172 + margin: .5rem .5rem .3rem;
173 + }
174 +
175 + &:not(.expanding-card).collapsed-card .card-header {
176 + border-bottom: 0;
177 +
178 + .nav-tabs {
179 + border-bottom: 0;
180 +
181 + .nav-item {
182 + margin-bottom: 0;
183 + }
184 + }
185 + }
186 +
187 + &.expanding-card {
188 + .card-header {
189 + .nav-tabs {
190 + .nav-item {
191 + margin-bottom: -1px;
192 + }
193 + }
194 + }
195 + }
196 + }
197 +
198 +}
199 +
200 +// Maximized Card Body Scroll fix
201 +html.maximized-card {
202 + overflow: hidden;
203 +}
204 +
205 +// Add clearfix to header, body and footer
206 +.card-header,
207 +.card-body,
208 +.card-footer {
209 + @include clearfix ();
210 +}
211 +
212 +// Box header
213 +.card-header {
214 + background-color: transparent;
215 + border-bottom: 1px solid $card-border-color;
216 + padding: (($card-spacer-y / 2) * 2) $card-spacer-x;
217 + position: relative;
218 +
219 + @if $enable-rounded {
220 + @include border-top-radius($border-radius);
221 + }
222 +
223 + .collapsed-card & {
224 + border-bottom: 0;
225 + }
226 +
227 + > .card-tools {
228 + float: right;
229 + margin-right: -$card-spacer-x / 2;
230 +
231 + .input-group,
232 + .nav,
233 + .pagination {
234 + margin-bottom: -$card-spacer-y / 2.5;
235 + margin-top: -$card-spacer-y / 2.5;
236 + }
237 +
238 + [data-toggle="tooltip"] {
239 + position: relative;
240 + }
241 + }
242 +}
243 +
244 +.card-title {
245 + float: left;
246 + font-size: $card-title-font-size;
247 + font-weight: $card-title-font-weight;
248 + margin: 0;
249 +}
250 +
251 +.card-text {
252 + clear: both;
253 +}
254 +
255 +
256 +// Box Tools Buttons
257 +.btn-tool {
258 + background-color: transparent;
259 + color: $gray-500;
260 + font-size: $font-size-sm;
261 + margin: -(($card-spacer-y / 2) * 2) 0;
262 + padding: .25rem .5rem;
263 +
264 + .btn-group.show &,
265 + &:hover {
266 + color: $gray-700;
267 + }
268 +
269 + .show &,
270 + &:focus {
271 + box-shadow: none !important;
272 + }
273 +}
274 +
275 +.text-sm {
276 + .card-title {
277 + font-size: $card-title-font-size-sm;
278 + }
279 +
280 + .nav-link {
281 + padding: $card-nav-link-padding-sm-y $card-nav-link-padding-sm-x;
282 + }
283 +}
284 +
285 +// Box Body
286 +.card-body {
287 + // @include border-radius-sides(0, 0, $border-radius, $border-radius);
288 + // .no-header & {
289 + // @include border-top-radius($border-radius);
290 + // }
291 +
292 + // Tables within the box body
293 + > .table {
294 + margin-bottom: 0;
295 +
296 + > thead > tr > th,
297 + > thead > tr > td {
298 + border-top-width: 0;
299 + }
300 + }
301 +
302 + // Calendar within the box body
303 + .fc {
304 + margin-top: 5px;
305 + }
306 +
307 + .full-width-chart {
308 + margin: -19px;
309 + }
310 +
311 + &.p-0 .full-width-chart {
312 + margin: -9px;
313 + }
314 +}
315 +
316 +.chart-legend {
317 + @include list-unstyled ();
318 + margin: 10px 0;
319 +
320 + > li {
321 + @media (max-width: map-get($grid-breakpoints, sm)) {
322 + float: left;
323 + margin-right: 10px;
324 + }
325 + }
326 +}
327 +
328 +// Comment Box
329 +.card-comments {
330 + background-color: $gray-100;
331 +
332 + .card-comment {
333 + @include clearfix ();
334 + border-bottom: 1px solid $gray-200;
335 + padding: 8px 0;
336 +
337 + &:last-of-type {
338 + border-bottom: 0;
339 + }
340 +
341 + &:first-of-type {
342 + padding-top: 0;
343 + }
344 +
345 + img {
346 + height: $card-img-size;
347 + width: $card-img-size;
348 + float: left;
349 + }
350 + }
351 +
352 + .comment-text {
353 + color: lighten($gray-700, 20%);
354 + margin-left: 40px;
355 + }
356 +
357 + .username {
358 + color: $gray-700;
359 + display: block;
360 + font-weight: 600;
361 + }
362 +
363 + .text-muted {
364 + font-size: 12px;
365 + font-weight: 400;
366 + }
367 +}
368 +
369 +// Widgets
370 +//-----------
371 +
372 +// Widget: TODO LIST
373 +.todo-list {
374 + list-style: none;
375 + margin: 0;
376 + overflow: auto;
377 + padding: 0;
378 +
379 + // Todo list element
380 + > li {
381 + @include border-radius(2px);
382 + background-color: $gray-100;
383 + border-left: 2px solid $gray-200;
384 + color: $gray-700;
385 + margin-bottom: 2px;
386 + padding: 10px;
387 +
388 + &:last-of-type {
389 + margin-bottom: 0;
390 + }
391 +
392 + > input[type="checkbox"] {
393 + margin: 0 10px 0 5px;
394 + }
395 +
396 + .text {
397 + display: inline-block;
398 + font-weight: 600;
399 + margin-left: 5px;
400 + }
401 +
402 + // Time labels
403 + .badge {
404 + font-size: .7rem;
405 + margin-left: 10px;
406 + }
407 +
408 + // Tools and options box
409 + .tools {
410 + color: theme-color("danger");
411 + display: none;
412 + float: right;
413 +
414 + // icons
415 + > .fa,
416 + > .fas,
417 + > .far,
418 + > .fab,
419 + > .fal,
420 + > .fad,
421 + > .svg-inline--fa,
422 + > .ion {
423 + cursor: pointer;
424 + margin-right: 5px;
425 + }
426 + }
427 +
428 + &:hover .tools {
429 + display: inline-block;
430 + }
431 +
432 + &.done {
433 + color: darken($gray-500, 25%);
434 +
435 + .text {
436 + font-weight: 500;
437 + text-decoration: line-through;
438 + }
439 +
440 + .badge {
441 + background-color: $gray-500 !important;
442 + }
443 + }
444 + }
445 +
446 + // Color variants
447 + @each $name, $color in $theme-colors {
448 + .#{$name} {
449 + border-left-color: $color;
450 + }
451 + }
452 +
453 + @each $name, $color in $colors {
454 + .#{$name} {
455 + border-left-color: $color;
456 + }
457 + }
458 +
459 + .handle {
460 + cursor: move;
461 + display: inline-block;
462 + margin: 0 5px;
463 + }
464 +}
465 +
466 +// END TODO WIDGET
467 +
468 +// Input in box
469 +.card-input {
470 + max-width: 200px;
471 +}
472 +
473 +// Nav Tabs override
474 +.card-default {
475 + .nav-item {
476 + &:first-child .nav-link {
477 + border-left: 0;
478 + }
479 + }
480 +}
481 +
482 +@include dark-mode () {
483 +
484 + // Color variants
485 + @each $name, $color in $theme-colors-alt {
486 + @include cards-variant($name, $color);
487 + }
488 +
489 + @each $name, $color in $colors-alt {
490 + @include cards-variant($name, $color);
491 + }
492 +
493 + .card {
494 + background-color: $dark;
495 + color: $white;
496 +
497 + .card {
498 + background-color: lighten($dark, 5%);
499 + color: $white;
500 + }
501 + .nav.flex-column > li {
502 + border-bottom-color: $gray-600;
503 + }
504 + .card-footer {
505 + background-color: rgba($black, .1);
506 + }
507 + &.card-outline-tabs .card-header a:hover {
508 + border-color: $gray-600;
509 + border-bottom-color: transparent;
510 + }
511 + &:not(.card-outline) > .card-header a.active {
512 + color: $white;
513 + }
514 + }
515 +
516 + .card-comments {
517 + background-color: lighten($dark, 1.25%);
518 + .username {
519 + color: $gray-400;
520 + }
521 + .card-comment {
522 + border-bottom-color: lighten($dark, 7.5%);
523 + }
524 + }
525 +
526 + .todo-list > li {
527 + background-color: lighten($dark, 5%);
528 + border-color: lighten($dark, 7.5%);
529 + color: $white;
530 + }
531 +
532 + .todo-list {
533 + @each $name, $color in $theme-colors-alt {
534 + .#{$name} {
535 + border-left-color: $color;
536 + }
537 + }
538 +
539 + @each $name, $color in $colors-alt {
540 + .#{$name} {
541 + border-left-color: $color;
542 + }
543 + }
544 + }
545 +}
1 +//
2 +// Component: Carousel
3 +//
4 +
5 +.carousel-control-custom-icon {
6 + .carousel-control-prev & {
7 + margin-left: -20px;
8 + }
9 + .carousel-control-next & {
10 + margin-right: 20px;
11 + }
12 +
13 + > .fa,
14 + > .fas,
15 + > .far,
16 + > .fab,
17 + > .fal,
18 + > .fad,
19 + > .svg-inline--fa,
20 + > .ion {
21 + display: inline-block;
22 + font-size: 40px;
23 + margin-top: -20px;
24 + position: absolute;
25 + top: 50%;
26 + z-index: 5;
27 + }
28 +}
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 + &:focus {
23 + outline: none;
24 + }
25 +}
26 +
27 +// Additional properties for button version
28 +// iOS requires the button element instead of an anchor tag.
29 +// If you want the anchor version, it requires `href="#"`.
30 +// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
31 +
32 +// stylelint-disable-next-line selector-no-qualifying-type
33 +button.close {
34 + padding: 0;
35 + background-color: transparent;
36 + border: 0;
37 +}
38 +
39 +// Future-proof disabling of clicks on `<a>` elements
40 +
41 +// stylelint-disable-next-line selector-no-qualifying-type
42 +a.close.disabled {
43 + pointer-events: none;
44 +}
1 +//
2 +// Misc: Colors
3 +//
4 +
5 +// Background colors (theme colors)
6 +@each $name, $color in $theme-colors {
7 + @include background-variant($name, $color);
8 +}
9 +
10 +// Background colors (colors)
11 +@each $name, $color in $colors {
12 + @include background-variant($name, $color);
13 +}
14 +
15 +.bg-gray {
16 + background-color: $gray-500;
17 + color: color-yiq($gray-500);
18 +}
19 +
20 +.bg-gray-light {
21 + background-color: lighten($gray-200, 3%);
22 + color: color-yiq(lighten($gray-200, 3%)) !important;
23 +}
24 +
25 +.bg-black {
26 + background-color: $black;
27 + color: color-yiq($black) !important;
28 +}
29 +
30 +.bg-white {
31 + background-color: $white;
32 + color: color-yiq($white) !important;
33 +}
34 +
35 +// Gradient Background colors (theme colors)
36 +@each $name, $color in $theme-colors {
37 + @include background-gradient-variant($name, $color);
38 +}
39 +
40 +// Gradient Background colors (colors)
41 +@each $name, $color in $colors {
42 + @include background-gradient-variant($name, $color);
43 +}
44 +
45 +// Backgrund Color Disabled
46 +[class^="bg-"].disabled {
47 + opacity: .65;
48 +}
49 +
50 +// Text muted hover
51 +a.text-muted:hover {
52 + color: theme-color(primary) !important;
53 +}
54 +
55 +// Link Styles
56 +.link-muted {
57 + color: darken($gray-500, 30%);
58 +
59 + &:hover,
60 + &:focus {
61 + color: darken($gray-500, 40%);
62 + }
63 +}
64 +
65 +.link-black {
66 + color: $gray-600;
67 +
68 + &:hover,
69 + &:focus {
70 + color: lighten($gray-500, 20%);
71 + }
72 +}
73 +
74 +// Accent colors (theme colors)
75 +@each $name, $color in $theme-colors {
76 + @include accent-variant($name, $color);
77 +}
78 +
79 +// Accent colors (colors)
80 +@each $name, $color in $colors {
81 + @include accent-variant($name, $color);
82 +}
83 +
84 +// Accent button override fix
85 +[class*="accent-"] {
86 + @each $name, $color in $theme-colors {
87 + a.btn-#{$name} {
88 + color: color-yiq($color);
89 + }
90 + }
91 +}
92 +
93 +@include dark-mode () {
94 + .bg-light {
95 + background-color: lighten($dark, 7.5%) !important;
96 + color: $white !important;
97 + }
98 + .text-black,
99 + .text-dark,
100 + .link-black,
101 + .link-dark {
102 + color: $gray-400;
103 + }
104 +
105 + // Background colors (theme colors)
106 + @each $name, $color in $theme-colors-alt {
107 + @include background-variant($name, $color);
108 + }
109 +
110 + // Background colors (colors)
111 + @each $name, $color in $colors-alt {
112 + @include background-variant($name, $color);
113 + }
114 +
115 + // Gradient Background colors (theme colors)
116 + @each $name, $color in $theme-colors-alt {
117 + @include background-gradient-variant($name, $color);
118 + }
119 +
120 + // Gradient Background colors (colors)
121 + @each $name, $color in $colors-alt {
122 + @include background-gradient-variant($name, $color);
123 + }
124 +
125 + // Accent colors (theme colors)
126 + @each $name, $color in $theme-colors-alt {
127 + @include accent-variant($name, $color);
128 + }
129 +
130 + [class*="accent-"] {
131 + @each $name, $color in $theme-colors-alt {
132 + a.btn-#{$name} {
133 + color: color-yiq($color);
134 + }
135 + }
136 + }
137 +
138 + // Accent colors (colors)
139 + @each $name, $color in $colors-alt {
140 + @include accent-variant($name, $color);
141 + }
142 +}
143 +
144 +//
1 +//
2 +// Component: Control Sidebar
3 +//
4 +
5 +html.control-sidebar-animate {
6 + overflow-x: hidden;
7 +}
8 +
9 +.control-sidebar {
10 + bottom: $main-footer-height;
11 + position: absolute;
12 + top: $main-header-height;
13 + z-index: $zindex-control-sidebar;
14 +
15 + &,
16 + &::before {
17 + bottom: $main-footer-height;
18 + display: none;
19 + right: -$control-sidebar-width;
20 + width: $control-sidebar-width;
21 + @include transition(right $transition-speed $transition-fn, display $transition-speed $transition-fn);
22 + }
23 +
24 + &::before {
25 + content: "";
26 + display: block;
27 + position: fixed;
28 + top: 0;
29 + z-index: -1;
30 + }
31 +}
32 +
33 +body.text-sm {
34 + .control-sidebar {
35 + bottom: $main-footer-height-sm;
36 + top: $main-header-height-sm;
37 + }
38 +}
39 +
40 +.main-header.text-sm ~ .control-sidebar {
41 + top: $main-header-height-sm;
42 +}
43 +
44 +.main-footer.text-sm ~ .control-sidebar {
45 + bottom: $main-footer-height-sm;
46 +}
47 +
48 +.control-sidebar-push-slide {
49 + .content-wrapper,
50 + .main-footer {
51 + @include transition(margin-right $transition-speed $transition-fn);
52 + }
53 +}
54 +
55 +// Control sidebar open state
56 +.control-sidebar-open {
57 + .control-sidebar {
58 + display: block;
59 +
60 + &,
61 + &::before {
62 + right: 0;
63 + }
64 + }
65 +
66 + &.control-sidebar-push,
67 + &.control-sidebar-push-slide {
68 + .content-wrapper,
69 + .main-footer {
70 + margin-right: $control-sidebar-width;
71 + }
72 + }
73 +}
74 +
75 +// Control sidebar slide over content state
76 +.control-sidebar-slide-open {
77 + .control-sidebar {
78 + display: block;
79 +
80 + &,
81 + &::before {
82 + right: 0;
83 + @include transition(right $transition-speed $transition-fn, display $transition-speed $transition-fn);
84 + }
85 + }
86 +
87 + &.control-sidebar-push,
88 + &.control-sidebar-push-slide {
89 + .content-wrapper,
90 + .main-footer {
91 + margin-right: $control-sidebar-width;
92 + }
93 + }
94 +}
95 +
96 +// Dark skin
97 +.control-sidebar-dark {
98 + background-color: $sidebar-dark-bg;
99 +
100 + &,
101 + a,
102 + .nav-link {
103 + color: $sidebar-dark-color;
104 + }
105 +
106 + a:hover {
107 + color: $sidebar-dark-hover-color;
108 + }
109 +
110 + // Headers and labels
111 + h1,
112 + h2,
113 + h3,
114 + h4,
115 + h5,
116 + h6,
117 + label {
118 + color: $sidebar-dark-hover-color;
119 + }
120 +
121 + // Tabs
122 + .nav-tabs {
123 + background-color: $sidebar-dark-hover-bg;
124 + border-bottom: 0;
125 + margin-bottom: 5px;
126 +
127 + .nav-item {
128 + margin: 0;
129 + }
130 +
131 + .nav-link {
132 + border-radius: 0;
133 + padding: 10px 20px;
134 + position: relative;
135 + text-align: center;
136 +
137 + &,
138 + &:hover,
139 + &:active,
140 + &:focus,
141 + &.active {
142 + border: 0;
143 + }
144 +
145 + &:hover,
146 + &:active,
147 + &:focus,
148 + &.active {
149 + border-bottom-color: transparent;
150 + border-left-color: transparent;
151 + border-top-color: transparent;
152 + color: $sidebar-dark-hover-color;
153 + }
154 +
155 + &.active {
156 + background-color: $sidebar-dark-bg;
157 + }
158 + }
159 + }
160 +
161 + .tab-pane {
162 + padding: 10px 15px;
163 + }
164 +}
165 +
166 +// Light skin
167 +.control-sidebar-light {
168 + color: lighten($sidebar-light-color, 10%);
169 +
170 + // Background
171 + background-color: $sidebar-light-bg;
172 + border-left: $main-header-bottom-border;
173 +}
1 +//
2 +// Component: Direct Chat
3 +//
4 +
5 +.direct-chat {
6 + .card-body {
7 + overflow-x: hidden;
8 + padding: 0;
9 + position: relative;
10 + }
11 +
12 + &.chat-pane-open {
13 + .direct-chat-contacts {
14 + @include translate(0, 0);
15 + }
16 + }
17 +
18 +
19 + &.timestamp-light {
20 + .direct-chat-timestamp {
21 + color: lighten(color-yiq($yiq-text-light), 10%);
22 + }
23 + }
24 +
25 + &.timestamp-dark {
26 + .direct-chat-timestamp {
27 + color: darken(color-yiq($yiq-text-dark), 20%);
28 + }
29 + }
30 +}
31 +
32 +.direct-chat-messages {
33 + @include translate(0, 0);
34 + height: 250px;
35 + overflow: auto;
36 + padding: 10px;
37 +}
38 +
39 +.direct-chat-msg,
40 +.direct-chat-text {
41 + display: block;
42 +}
43 +
44 +.direct-chat-msg {
45 + @include clearfix ();
46 + margin-bottom: 10px;
47 +}
48 +
49 +.direct-chat-messages,
50 +.direct-chat-contacts {
51 + transition: transform .5s ease-in-out;
52 +}
53 +
54 +.direct-chat-text {
55 + @if $enable-rounded {
56 + @include border-radius($border-radius-lg);
57 + }
58 +
59 + background-color: $direct-chat-default-msg-bg;
60 + border: 1px solid $direct-chat-default-msg-border-color;
61 + color: $direct-chat-default-font-color;
62 + margin: 5px 0 0 50px;
63 + padding: 5px 10px;
64 + position: relative;
65 +
66 + //Create the arrow
67 + &::after,
68 + &::before {
69 + border: solid transparent;
70 + border-right-color: $direct-chat-default-msg-border-color;
71 + content: " ";
72 + height: 0;
73 + pointer-events: none;
74 + position: absolute;
75 + right: 100%;
76 + top: 15px;
77 + width: 0;
78 + }
79 +
80 + &::after {
81 + border-width: 5px;
82 + margin-top: -5px;
83 + }
84 +
85 + &::before {
86 + border-width: 6px;
87 + margin-top: -6px;
88 + }
89 +
90 + .right & {
91 + margin-left: 0;
92 + margin-right: 50px;
93 +
94 + &::after,
95 + &::before {
96 + border-left-color: $direct-chat-default-msg-border-color;
97 + border-right-color: transparent;
98 + left: 100%;
99 + right: auto;
100 + }
101 + }
102 +}
103 +
104 +.direct-chat-img {
105 + @include border-radius(50%);
106 + float: left;
107 + height: 40px;
108 + width: 40px;
109 +
110 + .right & {
111 + float: right;
112 + }
113 +}
114 +
115 +.direct-chat-infos {
116 + display: block;
117 + font-size: $font-size-sm;
118 + margin-bottom: 2px;
119 +}
120 +
121 +.direct-chat-name {
122 + font-weight: 600;
123 +}
124 +
125 +.direct-chat-timestamp {
126 + color: darken($gray-500, 25%);
127 +}
128 +
129 +//Direct chat contacts pane
130 +.direct-chat-contacts-open {
131 + .direct-chat-contacts {
132 + @include translate(0, 0);
133 + }
134 +}
135 +
136 +.direct-chat-contacts {
137 + @include translate(101%, 0);
138 + background-color: $dark;
139 + bottom: 0;
140 + color: $white;
141 + height: 250px;
142 + overflow: auto;
143 + position: absolute;
144 + top: 0;
145 + width: 100%;
146 +}
147 +
148 +.direct-chat-contacts-light {
149 + background-color: $light;
150 +
151 + .contacts-list-name {
152 + color: $gray-700;
153 + }
154 +
155 + .contacts-list-date {
156 + color: $gray-600;
157 + }
158 +
159 + .contacts-list-msg {
160 + color: darken($gray-600, 10%);
161 + }
162 +}
163 +
164 +//Contacts list -- for displaying contacts in direct chat contacts pane
165 +.contacts-list {
166 + @include list-unstyled ();
167 +
168 + > li {
169 + @include clearfix ();
170 + border-bottom: 1px solid rgba($black, .2);
171 + margin: 0;
172 + padding: 10px;
173 +
174 + &:last-of-type {
175 + border-bottom: 0;
176 + }
177 + }
178 +}
179 +
180 +.contacts-list-img {
181 + @include border-radius(50%);
182 + float: left;
183 + width: 40px;
184 +}
185 +
186 +.contacts-list-info {
187 + color: $white;
188 + margin-left: 45px;
189 +}
190 +
191 +.contacts-list-name,
192 +.contacts-list-status {
193 + display: block;
194 +}
195 +
196 +.contacts-list-name {
197 + font-weight: 600;
198 +}
199 +
200 +.contacts-list-status {
201 + font-size: $font-size-sm;
202 +}
203 +
204 +.contacts-list-date {
205 + color: $gray-400;
206 + font-weight: 400;
207 +}
208 +
209 +.contacts-list-msg {
210 + color: darken($gray-400, 10%);
211 +}
212 +
213 +// Color variants
214 +@each $name, $color in $theme-colors {
215 + .direct-chat-#{$name} {
216 + @include direct-chat-variant($color);
217 + }
218 +}
219 +
220 +@each $name, $color in $colors {
221 + .direct-chat-#{$name} {
222 + @include direct-chat-variant($color);
223 + }
224 +}
225 +
226 +@include dark-mode () {
227 + .direct-chat-text {
228 + background-color: lighten($dark, 7.5%);
229 + border-color: lighten($dark, 10%);
230 + color: $white;
231 +
232 + &::after,
233 + &::before {
234 + border-right-color: lighten($dark, 10%);
235 + }
236 + }
237 + .direct-chat-timestamp {
238 + color: $gray-500;
239 + }
240 + .right > .direct-chat-text {
241 + &::after,
242 + &::before {
243 + border-right-color: transparent;
244 + }
245 + }
246 +
247 + // Color variants
248 + @each $name, $color in $theme-colors-alt {
249 + .direct-chat-#{$name} {
250 + @include direct-chat-variant($color);
251 + }
252 + }
253 +
254 + @each $name, $color in $colors-alt {
255 + .direct-chat-#{$name} {
256 + @include direct-chat-variant($color);
257 + }
258 + }
259 +}
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.