whimsical-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sam Ruby <ru...@apache.org>
Subject [whimsy.git] [1/1] Commit 99a387a: split committer => person/*
Date Sat, 02 Apr 2016 22:32:35 GMT
Commit 99a387a9ca5b0cc8fee7ae3be8a9cc1e681f791a:
    split committer => person/*


Branch: refs/heads/master
Author: Sam Ruby <rubys@intertwingly.net>
Committer: Sam Ruby <rubys@intertwingly.net>
Pusher: rubys <rubys@apache.org>

------------------------------------------------------------
www/roster/views/actions/fullname.json.rb                    |  
www/roster/views/app.js.rb                                   | ++++++++++++ -
www/roster/views/committer.html.rb                           | + -
www/roster/views/committer.js.rb                             |  -------------
www/roster/views/person.js.rb                                | ++++++++ 
www/roster/views/person/email.js.rb                          | +++++++++++ 
www/roster/views/person/forms.js.rb                          | +++++++++ 
www/roster/views/person/fullname.js.rb                       | +++++++++++++++ 
www/roster/views/person/github.js.rb                         | +++++++++ 
www/roster/views/person/memstat.js.rb                        | +++++++++ 
www/roster/views/person/memtext.rb                           | +++++++++++++++ 
www/roster/views/person/pgpkeys.js.rb                        | +++++++++++++++ 
www/roster/views/person/sascore.js.rb                        | +++++++++++++++ 
www/roster/views/person/sshkeys.js.rb                        | ++++++++++++ 
www/roster/views/person/urls.js.rb                           | ++++++++++ 
------------------------------------------------------------
954 changes: 551 additions, 403 deletions.
------------------------------------------------------------


diff --git a/www/roster/views/actions/fullname.json.rb b/www/roster/views/actions/fullname.json.rb
new file mode 100644
index 0000000..7ef586e
--- /dev/null
+++ b/www/roster/views/actions/fullname.json.rb
@@ -0,0 +1,48 @@
+#
+# Update LDAP SpamAssassin score attribute for a committer
+#
+person = ASF::Person.find(@userid)
+
+# update LDAP
+if person.public_name != @publicname
+  _ldap.update do
+    _previous person.public_name
+
+    if @publicname and not @dryrun
+      person.modify 'cn', @publicname
+    end
+  end
+end
+
+# determine commit message
+if person.icla.legal_name != @legalname
+  if person.icla.name != @publicname
+    message = "Update legal and public name for #{@userid}"
+  else
+    message = "Update legal name for #{@userid}"
+  end
+elsif person.icla.name != @publicname
+  message = "Update public name for #{@userid}"
+else
+  message = nil
+end
+
+# update iclas.txt
+if message
+  icla_txt = ASF::SVN['private/foundation/officers/iclas.txt']
+  _svn.update icla_txt, message: message do |dir, text|
+    # replace legal and public names in icla record
+    userid = Regexp.escape(@userid)
+    text[/^#{userid}:(.*?):/, 1] = @legalname
+    text[/^#{userid}:.*?:(.*?):/, 1] = @publicname
+  
+    text
+  end
+end
+
+# update cache
+person.icla.legal_name = @legalname
+person.icla.name = @publicname
+
+# return updated committer info
+_committer Committer.serialize(@userid, env)
diff --git a/www/roster/views/actions/pubname.json.rb b/www/roster/views/actions/pubname.json.rb
deleted file mode 100644
index 7ef586e..0000000
--- a/www/roster/views/actions/pubname.json.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Update LDAP SpamAssassin score attribute for a committer
-#
-person = ASF::Person.find(@userid)
-
-# update LDAP
-if person.public_name != @publicname
-  _ldap.update do
-    _previous person.public_name
-
-    if @publicname and not @dryrun
-      person.modify 'cn', @publicname
-    end
-  end
-end
-
-# determine commit message
-if person.icla.legal_name != @legalname
-  if person.icla.name != @publicname
-    message = "Update legal and public name for #{@userid}"
-  else
-    message = "Update legal name for #{@userid}"
-  end
-elsif person.icla.name != @publicname
-  message = "Update public name for #{@userid}"
-else
-  message = nil
-end
-
-# update iclas.txt
-if message
-  icla_txt = ASF::SVN['private/foundation/officers/iclas.txt']
-  _svn.update icla_txt, message: message do |dir, text|
-    # replace legal and public names in icla record
-    userid = Regexp.escape(@userid)
-    text[/^#{userid}:(.*?):/, 1] = @legalname
-    text[/^#{userid}:.*?:(.*?):/, 1] = @publicname
-  
-    text
-  end
-end
-
-# update cache
-person.icla.legal_name = @legalname
-person.icla.name = @publicname
-
-# return updated committer info
-_committer Committer.serialize(@userid, env)
diff --git a/www/roster/views/app.js.rb b/www/roster/views/app.js.rb
index 67d716e..59ae46e 100644
--- a/www/roster/views/app.js.rb
+++ b/www/roster/views/app.js.rb
@@ -5,7 +5,18 @@
 require_relative 'pmc/committers'
 require_relative 'pmc/confirm'
 
-require_relative 'committer'
+require_relative 'person'
+require_relative 'person/fullname'
+require_relative 'person/urls'
+require_relative 'person/email'
+require_relative 'person/pgpkeys'
+require_relative 'person/sshkeys'
+require_relative 'person/github'
+require_relative 'person/memstat'
+require_relative 'person/memtext'
+require_relative 'person/forms'
+require_relative 'person/sascore'
+
 require_relative 'committerSearch'
 
 require_relative 'group'
diff --git a/www/roster/views/committer.html.rb b/www/roster/views/committer.html.rb
index 97dae72..3a53fd7 100644
--- a/www/roster/views/committer.html.rb
+++ b/www/roster/views/committer.html.rb
@@ -17,6 +17,6 @@
 
   _script src: 'app.js'
   _.render '#main' do
-    _Committer committer: @committer, auth: @auth
+    _Person committer: @committer, auth: @auth
   end
 end
diff --git a/www/roster/views/committer.js.rb b/www/roster/views/committer.js.rb
deleted file mode 100644
index 8ffd3ee..0000000
--- a/www/roster/views/committer.js.rb
+++ /dev/null
@@ -1,401 +0,0 @@
-class Committer < React
-  def initialize
-    @committer = {}
-    @response = nil
-  end
-
-  def render
-    # usage information for authenticated users (owner, secretary, etc.)
-    if @auth
-      _div.alert.alert_success 'Double click on a field in this color to edit.'
-    end
-
-    _h2 "#{@committer.id}@apache.org"
-
-    _table.wide do
-
-      # Name
-      _tr data_edit: ('pubname' if @@auth.secretary) do
-        _td 'Name'
-        _td do
-          name = @committer.name
-
-          if @edit_pubname
-            _form.inline method: 'post' do
-              _div do
-                _label 'public name', for: 'publicname'
-                _input.publicname! name: 'publicname', required: true,
-                  defaultValue: name.public_name
-              end
-              _div do
-                _label 'legal name', for: 'legalname'
-                _input.legalname! name: 'legalname', required: true,
-                  defaultValue: name.legal_name
-              end
-              _button.btn.btn_primary 'submit'
-            end
-          else
-            if 
-              name.public_name==name.legal_name and 
-              name.public_name==name.ldap
-            then
-              _span @committer.name.public_name
-            else
-              _ul do
-                _li "#{@committer.name.public_name} (public name)"
-  
-                if name.legal_name and name.legal_name != name.public_name
-                  _li "#{@committer.name.legal_name} (legal name)"
-                end
-  
-                if name.ldap and name.ldap != name.public_name
-                  _li "#{@committer.name.ldap} (ldap)"
-                end
-              end
-            end
-          end
-        end
-      end
-
-      # Personal URL
-      if @committer.urls
-        _tr do
-          _td 'Personal URL'
-          _td do
-            _ul @committer.urls do |url|
-              _li {_a url, href: url}
-            end
-          end
-        end
-      end
-
-      # Committees
-      committees = @committer.committees
-      unless committees.empty?
-        _tr do
-          _td 'Committees'
-          _td do
-            _ul committees do |pmc|
-              _li {_a pmc, href: "committee/#{pmc}"}
-            end
-          end
-        end
-      end
-
-      # Committer
-      commit_list = @committer.committer
-      unless commit_list.all? {|pmc| committees.include? pmc}
-        _tr do
-          _td 'Committer'
-          _td do
-            _ul commit_list do |pmc|
-              next if committees.include? pmc
-              _li {_a pmc, href: "committee/#{pmc}"}
-            end
-          end
-        end
-      end
-
-      # Groups
-      unless @committer.groups.empty?
-        _tr do
-          _td 'Groups'
-          _td do
-            _ul @committer.groups do |group|
-              next if group == 'apldap'
-
-              if group == 'committers'
-                _li {_a group, href: "committer/"}
-              elsif group == 'member'
-                _li {_a group, href: "members"}
-              else
-                _li {_a group, href: "group/#{group}"}
-              end
-            end
-          end
-        end
-      end
-
-      # Email addresses
-      if @committer.mail
-        _tr do
-          _td 'Email addresses'
-          _td do
-            _ul @committer.mail do |url|
-              _li do
-                _a url, href: 'mailto:' + url
-              end
-            end
-          end
-        end
-      end
-
-      # PGP keys
-      if @committer.pgp
-        _tr do
-          _td 'PGP keys'
-          _td do
-            _ul @committer.pgp do |key|
-              _li do
-                if key =~ /^[0-9a-fA-F ]+$/
-                  _samp do
-                    _a key, href: 'https://sks-keyservers.net/pks/lookup?' +
-                      'op=index&search=0x' + key.gsub(' ', '')
-                  end
-                else
-                  _samp key
-                end
-              end
-            end
-          end
-        end
-      end
-
-      # SSH keys
-      if @committer.ssh
-        _tr do
-          _td 'SSH keys'
-          _td do
-            _ul @committer.ssh do |key|
-              _li.ssh do
-                _pre.wide key
-              end
-            end
-          end
-        end
-      end
-
-      # GitHub username
-      if @committer.githubUsername
-        _tr do
-          _td 'GitHub username'
-          _td do
-            _a @committer.githubUsername, href: 
-              "https://github.com/" + @committer.githubUsername
-          end
-        end
-      end
-
-      if @committer.member
-        # Member status
-        if @committer.member.status
-          _tr data_edit: ('memstat' if @@auth.secretary) do
-            _td 'Member status'
-            if @committer.member.info
-              _td do
-                _span @committer.member.status
-               if @edit_memstat
-                 _form.inline method: 'post' do
-                   if @committer.member.status.include? 'Active'
-                     _button.btn.btn_primary 'move to emeritus',
-                       name: 'action', value: 'emeritus'
-                   elsif @committer.member.status.include? 'Emeritus'
-                     _button.btn.btn_primary 'move to active',
-                       name: 'action', value: 'active'
-                   end
-                 end
-               end
-              end
-            else
-              _td.not_found 'Not in members.txt'
-            end
-          end
-        end
-
-        # Members.txt
-        if @committer.member.info
-          _tr data_edit: 'memtext' do
-            _td 'Members.txt'
-            _td do
-              if @edit_memtext
-                _form.inline method: 'post' do
-                  _div do
-                    _textarea defaultValue: @committer.member.info
-                  end
-                  _button.btn.btn_primary 'submit'
-                end
-              else
-                _pre @committer.member.info,
-                  class: ('small' if @committer.member.info =~ /.{81}/)
-              end
-            end
-          end
-        end
-
-        if @committer.member.nomination
-          _tr do
-            _td 'Nomination'
-            _td {_pre @committer.member.nomination}
-          end
-        end
-
-        # Forms on file
-        if @committer.forms
-          documents = "https://svn.apache.org/repos/private/documents"
-          _tr do
-            _td 'Forms on file'
-            _td do
-              _ul do
-                for form in @committer.forms
-                  link = @committer.forms[form]
-                  
-                  if form == 'icla'
-                    _li do
-                      _a 'ICLA', href: "#{documents}/iclas/#{link}"
-                    end
-                  elsif form == 'member'
-                    _li do
-                      _a 'Membership App', 
-                        href: "#{documents}/member_apps/#{link}"
-                    end
-                  else
-                    _li "#{form}: #{link}"
-                  end
-                end
-              end
-            end
-          end
-        end
-      end
-
-      # SpamAssassin score
-      _tr data_edit: 'sascore' do
-        _td 'SpamAssassin score'
-        _td do
-          if @edit_sascore
-            _form method: 'post' do
-              _input type: 'number', min: 0, max: 10, 
-                name: 'sascore', defaultValue: @committer.sascore
-              _input type: 'submit', value: 'submit'
-            end
-          else
-            _span @committer.sascore
-          end
-        end
-      end
-    end
-
-    # modal dialog for dry run results
-    _div.modal.fade tabindex: -1 do
-      _div.modal_dialog do
-        _div.modal_content do
-          _div.modal_header do
-            _button.close 'x', data_dismiss: 'modal'
-            _h4 'Dry run results'
-          end
-          _div.modal_body do
-            _textarea value: JSON.stringify(@response, nil, 2), readonly: true
-          end
-          _div.modal_footer do
-            _button.btn.btn_default 'Close', data_dismiss: 'modal'
-          end
-        end
-      end
-    end
-  end
-
-  # capture committer on initial load
-  def componentWillMount()
-    self.componentWillReceiveProps()
-  end
-
-  # replace committer on change, determine if user is authorized to make
-  # changes
-  def componentWillReceiveProps()
-    if @committer.id != @@committer.id
-      @committer = @@committer
-      @auth = (@@auth.id == @@committer.id or @@auth.secretary or @@auth.root)
-    end
-  end
-
-  # on initial display, look for add editable rows, highlight them,
-  # and watch for double clicks on them
-  def componentDidMount()
-    return unless @auth
-    Array(document.querySelectorAll('tr[data-edit]')).each do |tr|
-      tr.addEventListener('dblclick', self.dblclick)
-      tr.querySelector('td').classList.add 'bg-success'
-    end
-  end
-
-  # when a double click occurs, toggle the associated state
-  def dblclick(event)
-    tr = event.currentTarget
-    field = "edit_#{tr.dataset.edit}"
-    changes = {}
-    changes[field] = !self.state[field]
-    self.setState changes
-    window.getSelection().removeAllRanges()
-  end
-
-  # after update, register event listeners on forms
-  def componentDidUpdate()
-    Array(document.querySelectorAll('tr[data-edit]')).each do |tr|
-      form = tr.querySelector('form')
-      if form
-        form.setAttribute 'data-action', tr.getAttribute('data-edit')
-        jQuery('input[type=submit],button', form).click(self.submit)
-      end
-    end
-  end
-
-  # submit form using AJAX
-  def submit(event)
-    event.preventDefault()
-    form = jQuery(event.currentTarget).closest('form')
-    target = event.target
-
-    # serialize form
-    formData = form.serializeArray();
-
-    # add button if it has a value
-    if target and target.getAttribute('name') and target.getAttribute('value')
-      formData.push name: target.getAttribute('name'),
-        value: target.getAttribute('value')
-    end
-
-    # indicate dryrun is requested if option or control key is down
-    if event.altKey or event.ctrlKey
-      formData.unshift name: 'dryrun', value: true 
-    end
-
-    # issue request
-    jQuery.ajax(
-      method: (form[0].method || 'GET').upcase(),
-      url: document.location.href + '/' + form[0].getAttribute('data-action'),
-      data: formData,
-      dataType: 'json',
-
-      success: ->(response) {
-        @committer = response.committer if response.committer
-
-        # turn off edit mode on this field
-        tr = form.closest('tr')[0]
-        if tr
-          field = "edit_#{tr.dataset.edit}"
-          changes = {}
-          changes[field] = false
-          self.setState changes
-        end
-      },
-
-      error: ->(response) {
-        alert response.statusText
-      },
-
-      complete: ->(response) do
-        # show results of dryrun
-        if formData[0] and formData[0].name == 'dryrun'
-          @response = response.responseJSON
-          jQuery('div.modal').modal('show')
-        end
-
-        # reenable form for later reuse
-        jQuery('input, button', form).prop('disabled', false)
-      end
-    )
-
-    # disable input
-    jQuery('input, button', form).prop('disabled', true)
-  end
-end
diff --git a/www/roster/views/person.js.rb b/www/roster/views/person.js.rb
new file mode 100644
index 0000000..e051fd7
--- /dev/null
+++ b/www/roster/views/person.js.rb
@@ -0,0 +1,242 @@
+class Person < React
+  def initialize
+    @committer = {}
+    @response = nil
+  end
+
+  def render
+    # usage information for authenticated users (owner, secretary, etc.)
+    if @auth
+      _div.alert.alert_success 'Double click on a field in this color to edit.'
+    end
+
+    _h2 "#{@committer.id}@apache.org"
+
+    _table.wide do
+      _tbody do
+
+        # Name
+        _PersonName person: self
+
+        # Personal URL
+        if @committer.urls
+          _PersonUrls person: self
+        end
+
+        # Committees
+        committees = @committer.committees
+        unless committees.empty?
+          _tr do
+            _td 'Committees'
+            _td do
+              _ul committees do |pmc|
+                _li {_a pmc, href: "committee/#{pmc}"}
+              end
+            end
+          end
+        end
+
+        # Committer
+        commit_list = @committer.committer
+        unless commit_list.all? {|pmc| committees.include? pmc}
+          _tr do
+            _td 'Committer'
+            _td do
+              _ul commit_list do |pmc|
+                next if committees.include? pmc
+                _li {_a pmc, href: "committee/#{pmc}"}
+              end
+            end
+          end
+        end
+
+        # Groups
+        unless @committer.groups.empty?
+          _tr do
+            _td 'Groups'
+            _td do
+              _ul @committer.groups do |group|
+                next if group == 'apldap'
+
+                if group == 'committers'
+                  _li {_a group, href: "committer/"}
+                elsif group == 'member'
+                  _li {_a group, href: "members"}
+                else
+                  _li {_a group, href: "group/#{group}"}
+                end
+              end
+            end
+          end
+        end
+
+        # Email addresses
+        if @committer.mail
+          _PersonEmail person: self
+        end
+
+        # PGP keys
+        if @committer.pgp
+          _PersonPgpKeys person: self
+        end
+
+        # SSH keys
+        if @committer.ssh
+          _PersonSshKeys person: self
+        end
+
+        # GitHub username
+        if @committer.githubUsername
+          _PersonGitHub person: self
+        end
+
+        if @committer.member
+          _PersonMemberStatus person: self
+
+          # Members.txt
+          if @committer.member.info
+            _PersonMemberText person: self
+          end
+
+          if @committer.member.nomination
+            _tr do
+              _td 'Nomination'
+              _td {_pre @committer.member.nomination}
+            end
+          end
+
+          # Forms on file
+          if @committer.forms
+            _PersonForms person: self
+          end
+        end
+
+        # SpamAssassin score
+        _PersonSascore person: self
+      end
+    end
+
+    # modal dialog for dry run results
+    _div.modal.fade tabindex: -1 do
+      _div.modal_dialog do
+        _div.modal_content do
+          _div.modal_header do
+            _button.close 'x', data_dismiss: 'modal'
+            _h4 'Dry run results'
+          end
+          _div.modal_body do
+            _textarea value: JSON.stringify(@response, nil, 2), readonly: true
+          end
+          _div.modal_footer do
+            _button.btn.btn_default 'Close', data_dismiss: 'modal'
+          end
+        end
+      end
+    end
+  end
+
+  # capture committer on initial load
+  def componentWillMount()
+    self.componentWillReceiveProps()
+  end
+
+  # replace committer on change, determine if user is authorized to make
+  # changes
+  def componentWillReceiveProps()
+    if @committer.id != @@committer.id
+      @committer = @@committer
+      @auth = (@@auth.id == @@committer.id or @@auth.secretary or @@auth.root)
+    end
+  end
+
+  # on initial display, look for add editable rows, highlight them,
+  # and watch for double clicks on them
+  def componentDidMount()
+    return unless @auth
+    Array(document.querySelectorAll('tr[data-edit]')).each do |tr|
+      tr.addEventListener('dblclick', self.dblclick)
+      tr.querySelector('td').classList.add 'bg-success'
+    end
+  end
+
+  # when a double click occurs, toggle the associated state
+  def dblclick(event)
+    tr = event.currentTarget
+    field = "edit_#{tr.dataset.edit}"
+    changes = {}
+    changes[field] = !self.state[field]
+    self.setState changes
+    window.getSelection().removeAllRanges()
+  end
+
+  # after update, register event listeners on forms
+  def componentDidUpdate()
+    Array(document.querySelectorAll('tr[data-edit]')).each do |tr|
+      form = tr.querySelector('form')
+      if form
+        form.setAttribute 'data-action', tr.getAttribute('data-edit')
+        jQuery('input[type=submit],button', form).click(self.submit)
+      end
+    end
+  end
+
+  # submit form using AJAX
+  def submit(event)
+    event.preventDefault()
+    form = jQuery(event.currentTarget).closest('form')
+    target = event.target
+
+    # serialize form
+    formData = form.serializeArray();
+
+    # add button if it has a value
+    if target and target.getAttribute('name') and target.getAttribute('value')
+      formData.push name: target.getAttribute('name'),
+        value: target.getAttribute('value')
+    end
+
+    # indicate dryrun is requested if option or control key is down
+    if event.altKey or event.ctrlKey
+      formData.unshift name: 'dryrun', value: true 
+    end
+
+    # issue request
+    jQuery.ajax(
+      method: (form[0].method || 'GET').upcase(),
+      url: document.location.href + '/' + form[0].getAttribute('data-action'),
+      data: formData,
+      dataType: 'json',
+
+      success: ->(response) {
+        @committer = response.committer if response.committer
+
+        # turn off edit mode on this field
+        tr = form.closest('tr')[0]
+        if tr
+          field = "edit_#{tr.dataset.edit}"
+          changes = {}
+          changes[field] = false
+          self.setState changes
+        end
+      },
+
+      error: ->(response) {
+        alert response.statusText
+      },
+
+      complete: ->(response) do
+        # show results of dryrun
+        if formData[0] and formData[0].name == 'dryrun'
+          @response = response.responseJSON
+          jQuery('div.modal').modal('show')
+        end
+
+        # reenable form for later reuse
+        jQuery('input, button', form).prop('disabled', false)
+      end
+    )
+
+    # disable input
+    jQuery('input, button', form).prop('disabled', true)
+  end
+end
diff --git a/www/roster/views/person/email.js.rb b/www/roster/views/person/email.js.rb
new file mode 100644
index 0000000..3537221
--- /dev/null
+++ b/www/roster/views/person/email.js.rb
@@ -0,0 +1,21 @@
+#
+# Render and edit a person's E-mail addresses
+#
+
+class PersonEmail < React
+  def render
+    committer = @@person.state.committer
+
+    _tr do
+      _td 'Email addresses'
+
+      _td do
+        _ul committer.mail do |url|
+          _li do
+            _a url, href: 'mailto:' + url
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/www/roster/views/person/forms.js.rb b/www/roster/views/person/forms.js.rb
new file mode 100644
index 0000000..d936f16
--- /dev/null
+++ b/www/roster/views/person/forms.js.rb
@@ -0,0 +1,35 @@
+#
+# Show a list of a person's forms on file
+#
+
+class PersonForms < React
+  def render
+    committer = @@person.state.committer
+    documents = "https://svn.apache.org/repos/private/documents"
+
+    _tr do
+      _td 'Forms on file'
+
+      _td do
+        _ul do
+          for form in committer.forms
+            link = committer.forms[form]
+            
+            if form == 'icla'
+              _li do
+                _a 'ICLA', href: "#{documents}/iclas/#{link}"
+              end
+            elsif form == 'member'
+              _li do
+                _a 'Membership App', 
+                  href: "#{documents}/member_apps/#{link}"
+              end
+            else
+              _li "#{form}: #{link}"
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/www/roster/views/person/fullname.js.rb b/www/roster/views/person/fullname.js.rb
new file mode 100644
index 0000000..a12a9a5
--- /dev/null
+++ b/www/roster/views/person/fullname.js.rb
@@ -0,0 +1,58 @@
+#
+# Render and edit a person's name
+#
+
+class PersonName < React
+  def render
+    committer = @@person.state.committer
+
+    _tr data_edit: ('fullname' if @@person.props.auth.secretary) do
+      _td 'Name'
+
+      _td do
+        name = committer.name
+
+        if @@person.state.edit_fullname
+
+          _form.inline method: 'post' do
+            _div do
+              _label 'public name', for: 'publicname'
+              _input.publicname! name: 'publicname', required: true,
+                defaultValue: name.public_name
+            end
+
+            _div do
+              _label 'legal name', for: 'legalname'
+              _input.legalname! name: 'legalname', required: true,
+                defaultValue: name.legal_name
+            end
+
+            _button.btn.btn_primary 'submit'
+          end
+
+        else
+
+          if 
+            name.public_name==name.legal_name and 
+            name.public_name==name.ldap
+          then
+            _span committer.name.public_name
+          else
+            _ul do
+              _li "#{committer.name.public_name} (public name)"
+
+              if name.legal_name and name.legal_name != name.public_name
+                _li "#{committer.name.legal_name} (legal name)"
+              end
+
+              if name.ldap and name.ldap != name.public_name
+                _li "#{committer.name.ldap} (ldap)"
+              end
+            end
+          end
+
+        end
+      end
+    end
+  end
+end
diff --git a/www/roster/views/person/github.js.rb b/www/roster/views/person/github.js.rb
new file mode 100644
index 0000000..038bc6f
--- /dev/null
+++ b/www/roster/views/person/github.js.rb
@@ -0,0 +1,18 @@
+#
+# Render and edit a person's GitHub user name
+#
+
+class PersonGitHub < React
+  def render
+    committer = @@person.state.committer
+
+    _tr do
+      _td 'GitHub username'
+      _td do
+        _a committer.githubUsername, 
+          href: "https://github.com/" + committer.githubUsername
+      end
+    end
+  end
+end
+
diff --git a/www/roster/views/person/memstat.js.rb b/www/roster/views/person/memstat.js.rb
new file mode 100644
index 0000000..31cdd81
--- /dev/null
+++ b/www/roster/views/person/memstat.js.rb
@@ -0,0 +1,33 @@
+#
+# Render and edit a person's member status
+#
+
+class PersonMemberStatus < React
+  def render
+    committer = @@person.state.committer
+
+    _tr data_edit: ('memstat' if @@person.props.auth.secretary) do
+      _td 'Member status'
+
+      if committer.member.info
+        _td do
+          _span committer.member.status
+
+         if @@person.state.edit_memstat
+           _form.inline method: 'post' do
+             if committer.member.status.include? 'Active'
+               _button.btn.btn_primary 'move to emeritus',
+                 name: 'action', value: 'emeritus'
+             elsif committer.member.status.include? 'Emeritus'
+               _button.btn.btn_primary 'move to active',
+                 name: 'action', value: 'active'
+             end
+           end
+         end
+        end
+      else
+        _td.not_found 'Not in members.txt'
+      end
+    end
+  end
+end
diff --git a/www/roster/views/person/memtext.rb b/www/roster/views/person/memtext.rb
new file mode 100644
index 0000000..2af57ae
--- /dev/null
+++ b/www/roster/views/person/memtext.rb
@@ -0,0 +1,30 @@
+#
+# Render and edit a person's members.txt entry
+#
+
+class PersonMemberText < React
+  def render
+    committer = @@person.state.committer
+
+    _tr data_edit: 'memtext' do
+      _td 'Members.txt'
+
+      _td do
+        if @@person.state.edit_memtext
+
+          _form.inline method: 'post' do
+            _div do
+              _textarea defaultValue: committer.member.info
+            end
+            _button.btn.btn_primary 'submit'
+          end
+
+        else
+
+          _pre committer.member.info,
+            class: ('small' if committer.member.info =~ /.{81}/)
+        end
+      end
+    end
+  end
+end
diff --git a/www/roster/views/person/pgpkeys.js.rb b/www/roster/views/person/pgpkeys.js.rb
new file mode 100644
index 0000000..815c59c
--- /dev/null
+++ b/www/roster/views/person/pgpkeys.js.rb
@@ -0,0 +1,29 @@
+#
+# Render and edit a person's PGP keys
+#
+
+class PersonPgpKeys < React
+  def render
+    committer = @@person.state.committer
+
+    _tr do
+      _td 'PGP keys'
+
+      _td do
+        _ul committer.pgp do |key|
+          _li do
+            if key =~ /^[0-9a-fA-F ]+$/
+              _samp do
+                _a key, href: 'https://sks-keyservers.net/pks/lookup?' +
+                  'op=index&search=0x' + key.gsub(' ', '')
+              end
+            else
+              _samp key
+            end
+          end
+        end
+      end
+    end
+  end
+end
+
diff --git a/www/roster/views/person/sascore.js.rb b/www/roster/views/person/sascore.js.rb
new file mode 100644
index 0000000..c5c1a92
--- /dev/null
+++ b/www/roster/views/person/sascore.js.rb
@@ -0,0 +1,30 @@
+#
+# Render and edit a person's SpamAssassin score
+#
+
+class PersonSascore < React
+  def render
+    committer = @@person.state.committer
+
+    _tr data_edit: 'sascore' do
+      _td 'SpamAssassin score'
+
+      _td do
+
+        if @edit_sascore
+
+          _form method: 'post' do
+            _input type: 'number', min: 0, max: 10, 
+              name: 'sascore', defaultValue: committer.sascore
+            _input type: 'submit', value: 'submit'
+          end
+
+        else
+
+          _span committer.sascore
+
+        end
+      end
+    end
+  end
+end
diff --git a/www/roster/views/person/sshkeys.js.rb b/www/roster/views/person/sshkeys.js.rb
new file mode 100644
index 0000000..4124df3
--- /dev/null
+++ b/www/roster/views/person/sshkeys.js.rb
@@ -0,0 +1,23 @@
+#
+# Render and edit a person's SSH keys
+#
+
+class PersonSshKeys < React
+  def render
+    committer = @@person.state.committer
+
+    _tr do
+      _td 'SSH keys'
+
+
+      _td do
+        _ul committer.ssh do |key|
+          _li.ssh do
+            _pre.wide key
+          end
+        end
+      end
+    end
+  end
+end
+
diff --git a/www/roster/views/person/urls.js.rb b/www/roster/views/person/urls.js.rb
new file mode 100644
index 0000000..a73bc1b
--- /dev/null
+++ b/www/roster/views/person/urls.js.rb
@@ -0,0 +1,19 @@
+#
+# Render and edit a person's URLs
+#
+
+class PersonUrls < React
+  def render
+    committer = @@person.state.committer
+
+    _tr do
+      _td 'Personal URL'
+
+      _td do
+        _ul committer.urls do |url|
+          _li {_a url, href: url}
+        end
+      end
+    end
+  end
+end

Mime
View raw message