[Bps-public-commit] rt-extension-formtools branch readonly-ui created. 1.01-8-ga37218e

BPS Git Server git at git.bestpractical.com
Fri Jan 26 21:25:22 UTC 2024


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt-extension-formtools".

The branch, readonly-ui has been created
        at  a37218e0d106f4bef9200ad092d6fd004f9f7da6 (commit)

- Log -----------------------------------------------------------------
commit a37218e0d106f4bef9200ad092d6fd004f9f7da6
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jan 25 11:49:05 2024 -0500

    Readonly values should not get default values from clients

diff --git a/html/FormTools/Field b/html/FormTools/Field
index 46bf062..60a3c5b 100644
--- a/html/FormTools/Field
+++ b/html/FormTools/Field
@@ -95,12 +95,16 @@ if ( RT::Extension::FormTools::is_core_field($name) ) {
 }
 
 my $request_args = $m->request_args();
-if ( $field_type eq 'core' && exists $request_args->{$name} ) {
-    $default = $request_args->{$name};
-} elsif ( $field_type eq 'custom' && $cf->Id &&
-        ( exists $request_args->{ $input_name } ) ) {
-    $default = ($request_args->{ $input_name } ||
-                $request_args->{ $input_name .'s' } );
+
+if ( $render_as !~ /readonly/ ) {
+    my $request_args = $m->request_args();
+
+    if ( $field_type eq 'core' && exists $request_args->{$name} ) {
+        $default = $request_args->{$name};
+    }
+    elsif ( $field_type eq 'custom' && $cf->Id && ( exists $request_args->{$input_name} ) ) {
+        $default = ( $request_args->{$input_name} || $request_args->{ $input_name . 's' } );
+    }
 }
 
 $default = '' unless defined $default;

commit 6a97ce3fae8ae52717f86baa0a18e68e1e7ad5d0
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jan 25 11:46:37 2024 -0500

    Show global/queue level default values for readonly cfs

diff --git a/html/FormTools/Field b/html/FormTools/Field
index 0ff88db..46bf062 100644
--- a/html/FormTools/Field
+++ b/html/FormTools/Field
@@ -70,6 +70,24 @@ if ( RT::Extension::FormTools::is_core_field($name) ) {
         $default = [ split /\r?\n/, $default ];
     }
 
+    if ( !( defined $default && length $default ) && $cf->SupportDefaultValues ) {
+        if ( defined( my $default_values = $cf->DefaultValues( Object => $queue ) ) ) {
+            $default = $default_values;
+        }
+    }
+
+    # for readonly, @values is used to render multiple value inputs.
+    if ( $render_as =~ /readonly/ ) {
+        if ( ref $default eq 'ARRAY' ) {
+            if ( @$default > 1 ) {
+                @values = @$default;
+            }
+            else {
+                $default = $default->[0];
+            }
+        }
+    }
+
     $input_name = GetCustomFieldInputName(
         Object      => $ticket,
         CustomField => $cf,

commit b501049d7dcff1705fa11c483dfb5c6f2407f548
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jan 25 11:44:56 2024 -0500

    Support readonly fields on admin UI
    
    The only exception is "Content", which requires extra work to render the
    readonly value. Another reason not supporting it is it doesn't make much
    sense to have a static Content input. In case it's really needed, admins can
    create HTML + hidden fields to mimic the readonly behavior.

diff --git a/html/Admin/FormTools/Modify.html b/html/Admin/FormTools/Modify.html
index fef2402..050d476 100644
--- a/html/Admin/FormTools/Modify.html
+++ b/html/Admin/FormTools/Modify.html
@@ -130,6 +130,16 @@
                       </label>
                     </div>
                   </&>
+%               if ( $item ne 'Content' ) {
+                  <&| /Elements/LabeledValue, Label => '' &>
+                    <div class="custom-control custom-checkbox">
+                      <input class="custom-control-input" id="<% CSSClass($item) %>-readonly" type="checkbox" name="readonly" value="1" />
+                      <label class="custom-control-label" for="<% CSSClass($item) %>-readonly">
+                        <&|/l&>Readonly</&>
+                      </label>
+                    </div>
+                  </&>
+%               }
                 </div>
                 <div class="modal-footer">
                   <button type="submit" class="btn btn-primary button form-control"><% loc('Update') %></button>
@@ -230,6 +240,14 @@
                       </label>
                     </div>
                   </&>
+                  <&| /Elements/LabeledValue, Label => '' &>
+                    <div class="custom-control custom-checkbox">
+                      <input class="custom-control-input" id="<% CSSClass($item) %>-readonly" type="checkbox" name="readonly" value="1" />
+                      <label class="custom-control-label" for="<% CSSClass($item) %>-readonly">
+                        <&|/l&>Readonly</&>
+                      </label>
+                    </div>
+                  </&>
                 </div>
                 <div class="modal-footer">
                   <button type="submit" class="btn btn-primary button form-control"><% loc('Update') %></button>
@@ -511,6 +529,16 @@
                           </label>
                         </div>
                       </&>
+%                     if ( $item->{arguments}{name} ne 'Content' ) {
+                        <&| /Elements/LabeledValue, Label => '' &>
+                          <div class="custom-control custom-checkbox">
+                            <input class="custom-control-input" id="formtools-element-<% $form_page_id{$page_name} %>-<% $i %>-readonly" type="checkbox" name="readonly" value="1" <% ( $item->{arguments}{render_as} // '' ) =~ /readonly/ ? q{checked="checked"} : '' |n %> />
+                            <label class="custom-control-label" for="formtools-element-<% $form_page_id{$page_name} %>-<% $i %>-readonly">
+                              <&|/l&>Readonly</&>
+                            </label>
+                          </div>
+                        </&>
+%                     }
 %                   } elsif ( $item->{type} eq 'hidden' ) {
                       <&| /Elements/LabeledValue, Label => loc('Name') &>
                         <input name="name" type="text" class="form-control" value="<% $item->{'input-name'} // ''  %>" />
diff --git a/static/js/rt-extension-formtools.js b/static/js/rt-extension-formtools.js
index 285b2a0..bb6c6b6 100644
--- a/static/js/rt-extension-formtools.js
+++ b/static/js/rt-extension-formtools.js
@@ -215,6 +215,16 @@ formTools = {
                     delete value.arguments.render_as;
                 }
             }
+
+            const readonly = form.find(':input[name=readonly]');
+            if ( readonly.length ) {
+                if ( readonly.is(':checked') ) {
+                    value.arguments.render_as = 'readonly_plus_values';
+                }
+                else if ( value.arguments.render_as === 'readonly_plus_values' ) {
+                    delete value.arguments.render_as;
+                }
+            }
         }
         else if ( value.type === 'hidden' ) {
             value['input-name'] = form.find(':input[name=name]').val();

commit 1fb5dbe72b6eba6a7edeab94880f1ba99911e32f
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jan 25 10:30:21 2024 -0500

    Tweak the default value input
    
    Previously it was a plain text input for all the fields, this commit
    tweaks it to use textarea for core Content and HTML custom fields. For all
    the other custom fields, it calls the standard EditCustomField to render
    different inputs based on the custom field type.
    
    With this change, now we can support multiple default values.
    
    For combo/autocomplete custom fields, some enhanced js is not functioning
    right after these fields are added(via dragging&dropping) right now.
    Datepicker's position behaves weirdly in modal, so it's been disabled
    intentionally. Note that this doesn't prevent users from setting default
    values and it's not worse than previous plain text inputs anyway, so it's ok
    to call EditCustomField consistently for these types.

diff --git a/html/Admin/FormTools/Modify.html b/html/Admin/FormTools/Modify.html
index 9089a35..fef2402 100644
--- a/html/Admin/FormTools/Modify.html
+++ b/html/Admin/FormTools/Modify.html
@@ -103,7 +103,11 @@
                   </&>
 %               }
                   <&| /Elements/LabeledValue, Label => loc('Default Value') &>
-                    <input name="default" type="text" class="form-control" placeholder="<% $default_values{$item} %>" value="" />
+%                   if ( $item eq 'Content' ) {
+                      <textarea name="default" type="text" rows="5" class="form-control" placeholder="<% $default_values{$item} %>"></textarea>
+%                   } else {
+                      <input name="default" type="text" class="form-control" placeholder="<% $default_values{$item} %>" value="" />
+%                   }
                   </&>
 %               if ( $item ne 'Content' ) {
                   <&| /Elements/LabeledValue, Label => loc('Tooltip') &>
@@ -164,9 +168,18 @@
                   <&| /Elements/LabeledValue, Label => loc('Label') &>
                     <input name="label" type="text" class="form-control" placeholder="<% $item %>" value="" />
                   </&>
+
+%               if ( $cf_obj{$item}->SupportDefaultValues ) {
                   <&| /Elements/LabeledValue, Label => loc('Default Value') &>
-                    <input name="default" type="text" class="form-control" placeholder="<% $default_values{$item} %>" value="" />
+%                 if ( $cf_obj{$item}->Type eq 'HTML' ) {
+                    <textarea name="default" type="text" rows="5" class="form-control" placeholder="<% $default_values{$item} %>"></textarea>
+%                 } else {
+                    <& /Elements/EditCustomField, NamePrefix => 'template-' . GetCustomFieldInputName(Object => $queue, CustomField => $cf_obj{$item}), Object => $queue, CustomField => $cf_obj{$item}, Default => $default_values{$item} &>
+
+%                 }
                   </&>
+%               }
+
                   <&| /Elements/LabeledValue, Label => loc('Tooltip') &>
                     <input name="tooltip" type="text" class="form-control" placeholder="<% $tooltips{$item} // '' %>" value="" />
                   </&>
@@ -424,9 +437,25 @@
                         <input name="label" type="text" class="form-control" placeholder="<% $item->{arguments}{name} %>" value="<% $item->{arguments}{label} // ''  %>" />
                       </&>
 %                     }
-                      <&| /Elements/LabeledValue, Label => loc('Default Value') &>
-                        <input name="default" type="text" class="form-control" placeholder="<% $default_values{$item->{arguments}{name}} %>" value="<% $item->{arguments}{default} // '' %>" />
-                      </&>
+
+%                     if ( RT::Extension::FormTools::is_core_field($item->{arguments}{name}) ) {
+                        <&| /Elements/LabeledValue, Label => loc('Default Value') &>
+%                         if ( $item->{arguments}{name} eq 'Content' ) {
+                            <textarea name="default" type="text" class="form-control" rows="5" placeholder="<% $default_values{$item->{arguments}{name}} %>"><% $item->{arguments}{default} // '' %></textarea>
+%                         } else {
+                            <input name="default" type="text" class="form-control" placeholder="<% $default_values{$item->{arguments}{name}} %>" value="<% $item->{arguments}{default} // '' %>" />
+%                         }
+                        </&>
+%                     } elsif ( $cf_obj{$item->{arguments}{name}} && $cf_obj{$item->{arguments}{name}}->SupportDefaultValues ) {
+                        <&| /Elements/LabeledValue, Label => loc('Default Value') &>
+%                       if ( $cf_obj{$item->{arguments}{name}}->Type eq 'HTML' ) {
+                          <textarea name="default" type="text" class="form-control" rows="5" placeholder="<% $default_values{$item->{arguments}{name}} %>"><% $item->{arguments}{default} // '' %></textarea>
+%                       } else {
+                          <& /Elements/EditCustomField, Object => $queue, CustomField => $cf_obj{$item->{arguments}{name}}, Default => $item->{arguments}{default} // $default_values{$item->{arguments}{name}} &>
+%                       }
+                        </&>
+%                     }
+
 %                     if ( $item->{arguments}{name} ne 'Content' ) {
                       <&| /Elements/LabeledValue, Label => loc('Tooltip') &>
                         <input name="tooltip" type="text" class="form-control" placeholder="<% $tooltips{$item->{arguments}{name}} // '' %>" value="<% $item->{arguments}{tooltip} // '' %>" />
@@ -569,6 +598,17 @@ jQuery(function() {
         select.change();
         select.selectpicker('refresh');
     });
+
+    // Cloned selectpicker stuff doesn't work, here we destroy selectpicker
+    // from component list and re-initialize them when adding to form.
+    jQuery('.formtools-component-menu select.selectpicker').each(function () {
+        jQuery(this).selectpicker('destroy');
+    });
+
+    // Datepicker's position is weird in modal, here we disable it to not confuse people.
+    jQuery(':input.hasDatepicker').each(function () {
+        jQuery(this).off('focus');
+    });
 });
 </script>
 <%INIT>
