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 %} {% block settings %}
{% trans "Accounts" context "Accounting" as text %} {% trans "Accounts" context "Accounting" as text %}
{% setvar "title" text %} {% setvar "title" text %}
{% setvar "use_datatables" True %} {% add_lib "bootstrap4-datatables" %}
{% static "accounting/js/account-list.js" as file %}{% add_js file %} {% static "accounting/js/account-list.js" as file %}{% add_js file %}
{% endblock %} {% endblock %}

View File

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

View File

@ -28,7 +28,7 @@ First written: 2020/7/1
{% block settings %} {% 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 %} {% 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 "title" title %}
{% setvar "use_period_chooser" True %} {% add_lib "period-chooser" %}
{% static "accounting/css/report.css" as file %}{% add_css file %} {% static "accounting/css/report.css" as file %}{% add_css file %}
{% endblock %} {% endblock %}

View File

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

View File

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

View File

@ -28,7 +28,7 @@ First written: 2020/7/16
{% block settings %} {% 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 %} {% 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 "title" title %}
{% setvar "use_period_chooser" True %} {% add_lib "period-chooser" %}
{% static "accounting/css/report.css" as file %}{% add_css file %} {% static "accounting/css/report.css" as file %}{% add_css file %}
{% endblock %} {% endblock %}

View File

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

View File

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

View File

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

View File

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

View File

@ -28,8 +28,7 @@ First written: 2020/7/23
{% block settings %} {% block settings %}
{% setvar "title" _("Transfer Transaction") %} {% setvar "title" _("Transfer Transaction") %}
{% setvar "use_jqueryui" True %} {% add_lib "jquery-ui" "decimal-js" %}
{% static "ext-libs/decimal/decimal.min.js" as file %}{% add_js file %}
{% static "accounting/css/transactions.css" as file %}{% add_css file %} {% static "accounting/css/transactions.css" as file %}{% add_css file %}
{% static "accounting/css/summary-helper.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 %} {% 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 django.views.generic import ListView, DetailView
from mia_core.period import Period 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 mia_core.views import DeleteView, FormView, RedirectView
from . import utils from . import utils
from .forms import AccountForm, TransactionForm, TransactionSortForm from .forms import AccountForm, TransactionForm, TransactionSortForm
from .models import Record, Transaction, Account from .models import Record, Transaction, Account
add_default_libs("bootstrap4", "font-awesome-5", "i18n")
@method_decorator(require_GET, name="dispatch") @method_decorator(require_GET, name="dispatch")
class CashDefaultView(RedirectView): class CashDefaultView(RedirectView):

View File

@ -19,8 +19,9 @@
""" """
import datetime import datetime
import re
from datetime import date from datetime import date
from typing import Any from typing import Any, List
import titlecase import titlecase
from django import template from django import template
@ -31,7 +32,7 @@ from django.utils import timezone
from django.utils.safestring import SafeString from django.utils.safestring import SafeString
from django.utils.translation import gettext from django.utils.translation import gettext
from mia_core.utils import UrlBuilder from mia_core.utils import UrlBuilder, CssAndJavaScriptLibraries
register = template.Library() 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"))) 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) @register.simple_tag(takes_context=True)
def add_css(context: RequestContext, url: str) -> str: def add_css(context: RequestContext, url: str) -> str:
"""Adds a local CSS file. The file is added to the "css" template """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. url: The URL or path of the CSS file.
Returns: Returns:
An empty string An empty string.
""" """
if "css" not in context.dicts[0]: if "libs" not in context.dicts[0]:
context.dicts[0]["css"] = [] context.dicts[0]["libs"] = CssAndJavaScriptLibraries()
context.dicts[0]["css"].append(url) context.dicts[0]["libs"].add_css(url)
return "" return ""
@ -131,11 +150,11 @@ def add_js(context: RequestContext, url: str) -> str:
url: The URL or path of the JavaScript file. url: The URL or path of the JavaScript file.
Returns: Returns:
An empty string An empty string.
""" """
if "js" not in context.dicts[0]: if "libs" not in context.dicts[0]:
context.dicts[0]["js"] = [] context.dicts[0]["libs"] = CssAndJavaScriptLibraries()
context.dicts[0]["js"].append(url) context.dicts[0]["libs"].add_js(url)
return "" return ""
@ -215,3 +234,18 @@ def is_in_section(request: HttpRequest, section_name: str) -> bool:
view_name = request.resolver_match.view_name view_name = request.resolver_match.view_name
return view_name == section_name\ return view_name == section_name\
or view_name.startswith(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 random
import urllib.parse 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.conf import settings
from django.db.models import Model from django.db.models import Model
from django.http import HttpRequest from django.http import HttpRequest
from django.urls import reverse
from django.utils.translation import pgettext, get_language from django.utils.translation import pgettext, get_language
@ -438,3 +439,159 @@ class PaginationException(Exception):
""" """
def __init__(self, url_builder: UrlBuilder): def __init__(self, url_builder: UrlBuilder):
self.url = str(url_builder) 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)