Merge remote-tracking branch 'inventree/master' into l10

This commit is contained in:
Oliver 2021-06-17 08:49:00 +10:00
commit a8ae62e133
334 changed files with 52020 additions and 12840 deletions

View File

@ -51,6 +51,7 @@ jobs:
rm test_db.sqlite rm test_db.sqlite
invoke migrate invoke migrate
invoke import-records -f data.json invoke import-records -f data.json
invoke import-records -f data.json
- name: Test Translations - name: Test Translations
run: invoke translate run: invoke translate
- name: Check Migration Files - name: Check Migration Files

View File

@ -15,6 +15,10 @@ jobs:
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to Dockerhub - name: Login to Dockerhub
uses: docker/login-action@v1 uses: docker/login-action@v1
with: with:
@ -24,7 +28,9 @@ jobs:
uses: docker/build-push-action@v2 uses: docker/build-push-action@v2
with: with:
context: ./docker context: ./docker
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true push: true
target: production
repository: inventree/inventree repository: inventree/inventree
tags: inventree/inventree:latest tags: inventree/inventree:latest
- name: Image Digest - name: Image Digest

View File

@ -13,14 +13,21 @@ jobs:
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: cd - name: Set up QEMU
run: | uses: docker/setup-qemu-action@v1
cd docker - name: Set up Docker Buildx
- name: Push to Docker Hub uses: docker/setup-buildx-action@v1
uses: docker/build-push-action@v1 - name: Login to Dockerhub
uses: docker/login-action@v1
with: with:
username: ${{ secrets.DOCKER_USERNAME }} username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push
uses: docker/build-push-action@v2
with:
context: ./docker
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
target: production
repository: inventree/inventree repository: inventree/inventree
tag_with_ref: true tags: inventree/inventree:${{ github.event.release.tag_name }}
dockerfile: ./Dockerfile

View File

@ -56,3 +56,12 @@ jobs:
invoke install invoke install
- name: Run Tests - name: Run Tests
run: invoke test run: invoke test
- name: Data Import Export
run: |
invoke migrate
python3 ./InvenTree/manage.py flush --noinput
invoke import-fixtures
invoke export-records -f data.json
python3 ./InvenTree/manage.py flush --noinput
invoke import-records -f data.json
invoke import-records -f data.json

View File

@ -52,3 +52,12 @@ jobs:
invoke install invoke install
- name: Run Tests - name: Run Tests
run: invoke test run: invoke test
- name: Data Import Export
run: |
invoke migrate
python3 ./InvenTree/manage.py flush --noinput
invoke import-fixtures
invoke export-records -f data.json
python3 ./InvenTree/manage.py flush --noinput
invoke import-records -f data.json
invoke import-records -f data.json

9
.gitignore vendored
View File

@ -31,6 +31,7 @@ var/
*.log *.log
local_settings.py local_settings.py
*.sqlite3 *.sqlite3
*.sqlite3-journal
*.backup *.backup
*.old *.old
@ -45,6 +46,11 @@ static_i18n
# Local config file # Local config file
config.yaml config.yaml
# Default data file
data.json
*.json.tmp
*.tmp.json
# Key file # Key file
secret_key.txt secret_key.txt
@ -56,3 +62,6 @@ secret_key.txt
# Coverage reports # Coverage reports
.coverage .coverage
htmlcov/ htmlcov/
# Development files
dev/

View File

@ -4,7 +4,9 @@ import logging
from django.apps import AppConfig from django.apps import AppConfig
from django.core.exceptions import AppRegistryNotReady from django.core.exceptions import AppRegistryNotReady
from django.conf import settings
from InvenTree.ready import isInTestMode, canAppAccessDatabase
import InvenTree.tasks import InvenTree.tasks
@ -16,7 +18,11 @@ class InvenTreeConfig(AppConfig):
def ready(self): def ready(self):
self.start_background_tasks() if canAppAccessDatabase():
self.start_background_tasks()
if not isInTestMode():
self.update_exchange_rates()
def start_background_tasks(self): def start_background_tasks(self):
@ -42,3 +48,58 @@ class InvenTreeConfig(AppConfig):
schedule_type=Schedule.MINUTES, schedule_type=Schedule.MINUTES,
minutes=15 minutes=15
) )
InvenTree.tasks.schedule_task(
'InvenTree.tasks.update_exchange_rates',
schedule_type=Schedule.DAILY,
)
def update_exchange_rates(self):
"""
Update exchange rates each time the server is started, *if*:
a) Have not been updated recently (one day or less)
b) The base exchange rate has been altered
"""
try:
from djmoney.contrib.exchange.models import ExchangeBackend
from datetime import datetime, timedelta
from InvenTree.tasks import update_exchange_rates
except AppRegistryNotReady:
pass
base_currency = settings.BASE_CURRENCY
update = False
try:
backend = ExchangeBackend.objects.get(name='InvenTreeExchange')
last_update = backend.last_update
if last_update is not None:
delta = datetime.now().date() - last_update.date()
if delta > timedelta(days=1):
print(f"Last update was {last_update}")
update = True
else:
# Never been updated
print("Exchange backend has never been updated")
update = True
# Backend currency has changed?
if not base_currency == backend.base_currency:
print(f"Base currency changed from {backend.base_currency} to {base_currency}")
update = True
except (ExchangeBackend.DoesNotExist):
print("Exchange backend not found - updating")
update = True
except:
# Some other error - potentially the tables are not ready yet
return
if update:
update_exchange_rates()

View File

@ -6,6 +6,7 @@ Provides extra global data to all templates.
from InvenTree.status_codes import SalesOrderStatus, PurchaseOrderStatus from InvenTree.status_codes import SalesOrderStatus, PurchaseOrderStatus
from InvenTree.status_codes import BuildStatus, StockStatus from InvenTree.status_codes import BuildStatus, StockStatus
from InvenTree.status_codes import StockHistoryCode
import InvenTree.status import InvenTree.status
@ -65,6 +66,7 @@ def status_codes(request):
'PurchaseOrderStatus': PurchaseOrderStatus, 'PurchaseOrderStatus': PurchaseOrderStatus,
'BuildStatus': BuildStatus, 'BuildStatus': BuildStatus,
'StockStatus': StockStatus, 'StockStatus': StockStatus,
'StockHistoryCode': StockHistoryCode,
} }

View File

@ -1,21 +1,29 @@
from djmoney.contrib.exchange.backends.base import BaseExchangeBackend from django.conf import settings as inventree_settings
from djmoney.contrib.exchange.backends.base import SimpleExchangeBackend
class InvenTreeManualExchangeBackend(BaseExchangeBackend): class InvenTreeExchange(SimpleExchangeBackend):
""" """
Backend for manually updating currency exchange rates Backend for automatically updating currency exchange rates.
See the documentation for django-money: https://github.com/django-money/django-money Uses the exchangerate.host service API
Specifically: https://github.com/django-money/django-money/tree/master/djmoney/contrib/exchange/backends
""" """
name = "inventree" name = "InvenTreeExchange"
url = None
def get_rates(self, **kwargs): def __init__(self):
""" self.url = "https://api.exchangerate.host/latest"
Do not get any rates...
"""
return {} super().__init__()
def get_params(self):
# No API key is required
return {
}
def update_rates(self, base_currency=inventree_settings.BASE_CURRENCY):
symbols = ','.join(inventree_settings.CURRENCIES)
super().update_rates(base=base_currency, symbols=symbols)

View File

@ -7,10 +7,12 @@ from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django import forms from django import forms
from django.contrib.auth.models import User
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Field from crispy_forms.layout import Layout, Field
from crispy_forms.bootstrap import PrependedText, AppendedText, PrependedAppendedText, StrictButton, Div from crispy_forms.bootstrap import PrependedText, AppendedText, PrependedAppendedText, StrictButton, Div
from django.contrib.auth.models import User
from common.models import ColorTheme from common.models import ColorTheme
from part.models import PartCategory from part.models import PartCategory

View File

@ -8,7 +8,7 @@ import json
import os.path import os.path
from PIL import Image from PIL import Image
from decimal import Decimal from decimal import Decimal, InvalidOperation
from wsgiref.util import FileWrapper from wsgiref.util import FileWrapper
from django.http import StreamingHttpResponse from django.http import StreamingHttpResponse
@ -357,6 +357,8 @@ def extract_serial_numbers(serials, expected_quantity):
- Serial numbers must be positive - Serial numbers must be positive
- Serial numbers can be split by whitespace / newline / commma chars - Serial numbers can be split by whitespace / newline / commma chars
- Serial numbers can be supplied as an inclusive range using hyphen char e.g. 10-20 - Serial numbers can be supplied as an inclusive range using hyphen char e.g. 10-20
- Serial numbers can be supplied as <start>+ for getting all expecteded numbers starting from <start>
- Serial numbers can be supplied as <start>+<length> for getting <length> numbers starting from <start>
Args: Args:
expected_quantity: The number of (unique) serial numbers we expect expected_quantity: The number of (unique) serial numbers we expect
@ -369,6 +371,13 @@ def extract_serial_numbers(serials, expected_quantity):
numbers = [] numbers = []
errors = [] errors = []
# helpers
def number_add(n):
if n in numbers:
errors.append(_('Duplicate serial: {n}').format(n=n))
else:
numbers.append(n)
try: try:
expected_quantity = int(expected_quantity) expected_quantity = int(expected_quantity)
except ValueError: except ValueError:
@ -395,10 +404,7 @@ def extract_serial_numbers(serials, expected_quantity):
if a < b: if a < b:
for n in range(a, b + 1): for n in range(a, b + 1):
if n in numbers: number_add(n)
errors.append(_('Duplicate serial: {n}').format(n=n))
else:
numbers.append(n)
else: else:
errors.append(_("Invalid group: {g}").format(g=group)) errors.append(_("Invalid group: {g}").format(g=group))
@ -409,6 +415,31 @@ def extract_serial_numbers(serials, expected_quantity):
errors.append(_("Invalid group: {g}").format(g=group)) errors.append(_("Invalid group: {g}").format(g=group))
continue continue
# plus signals either
# 1: 'start+': expected number of serials, starting at start
# 2: 'start+number': number of serials, starting at start
elif '+' in group:
items = group.split('+')
# case 1, 2
if len(items) == 2:
start = int(items[0])
# case 2
if bool(items[1]):
end = start + int(items[1]) + 1
# case 1
else:
end = start + expected_quantity
for n in range(start, end):
number_add(n)
# no case
else:
errors.append(_("Invalid group: {g}").format(g=group))
continue
else: else:
if group in numbers: if group in numbers:
errors.append(_("Duplicate serial: {g}".format(g=group))) errors.append(_("Duplicate serial: {g}".format(g=group)))
@ -575,3 +606,19 @@ def getNewestMigrationFile(app, exclude_extension=True):
newest_file = newest_file.replace('.py', '') newest_file = newest_file.replace('.py', '')
return newest_file return newest_file
def clean_decimal(number):
""" Clean-up decimal value """
# Check if empty
if number is None or number == '':
return Decimal(0)
# Check if decimal type
try:
clean_number = Decimal(number)
except InvalidOperation:
clean_number = number
return clean_number.quantize(Decimal(1)) if clean_number == clean_number.to_integral() else clean_number.normalize()

View File

@ -77,12 +77,20 @@ class AuthRequiredMiddleware(object):
if request.path_info == reverse_lazy('logout'): if request.path_info == reverse_lazy('logout'):
return HttpResponseRedirect(reverse_lazy('login')) return HttpResponseRedirect(reverse_lazy('login'))
login = reverse_lazy('login') path = request.path_info
if not request.path_info == login and not request.path_info.startswith('/api/'): # List of URL endpoints we *do not* want to redirect to
urls = [
reverse_lazy('login'),
reverse_lazy('logout'),
reverse_lazy('admin:login'),
reverse_lazy('admin:logout'),
]
if path not in urls and not path.startswith('/api/'):
# Save the 'next' parameter to pass through to the login view # Save the 'next' parameter to pass through to the login view
return redirect('%s?next=%s' % (login, request.path)) return redirect('%s?next=%s' % (reverse_lazy('login'), request.path))
# Code to be executed for each request/response after # Code to be executed for each request/response after
# the view is called. # the view is called.

View File

@ -0,0 +1,46 @@
import sys
def isInTestMode():
"""
Returns True if the database is in testing mode
"""
if 'test' in sys.argv:
return True
return False
def canAppAccessDatabase():
"""
Returns True if the apps.py file can access database records.
There are some circumstances where we don't want the ready function in apps.py
to touch the database
"""
# If any of the following management commands are being executed,
# prevent custom "on load" code from running!
excluded_commands = [
'flush',
'loaddata',
'dumpdata',
'makemirations',
'migrate',
'check',
'mediarestore',
'shell',
'createsuperuser',
'wait_for_db',
'prerender',
'collectstatic',
'makemessages',
'compilemessages',
]
for cmd in excluded_commands:
if cmd in sys.argv:
return False
return True

View File

