2
0
Fork 0

feat: expose Web Libraries in app info config page

get away from that CDN, hopefully speeds things up etc.
This commit is contained in:
Lance Edgar 2024-08-06 19:59:30 -05:00
parent ed67cdb2d8
commit d35e6e71c9
5 changed files with 306 additions and 24 deletions

View file

@ -13,8 +13,164 @@
</b-input>
</b-field>
<b-field>
<b-checkbox name="${app.appname}.production"
v-model="simpleSettings['${app.appname}.production']"
native-value="true"
@input="settingsNeedSaved = true">
Production Mode
</b-checkbox>
</b-field>
</div>
<h3 class="block is-size-3">Web Libraries</h3>
<div class="block" style="padding-left: 2rem;">
<${b}-table :data="weblibs">
<${b}-table-column field="title"
label="Name"
v-slot="props">
{{ props.row.title }}
</${b}-table-column>
<${b}-table-column field="configured_version"
label="Version"
v-slot="props">
{{ props.row.configured_version || props.row.default_version }}
</${b}-table-column>
<${b}-table-column field="configured_url"
label="URL Override"
v-slot="props">
{{ props.row.configured_url }}
</${b}-table-column>
<${b}-table-column field="live_url"
label="Effective (Live) URL"
v-slot="props">
<span v-if="props.row.modified"
class="has-text-warning">
save settings and refresh page to see new URL
</span>
<span v-if="!props.row.modified">
{{ props.row.live_url }}
</span>
</${b}-table-column>
<${b}-table-column field="actions"
label="Actions"
v-slot="props">
<a href="#"
@click.prevent="editWebLibraryInit(props.row)">
% if request.use_oruga:
<o-icon icon="edit" />
% else:
<i class="fas fa-edit"></i>
% endif
Edit
</a>
</${b}-table-column>
</${b}-table>
% for weblib in weblibs or []:
${h.hidden('wuttaweb.libver.{}'.format(weblib['key']), **{':value': "simpleSettings['wuttaweb.libver.{}']".format(weblib['key'])})}
${h.hidden('wuttaweb.liburl.{}'.format(weblib['key']), **{':value': "simpleSettings['wuttaweb.liburl.{}']".format(weblib['key'])})}
% endfor
<${b}-modal has-modal-card
% if request.use_oruga:
v-model:active="editWebLibraryShowDialog"
% else:
:active.sync="editWebLibraryShowDialog"
% endif
>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Web Library: {{ editWebLibraryRecord.title }}</p>
</header>
<section class="modal-card-body">
<b-field grouped>
<b-field label="Default Version">
<b-input v-model="editWebLibraryRecord.default_version"
disabled>
</b-input>
</b-field>
<b-field label="Override Version">
<b-input v-model="editWebLibraryVersion">
</b-input>
</b-field>
</b-field>
<b-field label="Override URL">
<b-input v-model="editWebLibraryURL"
expanded />
</b-field>
<b-field label="Effective URL (as of last page load)">
<b-input v-model="editWebLibraryRecord.live_url"
disabled
expanded />
</b-field>
</section>
<footer class="modal-card-foot">
<b-button type="is-primary"
@click="editWebLibrarySave()"
icon-pack="fas"
icon-left="save">
Save
</b-button>
<b-button @click="editWebLibraryShowDialog = false">
Cancel
</b-button>
</footer>
</div>
</${b}-modal>
</div>
</%def>
<%def name="modify_this_page_vars()">
${parent.modify_this_page_vars()}
<script>
ThisPageData.weblibs = ${json.dumps(weblibs or [])|n}
ThisPageData.editWebLibraryShowDialog = false
ThisPageData.editWebLibraryRecord = {}
ThisPageData.editWebLibraryVersion = null
ThisPageData.editWebLibraryURL = null
ThisPage.methods.editWebLibraryInit = function(row) {
this.editWebLibraryRecord = row
this.editWebLibraryVersion = row.configured_version
this.editWebLibraryURL = row.configured_url
this.editWebLibraryShowDialog = true
}
ThisPage.methods.editWebLibrarySave = function() {
this.editWebLibraryRecord.configured_version = this.editWebLibraryVersion
this.editWebLibraryRecord.configured_url = this.editWebLibraryURL
this.editWebLibraryRecord.modified = true
this.simpleSettings[`wuttaweb.libver.${'$'}{this.editWebLibraryRecord.key}`] = this.editWebLibraryVersion
this.simpleSettings[`wuttaweb.liburl.${'$'}{this.editWebLibraryRecord.key}`] = this.editWebLibraryURL
this.settingsNeedSaved = true
this.editWebLibraryShowDialog = false
}
</script>
</%def>

View file