@@ -677,12 +717,14 @@ my @custom_fields;
 my %default_values;
 my %tooltips;
 my %dependent_custom_fields;
+my %cf_obj;
 
 while ( my $cf = $cfs->Next ) {
     push @custom_fields, $cf->Name;
+    $cf_obj{$cf->Name} = $cf;
     if ( $cf->SupportDefaultValues ) {
         if ( defined( my $default_values = $cf->DefaultValues(Object => $queue) ) ) {
-            $default_values{$cf->Name} = ref $default_values eq 'ARRAY' ? join(', ', @$default_values) : $default_values;
+            $default_values{$cf->Name} = $default_values;
         }
     }
     $tooltips{$cf->Name} = $cf->EntryHint // '';
diff --git a/html/FormTools/Field b/html/FormTools/Field
index eea7abc..0ff88db 100644
--- a/html/FormTools/Field
+++ b/html/FormTools/Field
@@ -63,7 +63,11 @@ if ( RT::Extension::FormTools::is_core_field($name) ) {
 
     if ($ticket) {
         @values = map { $_->Content } @{ $cf->ValuesForObject($ticket)->ItemsArrayRef };
-        $default ||= $values[0];
+        $default ||= @values > 1 ? \@values : $values[0];
+    }
+
+    if ( $default && !ref $default && $cf->MaxValues != 1 ) {
+        $default = [ split /\r?\n/, $default ];
     }
 
     $input_name = GetCustomFieldInputName(
@@ -119,6 +123,15 @@ $default = '' unless defined $default;
     data-validation="<% $ARGS{validation} %>"
 % }
 >
+
+% if ( $default && RT->Config->Get('MessageBoxRichText',  $session{'CurrentUser'}) && $default !~ /<.{1,5}>/ ) {
+%   $default =~ s/&/&/g;
+%   $default =~ s/</</g;
+%   $default =~ s/>/>/g;
+%   $default =~ s/"/"/g;
+%   $default =~ s/'/'/g;
+%   $default =~ s{\n}{<br />}g;
+% }
 <& /Elements/MessageBox,
     Name => $name,
     ($rows ? (Height => $rows) : ()),
diff --git a/static/js/rt-extension-formtools.js b/static/js/rt-extension-formtools.js
index 93411dc..285b2a0 100644
--- a/static/js/rt-extension-formtools.js
+++ b/static/js/rt-extension-formtools.js
@@ -68,13 +68,22 @@ formTools = {
             modal_copy.find('form.formtools-element-form').on('submit', formTools.elementSubmit);
             modal_copy.modal('show');
             modal_copy.attr('ondragenter', 'formTools.dragenter(event);');
-            modal_copy.find('select').selectpicker(); // initialize selectpicker after cloneNode to make it work
-            modal_copy.find('.custom-checkbox').each(function() {
+
+            modal_copy.find(':input[name^="template-"]').each(function() {
+                const input = jQuery(this);
+                input.attr('name', input.attr('name').replace(/^template-/, ''));
+            });
+            modal_copy.find('select:not(.combobox)').selectpicker();
+
+            modal_copy.find('.custom-checkbox, .custom-radio').each(function() {
                 const input = jQuery(this).find('input');
                 const label = jQuery(this).find('label');
-                label.attr('for', source_copy.id + input.attr('name'));
-                input.attr('id', source_copy.id + input.attr('name'));
+                label.attr('for', source_copy.id + label.attr('for').replace(/^template-/, ''));
+                input.attr('id', source_copy.id + input.attr('id').replace(/^template-/, ''));
             });
+
+            // combobox dropdown icon doesn't work after drag&drop, hide it for now
+            modal_copy.find('.combobox-container .input-group-append').hide();
         }
         formTools.submit();
     },
@@ -120,9 +129,35 @@ formTools = {
                 delete value.arguments.label;
             }
 
-            const default_value = form.find(':input[name=default]').val();
+            let default_value;
+            form.find(':input[name^="Object-"][name*="-CustomField-"]:not([name$="-Magic"])').each(function() {
+                const input = jQuery(this);
+                if ( input.is('[type=radio], [type=checkbox]') ) {
+                    if ( input.is(':checked') ) {
+                        if ( default_value ) {
+                            if ( !Array.isArray(default_value) ) {
+                                default_value = [default_value];
+                            }
+                            default_value.push(input.val());
+                        }
+                        else {
+                            default_value = input.val();
+                        }
+                    }
+                }
+                else {
+                    default_value = input.val();
+                }
+            });
+
+            if ( !default_value ) {
+                const default_input = form.find(':input[name=default]');
+                if ( default_input ) {
+                    default_value = default_input.val();
+                }
+            }
 
-            if ( default_value.length ) {
+            if ( default_value && default_value.length ) {
                 value.arguments.default = default_value;
             }
             else {

-----------------------------------------------------------------------


hooks/post-receive
-- 
rt-extension-formtools


More information about the Bps-public-commit mailing list