def createTagCell(value: str) -> XML: label = preserveSpaces(value) if value else '(undefined)' if value == tagValue: return xhtml.td(class_='navthis')[label] else: return xhtml.td(class_='navother')[pageLink( formAction, cleanedArgs.override(tagvalue=value, first=0))[label]]
def createKeyCell(key: str) -> XML: label = preserveSpaces(key) if key else '(show all)' if key == tagKey: return xhtml.td(class_='navthis')[label] else: return xhtml.td(class_='navother')[pageLink( formAction, cleanedArgs.override(tagkey=key, tagvalue=None, first=0))[label]]
def presentRows(self, **kwargs: object) -> XMLContent: proc = cast(ReportProcessor, kwargs['proc']) numListItems = cast(int, kwargs['numListItems']) targets = proc.uiTargets owners = proc.uiOwners showOwners = proc.userDB.showOwners objectName = self.objectName def columns1() -> XMLContent: yield xhtml.td( colspan=4)[f'Select {objectName} to display reports for:'] if len(targets) > 1: yield xhtml.td['Targets:'] if len(owners) > 1 and showOwners: yield xhtml.td['Owners:'] yield xhtml.tr[columns1()] def columns2() -> XMLContent: yield self.presentCustomBox(**kwargs) if len(targets) > 1: yield xhtml.td( rowspan=4, style='vertical-align:top')[selectionList( name='target', size=numListItems, style='width: 18ex')[(target or noneOption for target in sorted(targets))]] if len(owners) > 1 and showOwners: yield xhtml.td( rowspan=4, style='vertical-align:top')[selectionList( name='owner', size=numListItems, style='width: 18ex')[(owner or noneOption for owner in sorted(owners))]] yield xhtml.tr[columns2()] yield xhtml.tr[xhtml.td['Created after:'], xhtml.td[textInput(name='ctabove', value=timeValue(proc.args.ctabove), style='width:20ex')], xhtml.td['Created before:'], xhtml.td[textInput(name='ctbelow', value=timeValue(proc.args.ctbelow), style='width:20ex')]] yield xhtml.tr[xhtml.td['Execution state:'], xhtml.td(colspan=3)[executionStateBox(objectName)]] yield xhtml.tr[xhtml.td( colspan=4, style='text-align:center')[submitButton['Apply'], ' ', resetButton, ' ', clearButton]]
def columns2() -> XMLContent: yield self.presentCustomBox(**kwargs) if len(targets) > 1: yield xhtml.td( rowspan=4, style='vertical-align:top')[selectionList( name='target', size=numListItems, style='width: 18ex')[(target or noneOption for target in sorted(targets))]] if len(owners) > 1 and showOwners: yield xhtml.td( rowspan=4, style='vertical-align:top')[selectionList( name='owner', size=numListItems, style='width: 18ex')[(owner or noneOption for owner in sorted(owners))]]
def presentCustomBox(self, **kwargs: object) -> XMLContent: proc = cast(ReportTasks_GET.Processor, kwargs['proc']) numListItems = cast(int, kwargs['numListItems']) yield xhtml.td(colspan=4)[selectionList(name='task', selected=proc.args.task, size=numListItems)[sorted( proc.taskDefDB.keys())]]
def columns1() -> XMLContent: yield xhtml.td( colspan=4)[f'Select {objectName} to display reports for:'] if len(targets) > 1: yield xhtml.td['Targets:'] if len(owners) > 1 and showOwners: yield xhtml.td['Owners:']
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)]
def pageTab(tab: int) -> XMLNode: pageFirst = tab * recordsPerPage pageLast = min(pageFirst + recordsPerPage - 1, totalNrRecords - 1) text = str(pageFirst).zfill(numDigits) if pageFirst <= current <= pageLast: return xhtml.td(class_='navthis')[text] else: return linkTab(tab, text)
def generateBars() -> XMLContent: assert maxValue is not None # work around mypy issue 2608 for task, value in dataPoints: run = task.getLatestRun() if value is None: valueDescription = 'no value' barClass = 'graphbarnoval' height = graphHeight else: valueDescription = str(value) barClass = 'graphbar' # We cannot plot negative values, so clip to 0. height = max(value, 0) * graphHeight // maxValue url = createRunURL(run, 'data') yield xhtml.td( title='%s - %s' % (formatTime(run.getJob().getCreateTime()), valueDescription), onclick=f"document.location='{url}'")[xhtml.table( class_=barClass, style=f'width: {barWidth:d}px; height: {height:d}px')[ xhtml.tbody[xhtml.tr[xhtml.td]]]] yield xhtml.td(class_='raxis')[((str(mark * roundMarkValue), xhtml.br) for mark in range(numMarks, 0, -1))]
def __presentTabs(self, proc: PageProcessor, data: TableData[Record]) -> XMLContent: '''Generate tabs to switch pages of a long record set. ''' # Should this table should be presented with tabs? tabOffsetField = self.tabOffsetField if tabOffsetField is None: # Table subclass declares it does not want tabs. return None # Is there more than 1 tab worth of data? recordsPerPage = self.recordsPerPage totalNrRecords = data.totalNrRecords if totalNrRecords <= recordsPerPage: return None numColumns = sum(column.colSpan for column in data.columns) current = cast(int, getattr(proc.args, tabOffsetField)) maxNrTabs = self.__maxNrTabs numDigits = len(str(totalNrRecords)) numTabs = (totalNrRecords + recordsPerPage - 1) // recordsPerPage firstTab = max(current // recordsPerPage - maxNrTabs // 2, 0) limitTab = min(numTabs, firstTab + maxNrTabs) def linkTab(tab: int, text: str) -> XMLNode: return xhtml.td(class_='navother')[xhtml.a(href=pageURL( proc.page.name, proc.args.override(**{tabOffsetField: tab * recordsPerPage})), class_='nav')[text]] def pageTab(tab: int) -> XMLNode: pageFirst = tab * recordsPerPage pageLast = min(pageFirst + recordsPerPage - 1, totalNrRecords - 1) text = str(pageFirst).zfill(numDigits) if pageFirst <= current <= pageLast: return xhtml.td(class_='navthis')[text] else: return linkTab(tab, text) return xhtml.tr[xhtml.td( class_='topnav', colspan=numColumns )[xhtml.table(class_='topnav')[xhtml.tbody[xhtml.tr[ linkTab(max(firstTab - maxNrTabs // 2, 0), '\u2190') if firstTab > 0 else None, (pageTab(tab) for tab in range(firstTab, limitTab)), linkTab(min(firstTab + maxNrTabs + maxNrTabs // 2, numTabs - 1), '\u2192') if numTabs > limitTab else None]]]]]
def createStatusBar(tasks: Sequence[Task], length: int = 10) -> XMLContent: if len(tasks) == 0: return None elif len(tasks) <= length: return xhtml.table(class_='statusfew')[xhtml.tbody[xhtml.tr[(xhtml.td( class_=getTaskStatus(task)) for task in tasks)]]] else: statusFreq = dict.fromkeys(statusList, 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()]]]
def __presentBody(self, columns: Sequence[Column], **kwargs: object ) -> XMLContent: # Determine style implied by each column. colStyles = [] for column in columns: colStyle = column.cellStyle for _ in range(column.colSpan): colStyles.append(colStyle) rowSpans = [1] * len(colStyles) rowPresentations: XMLContent = [ row.adapt(r).present( colStyles=colStyles, rowSpans=rowSpans, columns=columns, **kwargs ) for r in self.iterRows(columns=columns, **kwargs) ] if max(rowSpans) > 1: raise ValueError( 'Row span beyond last row: %s' % ', '.join( f'{span - 1:d} row(s) left in column {index:d}' for index, span in enumerate(rowSpans) if span > 1 ) ) if not rowPresentations: if self.hideWhenEmpty: return None else: rowPresentations = xhtml.tr[ xhtml.td(colspan = len(colStyles))[ '(no content)' ] ] return xhtml.tbody(id = self.bodyId)[ rowPresentations ]
def linkTab(tab: int, text: str) -> XMLNode: return xhtml.td(class_='navother')[xhtml.a(href=pageURL( proc.page.name, proc.args.override(**{tabOffsetField: tab * recordsPerPage})), class_='nav')[text]]