Changed the CSS and JavaScript libraries from the hard-coded site-specific location to the settings with default to CDN download.

This commit is contained in:
依瑪貓 2020-08-29 21:54:12 +08:00
parent d1ef253d9d
commit c0946481dd
14 changed files with 216 additions and 26 deletions

View File

@ -28,7 +28,7 @@ First written: 2020/8/7
{% block settings %}
{% trans "Accounts" context "Accounting" as text %}
{% setvar "title" text %}
{% setvar "use_datatables" True %}
{% add_lib "bootstrap4-datatables" %}
{% static "accounting/js/account-list.js" as file %}{% add_js file %}
{% endblock %}

View File

@ -29,7 +29,7 @@ First written: 2020/7/20
{% block settings %}
{% blocktrans asvar title with prep_period=request.resolver_match.kwargs.period.prep_desc %}Balance Sheet {{ prep_period }}{% endblocktrans %}
{% setvar "title" title %}
{% setvar "use_period_chooser" True %}
{% add_lib "period-chooser" %}
{% static "accounting/css/report.css" as file %}{% add_css file %}
{% endblock %}

View File

@ -28,7 +28,7 @@ First written: 2020/7/1
{% block settings %}
{% blocktrans asvar title with account=request.resolver_match.kwargs.account.title prep_period=request.resolver_match.kwargs.period.prep_desc %}Cash Account for {{ account }} {{ prep_period }}{% endblocktrans %}
{% setvar "title" title %}
{% setvar "use_period_chooser" True %}
{% add_lib "period-chooser" %}
{% static "accounting/css/report.css" as file %}{% add_css file %}
{% endblock %}

View File

@ -28,7 +28,7 @@ First written: 2020/7/19
{% block settings %}
{% blocktrans asvar title with prep_period=request.resolver_match.kwargs.period.prep_desc %}Income Statement {{ prep_period }}{% endblocktrans %}
{% setvar "title" title %}
{% setvar "use_period_chooser" True %}
{% add_lib "period-chooser" %}
{% static "accounting/css/report.css" as file %}{% add_css file %}
{% endblock %}

View File

@ -28,7 +28,7 @@ First written: 2020/7/17
{% block settings %}
{% blocktrans asvar title with prep_period=request.resolver_match.kwargs.period.prep_desc %}Journal {{ prep_period }}{% endblocktrans %}
{% setvar "title" title %}
{% setvar "use_period_chooser" True %}
{% add_lib "period-chooser" %}
{% static "accounting/css/report.css" as file %}{% add_css file %}
{% endblock %}

View File

@ -28,7 +28,7 @@ First written: 2020/7/16
{% block settings %}
{% blocktrans asvar title with account=request.resolver_match.kwargs.account.title prep_period=request.resolver_match.kwargs.period.prep_desc %}Ledger for {{ account }} {{ prep_period }}{% endblocktrans %}
{% setvar "title" title %}
{% setvar "use_period_chooser" True %}
{% add_lib "period-chooser" %}
{% static "accounting/css/report.css" as file %}{% add_css file %}
{% endblock %}

View File

@ -28,7 +28,7 @@ First written: 2020/7/19
{% block settings %}
{% blocktrans asvar title with prep_period=request.resolver_match.kwargs.period.prep_desc %}Trial Balance {{ prep_period }}{% endblocktrans %}
{% setvar "title" title %}
{% setvar "use_period_chooser" True %}
{% add_lib "period-chooser" %}
{% static "accounting/css/report.css" as file %}{% add_css file %}
{% endblock %}

View File

@ -28,8 +28,7 @@ First written: 2020/7/23
{% block settings %}
{% setvar "title" _("Cash Expense Transaction") %}
{% setvar "use_jqueryui" True %}
{% static "ext-libs/decimal/decimal.min.js" as file %}{% add_js file %}
{% add_lib "jquery-ui" "decimal-js" %}
{% static "accounting/css/transactions.css" as file %}{% add_css file %}
{% static "accounting/css/summary-helper.css" as file %}{% add_css file %}
{% static "accounting/js/transaction-form.js" as file %}{% add_js file %}

View File

@ -28,8 +28,7 @@ First written: 2020/7/23
{% block settings %}
{% setvar "title" _("Cash Income Transaction") %}
{% setvar "use_jqueryui" True %}
{% static "ext-libs/decimal/decimal.min.js" as file %}{% add_js file %}
{% add_lib "jquery-ui" "decimal-js" %}
{% static "accounting/css/transactions.css" as file %}{% add_css file %}
{% static "accounting/css/summary-helper.css" as file %}{% add_css file %}
{% static "accounting/js/transaction-form.js" as file %}{% add_js file %}

View File

@ -29,7 +29,7 @@ First written: 2020/8/6
{% block settings %}
{% blocktrans asvar title with date=form.date|smart_date %}Reorder the Transactions in {{ date }}{% endblocktrans %}
{% setvar "title" title %}
{% setvar "use_jqueryui" True %}
{% add_lib "jquery-ui" %}
{% static "accounting/css/report.css" as file %}{% add_css file %}
{% static "accounting/css/transactions-sort.css" as file %}{% add_css file %}
{% static "accounting/js/transaction-sort.js" as file %}{% add_js file %}

