[Rt-commit] rt branch, 4.0/custom-fields-groups, updated. rt-4.0.4-237-g327e043

Ruslan Zakirov ruz at bestpractical.com
Mon Oct 1 15:14:02 EDT 2012


The branch, 4.0/custom-fields-groups has been updated
       via  327e043ed97e36a43c81b61ae4fbcc69e0c9fb04 (commit)
       via  b88261cda07c915f807990218f88e91bfdfbf2d2 (commit)
       via  3bf09713d4f82db5c6b98ceed6596060a784ef85 (commit)
       via  923d8dacee22db0077f2f00a5d2bea45aaa4d9bf (commit)
       via  513ccdaf57fc0f4ba076c673bf8c4725cf8de6bb (commit)
      from  7b82f5c85db5081b944e32d8800e34ea7d265130 (commit)

Summary of changes:
 etc/RT_Config.pm.in                             |   6 ++
 lib/RT/CustomField.pm                           |   1 +
 lib/RT/CustomFields.pm                          |   6 +-
 share/html/Admin/Users/Modify.html              |  42 ++++-----
 share/html/Elements/EditCustomFieldCustomGroups |  19 ++++
 share/html/Elements/EditCustomFields            |  64 +++++++++++++
 share/html/Elements/ShowCustomFields            |   2 +-
 share/html/Ticket/Create.html                   |  47 +++++++---
 share/html/Ticket/Elements/EditCustomFields     |  69 ++------------
 share/html/Ticket/Elements/EditDates            |   2 +-
 share/html/Ticket/Elements/EditPeople           |   2 +-
 share/html/Ticket/Modify.html                   |  12 +--
 share/html/Ticket/ModifyAll.html                |  12 +--
 t/web/cf_groups_users.t                         | 118 ++++++++++++++++++++++++
 14 files changed, 283 insertions(+), 119 deletions(-)
 create mode 100644 share/html/Elements/EditCustomFieldCustomGroups
 create mode 100644 share/html/Elements/EditCustomFields
 create mode 100644 t/web/cf_groups_users.t

- Log -----------------------------------------------------------------
commit 513ccdaf57fc0f4ba076c673bf8c4725cf8de6bb
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Sep 27 22:33:58 2012 +0400

    add generic /Elements/EditCustomFields

