feat: inherit from wuttaweb for AppInfoView, appinfo/configure template
This commit is contained in:
parent
2ffc067097
commit
f755460242
|
@ -703,7 +703,7 @@ class TailboneMenuHandler(WuttaMenuHandler):
|
|||
},
|
||||
{'type': 'sep'},
|
||||
{
|
||||
'title': "App Details",
|
||||
'title': "App Info",
|
||||
'route': 'appinfo',
|
||||
'perm': 'appinfo.list',
|
||||
},
|
||||
|
|
|
@ -1,247 +1,2 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
<%inherit file="/configure.mako" />
|
||||
|
||||
<%def name="form_content()">
|
||||
|
||||
<h3 class="block is-size-3">Basics</h3>
|
||||
<div class="block" style="padding-left: 2rem;">
|
||||
|
||||
<b-field grouped>
|
||||
|
||||
<b-field label="App Title">
|
||||
<b-input name="rattail.app_title"
|
||||
v-model="simpleSettings['rattail.app_title']"
|
||||
@input="settingsNeedSaved = true">
|
||||
</b-input>
|
||||
</b-field>
|
||||
|
||||
<b-field label="Node Type">
|
||||
## TODO: should be a dropdown, app handler defines choices
|
||||
<b-input name="rattail.node_type"
|
||||
v-model="simpleSettings['rattail.node_type']"
|
||||
@input="settingsNeedSaved = true">
|
||||
</b-input>
|
||||
</b-field>
|
||||
|
||||
<b-field label="Node Title">
|
||||
<b-input name="rattail.node_title"
|
||||
v-model="simpleSettings['rattail.node_title']"
|
||||
@input="settingsNeedSaved = true">
|
||||
</b-input>
|
||||
</b-field>
|
||||
|
||||
</b-field>
|
||||
|
||||
<b-field>
|
||||
<b-checkbox name="rattail.production"
|
||||
v-model="simpleSettings['rattail.production']"
|
||||
native-value="true"
|
||||
@input="settingsNeedSaved = true">
|
||||
Production Mode
|
||||
</b-checkbox>
|
||||
</b-field>
|
||||
|
||||
<div class="level-left">
|
||||
<div class="level-item">
|
||||
<b-field>
|
||||
<b-checkbox name="rattail.running_from_source"
|
||||
v-model="simpleSettings['rattail.running_from_source']"
|
||||
native-value="true"
|
||||
@input="settingsNeedSaved = true">
|
||||
Running from Source
|
||||
</b-checkbox>
|
||||
</b-field>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<b-field label="Top-Level Package" horizontal
|
||||
v-if="simpleSettings['rattail.running_from_source']">
|
||||
<b-input name="rattail.running_from_source.rootpkg"
|
||||
v-model="simpleSettings['rattail.running_from_source.rootpkg']"
|
||||
@input="settingsNeedSaved = true">
|
||||
</b-input>
|
||||
</b-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h3 class="block is-size-3">Display</h3>
|
||||
<div class="block" style="padding-left: 2rem;">
|
||||
|
||||
<b-field grouped>
|
||||
|
||||
<b-field label="Background Color">
|
||||
<b-input name="tailbone.background_color"
|
||||
v-model="simpleSettings['tailbone.background_color']"
|
||||
@input="settingsNeedSaved = true">
|
||||
</b-input>
|
||||
</b-field>
|
||||
|
||||
</b-field>
|
||||
|
||||
</div>
|
||||
|
||||
<h3 class="block is-size-3">Grids</h3>
|
||||
<div class="block" style="padding-left: 2rem;">
|
||||
|
||||
<b-field grouped>
|
||||
|
||||
<b-field label="Default Page Size">
|
||||
<b-input name="tailbone.grid.default_pagesize"
|
||||
v-model="simpleSettings['tailbone.grid.default_pagesize']"
|
||||
@input="settingsNeedSaved = true">
|
||||
</b-input>
|
||||
</b-field>
|
||||
|
||||
</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:
|
||||
${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_vue_vars()">
|
||||
${parent.modify_vue_vars()}
|
||||
<script>
|
||||
|
||||
ThisPageData.weblibs = ${json.dumps(weblibs)|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>
|
||||
<%inherit file="wuttaweb:templates/appinfo/configure.mako" />
|
||||
|
|
|
@ -666,6 +666,7 @@
|
|||
<%def name="make_b_tooltip_component()">
|
||||
<script type="text/x-template" id="b-tooltip-template">
|
||||
<o-tooltip :label="label"
|
||||
:position="orugaPosition"
|
||||
:multiline="multilined">
|
||||
<slot />
|
||||
</o-tooltip>
|
||||
|
@ -676,6 +677,14 @@
|
|||
props: {
|
||||
label: String,
|
||||
multilined: Boolean,
|
||||
position: String,
|
||||
},
|
||||
computed: {
|
||||
orugaPosition() {
|
||||
if (this.position) {
|
||||
return this.position.replace(/^is-/, '')
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -25,11 +25,7 @@ Settings Views
|
|||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from collections import OrderedDict
|
||||
|
||||
import colander
|
||||
|
||||
|
@ -37,201 +33,77 @@ from rattail.db.model import Setting
|
|||
from rattail.settings import Setting as AppSetting
|
||||
from rattail.util import import_module_path
|
||||
|
||||
from tailbone import forms
|
||||
from tailbone import forms, grids
|
||||
from tailbone.db import Session
|
||||
from tailbone.views import MasterView, View
|
||||
from wuttaweb.util import get_libver, get_liburl
|
||||
from wuttaweb.views.settings import AppInfoView as WuttaAppInfoView
|
||||
|
||||
|
||||
class AppInfoView(MasterView):
|
||||
"""
|
||||
Master view for the overall app, to show/edit config etc.
|
||||
"""
|
||||
route_prefix = 'appinfo'
|
||||
model_key = 'UNUSED'
|
||||
model_title = "UNUSED"
|
||||
model_title_plural = "App Details"
|
||||
creatable = False
|
||||
viewable = False
|
||||
editable = False
|
||||
deletable = False
|
||||
filterable = False
|
||||
pageable = False
|
||||
configurable = True
|
||||
|
||||
grid_columns = [
|
||||
'name',
|
||||
'version',
|
||||
'editable_project_location',
|
||||
]
|
||||
|
||||
def get_index_title(self):
|
||||
app = self.get_rattail_app()
|
||||
return "{} for {}".format(self.get_model_title_plural(),
|
||||
app.get_title())
|
||||
|
||||
def get_data(self, session=None):
|
||||
class AppInfoView(WuttaAppInfoView):
|
||||
""" """
|
||||
Session = Session
|
||||
weblib_config_prefix = 'tailbone'
|
||||
|
||||
# nb. init with empty data, only load it upon user request
|
||||
if not self.request.GET.get('partial'):
|
||||
return []
|
||||
|
||||
# TODO: pretty sure this is not cross-platform. probably some
|
||||
# sort of pip methods belong on the app handler? or it should
|
||||
# have a pip handler for all that?
|
||||
pip = os.path.join(sys.prefix, 'bin', 'pip')
|
||||
output = subprocess.check_output([pip, 'list', '--format=json'])
|
||||
data = json.loads(output.decode('utf_8').strip())
|
||||
|
||||
# must avoid null values for sort to work right
|
||||
for pkg in data:
|
||||
pkg.setdefault('editable_project_location', '')
|
||||
|
||||
return data
|
||||
# TODO: for now we override to get tailbone searchable grid
|
||||
def make_grid(self, **kwargs):
|
||||
""" """
|
||||
return grids.Grid(self.request, **kwargs)
|
||||
|
||||
def configure_grid(self, g):
|
||||
""" """
|
||||
super().configure_grid(g)
|
||||
|
||||
# sort on frontend
|
||||
g.sort_on_backend = False
|
||||
g.sort_multiple = False
|
||||
g.set_sort_defaults('name')
|
||||
|
||||
# name
|
||||
g.set_searchable('name')
|
||||
|
||||
# editable_project_location
|
||||
g.set_searchable('editable_project_location')
|
||||
|
||||
def template_kwargs_index(self, **kwargs):
|
||||
kwargs = super().template_kwargs_index(**kwargs)
|
||||
kwargs['configure_button_title'] = "Configure App"
|
||||
return kwargs
|
||||
|
||||
def get_weblibs(self):
|
||||
""" """
|
||||
return 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"),
|
||||
])
|
||||
|
||||
def configure_get_context(self, **kwargs):
|
||||
""" """
|
||||
context = super().configure_get_context(**kwargs)
|
||||
simple_settings = context['simple_settings']
|
||||
weblibs = self.get_weblibs()
|
||||
weblibs = context['weblibs']
|
||||
|
||||
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,
|
||||
prefix='tailbone',
|
||||
configured_only=True),
|
||||
'configured_url': get_liburl(self.request, key,
|
||||
prefix='tailbone',
|
||||
configured_only=True),
|
||||
|
||||
# these are for informational purposes only
|
||||
'default_version': get_libver(self.request, key,
|
||||
prefix='tailbone',
|
||||
default_only=True),
|
||||
'live_url': get_liburl(self.request, key,
|
||||
prefix='tailbone'),
|
||||
}
|
||||
for weblib in weblibs:
|
||||
key = weblib['key']
|
||||
|
||||
# TODO: this is only needed to migrate legacy settings to
|
||||
# use the newer wutaweb setting names
|
||||
# use the newer wuttaweb setting names
|
||||
url = simple_settings[f'wuttaweb.liburl.{key}']
|
||||
if not url and weblibs[key]['configured_url']:
|
||||
simple_settings[f'wuttaweb.liburl.{key}'] = weblibs[key]['configured_url']
|
||||
if not url and weblib['configured_url']:
|
||||
simple_settings[f'wuttaweb.liburl.{key}'] = weblib['configured_url']
|
||||
|
||||
context['weblibs'] = list(weblibs.values())
|
||||
return context
|
||||
|
||||
def configure_get_simple_settings(self):
|
||||
""" """
|
||||
simple_settings = [
|
||||
simple_settings = super().configure_get_simple_settings()
|
||||
|
||||
# basics
|
||||
{'section': 'rattail',
|
||||
'option': 'app_title'},
|
||||
{'section': 'rattail',
|
||||
'option': 'node_type'},
|
||||
{'section': 'rattail',
|
||||
'option': 'node_title'},
|
||||
{'section': 'rattail',
|
||||
'option': 'production',
|
||||
'type': bool},
|
||||
{'section': 'rattail',
|
||||
'option': 'running_from_source',
|
||||
'type': bool},
|
||||
{'section': 'rattail',
|
||||
'option': 'running_from_source.rootpkg'},
|
||||
|
||||
# display
|
||||
{'section': 'tailbone',
|
||||
'option': 'background_color'},
|
||||
|
||||
# grids
|
||||
{'section': 'tailbone',
|
||||
'option': 'grid.default_pagesize',
|
||||
# TODO: seems like should enforce this, but validation is
|
||||
# not setup yet
|
||||
# 'type': int
|
||||
},
|
||||
# TODO: the update home page redirect setting is off by
|
||||
# default for wuttaweb, but on for tailbone
|
||||
for setting in simple_settings:
|
||||
if setting['name'] == 'wuttaweb.home_redirect_to_login':
|
||||
value = self.config.get_bool('wuttaweb.home_redirect_to_login')
|
||||
if value is None:
|
||||
value = self.config.get_bool('tailbone.login_is_home', default=True)
|
||||
setting['default'] = value
|
||||
break
|
||||
|
||||
# nb. these are no longer used (deprecated), but we keep
|
||||
# them defined here so the tool auto-deletes them
|
||||
{'section': 'tailbone',
|
||||
'option': 'buefy_version'},
|
||||
{'section': 'tailbone',
|
||||
'option': 'vue_version'},
|
||||
|
||||
]
|
||||
simple_settings.extend([
|
||||
{'name': 'tailbone.buefy_version'},
|
||||
{'name': 'tailbone.vue_version'},
|
||||
])
|
||||
|
||||
def getval(key):
|
||||
return self.config.get(f'tailbone.{key}')
|
||||
|
||||
weblibs = self.get_weblibs()
|
||||
for key, title in weblibs.items():
|
||||
|
||||
simple_settings.append({
|
||||
'section': 'wuttaweb',
|
||||
'option': f"libver.{key}",
|
||||
'default': getval(f"libver.{key}"),
|
||||
})
|
||||
simple_settings.append({
|
||||
'section': 'wuttaweb',
|
||||
'option': f"liburl.{key}",
|
||||
'default': getval(f"liburl.{key}"),
|
||||
})
|
||||
|
||||
# nb. these are no longer used (deprecated), but we keep
|
||||
# them defined here so the tool auto-deletes them
|
||||
simple_settings.append({
|
||||
'section': 'tailbone',
|
||||
'option': f"libver.{key}",
|
||||
})
|
||||
simple_settings.append({
|
||||
'section': 'tailbone',
|
||||
'option': f"liburl.{key}",
|
||||
})
|
||||
for key in self.get_weblibs():
|
||||
simple_settings.extend([
|
||||
{'name': f'tailbone.libver.{key}'},
|
||||
{'name': f'tailbone.liburl.{key}'},
|
||||
])
|
||||
|
||||
return simple_settings
|
||||
|
||||
|
|
Loading…
Reference in a new issue