www/project/icla/views/pages/invite.js.rb (601 lines of code) (raw):

class Invite < Vue def initialize @disabled = true @alert = nil # initialize form fields @iclaname = '' @iclaemail = '' @pmc = '' @votelink = '' @noticelink = '' @phase = '' @role = '' @roleText = ' to submit ICLA for ' @subject = '' @subjectPhase = '' @previewMessage = 'Preview' @pmcOrPpmc = '' @phasePrefix = '' @member = Server.data.member @user = Server.data.user # initialize conditional text @showPMCVoteLink = false; @showPPMCVoteLink = false; @voteErrorMessage = ''; @showVoteErrorMessage = false; @showPMCNoticeLink = false; @showPPMCNoticeLink = false; @noticeErrorMessage = ''; @showNoticeErrorMessage = false; @showDiscussFrame = false; @showVoteFrame = false; @showPhaseFrame = false; @showRoleFrame = false; @discussComment = '' @voteComment = '' @proposalText = '' @voteProposalText = '' end def render _p %{ This application allows PMC and PPMC members to discuss contributors to achieve consensus; vote on contributors to become a committer or a PMC/PPMC member; or simply invite them to submit an ICLA. } _p do _b '** NOTE: only new contributors are currently supported, i.e. existing ASF committers are excluded. **' end _p %{ If you would like to discuss the candidate, go to the Discuss tab after filling the contributor and PMC/PPMC fields. } _p %{ If you have discussed the candidate and would like to conduct a vote, go to the Vote tab after filling the contributor and PMC/PPMC fields. } _p %{ If you have already achieved consensus, you can go to the Invite tab after filling the contributor and PMC/PPMC fields. } # error messages if @alert _div.alert.alert_danger do _b 'Error: ' _span @alert end end # # Form fields # _div.form_group do _label "Contributor's name (required):", :for => 'iclaname' _input.form_control.iclaname! placeholder: 'GivenName FamilyName', required: true, value: @iclaname end _div.form_group do _label "Contributor's E-Mail address (required):", :for => 'iclaemail' _input.form_control.iclaemail! type: 'email', required: true, placeholder: 'user@example.com', onChange: self.setIclaEmail, value: @iclaemail end _div.form_group do _label 'PMC/PPMC (required)', :for => 'pmc' _select.form_control.pmc! required: true, onChange: self.setPMC, value: @pmc do _option '' Server.data.allData.each_key do |pmc| _option pmc if Server.data.allData[pmc]['pmc'] end _option '---', disabled: true # No point letting it be chosen Server.data.allData.each_key do |ppmc| _option ppmc unless Server.data.allData[ppmc]['pmc'] end end end if @showPhaseFrame _ul.nav.nav_tabs do _li :class => ('active' if @phase == :discuss) do _a 'Discuss', onClick: self.selectDiscuss end _li :class => ('active' if @phase == :vote) do _a 'Vote', onClick: self.selectVote end _li :class => ('active' if @phase == :invite) do _a 'Invite', onClick: self.selectInvite end end end if @showPMCVoteLink _p %{ Fill the following field only if the person was voted by the PMC to become a committer. Link to the [RESULT][VOTE] message in the mail archives. } end if @showPPMCVoteLink _p %{ Fill the following field only if the person is an initial committer on a new project accepted for incubation, or the person has been voted as a committer on a podling. For new incubator projects use the http://wiki.apache.org/incubator/XXXProposal link; for existing podlings link to the [RESULT][VOTE] message in the mail archives. } end if @showPMCVoteLink or @showPPMCVoteLink _ 'Navigate to ' _a 'Ponymail', href: "https://lists.apache.org/list.html?private@#{@mail_list}.apache.org:lte=1M:[VOTE][RESULT]", target: _blank _ ', select the appropriate message, right-click PermaLink, copy link' _ ' to the clip-board, and paste the link here.' _p _div.form_group do _label 'VOTE link', :for => 'votelink' _input.form_control.votelink! type: 'url', onChange: self.setVoteLink, value: @votelink end if @showVoteErrorMessage _div.alert.alert_danger do _span @voteErrorMessage end end end if @showPMCNoticeLink _p %{ Fill the following field only if the person was voted by the PMC to become a PMC member. Link to the [NOTICE] message sent to the board. The message must have been in the archives for at least 72 hours. } end if @showPPMCNoticeLink _p %{ Fill the following field only if the person was voted by the PPMC to be a PPMC member. Link to the [NOTICE] message sent to the incubator PMC. The message must have been in the archives for at least 72 hours. } end if @showPMCNoticeLink or @showPPMCNoticeLink _ 'Navigate to ' if @showPMCNoticeLink _a 'Ponymail', href: "https://lists.apache.org/list.html?board@apache.org:lte=1M:NOTICE%20for%20#{@display_name}", target: _blank else _a 'Ponymail', href: "https://lists.apache.org/list.html?private@incubator.apache.org:lte=1M:NOTICE%20for%20#{@display_name}", target: _blank end _ ', select the appropriate message, right-click PermaLink, copy link' _ ' to the clip-board, and paste the link here.' _p _div.form_group do _label 'NOTICE link', :for => 'noticelink' _input.form_control.noticelink! type: 'url', onChange: self.setNoticeLink, value: @noticelink end end if @showNoticeErrorMessage _div.alert.alert_danger do _span @noticeErrorMessage end end if @showRoleFrame _div.form_check do _label do _input type: :radio, name: :role, value: :committer, id: 'role_committer', onClick: lambda {@role = :committer; @disabled = false @subject = @subjectPhase + ' Invite ' + @iclaname + ' to become a committer for ' + @display_name @proposalText = 'I propose we invite ' + @iclaname + ' to become a committer.' @voteProposalText = @proposalText + "\nHere is my +1." } _span @phasePrefix + ' invite to become a committer' end _br _label do _input type: :radio, name: :role, value: :pmc, id: 'role_pmc', onClick: lambda {@role = :pmc @disabled = false @subject = @subjectPhase + ' Invite ' + @iclaname + ' to become committer and ' + @pmcOrPPMC + ' member for ' + @display_name @proposalText = 'I propose we invite ' + @iclaname + ' to become a committer and ' + @pmcOrPPMC + ' member.' @voteProposalText = @proposalText + ' Here is my +1.' } _span @phasePrefix + ' invite to become a committer and ' + @pmcOrPPMC + ' member' end if @showDiscussFrame _br _label do _input type: :radio, name: :role, value: :invite, id: 'role_invite', onClick: lambda {@role = :invite @disabled = false @subject = @subjectPhase + ' Invite ' + @iclaname + ' to submit an ICLA for ' + @display_name @proposalText = 'I propose we invite ' + @iclaname + ' to submit an ICLA.' } _span @phasePrefix + ' invite to submit an ICLA' end end _p end end if @showDiscussFrame _div 'From: ' + @member _div 'To: private@' + @mail_list + '.apache.org' _div 'Subject: ' + @subject _p _span @proposalText _p _textarea.form_control rows: 4, placeholder: 'Here are my reasons:', name: 'discussComment', value: @discussComment, onChange: self.setdiscussComment end if @showVoteFrame _div 'From: ' + @member _div 'To: private@' + @mail_list + '.apache.org' _div 'Subject: ' + @subject _p _span @voteProposalText _p _textarea.form_control rows: 4, placeholder: 'Here are my reasons:', name: 'voteComment', value: @voteComment, onChange: self.setvoteComment end # # Submission buttons # _p do _button.btn.btn_primary @previewMessage, disabled: @disabled, onClick: self.preview end # # Hidden form: preview invite email # _div.modal.fade.invitation_preview! do _div.modal_dialog do _div.modal_content do _div.modal_header do _button.close "\u00d7", type: 'button', data_dismiss: 'modal' _h4 'Preview Invitation Email' end _div.modal_body do # headers _div do _b 'From: ' _span @userEmail end _div do _b 'To: ' _span "#{@iclaname} <#{@iclaemail}>" end _div do _b 'cc: ' _span @pmcEmail end # draft invitation email _div.form_group do _label :for => 'invitation' _textarea.form_control.invitation! value: @invitation, rows: 12, onChange: self.setInvitation end end _div.modal_footer do _button.btn.btn_default 'Cancel', data_dismiss: 'modal' _button.btn.btn_primary 'Mock Send', onClick: self.mockSend end end end end _p # # Hidden form: preview discussion email # _div.modal.fade.discussion_preview! do _div.modal_dialog do _div.modal_content do _div.modal_header do _button.close "\u00d7", type: 'button', data_dismiss: 'modal' _h4 'Discussion Email' end _div.modal_body do # headers _div do _b 'From: ' _span @member end _div do _b 'To: ' _span @pmcEmail end _div do _b 'Subject: ' _span @subject end _div do _b _pre @message end end _div.modal_footer do _button.btn.btn_default 'Close', data_dismiss: 'modal' end end end end _p # # Hidden form: preview vote email # _div.modal.fade.vote_preview! do _div.modal_dialog do _div.modal_content do _div.modal_header do _button.close "\u00d7", type: 'button', data_dismiss: 'modal' _h4 'Vote Email' end _div.modal_body do # headers _div do _b 'From: ' _span @member end _div do _b 'To: ' _span @pmcEmail end _div do _b 'Subject: ' _span @subject end _div do _b _pre @message end end _div.modal_footer do _button.btn.btn_default 'Close', data_dismiss: 'modal' end end end end _p end # when the form is initially loaded, set the focus on the iclaname field def mounted() document.getElementById('iclaname').focus() end # # field setters # def resetCheckBoxes() document.getElementById('role_pmc').checked = false if document.getElementById('role_pmc') document.getElementById('role_committer').checked = false if document.getElementById('role_committer') document.getElementById('role_invite').checked = false if document.getElementById('role_invite') end def setIclaName(event) @iclaname = event.target.value self.checkValidity() end def setIclaEmail(event) @iclaemail = event.target.value self.checkValidity() end def setPMC(event) @pmc = event.target.value if Server.data.allData[@pmc] @isPMC = Server.data.allData[@pmc]['pmc'] @pmcOrPPMC = @isPMC ? 'PMC' : 'PPMC' @phase = :discuss @subject = '' @showPhaseFrame = true @showRoleFrame = true @mail_list = Server.data.allData[@pmc]['mail_list'] @display_name = Server.data.allData[@pmc]['display_name'] else @isPMC = false # true, but not the whole story! @pmcOrPPMC = '---' @phase = :discuss @subject = '' @showPhaseFrame = false @showRoleFrame = false @mail_list = '---' @display_name = '---' end self.checkValidity() selectDiscuss() end def selectDiscuss(event) @phase = :discuss @subject = '' @subjectPhase = '[DISCUSS]' @previewMessage = 'Start the Discussion' @phasePrefix = ' Start the discussion to' @showDiscussFrame = true; @showRoleFrame = true; @showVoteFrame = false; @showPMCVoteLink = false @showPPMCVoteLink = false @showPMCNoticeLink = false @showPPMCNoticeLink = false @showVoteErrorMessage = false; @showNoticeErrorMessage = false; self.checkValidity() @disabled = true; self.resetCheckBoxes() end def setdiscussComment(event) @discussComment = event.target.value end def selectVote(event) @phase = :vote @subject = '' @subjectPhase = '[VOTE]' @previewMessage = 'Start the Vote' @phasePrefix = ' Start the vote to' @showVoteFrame = true; @showRoleFrame = true; @showDiscussFrame = false; @showPMCVoteLink = false @showPPMCVoteLink = false @showPMCNoticeLink = false @showPPMCNoticeLink = false @showVoteErrorMessage = false; @showNoticeErrorMessage = false; self.checkValidity() @disabled = true; self.resetCheckBoxes() end def setvoteComment(event) @voteComment = event.target.value end def selectInvite(event) @phase = :invite @previewMessage = 'Preview Invitation' @showDiscussFrame = false; @showVoteFrame = false; @showRoleFrame = false; @showPMCVoteLink = @isPMC @showPPMCVoteLink = ! @isPMC @showPMCNoticeLink = @isPMC @showPPMCNoticeLink = ! @isPMC @showVoteErrorMessage = false; @showNoticeErrorMessage = false; checkVoteLink() if document.getElementById('votelink'); checkNoticeLink() if document.getElementById('noticelink'); self.checkValidity() end def setVoteLink(event) @votelink = event.target.value @showVoteErrorMessage = false checkVoteLink() self.checkValidity() end def checkVoteLink() document.getElementById('votelink').setCustomValidity(''); if (@votelink) # verify that the link refers to lists.apache.org message on the project list if not @votelink=~ /^https:\/\/lists\.apache\.org\// @voteErrorMessage = "Error: Please link to\ a message via https://lists.apache.org/" @showVoteErrorMessage = true; end if not @votelink=~ /private@#{@mail_list}(\.incubator)?\.apache\.org/ @voteErrorMessage = "Error: Please link to\ the [RESULT][VOTE] message sent to the private list." @showVoteErrorMessage = true; end if @showVoteErrorMessage document.getElementById('votelink').setCustomValidity(@voteErrorMessage); end end end def setNoticeLink(event) @noticelink = event.target.value @showNoticeErrorMessage = false; checkNoticeLink() self.checkValidity() end def checkNoticeLink() document.getElementById('noticelink').setCustomValidity(''); # verify that the link refers to lists.apache.org message on the proper list if (@noticelink) if not @noticelink=~ /^https:\/\/lists\.apache\.org\// @noticeErrorMessage = "Error: please link to\ a message via https://lists.apache.org/" @showNoticeErrorMessage = true; end if @showPMCNoticeLink and not @noticelink=~ /board@apache\.org/ @noticeErrorMessage = "Error: please link to\ the NOTICE message sent to the board list." @showNoticeErrorMessage = true; end if @showPPMCNoticeLink and not @noticelink=~ /private@incubator\.apache\.org/ @noticeErrorMessage = "Error: please link to\ the NOTICE message sent to the incubator private list." @showNoticeErrorMessage = true; end if @showNoticeErrorMessage document.getElementById('noticelink').setCustomValidity(@noticeErrorMessage); end end end def setInvitation(event) @invitation = event.target.value self.checkValidity() end # # validation and processing # # client side field validations def checkValidity() @disabled = !%w(iclaname iclaemail pmc votelink noticelink).all? do |id| element = document.getElementById(id) (not element) or element.checkValidity() end end # server side field validations def preview() if @phase == :invite previewInvitation() elsif @phase == :discuss previewDiscussion() elsif @phase == :vote previewVote() end end def previewInvitation() data = { iclaname: @iclaname, iclaemail: @iclaemail, pmc: @pmc, votelink: @votelink, noticelink: @noticelink } @disabled = true @alert = nil console.log('>previewInvitation: ' + data.inspect) post 'validate', data do |response| console.log('<previewInvitation: ' + response.inspect) @disabled = false @alert = response.error @memberEmail = response.memberEmail @userEmail = response.userEmail @pmcEmail = response.pmcEmail @invitation = response.invitation @token = response.token document.getElementById(response.focus).focus() if response.focus jQuery('#invitation-preview').modal(:show) unless @alert end end def previewDiscussion() data = { iclaname: @iclaname, iclaemail: @iclaemail, pmc: @pmc, proposer: @member, subject: @subject, proposalText: @proposalText, discussComment: @discussComment } @disabled = true @alert = nil console.log('>previewDiscussion: ' + data.inspect) post 'discuss', data do |response| console.log('<previewDiscussion: ' + response.inspect) @disabled = false @alert = response.error @memberEmail = response.memberEmail @userEmail = response.userEmail @pmcEmail = response.pmcEmail @discussion = response.discussion @token = response.token @message = response.message document.getElementById(response.focus).focus() if response.focus jQuery('#discussion-preview').modal(:show) unless @alert end end def previewVote() data = { user: @user, iclaname: @iclaname, iclaemail: @iclaemail, pmc: @pmc, proposer: @member, subject: @subject, proposalText: @voteProposalText, voteComment: @voteComment, voteComment: @voteComment } @disabled = true @alert = nil console.log('>previewVote: ' + data.inspect) post 'vote', data do |response| console.log('<previewVote: ' + response.inspect) @disabled = false @alert = response.error @memberEmail = response.memberEmail @userEmail = response.userEmail @pmcEmail = response.pmcEmail @token = response.token @message = response.message document.getElementById(response.focus).focus() if response.focus jQuery('#vote-preview').modal(:show) unless @alert end end # pretend to send an invitation def mockSend() # dismiss modal dialog jQuery('#invitation-preview').modal(:hide) # save information for later use (for demo purposes, this is client only) FormData.token = @token FormData.fullname = @iclaname FormData.email = @iclaemail FormData.pmc = @pmc FormData.votelink = @votelink FormData.noticelink = @noticelink # for demo purposes advance to the interview. Note: the below line # updates the URL in a way that breaks the back button. history.replaceState({}, nil, "form?token=#@token") # change the view Main.navigate(Interview) end end