Refactor all Buefy form submit buttons, per Chrome behavior
ugh, what a pain.  and turns out i'd previously ran into this same issue for
jQuery, per commit e945ebe325
			
			
This commit is contained in:
		
							parent
							
								
									43a210cac4
								
							
						
					
					
						commit
						a4b27115ac
					
				
					 17 changed files with 517 additions and 319 deletions
				
			
		|  | @ -758,7 +758,10 @@ class Form(object): | |||
|         context.setdefault('form_kwargs', {}) | ||||
|         # TODO: deprecate / remove the latter option here | ||||
|         if self.auto_disable_save or self.auto_disable: | ||||
|             context['form_kwargs']['class_'] = 'autodisable' | ||||
|             if self.use_buefy: | ||||
|                 context['form_kwargs']['@submit'] = 'submit{}'.format(self.component_studly) | ||||
|             else: | ||||
|                 context['form_kwargs']['class_'] = 'autodisable' | ||||
|         if self.focus_spec: | ||||
|             context['form_kwargs']['data-focus'] = self.focus_spec | ||||
|         context['request'] = self.request | ||||
|  |  | |||
|  | @ -1,21 +1,19 @@ | |||
| 
 | ||||
| const OnceButton = { | ||||
| 
 | ||||
|     template: [ | ||||
|         '<b-button', | ||||
|         ':type="type"', | ||||
|         ':native-type="nativeType"', | ||||
|         ':tag="tag"', | ||||
|         ':href="href"', | ||||
|         ':title="title"', | ||||
|         ':disabled="buttonDisabled"', | ||||
|         '@click="clicked"', | ||||
|         'icon-pack="fas"', | ||||
|         ':icon-left="iconLeft"', | ||||
|         '>', | ||||
|         '{{ buttonText }}', | ||||
|         '</b-button>' | ||||
|     ].join(' '), | ||||
|     template: ` | ||||
|         <b-button :type="type" | ||||
|                   :native-type="nativeType" | ||||
|                   :tag="tag" | ||||
|                   :href="href" | ||||
|                   :title="title" | ||||
|                   :disabled="buttonDisabled" | ||||
|                   @click="clicked" | ||||
|                   icon-pack="fas" | ||||
|                   :icon-left="iconLeft"> | ||||
|           {{ buttonText }} | ||||
|         </b-button> | ||||
|         `,
 | ||||
| 
 | ||||
|     props: { | ||||
|         type: String, | ||||
|  |  | |||
|  | @ -33,6 +33,153 @@ | |||
|   % endif | ||||
| </%def> | ||||
| 
 | ||||
| 
 | ||||
| % if use_buefy: | ||||
|     <script type="text/x-template" id="app-settings-template"> | ||||
| 
 | ||||
|       <div class="form"> | ||||
|         ${h.form(form.action_url, id=dform.formid, method='post', **{'@submit': 'submitForm'})} | ||||
|         ${h.csrf_token(request)} | ||||
| 
 | ||||
|         % if dform.error: | ||||
|             <div class="error-messages"> | ||||
|               <div class="ui-state-error ui-corner-all"> | ||||
|                 <span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-alert"></span> | ||||
|                 Please see errors below. | ||||
|               </div> | ||||
|               <div class="ui-state-error ui-corner-all"> | ||||
|                 <span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-alert"></span> | ||||
|                 ${dform.error} | ||||
|               </div> | ||||
|             </div> | ||||
|         % endif | ||||
| 
 | ||||
|         <div class="app-wrapper"> | ||||
| 
 | ||||
|           <div class="field-wrapper"> | ||||
|             <label for="settings-group">Showing Group</label> | ||||
|             <b-select name="settings-group" | ||||
|                       v-model="showingGroup"> | ||||
|               <option value="">(All)</option> | ||||
|               <option v-for="group in groups" | ||||
|                       :key="group.label" | ||||
|                       :value="group.label"> | ||||
|                 {{ group.label }} | ||||
|               </option> | ||||
|             </b-select> | ||||
|           </div> | ||||
| 
 | ||||
|           <div v-for="group in groups" | ||||
|                class="card" | ||||
|                v-show="!showingGroup || showingGroup == group.label" | ||||
|                style="margin-bottom: 1rem;"> | ||||
|             <header class="card-header"> | ||||
|               <p class="card-header-title">{{ group.label }}</p> | ||||
|             </header> | ||||
|             <div class="card-content"> | ||||
|               <div v-for="setting in group.settings" | ||||
|                   :class="'field-wrapper' + (setting.error ? ' with-error' : '')"> | ||||
| 
 | ||||
|                 <div v-if="setting.error" class="field-error"> | ||||
|                   <span v-for="msg in setting.error_messages" | ||||
|                         class="error-msg"> | ||||
|                     {{ msg }} | ||||
|                   </span> | ||||
|                 </div> | ||||
| 
 | ||||
|                 <div class="field-row"> | ||||
|                   <label :for="setting.field_name">{{ setting.label }}</label> | ||||
|                   <div class="field"> | ||||
| 
 | ||||
|                     <input v-if="setting.data_type == 'bool'" | ||||
|                            type="checkbox" | ||||
|                            :name="setting.field_name" | ||||
|                            :id="setting.field_name" | ||||
|                            v-model="setting.value" | ||||
|                            value="true" /> | ||||
| 
 | ||||
|                     <b-select v-else-if="setting.choices" | ||||
|                               :name="setting.field_name" | ||||
|                               :id="setting.field_name" | ||||
|                               v-model="setting.value"> | ||||
|                       <option v-for="choice in setting.choices" | ||||
|                               :value="choice"> | ||||
|                         {{ choice }} | ||||
|                       </option> | ||||
|                     </b-select> | ||||
| 
 | ||||
|                     <b-input v-else | ||||
|                              :name="setting.field_name" | ||||
|                              :id="setting.field_name" | ||||
|                              v-model="setting.value" /> | ||||
|                   </div> | ||||
|                 </div> | ||||
| 
 | ||||
|                 <span v-if="setting.helptext" class="instructions"> | ||||
|                   {{ setting.helptext }} | ||||
|                 </span> | ||||
| 
 | ||||
|               </div><!-- field-wrapper --> | ||||
|             </div><!-- card-content --> | ||||
|           </div><!-- card --> | ||||
| 
 | ||||
|           <div class="buttons"> | ||||
|             <b-button type="is-primary" | ||||
|                       native-type="submit" | ||||
|                       :disabled="formSubmitting"> | ||||
|               {{ formButtonText }} | ||||
|             </b-button> | ||||
|             <once-button tag="a" href="${form.cancel_url}" | ||||
|                          text="Cancel"> | ||||
|             </once-button> | ||||
|           </div> | ||||
| 
 | ||||
|         </div><!-- app-wrapper --> | ||||
| 
 | ||||
|         ${h.end_form()} | ||||
|       </div> | ||||
|     </script> | ||||
| 
 | ||||
|     <div id="app-settings-app"> | ||||
|       <app-settings :groups="groups" :showing-group="showingGroup"></app-settings> | ||||
|     </div> | ||||
| 
 | ||||
|     <script type="text/javascript"> | ||||
| 
 | ||||
|       Vue.component('app-settings', { | ||||
|           template: '#app-settings-template', | ||||
|           props: { | ||||
|               groups: Array, | ||||
|               showingGroup: String | ||||
|           }, | ||||
|           data() { | ||||
|               return { | ||||
|                   formSubmitting: false, | ||||
|                   formButtonText: ${json.dumps(getattr(form, 'submit_label', getattr(form, 'save_label', "Submit")))|n}, | ||||
|               } | ||||
|           }, | ||||
|           methods: { | ||||
|               submitForm() { | ||||
|                   this.formSubmitting = true | ||||
|                   this.formButtonText = "Working, please wait..." | ||||
|               } | ||||
|           } | ||||
|       }) | ||||
| 
 | ||||
|       new Vue({ | ||||
|           el: '#app-settings-app', | ||||
|           data() { | ||||
|               return { | ||||
|                   groups: ${json.dumps(buefy_data)|n}, | ||||
|                   showingGroup: ${json.dumps(current_group or '')|n} | ||||
|               } | ||||
|           } | ||||
|       }) | ||||
| 
 | ||||
|     </script> | ||||
| 
 | ||||
| % else: | ||||
| ## legacy / not buefy | ||||
| <div class="form"> | ||||
|   ${h.form(form.action_url, id=dform.formid, method='post', class_='autodisable')} | ||||
|   ${h.csrf_token(request)} | ||||
|  | @ -50,13 +197,6 @@ | |||
|       </div> | ||||
|   % endif | ||||
| 
 | ||||
|   % if use_buefy: | ||||
|   <div id="app-settings-app"> | ||||
|     <app-settings :groups="groups" :showing-group="showingGroup"></app-settings> | ||||
|   </div> | ||||
| 
 | ||||
|   % else: | ||||
|   ## not buefy | ||||
|   <div class="group-picker"> | ||||
|     <div class="field-wrapper"> | ||||
|       <label for="settings-group">Showing Group</label> | ||||
|  | @ -105,122 +245,6 @@ | |||
|     ${h.link_to("Cancel", form.cancel_url, class_='cancel button{}'.format(' autodisable' if form.auto_disable_cancel else ''))} | ||||
|   </div> | ||||
| 
 | ||||
|   ## end of legacy (not buefy) | ||||
|   % endif | ||||
| 
 | ||||
|   ${h.end_form()} | ||||
| </div> | ||||
| 
 | ||||
| % if use_buefy: | ||||
|     <script type="text/x-template" id="app-settings-template"> | ||||
|       <div class="app-wrapper"> | ||||
| 
 | ||||
|         <div class="field-wrapper"> | ||||
|           <label for="settings-group">Showing Group</label> | ||||
|           <b-select @input="showGroup" | ||||
|                     name="settings-group" | ||||
|                     v-model="showingGroup"> | ||||
|             <option value="">(All)</option> | ||||
|             <option v-for="group in groups" | ||||
|                     :key="group.label" | ||||
|                     :value="group.label"> | ||||
|               {{ group.label }} | ||||
|             </option> | ||||
|           </b-select> | ||||
|         </div> | ||||
| 
 | ||||
|         <div v-for="group in groups" | ||||
|              class="card" | ||||
|              v-show="!showingGroup || showingGroup == group.label" | ||||
|              style="margin-bottom: 1rem;"> | ||||
|           <header class="card-header"> | ||||
|             <p class="card-header-title">{{ group.label }}</p> | ||||
|           </header> | ||||
|           <div class="card-content"> | ||||
|             <div v-for="setting in group.settings" | ||||
|                 :class="'field-wrapper' + (setting.error ? ' with-error' : '')"> | ||||
| 
 | ||||
|               <div v-if="setting.error" class="field-error"> | ||||
|                 <span v-for="msg in setting.error_messages" | ||||
|                       class="error-msg"> | ||||
|                   {{ msg }} | ||||
|                 </span> | ||||
|               </div> | ||||
| 
 | ||||
|               <div class="field-row"> | ||||
|                 <label :for="setting.field_name">{{ setting.label }}</label> | ||||
|                 <div class="field"> | ||||
| 
 | ||||
|                   <input v-if="setting.data_type == 'bool'" | ||||
|                          type="checkbox" | ||||
|                          :name="setting.field_name" | ||||
|                          :id="setting.field_name" | ||||
|                          v-model="setting.value" | ||||
|                          value="true" /> | ||||
| 
 | ||||
|                   <b-select v-else-if="setting.choices" | ||||
|                             :name="setting.field_name" | ||||
|                             :id="setting.field_name" | ||||
|                             v-model="setting.value"> | ||||
|                     <option v-for="choice in setting.choices" | ||||
|                             :value="choice"> | ||||
|                       {{ choice }} | ||||
|                     </option> | ||||
|                   </b-select> | ||||
| 
 | ||||
|                   <b-input v-else | ||||
|                            :name="setting.field_name" | ||||
|                            :id="setting.field_name" | ||||
|                            v-model="setting.value" /> | ||||
|                 </div> | ||||
|               </div> | ||||
| 
 | ||||
|               <span v-if="setting.helptext" class="instructions"> | ||||
|                 {{ setting.helptext }} | ||||
|               </span> | ||||
| 
 | ||||
|             </div><!-- field-wrapper --> | ||||
|           </div><!-- card-content --> | ||||
|         </div><!-- card --> | ||||
| 
 | ||||
|         <div class="buttons"> | ||||
|           <once-button type="is-primary" | ||||
|                        native-type="submit" | ||||
|                        text="${getattr(form, 'submit_label', getattr(form, 'save_label', "Submit"))}"> | ||||
|           </once-button> | ||||
|           <once-button tag="a" href="${form.cancel_url}" | ||||
|                        text="Cancel"> | ||||
|           </once-button> | ||||
|         </div> | ||||
| 
 | ||||
|       </div><!-- app-wrapper --> | ||||
|     </script> | ||||
| 
 | ||||
|     <script type="text/javascript"> | ||||
| 
 | ||||
|       Vue.component('app-settings', { | ||||
|           template: '#app-settings-template', | ||||
|           props: { | ||||
|               groups: Array, | ||||
|               showingGroup: String | ||||
|           }, | ||||
|           methods: { | ||||
|               showGroup(group) { | ||||
|                   console.log("SHOWING GROUP") | ||||
|                   console.log(group) | ||||
|               } | ||||
|           } | ||||
|       }) | ||||
| 
 | ||||
|       new Vue({ | ||||
|           el: '#app-settings-app', | ||||
|           data() { | ||||
|               return { | ||||
|                   groups: ${json.dumps(buefy_data)|n}, | ||||
|                   showingGroup: ${json.dumps(current_group or '')|n} | ||||
|               } | ||||
|           } | ||||
|       }) | ||||
| 
 | ||||
|     </script> | ||||
| % endif | ||||
|  |  | |||
|  | @ -75,16 +75,27 @@ | |||
| </%def> | ||||
| 
 | ||||
| <%def name="execute_submit_button()"> | ||||
|   <once-button type="is-primary" | ||||
|                native-type="submit" | ||||
|                % if not execute_enabled: | ||||
|                disabled | ||||
|                % endif | ||||
|                % if why_not_execute: | ||||
|                title="${why_not_execute}" | ||||
|                % endif | ||||
|                text="${execute_title}"> | ||||
|   </once-button> | ||||
|   <b-button type="is-primary" | ||||
|             % if master.has_execution_options(batch): | ||||
|             @click="executeBatch" | ||||
|             % else: | ||||
|             native-type="submit" | ||||
|             % endif | ||||
|             % if not execute_enabled: | ||||
|             disabled | ||||
|             % elif not master.has_execution_options(batch): | ||||
|             :disabled="executeFormSubmitting" | ||||
|             % endif | ||||
|             % if why_not_execute: | ||||
|             title="${why_not_execute}" | ||||
|             % endif | ||||
|             > | ||||
|     % if master.has_execution_options(batch): | ||||
|     ${execute_title} | ||||
|     % else: | ||||
|     {{ executeFormButtonText }} | ||||
|     % endif | ||||
|   </b-button> | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="object_helpers()"> | ||||
|  | @ -131,8 +142,7 @@ | |||
|               <p>Batch has not yet been executed.</p> | ||||
|               % if use_buefy: | ||||
|                   % if master.has_execution_options(batch): | ||||
|                       ## TODO: this doesn't work yet | ||||
|                       ${self.execute_submit_button()} | ||||
|                       <p>TODO: must implement execution with options</p> | ||||
|                   % else: | ||||
|                       <execute-form></execute-form> | ||||
|                   % endif | ||||
|  | @ -180,19 +190,26 @@ | |||
| <%def name="render_this_page_buefy()"> | ||||
|   % if use_buefy and master.handler.executable(batch) and request.has_perm('{}.execute'.format(permission_prefix)): | ||||
|       ## TODO: stop using |n filter | ||||
|       ${execute_form.render_deform(buttons=capture(execute_submit_button))|n} | ||||
|       ${execute_form.render_deform(buttons=capture(execute_submit_button), form_kwargs={'@submit': 'submitExecuteForm'})|n} | ||||
|   % endif | ||||
|   ${parent.render_this_page_buefy()} | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="declare_page_vars()"> | ||||
|   ${parent.declare_page_vars()} | ||||
| <%def name="modify_this_page()"> | ||||
|   ${parent.modify_this_page()} | ||||
|   % if not batch.executed and request.has_perm('{}.execute'.format(permission_prefix)): | ||||
|       <script type="text/javascript"> | ||||
| 
 | ||||
|         let ${execute_form.component_studly} = { | ||||
|             template: '#${execute_form.component}-template', | ||||
|             methods: {} | ||||
|         ${execute_form.component_studly}Data.executeFormButtonText = "${execute_title}" | ||||
|         ${execute_form.component_studly}Data.executeFormSubmitting = false | ||||
| 
 | ||||
|         ${execute_form.component_studly}.methods.executeBatch = function() { | ||||
|             alert("TODO: implement options dialog for batch execution") | ||||
|         } | ||||
| 
 | ||||
|         ${execute_form.component_studly}.methods.submitExecuteForm = function() { | ||||
|             this.executeFormSubmitting = true | ||||
|             this.executeFormButtonText = "Executing, please wait..." | ||||
|         } | ||||
| 
 | ||||
|       </script> | ||||
|  |  | |||
|  | @ -5,12 +5,17 @@ | |||
|   ${parent.grid_tools()} | ||||
| 
 | ||||
|   % if request.has_perm('datasync.restart'): | ||||
|       ${h.form(url('datasync.restart'), name='restart-datasync', class_='autodisable control')} | ||||
|       % if use_buefy: | ||||
|       ${h.form(url('datasync.restart'), name='restart-datasync', class_='control', **{'@submit': 'submitRestartDatasyncForm'})} | ||||
|       % else: | ||||
|       ${h.form(url('datasync.restart'), name='restart-datasync', class_='autodisable')} | ||||
|       % endif | ||||
|       ${h.csrf_token(request)} | ||||
|       % if use_buefy: | ||||
|       <once-button native-type="submit" | ||||
|                    text="Restart DataSync"> | ||||
|       </once-button> | ||||
|       <b-button native-type="submit" | ||||
|                 :disabled="restartDatasyncFormSubmitting"> | ||||
|         {{ restartDatasyncFormButtonText }} | ||||
|       </b-button> | ||||
|       % else: | ||||
|       ${h.submit('submit', "Restart DataSync", data_working_label="Restarting DataSync", class_='button')} | ||||
|       % endif | ||||
|  | @ -18,12 +23,49 @@ | |||
|   % endif | ||||
| 
 | ||||
|   % if allow_filemon_restart and request.has_perm('filemon.restart'): | ||||
|       ${h.form(url('filemon.restart'), name='restart-filemon', class_='autodisable control')} | ||||
|       % if use_buefy: | ||||
|       ${h.form(url('filemon.restart'), name='restart-filemon', class_='control', **{'@submit': 'submitRestartFilemonForm'})} | ||||
|       % else: | ||||
|       ${h.form(url('filemon.restart'), name='restart-filemon', class_='autodisable')} | ||||
|       % endif | ||||
|       ${h.csrf_token(request)} | ||||
|       % if use_buefy: | ||||
|       <b-button native-type="submit" | ||||
|                 :disabled="restartFilemonFormSubmitting"> | ||||
|         {{ restartFilemonFormButtonText }} | ||||
|       </b-button> | ||||
|       % else: | ||||
|       ${h.submit('submit', "Restart FileMon", data_working_label="Restarting FileMon", class_='button')} | ||||
|       % endif | ||||
|       ${h.end_form()} | ||||
|   % endif | ||||
| 
 | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="modify_tailbone_grid()"> | ||||
|   ${parent.modify_tailbone_grid()} | ||||
|   <script type="text/javascript"> | ||||
| 
 | ||||
|     % if request.has_perm('datasync.restart'): | ||||
|         TailboneGridData.restartDatasyncFormSubmitting = false | ||||
|         TailboneGridData.restartDatasyncFormButtonText = "Restart Datasync" | ||||
|         TailboneGrid.methods.submitRestartDatasyncForm = function() { | ||||
|             this.restartDatasyncFormSubmitting = true | ||||
|             this.restartDatasyncFormButtonText = "Restarting Datasync..." | ||||
|         } | ||||
|     % endif | ||||
| 
 | ||||
|     % if allow_filemon_restart and request.has_perm('filemon.restart'): | ||||
|         TailboneGridData.restartFilemonFormSubmitting = false | ||||
|         TailboneGridData.restartFilemonFormButtonText = "Restart Filemon" | ||||
|         TailboneGrid.methods.submitRestartFilemonForm = function() { | ||||
|             this.restartFilemonFormSubmitting = true | ||||
|             this.restartFilemonFormButtonText = "Restarting Filemon..." | ||||
|         } | ||||
|     % endif | ||||
| 
 | ||||
|   </script> | ||||
| </%def> | ||||
| 
 | ||||
| 
 | ||||
| ${parent.body()} | ||||
|  |  | |||
|  | @ -15,15 +15,21 @@ | |||
|   </div> | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="page_content()"> | ||||
|   <div class="form-wrapper"> | ||||
|     % if use_buefy: | ||||
|         ${self.render_buefy_form()} | ||||
|     % else: | ||||
|         ${self.render_form()} | ||||
|     % endif | ||||
|   </div> | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="render_this_page()"> | ||||
|   <div style="display: flex; justify-content: space-between;"> | ||||
| 
 | ||||
|     <div class="form-wrapper"> | ||||
|       % if use_buefy: | ||||
|           ${self.render_buefy_form()} | ||||
|       % else: | ||||
|           ${self.render_form()} | ||||
|       % endif | ||||
|     <div class="this-page-content"> | ||||
|       ${self.page_content()} | ||||
|     </div> | ||||
| 
 | ||||
|     <div style="display: flex; align-items: flex-start;"> | ||||
|  | @ -46,20 +52,6 @@ | |||
|   ${parent.render_this_page_buefy()} | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="declare_page_vars()"> | ||||
|   ${parent.declare_page_vars()} | ||||
|   % if form is not Undefined: | ||||
|       <script type="text/javascript"> | ||||
| 
 | ||||
|         let ${form.component_studly} = { | ||||
|             template: '#${form.component}-template', | ||||
|             methods: {} | ||||
|         } | ||||
| 
 | ||||
|       </script> | ||||
|   % endif | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="finalize_page_components()"> | ||||
|   ${parent.finalize_page_components()} | ||||
|   % if form is not Undefined: | ||||
|  |  | |||
|  | @ -44,10 +44,11 @@ | |||
|       <div class="buttons"> | ||||
|         ## TODO: deprecate / remove the latter option here | ||||
|         % if form.auto_disable_save or form.auto_disable: | ||||
|             <once-button type="is-primary" | ||||
|                          native-type="submit" | ||||
|                          text="${getattr(form, 'submit_label', getattr(form, 'save_label', "Submit"))}"> | ||||
|             </once-button> | ||||
|             <b-button type="is-primary" | ||||
|                       native-type="submit" | ||||
|                       :disabled="${form.component_studly}Submitting"> | ||||
|               {{ ${form.component_studly}ButtonText }} | ||||
|             </b-button> | ||||
|         % else: | ||||
|             <b-button type="is-primary" | ||||
|                       native-type="submit"> | ||||
|  | @ -83,6 +84,20 @@ | |||
| 
 | ||||
| <script type="text/javascript"> | ||||
| 
 | ||||
|   let ${form.component_studly} = { | ||||
|       template: '#${form.component}-template', | ||||
|       methods: { | ||||
| 
 | ||||
|           ## TODO: deprecate / remove the latter option here | ||||
|           % if form.auto_disable_save or form.auto_disable: | ||||
|               submit${form.component_studly}() { | ||||
|                   this.${form.component_studly}Submitting = true | ||||
|                   this.${form.component_studly}ButtonText = "Working, please wait..." | ||||
|               } | ||||
|           % endif | ||||
|       } | ||||
|   } | ||||
| 
 | ||||
|   let ${form.component_studly}Data = { | ||||
| 
 | ||||
|       ## TODO: ugh, this seems pretty hacky.  need to declare some data models | ||||
|  | @ -95,6 +110,12 @@ | |||
|               % endif | ||||
|           % endfor | ||||
|       % endif | ||||
| 
 | ||||
|       ## TODO: deprecate / remove the latter option here | ||||
|       % if form.auto_disable_save or form.auto_disable: | ||||
|           ${form.component_studly}Submitting: false, | ||||
|           ${form.component_studly}ButtonText: ${json.dumps(getattr(form, 'submit_label', getattr(form, 'save_label', "Submit")))|n}, | ||||
|       % endif | ||||
|   } | ||||
| 
 | ||||
| </script> | ||||
|  |  | |||
|  | @ -27,7 +27,11 @@ | |||
|   % endif | ||||
|   <br /> | ||||
| 
 | ||||
|   ${h.form(request.current_route_url(), class_=None if use_buefy else 'autodisable')} | ||||
|   % if use_buefy: | ||||
|   ${h.form(request.current_route_url(), **{'@submit': 'submitForm'})} | ||||
|   % else: | ||||
|   ${h.form(request.current_route_url(), class_='autodisable')} | ||||
|   % endif | ||||
|   ${h.csrf_token(request)} | ||||
|   ${h.hidden('clone', value='clone')} | ||||
|     <div class="buttons"> | ||||
|  | @ -35,10 +39,11 @@ | |||
|           <once-button tag="a" href="${form.cancel_url}" | ||||
|                        text="Whoops, nevermind..."> | ||||
|           </once-button> | ||||
|           <once-button type="is-primary" | ||||
|                        native-type="submit" | ||||
|                        text="Yes, please clone away"> | ||||
|           </once-button> | ||||
|           <b-button type="is-primary" | ||||
|                     native-type="submit" | ||||
|                     :disabled="formSubmitting"> | ||||
|             {{ submitButtonText }} | ||||
|           </b-button> | ||||
|       % else: | ||||
|           ${h.link_to("Whoops, nevermind...", form.cancel_url, class_='button autodisable')} | ||||
|           ${h.submit('submit', "Yes, please clone away")} | ||||
|  | @ -47,5 +52,20 @@ | |||
|   ${h.end_form()} | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="modify_this_page()"> | ||||
|   ${parent.modify_this_page()} | ||||
|   <script type="text/javascript"> | ||||
| 
 | ||||
|     TailboneFormData.formSubmitting = false | ||||
|     TailboneFormData.submitButtonText = "Yes, please clone away" | ||||
| 
 | ||||
|     TailboneForm.methods.submitForm = function() { | ||||
|         this.formSubmitting = true | ||||
|         this.submitButtonText = "Working, please wait..." | ||||
|     } | ||||
| 
 | ||||
|   </script> | ||||
| </%def> | ||||
| 
 | ||||
| 
 | ||||
| ${parent.body()} | ||||
|  |  | |||
|  | @ -44,17 +44,22 @@ | |||
|   % endif | ||||
|   <br /> | ||||
| 
 | ||||
|   ${h.form(request.current_route_url(), class_=None if use_buefy else 'autodisable')} | ||||
|   % if use_buefy: | ||||
|   ${h.form(request.current_route_url(), **{'@submit': 'submitForm'})} | ||||
|   % else: | ||||
|   ${h.form(request.current_route_url(), class_='autodisable')} | ||||
|   % endif | ||||
|   ${h.csrf_token(request)} | ||||
|     <div class="buttons"> | ||||
|       % if use_buefy: | ||||
|           <once-button tag="a" href="${form.cancel_url}" | ||||
|                        text="Whoops, nevermind..."> | ||||
|           </once-button> | ||||
|           <once-button type="is-primary is-danger" | ||||
|                        native-type="submit" | ||||
|                        text="Yes, please DELETE this data forever!"> | ||||
|           </once-button> | ||||
|           <b-button type="is-primary is-danger" | ||||
|                     native-type="submit" | ||||
|                     :disabled="formSubmitting"> | ||||
|             {{ formButtonText }} | ||||
|           </b-button> | ||||
|       % else: | ||||
|       <a class="button" href="${form.cancel_url}">Whoops, nevermind...</a> | ||||
|       ${h.submit('submit', "Yes, please DELETE this data forever!", class_='button is-primary')} | ||||
|  | @ -63,5 +68,20 @@ | |||
|   ${h.end_form()} | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="modify_this_page()"> | ||||
|   ${parent.modify_this_page()} | ||||
|   <script type="text/javascript"> | ||||
| 
 | ||||
|     TailboneFormData.formSubmitting = false | ||||
|     TailboneFormData.formButtonText = "Yes, please DELETE this data forever!" | ||||
| 
 | ||||
|     TailboneForm.methods.submitForm = function() { | ||||
|         this.formSubmitting = true | ||||
|         this.formButtonText = "Working, please wait..." | ||||
|     } | ||||
| 
 | ||||
|   </script> | ||||
| </%def> | ||||
| 
 | ||||
| 
 | ||||
| ${parent.body()} | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| 
 | ||||
| <%def name="extra_javascript()"> | ||||
|   ${parent.extra_javascript()} | ||||
|   % if not use_buefy: | ||||
|   <script type="text/javascript"> | ||||
| 
 | ||||
|     $(function() { | ||||
|  | @ -18,6 +19,7 @@ | |||
| 
 | ||||
|     }); | ||||
|   </script> | ||||
|   % endif | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="context_menu_items()"> | ||||
|  |  | |||
|  | @ -14,9 +14,7 @@ | |||
| 
 | ||||
| <%def name="extra_javascript()"> | ||||
|   ${parent.extra_javascript()} | ||||
|   % if use_buefy: | ||||
|       ${h.javascript_link(request.static_url('tailbone:static/js/tailbone.buefy.grid.js') + '?ver={}'.format(tailbone.__version__))} | ||||
|   % else: | ||||
|   % if not use_buefy: | ||||
|   <script type="text/javascript"> | ||||
|     $(function() { | ||||
| 
 | ||||
|  | @ -148,18 +146,23 @@ | |||
|   ## merge 2 objects | ||||
|   % if master.mergeable and request.has_perm('{}.merge'.format(permission_prefix)): | ||||
| 
 | ||||
|       ${h.form(url('{}.merge'.format(route_prefix)), name='merge-things', class_='control')} | ||||
|       % if use_buefy: | ||||
|       ${h.form(url('{}.merge'.format(route_prefix)), **{'@submit': 'submitMergeForm'})} | ||||
|       % else: | ||||
|       ${h.form(url('{}.merge'.format(route_prefix)), name='merge-things')} | ||||
|       % endif | ||||
|       ${h.csrf_token(request)} | ||||
|       % if use_buefy: | ||||
|           <input type="hidden" | ||||
|                  name="uuids" | ||||
|                  :value="checkedRowUUIDs()" /> | ||||
|           <once-button type="is-primary" | ||||
|                        native-type="submit" | ||||
|                        icon-left="object-ungroup" | ||||
|                        :disabled="checkedRows.length != 2" | ||||
|                        text="Merge 2 ${model_title_plural}"> | ||||
|           </once-button> | ||||
|           <b-button type="is-primary" | ||||
|                     native-type="submit" | ||||
|                     icon-pack="fas" | ||||
|                     icon-left="object-ungroup" | ||||
|                     :disabled="mergeFormSubmitting || checkedRows.length != 2"> | ||||
|             {{ mergeFormButtonText }} | ||||
|           </b-button> | ||||
|       % else: | ||||
|           ${h.hidden('uuids')} | ||||
|           <button type="submit" class="button">Merge 2 ${model_title_plural}</button> | ||||
|  | @ -213,7 +216,17 @@ | |||
| </%def> | ||||
| 
 | ||||
| <%def name="modify_tailbone_grid()"> | ||||
|   ## NOTE: if you override this, must use <script> tags | ||||
|   <script type="text/javascript"> | ||||
| 
 | ||||
|     % if master.mergeable and request.has_perm('{}.merge'.format(permission_prefix)): | ||||
|         TailboneGridData.mergeFormButtonText = "Merge 2 ${model_title_plural}" | ||||
|         TailboneGridData.mergeFormSubmitting = false | ||||
|         TailboneGrid.methods.submitMergeForm = function() { | ||||
|             this.mergeFormSubmitting = true | ||||
|             this.mergeFormButtonText = "Working, please wait..." | ||||
|         } | ||||
|     % endif | ||||
|   </script> | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="make_tailbone_grid_app()"> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| ## -*- coding: utf-8 -*- | ||||
| <%inherit file="/base.mako" /> | ||||
| <%inherit file="/page.mako" /> | ||||
| 
 | ||||
| <%def name="title()">Merge 2 ${model_title_plural}</%def> | ||||
| 
 | ||||
|  | @ -91,62 +91,7 @@ | |||
|   <li>${h.link_to("Back to {}".format(model_title_plural), url(route_prefix))}</li> | ||||
| </%def> | ||||
| 
 | ||||
| 
 | ||||
| % if use_buefy: | ||||
| 
 | ||||
| <script type="text/x-template" id="merge-buttons-template"> | ||||
|   <div class="level" style="margin-top: 2em;"> | ||||
|     <div class="level-left"> | ||||
| 
 | ||||
|       <div class="level-item"> | ||||
|         <a class="button" href="${index_url}">Whoops, nevermind</a> | ||||
|       </div> | ||||
| 
 | ||||
|       <div class="level-item"> | ||||
|         ${h.form(request.current_route_url())} | ||||
|         ${h.csrf_token(request)} | ||||
|         ${h.hidden('uuids', value='{},{}'.format(object_to_keep.uuid, object_to_remove.uuid))} | ||||
|         <once-button native-type="submit" | ||||
|                      text="Swap which ${model_title} is kept/removed" | ||||
|                      working="Swapping"> | ||||
|         </once-button> | ||||
|         ${h.end_form()} | ||||
|       </div> | ||||
| 
 | ||||
|       <div class="level-item"> | ||||
|         ${h.form(request.current_route_url())} | ||||
|         ${h.csrf_token(request)} | ||||
|         ${h.hidden('uuids', value='{},{}'.format(object_to_remove.uuid, object_to_keep.uuid))} | ||||
|         ${h.hidden('commit-merge', value='yes')} | ||||
|         <once-button native-type="submit" | ||||
|                      type="is-primary" | ||||
|                      text="Yes, perform this merge" | ||||
|                      working="Merging"> | ||||
|         </once-button> | ||||
|         ${h.end_form()} | ||||
|       </div> | ||||
| 
 | ||||
|     </div> | ||||
|   </div> | ||||
| </script> | ||||
| 
 | ||||
| <script type="text/javascript"> | ||||
| 
 | ||||
|   const MergeButtons = { | ||||
|       template: '#merge-buttons-template' | ||||
|   } | ||||
| 
 | ||||
|   Vue.component('merge-buttons', MergeButtons) | ||||
| 
 | ||||
| </script> | ||||
| 
 | ||||
| ## end of buefy | ||||
| % endif | ||||
| 
 | ||||
| 
 | ||||
| <ul id="context-menu"> | ||||
|   ${self.context_menu_items()} | ||||
| </ul> | ||||
| <%def name="page_content()"> | ||||
| 
 | ||||
| <p> | ||||
|   You are about to <strong>merge</strong> two ${model_title} records, | ||||
|  | @ -193,16 +138,7 @@ | |||
| </table> | ||||
| 
 | ||||
| % if use_buefy: | ||||
| 
 | ||||
|     <div id="merge-buttons-app"> | ||||
|       <merge-buttons></merge-buttons> | ||||
|     </div> | ||||
| 
 | ||||
|     <script type="text/javascript"> | ||||
|       new Vue({ | ||||
|           el: '#merge-buttons-app' | ||||
|       }) | ||||
|     </script> | ||||
|     <merge-buttons></merge-buttons> | ||||
| 
 | ||||
| % else: | ||||
| ## no buefy; do legacy stuff | ||||
|  | @ -216,3 +152,77 @@ ${h.csrf_token(request)} | |||
| </div> | ||||
| ${h.end_form()} | ||||
| % endif | ||||
| </%def> | ||||
| 
 | ||||
| 
 | ||||
| % if use_buefy: | ||||
| <script type="text/x-template" id="merge-buttons-template"> | ||||
|   <div class="level" style="margin-top: 2em;"> | ||||
|     <div class="level-left"> | ||||
| 
 | ||||
|       <div class="level-item"> | ||||
|         <a class="button" href="${index_url}">Whoops, nevermind</a> | ||||
|       </div> | ||||
| 
 | ||||
|       <div class="level-item"> | ||||
|         ${h.form(request.current_route_url(), **{'@submit': 'submitSwapForm'})} | ||||
|         ${h.csrf_token(request)} | ||||
|         ${h.hidden('uuids', value='{},{}'.format(object_to_keep.uuid, object_to_remove.uuid))} | ||||
|         <b-button native-type="submit" | ||||
|                   :disabled="swapFormSubmitting"> | ||||
|           {{ swapFormButtonText }} | ||||
|         </b-button> | ||||
|         ${h.end_form()} | ||||
|       </div> | ||||
| 
 | ||||
|       <div class="level-item"> | ||||
|         % if use_buefy: | ||||
|         ${h.form(request.current_route_url(), **{'@submit': 'submitMergeForm'})} | ||||
|         % else: | ||||
|         ${h.form(request.current_route_url())} | ||||
|         % endif | ||||
|         ${h.csrf_token(request)} | ||||
|         ${h.hidden('uuids', value='{},{}'.format(object_to_remove.uuid, object_to_keep.uuid))} | ||||
|         ${h.hidden('commit-merge', value='yes')} | ||||
|         <b-button type="is-primary" | ||||
|                   native-type="submit" | ||||
|                   :disabled="mergeFormSubmitting"> | ||||
|           {{ mergeFormButtonText }} | ||||
|         </b-button> | ||||
|         ${h.end_form()} | ||||
|       </div> | ||||
| 
 | ||||
|     </div> | ||||
|   </div> | ||||
| </script> | ||||
| 
 | ||||
| <script type="text/javascript"> | ||||
| 
 | ||||
|   const MergeButtons = { | ||||
|       template: '#merge-buttons-template', | ||||
|       data() { | ||||
|           return { | ||||
|               swapFormButtonText: "Swap which ${model_title} is kept/removed", | ||||
|               swapFormSubmitting: false, | ||||
|               mergeFormButtonText: "Yes, perform this merge", | ||||
|               mergeFormSubmitting: false, | ||||
|           } | ||||
|       }, | ||||
|       methods: { | ||||
|           submitSwapForm() { | ||||
|               this.swapFormSubmitting = true | ||||
|               this.swapFormButtonText = "Swapping, please wait..." | ||||
|           }, | ||||
|           submitMergeForm() { | ||||
|               this.mergeFormSubmitting = true | ||||
|               this.mergeFormButtonText = "Merging, please wait..." | ||||
|           }, | ||||
|       } | ||||
|   } | ||||
| 
 | ||||
|   Vue.component('merge-buttons', MergeButtons) | ||||
| 
 | ||||
| </script> | ||||
| % endif | ||||
| 
 | ||||
| ${parent.body()} | ||||
|  |  | |||
|  | @ -43,6 +43,8 @@ | |||
|         methods: {} | ||||
|     } | ||||
| 
 | ||||
|     let ThisPageData = {} | ||||
| 
 | ||||
|   </script> | ||||
| </%def> | ||||
| 
 | ||||
|  | @ -56,6 +58,8 @@ | |||
|   ${self.finalize_page_components()} | ||||
|   <script type="text/javascript"> | ||||
| 
 | ||||
|     ThisPage.data = function() { return ThisPageData } | ||||
| 
 | ||||
|     Vue.component('this-page', ThisPage) | ||||
| 
 | ||||
|     new Vue({ | ||||
|  |  | |||
|  | @ -82,7 +82,7 @@ ${h.end_form()} | |||
| <script type="text/x-template" id="find-principals-template"> | ||||
|   <div class="app-wrapper"> | ||||
| 
 | ||||
|     ${h.form(request.current_route_url())} | ||||
|     ${h.form(request.current_route_url(), **{'@submit': 'submitForm'})} | ||||
|     ${h.csrf_token(request)} | ||||
| 
 | ||||
|     <div class="field-wrapper"> | ||||
|  | @ -116,10 +116,11 @@ ${h.end_form()} | |||
|     </div> | ||||
| 
 | ||||
|     <div class="buttons"> | ||||
|       <once-button type="is-primary" | ||||
|                    native-type="submit" | ||||
|                    text="Find ${model_title_plural}"> | ||||
|       </once-button> | ||||
|       <b-button type="is-primary" | ||||
|                 native-type="submit" | ||||
|                 :disabled="formSubmitting"> | ||||
|         {{ formButtonText }} | ||||
|       </b-button> | ||||
|     </div> | ||||
| 
 | ||||
|     ${h.end_form()} | ||||
|  | @ -148,12 +149,14 @@ ${h.end_form()} | |||
|               groupPermissions: ${json.dumps(buefy_perms.get(selected_group, {}).get('permissions', []))|n}, | ||||
|               selectedGroup: ${json.dumps(selected_group)|n}, | ||||
|               % if selected_permission: | ||||
|               selectedPermission: ${json.dumps(selected_permission)|n} | ||||
|               selectedPermission: ${json.dumps(selected_permission)|n}, | ||||
|               % elif selected_group in buefy_perms: | ||||
|               selectedPermission: ${json.dumps(buefy_perms[selected_group]['permissions'][0]['permkey'])|n} | ||||
|               selectedPermission: ${json.dumps(buefy_perms[selected_group]['permissions'][0]['permkey'])|n}, | ||||
|               % else: | ||||
|               selectedPermission: null | ||||
|               selectedPermission: null, | ||||
|               % endif | ||||
|               formButtonText: "Find ${model_title_plural}", | ||||
|               formSubmitting: false, | ||||
|           } | ||||
|       }, | ||||
|       methods: { | ||||
|  | @ -163,6 +166,11 @@ ${h.end_form()} | |||
|               // re-populate Permission dropdown, auto-select first option | ||||
|               this.groupPermissions = this.permissionGroups[groupkey].permissions | ||||
|               this.selectedPermission = this.groupPermissions[0].permkey | ||||
|           }, | ||||
| 
 | ||||
|           submitForm() { | ||||
|               this.formSubmitting = true | ||||
|               this.formButtonText = "Working, please wait..." | ||||
|           } | ||||
|       } | ||||
|   }) | ||||
|  |  | |||
|  | @ -21,13 +21,32 @@ | |||
|   % endif | ||||
| </%def> | ||||
| 
 | ||||
| ${parent.body()} | ||||
| <%def name="render_form()"> | ||||
|   ${parent.render_form()} | ||||
|   % if not use_buefy: | ||||
|       ${h.form(url('email.preview'), name='send-email-preview', class_='autodisable')} | ||||
|         ${h.csrf_token(request)} | ||||
|         ${h.hidden('email_key', value=instance['key'])} | ||||
|         ${h.link_to("Preview HTML", '{}?key={}&type=html'.format(url('email.preview'), instance['key']), id='preview-html', class_='button', target='_blank')} | ||||
|         ${h.link_to("Preview TXT", '{}?key={}&type=txt'.format(url('email.preview'), instance['key']), id='preview-txt', class_='button', target='_blank')} | ||||
|         or | ||||
|         ${h.text('recipient', value=request.user.email_address or '')} | ||||
|         ${h.submit('send_{}'.format(instance['key']), value="Send Preview Email")} | ||||
|       ${h.end_form()} | ||||
|   % endif | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="render_buefy_form()"> | ||||
|   ${parent.render_buefy_form()} | ||||
|   <email-preview-tools></email-preview-tools> | ||||
| </%def> | ||||
| 
 | ||||
| 
 | ||||
| % if use_buefy: | ||||
| 
 | ||||
|     <script type="text/x-template" id="email-preview-tools-template"> | ||||
| 
 | ||||
|     ${h.form(url('email.preview'))} | ||||
|     ${h.form(url('email.preview'), **{'@submit': 'submitPreviewForm'})} | ||||
|       ${h.csrf_token(request)} | ||||
|       ${h.hidden('email_key', value=instance['key'])} | ||||
| 
 | ||||
|  | @ -76,10 +95,11 @@ ${parent.body()} | |||
|         </div> | ||||
| 
 | ||||
|         <div class="control"> | ||||
|           <once-button type="is-primary" | ||||
|                        native-type="submit" | ||||
|                        text="Send Preview Email"> | ||||
|           </once-button> | ||||
|           <b-button type="is-primary" | ||||
|                     native-type="submit" | ||||
|                     :disabled="previewFormSubmitting"> | ||||
|             {{ previewFormButtonText }} | ||||
|           </b-button> | ||||
|         </div> | ||||
| 
 | ||||
|       </div><!-- field --> | ||||
|  | @ -90,36 +110,25 @@ ${parent.body()} | |||
|     <script type="text/javascript"> | ||||
| 
 | ||||
|       const EmailPreviewTools = { | ||||
|           template: '#email-preview-tools-template' | ||||
|           template: '#email-preview-tools-template', | ||||
|           data() { | ||||
|               return { | ||||
|                   previewFormButtonText: "Send Preview Email", | ||||
|                   previewFormSubmitting: false, | ||||
|               } | ||||
|           }, | ||||
|           methods: { | ||||
|               submitPreviewForm() { | ||||
|                   this.previewFormSubmitting = true | ||||
|                   this.previewFormButtonText = "Working, please wait..." | ||||
|               } | ||||
|           } | ||||
|       } | ||||
| 
 | ||||
|       Vue.component('email-preview-tools', EmailPreviewTools) | ||||
| 
 | ||||
|     </script> | ||||
| 
 | ||||
|     <div id="email-preview-tools-app"> | ||||
|       <email-preview-tools></email-preview-tools> | ||||
|     </div> | ||||
| 
 | ||||
|     <script type="text/javascript"> | ||||
| 
 | ||||
|       new Vue({ | ||||
|           el: '#email-preview-tools-app' | ||||
|       }) | ||||
| 
 | ||||
|     </script> | ||||
| 
 | ||||
| % else: | ||||
|     ## not buefy; do traditional thing | ||||
| 
 | ||||
|     ${h.form(url('email.preview'), name='send-email-preview', class_='autodisable')} | ||||
|       ${h.csrf_token(request)} | ||||
|       ${h.hidden('email_key', value=instance['key'])} | ||||
|       ${h.link_to("Preview HTML", '{}?key={}&type=html'.format(url('email.preview'), instance['key']), id='preview-html', class_='button', target='_blank')} | ||||
|       ${h.link_to("Preview TXT", '{}?key={}&type=txt'.format(url('email.preview'), instance['key']), id='preview-txt', class_='button', target='_blank')} | ||||
|       or | ||||
|       ${h.text('recipient', value=request.user.email_address or '')} | ||||
|       ${h.submit('send_{}'.format(instance['key']), value="Send Preview Email")} | ||||
|     ${h.end_form()} | ||||
| 
 | ||||
| % endif | ||||
| 
 | ||||
| ${parent.body()} | ||||
|  |  | |||
|  | @ -147,6 +147,7 @@ | |||
| </%def> | ||||
| 
 | ||||
| <%def name="modify_this_page()"> | ||||
|   ${parent.modify_this_page()} | ||||
|   <script type="text/javascript"> | ||||
| 
 | ||||
|     ThisPage.data = function() { return { | ||||
|  |  | |||
|  | @ -42,13 +42,18 @@ | |||
|   % if not instance.executed and instance.status_code == enum.UPGRADE_STATUS_PENDING and request.has_perm('{}.execute'.format(permission_prefix)): | ||||
|       <div class="buttons"> | ||||
|         % if instance.enabled and not instance.executing: | ||||
|             % if use_buefy: | ||||
|             ${h.form(url('{}.execute'.format(route_prefix), uuid=instance.uuid), **{'@submit': 'submitForm'})} | ||||
|             % else: | ||||
|             ${h.form(url('{}.execute'.format(route_prefix), uuid=instance.uuid), class_='autodisable')} | ||||
|             % endif | ||||
|             ${h.csrf_token(request)} | ||||
|             % if use_buefy: | ||||
|                 <once-button type="is-primary" | ||||
|                              native-type="submit" | ||||
|                              text="Execute this upgrade"> | ||||
|                 </once-button> | ||||
|                 <b-button type="is-primary" | ||||
|                           native-type="submit" | ||||
|                           :disabled="formSubmitting"> | ||||
|                   {{ formButtonText }} | ||||
|                 </b-button> | ||||
|             % else: | ||||
|                 ${h.submit('execute', "Execute this upgrade", class_='button is-primary')} | ||||
|             % endif | ||||
|  | @ -62,11 +67,20 @@ | |||
|   % endif | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="modify_tailbone_form()"> | ||||
| <%def name="modify_this_page()"> | ||||
|   ${parent.modify_this_page()} | ||||
|   <script type="text/javascript"> | ||||
| 
 | ||||
|     TailboneFormData.showingPackages = 'diffs' | ||||
| 
 | ||||
|     TailboneFormData.formButtonText = "Execute this upgrade" | ||||
|     TailboneFormData.formSubmitting = false | ||||
| 
 | ||||
|     TailboneForm.methods.submitForm = function() { | ||||
|         this.formSubmitting = true | ||||
|         this.formButtonText = "Working, please wait..." | ||||
|     } | ||||
| 
 | ||||
|   </script> | ||||
| </%def> | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar