introduce breadcrumbs in the web config

This commit is contained in:
Jakob Ketterl 2021-04-18 17:49:13 +02:00
parent 1968e15237
commit e8cf014903
17 changed files with 139 additions and 16 deletions

View File

@ -152,3 +152,7 @@ h1 {
.scheduler-static-time-inputs > select {
flex: 1 0 auto;
}
.breadcrumb {
margin-top: .5rem;
}

View File

@ -10,6 +10,7 @@
</HEAD><BODY>
${header}
<div class="container">
${breadcrumb}
<h1>OpenWebRX Feature Report</h1>
<table class="features table">
<tr>
@ -19,5 +20,6 @@
<th>Available</th>
</tr>
</table>
${breadcrumb}
</div>
</BODY></HTML>

View File

@ -13,8 +13,7 @@ $(function(){
});
$table.append(
'<tr>' +
'<td colspan=2>' + name + '</td>' +
'<td>' + converter.makeHtml(details.description) + '</td>' +
'<td colspan=3>' + name + '</td>' +
'<td>' + (details.available ? 'YES' : 'NO') + '</td>' +
'</tr>' +
requirements.join("")

View File

@ -11,6 +11,7 @@
<body>
${header}
<div class="container">
${breadcrumb}
<div class="row">
<h1 class="col-12">Bookmarks</h1>
</div>
@ -24,6 +25,7 @@ ${header}
<button type="button" class="btn btn-primary bookmark-add">Add a new bookmark</button>
</div>
</div>
${breadcrumb}
</div>
<div class="modal" id="deleteModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">

View File

@ -11,10 +11,12 @@
<body>
${header}
<div class="container">
${breadcrumb}
<div class="row">
<h1 class="col-12">${title}</h1>
</div>
${content}
${breadcrumb}
</div>
${modal}
</body>

42
owrx/breadcrumb.py Normal file
View File

@ -0,0 +1,42 @@
from typing import List
from abc import ABC, abstractmethod
class BreadcrumbItem(object):
def __init__(self, title, href):
self.title = title
self.href = href
def render(self, documentRoot):
return '<li class="breadcrumb-item"><a href="{documentRoot}{href}">{title}</a></li>'.format(
documentRoot=documentRoot, href=self.href, title=self.title
)
class Breadcrumb(object):
def __init__(self, breadcrumbs: List[BreadcrumbItem]):
self.items = breadcrumbs
def render(self, documentRoot):
return """
<ol class="breadcrumb">
{crumbs}
</ol>
""".format(
crumbs="".join(item.render(documentRoot) for item in self.items)
)
def append(self, crumb: BreadcrumbItem):
self.items.append(crumb)
return self
class BreadcrumbMixin(ABC):
def template_variables(self):
variables = super().template_variables()
variables["breadcrumb"] = self.get_breadcrumb().render(self.get_document_root())
return variables
@abstractmethod
def get_breadcrumb(self) -> Breadcrumb:
pass

View File

@ -0,0 +1,11 @@
from owrx.controllers.template import WebpageController
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem, BreadcrumbMixin
from owrx.controllers.settings import SettingsBreadcrumb
class FeatureController(BreadcrumbMixin, WebpageController):
def get_breadcrumb(self) -> Breadcrumb:
return SettingsBreadcrumb().append(BreadcrumbItem("Feature report", "features"))
def indexAction(self):
self.serve_template("features.html", **self.template_variables())

View File

@ -2,6 +2,7 @@ from owrx.config import Config
from owrx.controllers.admin import AuthorizationMixin
from owrx.controllers.template import WebpageController
from owrx.form.error import FormError
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem, BreadcrumbMixin
from abc import ABCMeta, abstractmethod
from urllib.parse import parse_qs
@ -50,7 +51,7 @@ class SettingsController(AuthorizationMixin, WebpageController):
self.serve_template("settings.html", **self.template_variables())
class SettingsFormController(AuthorizationMixin, WebpageController, metaclass=ABCMeta):
class SettingsFormController(AuthorizationMixin, BreadcrumbMixin, WebpageController, metaclass=ABCMeta):
def __init__(self, handler, request, options):
super().__init__(handler, request, options)
self.errors = {}
@ -144,3 +145,9 @@ class SettingsFormController(AuthorizationMixin, WebpageController, metaclass=AB
def buildModal(self):
return ""
class SettingsBreadcrumb(Breadcrumb):
def __init__(self):
super().__init__([])
self.append(BreadcrumbItem("Settings", "settings"))

View File

@ -1,11 +1,16 @@
from owrx.controllers.settings import SettingsFormController, Section
from owrx.form import CheckboxInput, ServicesCheckboxInput
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem
from owrx.controllers.settings import SettingsBreadcrumb
class BackgroundDecodingController(SettingsFormController):
def getTitle(self):
return "Background decoding"
def get_breadcrumb(self) -> Breadcrumb:
return SettingsBreadcrumb().append(BreadcrumbItem("Background decoding", "settings/backgrounddecoding"))
def getSections(self):
return [
Section(

View File

@ -1,7 +1,9 @@
from owrx.controllers.template import WebpageController
from owrx.controllers.admin import AuthorizationMixin
from owrx.controllers.settings import SettingsBreadcrumb
from owrx.bookmarks import Bookmark, Bookmarks
from owrx.modes import Modes
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem, BreadcrumbMixin
import json
import math
@ -10,7 +12,10 @@ import logging
logger = logging.getLogger(__name__)
class BookmarksController(AuthorizationMixin, WebpageController):
class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController):
def get_breadcrumb(self) -> Breadcrumb:
return SettingsBreadcrumb().append(BreadcrumbItem("Bookmark editor", "settings/bookmarks"))
def template_variables(self):
variables = super().template_variables()
variables["bookmarks"] = self.render_table()

View File

@ -1,14 +1,18 @@
from owrx.controllers.settings import SettingsFormController, Section
from owrx.controllers.settings import SettingsFormController, Section, SettingsBreadcrumb
from owrx.form import CheckboxInput, NumberInput, DropdownInput, Js8ProfileCheckboxInput, MultiCheckboxInput, Option
from owrx.form.wfm import WfmTauValues
from owrx.form.wsjt import Q65ModeMatrix, WsjtDecodingDepthsInput
from owrx.wsjt import Fst4Profile, Fst4wProfile
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem
class DecodingSettingsController(SettingsFormController):
def getTitle(self):
return "Demodulation and decoding"
def get_breadcrumb(self) -> Breadcrumb:
return SettingsBreadcrumb().append(BreadcrumbItem("Demodulation and decoding", "settings/decoding"))
def getSections(self):
return [
Section(

View File

@ -14,6 +14,8 @@ from owrx.form.receiverid import ReceiverKeysConverter
from owrx.form.gfx import AvatarInput, TopPhotoInput
from owrx.form.device import WaterfallLevelsInput, WaterfallAutoLevelsInput
from owrx.waterfall import WaterfallOptions
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem
from owrx.controllers.settings import SettingsBreadcrumb
import shutil
import os
from glob import glob
@ -27,6 +29,9 @@ class GeneralSettingsController(SettingsFormController):
def getTitle(self):
return "General Settings"
def get_breadcrumb(self) -> Breadcrumb:
return SettingsBreadcrumb().append(BreadcrumbItem("General Settings", "settings/general"))
def getSections(self):
return [
Section(

View File

@ -1,12 +1,16 @@
from owrx.controllers.settings import SettingsFormController, Section
from owrx.controllers.settings import SettingsFormController, Section, SettingsBreadcrumb
from owrx.form.converter import OptionalConverter
from owrx.form.aprs import AprsBeaconSymbols, AprsAntennaDirections
from owrx.form import TextInput, CheckboxInput, DropdownInput, NumberInput
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem
class ReportingController(SettingsFormController):
def getTitle(self):
return "Spotting and Reporting"
return "Spotting and reporting"
def get_breadcrumb(self) -> Breadcrumb:
return SettingsBreadcrumb().append(BreadcrumbItem("Spotting and reporting", "settings/reporting"))
def getSections(self):
return [

View File

@ -4,16 +4,23 @@ from owrx.controllers.settings import SettingsFormController
from owrx.source import SdrDeviceDescription, SdrDeviceDescriptionMissing, SdrClientClass
from owrx.config import Config
from owrx.connection import OpenWebRxReceiverClient
from owrx.controllers.settings import Section
from owrx.controllers.settings import Section, SettingsBreadcrumb
from urllib.parse import quote, unquote
from owrx.sdr import SdrService
from owrx.form import TextInput, DropdownInput, Option
from owrx.form.validator import RequiredValidator
from owrx.property import PropertyLayer, PropertyStack
from owrx.breadcrumb import BreadcrumbMixin, Breadcrumb, BreadcrumbItem
from abc import ABCMeta, abstractmethod
class SdrDeviceListController(AuthorizationMixin, WebpageController):
class SdrDeviceBreadcrumb(SettingsBreadcrumb):
def __init__(self):
super().__init__()
self.append(BreadcrumbItem("SDR device settings", "settings/sdr"))
class SdrDeviceListController(AuthorizationMixin, BreadcrumbMixin, WebpageController):
def template_variables(self):
variables = super().template_variables()
variables["content"] = self.render_devices()
@ -21,6 +28,9 @@ class SdrDeviceListController(AuthorizationMixin, WebpageController):
variables["modal"] = ""
return variables
def get_breadcrumb(self):
return SdrDeviceBreadcrumb()
def render_devices(self):
def render_device(device_id, config):
sources = SdrService.getAllSources()
@ -213,6 +223,11 @@ class SdrFormControllerWithModal(SdrFormController, metaclass=ABCMeta):
class SdrDeviceController(SdrFormControllerWithModal):
def get_breadcrumb(self) -> Breadcrumb:
return SdrDeviceBreadcrumb().append(
BreadcrumbItem(self.device["name"], "settings/sdr/{}".format(self.device_id))
)
def getData(self):
return self.device
@ -271,6 +286,9 @@ class NewSdrDeviceController(SettingsFormController):
self.stack.addLayer(0, id_layer)
self.stack.addLayer(1, self.data_layer)
def get_breadcrumb(self) -> Breadcrumb:
return SdrDeviceBreadcrumb().append(BreadcrumbItem("New device", "settings/sdr/newsdr"))
def getSections(self):
return [
Section(
@ -313,6 +331,17 @@ class SdrProfileController(SdrFormControllerWithModal):
super().__init__(handler, request, options)
self.profile_id, self.profile = self._get_profile()
def get_breadcrumb(self) -> Breadcrumb:
return (
SdrDeviceBreadcrumb()
.append(BreadcrumbItem(self.device["name"], "settings/sdr/{}".format(self.device_id)))
.append(
BreadcrumbItem(
self.profile["name"], "settings/sdr/{}/profile/{}".format(self.device_id, self.profile_id)
)
)
)
def getData(self):
return self.profile
@ -378,6 +407,13 @@ class NewProfileController(SdrProfileController):
self.stack.addLayer(1, id_layer)
super().__init__(handler, request, options)
def get_breadcrumb(self) -> Breadcrumb:
return (
SdrDeviceBreadcrumb()
.append(BreadcrumbItem(self.device["name"], "settings/sdr/{}".format(self.device_id)))
.append(BreadcrumbItem("New profile", "settings/sdr/{}/newprofile".format(self.device_id)))
)
def _get_profile(self):
return "new", self.stack

View File

@ -43,8 +43,3 @@ class MapController(WebpageController):
def indexAction(self):
# TODO check if we have a google maps api key first?
self.serve_template("map.html", **self.template_variables())
class FeatureController(WebpageController):
def indexAction(self):
self.serve_template("features.html", **self.template_variables())

View File

@ -99,7 +99,6 @@ class FeatureDetector(object):
def feature_details(name):
return {
"description": "",
"available": self.is_available(name),
"requirements": {name: requirement_details(name) for name in self.get_requirements(name)},
}

View File

@ -1,5 +1,6 @@
from owrx.controllers.status import StatusController
from owrx.controllers.template import IndexController, MapController, FeatureController
from owrx.controllers.template import IndexController, MapController
from owrx.controllers.feature import FeatureController
from owrx.controllers.assets import OwrxAssetsController, AprsSymbolsController, CompiledAssetsController
from owrx.controllers.websocket import WebSocketController
from owrx.controllers.api import ApiController