@ -17,9 +17,10 @@ import random
import string import string
import shutil import shutil
import sys import sys
import tempfile
from datetime import datetime from datetime import datetime
import moneyed
import yaml import yaml
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -88,6 +89,11 @@ DEBUG = _is_true(get_setting(
CONFIG.get('debug', True) CONFIG.get('debug', True)
)) ))
DOCKER = _is_true(get_setting(
'INVENTREE_DOCKER',
False
))
# Configure logging settings # Configure logging settings
log_level = get_setting( log_level = get_setting(
'INVENTREE_LOG_LEVEL', 'INVENTREE_LOG_LEVEL',
@ -185,7 +191,7 @@ STATIC_URL = '/static/'
STATIC_ROOT = os.path.abspath( STATIC_ROOT = os.path.abspath(
get_setting( get_setting(
'INVENTREE_STATIC_ROOT', 'INVENTREE_STATIC_ROOT',
CONFIG.get('static_root', '/home/inventree/static') CONFIG.get('static_root', '/home/inventree/data/static')
) )
) )
@ -250,7 +256,6 @@ INSTALLED_APPS = [
# Third part add-ons # Third part add-ons
'django_filters', # Extended filter functionality 'django_filters', # Extended filter functionality
'dbbackup', # Database backup / restore
'rest_framework', # DRF (Django Rest Framework) 'rest_framework', # DRF (Django Rest Framework)
'rest_framework.authtoken', # Token authentication for API 'rest_framework.authtoken', # Token authentication for API
'corsheaders', # Cross-origin Resource Sharing for DRF 'corsheaders', # Cross-origin Resource Sharing for DRF
@ -265,6 +270,7 @@ INSTALLED_APPS = [
'djmoney.contrib.exchange', # django-money exchange rates 'djmoney.contrib.exchange', # django-money exchange rates
'error_report', # Error reporting in the admin interface 'error_report', # Error reporting in the admin interface
'django_q', 'django_q',
'formtools', # Form wizard tools
] ]
MIDDLEWARE = CONFIG.get('middleware', [ MIDDLEWARE = CONFIG.get('middleware', [
@ -432,11 +438,15 @@ It can be specified in config.yaml (or envvar) as either (for example):
- django.db.backends.postgresql - django.db.backends.postgresql
""" """
db_engine = db_config['ENGINE'] db_engine = db_config['ENGINE'].lower()
if db_engine.lower() in ['sqlite3', 'postgresql', 'mysql']: # Correct common misspelling
if db_engine == 'sqlite':
db_engine = 'sqlite3'
if db_engine in ['sqlite3', 'postgresql', 'mysql']:
# Prepend the required python module string # Prepend the required python module string
db_engine = f'django.db.backends.{db_engine.lower()}' db_engine = f'django.db.backends.{db_engine}'
db_config['ENGINE'] = db_engine db_config['ENGINE'] = db_engine
db_name = db_config['NAME'] db_name = db_config['NAME']
@ -493,7 +503,7 @@ LANGUAGES = [
('en', _('English')), ('en', _('English')),
('fr', _('French')), ('fr', _('French')),
('de', _('German')), ('de', _('German')),
('pk', _('Polish')), ('pl', _('Polish')),
('tr', _('Turkish')), ('tr', _('Turkish')),
] ]
@ -505,8 +515,19 @@ CURRENCIES = CONFIG.get(
], ],
) )
# TODO - Allow live web-based backends in the future # Check that each provided currency is supported
EXCHANGE_BACKEND = 'InvenTree.exchange.InvenTreeManualExchangeBackend' for currency in CURRENCIES:
if currency not in moneyed.CURRENCIES:
print(f"Currency code '{currency}' is not supported")
sys.exit(1)
BASE_CURRENCY = get_setting(
'INVENTREE_BASE_CURRENCY',
CONFIG.get('base_currency', 'USD')
)
# Custom currency exchange backend
EXCHANGE_BACKEND = 'InvenTree.exchange.InvenTreeExchange'
# Extract email settings from the config file # Extract email settings from the config file
email_config = CONFIG.get('email', {}) email_config = CONFIG.get('email', {})
@ -586,17 +607,6 @@ CRISPY_TEMPLATE_PACK = 'bootstrap3'
# Use database transactions when importing / exporting data # Use database transactions when importing / exporting data
IMPORT_EXPORT_USE_TRANSACTIONS = True IMPORT_EXPORT_USE_TRANSACTIONS = True
BACKUP_DIR = get_setting(
'INVENTREE_BACKUP_DIR',
CONFIG.get('backup_dir', tempfile.gettempdir()),
)
# Settings for dbbsettings app
DBBACKUP_STORAGE = 'django.core.files.storage.FileSystemStorage'
DBBACKUP_STORAGE_OPTIONS = {
'location': BACKUP_DIR,
}
# Internal IP addresses allowed to see the debug toolbar # Internal IP addresses allowed to see the debug toolbar
INTERNAL_IPS = [ INTERNAL_IPS = [
'127.0.0.1', '127.0.0.1',

File diff suppressed because one or more lines are too long

View File

@ -1,14 +1,14 @@
@charset "UTF-8";
/** /**
* @author zhixin wen <wenzhixin2010@gmail.com> * @author zhixin wen <wenzhixin2010@gmail.com>
* version: 1.14.2 * version: 1.18.3
* https://github.com/wenzhixin/bootstrap-table/ * https://github.com/wenzhixin/bootstrap-table/
*/ */
.bootstrap-table .fixed-table-toolbar:after { .bootstrap-table .fixed-table-toolbar::after {
content: ""; content: "";
display: block; display: block;
clear: both; clear: both;
} }
.bootstrap-table .fixed-table-toolbar .bs-bars, .bootstrap-table .fixed-table-toolbar .bs-bars,
.bootstrap-table .fixed-table-toolbar .search, .bootstrap-table .fixed-table-toolbar .search,
.bootstrap-table .fixed-table-toolbar .columns { .bootstrap-table .fixed-table-toolbar .columns {
@ -16,26 +16,34 @@
margin-top: 10px; margin-top: 10px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group { .bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group {
display: inline-block; display: inline-block;
margin-left: -1px !important; margin-left: -1px !important;
} }
.bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group > .btn {
border-radius: 0;
}
.bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group:first-child > .btn { .bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group:first-child > .btn {
border-top-left-radius: 4px; border-top-left-radius: 4px;
border-bottom-left-radius: 4px; border-bottom-left-radius: 4px;
} }
.bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group:last-child > .btn { .bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group:last-child > .btn {
border-top-right-radius: 4px; border-top-right-radius: 4px;
border-bottom-right-radius: 4px; border-bottom-right-radius: 4px;
} }
.bootstrap-table .fixed-table-toolbar .columns .btn-group > .btn-group > .btn {
border-radius: 0;
}
.bootstrap-table .fixed-table-toolbar .columns .dropdown-menu { .bootstrap-table .fixed-table-toolbar .columns .dropdown-menu {
text-align: left; text-align: left;
max-height: 300px; max-height: 300px;
overflow: auto; overflow: auto;
-ms-overflow-style: scrollbar;
z-index: 1001;
} }
.bootstrap-table .fixed-table-toolbar .columns label { .bootstrap-table .fixed-table-toolbar .columns label {
display: block; display: block;
padding: 3px 20px; padding: 3px 20px;
@ -43,68 +51,188 @@
font-weight: normal; font-weight: normal;
line-height: 1.428571429; line-height: 1.428571429;
} }
.bootstrap-table .fixed-table-toolbar .columns-left { .bootstrap-table .fixed-table-toolbar .columns-left {
margin-right: 5px; margin-right: 5px;
} }
.bootstrap-table .fixed-table-toolbar .columns-right { .bootstrap-table .fixed-table-toolbar .columns-right {
margin-left: 5px; margin-left: 5px;
} }
.bootstrap-table .fixed-table-toolbar .pull-right .dropdown-menu { .bootstrap-table .fixed-table-toolbar .pull-right .dropdown-menu {
right: 0; right: 0;
left: auto; left: auto;
} }
.bootstrap-table .fixed-table-container { .bootstrap-table .fixed-table-container {
position: relative; position: relative;
clear: both; clear: both;
} }
.bootstrap-table .fixed-table-container .table {
width: 100%;
margin-bottom: 0 !important;
}
.bootstrap-table .fixed-table-container .table th,
.bootstrap-table .fixed-table-container .table td {
vertical-align: middle;
box-sizing: border-box;
}
.bootstrap-table .fixed-table-container .table thead th {
vertical-align: bottom;
padding: 0;
margin: 0;
}
.bootstrap-table .fixed-table-container .table thead th:focus {
outline: 0 solid transparent;
}
.bootstrap-table .fixed-table-container .table thead th.detail {
width: 30px;
}
.bootstrap-table .fixed-table-container .table thead th .th-inner {
padding: 0.75rem;
vertical-align: bottom;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.bootstrap-table .fixed-table-container .table thead th .sortable {
cursor: pointer;
background-position: right;
background-repeat: no-repeat;
padding-right: 30px !important;
}
.bootstrap-table .fixed-table-container .table thead th .both {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC");
}
.bootstrap-table .fixed-table-container .table thead th .asc {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==");
}
.bootstrap-table .fixed-table-container .table thead th .desc {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ");
}
.bootstrap-table .fixed-table-container .table tbody tr.selected td {
background-color: rgba(0, 0, 0, 0.075);
}
.bootstrap-table .fixed-table-container .table tbody tr.no-records-found td {
text-align: center;
}
.bootstrap-table .fixed-table-container .table tbody tr .card-view {
display: flex;
}
.bootstrap-table .fixed-table-container .table tbody tr .card-view .card-view-title {
font-weight: bold;
display: inline-block;
min-width: 30%;
width: auto !important;
text-align: left !important;
}
.bootstrap-table .fixed-table-container .table tbody tr .card-view .card-view-value {
width: 100% !important;
}
.bootstrap-table .fixed-table-container .table .bs-checkbox {
text-align: center;
}
.bootstrap-table .fixed-table-container .table .bs-checkbox label {
margin-bottom: 0;
}
.bootstrap-table .fixed-table-container .table .bs-checkbox label input[type="radio"],
.bootstrap-table .fixed-table-container .table .bs-checkbox label input[type="checkbox"] {
margin: 0 auto !important;
}
.bootstrap-table .fixed-table-container .table.table-sm .th-inner {
padding: 0.3rem;
}
.bootstrap-table .fixed-table-container.fixed-height:not(.has-footer) { .bootstrap-table .fixed-table-container.fixed-height:not(.has-footer) {
border-bottom: 1px solid #dee2e6; border-bottom: 1px solid #dee2e6;
} }
.bootstrap-table .fixed-table-container.fixed-height.has-card-view {
border-top: 1px solid #dee2e6;
border-bottom: 1px solid #dee2e6;
}
.bootstrap-table .fixed-table-container.fixed-height .fixed-table-border { .bootstrap-table .fixed-table-container.fixed-height .fixed-table-border {
border-left: 1px solid #dee2e6; border-left: 1px solid #dee2e6;
border-right: 1px solid #dee2e6; border-right: 1px solid #dee2e6;
} }
.bootstrap-table .fixed-table-container.fixed-height .table thead th { .bootstrap-table .fixed-table-container.fixed-height .table thead th {
border-bottom: 1px solid #dee2e6; border-bottom: 1px solid #dee2e6;
} }
.bootstrap-table .fixed-table-container.fixed-height .table-dark thead th { .bootstrap-table .fixed-table-container.fixed-height .table-dark thead th {
border-bottom: 1px solid #32383e; border-bottom: 1px solid #32383e;
} }
.bootstrap-table .fixed-table-container .fixed-table-header { .bootstrap-table .fixed-table-container .fixed-table-header {
overflow: hidden; overflow: hidden;
} }
.bootstrap-table .fixed-table-container .fixed-table-body { .bootstrap-table .fixed-table-container .fixed-table-body {
overflow-x: auto; overflow-x: auto;
overflow-y: auto; overflow-y: auto;
height: 100%; height: 100%;
} }
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading { .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading {
align-items: center; align-items: center;
background: #fff; background: #fff;
display: none; display: flex;
justify-content: center; justify-content: center;
position: absolute; position: absolute;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
z-index: 1000; z-index: 1000;
transition: visibility 0s, opacity 0.15s ease-in-out;
opacity: 0;
visibility: hidden;
} }
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.open {
visibility: visible;
opacity: 1;
}
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap { .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap {
align-items: baseline; align-items: baseline;
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .loading-text { .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .loading-text {
font-size: 2rem;
margin-right: 6px; margin-right: 6px;
} }
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap { .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap {
align-items: center; align-items: center;
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot, .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot,
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap:after, .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after,
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap:before { .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::before {
content: ""; content: "";
animation-duration: 1.5s; animation-duration: 1.5s;
animation-iteration-count: infinite; animation-iteration-count: infinite;
@ -117,139 +245,102 @@
opacity: 0; opacity: 0;
width: 5px; width: 5px;
} }
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot { .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot {
animation-delay: 0.3s; animation-delay: 0.3s;
} }
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap:after {
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after {
animation-delay: 0.6s; animation-delay: 0.6s;
} }
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark { .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark {
background: #212529; background: #212529;
} }
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-dot, .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-dot,
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap:after, .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::after,
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap:before { .bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::before {
background: #fff; background: #fff;
} }
.bootstrap-table .fixed-table-container .table {
width: 100%;
margin-bottom: 0 !important;
}
.bootstrap-table .fixed-table-container .table th,
.bootstrap-table .fixed-table-container .table td {
vertical-align: middle;
box-sizing: border-box;
}
.bootstrap-table .fixed-table-container .table thead th {
vertical-align: bottom;
padding: 0;
margin: 0;
}
.bootstrap-table .fixed-table-container .table thead th:focus {
outline: 0 solid transparent;
}
.bootstrap-table .fixed-table-container .table thead th.detail {
width: 30px;
}
.bootstrap-table .fixed-table-container .table thead th .th-inner {
padding: 0.75rem;
vertical-align: bottom;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.bootstrap-table .fixed-table-container .table thead th .sortable {
cursor: pointer;
background-position: right;
background-repeat: no-repeat;
padding-right: 30px;
}
.bootstrap-table .fixed-table-container .table thead th .both {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC");
}
.bootstrap-table .fixed-table-container .table thead th .asc {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==");
}
.bootstrap-table .fixed-table-container .table thead th .desc {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ");
}
.bootstrap-table .fixed-table-container .table tbody tr.selected td {
background-color: rgba(0, 0, 0, 0.075);
}
.bootstrap-table .fixed-table-container .table tbody tr.no-records-found {
text-align: center;
}
.bootstrap-table .fixed-table-container .table tbody tr .card-view .card-view-title {
font-weight: bold;
display: inline-block;
min-width: 30%;
text-align: left !important;
}
.bootstrap-table .fixed-table-container .table .bs-checkbox {
text-align: center;
}
.bootstrap-table .fixed-table-container .table input[type=radio],
.bootstrap-table .fixed-table-container .table input[type=checkbox] {
margin: 0 auto !important;
}
.bootstrap-table .fixed-table-container .table.table-sm .th-inner {
padding: 0.3rem;
}
.bootstrap-table .fixed-table-container .fixed-table-footer { .bootstrap-table .fixed-table-container .fixed-table-footer {
overflow: hidden; overflow: hidden;
} }
.bootstrap-table .fixed-table-pagination:after {
.bootstrap-table .fixed-table-pagination::after {
content: ""; content: "";
display: block; display: block;
clear: both; clear: both;
} }
.bootstrap-table .fixed-table-pagination > .pagination-detail, .bootstrap-table .fixed-table-pagination > .pagination-detail,
.bootstrap-table .fixed-table-pagination > .pagination { .bootstrap-table .fixed-table-pagination > .pagination {
margin-top: 10px; margin-top: 10px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.bootstrap-table .fixed-table-pagination > .pagination-detail .pagination-info { .bootstrap-table .fixed-table-pagination > .pagination-detail .pagination-info {
line-height: 34px; line-height: 34px;
margin-right: 5px; margin-right: 5px;
} }
.bootstrap-table .fixed-table-pagination > .pagination-detail .page-list { .bootstrap-table .fixed-table-pagination > .pagination-detail .page-list {
display: inline-block; display: inline-block;
} }
.bootstrap-table .fixed-table-pagination > .pagination-detail .page-list .btn-group { .bootstrap-table .fixed-table-pagination > .pagination-detail .page-list .btn-group {
position: relative; position: relative;
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
} }
.bootstrap-table .fixed-table-pagination > .pagination-detail .page-list .btn-group .dropdown-menu { .bootstrap-table .fixed-table-pagination > .pagination-detail .page-list .btn-group .dropdown-menu {
margin-bottom: 0; margin-bottom: 0;
} }
.bootstrap-table .fixed-table-pagination > .pagination ul.pagination { .bootstrap-table .fixed-table-pagination > .pagination ul.pagination {
margin: 0; margin: 0;
} }
.bootstrap-table .fixed-table-pagination > .pagination ul.pagination a {
padding: 6px 12px;
line-height: 1.428571429;
}
.bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a { .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a {
color: #c8c8c8; color: #c8c8c8;
} }
.bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a:before {
content: "⬅"; .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a::before {
content: '\2B05';
} }
.bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a:after {
content: "➡"; .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a::after {
content: '\27A1';
} }
.bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.disabled a { .bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.disabled a {
pointer-events: none; pointer-events: none;
cursor: default; cursor: default;
} }
.bootstrap-table.fullscreen { .bootstrap-table.fullscreen {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
z-index: 1050; z-index: 1050;
width: 100% !important; width: 100% !important;
background: #FFF; background: #fff;
height: calc(100vh);
overflow-y: scroll;
}
.bootstrap-table.bootstrap4 .pagination-lg .page-link, .bootstrap-table.bootstrap5 .pagination-lg .page-link {
padding: .5rem 1rem;
}
.bootstrap-table.bootstrap5 .float-left {
float: left;
}
.bootstrap-table.bootstrap5 .float-right {
float: right;
} }
/* calculate scrollbar width */ /* calculate scrollbar width */
@ -278,5 +369,3 @@ div.fixed-table-scroll-outer {
opacity: 0; opacity: 0;
} }
} }
/*# sourceMappingURL=bootstrap-table.css.map */

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,32 +1,869 @@
/** (function (global, factory) {
* When using server-side processing, the default mode of operation for typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) :
* bootstrap-table is to simply throw away any data that currently exists in the typeof define === 'function' && define.amd ? define(['jquery'], factory) :
* table and make a request to the server to get the first page of data to (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.jQuery));
* display. This is fine for an empty table, but if you already have the first }(this, (function ($) { 'use strict';
* page of data displayed in the plain HTML, it is a waste of resources. As
* such, you can use data-defer-url instead of data-url to allow you to instruct
* bootstrap-table to not make that initial request, rather it will use the data
* already on the page.
*
* @author: Ruben Suarez
* @webSite: http://rubensa.eu.org
* @version: v1.0.0
*/
(function($) { function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
'use strict';
$.extend($.fn.bootstrapTable.defaults, { var $__default = /*#__PURE__*/_interopDefaultLegacy($);
deferUrl : undefined
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
}); });
if (superClass) _setPrototypeOf(subClass, superClass);
}
var BootstrapTable = $.fn.bootstrapTable.Constructor, _init = BootstrapTable.prototype.init; function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
BootstrapTable.prototype.init = function() { function _setPrototypeOf(o, p) {
_init.apply(this, Array.prototype.slice.apply(arguments)); _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _superPropBase(object, property) {
while (!Object.prototype.hasOwnProperty.call(object, property)) {
object = _getPrototypeOf(object);
if (object === null) break;
}
return object;
}
function _get(target, property, receiver) {
if (typeof Reflect !== "undefined" && Reflect.get) {
_get = Reflect.get;
} else {
_get = function _get(target, property, receiver) {
var base = _superPropBase(target, property);
if (!base) return;
var desc = Object.getOwnPropertyDescriptor(base, property);
if (desc.get) {
return desc.get.call(receiver);
}
return desc.value;
};
}
return _get(target, property, receiver || target);
}
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var check = function (it) {
return it && it.Math == Math && it;
};
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
var global_1 =
/* global globalThis -- safe */
check(typeof globalThis == 'object' && globalThis) ||
check(typeof window == 'object' && window) ||
check(typeof self == 'object' && self) ||
check(typeof commonjsGlobal == 'object' && commonjsGlobal) ||
// eslint-disable-next-line no-new-func -- fallback
(function () { return this; })() || Function('return this')();
var fails = function (exec) {
try {
return !!exec();
} catch (error) {
return true;
}
};
// Detect IE8's incomplete defineProperty implementation
var descriptors = !fails(function () {
return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7;
});
var nativePropertyIsEnumerable = {}.propertyIsEnumerable;
var getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
// Nashorn ~ JDK8 bug
var NASHORN_BUG = getOwnPropertyDescriptor$1 && !nativePropertyIsEnumerable.call({ 1: 2 }, 1);
// `Object.prototype.propertyIsEnumerable` method implementation
// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
var f$4 = NASHORN_BUG ? function propertyIsEnumerable(V) {
var descriptor = getOwnPropertyDescriptor$1(this, V);
return !!descriptor && descriptor.enumerable;
} : nativePropertyIsEnumerable;
var objectPropertyIsEnumerable = {
f: f$4
};
var createPropertyDescriptor = function (bitmap, value) {
return {
enumerable: !(bitmap & 1),
configurable: !(bitmap & 2),
writable: !(bitmap & 4),
value: value
};
};
var toString = {}.toString;
var classofRaw = function (it) {
return toString.call(it).slice(8, -1);
};
var split = ''.split;
// fallback for non-array-like ES3 and non-enumerable old V8 strings
var indexedObject = fails(function () {
// throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
// eslint-disable-next-line no-prototype-builtins -- safe
return !Object('z').propertyIsEnumerable(0);
}) ? function (it) {
return classofRaw(it) == 'String' ? split.call(it, '') : Object(it);
} : Object;
// `RequireObjectCoercible` abstract operation
// https://tc39.es/ecma262/#sec-requireobjectcoercible
var requireObjectCoercible = function (it) {
if (it == undefined) throw TypeError("Can't call method on " + it);
return it;
};
// toObject with fallback for non-array-like ES3 strings
var toIndexedObject = function (it) {
return indexedObject(requireObjectCoercible(it));
};
var isObject = function (it) {
return typeof it === 'object' ? it !== null : typeof it === 'function';
};
// `ToPrimitive` abstract operation
// https://tc39.es/ecma262/#sec-toprimitive
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
// and the second argument - flag - preferred type is a string
var toPrimitive = function (input, PREFERRED_STRING) {
if (!isObject(input)) return input;
var fn, val;
if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;
if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
throw TypeError("Can't convert object to primitive value");
};
var hasOwnProperty = {}.hasOwnProperty;
var has$1 = function (it, key) {
return hasOwnProperty.call(it, key);
};
var document = global_1.document;
// typeof document.createElement is 'object' in old IE
var EXISTS = isObject(document) && isObject(document.createElement);
var documentCreateElement = function (it) {
return EXISTS ? document.createElement(it) : {};
};
// Thank's IE8 for his funny defineProperty
var ie8DomDefine = !descriptors && !fails(function () {
return Object.defineProperty(documentCreateElement('div'), 'a', {
get: function () { return 7; }
}).a != 7;
});
var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
// `Object.getOwnPropertyDescriptor` method
// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
var f$3 = descriptors ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
O = toIndexedObject(O);
P = toPrimitive(P, true);
if (ie8DomDefine) try {
return nativeGetOwnPropertyDescriptor(O, P);
} catch (error) { /* empty */ }
if (has$1(O, P)) return createPropertyDescriptor(!objectPropertyIsEnumerable.f.call(O, P), O[P]);
};
var objectGetOwnPropertyDescriptor = {
f: f$3
};
var anObject = function (it) {
if (!isObject(it)) {
throw TypeError(String(it) + ' is not an object');
} return it;
};
var nativeDefineProperty = Object.defineProperty;
// `Object.defineProperty` method
// https://tc39.es/ecma262/#sec-object.defineproperty
var f$2 = descriptors ? nativeDefineProperty : function defineProperty(O, P, Attributes) {
anObject(O);
P = toPrimitive(P, true);
anObject(Attributes);
if (ie8DomDefine) try {
return nativeDefineProperty(O, P, Attributes);
} catch (error) { /* empty */ }
if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
if ('value' in Attributes) O[P] = Attributes.value;
return O;
};
var objectDefineProperty = {
f: f$2
};
var createNonEnumerableProperty = descriptors ? function (object, key, value) {
return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
} : function (object, key, value) {
object[key] = value;
return object;
};
var setGlobal = function (key, value) {
try {
createNonEnumerableProperty(global_1, key, value);
} catch (error) {
global_1[key] = value;
} return value;
};
var SHARED = '__core-js_shared__';
var store$1 = global_1[SHARED] || setGlobal(SHARED, {});
var sharedStore = store$1;
var functionToString = Function.toString;
// this helper broken in `3.4.1-3.4.4`, so we can't use `shared` helper
if (typeof sharedStore.inspectSource != 'function') {
sharedStore.inspectSource = function (it) {
return functionToString.call(it);
};
}
var inspectSource = sharedStore.inspectSource;
var WeakMap$1 = global_1.WeakMap;
var nativeWeakMap = typeof WeakMap$1 === 'function' && /native code/.test(inspectSource(WeakMap$1));
var shared = createCommonjsModule(function (module) {
(module.exports = function (key, value) {
return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
})('versions', []).push({
version: '3.9.1',
mode: 'global',
copyright: '© 2021 Denis Pushkarev (zloirock.ru)'
});
});
var id = 0;
var postfix = Math.random();
var uid = function (key) {
return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);
};
var keys = shared('keys');
var sharedKey = function (key) {
return keys[key] || (keys[key] = uid(key));
};
var hiddenKeys$1 = {};
var WeakMap = global_1.WeakMap;
var set, get, has;
var enforce = function (it) {
return has(it) ? get(it) : set(it, {});
};
var getterFor = function (TYPE) {
return function (it) {
var state;
if (!isObject(it) || (state = get(it)).type !== TYPE) {
throw TypeError('Incompatible receiver, ' + TYPE + ' required');
} return state;
};
};
if (nativeWeakMap) {
var store = sharedStore.state || (sharedStore.state = new WeakMap());
var wmget = store.get;
var wmhas = store.has;
var wmset = store.set;
set = function (it, metadata) {
metadata.facade = it;
wmset.call(store, it, metadata);
return metadata;
};
get = function (it) {
return wmget.call(store, it) || {};
};
has = function (it) {
return wmhas.call(store, it);
};
} else {
var STATE = sharedKey('state');
hiddenKeys$1[STATE] = true;
set = function (it, metadata) {
metadata.facade = it;
createNonEnumerableProperty(it, STATE, metadata);
return metadata;
};
get = function (it) {
return has$1(it, STATE) ? it[STATE] : {};
};
has = function (it) {
return has$1(it, STATE);
};
}
var internalState = {
set: set,
get: get,
has: has,
enforce: enforce,
getterFor: getterFor
};
var redefine = createCommonjsModule(function (module) {
var getInternalState = internalState.get;
var enforceInternalState = internalState.enforce;
var TEMPLATE = String(String).split('String');
(module.exports = function (O, key, value, options) {
var unsafe = options ? !!options.unsafe : false;
var simple = options ? !!options.enumerable : false;
var noTargetGet = options ? !!options.noTargetGet : false;
var state;
if (typeof value == 'function') {
if (typeof key == 'string' && !has$1(value, 'name')) {
createNonEnumerableProperty(value, 'name', key);
}
state = enforceInternalState(value);
if (!state.source) {
state.source = TEMPLATE.join(typeof key == 'string' ? key : '');
}
}
if (O === global_1) {
if (simple) O[key] = value;
else setGlobal(key, value);
return;
} else if (!unsafe) {
delete O[key];
} else if (!noTargetGet && O[key]) {
simple = true;
}
if (simple) O[key] = value;
else createNonEnumerableProperty(O, key, value);
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, 'toString', function toString() {
return typeof this == 'function' && getInternalState(this).source || inspectSource(this);
});
});
var path = global_1;
var aFunction = function (variable) {
return typeof variable == 'function' ? variable : undefined;
};
var getBuiltIn = function (namespace, method) {
return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global_1[namespace])
: path[namespace] && path[namespace][method] || global_1[namespace] && global_1[namespace][method];
};
var ceil = Math.ceil;
var floor = Math.floor;
// `ToInteger` abstract operation
// https://tc39.es/ecma262/#sec-tointeger
var toInteger = function (argument) {
return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);
};
var min$1 = Math.min;
// `ToLength` abstract operation
// https://tc39.es/ecma262/#sec-tolength
var toLength = function (argument) {
return argument > 0 ? min$1(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
};
var max = Math.max;
var min = Math.min;
// Helper for a popular repeating case of the spec:
// Let integer be ? ToInteger(index).
// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
var toAbsoluteIndex = function (index, length) {
var integer = toInteger(index);
return integer < 0 ? max(integer + length, 0) : min(integer, length);
};
// `Array.prototype.{ indexOf, includes }` methods implementation
var createMethod = function (IS_INCLUDES) {
return function ($this, el, fromIndex) {
var O = toIndexedObject($this);
var length = toLength(O.length);
var index = toAbsoluteIndex(fromIndex, length);
var value;
// Array#includes uses SameValueZero equality algorithm
// eslint-disable-next-line no-self-compare -- NaN check
if (IS_INCLUDES && el != el) while (length > index) {
value = O[index++];
// eslint-disable-next-line no-self-compare -- NaN check
if (value != value) return true;
// Array#indexOf ignores holes, Array#includes - not
} else for (;length > index; index++) {
if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
} return !IS_INCLUDES && -1;
};
};
var arrayIncludes = {
// `Array.prototype.includes` method
// https://tc39.es/ecma262/#sec-array.prototype.includes
includes: createMethod(true),
// `Array.prototype.indexOf` method
// https://tc39.es/ecma262/#sec-array.prototype.indexof
indexOf: createMethod(false)
};
var indexOf = arrayIncludes.indexOf;
var objectKeysInternal = function (object, names) {
var O = toIndexedObject(object);
var i = 0;
var result = [];
var key;
for (key in O) !has$1(hiddenKeys$1, key) && has$1(O, key) && result.push(key);
// Don't enum bug & hidden keys
while (names.length > i) if (has$1(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'toLocaleString',
'toString',
'valueOf'
];
var hiddenKeys = enumBugKeys.concat('length', 'prototype');
// `Object.getOwnPropertyNames` method
// https://tc39.es/ecma262/#sec-object.getownpropertynames
var f$1 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
return objectKeysInternal(O, hiddenKeys);
};
var objectGetOwnPropertyNames = {
f: f$1
};
var f = Object.getOwnPropertySymbols;
var objectGetOwnPropertySymbols = {
f: f
};
// all object keys, includes non-enumerable and symbols
var ownKeys = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
var keys = objectGetOwnPropertyNames.f(anObject(it));
var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
};
var copyConstructorProperties = function (target, source) {
var keys = ownKeys(source);
var defineProperty = objectDefineProperty.f;
var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (!has$1(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
}
};
var replacement = /#|\.prototype\./;
var isForced = function (feature, detection) {
var value = data[normalize(feature)];
return value == POLYFILL ? true
: value == NATIVE ? false
: typeof detection == 'function' ? fails(detection)
: !!detection;
};
var normalize = isForced.normalize = function (string) {
return String(string).replace(replacement, '.').toLowerCase();
};
var data = isForced.data = {};
var NATIVE = isForced.NATIVE = 'N';
var POLYFILL = isForced.POLYFILL = 'P';
var isForced_1 = isForced;
var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
/*
options.target - name of the target object
options.global - target is the global object
options.stat - export as static methods of target
options.proto - export as prototype methods of target
options.real - real prototype method for the `pure` version
options.forced - export even if the native feature is available
options.bind - bind methods to the target, required for the `pure` version
options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
options.unsafe - use the simple assignment of property instead of delete + defineProperty
options.sham - add a flag to not completely full polyfills
options.enumerable - export as enumerable property
options.noTargetGet - prevent calling a getter on target
*/
var _export = function (options, source) {
var TARGET = options.target;
var GLOBAL = options.global;
var STATIC = options.stat;
var FORCED, target, key, targetProperty, sourceProperty, descriptor;
if (GLOBAL) {
target = global_1;
} else if (STATIC) {
target = global_1[TARGET] || setGlobal(TARGET, {});
} else {
target = (global_1[TARGET] || {}).prototype;
}
if (target) for (key in source) {
sourceProperty = source[key];
if (options.noTargetGet) {
descriptor = getOwnPropertyDescriptor(target, key);
targetProperty = descriptor && descriptor.value;
} else targetProperty = target[key];
FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
// contained in target
if (!FORCED && targetProperty !== undefined) {
if (typeof sourceProperty === typeof targetProperty) continue;
copyConstructorProperties(sourceProperty, targetProperty);
}
// add a flag to not completely full polyfills
if (options.sham || (targetProperty && targetProperty.sham)) {
createNonEnumerableProperty(sourceProperty, 'sham', true);
}
// extend global
redefine(target, key, sourceProperty, options);
}
};
// `IsArray` abstract operation
// https://tc39.es/ecma262/#sec-isarray
var isArray = Array.isArray || function isArray(arg) {
return classofRaw(arg) == 'Array';
};
// `ToObject` abstract operation
// https://tc39.es/ecma262/#sec-toobject
var toObject = function (argument) {
return Object(requireObjectCoercible(argument));
};
var createProperty = function (object, key, value) {
var propertyKey = toPrimitive(key);
if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value));
else object[propertyKey] = value;
};
var engineIsNode = classofRaw(global_1.process) == 'process';
var engineUserAgent = getBuiltIn('navigator', 'userAgent') || '';
var process = global_1.process;
var versions = process && process.versions;
var v8 = versions && versions.v8;
var match, version;
if (v8) {
match = v8.split('.');
version = match[0] + match[1];
} else if (engineUserAgent) {
match = engineUserAgent.match(/Edge\/(\d+)/);
if (!match || match[1] >= 74) {
match = engineUserAgent.match(/Chrome\/(\d+)/);
if (match) version = match[1];
}
}
var engineV8Version = version && +version;
var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () {
/* global Symbol -- required for testing */
return !Symbol.sham &&
// Chrome 38 Symbol has incorrect toString conversion
// Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
(engineIsNode ? engineV8Version === 38 : engineV8Version > 37 && engineV8Version < 41);
});
var useSymbolAsUid = nativeSymbol
/* global Symbol -- safe */
&& !Symbol.sham
&& typeof Symbol.iterator == 'symbol';
var WellKnownSymbolsStore = shared('wks');
var Symbol$1 = global_1.Symbol;
var createWellKnownSymbol = useSymbolAsUid ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid;
var wellKnownSymbol = function (name) {
if (!has$1(WellKnownSymbolsStore, name) || !(nativeSymbol || typeof WellKnownSymbolsStore[name] == 'string')) {
if (nativeSymbol && has$1(Symbol$1, name)) {
WellKnownSymbolsStore[name] = Symbol$1[name];
} else {
WellKnownSymbolsStore[name] = createWellKnownSymbol('Symbol.' + name);
}
} return WellKnownSymbolsStore[name];
};
var SPECIES$1 = wellKnownSymbol('species');
// `ArraySpeciesCreate` abstract operation
// https://tc39.es/ecma262/#sec-arrayspeciescreate
var arraySpeciesCreate = function (originalArray, length) {
var C;
if (isArray(originalArray)) {
C = originalArray.constructor;
// cross-realm fallback
if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
else if (isObject(C)) {
C = C[SPECIES$1];
if (C === null) C = undefined;
}
} return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
};
var SPECIES = wellKnownSymbol('species');
var arrayMethodHasSpeciesSupport = function (METHOD_NAME) {
// We can't use this feature detection in V8 since it causes
// deoptimization and serious performance degradation
// https://github.com/zloirock/core-js/issues/677
return engineV8Version >= 51 || !fails(function () {
var array = [];
var constructor = array.constructor = {};
constructor[SPECIES] = function () {
return { foo: 1 };
};
return array[METHOD_NAME](Boolean).foo !== 1;
});
};
var IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');
var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';
// We can't use this feature detection in V8 since it causes
// deoptimization and serious performance degradation
// https://github.com/zloirock/core-js/issues/679
var IS_CONCAT_SPREADABLE_SUPPORT = engineV8Version >= 51 || !fails(function () {
var array = [];
array[IS_CONCAT_SPREADABLE] = false;
return array.concat()[0] !== array;
});
var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');
var isConcatSpreadable = function (O) {
if (!isObject(O)) return false;
var spreadable = O[IS_CONCAT_SPREADABLE];
return spreadable !== undefined ? !!spreadable : isArray(O);
};
var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;
// `Array.prototype.concat` method
// https://tc39.es/ecma262/#sec-array.prototype.concat
// with adding support of @@isConcatSpreadable and @@species
_export({ target: 'Array', proto: true, forced: FORCED }, {
// eslint-disable-next-line no-unused-vars -- required for `.length`
concat: function concat(arg) {
var O = toObject(this);
var A = arraySpeciesCreate(O, 0);
var n = 0;
var i, k, length, len, E;
for (i = -1, length = arguments.length; i < length; i++) {
E = i === -1 ? O : arguments[i];
if (isConcatSpreadable(E)) {
len = toLength(E.length);
if (n + len > MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
} else {
if (n >= MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
createProperty(A, n++, E);
}
}
A.length = n;
return A;
}
});
/**
* When using server-side processing, the default mode of operation for
* bootstrap-table is to simply throw away any data that currently exists in the
* table and make a request to the server to get the first page of data to
* display. This is fine for an empty table, but if you already have the first
* page of data displayed in the plain HTML, it is a waste of resources. As
* such, you can use data-defer-url instead of data-url to allow you to instruct
* bootstrap-table to not make that initial request, rather it will use the data
* already on the page.
*
* @author: Ruben Suarez
* @webSite: http://rubensa.eu.org
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
$__default['default'].extend($__default['default'].fn.bootstrapTable.defaults, {
deferUrl: undefined
});
$__default['default'].BootstrapTable = /*#__PURE__*/function (_$$BootstrapTable) {
_inherits(_class, _$$BootstrapTable);
var _super = _createSuper(_class);
function _class() {
_classCallCheck(this, _class);
return _super.apply(this, arguments);
}
_createClass(_class, [{
key: "init",
value: function init() {
var _get2;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
(_get2 = _get(_getPrototypeOf(_class.prototype), "init", this)).call.apply(_get2, [this].concat(args));
if (this.options.deferUrl) { if (this.options.deferUrl) {
this.options.url = this.options.deferUrl; this.options.url = this.options.deferUrl;
} }
} }
})(jQuery); }]);
return _class;
}($__default['default'].BootstrapTable);
})));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,13 +1,13 @@
@charset "UTF-8";
/** /**
* @author: Dennis Hernández * @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog * @webSite: http://djhvscf.github.io/Blog
* @version: v2.1.1 * @version: v2.1.1
*/ */
.no-filter-control { .no-filter-control {
height: 34px; height: 34px;
} }
.filter-control { .filter-control {
margin: 0 2px 2px 2px; margin: 0 2px 2px 2px;
} }

View File

@ -0,0 +1,10 @@
/**
* bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)
*
* @version v1.18.3
* @homepage https://bootstrap-table.com
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
* @license MIT
*/
@charset "UTF-8";.no-filter-control{height:34px}.filter-control{margin:0 2px 2px 2px}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,27 +1,25 @@
.fixed-table-header-columns, .fixed-columns,
.fixed-table-body-columns { .fixed-columns-right {
position: absolute; position: absolute;
top: 0;
height: 100%;
background-color: #fff; background-color: #fff;
box-sizing: border-box; box-sizing: border-box;
overflow: hidden;
z-index: 1; z-index: 1;
} }
.fixed-table-header-columns { .fixed-columns {
z-index: 2; left: 0;
} }
.fixed-table-header-columns .table, .fixed-columns .fixed-table-body {
.fixed-table-body-columns .table { overflow: hidden !important;
border-right: 1px solid #ddd;
} }
.fixed-table-header-columns .table.table-no-bordered, .fixed-columns-right {
.fixed-table-body-columns .table.table-no-bordered { right: 0;
border-right: 1px solid transparent;
} }
.fixed-table-body-columns table { .fixed-columns-right .fixed-table-body {
position: absolute; overflow-x: hidden !important;
animation: none;
} }

View File

@ -0,0 +1,10 @@
/**
* bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)
*
* @version v1.18.3
* @homepage https://bootstrap-table.com
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
* @license MIT
*/
.fixed-columns,.fixed-columns-right{position:absolute;top:0;height:100%;background-color:#fff;box-sizing:border-box;z-index:1}.fixed-columns{left:0}.fixed-columns .fixed-table-body{overflow:hidden!important}.fixed-columns-right{right:0}.fixed-columns-right .fixed-table-body{overflow-x:hidden!important}

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,8 @@
.bootstrap-table .table > tbody > tr.groupBy { .bootstrap-table .table > tbody > tr.groupBy.expanded,
cursor: pointer; .bootstrap-table .table > tbody > tr.groupBy.collapsed {
cursor: pointer;
} }
.bootstrap-table .table > tbody > tr.groupBy.expanded { .bootstrap-table .table > tbody > tr.hidden {
display: none;
}
.bootstrap-table .table > tbody > tr.hidden + tr.detail-view {
display: none;
} }

View File

@ -0,0 +1,10 @@
/**
* bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)
*
* @version v1.18.3
* @homepage https://bootstrap-table.com
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
* @license MIT
*/
.bootstrap-table .table>tbody>tr.groupBy.collapsed,.bootstrap-table .table>tbody>tr.groupBy.expanded{cursor:pointer}.bootstrap-table .table>tbody>tr.hidden{display:none}

File diff suppressed because one or more lines are too long

View File

@ -1,35 +1,159 @@
/** (function (global, factory) {
* @author: Jewway typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) :
* @version: v1.0.0 typeof define === 'function' && define.amd ? define(['jquery'], factory) :
*/ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.jQuery));
}(this, (function ($) { 'use strict';
!function ($) { function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
'use strict';
var BootstrapTable = $.fn.bootstrapTable.Constructor; var $__default = /*#__PURE__*/_interopDefaultLegacy($);
BootstrapTable.prototype.changeTitle = function (locale) { function _classCallCheck(instance, Constructor) {
$.each(this.options.columns, function (idx, columnList) { if (!(instance instanceof Constructor)) {
$.each(columnList, function (idx, column) { throw new TypeError("Cannot call a class as a function");
if (column.field) { }
column.title = locale[column.field]; }
}
}); function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
}); });
this.initHeader(); if (superClass) _setPrototypeOf(subClass, superClass);
this.initBody(); }
this.initToolbar();
};
BootstrapTable.prototype.changeLocale = function (localeId) { function _getPrototypeOf(o) {
this.options.locale = localeId; _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
this.initLocale(); return o.__proto__ || Object.getPrototypeOf(o);
this.initPagination(); };
this.initBody(); return _getPrototypeOf(o);
this.initToolbar(); }
};
$.fn.bootstrapTable.methods.push('changeTitle'); function _setPrototypeOf(o, p) {
$.fn.bootstrapTable.methods.push('changeLocale'); _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
}(jQuery); return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
/**
* @author: Jewway
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
$__default['default'].fn.bootstrapTable.methods.push('changeTitle');
$__default['default'].fn.bootstrapTable.methods.push('changeLocale');
$__default['default'].BootstrapTable = /*#__PURE__*/function (_$$BootstrapTable) {
_inherits(_class, _$$BootstrapTable);
var _super = _createSuper(_class);
function _class() {
_classCallCheck(this, _class);
return _super.apply(this, arguments);
}
_createClass(_class, [{
key: "changeTitle",
value: function changeTitle(locale) {
$__default['default'].each(this.options.columns, function (idx, columnList) {
$__default['default'].each(columnList, function (idx, column) {
if (column.field) {
column.title = locale[column.field];
}
});
});
this.initHeader();
this.initBody();
this.initToolbar();
}
}, {
key: "changeLocale",
value: function changeLocale(localeId) {
this.options.locale = localeId;
this.initLocale();
this.initPagination();
this.initBody();
this.initToolbar();
}
}]);
return _class;
}($__default['default'].BootstrapTable);
})));

