コード例 #1
0
ファイル: FabPage.py プロジェクト: boxingbeetle/softfab
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)]
コード例 #2
0
ファイル: FabPage.py プロジェクト: boxingbeetle/softfab
    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)
コード例 #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)
コード例 #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)]
コード例 #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
コード例 #6
0
ファイル: jobview.py プロジェクト: boxingbeetle/softfab
        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')
コード例 #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)
コード例 #8
0
ファイル: Task.py プロジェクト: boxingbeetle/softfab

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]