www/board/agenda/views/pages/roll-call.js.rb (174 lines of code) (raw):
#
# Secretary Roll Call update form
class RollCall < Vue
def initialize
RollCall.lockFocus = false
@guest = ''
end
def render
_section.flexbox do
_section.rollcall! do
_h3 'Directors'
_ul people do |person|
_Attendee person: person if person.role == :director
end
_h3 'Executive Officers'
_ul people do |person|
_Attendee person: person if person.role == :officer
end
_h3 'Guests'
_ul do
people.each do |person|
_Attendee person: person if person.role == :guest
end
# walk-on guest support
_li do
_input.walkon value: @guest, disabled: @disabled,
onFocus:-> {RollCall.lockFocus = true},
onBlur:-> {RollCall.lockFocus = false}
end
if @guest.length >= 3
guest = @guest.downcase().split(' ')
found = false
Server.committers.each do |person|
if
guest.all? {|part|
person.id.include? part or
person.name.downcase().include? part
} and
not people.any? {|registered| registered.id == person.id}
then
_Attendee person: person, walkon: true
found = true
end
end
# non committer
_Attendee person: {name: @guest}, walkon: true if not found
end
end
end
# draft minutes
_section do
minutes = Minutes.get(@@item.title)
if minutes
_h3 'Minutes'
_pre.comment minutes
end
end
end
end
# collect a sorted list of people
def people
list = []
# start with those listed in the agenda
@@item.people.each_pair do |id, person|
person.id = id
list << person
end
# add remaining attendees
attendees = Minutes.attendees
if attendees
attendees.each_pair do |name, attendee|
if not list.any? {|person| person.name == name}
person = attendee
person.name = name
person.role = :guest
list << person
end
end
end
# sort list
list.sort do |person1, person2|
return person1.sortName > person2.sortName ? 1 : -1
end
end
# clear guest
def clear_guest()
@guest = ''
end
# client side initialization on first rendering
def mounted()
if Server.committers
@disabled = false
else
@disabled = true
retrieve 'committers', :json do |committers|
Server.committers = committers || []
@disabled = false
end
end
# export clear method
RollCall.clear_guest = self.clear_guest
end
# scroll walkon input field towards the center of the screen
def updated()
if RollCall.lockFocus and @guest.length >= 3
walkon = document.getElementsByClassName('walkon')[0]
offset = walkon.offsetTop + walkon.offsetHeight/2 - window.innerHeight/2
jQuery('html, body').animate({scrollTop: offset}, :slow)
end
end
end
#
# An individual attendee (Director, Executive Officer, or Guest)
#
class Attendee < Vue
def initialize
# last posted value for notes for this attendee
@base = ''
end
def created
@base = status.notes
end
# create a version of notes without the leading dash
def notes
status.notes ? status.notes.sub(' - ', '') : ''
end
def notes=(value)
if value
status.notes = " - #{value}"
else
status.notes = nil
end
end
# perform initialization on first rendering
def status
return @saved_status if Header.clock_counter > 0
@saved_status = Minutes.attendees[@@person.name] || {}
end
# render a checkbox, a hypertexted link of the attendee's name to the
# roster page for the committer, and notes in both editable and non-editable
# forms. CSS controls which version of the notes is actually displayed.
def render
_li onMouseOver: self.focus do
_input type: :checkbox, checked: status.present, onClick: self.click
roster = '/roster/committer/'
if @@person.id
_a @@person.name, href: "#{roster}#{@@person.id}",
style: {fontWeight: (@@person.member ? 'bold' : 'normal')}
else
_a.hilite @@person.name, href: "#{roster}?q=#{@@person.name}"
end
unless @@walkon or status.present or @@person.role==:guest or @@person.attending
_span "\u00A0(expected to be absent)" unless status.notes
end
unless @@walkon
_label
_input type: 'text', value: self.notes, onBlur: self.blur,
disabled: @disabled
_span status.notes
end
end
end
# when moving cursor over a list item, focus on the input field
def focus(event)
unless RollCall.lockFocus
event.target.parentNode.querySelector('input[type=text]').focus()
end
end
# when checkbox is clicked, post update
def click(event)
status.present = event.target.checked
post_update()
end
# when leaving a list item, post update if value changed
def blur()
if @base != status.notes
@base = status.notes
post_update()
end
end
# send updates to the server
def post_update()
data = {
agenda: Agenda.file,
action: 'attendance',
name: @@person.name,
id: @@person.id,
present: status.present,
notes: notes
}
@disabled = true
Header.clock_counter += 1
post 'minute', data do |minutes|
Header.clock_counter -= 1
Minutes.load minutes
RollCall.clear_guest() if @@walkon
@disabled = false
end
end
end