View File

@ -0,0 +1,10 @@
/**
* bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)
*
* @version v1.18.3
* @homepage https://bootstrap-table.com
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
* @license MIT
*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).jQuery)}(this,(function(t){"use strict";function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t);function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function r(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function i(t){return(i=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function u(t,e){return(u=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function f(t,e){return!e||"object"!=typeof e&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function c(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,o=i(t);if(e){var r=i(this).constructor;n=Reflect.construct(o,arguments,r)}else n=o.apply(this,arguments);return f(this,n)}}n.default.fn.bootstrapTable.methods.push("changeTitle"),n.default.fn.bootstrapTable.methods.push("changeLocale"),n.default.BootstrapTable=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&u(t,e)}(l,t);var e,i,f,a=c(l);function l(){return o(this,l),a.apply(this,arguments)}return e=l,(i=[{key:"changeTitle",value:function(t){n.default.each(this.options.columns,(function(e,o){n.default.each(o,(function(e,n){n.field&&(n.title=t[n.field])}))})),this.initHeader(),this.initBody(),this.initToolbar()}},{key:"changeLocale",value:function(t){this.options.locale=t,this.initLocale(),this.initPagination(),this.initBody(),this.initToolbar()}}])&&r(e.prototype,i),f&&r(e,f),l}(n.default.BootstrapTable)}));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,11 @@
.jumpto input { .bootstrap-table.bootstrap3 .fixed-table-pagination > .pagination ul.pagination,
height: 31px; .bootstrap-table.bootstrap3 .fixed-table-pagination > .pagination .page-jump-to {
width: 50px; display: inline;
margin-left: 5px; }
margin-right: 5px;
text-align: center; .bootstrap-table .fixed-table-pagination > .pagination .page-jump-to input {
display: inline-block; width: 70px;
margin-left: 5px;
text-align: center;
float: left;
} }

View File

@ -0,0 +1,10 @@
/**
* bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)
*
* @version v1.18.3
* @homepage https://bootstrap-table.com
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
* @license MIT
*/
.bootstrap-table.bootstrap3 .fixed-table-pagination>.pagination .page-jump-to,.bootstrap-table.bootstrap3 .fixed-table-pagination>.pagination ul.pagination{display:inline}.bootstrap-table .fixed-table-pagination>.pagination .page-jump-to input{width:70px;margin-left:5px;text-align:center;float:left}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,14 +1,14 @@
.reorder_rows_onDragClass td { .reorder_rows_onDragClass td {
background-color: #eee; background-color: #eee;
-webkit-box-shadow: 11px 5px 12px 2px #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; -webkit-box-shadow: 11px 5px 12px 2px #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
-webkit-box-shadow: 6px 3px 5px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; -webkit-box-shadow: 6px 3px 5px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
-moz-box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; -moz-box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
-box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; -box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
} }
.reorder_rows_onDragClass td:last-child { .reorder_rows_onDragClass td:last-child {
-webkit-box-shadow: 8px 7px 12px 0 #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; -webkit-box-shadow: 8px 7px 12px 0 #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
-webkit-box-shadow: 1px 8px 6px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset; -webkit-box-shadow: 1px 8px 6px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
-moz-box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset; -moz-box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset;
-box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset; -box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset;
} }