View File

@ -28,8 +28,7 @@ First written: 2020/7/23
{% block settings %}
{% setvar "title" _("Transfer Transaction") %}
{% setvar "use_jqueryui" True %}
{% static "ext-libs/decimal/decimal.min.js" as file %}{% add_js file %}
{% add_lib "jquery-ui" "decimal-js" %}
{% static "accounting/css/transactions.css" as file %}{% add_css file %}
{% static "accounting/css/summary-helper.css" as file %}{% add_css file %}
{% static "accounting/js/transaction-form.js" as file %}{% add_js file %}

View File

@ -39,12 +39,14 @@ from django.views.decorators.http import require_GET, require_POST
from django.views.generic import ListView, DetailView
from mia_core.period import Period
from mia_core.utils import Pagination, PaginationException
from mia_core.utils import Pagination, PaginationException, add_default_libs
from mia_core.views import DeleteView, FormView, RedirectView
from . import utils
from .forms import AccountForm, TransactionForm, TransactionSortForm
from .models import Record, Transaction, Account
add_default_libs("bootstrap4", "font-awesome-5", "i18n")
@method_decorator(require_GET, name="dispatch")
class CashDefaultView(RedirectView):

View File

@ -19,8 +19,9 @@
"""
import datetime
import re
from datetime import date
from typing import Any
from typing import Any, List
import titlecase
from django import template
@ -31,7 +32,7 @@ from django.utils import timezone
from django.utils.safestring import SafeString
from django.utils.translation import gettext
from mia_core.utils import UrlBuilder
from mia_core.utils import UrlBuilder, CssAndJavaScriptLibraries
register = template.Library()
@ -103,6 +104,24 @@ def url_keep_return(context: RequestContext, url: str) -> str:
return str(UrlBuilder(url).query(r=context.request.GET.get("r")))
@register.simple_tag(takes_context=True)
def add_lib(context: RequestContext, *args) -> str:
"""Adds CSS and JavaScript libraries.
Args:
context: The request context.
args: The names of the CSS and JavaScript libraries.
Returns:
An empty string.
"""
if "libs" not in context.dicts[0]:
context.dicts[0]["libs"] = CssAndJavaScriptLibraries(args)
else:
context.dicts[0]["libs"].use(args)
return ""
@register.simple_tag(takes_context=True)
def add_css(context: RequestContext, url: str) -> str:
"""Adds a local CSS file. The file is added to the "css" template
@ -113,11 +132,11 @@ def add_css(context: RequestContext, url: str) -> str:
url: The URL or path of the CSS file.
Returns:
An empty string
An empty string.
"""
if "css" not in context.dicts[0]:
context.dicts[0]["css"] = []
context.dicts[0]["css"].append(url)
if "libs" not in context.dicts[0]:
context.dicts[0]["libs"] = CssAndJavaScriptLibraries()
context.dicts[0]["libs"].add_css(url)
return ""
@ -131,11 +150,11 @@ def add_js(context: RequestContext, url: str) -> str:
url: The URL or path of the JavaScript file.
Returns:
An empty string
An empty string.
"""
if "js" not in context.dicts[0]:
context.dicts[0]["js"] = []
context.dicts[0]["js"].append(url)
if "libs" not in context.dicts[0]:
context.dicts[0]["libs"] = CssAndJavaScriptLibraries()
context.dicts[0]["libs"].add_js(url)
return ""
@ -215,3 +234,18 @@ def is_in_section(request: HttpRequest, section_name: str) -> bool:
view_name = request.resolver_match.view_name
return view_name == section_name\
or view_name.startswith(section_name + ".")
@register.filter
def is_static_url(target: str) -> bool:
"""Returns whether the target URL is a static path
Args:
target: The target, either a static path that need to be passed to
the static template tag, or an HTTP, HTTPS URL or absolute path
that should be displayed directly.
Returns:
True if the target URL is a static path, or False otherwise.
"""
return not (re.match("^https?://", target) or target.startswith("/"))

View File

