mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge remote-tracking branch 'inventree/master' into l10
This commit is contained in:
commit
a8ae62e133
1
.github/workflows/coverage.yaml
vendored
1
.github/workflows/coverage.yaml
vendored
@ -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
|
||||||
|
6
.github/workflows/docker_build.yaml
vendored
6
.github/workflows/docker_build.yaml
vendored
@ -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
|
||||||
|
21
.github/workflows/docker_publish.yaml
vendored
21
.github/workflows/docker_publish.yaml
vendored
@ -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
|
|
||||||
|
9
.github/workflows/mysql.yaml
vendored
9
.github/workflows/mysql.yaml
vendored
@ -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
|
9
.github/workflows/postgresql.yaml
vendored
9
.github/workflows/postgresql.yaml
vendored
@ -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
9
.gitignore
vendored
@ -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/
|
@ -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()
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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.
|
||||||
|
46
InvenTree/InvenTree/ready.py
Normal file
46
InvenTree/InvenTree/ready.py
Normal 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
|
@ -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',
|
||||||
|
10
InvenTree/InvenTree/static/bootstrap-table/bootstrap-table-en-US.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/bootstrap-table-en-US.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -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 */
|
|
7409
InvenTree/InvenTree/static/bootstrap-table/bootstrap-table.js
vendored
Normal file
7409
InvenTree/InvenTree/static/bootstrap-table/bootstrap-table.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
10
InvenTree/InvenTree/static/bootstrap-table/extensions/addrbar/bootstrap-table-addrbar.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/addrbar/bootstrap-table-addrbar.min.js
vendored
Normal file
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
File diff suppressed because it is too large
Load Diff
10
InvenTree/InvenTree/static/bootstrap-table/extensions/cookie/bootstrap-table-cookie.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/cookie/bootstrap-table-cookie.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
10
InvenTree/InvenTree/static/bootstrap-table/extensions/copy-rows/bootstrap-table-copy-rows.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/copy-rows/bootstrap-table-copy-rows.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1256
InvenTree/InvenTree/static/bootstrap-table/extensions/custom-view/bootstrap-table-custom-view.js
vendored
Normal file
1256
InvenTree/InvenTree/static/bootstrap-table/extensions/custom-view/bootstrap-table-custom-view.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -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);
|
||||||
|
|
||||||
|
})));
|
||||||
|
10
InvenTree/InvenTree/static/bootstrap-table/extensions/defer-url/bootstrap-table-defer-url.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/defer-url/bootstrap-table-defer-url.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
10
InvenTree/InvenTree/static/bootstrap-table/extensions/editable/bootstrap-table-editable.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/editable/bootstrap-table-editable.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
10
InvenTree/InvenTree/static/bootstrap-table/extensions/export/bootstrap-table-export.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/export/bootstrap-table-export.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -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;
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@ -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
10
InvenTree/InvenTree/static/bootstrap-table/extensions/filter-control/utils.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/filter-control/utils.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -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;
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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
@ -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;
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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
@ -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);
|
||||||
|
|
||||||
|
})));
|
||||||
|
@ -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 it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
10
InvenTree/InvenTree/static/bootstrap-table/extensions/mobile/bootstrap-table-mobile.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/mobile/bootstrap-table-mobile.min.js
vendored
Normal file
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
@ -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;
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@ -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 it is too large
Load Diff
10
InvenTree/InvenTree/static/bootstrap-table/extensions/pipeline/bootstrap-table-pipeline.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/pipeline/bootstrap-table-pipeline.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
10
InvenTree/InvenTree/static/bootstrap-table/extensions/print/bootstrap-table-print.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/print/bootstrap-table-print.min.js
vendored
Normal file
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
@ -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;
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@ -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
@ -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);
|
||||||
|
|
||||||
|
})));
|
||||||
|
10
InvenTree/InvenTree/static/bootstrap-table/extensions/resizable/bootstrap-table-resizable.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/resizable/bootstrap-table-resizable.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -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;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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 it is too large
Load Diff
10
InvenTree/InvenTree/static/bootstrap-table/extensions/toolbar/bootstrap-table-toolbar.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/toolbar/bootstrap-table-toolbar.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
10
InvenTree/InvenTree/static/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.min.js
vendored
Normal file
10
InvenTree/InvenTree/static/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
||||||
|
}
|
@ -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);
|
|
File diff suppressed because it is too large
Load Diff
@ -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
13
InvenTree/InvenTree/static/script/chart.min.js
vendored
Normal file
13
InvenTree/InvenTree/static/script/chart.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
InvenTree/InvenTree/static/script/clipboard.min.js
vendored
Normal file
7
InvenTree/InvenTree/static/script/clipboard.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -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) {
|
||||||
|
1
InvenTree/InvenTree/static/script/randomColor.min.js
vendored
Normal file
1
InvenTree/InvenTree/static/script/randomColor.min.js
vendored
Normal 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});
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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')
|
||||||
|
@ -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')]
|
||||||
|
@ -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):
|
||||||
|
@ -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():
|
||||||
|
@ -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:
|
||||||
|
20
InvenTree/build/migrations/0028_builditem_bom_item.py
Normal file
20
InvenTree/build/migrations/0028_builditem_bom_item.py
Normal 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'),
|
||||||
|
),
|
||||||
|
]
|
62
InvenTree/build/migrations/0029_auto_20210601_1525.py
Normal file
62
InvenTree/build/migrations/0029_auto_20210601_1525.py
Normal 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),
|
||||||
|
]
|
@ -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
Loading…
Reference in New Issue
Block a user