View File

@ -0,0 +1,10 @@
/**
* bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)
*
* @version v1.18.3
* @homepage https://bootstrap-table.com
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
* @license MIT
*/
.reorder_rows_onDragClass td{background-color:#eee;-webkit-box-shadow:11px 5px 12px 2px #333,0 1px 0 #ccc inset,0 -1px 0 #ccc inset;-webkit-box-shadow:6px 3px 5px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset;-moz-box-shadow:6px 4px 5px 1px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset;-box-shadow:6px 4px 5px 1px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset}.reorder_rows_onDragClass td:last-child{-webkit-box-shadow:8px 7px 12px 0 #333,0 1px 0 #ccc inset,0 -1px 0 #ccc inset;-webkit-box-shadow:1px 8px 6px -4px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset;-moz-box-shadow:0 9px 4px -4px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset,-1px 0 0 #ccc inset;-box-shadow:0 9px 4px -4px #555,0 1px 0 #ccc inset,0 -1px 0 #ccc inset,-1px 0 0 #ccc inset}

File diff suppressed because one or more lines are too long

View File

@ -1,72 +1,919 @@
/** (function (global, factory) {
* @author: Dennis Hernández typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) :
* @webSite: http://djhvscf.github.io/Blog typeof define === 'function' && define.amd ? define(['jquery'], factory) :
* @version: v2.0.0 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.jQuery));
*/ }(this, (function ($) { 'use strict';
(function($) { function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
"use strict";
var initResizable = function(that) { var $__default = /*#__PURE__*/_interopDefaultLegacy($);
if (that.options.resizable && !that.options.cardView && !isInit(that)) {
that.$el.resizableColumns(); function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _superPropBase(object, property) {
while (!Object.prototype.hasOwnProperty.call(object, property)) {
object = _getPrototypeOf(object);
if (object === null) break;
}
return object;
}
function _get(target, property, receiver) {
if (typeof Reflect !== "undefined" && Reflect.get) {
_get = Reflect.get;
} else {
_get = function _get(target, property, receiver) {
var base = _superPropBase(target, property);
if (!base) return;
var desc = Object.getOwnPropertyDescriptor(base, property);
if (desc.get) {
return desc.get.call(receiver);
}
return desc.value;
};
}
return _get(target, property, receiver || target);
}
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var check = function (it) {
return it && it.Math == Math && it;
};
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
var global_1 =
/* global globalThis -- safe */
check(typeof globalThis == 'object' && globalThis) ||
check(typeof window == 'object' && window) ||
check(typeof self == 'object' && self) ||
check(typeof commonjsGlobal == 'object' && commonjsGlobal) ||
// eslint-disable-next-line no-new-func -- fallback
(function () { return this; })() || Function('return this')();
var fails = function (exec) {
try {
return !!exec();
} catch (error) {
return true;
} }
}; };
var reInitResizable = function(that) { // Detect IE8's incomplete defineProperty implementation
var descriptors = !fails(function () {
return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7;
});
var nativePropertyIsEnumerable = {}.propertyIsEnumerable;
var getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
// Nashorn ~ JDK8 bug
var NASHORN_BUG = getOwnPropertyDescriptor$1 && !nativePropertyIsEnumerable.call({ 1: 2 }, 1);
// `Object.prototype.propertyIsEnumerable` method implementation
// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
var f$4 = NASHORN_BUG ? function propertyIsEnumerable(V) {
var descriptor = getOwnPropertyDescriptor$1(this, V);
return !!descriptor && descriptor.enumerable;
} : nativePropertyIsEnumerable;
var objectPropertyIsEnumerable = {
f: f$4
};
var createPropertyDescriptor = function (bitmap, value) {
return {
enumerable: !(bitmap & 1),
configurable: !(bitmap & 2),
writable: !(bitmap & 4),
value: value
};
};
var toString = {}.toString;
var classofRaw = function (it) {
return toString.call(it).slice(8, -1);
};
var split = ''.split;
// fallback for non-array-like ES3 and non-enumerable old V8 strings
var indexedObject = fails(function () {
// throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
// eslint-disable-next-line no-prototype-builtins -- safe
return !Object('z').propertyIsEnumerable(0);
}) ? function (it) {
return classofRaw(it) == 'String' ? split.call(it, '') : Object(it);
} : Object;
// `RequireObjectCoercible` abstract operation
// https://tc39.es/ecma262/#sec-requireobjectcoercible
var requireObjectCoercible = function (it) {
if (it == undefined) throw TypeError("Can't call method on " + it);
return it;
};
// toObject with fallback for non-array-like ES3 strings
var toIndexedObject = function (it) {
return indexedObject(requireObjectCoercible(it));
};
var isObject = function (it) {
return typeof it === 'object' ? it !== null : typeof it === 'function';
};
// `ToPrimitive` abstract operation
// https://tc39.es/ecma262/#sec-toprimitive
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
// and the second argument - flag - preferred type is a string
var toPrimitive = function (input, PREFERRED_STRING) {
if (!isObject(input)) return input;
var fn, val;
if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;
if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
throw TypeError("Can't convert object to primitive value");
};
var hasOwnProperty = {}.hasOwnProperty;
var has$1 = function (it, key) {
return hasOwnProperty.call(it, key);
};
var document = global_1.document;
// typeof document.createElement is 'object' in old IE
var EXISTS = isObject(document) && isObject(document.createElement);
var documentCreateElement = function (it) {
return EXISTS ? document.createElement(it) : {};
};
// Thank's IE8 for his funny defineProperty
var ie8DomDefine = !descriptors && !fails(function () {
return Object.defineProperty(documentCreateElement('div'), 'a', {
get: function () { return 7; }
}).a != 7;
});
var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
// `Object.getOwnPropertyDescriptor` method
// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
var f$3 = descriptors ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
O = toIndexedObject(O);
P = toPrimitive(P, true);
if (ie8DomDefine) try {
return nativeGetOwnPropertyDescriptor(O, P);
} catch (error) { /* empty */ }
if (has$1(O, P)) return createPropertyDescriptor(!objectPropertyIsEnumerable.f.call(O, P), O[P]);
};
var objectGetOwnPropertyDescriptor = {
f: f$3
};
var anObject = function (it) {
if (!isObject(it)) {
throw TypeError(String(it) + ' is not an object');
} return it;
};
var nativeDefineProperty = Object.defineProperty;
// `Object.defineProperty` method
// https://tc39.es/ecma262/#sec-object.defineproperty
var f$2 = descriptors ? nativeDefineProperty : function defineProperty(O, P, Attributes) {
anObject(O);
P = toPrimitive(P, true);
anObject(Attributes);
if (ie8DomDefine) try {
return nativeDefineProperty(O, P, Attributes);
} catch (error) { /* empty */ }
if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
if ('value' in Attributes) O[P] = Attributes.value;
return O;
};
var objectDefineProperty = {
f: f$2
};
var createNonEnumerableProperty = descriptors ? function (object, key, value) {
return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
} : function (object, key, value) {
object[key] = value;
return object;
};
var setGlobal = function (key, value) {
try {
createNonEnumerableProperty(global_1, key, value);
} catch (error) {
global_1[key] = value;
} return value;
};
var SHARED = '__core-js_shared__';
var store$1 = global_1[SHARED] || setGlobal(SHARED, {});
var sharedStore = store$1;
var functionToString = Function.toString;
// this helper broken in `3.4.1-3.4.4`, so we can't use `shared` helper
if (typeof sharedStore.inspectSource != 'function') {
sharedStore.inspectSource = function (it) {
return functionToString.call(it);
};
}
var inspectSource = sharedStore.inspectSource;
var WeakMap$1 = global_1.WeakMap;
var nativeWeakMap = typeof WeakMap$1 === 'function' && /native code/.test(inspectSource(WeakMap$1));
var shared = createCommonjsModule(function (module) {
(module.exports = function (key, value) {
return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
})('versions', []).push({
version: '3.9.1',
mode: 'global',
copyright: '© 2021 Denis Pushkarev (zloirock.ru)'
});
});
var id = 0;
var postfix = Math.random();
var uid = function (key) {
return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);
};
var keys = shared('keys');
var sharedKey = function (key) {
return keys[key] || (keys[key] = uid(key));
};
var hiddenKeys$1 = {};
var WeakMap = global_1.WeakMap;
var set, get, has;
var enforce = function (it) {
return has(it) ? get(it) : set(it, {});
};
var getterFor = function (TYPE) {
return function (it) {
var state;
if (!isObject(it) || (state = get(it)).type !== TYPE) {
throw TypeError('Incompatible receiver, ' + TYPE + ' required');
} return state;
};
};
if (nativeWeakMap) {
var store = sharedStore.state || (sharedStore.state = new WeakMap());
var wmget = store.get;
var wmhas = store.has;
var wmset = store.set;
set = function (it, metadata) {
metadata.facade = it;
wmset.call(store, it, metadata);
return metadata;
};
get = function (it) {
return wmget.call(store, it) || {};
};
has = function (it) {
return wmhas.call(store, it);
};
} else {
var STATE = sharedKey('state');
hiddenKeys$1[STATE] = true;
set = function (it, metadata) {
metadata.facade = it;
createNonEnumerableProperty(it, STATE, metadata);
return metadata;
};
get = function (it) {
return has$1(it, STATE) ? it[STATE] : {};
};
has = function (it) {
return has$1(it, STATE);
};
}
var internalState = {
set: set,
get: get,
has: has,
enforce: enforce,
getterFor: getterFor
};
var redefine = createCommonjsModule(function (module) {
var getInternalState = internalState.get;
var enforceInternalState = internalState.enforce;
var TEMPLATE = String(String).split('String');
(module.exports = function (O, key, value, options) {
var unsafe = options ? !!options.unsafe : false;
var simple = options ? !!options.enumerable : false;
var noTargetGet = options ? !!options.noTargetGet : false;
var state;
if (typeof value == 'function') {
if (typeof key == 'string' && !has$1(value, 'name')) {
createNonEnumerableProperty(value, 'name', key);
}
state = enforceInternalState(value);
if (!state.source) {
state.source = TEMPLATE.join(typeof key == 'string' ? key : '');
}
}
if (O === global_1) {
if (simple) O[key] = value;
else setGlobal(key, value);
return;
} else if (!unsafe) {
delete O[key];
} else if (!noTargetGet && O[key]) {
simple = true;
}
if (simple) O[key] = value;
else createNonEnumerableProperty(O, key, value);
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, 'toString', function toString() {
return typeof this == 'function' && getInternalState(this).source || inspectSource(this);
});
});
var path = global_1;
var aFunction = function (variable) {
return typeof variable == 'function' ? variable : undefined;
};
var getBuiltIn = function (namespace, method) {
return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global_1[namespace])
: path[namespace] && path[namespace][method] || global_1[namespace] && global_1[namespace][method];
};
var ceil = Math.ceil;
var floor = Math.floor;
// `ToInteger` abstract operation
// https://tc39.es/ecma262/#sec-tointeger
var toInteger = function (argument) {
return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);
};
var min$1 = Math.min;
// `ToLength` abstract operation
// https://tc39.es/ecma262/#sec-tolength
var toLength = function (argument) {
return argument > 0 ? min$1(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
};
var max = Math.max;
var min = Math.min;
// Helper for a popular repeating case of the spec:
// Let integer be ? ToInteger(index).
// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
var toAbsoluteIndex = function (index, length) {
var integer = toInteger(index);
return integer < 0 ? max(integer + length, 0) : min(integer, length);
};
// `Array.prototype.{ indexOf, includes }` methods implementation
var createMethod = function (IS_INCLUDES) {
return function ($this, el, fromIndex) {
var O = toIndexedObject($this);
var length = toLength(O.length);
var index = toAbsoluteIndex(fromIndex, length);
var value;
// Array#includes uses SameValueZero equality algorithm
// eslint-disable-next-line no-self-compare -- NaN check
if (IS_INCLUDES && el != el) while (length > index) {
value = O[index++];
// eslint-disable-next-line no-self-compare -- NaN check
if (value != value) return true;
// Array#indexOf ignores holes, Array#includes - not
} else for (;length > index; index++) {
if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
} return !IS_INCLUDES && -1;
};
};
var arrayIncludes = {
// `Array.prototype.includes` method
// https://tc39.es/ecma262/#sec-array.prototype.includes
includes: createMethod(true),
// `Array.prototype.indexOf` method
// https://tc39.es/ecma262/#sec-array.prototype.indexof
indexOf: createMethod(false)
};
var indexOf = arrayIncludes.indexOf;
var objectKeysInternal = function (object, names) {
var O = toIndexedObject(object);
var i = 0;
var result = [];
var key;
for (key in O) !has$1(hiddenKeys$1, key) && has$1(O, key) && result.push(key);
// Don't enum bug & hidden keys
while (names.length > i) if (has$1(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'toLocaleString',
'toString',
'valueOf'
];
var hiddenKeys = enumBugKeys.concat('length', 'prototype');
// `Object.getOwnPropertyNames` method
// https://tc39.es/ecma262/#sec-object.getownpropertynames
var f$1 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
return objectKeysInternal(O, hiddenKeys);
};
var objectGetOwnPropertyNames = {
f: f$1
};
var f = Object.getOwnPropertySymbols;
var objectGetOwnPropertySymbols = {
f: f
};
// all object keys, includes non-enumerable and symbols
var ownKeys = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
var keys = objectGetOwnPropertyNames.f(anObject(it));
var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
};
var copyConstructorProperties = function (target, source) {
var keys = ownKeys(source);
var defineProperty = objectDefineProperty.f;
var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (!has$1(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
}
};
var replacement = /#|\.prototype\./;
var isForced = function (feature, detection) {
var value = data[normalize(feature)];
return value == POLYFILL ? true
: value == NATIVE ? false
: typeof detection == 'function' ? fails(detection)
: !!detection;
};
var normalize = isForced.normalize = function (string) {
return String(string).replace(replacement, '.').toLowerCase();
};
var data = isForced.data = {};
var NATIVE = isForced.NATIVE = 'N';
var POLYFILL = isForced.POLYFILL = 'P';
var isForced_1 = isForced;
var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
/*
options.target - name of the target object
options.global - target is the global object
options.stat - export as static methods of target
options.proto - export as prototype methods of target
options.real - real prototype method for the `pure` version
options.forced - export even if the native feature is available
options.bind - bind methods to the target, required for the `pure` version
options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
options.unsafe - use the simple assignment of property instead of delete + defineProperty
options.sham - add a flag to not completely full polyfills
options.enumerable - export as enumerable property
options.noTargetGet - prevent calling a getter on target
*/
var _export = function (options, source) {
var TARGET = options.target;
var GLOBAL = options.global;
var STATIC = options.stat;
var FORCED, target, key, targetProperty, sourceProperty, descriptor;
if (GLOBAL) {
target = global_1;
} else if (STATIC) {
target = global_1[TARGET] || setGlobal(TARGET, {});
} else {
target = (global_1[TARGET] || {}).prototype;
}
if (target) for (key in source) {
sourceProperty = source[key];
if (options.noTargetGet) {
descriptor = getOwnPropertyDescriptor(target, key);
targetProperty = descriptor && descriptor.value;
} else targetProperty = target[key];
FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
// contained in target
if (!FORCED && targetProperty !== undefined) {
if (typeof sourceProperty === typeof targetProperty) continue;
copyConstructorProperties(sourceProperty, targetProperty);
}
// add a flag to not completely full polyfills
if (options.sham || (targetProperty && targetProperty.sham)) {
createNonEnumerableProperty(sourceProperty, 'sham', true);
}
// extend global
redefine(target, key, sourceProperty, options);
}
};
// `IsArray` abstract operation
// https://tc39.es/ecma262/#sec-isarray
var isArray = Array.isArray || function isArray(arg) {
return classofRaw(arg) == 'Array';
};
// `ToObject` abstract operation
// https://tc39.es/ecma262/#sec-toobject
var toObject = function (argument) {
return Object(requireObjectCoercible(argument));
};
var createProperty = function (object, key, value) {
var propertyKey = toPrimitive(key);
if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value));
else object[propertyKey] = value;
};
var engineIsNode = classofRaw(global_1.process) == 'process';
var engineUserAgent = getBuiltIn('navigator', 'userAgent') || '';
var process = global_1.process;
var versions = process && process.versions;
var v8 = versions && versions.v8;
var match, version;
if (v8) {
match = v8.split('.');
version = match[0] + match[1];
} else if (engineUserAgent) {
match = engineUserAgent.match(/Edge\/(\d+)/);
if (!match || match[1] >= 74) {
match = engineUserAgent.match(/Chrome\/(\d+)/);
if (match) version = match[1];
}
}
var engineV8Version = version && +version;
var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () {
/* global Symbol -- required for testing */
return !Symbol.sham &&
// Chrome 38 Symbol has incorrect toString conversion
// Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
(engineIsNode ? engineV8Version === 38 : engineV8Version > 37 && engineV8Version < 41);
});
var useSymbolAsUid = nativeSymbol
/* global Symbol -- safe */
&& !Symbol.sham
&& typeof Symbol.iterator == 'symbol';
var WellKnownSymbolsStore = shared('wks');
var Symbol$1 = global_1.Symbol;
var createWellKnownSymbol = useSymbolAsUid ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid;
var wellKnownSymbol = function (name) {
if (!has$1(WellKnownSymbolsStore, name) || !(nativeSymbol || typeof WellKnownSymbolsStore[name] == 'string')) {
if (nativeSymbol && has$1(Symbol$1, name)) {
WellKnownSymbolsStore[name] = Symbol$1[name];
} else {
WellKnownSymbolsStore[name] = createWellKnownSymbol('Symbol.' + name);
}
} return WellKnownSymbolsStore[name];
};
var SPECIES$1 = wellKnownSymbol('species');
// `ArraySpeciesCreate` abstract operation
// https://tc39.es/ecma262/#sec-arrayspeciescreate
var arraySpeciesCreate = function (originalArray, length) {
var C;
if (isArray(originalArray)) {
C = originalArray.constructor;
// cross-realm fallback
if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
else if (isObject(C)) {
C = C[SPECIES$1];
if (C === null) C = undefined;
}
} return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
};
var SPECIES = wellKnownSymbol('species');
var arrayMethodHasSpeciesSupport = function (METHOD_NAME) {
// We can't use this feature detection in V8 since it causes
// deoptimization and serious performance degradation
// https://github.com/zloirock/core-js/issues/677
return engineV8Version >= 51 || !fails(function () {
var array = [];
var constructor = array.constructor = {};
constructor[SPECIES] = function () {
return { foo: 1 };
};
return array[METHOD_NAME](Boolean).foo !== 1;
});
};
var IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');
var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';
// We can't use this feature detection in V8 since it causes
// deoptimization and serious performance degradation
// https://github.com/zloirock/core-js/issues/679
var IS_CONCAT_SPREADABLE_SUPPORT = engineV8Version >= 51 || !fails(function () {
var array = [];
array[IS_CONCAT_SPREADABLE] = false;
return array.concat()[0] !== array;
});
var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');
var isConcatSpreadable = function (O) {
if (!isObject(O)) return false;
var spreadable = O[IS_CONCAT_SPREADABLE];
return spreadable !== undefined ? !!spreadable : isArray(O);
};
var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;
// `Array.prototype.concat` method
// https://tc39.es/ecma262/#sec-array.prototype.concat
// with adding support of @@isConcatSpreadable and @@species
_export({ target: 'Array', proto: true, forced: FORCED }, {
// eslint-disable-next-line no-unused-vars -- required for `.length`
concat: function concat(arg) {
var O = toObject(this);
var A = arraySpeciesCreate(O, 0);
var n = 0;
var i, k, length, len, E;
for (i = -1, length = arguments.length; i < length; i++) {
E = i === -1 ? O : arguments[i];
if (isConcatSpreadable(E)) {
len = toLength(E.length);
if (n + len > MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
} else {
if (n >= MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
createProperty(A, n++, E);
}
}
A.length = n;
return A;
}
});
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v2.0.0
*/
var isInit = function isInit(that) {
return that.$el.data('resizableColumns') !== undefined;
};
var initResizable = function initResizable(that) {
if (that.options.resizable && !that.options.cardView && !isInit(that) && that.$el.is(':visible')) {
that.$el.resizableColumns({
store: window.store
});
}
};
var destroy = function destroy(that) {
if (isInit(that)) {
that.$el.data('resizableColumns').destroy();
}
};
var reInitResizable = function reInitResizable(that) {
destroy(that); destroy(that);
initResizable(that); initResizable(that);
}; };
var destroy = function(that) { $__default['default'].extend($__default['default'].fn.bootstrapTable.defaults, {
if (isInit(that)) {
that.$el.data("resizableColumns").destroy();
}
};
var isInit = function(that) {
return that.$el.data("resizableColumns") !== undefined;
};
$.extend($.fn.bootstrapTable.defaults, {
resizable: false resizable: false
}); });
var BootstrapTable = $.fn.bootstrapTable.Constructor, $__default['default'].BootstrapTable = /*#__PURE__*/function (_$$BootstrapTable) {
_initBody = BootstrapTable.prototype.initBody, _inherits(_class, _$$BootstrapTable);
_toggleView = BootstrapTable.prototype.toggleView,
_resetView = BootstrapTable.prototype.resetView;
BootstrapTable.prototype.initBody = function() { var _super = _createSuper(_class);
var that = this;
_initBody.apply(this, Array.prototype.slice.apply(arguments));
that.$el function _class() {
.off("column-switch.bs.table, page-change.bs.table") _classCallCheck(this, _class);
.on("column-switch.bs.table, page-change.bs.table", function() {
reInitResizable(that);
});
};
BootstrapTable.prototype.toggleView = function() { return _super.apply(this, arguments);
_toggleView.apply(this, Array.prototype.slice.apply(arguments));
if (this.options.resizable && this.options.cardView) {
//Destroy the plugin
destroy(this);
} }
};
BootstrapTable.prototype.resetView = function() { _createClass(_class, [{
var that = this; key: "initBody",
value: function initBody() {
var _get2,
_this = this;
_resetView.apply(this, Array.prototype.slice.apply(arguments)); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
if (this.options.resizable) { (_get2 = _get(_getPrototypeOf(_class.prototype), "initBody", this)).call.apply(_get2, [this].concat(args));
// because in fitHeader function, we use setTimeout(func, 100);
setTimeout(function() { this.$el.off('column-switch.bs.table page-change.bs.table').on('column-switch.bs.table page-change.bs.table', function () {
initResizable(that); reInitResizable(_this);
}, 100); });
} }
}; }, {
})(jQuery); key: "toggleView",
value: function toggleView() {
var _get3;
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
(_get3 = _get(_getPrototypeOf(_class.prototype), "toggleView", this)).call.apply(_get3, [this].concat(args));
if (this.options.resizable && this.options.cardView) {
// Destroy the plugin
destroy(this);
}
}
}, {
key: "resetView",
value: function resetView() {
var _get4,
_this2 = this;
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
(_get4 = _get(_getPrototypeOf(_class.prototype), "resetView", this)).call.apply(_get4, [this].concat(args));
if (this.options.resizable) {
// because in fitHeader function, we use setTimeout(func, 100);
setTimeout(function () {
initResizable(_this2);
}, 100);
}
}
}]);
return _class;
}($__default['default'].BootstrapTable);
})));

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,6 @@
* @author vincent loh <vincent.ml@gmail.com> * @author vincent loh <vincent.ml@gmail.com>
* @update zhixin wen <wenzhixin2010@gmail.com> * @update zhixin wen <wenzhixin2010@gmail.com>
*/ */
.fix-sticky { .fix-sticky {
position: fixed !important; position: fixed !important;
overflow: hidden; overflow: hidden;
@ -17,6 +16,6 @@
background: #e9ecef; background: #e9ecef;
} }
.fix-sticky table thead.thead-light { .fix-sticky table thead.thead-dark {
background: #212529; background: #212529;
} }

