You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whimsical.apache.org by ru...@apache.org on 2017/10/11 16:15:53 UTC
[whimsy] 02/02: rough in a prod to non-responsive PMCs
This is an automated email from the ASF dual-hosted git repository.
rubys pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/whimsy.git
commit d62a8d31340aba29fad461b6c45f420639019d4a
Author: Sam Ruby <ru...@intertwingly.net>
AuthorDate: Wed Oct 11 12:15:24 2017 -0400
rough in a prod to non-responsive PMCs
---
www/board/agenda/routes.rb | 2 +-
www/board/agenda/templates/non-responsive.txt | 43 ++++++++++++++++++++++
.../agenda/views/actions/reminder-text.json.rb | 1 +
www/board/agenda/views/buttons/reminders.js.rb | 32 ++++++++++++++--
www/board/agenda/views/models/agenda.js.rb | 7 ++++
www/board/agenda/views/pages/missing.js.rb | 38 +++++++++++++++----
www/board/agenda/views/router.js.rb | 10 +++--
7 files changed, 118 insertions(+), 15 deletions(-)
diff --git a/www/board/agenda/routes.rb b/www/board/agenda/routes.rb
index 9805570..b76400d 100755
--- a/www/board/agenda/routes.rb
+++ b/www/board/agenda/routes.rb
@@ -290,7 +290,7 @@ get '/json/potential-actions' do
_json :'actions/potential-actions'
end
-get %r{/json/(reminder[12])} do |reminder|
+get %r{/json/(reminder[12]|non-responsive)} do |reminder|
@reminder = reminder
_json :'actions/reminder-text'
end
diff --git a/www/board/agenda/templates/non-responsive.txt b/www/board/agenda/templates/non-responsive.txt
new file mode 100644
index 0000000..a01b8d3
--- /dev/null
+++ b/www/board/agenda/templates/non-responsive.txt
@@ -0,0 +1,43 @@
+Subject: ASF Board Report for [project] - Repeated Reminder for [month] [year]
+
+Dear [project] community,
+
+In the governance model at the ASF the board delegates responsibility for
+managing projects to PMCs. To enable to board to provide oversight across the
+foundation, the PMCs are tasked with providing the board with a quarterly
+report on the health of the project. The board has noticed that the reports
+for [project] have been missed for a number of months.
+
+The reports to the board are normally written by the PMC chair but all PMC
+members have an individual responsibility to ensure that a report is
+submitted. If the PMC chair is not available then any PMC member can submit
+the report. If you need help with this process, please reach out to
+board@apache.org
+
+Please ensure that a report for [project] is submitted to the board for the
+next meeting.
+
+If the PMC chair is not going to be available for an extended period of time
+it may make sense to rotate the PMC chair. Rotating the PMC chair does not
+mean the current chair has failed. People's situations and interests change,
+and rotation is good as it allows more people to become familiar with that
+role. Again, if assistance is required with this process, please feel free to
+reach out to board@apache.org
+
+As projects mature, they will naturally reach a point where activity reduces
+to a level that the project is no longer sustainable. At Apache, projects
+reach this stage when there are no longer 3 active PMC members providing
+oversight. Projects that reach this stage are placed in the attic[1]. If
+[project] has reached this point, please reach out to the Attic project to
+arrange transfer. On the other hand, if your project is mostly dormant but
+still has at least three active PMC members it can stay in that state for as
+long as needed. If your project is in such a state, please mention that in
+your report and verify the PMC's state at regular intervals.
+
+Finally, if you have any questions please feel free to reach out to
+board@apache.org.
+
+Thanks,
+The ASF Board
+
+[1] (http://attic.apache.org/
diff --git a/www/board/agenda/views/actions/reminder-text.json.rb b/www/board/agenda/views/actions/reminder-text.json.rb
index bffbc86..cc57c05 100644
--- a/www/board/agenda/views/actions/reminder-text.json.rb
+++ b/www/board/agenda/views/actions/reminder-text.json.rb
@@ -3,6 +3,7 @@ require 'active_support/core_ext/integer/inflections.rb'
# read template for the reminders
@reminder.untaint if @reminder =~ /^reminder\d$/
+@reminder.untaint if @reminder =~ /^non-responsive$/
template = File.read("templates/#@reminder.txt")
# find the latest agenda
diff --git a/www/board/agenda/views/buttons/reminders.js.rb b/www/board/agenda/views/buttons/reminders.js.rb
index bdccedc..8c4269b 100644
--- a/www/board/agenda/views/buttons/reminders.js.rb
+++ b/www/board/agenda/views/buttons/reminders.js.rb
@@ -15,6 +15,7 @@ class InitialReminder < Vue
{
text: 'send initial reminders',
class: 'btn_primary',
+ disabled: true,
data_toggle: 'modal',
data_target: '#reminder-form'
}
@@ -22,7 +23,9 @@ class InitialReminder < Vue
# fetch email template
def loadText(event)
- if event.target.textContent == 'send initial reminders'
+ if event.target.textContent.include? 'non-responsive'
+ reminder = 'non-responsive'
+ elsif event.target.textContent.include? 'initial'
reminder = 'reminder1'
else
reminder = 'reminder2'
@@ -32,14 +35,21 @@ class InitialReminder < Vue
@subject = response.subject
@message = response.body
@disabled = false
+
+ if reminder == 'non-responsive'
+ @selection = 'inactive'
+ else
+ @selection = 'active'
+ end
end
end
# wire up event handlers
def mounted()
Vue.nextTick do
- Array(document.querySelectorAll('.btn-primary')).each do |button|
+ Array(document.querySelectorAll('button')).each do |button|
if button.getAttribute('data-target') == '#reminder-form'
+ button.disabled = false
button.addEventListener :click, self.loadText
end
end
@@ -69,6 +79,7 @@ class InitialReminder < Vue
# on click, disable the input fields and buttons and submit
def click(event)
+ event.target.disabled = true
@disabled = true
dryrun = (event.target.textContent == 'Dry Run')
@@ -83,7 +94,9 @@ class InitialReminder < Vue
# collect up a list of PMCs that are checked
Array(document.querySelectorAll('input[type=checkbox]')).each do |input|
- data.pmcs << input.value if input.checked
+ if input.checked and input.classList.contains(@selection)
+ data.pmcs << input.value
+ end
end
post 'send-reminders', data do |response|
@@ -100,6 +113,7 @@ class InitialReminder < Vue
alert("No reminders were sent")
end
+ event.target.disabled = true
@disabled = false
jQuery('#reminder-form').modal(:hide)
document.body.classList.remove('modal-open')
@@ -112,7 +126,17 @@ end
#
class FinalReminder < Vue
def render
- _button.btn.btn_primary 'send final reminders',
+ _button.btn.btn_primary 'send final reminders', disabled: true,
+ data_toggle: 'modal', data_target: '#reminder-form'
+ end
+end
+
+#
+# A button for warning non-responsive PMCs
+#
+class ProdReminder < Vue
+ def render
+ _button.btn.btn_danger 'prod non-responsive PMCs', disabled: true,
data_toggle: 'modal', data_target: '#reminder-form'
end
end
diff --git a/www/board/agenda/views/models/agenda.js.rb b/www/board/agenda/views/models/agenda.js.rb
index 4545cc7..575287b 100644
--- a/www/board/agenda/views/models/agenda.js.rb
+++ b/www/board/agenda/views/models/agenda.js.rb
@@ -164,10 +164,17 @@ class Agenda
end
end
+ # report was marked as NOT accepted during the meeting
def rejected
Minutes.rejected and Minutes.rejected.include?(@title)
end
+ # PMC has missed two consecutive months
+ def nonresponsive
+ @notes and @notes.include? 'missing' and
+ @notes.sub(/^.*missing/, '').split(',').length >= 2
+ end
+
# compute href by taking the title and replacing all non alphanumeric
# characters with dashes
def href
diff --git a/www/board/agenda/views/pages/missing.js.rb b/www/board/agenda/views/pages/missing.js.rb
index 94c5682..05fb4f6 100644
--- a/www/board/agenda/views/pages/missing.js.rb
+++ b/www/board/agenda/views/pages/missing.js.rb
@@ -18,15 +18,39 @@ class Missing < Vue
first = true
Agenda.index.each do |item|
- if item.missing and item.owner
+ if item.missing and item.owner and item.nonresponsive
+ _h2 'Non responsive PMCs' if first
+
+ _h3 class: item.color do
+ if item.attach =~ /^[A-Z]+/
+ _input.inactive type: 'checkbox', name: 'selected',
+ value: item.title, checked: @checked[item.title]
+ end
+
+ _Link text: item.title, href: "flagged/#{item.href}",
+ class: ('default' if first)
+ first = false
+
+ _span.owner " [#{item.owner} / #{item.shepherd}]"
+
+ if item.flagged_by
+ flagged_by = Server.directors[item.flagged_by] || item.flagged_by
+ _span.owner " flagged by: #{flagged_by}"
+ end
+ end
+
+ _AdditionalInfo item: item, prefix: true
+ end
+ end
+
+ _h2 'Other missing reports' unless first
+
+ Agenda.index.each do |item|
+ if item.missing and item.owner and not item.nonresponsive
_h3 class: item.color do
if item.attach =~ /^[A-Z]+/
- _input type: 'checkbox', name: 'selected', value: item.title,
- checked: true, disabled: true, domPropsDisabled: false,
- domPropsChecked: @checked[item.title], onClick:-> {
- @checked[item.title] = !@checked[item.title]
- Vue.forceUpdate()
- }
+ _input.active type: 'checkbox', name: 'selected',
+ value: item.title, checked: @checked[item.title]
end
_Link text: item.title, href: "flagged/#{item.href}",
diff --git a/www/board/agenda/views/router.js.rb b/www/board/agenda/views/router.js.rb
index 02e4fb5..d884929 100644
--- a/www/board/agenda/views/router.js.rb
+++ b/www/board/agenda/views/router.js.rb
@@ -10,7 +10,6 @@ class Router
# route request based on path and query from the window location (URL)
def self.route(path, query)
options = {}
- buttons = []
if not path or path == '.'
item = Agenda
@@ -36,8 +35,13 @@ class Router
item = {view: Rejected, title: 'Reports which were NOT accepted'}
elsif path == 'missing'
- item = {view: Missing, title: 'Missing reports',
- buttons: [{form: InitialReminder}, {button: FinalReminder}]}
+ buttons = [{form: InitialReminder}, {button: FinalReminder}]
+
+ if Agenda.index.any? {|item| item.nonresponsive}
+ buttons << {form: ProdReminder}
+ end
+
+ item = {view: Missing, title: 'Missing reports', buttons: buttons}
elsif path =~ %r{^flagged/[-\w]+$}
item = Agenda.find(path[8..-1])
--
To stop receiving notification emails like this one, please contact
"commits@whimsical.apache.org" <co...@whimsical.apache.org>.