Exemple #1
0
class LinkBar(Widget):
    '''A bar which contains links to other pages.
    '''

    # These icons are referenced from the style sheet.
    styleRoot.addIcon('IconNew')
    styleRoot.addIcon('IconEdit')
    styleRoot.addIcon('IconDelete')

    __iconModifierStyle = {
        IconModifier.NEW: 'newicon',
        IconModifier.EDIT: 'editicon',
        IconModifier.DELETE: 'delicon',
    }

    __levelSep = xhtml.div(class_='level')['\u25B8']

    def __presentLinkButton(self, button: LinkBarButton,
                            **kwargs: object) -> XMLNode:
        iconStyle = ['navicon']
        iconModifier = button.modifier
        if iconModifier is not IconModifier.NONE:
            iconStyle.append(self.__iconModifierStyle[button.modifier])

        return xhtml.div(class_='navthis' if button.active else None)[xhtml.a(
            href=button.url)[xhtml.span(
                class_=' '.join(iconStyle))[button.icon.present(**kwargs)],
                             xhtml.span(class_='navlabel')[button.label]]]

    def __presentButtons(self, **kwargs: object) -> XMLContent:
        rootButtons = cast(Sequence[LinkBarButton], kwargs['rootButtons'])
        childButtons = cast(Sequence[LinkBarButton], kwargs['childButtons'])
        levelSep = self.__levelSep

        # Root path.
        for button in rootButtons:
            presentation = self.__presentLinkButton(button, **kwargs)
            isParent = not button.active
            if isParent or childButtons:
                presentation = presentation.addClass('rootpath')
            yield presentation
            if isParent:
                yield levelSep

        # Children.
        if childButtons:
            yield levelSep
            for button in childButtons:
                yield self.__presentLinkButton(button, **kwargs)

    def present(self, **kwargs: object) -> XMLContent:
        return xhtml.div(class_='linkbar')[self.__presentButtons(**kwargs)]
Exemple #2
0
    def __processPage(cls, name: str, parents: Sequence[str] = ()) -> None:
        baseModule = cls.__module__.split('.')[:-1]
        fullName = '.'.join(baseModule + [name])
        if fullName not in sys.modules:
            __import__(fullName)
        module = sys.modules[fullName]
        pageClass = getattr(module, name + '_GET')
        description = pageClass.description
        linkDescription = pageClass.linkDescription
        if linkDescription is None:
            linkDescription = pageClass.description
        # TODO: Maybe it's easier to just store the class reference?
        cls.__pageInfo[name] = {
            'parents':
            parents,
            'icon':
            None
            if pageClass.icon is None else styleRoot.addIcon(pageClass.icon),
            'iconModifier':
            pageClass.iconModifier,
            'description':
            description,
            'linkDescription':
            linkDescription,
            'isActive':
            pageClass.isActive,
            'parameters':
            frozenset(pageClass.Arguments.iterMandatoryArgs()),
            'pageClass':
            pageClass,
        }

        parentsInc = tuple(parents) + (name, )
        for child in pageClass.children:
            cls.__processPage(child, parentsInc)
Exemple #3
0
 def iterRootButtons(self,
                     args: Optional[Arguments]) -> Iterator[LinkBarButton]:
     parents: List[LinkBarButton] = []
     resource: Optional[DocResource] = self.resource
     url = ''
     while resource is not None:
         parents.append(resource.page.createLinkBarButton(url))
         resource = resource.parent
         url += '../'
     yield LinkBarButton(label='Home',
                         url=url + 'Home',
                         icon=styleRoot.addIcon('IconHome'))
     yield from reversed(parents)
Exemple #4
0
    def renderIcon(self, arg: str) -> XMLContent:
        # Parse arguments.
        iconStyle = ['navicon']
        args = arg.split()
        if len(args) == 1:
            icon, = args
        elif len(args) == 2:
            icon, modifier = args
            iconStyle.append(modifier + 'icon')
        else:
            raise ValueError(arg)

        # Determine relative URL to style resources.
        depth = 0
        resource: Optional[DocResource] = self.resource
        while resource is not None:
            resource = resource.parent
            depth += 1
        styleURL = '../' * depth + styleRoot.relativeURL

        # Render.
        yield xhtml.span(
            class_=' '.join(iconStyle))[styleRoot.addIcon(icon).present(
                styleURL=styleURL)]