@ -20,11 +20,12 @@
"""
import random
import urllib.parse
from typing import Dict, List, Any, Type
from typing import Dict, List, Any, Type, Tuple
from django.conf import settings
from django.db.models import Model
from django.http import HttpRequest
from django.urls import reverse
from django.utils.translation import pgettext, get_language
@ -438,3 +439,159 @@ class PaginationException(Exception):
"""
def __init__(self, url_builder: UrlBuilder):
self.url = str(url_builder)
CDN_LIBRARIES = {
"jquery": {"css": [], "js": ["https://code.jquery.com/jquery-3.5.1.min.js"]},
"bootstrap4": {
"css": ["https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"],
"js": ["https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js",
"https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"]},
"font-awesome-5": {
"css": ["https://use.fontawesome.com/releases/v5.14.0/css/all.css"],
"js": []},
"bootstrap4-datatables": {
"css": ["https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css",
"https://cdn.datatables.net/1.10.21/css/dataTables.bootstrap4.min.css"],
"js": ["https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js",
"https://cdn.datatables.net/1.10.21/js/dataTables.bootstrap4.min.js"]},
"jquery-ui": {"css": ["https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css"],
"js": ["https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"]},
"bootstrap4-tempusdominus": {
"css": ["https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.1.2/css/tempusdominus-bootstrap-4.min.css"],
"js": ["https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment-with-locales.min.js",
"https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.1.2/js/tempusdominus-bootstrap-4.js"]},
"decimal-js": {"css": [],
"js": ["https://cdnjs.cloudflare.com/ajax/libs/decimal.js/10.2.0/decimal.min.js"]},
"period-chooser": {"css": ["mia_core/css/period-chooser.css"],
"js": ["mia_core/js/period-chooser.js"]}
}
DEFAULT_LIBS = []
class CssAndJavaScriptLibraries:
"""The CSS and JavaScript library resolver."""
AVAILABLE_LIBS: List[str] = ["jquery", "bootstrap4", "font-awesome-5",
"bootstrap4-datatables", "jquery-ui",
"bootstrap4-tempusdominus", "decimal-js",
"i18n", "period-chooser"]
def __init__(self, *args):
self._use: Dict[str, bool] = {x: False for x in self.AVAILABLE_LIBS}
self._add_default_libs()
# The specified libraries
if len(args) > 0:
libs = args[0]
invalid = [x for x in libs if x not in self.AVAILABLE_LIBS]
if len(invalid) > 0:
raise NameError("library %s invalid" % ", ".join(invalid))
for lib in libs:
self._use[lib] = True
self._css = []
try:
self._css = self._css + settings.DEFAULT_CSS
except AttributeError:
pass
self._js = []
try:
self._css = self._css + settings.DEFAULT_JS
except AttributeError:
pass
def _add_default_libs(self):
"""Adds the default libraries."""
invalid = [x for x in DEFAULT_LIBS if x not in self.AVAILABLE_LIBS]
if len(invalid) > 0:
raise NameError("library %s invalid" % ", ".join(invalid))
for lib in DEFAULT_LIBS:
self._use[lib] = True
def use(self, *args) -> None:
"""Use the specific libraries.
Args:
args: The libraries.
"""
if len(args) == 0:
return
libs = args[0]
invalid = [x for x in libs if x not in self.AVAILABLE_LIBS]
if len(invalid) > 0:
raise NameError("library %s invalid" % ", ".join(invalid))
for lib in libs:
self._use[lib] = True
def add_css(self, css) -> None:
"""Adds a custom CSS file."""
self._css.append(css)
def add_js(self, js) -> None:
"""Adds a custom JavaScript file."""
self._js.append(js)
def css(self) -> List[str]:
"""Returns the stylesheet files to use."""
use: Dict[str, bool] = self._solve_use_depencies()
css = []
for lib in [x for x in self.AVAILABLE_LIBS if use[x]]:
if lib == "i18n":
continue
try:
css = css + settings.STATIC_LIBS[lib]["css"]
except AttributeError:
css = css + CDN_LIBRARIES[lib]["css"]
except TypeError:
css = css + CDN_LIBRARIES[lib]["css"]
except KeyError:
css = css + CDN_LIBRARIES[lib]["css"]
return css + self._css
def js(self) -> List[str]:
"""Returns the JavaScript files to use."""
use: Dict[str, bool] = self._solve_use_depencies()
js = []
for lib in [x for x in self.AVAILABLE_LIBS if use[x]]:
if lib == "i18n":
js.append(reverse("javascript-catalog"))
continue
try:
js = js + settings.STATIC_LIBS[lib]["js"]
except AttributeError:
js = js + CDN_LIBRARIES[lib]["js"]
except TypeError:
js = js + CDN_LIBRARIES[lib]["js"]
except KeyError:
js = js + CDN_LIBRARIES[lib]["js"]
return js + self._js
def _solve_use_depencies(self) -> Dict[str, bool]:
"""Solves and returns the library dependencies."""
use: Dict[str, bool] = {x: self._use[x] for x in self._use}
if use["period-chooser"]:
use["bootstrap4-tempusdominus"] = True
if use["bootstrap4-tempusdominus"]:
use["bootstrap4"] = True
if use["bootstrap4-datatables"]:
use["bootstrap4"] = True
if use["jquery-ui"]:
use["jquery"] = True
if use["bootstrap4"]:
use["jquery"] = True
return use
def add_default_libs(*args) -> None:
"""Adds the specified libraries to the default CSS and JavaScript
libraries.
Args:
args: The libraries to be added to the default libraries
"""
libs = args
invalid = [x for x in libs
if x not in CssAndJavaScriptLibraries.AVAILABLE_LIBS]
if len(invalid) > 0:
raise NameError("library %s invalid" % ", ".join(invalid))
for lib in libs:
if lib not in DEFAULT_LIBS:
DEFAULT_LIBS.append(lib)