[gen] Calendar field: first version of the timeline rendering.
This commit is contained in:
parent
429eaf8abc
commit
1be8163c70
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
import types
|
import types
|
||||||
from appy import Object
|
from appy import Object
|
||||||
|
@ -19,18 +20,19 @@ class Calendar(Field):
|
||||||
pxTimeLineMonths = Px('''
|
pxTimeLineMonths = Px('''
|
||||||
<tr><th></th> <!-- Names of months -->
|
<tr><th></th> <!-- Names of months -->
|
||||||
<th for="mInfo in monthsInfos"
|
<th for="mInfo in monthsInfos"
|
||||||
colspan=":mInfo.colspan">::mInfo.month</th></tr>''')
|
colspan=":mInfo.colspan">::mInfo.month</th><th></th></tr>''')
|
||||||
|
|
||||||
# For timeline rendering, the row displaying day letters
|
# For timeline rendering, the row displaying day letters
|
||||||
pxTimelineDayLetters = Px('''
|
pxTimelineDayLetters = Px('''
|
||||||
<tr><td></td> <!-- Days (letters) -->
|
<tr><td></td> <!-- Days (letters) -->
|
||||||
<td for="date in grid"><b>:namesOfDays[date.aDay()].name[0]</b></td>
|
<td for="date in grid"><b>:namesOfDays[date.aDay()].name[0]</b></td>
|
||||||
</tr>''')
|
<td></td></tr>''')
|
||||||
|
|
||||||
# For timeline rendering, the row displaying day numbers
|
# For timeline rendering, the row displaying day numbers
|
||||||
pxTimelineDayNumbers = Px('''
|
pxTimelineDayNumbers = Px('''
|
||||||
<tr><td></td> <!-- Days (numbers) -->
|
<tr><td></td> <!-- Days (numbers) -->
|
||||||
<td for="date in grid"><b>:str(date.day()).zfill(2)</b></td></tr>''')
|
<td for="date in grid"><b>:str(date.day()).zfill(2)</b></td>
|
||||||
|
<td></td></tr>''')
|
||||||
|
|
||||||
# Timeline view for a calendar
|
# Timeline view for a calendar
|
||||||
pxViewTimeline = Px('''
|
pxViewTimeline = Px('''
|
||||||
|
@ -39,22 +41,35 @@ class Calendar(Field):
|
||||||
<!-- Column specifiers -->
|
<!-- Column specifiers -->
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<!-- Names of calendars -->
|
<!-- Names of calendars -->
|
||||||
<col style="width: 140px"></col>
|
<col></col>
|
||||||
<col for="date in grid"
|
<col for="date in grid"
|
||||||
style=":field.getCellStyle(zobj, date, render, today)"></col>
|
style=":field.getColumnStyle(zobj, date, render, today)"></col>
|
||||||
|
<col></col>
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<!-- Header rows (months and days) -->
|
<!-- Header rows (months and days) -->
|
||||||
<x>:field.pxTimeLineMonths</x>
|
<x>:field.pxTimeLineMonths</x>
|
||||||
<x>:field.pxTimelineDayLetters</x><x>:field.pxTimelineDayNumbers</x>
|
<x>:field.pxTimelineDayLetters</x><x>:field.pxTimelineDayNumbers</x>
|
||||||
<!-- The calendar in itself -->
|
<!-- The calendar in itself -->
|
||||||
<tr if="allEventTypes">
|
<tr if="allEventTypes">
|
||||||
<td class="tlName">Name</td>
|
<td class="tlName"></td>
|
||||||
<td for="date in grid"></td>
|
<td for="date in grid"></td>
|
||||||
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- Other calendars -->
|
<!-- Other calendars -->
|
||||||
<tr for="other in otherCalendars">
|
<tr for="other in otherCalendars"
|
||||||
<td class="tlName">:field.getTimelineName(*other)</td>
|
var2="tlName=field.getTimelineName(*other)">
|
||||||
<td for="date in grid"></td>
|
<td class="tlLeft">::tlName</td>
|
||||||
|
<!-- A cell in this other calendar -->
|
||||||
|
<x for="date in grid"
|
||||||
|
var2="inRange=field.dateInRange(date, startDate, endDate)">
|
||||||
|
<td if="not inRange"></td>
|
||||||
|
<td if="inRange"
|
||||||
|
var2="events=field.getOtherEventsAt(zobj, date, other, eventNames,\
|
||||||
|
render, colors, single=True)"
|
||||||
|
style=":field.getCellStyle(zobj, date, render, \
|
||||||
|
events)">::field.getTimelineCell(events)</td>
|
||||||
|
</x>
|
||||||
|
<td class="tlRight">::tlName</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- Footer (repetition of months and days) -->
|
<!-- Footer (repetition of months and days) -->
|
||||||
<x>:field.pxTimelineDayNumbers</x><x>:field.pxTimelineDayLetters</x>
|
<x>:field.pxTimelineDayNumbers</x><x>:field.pxTimelineDayLetters</x>
|
||||||
|
@ -74,9 +89,7 @@ class Calendar(Field):
|
||||||
<!-- The calendar in itself -->
|
<!-- The calendar in itself -->
|
||||||
<tr for="row in grid" valign="top" height=":rowHeight">
|
<tr for="row in grid" valign="top" height=":rowHeight">
|
||||||
<x for="date in row"
|
<x for="date in row"
|
||||||
var2="tooEarly=startDate and (date < startDate);
|
var2="inRange=field.dateInRange(date, startDate, endDate);
|
||||||
tooLate=endDate and not tooEarly and (date > endDate);
|
|
||||||
inRange=not tooEarly and not tooLate;
|
|
||||||
cssClasses=field.getCellClass(zobj, date, render, today)">
|
cssClasses=field.getCellClass(zobj, date, render, today)">
|
||||||
<!-- Dump an empty cell if we are out of the supported date range -->
|
<!-- Dump an empty cell if we are out of the supported date range -->
|
||||||
<td if="not inRange" class=":cssClasses"></td>
|
<td if="not inRange" class=":cssClasses"></td>
|
||||||
|
@ -112,12 +125,12 @@ class Calendar(Field):
|
||||||
(q('del'), q(field.name), q(dayString), q(spansDays))"/>
|
(q('del'), q(field.name), q(dayString), q(spansDays))"/>
|
||||||
<!-- A single event is allowed for the moment -->
|
<!-- A single event is allowed for the moment -->
|
||||||
<div if="events" var2="eventType=events[0].eventType">
|
<div if="events" var2="eventType=events[0].eventType">
|
||||||
<span style="color: grey">:field.getEventName(zobj, eventType)</span>
|
<span style="color: grey">:eventNames[eventType]</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- Events from other calendars -->
|
<!-- Events from other calendars -->
|
||||||
<x if="otherCalendars"
|
<x if="otherCalendars"
|
||||||
var2="otherEvents=field.getOtherEventsAt(zobj, date, \
|
var2="otherEvents=field.getOtherEventsAt(zobj, date, \
|
||||||
otherCalendars)">
|
otherCalendars, eventNames, render, colors)">
|
||||||
<div style=":'color: %s; font-style: italic' % event.color"
|
<div style=":'color: %s; font-style: italic' % event.color"
|
||||||
for="event in otherEvents">:event.name</div>
|
for="event in otherEvents">:event.name</div>
|
||||||
</x>
|
</x>
|
||||||
|
@ -147,7 +160,7 @@ class Calendar(Field):
|
||||||
<select name="eventType">
|
<select name="eventType">
|
||||||
<option value="">:_('choose_a_value')</option>
|
<option value="">:_('choose_a_value')</option>
|
||||||
<option for="eventType in allEventTypes"
|
<option for="eventType in allEventTypes"
|
||||||
value=":eventType">:field.getEventName(zobj,eventType)</option>
|
value=":eventType">:eventNames[eventType]</option>
|
||||||
</select><br/><br/>
|
</select><br/><br/>
|
||||||
<!--Span the event on several days -->
|
<!--Span the event on several days -->
|
||||||
<div align="center" class="discreet" style="margin-bottom: 3px">
|
<div align="center" class="discreet" style="margin-bottom: 3px">
|
||||||
|
@ -215,6 +228,9 @@ class Calendar(Field):
|
||||||
startDate=field.getStartDate(zobj);
|
startDate=field.getStartDate(zobj);
|
||||||
endDate=field.getEndDate(zobj);
|
endDate=field.getEndDate(zobj);
|
||||||
otherCalendars=field.getOtherCalendars(zobj, preComputed);
|
otherCalendars=field.getOtherCalendars(zobj, preComputed);
|
||||||
|
eventNames=field.getEventNames(zobj, allEventTypes, \
|
||||||
|
otherCalendars);
|
||||||
|
colors=field.getColors(zobj);
|
||||||
namesOfDays=field.getNamesOfDays(_)"
|
namesOfDays=field.getNamesOfDays(_)"
|
||||||
id=":ajaxHookId">
|
id=":ajaxHookId">
|
||||||
<script>:'var %s_maxEventLength = %d;' % \
|
<script>:'var %s_maxEventLength = %d;' % \
|
||||||
|
@ -259,9 +275,9 @@ class Calendar(Field):
|
||||||
colspan=1, master=None, masterValue=None, focus=False,
|
colspan=1, master=None, masterValue=None, focus=False,
|
||||||
mapping=None, label=None, maxEventLength=50, render='month',
|
mapping=None, label=None, maxEventLength=50, render='month',
|
||||||
otherCalendars=None, timelineName=None, additionalInfo=None,
|
otherCalendars=None, timelineName=None, additionalInfo=None,
|
||||||
startDate=None, endDate=None, defaultDate=None,
|
startDate=None, endDate=None, defaultDate=None, colors=None,
|
||||||
preCompute=None, applicableEvents=None, view=None, xml=None,
|
showUncolored=False, preCompute=None, applicableEvents=None,
|
||||||
delete=True):
|
view=None, xml=None, delete=True):
|
||||||
Field.__init__(self, validator, (0,1), default, show, page, group,
|
Field.__init__(self, validator, (0,1), default, show, page, group,
|
||||||
layouts, move, False, True, False, specificReadPermission,
|
layouts, move, False, True, False, specificReadPermission,
|
||||||
specificWritePermission, width, height, None, colspan,
|
specificWritePermission, width, height, None, colspan,
|
||||||
|
@ -340,6 +356,15 @@ class Calendar(Field):
|
||||||
# date is specified, it will be 'now' at the moment the calendar is
|
# date is specified, it will be 'now' at the moment the calendar is
|
||||||
# shown.
|
# shown.
|
||||||
self.defaultDate = defaultDate
|
self.defaultDate = defaultDate
|
||||||
|
# "colors" must be or return a dict ~{s_eventType: s_color}~ giving a
|
||||||
|
# color to every event type defined in this calendar or in any calendar
|
||||||
|
# from "otherCalendars". In a timeline, cells are too small to display
|
||||||
|
# translated names for event types, so colors are used instead.
|
||||||
|
self.colors = colors or {}
|
||||||
|
# For event types that are not present in self.colors hereabove, must we
|
||||||
|
# still show them? If yes, they will be represented by a dot with a
|
||||||
|
# tooltip containing the event name.
|
||||||
|
self.showUncolored = showUncolored
|
||||||
# For a specific day, all event types may not be applicable. If this is
|
# For a specific day, all event types may not be applicable. If this is
|
||||||
# the case, one may specify here a method that defines, for a given day,
|
# the case, one may specify here a method that defines, for a given day,
|
||||||
# a sub-set of all event types. This method must accept 3 args: the day
|
# a sub-set of all event types. This method must accept 3 args: the day
|
||||||
|
@ -441,9 +466,16 @@ class Calendar(Field):
|
||||||
|
|
||||||
def getTimelineName(self, obj, name, color):
|
def getTimelineName(self, obj, name, color):
|
||||||
'''Returns the name of this calendar as must be shown in a timeline.'''
|
'''Returns the name of this calendar as must be shown in a timeline.'''
|
||||||
if not self.timelineName: return obj.title
|
if not self.timelineName:
|
||||||
|
return '<a href="%s">%s</a>' % (obj.url, obj.title)
|
||||||
return self.timelineName(self, obj, name, color)
|
return self.timelineName(self, obj, name, color)
|
||||||
|
|
||||||
|
def getTimelineCell(self, events):
|
||||||
|
'''Gets the content of a cell in a timeline calendar.'''
|
||||||
|
# Currently a single event is allowed
|
||||||
|
if not events or not events[0].symbol: return ''
|
||||||
|
return events[0].symbol
|
||||||
|
|
||||||
def getAdditionalInfoAt(self, obj, date, preComputed):
|
def getAdditionalInfoAt(self, obj, date, preComputed):
|
||||||
'''If the user has specified a method in self.additionalInfo, we call
|
'''If the user has specified a method in self.additionalInfo, we call
|
||||||
it for displaying this additional info in the calendar, at some
|
it for displaying this additional info in the calendar, at some
|
||||||
|
@ -457,6 +489,19 @@ class Calendar(Field):
|
||||||
if callable(self.eventTypes): return self.eventTypes(obj.appy())
|
if callable(self.eventTypes): return self.eventTypes(obj.appy())
|
||||||
return self.eventTypes
|
return self.eventTypes
|
||||||
|
|
||||||
|
def getColors(self, obj):
|
||||||
|
'''Gets the colors for event types managed by this calendar and
|
||||||
|
otherCalendars (from self.colors).'''
|
||||||
|
if callable(self.colors): return self.colors(obj)
|
||||||
|
return self.colors
|
||||||
|
|
||||||
|
def dateInRange(self, date, startDate, endDate):
|
||||||
|
'''Is p_date within the range (possibly) defined for this calendar by
|
||||||
|
p_startDate and p_endDate ?'''
|
||||||
|
tooEarly = startDate and (date < startDate)
|
||||||
|
tooLate = endDate and not tooEarly and (date > endDate)
|
||||||
|
return not tooEarly and not tooLate
|
||||||
|
|
||||||
def getApplicableEventsTypesAt(self, obj, date, allEventTypes, preComputed,
|
def getApplicableEventsTypesAt(self, obj, date, allEventTypes, preComputed,
|
||||||
forBrowser=False):
|
forBrowser=False):
|
||||||
'''Returns the event types that are applicable at a given p_date. More
|
'''Returns the event types that are applicable at a given p_date. More
|
||||||
|
@ -593,15 +638,36 @@ class Calendar(Field):
|
||||||
if not events: return False
|
if not events: return False
|
||||||
return events[0].eventType == otherEvents[0].eventType
|
return events[0].eventType == otherEvents[0].eventType
|
||||||
|
|
||||||
def getOtherEventsAt(self, obj, date, otherCalendars):
|
def getOtherEventsAt(self, obj, date, otherCalendars, eventNames, render,
|
||||||
'''Gets events that are defined in p_otherCalendars at some p_date.'''
|
colors, single=False):
|
||||||
|
'''Gets events that are defined in p_otherCalendars at some p_date.
|
||||||
|
If p_single is True, p_otherCalendars does not contain the list of
|
||||||
|
all other calendars, but information about a single calendar.'''
|
||||||
res = []
|
res = []
|
||||||
|
if single: otherCalendars = [otherCalendars]
|
||||||
|
isTimeline = render == 'timeline'
|
||||||
for o, field, color in otherCalendars:
|
for o, field, color in otherCalendars:
|
||||||
events = field.getEventsAt(o.o, date)
|
events = field.getEventsAt(o.o, date)
|
||||||
if events:
|
if events:
|
||||||
eventType = events[0].eventType
|
eventType = events[0].eventType
|
||||||
eventName = field.getEventName(o.o, eventType)
|
info = Object(color=color)
|
||||||
info = Object(name=eventName, color=color)
|
if isTimeline:
|
||||||
|
# Get the background color for this cell if it has been
|
||||||
|
# defined, or (a) nothing if showUncolored is False, (b) a
|
||||||
|
# tooltipped dot else.
|
||||||
|
if eventType in colors:
|
||||||
|
info.bgColor = colors[eventType]
|
||||||
|
info.symbol = None
|
||||||
|
else:
|
||||||
|
info.bgColor = None
|
||||||
|
if self.showUncolored:
|
||||||
|
info.symbol = '<acronym title="%s">▪</acronym>' % \
|
||||||
|
eventNames[eventType]
|
||||||
|
else:
|
||||||
|
info.symbol = None
|
||||||
|
else:
|
||||||
|
# Get the event name
|
||||||
|
info.name = eventNames[eventType]
|
||||||
res.append(info)
|
res.append(info)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@ -613,15 +679,31 @@ class Calendar(Field):
|
||||||
else:
|
else:
|
||||||
return obj.translate('%s_event_%s' % (self.labelId, eventType))
|
return obj.translate('%s_event_%s' % (self.labelId, eventType))
|
||||||
|
|
||||||
|
def getEventNames(self, obj, eventTypes, otherCalendars):
|
||||||
|
'''Computes a dict of event names, keyed by event types, for all events
|
||||||
|
in this calendar and p_otherCalendars).'''
|
||||||
|
res = {}
|
||||||
|
if eventTypes:
|
||||||
|
for et in eventTypes:
|
||||||
|
res[et] = self.getEventName(obj, et)
|
||||||
|
if not otherCalendars: return res
|
||||||
|
for other, field, color in otherCalendars:
|
||||||
|
eventTypes = field.getEventTypes(other)
|
||||||
|
if eventTypes:
|
||||||
|
for et in eventTypes:
|
||||||
|
if et not in res:
|
||||||
|
res[et] = field.getEventName(other, et)
|
||||||
|
return res
|
||||||
|
|
||||||
def getStartDate(self, obj):
|
def getStartDate(self, obj):
|
||||||
'''Get the start date for this calendar if defined.'''
|
'''Get the start date for this calendar if defined'''
|
||||||
if self.startDate:
|
if self.startDate:
|
||||||
d = self.startDate(obj.appy())
|
d = self.startDate(obj.appy())
|
||||||
# Return the start date without hour, in UTC.
|
# Return the start date without hour, in UTC
|
||||||
return DateTime('%d/%d/%d UTC' % (d.year(), d.month(), d.day()))
|
return DateTime('%d/%d/%d UTC' % (d.year(), d.month(), d.day()))
|
||||||
|
|
||||||
def getEndDate(self, obj):
|
def getEndDate(self, obj):
|
||||||
'''Get the end date for this calendar if defined.'''
|
'''Get the end date for this calendar if defined'''
|
||||||
if self.endDate:
|
if self.endDate:
|
||||||
d = self.endDate(obj.appy())
|
d = self.endDate(obj.appy())
|
||||||
# Return the end date without hour, in UTC.
|
# Return the end date without hour, in UTC.
|
||||||
|
@ -720,9 +802,9 @@ class Calendar(Field):
|
||||||
elif action == 'deleteEvent':
|
elif action == 'deleteEvent':
|
||||||
return self.deleteEvent(obj, DateTime(rq['day']))
|
return self.deleteEvent(obj, DateTime(rq['day']))
|
||||||
|
|
||||||
def getCellStyle(self, obj, date, render, today):
|
def getColumnStyle(self, obj, date, render, today):
|
||||||
'''What style(s) must apply to the table cell representing p_date
|
'''What style(s) must apply to the table column representing p_date
|
||||||
in the calendar?'''
|
in the calendar? For timelines only.'''
|
||||||
if render != 'timeline': return ''
|
if render != 'timeline': return ''
|
||||||
# Cells representing specific days must have a specific background color
|
# Cells representing specific days must have a specific background color
|
||||||
res = ''
|
res = ''
|
||||||
|
@ -731,10 +813,18 @@ class Calendar(Field):
|
||||||
res = 'background-color: %s' % Calendar.timelineBgColors[day]
|
res = 'background-color: %s' % Calendar.timelineBgColors[day]
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def getCellStyle(self, obj, date, render, events):
|
||||||
|
'''Gets the cell style to apply to the cell corresponding to p_date.'''
|
||||||
|
if render != 'timeline': return '' # Currently, for timelines only
|
||||||
|
if not events: return ''
|
||||||
|
# Currently, a single event is allowed
|
||||||
|
event = events[0]
|
||||||
|
return event.bgColor and ('background-color: %s' % event.bgColor) or ''
|
||||||
|
|
||||||
def getCellClass(self, obj, date, render, today):
|
def getCellClass(self, obj, date, render, today):
|
||||||
'''What CSS class(es) must apply to the table cell representing p_date
|
'''What CSS class(es) must apply to the table cell representing p_date
|
||||||
in the calendar?'''
|
in the calendar?'''
|
||||||
if render != 'month': return ''
|
if render != 'month': return '' # Currently, for month rendering only
|
||||||
res = []
|
res = []
|
||||||
# We must distinguish between past and future dates
|
# We must distinguish between past and future dates
|
||||||
if date < today:
|
if date < today:
|
||||||
|
|
|
@ -209,7 +209,8 @@ class String(Field):
|
||||||
name=":name" id=":name" class=":masterCss"
|
name=":name" id=":name" class=":masterCss"
|
||||||
multiple=":isMultiple and 'multiple' or ''"
|
multiple=":isMultiple and 'multiple' or ''"
|
||||||
onchange=":field.getOnChange(zobj, layoutType)"
|
onchange=":field.getOnChange(zobj, layoutType)"
|
||||||
size=":isMultiple and field.height or 1">
|
size=":field.getSelectSize(isMultiple)"
|
||||||
|
style=":field.getSelectStyle(isMultiple)">
|
||||||
<option for="val in possibleValues" value=":val[0]"
|
<option for="val in possibleValues" value=":val[0]"
|
||||||
selected=":field.isSelected(zobj, name, val[0], rawValue)"
|
selected=":field.isSelected(zobj, name, val[0], rawValue)"
|
||||||
title=":val[1]">:ztool.truncateValue(val[1],field.width)</option>
|
title=":val[1]">:ztool.truncateValue(val[1],field.width)</option>
|
||||||
|
@ -479,6 +480,21 @@ class String(Field):
|
||||||
res = False
|
res = False
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def getSelectSize(self, isMultiple):
|
||||||
|
'''When this field renders as a selection list, get the value of its
|
||||||
|
"size" attribute.'''
|
||||||
|
if not isMultiple: return 1
|
||||||
|
if isinstance(self.height, int): return self.height
|
||||||
|
# "height" can be defined as a string. In this case it is used to define
|
||||||
|
# height via a attribute "style", not "size".
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def getSelectStyle(self, isMultiple):
|
||||||
|
'''When thiss field renders as a selection list, get the value of its
|
||||||
|
"style" attribute.'''
|
||||||
|
if not isMultiple or not isinstance(self.height, str): return ''
|
||||||
|
return 'height: %s' % self.height
|
||||||
|
|
||||||
def isMultilingual(self, obj, dontKnow=False):
|
def isMultilingual(self, obj, dontKnow=False):
|
||||||
'''Is this field multilingual ? If we don't know, say p_dontKnow.'''
|
'''Is this field multilingual ? If we don't know, say p_dontKnow.'''
|
||||||
# In the following case, impossible to know: we say no.
|
# In the following case, impossible to know: we say no.
|
||||||
|
|
|
@ -27,7 +27,8 @@ input[type=button] { border: 1px solid #d0d0d0; margin: 0 3px;
|
||||||
background-color: #f8f8f8; cursor: pointer }
|
background-color: #f8f8f8; cursor: pointer }
|
||||||
input[type=submit] { border: 1px solid #d0d0d0; background-color: #f8f8f8;
|
input[type=submit] { border: 1px solid #d0d0d0; background-color: #f8f8f8;
|
||||||
cursor: pointer }
|
cursor: pointer }
|
||||||
input[type=password] { border: 1px solid #d0d0d0;
|
input[type=password] { border: 1px solid #d0d0d0; padding: 0 2px;
|
||||||
|
margin-bottom:1px;
|
||||||
font-family: "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif }
|
font-family: "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif }
|
||||||
input[type=text] { border: 1px solid #d0d0d0; padding: 0 2px; margin-bottom:1px;
|
input[type=text] { border: 1px solid #d0d0d0; padding: 0 2px; margin-bottom:1px;
|
||||||
font-family: "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif }
|
font-family: "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif }
|
||||||
|
@ -128,7 +129,9 @@ td.search { padding-top: 8px }
|
||||||
.timeline { font-size: 90%; color: #555555 }
|
.timeline { font-size: 90%; color: #555555 }
|
||||||
.timeline td { text-align: center; padding: 1px }
|
.timeline td { text-align: center; padding: 1px }
|
||||||
.timeline th { padding: 1px }
|
.timeline th { padding: 1px }
|
||||||
.tlName { text-align: left !important }
|
.tlLeft { text-align: left !important }
|
||||||
|
.tlRight { text-align: right !important }
|
||||||
|
.tlRight { text-align: right !important }
|
||||||
.msgTable { margin: 6px 0; width: 100%; font-size: 93% }
|
.msgTable { margin: 6px 0; width: 100%; font-size: 93% }
|
||||||
.msgTable tr { vertical-align: top }
|
.msgTable tr { vertical-align: top }
|
||||||
.msgTable td, .msgTable th { border: 1px solid grey; color: #555555;
|
.msgTable td, .msgTable th { border: 1px solid grey; color: #555555;
|
||||||
|
|
Loading…
Reference in a new issue