Exemple #5
0
# SPDX-License-Identifier: BSD-3-Clause

from traceback import TracebackException
from typing import Generic, Iterable, Iterator, Optional, cast

from softfab.Page import ProcT, Responder, logPageException
from softfab.StyleResources import styleRoot
from softfab.pagelinks import createUserDetailsLink, loginURL, logoutURL
from softfab.request import Request
from softfab.response import Response, ResponseHeaders
from softfab.timelib import getTime
from softfab.timeview import formatTime
from softfab.version import VERSION
from softfab.xmlgen import XML, XMLContent, XMLNode, XMLPresentable, xhtml

_logoIcon = styleRoot.addIcon('SoftFabLogo')
_shortcutIcon = styleRoot.addShortcutIcon('SoftFabIcon')

factoryStyleSheet = styleRoot.addStyleSheet('sw-factory')

fixedHeadItems: Iterable[XMLPresentable] = (
    xhtml.meta(charset='UTF-8'), factoryStyleSheet,
    xhtml.meta(name='viewport',
               content='width=device-width, initial-scale=1, minimum-scale=1'),
    _shortcutIcon)


class UIResponder(Responder, Generic[ProcT]):
    def __init__(self, page: 'UIPage[ProcT]', proc: ProcT):
        super().__init__()
        self.page = page
Exemple #6
0
        for task in tasks:
            statusFreq[getTaskStatus(task)] += 1

        def iterBars() -> Iterator[XMLContent]:
            for status in statusList:
                freq = statusFreq[status]
                if freq != 0:
                    yield xhtml.td(
                        style=f'width:{100 * freq // len(tasks):d}%',
                        class_=status)[str(freq)]

        return xhtml.table(
            class_='statusmany')[xhtml.tbody[xhtml.tr[iterBars()]]]


_scheduleIcon = styleRoot.addIcon('ScheduleSmall')
_scheduleIconGray = styleRoot.addIcon('ScheduleSmallD')


class _DescriptionColumn(DataColumn[Job]):
    keyName = 'description'

    def presentCell(self, record: Job, **kwargs: object) -> XMLContent:
        table = cast(JobsTable, kwargs['table'])
        if table.descriptionLink:
            yield xhtml.a(href=createJobURL(
                record.getId()), )[record.getDescription()]
        else:
            yield record.getDescription()

        scheduleDB: ScheduleDB = getattr(kwargs['proc'], 'scheduleDB')
Exemple #7
0
 def createLinkBarButton(self, url: str) -> LinkBarButton:
     return LinkBarButton(label=self.metadata.button,
                          url=url,
                          icon=styleRoot.addIcon(self.metadata.icon),
                          active=not url)
Exemple #8
0

def presentLabel(label: str) -> str:
    """Compute a good-looking tab label from the technical label.
    """
    root, ext_ = splitext(label)
    if root:
        # Note: Don't use the title() method, since that will capitalize the
        #       first letter in a word even if it is preceded by non-letters.
        return ' '.join(word[0].upper() + word[1:]
                        for word in reLabelSplit.split(root))
    else:
        return '(empty)'


openInNewTabIcon = styleRoot.addIcon('OpenInNewTab')


class Task_GET(FabPage['Task_GET.Processor', 'Task_GET.Arguments']):
    icon = 'IconReport'
    description = 'Task'

    class Arguments(TaskReportArgs):
        pass

    class Processor(TaskProcessorMixin, PageProcessor[Arguments]):

        frameworkDB: ClassVar[FrameworkDB]
        taskDefDB: ClassVar[TaskDefDB]
        taskRunDB: ClassVar[TaskRunDB]
        userDB: ClassVar[UserDB]