diff --git a/share/html/Elements/EditCustomFields b/share/html/Elements/EditCustomFields
new file mode 100644
index 0000000..a33ac86
--- /dev/null
+++ b/share/html/Elements/EditCustomFields
@@ -0,0 +1,64 @@
+% if ( $WRAP ) {
+<<% $WRAP %> class="edit-custom-fields">
+% }
+% while ( my $CustomField = $CustomFields->Next ) {
+% next unless $CustomField->CurrentUserHasRight('ModifyCustomField');
+% my $Type = $CustomField->Type || 'Unknown';
+
+  <<% $FIELD %> class="edit-custom-field cftype-<% $Type %>">
+    <<% $CELL %> class="cflabel">
+      <span class="name"><% loc($CustomField->Name) %></span><br />
+      <span class="type"><% $CustomField->FriendlyType %></span>
+    </<% $CELL %>>
+    <<% $CELL %> class="entry">
+% my $default = $m->notes('Field-' . $CustomField->Id);
+% $default ||= $ARGS{"CustomField-". $CustomField->Id };
+      <& /Elements/EditCustomField,
+          %ARGS,
+          CustomField => $CustomField,
+          NamePrefix => $NamePrefix,
+          Default => $default,
+      &>
+%  if (my $msg = $m->notes('InvalidField-' . $CustomField->Id)) {
+        <br />
+        <span class="cfinvalidfield"><% $msg %></span>
+%  }
+    </<% $CELL %>>
+  </<% $FIELD %>>
+% }
+
+% if ( $WRAP ) {
+</<% $WRAP %>>
+% }
+% $m->callback( %ARGS, CallbackName => 'AfterCustomFields' );
+<%INIT>
+$NamePrefix   ||= join '-', 'Object', ref($Object), ($Object->Id || ''), 'CustomField', '';
+$CustomFields ||= $Object->CustomFields;
+
+$CustomFields->LimitToGroup( $Group  ) if defined $Group;
+
+$m->callback( %ARGS, CallbackName => 'MassageCustomFields', $CustomFields => $CustomFields );
+
+# don't print anything if there is no custom fields
+return unless $CustomFields->First;
+$CustomFields->GotoFirstItem;
+
+$AsTable ||= $InTable;
+my $FIELD = $AsTable ? 'tr' : 'div';
+my $CELL  = $AsTable ? 'td' : 'div';
+my $WRAP  = '';
+if ( $AsTable ) {
+    $WRAP = 'table' unless $InTable;
+} else {
+    $WRAP = 'div';
+}
+
+</%INIT>
+<%ARGS>
+$Object
+$CustomFields => undef
+$NamePrefix   => ''
+$Group        => undef
+$AsTable => 1
+$InTable => 0
+</%ARGS>
diff --git a/share/html/Ticket/Elements/EditCustomFields b/share/html/Ticket/Elements/EditCustomFields
index 742df6f..563d56b 100755
--- a/share/html/Ticket/Elements/EditCustomFields
+++ b/share/html/Ticket/Elements/EditCustomFields
@@ -45,77 +45,24 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-% $m->callback( %ARGS, CallbackName => 'BeforeCustomFields' );
-% if ( $WRAP ) {
-<<% $WRAP %> class="edit-custom-fields">
-% }
-% while ( my $CustomField = $CustomFields->Next ) {
-% next unless $CustomField->CurrentUserHasRight('ModifyCustomField');
-% my $Type = $CustomField->Type || 'Unknown';
-  <<% $FIELD %> class="edit-custom-field cftype-<% $Type %>">
-    <<% $CELL %> class="cflabel">
-      <span class="name"><% loc($CustomField->Name) %></span><br />
-      <span class="type"><% $CustomField->FriendlyType %></span>
-    </<% $CELL %>>
-    <<% $CELL %> class="entry">
-% my $default = $m->notes('Field-' . $CustomField->Id);
-% $default ||= $ARGS{"CustomField-". $CustomField->Id };
-      <& /Elements/EditCustomField, 
-          %ARGS,
-          Object => $TicketObj,
-          CustomField => $CustomField,
-          NamePrefix => $NamePrefix,
-          Default => $default,
-      &>
-%  if (my $msg = $m->notes('InvalidField-' . $CustomField->Id)) {
-        <br />
-        <span class="cfinvalidfield"><% $msg %></span>
-%  }
-    </<% $CELL %>>
-  </<% $FIELD %>>
-% }
-
-% if ( $WRAP ) {
-</<% $WRAP %>>
-% }
-% $m->callback( %ARGS, CallbackName => 'AfterCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj );
 <%INIT>
 my $CustomFields;
-
 if ($TicketObj && !$OnCreate) {
-    $CustomFields = $TicketObj->CustomFields();
-    $NamePrefix .= "Object-RT::Ticket-".$TicketObj->Id."-CustomField-";
+    $CustomFields = $TicketObj->CustomFields;
 } else {
-    $CustomFields = $QueueObj->TicketCustomFields();
-    $NamePrefix .= "Object-RT::Ticket--CustomField-";
+    $CustomFields = $QueueObj->TicketCustomFields;
 }
-
-$CustomFields->LimitToGroup( $Group ) if defined $Group;
-
 $m->callback( %ARGS, CallbackName => 'MassageCustomFields', CustomFields => $CustomFields );
 
-# don't print anything if there is no custom fields
-return unless $CustomFields->First;
-$CustomFields->GotoFirstItem;
-
-$AsTable ||= $InTable;
-my $FIELD = $AsTable ? 'tr' : 'div';
-my $CELL  = $AsTable ? 'td' : 'div';
-my $WRAP  = '';
-if ( $AsTable ) {
-    $WRAP = 'table' unless $InTable;
-} else {
-    $WRAP = 'div';
-}
+return $m->comp('/Elements/EditCustomFields',
+    %ARGS,
+    Object => $TicketObj || RT::Ticket->new( $session{'CurrenUser'} ),
+    CustomFields => $CustomFields,
+);
 
 </%INIT>
 <%ARGS>
-$NamePrefix => ''
 $TicketObj => undef
 $QueueObj => undef
 $OnCreate => undef
-$Group => undef
-$DefaultsFromTopArguments => 1
-$AsTable => 0
-$InTable => 0
 </%ARGS>

commit 923d8dacee22db0077f2f00a5d2bea45aaa4d9bf
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Sep 28 00:13:45 2012 +0400

    /Elements/EditCustomFieldCustomGroups
    
    Renders boxes with custom custom field's groups.

diff --git a/share/html/Elements/EditCustomFieldCustomGroups b/share/html/Elements/EditCustomFieldCustomGroups
new file mode 100644
index 0000000..17b1b44
--- /dev/null
+++ b/share/html/Elements/EditCustomFieldCustomGroups
@@ -0,0 +1,19 @@
+% foreach my $group ( RT::CustomField->CustomGroups( $Object ), '' ) {
+<&| /Widgets/TitleBox,
+    title => $group? loc($group) : loc('Custom Fields'),
+    class => $css_class .' '. ($group? CSSClass("$css_class-$group") : ''),
+    hide_empty => 1,
+&>
+<& EditCustomFields, %ARGS, Object => $Object, Group => $group &>
+</&>
+% }
+<%ARGS>
+$Object
+</%ARGS>
+<%INIT>
+my $css_class = lc(ref($Object)||$Object);
+$css_class =~ s/^rt:://;
+$css_class =~ s/::/-/g;
+$css_class = CSSClass($css_class);
+$css_class .= '-info-cfs';
+</%INIT>
\ No newline at end of file
diff --git a/share/html/Ticket/Create.html b/share/html/Ticket/Create.html
index 3405ebf..8317ce7 100755
--- a/share/html/Ticket/Create.html
+++ b/share/html/Ticket/Create.html
@@ -107,15 +107,12 @@
   </&>
 % $m->callback( CallbackName => 'AfterBasics', QueueObj => $QueueObj );
 
-% foreach my $group ( RT::CustomField->CustomGroups( 'RT::Ticket' ), '' ) {
-<&| /Widgets/TitleBox,
-    title => $group? loc($group) : loc('Custom Fields'),
-    class => 'ticket-info-cfs '. ($group? CSSClass("ticket-info-cfs-$group") : ''),
-    hide_empty => 1
+<& /Elements/EditCustomFieldCustomGroups,
+    %ARGS,
+    Object => $ticket,
+    CustomFields => $QueueObj->TicketCustomFields,
+    DefaultsFromTopArguments => 0,
 &>
-<& Elements/EditCustomFields, %ARGS, QueueObj => $QueueObj, DefaultsFromTopArguments => 0, Group => $group &>
-</&>
-% }
 
 </div>
 
@@ -377,6 +374,8 @@ $m->callback( QueueObj => $QueueObj, title => \$title, results => \@results, ARG
 
 $QueueObj->Disabled && Abort(loc("Cannot create tickets in a disabled queue."));
 
+my $ticket = RT::Ticket->new($session{'CurrentUser'}); # empty ticket object
+
 my $CFs = $QueueObj->TicketCustomFields();
 
 my $ValidCFs = $m->comp(
diff --git a/share/html/Ticket/Modify.html b/share/html/Ticket/Modify.html
index 67edcdb..9e20b86 100755
--- a/share/html/Ticket/Modify.html
+++ b/share/html/Ticket/Modify.html
@@ -61,15 +61,7 @@
 </&>
 % $m->callback( CallbackName => 'AfterBasics', Ticket => $TicketObj );
 
-% foreach my $group ( RT::CustomField->CustomGroups( $TicketObj ), '' ) {
-<&| /Widgets/TitleBox,
-    title => $group? loc($group) : loc('Custom Fields'),
-    class => 'ticket-info-cfs '. ($group? CSSClass("ticket-info-cfs-$group") : ''),
-    hide_empty => 1,
-&>
-<& Elements/EditCustomFields, TicketObj => $TicketObj, DefaultsFromTopArguments => 0, Group => $group &>
-</&>
-% }
+<& /Elements/EditCustomFieldCustomGroups, Object => $TicketObj, DefaultsFromTopArguments => 0 &>
 
 <& /Elements/Submit, Name => 'SubmitTicket', Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#993333" &>
 </form>
diff --git a/share/html/Ticket/ModifyAll.html b/share/html/Ticket/ModifyAll.html
index 017285f..2b59dbd 100755
--- a/share/html/Ticket/ModifyAll.html
+++ b/share/html/Ticket/ModifyAll.html
@@ -62,15 +62,7 @@
 
 % $m->callback(CallbackName => 'AfterBasics', Ticket => $Ticket);
 
-% foreach my $group ( RT::CustomField->CustomGroups( $Ticket ), '' ) {
-<&| /Widgets/TitleBox,
-    title => $group? loc($group) : loc('CustomFields'),
-    class => 'ticket-info-cfs '. ($group? CSSClass("ticket-info-cfs-$group") : ''),
-    hide_empty => 1,
-&>
-<& Elements/EditCustomFields, TicketObj => $Ticket, Group => $group &>
-</&>
-% }
+<& /Elements/EditCustomFieldCustomGroups, Object => $Ticket &>
 
 <&| /Widgets/TitleBox, title => loc('Dates'), class=>'ticket-info-dates'&>
 <& Elements/EditDates, TicketObj => $Ticket &>

commit 3bf09713d4f82db5c6b98ceed6596060a784ef85
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Sep 28 00:15:00 2012 +0400

    deprecate /Ticket/Elements/EditCustomFields
    
    In favor of /Elements/EditCustomFields.
    
    Call on create is slightly longer. Note that passing
    new custom fields collection is done to avoid re-applying
    limits on the same collection.
    
    It's deperecated not only because of its simplicity, but
    also because of new /Elements/EditCustomFieldCustomGroups
    comp which calls /Elements/EditCustomFields directly skiping
    component in /Ticket/Elements. So any customization the subject
    wouldn't be applied to all CF editors.

diff --git a/share/html/Ticket/Create.html b/share/html/Ticket/Create.html
index 8317ce7..2cf40b9 100755
--- a/share/html/Ticket/Create.html
+++ b/share/html/Ticket/Create.html
@@ -101,7 +101,13 @@
 
 % $m->callback( CallbackName => 'AfterOwner', ARGSRef => \%ARGS );
 
-      <& /Ticket/Elements/EditCustomFields, %ARGS, QueueObj => $QueueObj, Group => 'Basics', InTable => 1 &>
+      <& /Elements/EditCustomFields,
+          %ARGS,
+          Object => $ticket,
+          CustomFields => $QueueObj->TicketCustomFields,
+          Group => 'Basics',
+          InTable => 1,
+      &>
       <& /Ticket/Elements/EditTransactionCustomFields, %ARGS, QueueObj => $QueueObj, InTable => 1 &>
     </table>
   </&>
@@ -160,7 +166,13 @@
   </td>
 </tr>
 
-<& Elements/EditCustomFields, QueueObj => $QueueObj, Group => 'People', InTable => 1 &>
+<& /Elements/EditCustomFields,
+    %ARGS,
+    Object => $ticket,
+    CustomFields => $QueueObj->TicketCustomFields,
+    Group => 'People',
+    InTable => 1,
+&>
 
 <tr>
 <td class="label">
@@ -248,7 +260,13 @@
 <table>
 <tr><td class="label"><&|/l&>Starts</&>:</td><td><& /Elements/SelectDate, Name => "Starts", Default => $ARGS{Starts} || '' &></td></tr>
 <tr><td class="label"><&|/l&>Due</&>:</td><td><& /Elements/SelectDate, Name => "Due", Default => $ARGS{Due} || '' &></td></tr>
-<& Elements/EditCustomFields, QueueObj => $QueueObj, Group => 'Dates', InTable => 1 &>
+<& /Elements/EditCustomFields,
+    %ARGS,
+    Object => $ticket,
+    CustomFields => $QueueObj->TicketCustomFields,
+    Group => 'Dates',
+    InTable => 1,
+&>
 </table>
 </&>
 </div>
@@ -268,7 +286,13 @@
 <tr><td class="label"><&|/l&>Children</&></td><td><input size="10" name="MemberOf-new" value="<% $ARGS{'MemberOf-new'} || '' %>" /></td></tr>
 <tr><td class="label"><&|/l&>Refers to</&></td><td><input size="10" name="new-RefersTo" value="<% $ARGS{'new-RefersTo'} || '' %>" /></td></tr>
 <tr><td class="label"><&|/l&>Referred to by</&></td><td><input size="10" name="RefersTo-new" value="<% $ARGS{'RefersTo-new'} || '' %>" /></td></tr>
-<& Elements/EditCustomFields, QueueObj => $QueueObj, Group => 'Links', InTable => 1 &>
+<& /Elements/EditCustomFields,
+    %ARGS,
+    Object => $ticket,
+    CustomFields => $QueueObj->TicketCustomFields,
+    Group => 'Links',
+    InTable => 1,
+&>
 </table>
 </&>
 </div>
diff --git a/share/html/Ticket/Elements/EditCustomFields b/share/html/Ticket/Elements/EditCustomFields
index 563d56b..fd5784f 100755
--- a/share/html/Ticket/Elements/EditCustomFields
+++ b/share/html/Ticket/Elements/EditCustomFields
@@ -46,6 +46,8 @@
 %#
 %# END BPS TAGGED BLOCK }}}
 <%INIT>
+$RT::Logger->warning("DEPRECATED: use /Elements/EditCustomFields");
+
 my $CustomFields;
 if ($TicketObj && !$OnCreate) {
     $CustomFields = $TicketObj->CustomFields;
diff --git a/share/html/Ticket/Elements/EditDates b/share/html/Ticket/Elements/EditDates
index 7b6d7a6..f2d83fd 100755
--- a/share/html/Ticket/Elements/EditDates
+++ b/share/html/Ticket/Elements/EditDates
@@ -70,7 +70,7 @@
       <& /Elements/SelectDate, menu_prefix => 'Due', current => 0 &> (<% $TicketObj->DueObj->AsString %>)
     </td>
   </tr>
-  <& EditCustomFields, TicketObj => $TicketObj, Group => 'Dates', InTable => 1 &>
+  <& /Elements/EditCustomFields, Object => $TicketObj, Group => 'Dates', InTable => 1 &>
 % $m->callback( %ARGS, CallbackName => 'EndOfList', Ticket => $TicketObj );
 </table>
 <%ARGS>
diff --git a/share/html/Ticket/Elements/EditPeople b/share/html/Ticket/Elements/EditPeople
index 87afade..0673fba 100755
--- a/share/html/Ticket/Elements/EditPeople
+++ b/share/html/Ticket/Elements/EditPeople
@@ -85,7 +85,7 @@
   <td class="value"><& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->AdminCc &></td>
 </tr>
 
-<& EditCustomFields, TicketObj => $Ticket, Group => 'People', InTable => 1 &>
+<& /Elements/EditCustomFields, Object => $Ticket, Group => 'People', InTable => 1 &>
 
 </table>
 
diff --git a/share/html/Ticket/Modify.html b/share/html/Ticket/Modify.html
index 9e20b86..5e9c418 100755
--- a/share/html/Ticket/Modify.html
+++ b/share/html/Ticket/Modify.html
@@ -57,7 +57,7 @@
 
 <&| /Widgets/TitleBox, title => loc('Modify ticket #[_1]',$TicketObj->Id), class=>'ticket-info-basics' &>
 <& Elements/EditBasics, TicketObj => $TicketObj &>
-<& Elements/EditCustomFields, TicketObj => $TicketObj, DefaultsFromTopArguments => 0, Group => 'Basics' &>
+<& /Elements/EditCustomFields, Object => $TicketObj, DefaultsFromTopArguments => 0, Group => 'Basics' &>
 </&>
 % $m->callback( CallbackName => 'AfterBasics', Ticket => $TicketObj );
 
diff --git a/share/html/Ticket/ModifyAll.html b/share/html/Ticket/ModifyAll.html
index 2b59dbd..6c67d42 100755
--- a/share/html/Ticket/ModifyAll.html
+++ b/share/html/Ticket/ModifyAll.html
@@ -57,7 +57,7 @@
 
 <&| /Widgets/TitleBox, title => loc('Modify ticket # [_1]', $Ticket->Id), class=>'ticket-info-basics' &>
 <& Elements/EditBasics, TicketObj => $Ticket &>
-<& Elements/EditCustomFields, TicketObj => $Ticket, Group => 'Basics' &>
+<& /Elements/EditCustomFields, Object => $Ticket, Group => 'Basics' &>
 </&>
 
 % $m->callback(CallbackName => 'AfterBasics', Ticket => $Ticket);

commit b88261cda07c915f807990218f88e91bfdfbf2d2
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Sep 29 01:51:56 2012 +0400

    add a new argument in LimitToGroup
    
    object/class argument, without it we have to guess in
    which object we're interested in

diff --git a/lib/RT/CustomFields.pm b/lib/RT/CustomFields.pm
index ca24763..b04f9ef 100644
--- a/lib/RT/CustomFields.pm
+++ b/lib/RT/CustomFields.pm
@@ -97,13 +97,15 @@ sub _Init {
 
 sub LimitToGroup {
     my $self = shift;
+    my $obj = shift;
     my $group = shift;
 
     my $config = RT->Config->Get('CustomFieldGroups');
        $config = {} unless ref($config) eq 'HASH';
+       $config = $config->{ref($obj) || $obj} || {};
 
     if ( $group ) {
-        my $list = $config->{'RT::Ticket'}{$group};
+        my $list = $config->{$group};
         unless ( $list and ref($list) eq 'ARRAY' and @$list ) {
             return $self->Limit( FIELD => 'id', VALUE => 0, ENTRYAGGREGATOR => 'AND' );
         }
@@ -112,7 +114,7 @@ sub LimitToGroup {
         }
     } else {
         my @list = map {@$_} grep defined && ref($_) eq 'ARRAY',
-            values %{ $config->{'RT::Ticket'} };
+            values %{ $config };
 
         return unless @list;
         foreach ( @list ) {
diff --git a/share/html/Elements/EditCustomFields b/share/html/Elements/EditCustomFields
index a33ac86..cc4bf91 100644
--- a/share/html/Elements/EditCustomFields
+++ b/share/html/Elements/EditCustomFields
@@ -35,7 +35,7 @@
 $NamePrefix   ||= join '-', 'Object', ref($Object), ($Object->Id || ''), 'CustomField', '';
 $CustomFields ||= $Object->CustomFields;
 
-$CustomFields->LimitToGroup( $Group  ) if defined $Group;
+$CustomFields->LimitToGroup( $Object => $Group ) if defined $Group;
 
 $m->callback( %ARGS, CallbackName => 'MassageCustomFields', $CustomFields => $CustomFields );
 
diff --git a/share/html/Elements/ShowCustomFields b/share/html/Elements/ShowCustomFields
index 5d2679b..2212007 100644
--- a/share/html/Elements/ShowCustomFields
+++ b/share/html/Elements/ShowCustomFields
@@ -83,7 +83,7 @@ $m->callback(
     CustomFields => $CustomFields,
 );
 
-$CustomFields->LimitToGroup($Group) if defined $Group;
+$CustomFields->LimitToGroup( $Object => $Group ) if defined $Group;
 
 # don't print anything if there is no custom fields
 return unless $CustomFields->First;

commit 327e043ed97e36a43c81b61ae4fbcc69e0c9fb04
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Sep 29 01:55:53 2012 +0400

    custom field groups for Users

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index abce5f8..d51874a 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -2604,6 +2604,12 @@ Set(%CustomFieldGroups,
         People => [],
         Links   => [],
     },
+    'RT::User' => {
+        Identity => [],
+        'Access control' => [],
+        Location => [],
+        Phones   => [],
+    },
 );
 
 1;
diff --git a/lib/RT/CustomField.pm b/lib/RT/CustomField.pm
index 210d36a..5c60668 100644
--- a/lib/RT/CustomField.pm
+++ b/lib/RT/CustomField.pm
@@ -1216,6 +1216,7 @@ sub Groups {
 
 our %BUILTIN_GROUPS = (
     'RT::Ticket' => { map { $_ => 1 } qw(Basics Dates Links People) },
+    'RT::User' => { map { $_ => 1 } 'Identity', 'Access control', 'Location', 'Phones' },
 );
 $BUILTIN_GROUPS{''} = { map { %$_ } values %BUILTIN_GROUPS  };
 
diff --git a/share/html/Admin/Users/Modify.html b/share/html/Admin/Users/Modify.html
index d189799..51cd8e6 100755
--- a/share/html/Admin/Users/Modify.html
+++ b/share/html/Admin/Users/Modify.html
@@ -50,7 +50,7 @@
 
 <& /Elements/ListActions, actions => \@results &>
 
-<form action="<%RT->Config->Get('WebPath')%>/Admin/Users/Modify.html" method="post" enctype="multipart/form-data">
+<form action="<%RT->Config->Get('WebPath')%>/Admin/Users/Modify.html" method="post" enctype="multipart/form-data" name="<% $Create ? 'UserCreate': 'UserModify' %>">
 %if ($Create) {
 <input type="hidden" class="hidden" name="id" value="new" />
 % } else {
@@ -60,7 +60,7 @@
 <tr>
 
 <td valign="top" class="boxcontainer">
-<&| /Widgets/TitleBox, title => loc('Identity') &>
+<&| /Widgets/TitleBox, title => loc('Identity'), class => 'user-info-identity' &>
 
 <table>
 <tr><td align="right">
@@ -98,10 +98,12 @@
 </td><td>
 <textarea name="FreeformContactInfo" cols="20" rows="5"><%$UserObj->FreeformContactInfo||$FreeformContactInfo||''%></textarea>
 </td></tr>
+<& /Elements/EditCustomFields, Object => $UserObj, Group => 'Identity', InTable => 1 &>
 </table>
 </&>
+
 <br />
-<&| /Widgets/TitleBox, title => loc('Access control') &>
+<&| /Widgets/TitleBox, title => loc('Access control'), class => 'user-info-access-control' &>
 <input type="hidden" class="hidden" name="SetEnabled" value="1" />
 <input type="checkbox" class="checkbox" name="Enabled" value="1" <%$EnabledChecked%> />
 <&|/l&>Let this user access RT</&><br />
@@ -114,12 +116,15 @@
     User => $UserObj,
     Name => [qw(CurrentPass Pass1 Pass2)],
 &>
+
+<& /Elements/EditCustomFields, Object => $UserObj, Group => 'Access control' &>
+
 </&>
 % $m->callback( %ARGS, CallbackName => 'LeftColumnBottom', UserObj => $UserObj );
 </td>
 
 <td valign="top" class="boxcontainer">
-<&| /Widgets/TitleBox, title => loc('Location') &>
+<&| /Widgets/TitleBox, title => loc('Location'), class => 'user-info-location' &>
 <table>
 <tr><td align="right">
 <&|/l&>Organization</&>: 
@@ -158,10 +163,13 @@
 </td><td>
 <input name="Country" value="<%$UserObj->Country||$Country||''%>" />
 </td></tr>
+
+<& /Elements/EditCustomFields, Object => $UserObj, Group => 'Location', InTable => 1 &>
+
 </table>
 </&>
 <br />
-<&| /Widgets/TitleBox, title => loc('Phone numbers') &>
+<&| /Widgets/TitleBox, title => loc('Phone numbers'), class => 'user-info-phones' &>
 <table>
 <tr><td align="right">
 <&|/l&>Residence</&>: 
@@ -184,25 +192,15 @@
 <input name="PagerPhone" value="<%$UserObj->PagerPhone||$PagerPhone||''%>" size="13" /><br />
 </td>
 </tr>
+
+<& /Elements/EditCustomFields, Object => $UserObj, Group => 'Phones', InTable => 1 &>
+
 </table>
 </&>
 <br />
-<&| /Widgets/TitleBox, title => loc('Custom Fields') &>
-<table>
-% my $CFs = $UserObj->CustomFields;
-% while (my $CF = $CFs->Next) {
-<tr valign="top"><td align="right">
-<% loc($CF->Name) %>:
-</td><td>
-% if ($UserObj->id) {
-<& /Elements/EditCustomField, %ARGS, Object => $UserObj, CustomField => $CF &>
-% } else {
-<& /Elements/EditCustomField, %ARGS, NamePrefix => 'Object-RT::User-new-CustomField-', CustomField => $CF &>
-% }
-</td></tr>
-% }
-</table>
-</&>
+
+<& /Elements/EditCustomFieldCustomGroups, Object => $UserObj &>
+
 % $m->callback( %ARGS, CallbackName => 'RightColumnBottom', UserObj => $UserObj );
 </td></tr>
 <tr>
@@ -278,7 +276,7 @@ else {
 		push @results, $msg;
         foreach my $key ( keys %ARGS) {
             # Convert custom fields on the "new" object to custom fields on the one we've just created
-            if ($key =~ /^Object-RT::User-new-CustomField-(.*)$/) {
+            if ($key =~ /^Object-RT::User--CustomField-(.*)$/) {
             $ARGS{'Object-RT::User-'.$val.'-CustomField-'.$1} = delete $ARGS{$key};
             }
         }
diff --git a/t/web/cf_groups_users.t b/t/web/cf_groups_users.t
new file mode 100644
index 0000000..755344f
--- /dev/null
+++ b/t/web/cf_groups_users.t
@@ -0,0 +1,118 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 49;
+
+RT->Config->Set( 'CustomFieldGroups',
+    'RT::User' => {
+        Identity         => ['TestIdentity'],
+        'Access control' => ['TestAccessControl'],
+        Location         => ['TestLocation'],
+        Phones           => ['TestPhones'],
+        More             => ['TestMore'],
+    },
+);
+
+my %CF;
+
+foreach my $name ( map { @$_ } values %{ RT->Config->Get('CustomFieldGroups')->{'RT::User'} } ) {
+    my $cf = RT::CustomField->new( RT->SystemUser );
+    my ($id, $msg) = $cf->Create(
+        Name => $name,
+        Description => 'A custom field',
+        LookupType => RT::User->new( $RT::SystemUser )->CustomFieldLookupType,
+        Type => 'FreeformSingle',
+        Pattern => qr{^(?!bad value).*$},
+    );
+    ok $id, "custom field '$name' correctly created";
+
+    ($id, $msg) = $cf->AddToObject( RT::User->new( $cf->CurrentUser ) );
+    ok $id, "applied custom field" or diag "error: $msg";
+
+    $CF{$name} = $cf;
+}
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok $m->login, 'logged in as root';
+
+my $index = 1;
+
+{
+    note "testing Create";
+    $m->follow_link_ok({id => 'tools-config-users-create'}, 'Create ');
+
+    my $dom = $m->dom;
+    $m->form_name('UserCreate');
+
+    $m->field( 'Name', 'user'. $index++ );
+
+    my $prefix = 'Object-RT::User--CustomField-';
+    my $input_name = $prefix . $CF{'TestIdentity'}->id .'-Value';
+    is $dom->find(qq{input[name="$input_name"]})->size, 1, "only one CF input on the page";
+    ok $dom->at(qq{.user-info-identity input[name="$input_name"]}), "CF is in the right place";
+    $m->field( $input_name, 'TestIdentityValue' );
+
+    $input_name = $prefix . $CF{'TestAccessControl'}->id .'-Value';
+    is $dom->find(qq{input[name="$input_name"]})->size, 1, "only one CF input on the page";
+    ok $dom->at(qq{.user-info-access-control input[name="$input_name"]}), "CF is in the right place";
+    $m->field( $input_name, 'TestAccessControlValue' );
+
+    $input_name = $prefix . $CF{'TestLocation'}->id .'-Value';
+    is $dom->find(qq{input[name="$input_name"]})->size, 1, "only one CF input on the page";
+    ok $dom->at(qq{.user-info-location input[name="$input_name"]}), "CF is in the right place";
+    $m->field( $input_name, 'TestLocationValue' );
+
+    $input_name = $prefix . $CF{'TestPhones'}->id .'-Value';
+    is $dom->find(qq{input[name="$input_name"]})->size, 1, "only one CF input on the page";
+    ok $dom->at(qq{.user-info-phones input[name="$input_name"]}), "CF is in the right place";
+    $m->field( $input_name, 'TestPhonesValue' );
+
+    $input_name = $prefix . $CF{'TestMore'}->id .'-Value';
+    is $dom->find(qq{input[name="$input_name"]})->size, 1, "only one CF input on the page";
+    ok $dom->at(qq{.user-info-cfs input[name="$input_name"]}), "CF is in the right place";
+    $m->field( $input_name, 'TestMoreValue' );
+
+    $m->submit;
+    $m->content_like(qr{User created});
+    my ($id) = ($m->uri =~ /id=(\d+)/);
+    ok $id, "found user's id #$id";
+
+    note "testing values on Modify page and on the object";
+    {
+        my $user = RT::User->new( RT->SystemUser );
+        $user->Load( $id );
+        ok $user->id, "loaded user";
+
+        $m->form_name('UserModify');
+        foreach my $cf_name ( keys %CF ) {
+            is $user->FirstCustomFieldValue($cf_name), "${cf_name}Value",
+                "correct value of $cf_name CF";
+            my $input = 'Object-RT::User-'. $id .'-CustomField-'
+                . $CF{$cf_name}->id .'-Value';
+            is $m->value($input), "${cf_name}Value",
+                "correct value in UI";
+            $m->field( $input, "${cf_name}Changed" );
+        }
+        $m->submit;
+    }
+
+    note "testing that update works";
+    {
+        my $user = RT::User->new( RT->SystemUser );
+        $user->Load( $id );
+        ok $user->id, "loaded user";
+
+        $m->form_name('UserModify');
+        foreach my $cf_name ( keys %CF ) {
+            is $user->FirstCustomFieldValue($cf_name), "${cf_name}Changed",
+                "correct value of $cf_name CF";
+            my $input = 'Object-RT::User-'. $id .'-CustomField-'
+                . $CF{$cf_name}->id .'-Value';
+            is $m->value($input), "${cf_name}Changed",
+                "correct value in UI";
+        }
+    }
+}
+

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


More information about the Rt-commit mailing list