@ -53,6 +53,7 @@ def get_form_data(request):
def get_libver(
request,
key,
configured_only=False,
default_only=False,
prefix='wuttaweb',
):
@ -78,13 +79,11 @@ def get_libver(
:param key: Unique key for the library, as string. Possibilities
are the same as for :func:`get_liburl()`.
:param default_only: If this flag is ``True``, the logic will
*not* look for a "configured" version but rather will *only*
return the "default" version regardless of config.
:param configured_only: Pass ``True`` here if you only want the
configured version and ignore the default version.
If the flag is ``False`` (which it is by default) then the
config value will be used if present, and a default version is
used only if the config does not have a value.
:param default_only: Pass ``True`` here if you only want the
default version and ignore the configured version.
:param prefix: If specified, will override the prefix used for
config lookups.
@ -95,7 +94,7 @@ def get_libver(
be removed in the future.
:returns: The appropriate version string, e.g. ``'1.2.3'`` or
``'latest'`` etc.
``'latest'`` etc. Can also return ``None`` in some cases.
"""
config = request.wutta_config
@ -115,11 +114,14 @@ def get_libver(
version = config.get(f'{prefix}.buefy_version')
if version:
return version
return 'latest'
if not configured_only:
return 'latest'
elif key == 'buefy.css':
# nb. this always returns something
return get_libver(request, 'buefy', default_only=default_only)
return get_libver(request, 'buefy',
default_only=default_only,
configured_only=configured_only)
elif key == 'vue':
if not default_only:
@ -127,36 +129,47 @@ def get_libver(
version = config.get(f'{prefix}.vue_version')
if version:
return version
return '2.6.14'
if not configured_only:
return '2.6.14'
elif key == 'vue_resource':
return 'latest'
if not configured_only:
return 'latest'
elif key == 'fontawesome':
return '5.3.1'
if not configured_only:
return '5.3.1'
elif key == 'bb_vue':
return '3.4.31'
if not configured_only:
return '3.4.31'
elif key == 'bb_oruga':
return '0.8.12'
if not configured_only:
return '0.8.12'
elif key in ('bb_oruga_bulma', 'bb_oruga_bulma_css'):
return '0.3.0'
if not configured_only:
return '0.3.0'
elif key == 'bb_fontawesome_svg_core':
return '6.5.2'
if not configured_only:
return '6.5.2'
elif key == 'bb_free_solid_svg_icons':
return '6.5.2'
if not configured_only:
return '6.5.2'
elif key == 'bb_vue_fontawesome':
return '3.0.6'
if not configured_only:
return '3.0.6'
def get_liburl(
request,
key,
configured_only=False,
default_only=False,
prefix='wuttaweb',
):
"""
@ -206,6 +219,12 @@ def get_liburl(
* ``bb_free_solid_svg_icons``
* ``bb_vue_fontawesome``
:param configured_only: Pass ``True`` here if you only want the
configured URL and ignore the default URL.
:param default_only: Pass ``True`` here if you only want the
default URL and ignore the configured URL.
:param prefix: If specified, will override the prefix used for
config lookups.
@ -214,13 +233,18 @@ def get_liburl(
This ``prefix`` param is for backward compatibility and may
be removed in the future.
:returns: The appropriate URL as string.
:returns: The appropriate URL as string. Can also return ``None``
in some cases.
"""
config = request.wutta_config
url = config.get(f'{prefix}.liburl.{key}')
if url:
return url
if not default_only:
url = config.get(f'{prefix}.liburl.{key}')
if url:
return url
if configured_only:
return
version = get_libver(request, key, prefix=prefix)

View file

@ -24,7 +24,10 @@
Views for app settings
"""
from collections import OrderedDict
from wuttaweb.views import MasterView
from wuttaweb.util import get_libver, get_liburl
class AppInfoView(MasterView):
@ -47,9 +50,82 @@ class AppInfoView(MasterView):
# basics
{'name': f'{self.app.appname}.app_title'},
{'name': f'{self.app.appname}.production',
'type': bool},
# web libs
{'name': 'wuttaweb.libver.vue'},
{'name': 'wuttaweb.liburl.vue'},
{'name': 'wuttaweb.libver.vue_resource'},
{'name': 'wuttaweb.liburl.vue_resource'},
{'name': 'wuttaweb.libver.buefy'},
{'name': 'wuttaweb.liburl.buefy'},
{'name': 'wuttaweb.libver.buefy.css'},
{'name': 'wuttaweb.liburl.buefy.css'},
{'name': 'wuttaweb.libver.fontawesome'},
{'name': 'wuttaweb.liburl.fontawesome'},
{'name': 'wuttaweb.libver.bb_vue'},
{'name': 'wuttaweb.liburl.bb_vue'},
{'name': 'wuttaweb.libver.bb_oruga'},
{'name': 'wuttaweb.liburl.bb_oruga'},
{'name': 'wuttaweb.libver.bb_oruga_bulma'},
{'name': 'wuttaweb.liburl.bb_oruga_bulma'},
{'name': 'wuttaweb.libver.bb_oruga_bulma_css'},
{'name': 'wuttaweb.liburl.bb_oruga_bulma_css'},
{'name': 'wuttaweb.libver.bb_fontawesome_svg_core'},
{'name': 'wuttaweb.liburl.bb_fontawesome_svg_core'},
{'name': 'wuttaweb.libver.bb_free_solid_svg_icons'},
{'name': 'wuttaweb.liburl.bb_free_solid_svg_icons'},
{'name': 'wuttaweb.libver.bb_vue_fontawesome'},
{'name': 'wuttaweb.liburl.bb_vue_fontawesome'},
]
def configure_get_context(self, **kwargs):
""" """
# normal context
context = super().configure_get_context(**kwargs)
# we will add `weblibs` to context, based on config values
weblibs = OrderedDict([
('vue', "Vue"),
('vue_resource', "vue-resource"),
('buefy', "Buefy"),
('buefy.css', "Buefy CSS"),
('fontawesome', "FontAwesome"),
('bb_vue', "(BB) vue"),
('bb_oruga', "(BB) @oruga-ui/oruga-next"),
('bb_oruga_bulma', "(BB) @oruga-ui/theme-bulma (JS)"),
('bb_oruga_bulma_css', "(BB) @oruga-ui/theme-bulma (CSS)"),
('bb_fontawesome_svg_core', "(BB) @fortawesome/fontawesome-svg-core"),
('bb_free_solid_svg_icons', "(BB) @fortawesome/free-solid-svg-icons"),
('bb_vue_fontawesome', "(BB) @fortawesome/vue-fontawesome"),
])
# import ipdb; ipdb.set_trace()
for key in weblibs:
title = weblibs[key]
weblibs[key] = {
'key': key,
'title': title,
# nb. these values are exactly as configured, and are
# used for editing the settings
'configured_version': get_libver(self.request, key,
configured_only=True),
'configured_url': get_liburl(self.request, key,
configured_only=True),
# nb. these are for display only
'default_version': get_libver(self.request, key, default_only=True),
'live_url': get_liburl(self.request, key),
}
context['weblibs'] = list(weblibs.values())
return context
def defaults(config, **kwargs):
base = globals()

View file

@ -30,6 +30,10 @@ class TestGetLibVer(TestCase):
version = util.get_libver(self.request, 'buefy')
self.assertEqual(version, '0.9.29')
def test_buefy_configured_only(self):
version = util.get_libver(self.request, 'buefy', configured_only=True)
self.assertIsNone(version)
def test_buefy_default_only(self):
self.config.setdefault('wuttaweb.libver.buefy', '0.9.29')
version = util.get_libver(self.request, 'buefy', default_only=True)
@ -51,6 +55,10 @@ class TestGetLibVer(TestCase):
version = util.get_libver(self.request, 'buefy.css')
self.assertEqual(version, '0.9.29')
def test_buefy_css_configured_only(self):
version = util.get_libver(self.request, 'buefy.css', configured_only=True)
self.assertIsNone(version)
def test_buefy_css_default_only(self):
self.config.setdefault('wuttaweb.libver.buefy', '0.9.29')
version = util.get_libver(self.request, 'buefy.css', default_only=True)
@ -70,6 +78,10 @@ class TestGetLibVer(TestCase):
version = util.get_libver(self.request, 'vue')
self.assertEqual(version, '3.4.31')
def test_vue_configured_only(self):
version = util.get_libver(self.request, 'vue', configured_only=True)
self.assertIsNone(version)
def test_vue_default_only(self):
self.config.setdefault('wuttaweb.libver.vue', '3.4.31')
version = util.get_libver(self.request, 'vue', default_only=True)
@ -166,6 +178,15 @@ class TestGetLibUrl(TestCase):
url = util.get_liburl(self.request, 'buefy')
self.assertEqual(url, '/lib/buefy.js')
def test_buefy_default_only(self):
self.config.setdefault('wuttaweb.liburl.buefy', '/lib/buefy.js')
url = util.get_liburl(self.request, 'buefy', default_only=True)
self.assertEqual(url, 'https://unpkg.com/buefy@latest/dist/buefy.min.js')
def test_buefy_configured_only(self):
url = util.get_liburl(self.request, 'buefy', configured_only=True)
self.assertIsNone(url)
def test_buefy_css_default(self):
url = util.get_liburl(self.request, 'buefy.css')
self.assertEqual(url, 'https://unpkg.com/buefy@latest/dist/buefy.min.css')

View file

@ -8,11 +8,16 @@ from wuttaweb.views import settings
class TestAppInfoView(WebTestCase):
def test_index(self):
# just a sanity check
# sanity/coverage check
view = settings.AppInfoView(self.request)
response = view.index()
def test_configure_get_simple_settings(self):
# just a sanity check
# sanity/coverage check
view = settings.AppInfoView(self.request)
simple = view.configure_get_simple_settings()
def test_configure_get_context(self):
# sanity/coverage check
view = settings.AppInfoView(self.request)
context = view.configure_get_context()