View File

@ -0,0 +1,10 @@
/**
* bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)
*
* @version v1.18.3
* @homepage https://bootstrap-table.com
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
* @license MIT
*/
.fix-sticky{position:fixed!important;overflow:hidden;z-index:100}.fix-sticky table thead{background:#fff}.fix-sticky table thead.thead-light{background:#e9ecef}.fix-sticky table thead.thead-dark{background:#212529}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,13 +0,0 @@
@charset "UTF-8";
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v2.1.1
*/
.no-filter-control {
height: 34px;
}
.filter-control {
margin: 0 2px 2px 2px;
}

View File

@ -1,11 +0,0 @@
.bootstrap-table .table > tbody > tr.groupBy {
cursor: pointer;
}
.bootstrap-table .table > tbody > tr.groupBy.expanded {
}
.bootstrap-table .table > tbody > tr.hidden + tr.detail-view {
display: none;
}

View File

@ -466,6 +466,24 @@
background: #eee; background: #eee;
} }
/* pricing table widths */
.table-price-two tr td:first-child {
width: 40%;
}
.table-price-three tr td:first-child {
width: 40%;
}
.table-price-two tr td:last-child {
width: 60%;
}
.table-price-three tr td:last-child {
width: 30%;
}
/* !pricing table widths */
.btn-glyph { .btn-glyph {
padding-left: 6px; padding-left: 6px;
padding-right: 6px; padding-right: 6px;
@ -489,7 +507,7 @@
padding-right: 6px; padding-right: 6px;
padding-top: 3px; padding-top: 3px;
padding-bottom: 2px; padding-bottom: 2px;
}; }
.panel-heading .badge { .panel-heading .badge {
float: right; float: right;
@ -550,7 +568,7 @@
} }
.media { .media {
//padding-top: 15px; /* padding-top: 15px; */
overflow: visible; overflow: visible;
} }
@ -576,8 +594,8 @@
width: 160px; width: 160px;
position: fixed; position: fixed;
z-index: 1; z-index: 1;
//top: 0; /* top: 0;
//left: 0; left: 0; */
overflow-x: hidden; overflow-x: hidden;
padding-top: 20px; padding-top: 20px;
padding-right: 25px; padding-right: 25px;
@ -808,7 +826,7 @@ input[type="submit"] {
width: 100%; width: 100%;
padding: 20px; padding: 20px;
z-index: 5000; z-index: 5000;
pointer-events: none; // Prevent this div from blocking links underneath pointer-events: none; /* Prevent this div from blocking links underneath */
} }
.alert { .alert {
@ -883,6 +901,15 @@ input[type="submit"] {
color: #e00; color: #e00;
} }
.info-messages {
padding: 5px;
}
.info-messages .alert {
padding: 5px;
margin-bottom: 10px;
}
.part-allocation { .part-allocation {
padding: 3px 10px; padding: 3px 10px;
border: 1px solid #ccc; border: 1px solid #ccc;
@ -919,3 +946,18 @@ input[type="submit"] {
input[type="date"].form-control, input[type="time"].form-control, input[type="datetime-local"].form-control, input[type="month"].form-control { input[type="date"].form-control, input[type="time"].form-control, input[type="datetime-local"].form-control, input[type="month"].form-control {
line-height: unset; line-height: unset;
} }
.clip-btn {
font-size: 10px;
padding: 0px 6px;
color: var(--label-grey);
background: none;
}
.clip-btn:hover {
background: var(--label-grey);
}
.sidebar-icon {
min-width: 19px;
}

View File

@ -1,7 +0,0 @@
/*
* bootstrap-table - v1.12.1 - 2018-03-12
* https://github.com/wenzhixin/bootstrap-table
* Copyright (c) 2018 zhixin wen
* Licensed MIT License
*/
!function(a){"use strict";a.fn.bootstrapTable.locales["en-US"]={formatLoadingMessage:function(){return"Loading, please wait..."},formatRecordsPerPage:function(a){return a+" rows per page"},formatShowingRows:function(a,b,c){return"Showing "+a+" to "+b+" of "+c+" rows"},formatSearch:function(){return"Search"},formatNoMatches:function(){return"No matching records found"},formatPaginationSwitch:function(){return"Hide/Show pagination"},formatRefresh:function(){return"Refresh"},formatToggle:function(){return"Toggle"},formatColumns:function(){return"Columns"},formatAllRows:function(){return"All"},formatExport:function(){return"Export data"},formatClearFilters:function(){return"Clear filters"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["en-US"])}(jQuery);

View File

@ -1,269 +0,0 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define([], factory);
} else if (typeof exports !== "undefined") {
factory();
} else {
var mod = {
exports: {}
};
factory();
global.bootstrapTableGroupBy = mod.exports;
}
})(this, function () {
'use strict';
/**
* @author: Yura Knoxville
* @version: v1.1.0
*/
(function ($) {
'use strict';
var initBodyCaller, tableGroups;
// it only does '%s', and return '' when arguments are undefined
var sprintf = function sprintf(str) {
var args = arguments,
flag = true,
i = 1;
str = str.replace(/%s/g, function () {
var arg = args[i++];
if (typeof arg === 'undefined') {
flag = false;
return '';
}
return arg;
});
return flag ? str : '';
};
var groupBy = function groupBy(array, f) {
var groups = {};
array.forEach(function (o) {
var group = f(o);
groups[group] = groups[group] || [];
groups[group].push(o);
});
return groups;
};
$.extend($.fn.bootstrapTable.defaults, {
groupBy: false,
groupByField: '',
groupByFormatter: undefined
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initSort = BootstrapTable.prototype.initSort,
_initBody = BootstrapTable.prototype.initBody,
_updateSelected = BootstrapTable.prototype.updateSelected;
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
BootstrapTable.prototype.initSort = function () {
_initSort.apply(this, Array.prototype.slice.apply(arguments));
var that = this;
tableGroups = [];
/* Sort the items into groups */
if (this.options.groupBy && this.options.groupByField !== '') {
var that = this;
var groups = groupBy(that.data, function (item) {
return [item[that.options.groupByField]];
});
var index = 0;
$.each(groups, function (key, value) {
tableGroups.push({
id: index,
name: key,
data: value
});
value.forEach(function (item) {
if (!item._data) {
item._data = {};
}
if (value.length > 1) {
item._data['parent-index'] = index;
} else {
item._data['parent-index'] = null;
}
item._data['group-data'] = value;
item._data['table'] = that;
});
index++;
});
}
};
BootstrapTable.prototype.initBody = function () {
initBodyCaller = true;
_initBody.apply(this, Array.prototype.slice.apply(arguments));
if (this.options.groupBy && this.options.groupByField !== '') {
var that = this,
checkBox = false,
visibleColumns = 0;
var cols = [];
this.columns.forEach(function (column) {
if (column.checkbox) {
checkBox = true;
} else {
if (column.visible) {
visibleColumns += 1;
cols.push(column);
}
}
});
if (this.options.detailView && !this.options.cardView) {
visibleColumns += 1;
}
tableGroups.forEach(function (item) {
var html = [];
html.push(sprintf('<tr class="info groupBy expanded" data-group-index="%s">', item.id));
if (that.options.detailView && !that.options.cardView) {
html.push('<td class="detail"></td>');
}
if (checkBox) {
html.push('<td class="bs-checkbox">', '<input name="btSelectGroup" type="checkbox" />', '</td>');
}
cols.forEach(function(col) {
var cell = '<td>';
if (typeof that.options.groupByFormatter == 'function') {
cell += '<i>' + that.options.groupByFormatter(col.field, item.id, item.data) + "</i>";
}
cell += "</td>";
html.push(cell);
});
/*
var formattedValue = item.name;
if (typeof that.options.groupByFormatter == "function") {
formattedValue = that.options.groupByFormatter(item.name, item.id, item.data);
}
html.push('<td', sprintf(' colspan="%s"', visibleColumns), '>', formattedValue, '</td>');
cols.forEach(function(col) {
html.push('<td>' + item.data[0][col.field] + '</td>');
});
*/
html.push('</tr>');
if(item.data.length > 1) {
that.$body.find('tr[data-parent-index=' + item.id + ']').addClass('hidden stock-sub-group');
// Insert the group header row before the first item
that.$body.find('tr[data-parent-index=' + item.id + ']:first').before($(html.join('')));
}
});
this.$selectGroup = [];
this.$body.find('[name="btSelectGroup"]').each(function () {
var self = $(this);
that.$selectGroup.push({
group: self,
item: that.$selectItem.filter(function () {
return $(this).closest('tr').data('parent-index') === self.closest('tr').data('group-index');
})
});
});
this.$container.off('click', '.groupBy').on('click', '.groupBy', function () {
$(this).toggleClass('expanded');
that.$body.find('tr[data-parent-index=' + $(this).closest('tr').data('group-index') + ']').toggleClass('hidden');
});
this.$container.off('click', '[name="btSelectGroup"]').on('click', '[name="btSelectGroup"]', function (event) {
event.stopImmediatePropagation();
var self = $(this);
var checked = self.prop('checked');
that[checked ? 'checkGroup' : 'uncheckGroup']($(this).closest('tr').data('group-index'));
});
}
initBodyCaller = false;
this.updateSelected();
};
BootstrapTable.prototype.updateSelected = function () {
if (!initBodyCaller) {
_updateSelected.apply(this, Array.prototype.slice.apply(arguments));
if (this.options.groupBy && this.options.groupByField !== '') {
this.$selectGroup.forEach(function (item) {
var checkGroup = item.item.filter(':enabled').length === item.item.filter(':enabled').filter(':checked').length;
item.group.prop('checked', checkGroup);
});
}
}
};
BootstrapTable.prototype.getGroupSelections = function (index) {
var that = this;
return $.grep(this.data, function (row) {
return row[that.header.stateField] && row._data['parent-index'] === index;
});
};
BootstrapTable.prototype.checkGroup = function (index) {
this.checkGroup_(index, true);
};
BootstrapTable.prototype.uncheckGroup = function (index) {
this.checkGroup_(index, false);
};
BootstrapTable.prototype.checkGroup_ = function (index, checked) {
var rows;
var filter = function filter() {
return $(this).closest('tr').data('parent-index') === index;
};
if (!checked) {
rows = this.getGroupSelections(index);
}
this.$selectItem.filter(filter).prop('checked', checked);
this.updateRows();
this.updateSelected();
if (checked) {
rows = this.getGroupSelections(index);
}
this.trigger(checked ? 'check-all' : 'uncheck-all', rows);
};
})(jQuery);
});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,30 @@
function attachClipboard(selector, containerselector, textElement) {
// set container
if (containerselector){
containerselector = document.getElementById(containerselector);
} else {
containerselector = document.body;
}
// set text-function
if (textElement){
text = function() {
return document.getElementById(textElement).textContent;
}
} else {
text = function(trigger) {
var content = trigger.parentElement.parentElement.textContent;return content.trim();
}
}
// create Clipboard
var cis = new ClipboardJS(selector, {
text: text,
container: containerselector
});
}
function inventreeDocReady() { function inventreeDocReady() {
/* Run this function when the HTML document is loaded. /* Run this function when the HTML document is loaded.
* This will be called for every page that extends "base.html" * This will be called for every page that extends "base.html"
@ -48,6 +75,11 @@ function inventreeDocReady() {
no_post: true, no_post: true,
}); });
}); });
// Initialize clipboard-buttons
attachClipboard('.clip-btn');
attachClipboard('.clip-btn', 'modal-about'); // modals
attachClipboard('.clip-btn-version', 'modal-about', 'about-copy-text'); // version-text
} }
function isFileTransfer(transfer) { function isFileTransfer(transfer) {

View File

@ -0,0 +1 @@
!function(r,e){var n;"object"==typeof exports?(n=e(),"object"==typeof module&&module&&module.exports&&(exports=module.exports=n),exports.randomColor=n):"function"==typeof define&&define.amd?define([],e):r.randomColor=e()}(this,function(){var o=null,s={};r("monochrome",null,[[0,0],[100,0]]),r("red",[-26,18],[[20,100],[30,92],[40,89],[50,85],[60,78],[70,70],[80,60],[90,55],[100,50]]),r("orange",[18,46],[[20,100],[30,93],[40,88],[50,86],[60,85],[70,70],[100,70]]),r("yellow",[46,62],[[25,100],[40,94],[50,89],[60,86],[70,84],[80,82],[90,80],[100,75]]),r("green",[62,178],[[30,100],[40,90],[50,85],[60,81],[70,74],[80,64],[90,50],[100,40]]),r("blue",[178,257],[[20,100],[30,86],[40,80],[50,74],[60,60],[70,52],[80,44],[90,39],[100,35]]),r("purple",[257,282],[[20,100],[30,87],[40,79],[50,70],[60,65],[70,59],[80,52],[90,45],[100,42]]),r("pink",[282,334],[[20,100],[30,90],[40,86],[60,84],[80,80],[90,75],[100,73]]);var i=[],f=function(r){if(void 0!==(r=r||{}).seed&&null!==r.seed&&r.seed===parseInt(r.seed,10))o=r.seed;else if("string"==typeof r.seed)o=function(r){for(var e=0,n=0;n!==r.length&&!(e>=Number.MAX_SAFE_INTEGER);n++)e+=r.charCodeAt(n);return e}(r.seed);else{if(void 0!==r.seed&&null!==r.seed)throw new TypeError("The seed value must be an integer or string");o=null}var e,n;if(null===r.count||void 0===r.count)return function(r,e){switch(e.format){case"hsvArray":return r;case"hslArray":return d(r);case"hsl":var n=d(r);return"hsl("+n[0]+", "+n[1]+"%, "+n[2]+"%)";case"hsla":var t=d(r),a=e.alpha||Math.random();return"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+a+")";case"rgbArray":return h(r);case"rgb":return"rgb("+h(r).join(", ")+")";case"rgba":var u=h(r),a=e.alpha||Math.random();return"rgba("+u.join(", ")+", "+a+")";default:return function(r){var e=h(r);function n(r){var e=r.toString(16);return 1==e.length?"0"+e:e}return"#"+n(e[0])+n(e[1])+n(e[2])}(r)}}([e=function(r){{if(0<i.length){var e=c(o=function(r){if(isNaN(r)){if("string"==typeof r)if(s[r]){var e=s[r];if(e.hueRange)return e.hueRange}else if(r.match(/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i)){return l(g(r)[0]).hueRange}}else{var n=parseInt(r);if(n<360&&0<n)return l(r).hueRange}return[0,360]}(r.hue)),n=(o[1]-o[0])/i.length,t=parseInt((e-o[0])/n);!0===i[t]?t=(t+2)%i.length:i[t]=!0;var a=(o[0]+t*n)%359,u=(o[0]+(t+1)*n)%359;return(e=c(o=[a,u]))<0&&(e=360+e),e}var o=function(r){if("number"==typeof parseInt(r)){var e=parseInt(r);if(e<360&&0<e)return[e,e]}if("string"==typeof r)if(s[r]){var n=s[r];if(n.hueRange)return n.hueRange}else if(r.match(/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i)){var t=g(r)[0];return[t,t]}return[0,360]}(r.hue);return(e=c(o))<0&&(e=360+e),e}}(r),n=function(r,e){if("monochrome"===e.hue)return 0;if("random"===e.luminosity)return c([0,100]);var n=function(r){return l(r).saturationRange}(r),t=n[0],a=n[1];switch(e.luminosity){case"bright":t=55;break;case"dark":t=a-10;break;case"light":a=55}return c([t,a])}(e,r),function(r,e,n){var t=function(r,e){for(var n=l(r).lowerBounds,t=0;t<n.length-1;t++){var a=n[t][0],u=n[t][1],o=n[t+1][0],s=n[t+1][1];if(a<=e&&e<=o){var i=(s-u)/(o-a);return i*e+(u-i*a)}}return 0}(r,e),a=100;switch(n.luminosity){case"dark":a=t+20;break;case"light":t=(a+t)/2;break;case"random":t=0,a=100}return c([t,a])}(e,n,r)],r);for(var t=r.count,a=[],u=0;u<r.count;u++)i.push(!1);for(r.count=null;t>a.length;)o&&r.seed&&(r.seed+=1),a.push(f(r));return r.count=t,a};function l(r){for(var e in 334<=r&&r<=360&&(r-=360),s){var n=s[e];if(n.hueRange&&r>=n.hueRange[0]&&r<=n.hueRange[1])return s[e]}return"Color not found"}function c(r){if(null===o){var e=Math.random();return e+=.618033988749895,e%=1,Math.floor(r[0]+e*(r[1]+1-r[0]))}var n=r[1]||1,t=r[0]||0,a=(o=(9301*o+49297)%233280)/233280;return Math.floor(t+a*(n-t))}function r(r,e,n){var t=n[0][0],a=n[n.length-1][0],u=n[n.length-1][1],o=n[0][1];s[r]={hueRange:e,lowerBounds:n,saturationRange:[t,a],brightnessRange:[u,o]}}function h(r){var e=r[0];0===e&&(e=1),360===e&&(e=359),e/=360;var n=r[1]/100,t=r[2]/100,a=Math.floor(6*e),u=6*e-a,o=t*(1-n),s=t*(1-u*n),i=t*(1-(1-u)*n),f=256,l=256,c=256;switch(a){case 0:f=t,l=i,c=o;break;case 1:f=s,l=t,c=o;break;case 2:f=o,l=t,c=i;break;case 3:f=o,l=s,c=t;break;case 4:f=i,l=o,c=t;break;case 5:f=t,l=o,c=s}return[Math.floor(255*f),Math.floor(255*l),Math.floor(255*c)]}function g(r){r=3===(r=r.replace(/^#/,"")).length?r.replace(/(.)/g,"$1$1"):r;var e=parseInt(r.substr(0,2),16)/255,n=parseInt(r.substr(2,2),16)/255,t=parseInt(r.substr(4,2),16)/255,a=Math.max(e,n,t),u=a-Math.min(e,n,t),o=a?u/a:0;switch(a){case e:return[(n-t)/u%6*60||0,o,a];case n:return[60*((t-e)/u+2)||0,o,a];case t:return[60*((e-n)/u+4)||0,o,a]}}function d(r){var e=r[0],n=r[1]/100,t=r[2]/100,a=(2-n)*t;return[e,Math.round(n*t/(a<1?a:2-a)*1e4)/100,a/2*100]}return f});

View File

@ -7,6 +7,8 @@ class StatusCode:
This is used to map a set of integer values to text. This is used to map a set of integer values to text.
""" """
colors = {}
@classmethod @classmethod
def render(cls, key, large=False): def render(cls, key, large=False):
""" """
@ -224,6 +226,82 @@ class StockStatus(StatusCode):
] ]
class StockHistoryCode(StatusCode):
LEGACY = 0
CREATED = 1
# Manual editing operations
EDITED = 5
ASSIGNED_SERIAL = 6
# Manual stock operations
STOCK_COUNT = 10
STOCK_ADD = 11
STOCK_REMOVE = 12
# Location operations
STOCK_MOVE = 20
# Installation operations
INSTALLED_INTO_ASSEMBLY = 30
REMOVED_FROM_ASSEMBLY = 31
INSTALLED_CHILD_ITEM = 35
REMOVED_CHILD_ITEM = 36
# Stock splitting operations
SPLIT_FROM_PARENT = 40
SPLIT_CHILD_ITEM = 42
# Build order codes
BUILD_OUTPUT_CREATED = 50
BUILD_OUTPUT_COMPLETED = 55
# Sales order codes
# Purchase order codes
RECEIVED_AGAINST_PURCHASE_ORDER = 70
# Customer actions
SENT_TO_CUSTOMER = 100
RETURNED_FROM_CUSTOMER = 105
options = {
LEGACY: _('Legacy stock tracking entry'),
CREATED: _('Stock item created'),
EDITED: _('Edited stock item'),
ASSIGNED_SERIAL: _('Assigned serial number'),
STOCK_COUNT: _('Stock counted'),
STOCK_ADD: _('Stock manually added'),
STOCK_REMOVE: _('Stock manually removed'),
STOCK_MOVE: _('Location changed'),
INSTALLED_INTO_ASSEMBLY: _('Installed into assembly'),
REMOVED_FROM_ASSEMBLY: _('Removed from assembly'),
INSTALLED_CHILD_ITEM: _('Installed component item'),
REMOVED_CHILD_ITEM: _('Removed component item'),
SPLIT_FROM_PARENT: _('Split from parent item'),
SPLIT_CHILD_ITEM: _('Split child item'),
SENT_TO_CUSTOMER: _('Sent to customer'),
RETURNED_FROM_CUSTOMER: _('Returned from customer'),
BUILD_OUTPUT_CREATED: _('Build order output created'),
BUILD_OUTPUT_COMPLETED: _('Build order output completed'),
RECEIVED_AGAINST_PURCHASE_ORDER: _('Received against purchase order')
}
class BuildStatus(StatusCode): class BuildStatus(StatusCode):
# Build status codes # Build status codes

View File

@ -161,6 +161,45 @@ def check_for_updates():
) )
def update_exchange_rates():
"""
Update currency exchange rates
"""
try:
from InvenTree.exchange import InvenTreeExchange
from djmoney.contrib.exchange.models import ExchangeBackend, Rate
from django.conf import settings
except AppRegistryNotReady:
# Apps not yet loaded!
return
except:
# Other error?
return
# Test to see if the database is ready yet
try:
backend = ExchangeBackend.objects.get(name='InvenTreeExchange')
except ExchangeBackend.DoesNotExist:
pass
except:
# Some other error
print("Database not ready")
return
backend = InvenTreeExchange()
print(f"Updating exchange rates from {backend.url}")
base = settings.BASE_CURRENCY
print(f"Using base currency '{base}'")
backend.update_rates(base_currency=base)
# Remove any exchange rates which are not in the provided currencies
Rate.objects.filter(backend="InvenTreeExchange").exclude(currency__in=settings.CURRENCIES).delete()
def send_email(subject, body, recipients, from_email=None): def send_email(subject, body, recipients, from_email=None):
""" """
Send an email with the specified subject and body, Send an email with the specified subject and body,

View File

@ -5,6 +5,12 @@ from django.test import TestCase
import django.core.exceptions as django_exceptions import django.core.exceptions as django_exceptions
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.conf import settings
from djmoney.money import Money
from djmoney.contrib.exchange.models import Rate, convert_money
from djmoney.contrib.exchange.exceptions import MissingRate
from .validators import validate_overage, validate_part_name from .validators import validate_overage, validate_part_name
from . import helpers from . import helpers
from . import version from . import version
@ -13,6 +19,8 @@ from mptt.exceptions import InvalidMove
from decimal import Decimal from decimal import Decimal
import InvenTree.tasks
from stock.models import StockLocation from stock.models import StockLocation
@ -244,6 +252,14 @@ class TestSerialNumberExtraction(TestCase):
self.assertIn(3, sn) self.assertIn(3, sn)
self.assertIn(13, sn) self.assertIn(13, sn)
sn = e("1+", 10)
self.assertEqual(len(sn), 10)
self.assertEqual(sn, [_ for _ in range(1, 11)])
sn = e("4, 1+2", 4)
self.assertEqual(len(sn), 4)
self.assertEqual(sn, ["4", 1, 2, 3])
def test_failures(self): def test_failures(self):
e = helpers.extract_serial_numbers e = helpers.extract_serial_numbers
@ -300,3 +316,46 @@ class TestVersionNumber(TestCase):
self.assertTrue(v_c > v_b) self.assertTrue(v_c > v_b)
self.assertTrue(v_d > v_c) self.assertTrue(v_d > v_c)
self.assertTrue(v_d > v_a) self.assertTrue(v_d > v_a)
class CurrencyTests(TestCase):
"""
Unit tests for currency / exchange rate functionality
"""
def test_rates(self):
# Initially, there will not be any exchange rate information
rates = Rate.objects.all()
self.assertEqual(rates.count(), 0)
# Without rate information, we cannot convert anything...
with self.assertRaises(MissingRate):
convert_money(Money(100, 'USD'), 'AUD')
with self.assertRaises(MissingRate):
convert_money(Money(100, 'AUD'), 'USD')
currencies = settings.CURRENCIES
InvenTree.tasks.update_exchange_rates()
rates = Rate.objects.all()
self.assertEqual(rates.count(), len(currencies))
# Now that we have some exchange rate information, we can perform conversions
# Forwards
convert_money(Money(100, 'USD'), 'AUD')
# Backwards
convert_money(Money(100, 'AUD'), 'USD')
# Convert between non base currencies
convert_money(Money(100, 'CAD'), 'NZD')
# Convert to a symbol which is not covered
with self.assertRaises(MissingRate):
convert_money(Money(100, 'GBP'), 'ZWL')

View File

@ -37,9 +37,11 @@ from django.conf.urls.static import static
from django.views.generic.base import RedirectView from django.views.generic.base import RedirectView
from rest_framework.documentation import include_docs_urls from rest_framework.documentation import include_docs_urls
from .views import auth_request
from .views import IndexView, SearchView, DatabaseStatsView from .views import IndexView, SearchView, DatabaseStatsView
from .views import SettingsView, EditUserView, SetPasswordView from .views import SettingsView, EditUserView, SetPasswordView
from .views import ColorThemeSelectView, SettingCategorySelectView from .views import CurrencySettingsView, CurrencyRefreshView
from .views import AppearanceSelectView, SettingCategorySelectView
from .views import DynamicJsView from .views import DynamicJsView
from common.views import SettingEdit from common.views import SettingEdit
@ -79,16 +81,19 @@ apipatterns = [
settings_urls = [ settings_urls = [
url(r'^user/?', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings-user'), url(r'^user/?', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings-user'),
url(r'^theme/?', ColorThemeSelectView.as_view(), name='settings-theme'), url(r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'),
url(r'^i18n/?', include('django.conf.urls.i18n')),
url(r'^global/?', SettingsView.as_view(template_name='InvenTree/settings/global.html'), name='settings-global'), url(r'^global/', SettingsView.as_view(template_name='InvenTree/settings/global.html'), name='settings-global'),
url(r'^report/?', SettingsView.as_view(template_name='InvenTree/settings/report.html'), name='settings-report'), url(r'^report/', SettingsView.as_view(template_name='InvenTree/settings/report.html'), name='settings-report'),
url(r'^category/?', SettingCategorySelectView.as_view(), name='settings-category'), url(r'^category/', SettingCategorySelectView.as_view(), name='settings-category'),
url(r'^part/?', SettingsView.as_view(template_name='InvenTree/settings/part.html'), name='settings-part'), url(r'^part/', SettingsView.as_view(template_name='InvenTree/settings/part.html'), name='settings-part'),
url(r'^stock/?', SettingsView.as_view(template_name='InvenTree/settings/stock.html'), name='settings-stock'), url(r'^stock/', SettingsView.as_view(template_name='InvenTree/settings/stock.html'), name='settings-stock'),
url(r'^build/?', SettingsView.as_view(template_name='InvenTree/settings/build.html'), name='settings-build'), url(r'^build/', SettingsView.as_view(template_name='InvenTree/settings/build.html'), name='settings-build'),
url(r'^purchase-order/?', SettingsView.as_view(template_name='InvenTree/settings/po.html'), name='settings-po'), url(r'^purchase-order/', SettingsView.as_view(template_name='InvenTree/settings/po.html'), name='settings-po'),
url(r'^sales-order/?', SettingsView.as_view(template_name='InvenTree/settings/so.html'), name='settings-so'), url(r'^sales-order/', SettingsView.as_view(template_name='InvenTree/settings/so.html'), name='settings-so'),
url(r'^currencies/', CurrencySettingsView.as_view(), name='settings-currencies'),
url(r'^currencies-refresh/', CurrencyRefreshView.as_view(), name='settings-currencies-refresh'),
url(r'^(?P<pk>\d+)/edit/', SettingEdit.as_view(), name='setting-edit'), url(r'^(?P<pk>\d+)/edit/', SettingEdit.as_view(), name='setting-edit'),
@ -151,24 +156,28 @@ urlpatterns = [
url(r'^search/', SearchView.as_view(), name='search'), url(r'^search/', SearchView.as_view(), name='search'),
url(r'^stats/', DatabaseStatsView.as_view(), name='stats'), url(r'^stats/', DatabaseStatsView.as_view(), name='stats'),
url(r'^auth/?', auth_request),
url(r'^api/', include(apipatterns)), url(r'^api/', include(apipatterns)),
url(r'^api-doc/', include_docs_urls(title='InvenTree API')), url(r'^api-doc/', include_docs_urls(title='InvenTree API')),
url(r'^markdownx/', include('markdownx.urls')), url(r'^markdownx/', include('markdownx.urls')),
] ]
# Static file access # Server running in "DEBUG" mode?
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) if settings.DEBUG:
# Static file access
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
# Media file access # Media file access
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# Debug toolbar access (if in DEBUG mode) # Debug toolbar access (only allowed in DEBUG mode)
if settings.DEBUG and 'debug_toolbar' in settings.INSTALLED_APPS: if 'debug_toolbar' in settings.INSTALLED_APPS:
import debug_toolbar import debug_toolbar
urlpatterns = [ urlpatterns = [
path('__debug/', include(debug_toolbar.urls)), path('__debug/', include(debug_toolbar.urls)),
] + urlpatterns ] + urlpatterns
# Send any unknown URLs to the parts page # Send any unknown URLs to the parts page
urlpatterns += [url(r'^.*$', RedirectView.as_view(url='/index/', permanent=False), name='index')] urlpatterns += [url(r'^.*$', RedirectView.as_view(url='/index/', permanent=False), name='index')]

View File

@ -74,7 +74,7 @@ def validate_build_order_reference(value):
match = re.search(pattern, value) match = re.search(pattern, value)
if match is None: if match is None:
raise ValidationError(_('Reference must match pattern') + f" '{pattern}'") raise ValidationError(_('Reference must match pattern {pattern}').format(pattern=pattern))
def validate_purchase_order_reference(value): def validate_purchase_order_reference(value):
@ -88,7 +88,7 @@ def validate_purchase_order_reference(value):
match = re.search(pattern, value) match = re.search(pattern, value)
if match is None: if match is None:
raise ValidationError(_('Reference must match pattern') + f" '{pattern}'") raise ValidationError(_('Reference must match pattern {pattern}').format(pattern=pattern))
def validate_sales_order_reference(value): def validate_sales_order_reference(value):
@ -102,7 +102,7 @@ def validate_sales_order_reference(value):
match = re.search(pattern, value) match = re.search(pattern, value)
if match is None: if match is None:
raise ValidationError(_('Reference must match pattern') + f" '{pattern}'") raise ValidationError(_('Reference must match pattern {pattern}').format(pattern=pattern))
def validate_tree_name(value): def validate_tree_name(value):

View File

@ -8,10 +8,21 @@ import re
import common.models import common.models
INVENTREE_SW_VERSION = "0.2.2 pre" INVENTREE_SW_VERSION = "0.2.4 pre"
# Increment this number whenever there is a significant change to the API that any clients need to know about """
INVENTREE_API_VERSION = 2 Increment thi API version number whenever there is a significant change to the API that any clients need to know about
v3 -> 2021-05-22:
- The updated StockItem "history tracking" now uses a different interface
v4 -> 2021-06-01
- BOM items can now accept "variant stock" to be assigned against them
- Many slight API tweaks were needed to get this to work properly!
"""
INVENTREE_API_VERSION = 4
def inventreeInstanceName(): def inventreeInstanceName():

View File

@ -10,20 +10,25 @@ from __future__ import unicode_literals
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.http import JsonResponse, HttpResponseRedirect from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.conf import settings
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin
from django.views import View from django.views import View
from django.views.generic import ListView, DetailView, CreateView, FormView, DeleteView, UpdateView from django.views.generic import ListView, DetailView, CreateView, FormView, DeleteView, UpdateView
from django.views.generic.base import TemplateView from django.views.generic.base import RedirectView, TemplateView
from djmoney.contrib.exchange.models import ExchangeBackend, Rate
from part.models import Part, PartCategory from part.models import Part, PartCategory
from stock.models import StockLocation, StockItem from stock.models import StockLocation, StockItem
from common.models import InvenTreeSetting, ColorTheme from common.models import InvenTreeSetting, ColorTheme
from users.models import check_user_role, RuleSet from users.models import check_user_role, RuleSet
import InvenTree.tasks
from .forms import DeleteForm, EditUserForm, SetPasswordForm from .forms import DeleteForm, EditUserForm, SetPasswordForm
from .forms import ColorThemeSelectForm, SettingCategorySelectForm from .forms import ColorThemeSelectForm, SettingCategorySelectForm
from .helpers import str2bool from .helpers import str2bool
@ -31,6 +36,19 @@ from .helpers import str2bool
from rest_framework import views from rest_framework import views
def auth_request(request):
"""
Simple 'auth' endpoint used to determine if the user is authenticated.
Useful for (for example) redirecting authentication requests through
django's permission framework.
"""
if request.user.is_authenticated:
return HttpResponse(status=200)
else:
return HttpResponse(status=403)
class TreeSerializer(views.APIView): class TreeSerializer(views.APIView):
""" JSON View for serializing a Tree object. """ JSON View for serializing a Tree object.
@ -769,12 +787,57 @@ class SettingsView(TemplateView):
return ctx return ctx
class ColorThemeSelectView(FormView): class CurrencyRefreshView(RedirectView):
"""
POST endpoint to refresh / update exchange rates
"""
url = reverse_lazy("settings-currencies")
def post(self, request, *args, **kwargs):
"""
On a POST request we will attempt to refresh the exchange rates
"""
# Will block for a little bit
InvenTree.tasks.update_exchange_rates()
return self.get(request, *args, **kwargs)
class CurrencySettingsView(TemplateView):
"""
View for configuring currency settings
"""
template_name = "InvenTree/settings/currencies.html"
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs).copy()
ctx['settings'] = InvenTreeSetting.objects.all().order_by('key')
ctx["base_currency"] = settings.BASE_CURRENCY
ctx["currencies"] = settings.CURRENCIES
ctx["rates"] = Rate.objects.filter(backend="InvenTreeExchange")
# When were the rates last updated?
try:
backend = ExchangeBackend.objects.get(name='InvenTreeExchange')
ctx["rates_updated"] = backend.last_update
except:
ctx["rates_updated"] = None
return ctx
class AppearanceSelectView(FormView):
""" View for selecting a color theme """ """ View for selecting a color theme """
form_class = ColorThemeSelectForm form_class = ColorThemeSelectForm
success_url = reverse_lazy('settings-theme') success_url = reverse_lazy('settings-appearance')
template_name = "InvenTree/settings/theme.html" template_name = "InvenTree/settings/appearance.html"
def get_user_theme(self): def get_user_theme(self):
""" Get current user color theme """ """ Get current user color theme """
@ -788,7 +851,7 @@ class ColorThemeSelectView(FormView):
def get_initial(self): def get_initial(self):
""" Select current user color theme as initial choice """ """ Select current user color theme as initial choice """
initial = super(ColorThemeSelectView, self).get_initial() initial = super(AppearanceSelectView, self).get_initial()
user_theme = self.get_user_theme() user_theme = self.get_user_theme()
if user_theme: if user_theme:

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2 on 2021-06-01 05:23
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('part', '0066_bomitem_allow_variants'),
('build', '0027_auto_20210404_2016'),
]
operations = [
migrations.AddField(
model_name='builditem',
name='bom_item',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='allocate_build_items', to='part.bomitem'),
),
]

View File

@ -0,0 +1,62 @@
# Generated by Django 3.2 on 2021-06-01 05:25
from django.db import migrations
def assign_bom_items(apps, schema_editor):
"""
Run through existing BuildItem objects,
and assign a matching BomItem
"""
BuildItem = apps.get_model('build', 'builditem')
BomItem = apps.get_model('part', 'bomitem')
Part = apps.get_model('part', 'part')
print("Assigning BomItems to existing BuildItem objects")
count_valid = 0
count_total = 0
for build_item in BuildItem.objects.all():
# Try to find a BomItem which matches the BuildItem
# Note: Before this migration, variant stock assignment was not allowed,
# so BomItem lookup should be pretty easy
count_total += 1
try:
bom_item = BomItem.objects.get(
part__id=build_item.build.part.pk,
sub_part__id=build_item.stock_item.part.pk,
)
build_item.bom_item = bom_item
build_item.save()
count_valid += 1
except BomItem.DoesNotExist:
pass
print(f"Assigned BomItem for {count_valid}/{count_total} entries")
def unassign_bom_items(apps, schema_editor):
"""
Reverse migration does not do anything.
Function here to preserve ability to reverse migration
"""
pass
class Migration(migrations.Migration):
dependencies = [
('build', '0028_builditem_bom_item'),
]
operations = [
migrations.RunPython(assign_bom_items, reverse_code=unassign_bom_items),
]

View File

@ -22,7 +22,7 @@ from markdownx.models import MarkdownxField
from mptt.models import MPTTModel, TreeForeignKey from mptt.models import MPTTModel, TreeForeignKey
from InvenTree.status_codes import BuildStatus, StockStatus from InvenTree.status_codes import BuildStatus, StockStatus, StockHistoryCode
from InvenTree.helpers import increment, getSetting, normalize, MakeBarcode from InvenTree.helpers import increment, getSetting, normalize, MakeBarcode
from InvenTree.validators import validate_build_order_reference from InvenTree.validators import validate_build_order_reference
from InvenTree.models import InvenTreeAttachment from InvenTree.models import InvenTreeAttachment
@ -30,6 +30,7 @@ from InvenTree.models import InvenTreeAttachment
import common.models import common.models
import InvenTree.fields import InvenTree.fields
import InvenTree.helpers
from stock import models as StockModels from stock import models as StockModels
from part import models as PartModels from part import models as PartModels
@ -811,6 +812,7 @@ class Build(MPTTModel):
# Select the location for the build output # Select the location for the build output
location = kwargs.get('location', self.destination) location = kwargs.get('location', self.destination)
status = kwargs.get('status', StockStatus.OK) status = kwargs.get('status', StockStatus.OK)
notes = kwargs.get('notes', '')
# List the allocated BuildItem objects for the given output # List the allocated BuildItem objects for the given output
allocated_items = output.items_to_install.all() allocated_items = output.items_to_install.all()
@ -834,10 +836,13 @@ class Build(MPTTModel):
output.save() output.save()
output.addTransactionNote( output.add_tracking_entry(
_('Completed build output'), StockHistoryCode.BUILD_OUTPUT_COMPLETED,
user, user,
system=True notes=notes,
deltas={
'status': status,
}
) )
# Increase the completed quantity for this build # Increase the completed quantity for this build
@ -876,9 +881,12 @@ class Build(MPTTModel):
output - Build output (StockItem). output - Build output (StockItem).
""" """
# Remember, if 'variant' stock is allowed to be allocated, it becomes more complicated!
variants = part.get_descendants(include_self=True)
allocations = BuildItem.objects.filter( allocations = BuildItem.objects.filter(
build=self, build=self,
stock_item__part=part, stock_item__part__pk__in=[p.pk for p in variants],
install_into=output, install_into=output,
) )
@ -996,14 +1004,28 @@ class Build(MPTTModel):
@property @property
def required_parts(self): def required_parts(self):
""" Returns a dict of parts required to build this part (BOM) """ """ Returns a list of parts required to build this part (BOM) """
parts = [] parts = []
for item in self.part.bom_items.all().prefetch_related('sub_part'): for item in self.bom_items:
parts.append(item.sub_part) parts.append(item.sub_part)
return parts return parts
@property
def required_parts_to_complete_build(self):
""" Returns a list of parts required to complete the full build """
parts = []
for bom_item in self.bom_items:
# Get remaining quantity needed
required_quantity_to_complete_build = self.remaining * bom_item.quantity
# Compare to net stock
if bom_item.sub_part.net_stock < required_quantity_to_complete_build:
parts.append(bom_item.sub_part)
return parts
def availableStockItems(self, part, output): def availableStockItems(self, part, output):
""" """
Returns stock items which are available for allocation to this build. Returns stock items which are available for allocation to this build.
@ -1018,7 +1040,19 @@ class Build(MPTTModel):
StockModels.StockItem.IN_STOCK_FILTER StockModels.StockItem.IN_STOCK_FILTER
) )
items = items.filter(part=part) # Check if variants are allowed for this part
try:
bom_item = PartModels.BomItem.objects.get(part=self.part, sub_part=part)
allow_part_variants = bom_item.allow_variants
except PartModels.BomItem.DoesNotExist:
allow_part_variants = False
if allow_part_variants:
parts = part.get_descendants(include_self=True)
items = items.filter(part__pk__in=[p.pk for p in parts])
else:
items = items.filter(part=part)
# Exclude any items which have already been allocated # Exclude any items which have already been allocated
allocated = BuildItem.objects.filter( allocated = BuildItem.objects.filter(
@ -1142,10 +1176,6 @@ class BuildItem(models.Model):
if self.stock_item.part and self.stock_item.part.trackable and not self.install_into: if self.stock_item.part and self.stock_item.part.trackable and not self.install_into:
raise ValidationError(_('Build item must specify a build output, as master part is marked as trackable')) raise ValidationError(_('Build item must specify a build output, as master part is marked as trackable'))
# Allocated part must be in the BOM for the master part
if self.stock_item.part not in self.build.part.getRequiredParts(recursive=False):
errors['stock_item'] = [_("Selected stock item not found in BOM for part '{p}'").format(p=self.build.part.full_name)]
# Allocated quantity cannot exceed available stock quantity # Allocated quantity cannot exceed available stock quantity
if self.quantity > self.stock_item.quantity: if self.quantity > self.stock_item.quantity:
errors['quantity'] = [_("Allocated quantity ({n}) must not exceed available quantity ({q})").format( errors['quantity'] = [_("Allocated quantity ({n}) must not exceed available quantity ({q})").format(
@ -1171,6 +1201,61 @@ class BuildItem(models.Model):
if len(errors) > 0: if len(errors) > 0:
raise ValidationError(errors) raise ValidationError(errors)
"""
Attempt to find the "BomItem" which links this BuildItem to the build.
- If a BomItem is already set, and it is valid, then we are ok!
"""
bom_item_valid = False
if self.bom_item:
"""
A BomItem object has already been assigned. This is valid if:
a) It points to the same "part" as the referened build
b) Either:
i) The sub_part points to the same part as the referenced StockItem
ii) The BomItem allows variants and the part referenced by the StockItem
is a variant of the sub_part referenced by the BomItem
"""
if self.build and self.build.part == self.bom_item.part:
# Check that the sub_part points to the stock_item (either directly or via a variant)
if self.bom_item.sub_part == self.stock_item.part:
bom_item_valid = True
elif self.bom_item.allow_variants and self.stock_item.part in self.bom_item.sub_part.get_descendants(include_self=False):
bom_item_valid = True
# If the existing BomItem is *not* valid, try to find a match
if not bom_item_valid:
if self.build and self.stock_item:
ancestors = self.stock_item.part.get_ancestors(include_self=True, ascending=True)
for idx, ancestor in enumerate(ancestors):
try:
bom_item = PartModels.BomItem.objects.get(part=self.build.part, sub_part=ancestor)
except PartModels.BomItem.DoesNotExist:
continue
# A matching BOM item has been found!
if idx == 0 or bom_item.allow_variants:
bom_item_valid = True
self.bom_item = bom_item
break
# BomItem did not exist or could not be validated.
# Search for a new one
if not bom_item_valid:
raise ValidationError({
'stock_item': _("Selected stock item not found in BOM for part '{p}'").format(p=self.build.part.full_name)
})
@transaction.atomic @transaction.atomic
def complete_allocation(self, user): def complete_allocation(self, user):
""" """
@ -1199,6 +1284,31 @@ class BuildItem(models.Model):
# Simply remove the items from stock # Simply remove the items from stock
item.take_stock(self.quantity, user) item.take_stock(self.quantity, user)
def getStockItemThumbnail(self):
"""
Return qualified URL for part thumbnail image
"""
thumb_url = None
if self.stock_item and self.stock_item.part:
try:
# Try to extract the thumbnail
thumb_url = self.stock_item.part.image.thumbnail.url
except:
pass
if thumb_url is None and self.bom_item and self.bom_item.sub_part:
try:
thumb_url = self.bom_item.sub_part.image.thumbnail.url
except:
pass
if thumb_url is not None:
return InvenTree.helpers.getMediaUrl(thumb_url)
else:
return InvenTree.helpers.getBlankThumbnail()
build = models.ForeignKey( build = models.ForeignKey(
Build, Build,
on_delete=models.CASCADE, on_delete=models.CASCADE,
@ -1207,6 +1317,15 @@ class BuildItem(models.Model):
help_text=_('Build to allocate parts') help_text=_('Build to allocate parts')
) )
# Internal model which links part <-> sub_part
# We need to track this separately, to allow for "variant' stock
bom_item = models.ForeignKey(
PartModels.BomItem,
on_delete=models.CASCADE,
related_name='allocate_build_items',
blank=True, null=True,
)
stock_item = models.ForeignKey( stock_item = models.ForeignKey(
'stock.StockItem', 'stock.StockItem',
on_delete=models.CASCADE, on_delete=models.CASCADE,

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