rt 4.2.15
[freeside.git] / rt / share / html / Elements / ColumnMap
index 12a6145..4e9d35e 100644 (file)
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2018 Best Practical Solutions, LLC
 %#                                          <sales@bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
@@ -52,11 +52,13 @@ $Attr  => undef
 </%ARGS>
 <%ONCE>
 
-# This is scary and should totally be refactored -- jesse
-my $COLUMN_MAP = {
+use Scalar::Util;
+
+my ($COLUMN_MAP, $WCOLUMN_MAP);
+$WCOLUMN_MAP = $COLUMN_MAP = {
     id => {
         attribute => 'id',
-        title    => 'id', # loc
+        title     => '#', # loc
         align     => 'right',
         value     => sub { return $_[0]->id }
     },
@@ -96,6 +98,12 @@ my $COLUMN_MAP = {
         attribute => sub { return shift @_ },
         title     => sub { return pop @_ },
         value     => sub {
+            my $self = $WCOLUMN_MAP->{CustomField};
+            my $cf   = $self->{load}->(@_);
+            return unless $cf->Id;
+            return $self->{render}->( $cf, $cf->ValuesForObject($_[0])->ItemsArrayRef );
+        },
+        load      => sub {
             # Cache the CF object on a per-request basis, to avoid
             # having to load it for every row
             my $key = join("-","CF",
@@ -106,36 +114,31 @@ my $COLUMN_MAP = {
             my $cf = $m->notes($key);
             unless ($cf) {
                 $cf = $_[0]->LoadCustomFieldByIdentifier($_[-1]);
+                RT->Logger->debug("Unable to load $_[-1] for ".$_[0]->CustomFieldLookupType." ".$_[0]->CustomFieldLookupId)
+                    unless $cf->Id;
                 $m->notes($key, $cf);
             }
 
-            # Display custom field contents, separated by newlines.
-            # For Image custom fields we also show a thumbnail here.
-
-            my $values = $cf->ValuesForObject( $_[0] );
-            return if $values->Count == 0;
-            my @values;
-            # it is guaranteed to be the same type for all fields, right?
-            my $v = $values->First;
-            my $cftype = $v->CustomFieldObj->Type;
-
-            do {
-                if ($cftype eq 'Image') {
-                    push @values, 
-                        \($m->scomp( '/Elements/ShowCustomFieldImage',
-                                      Object => $v ));
-                } elsif ( $cftype eq 'Date' or $cftype eq 'DateTime' ) {
-                    # then actually return the date object;
-                    # ProcessColumnMapValue will stringify it
-                    my $DateObj = RT::Date->new( $session{'CurrentUser'} );
-                    $DateObj->Set(Format => 'unknown', Value => $v->Content);
-                    push @values, $DateObj;
-                } else {
-                    push @values, $v->Content;
+            return $cf;
+          },
+          render    => sub {
+            my ($cf, $ocfvs) = @_;
+            my $comp = $m->comp_exists("/Elements/ShowCustomField".$cf->Type)
+                     ? "/Elements/ShowCustomField".$cf->Type
+                     : undef;
+
+            my @values = map {
+                $comp
+                    ? \($m->scomp( $comp, Object => $_ ))
+                    : $_->Content
+            } @$ocfvs;
+
+            if (@values > 1) {
+                for my $value (splice @values) {
+                    push @values, \"<li>", $value, \"</li> \n";
                 }
-                push @values, \'<br />'; # this is deeply silly
-            } while ($v = $values->Next);
-            pop @values; # Remove that last <br />
+                @values = (\"<ul class='cf-values'>", @values, \"</ul>");
+            }
             return @values;
         },
     },
@@ -146,9 +149,9 @@ my $COLUMN_MAP = {
             my $checked = $DECODED_ARGS->{ $name .'All' }? 'checked="checked"': '';
 
             return \qq{<input type="checkbox" name="}, $name, \qq{All" value="1" $checked
-                              onclick="setCheckbox(this.form, },
+                              onclick="setCheckbox(this, },
                               $m->interp->apply_escapes($name,'j'),
-                              \qq{, this.checked)" />};
+                              \qq{)" />};
         },
         value => sub {
             my $id = $_[0]->id;
@@ -160,7 +163,7 @@ my $COLUMN_MAP = {
             my $arg = $DECODED_ARGS->{ $name };
             my $checked = '';
             if ( $arg && ref $arg ) {
-                $checked = 'checked="checked"' if grep $_ == $id, @$arg;
+                $checked = 'checked="checked"' if grep $_ == $id, grep { defined and length } @$arg;
             }
             elsif ( $arg ) {
                 $checked = 'checked="checked"' if $arg == $id;
@@ -187,20 +190,60 @@ my $COLUMN_MAP = {
     } qw(WebPath WebBaseURL WebURL)),
     WebRequestPath    => { value => sub { substr( $m->request_path, 1 ) } },
     WebRequestPathDir => { value => sub { substr( $m->request_comp->dir_path, 1 ) } },
+    WebHomePath       => {
+        value => sub {
+            my $path = RT->Config->Get("WebPath");
+            if (not $session{CurrentUser}->Privileged) {
+                $path .= "/SelfService";
+            }
+            return \$path;
+        },
+    },
+    CurrentUser       => { value => sub { $session{CurrentUser}->id } },
+    CurrentUserName   => { value => sub { $session{CurrentUser}->Name } },
 };
 
 $COLUMN_MAP->{'CF'} = $COLUMN_MAP->{'CustomField'};
 
+Scalar::Util::weaken($WCOLUMN_MAP);
+
+my $ROLE_MAP = {};
+
 </%ONCE>
 <%INIT>
 $m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'Once', CallbackOnce => 1 );
-$m->callback( COLUMN_MAP => $COLUMN_MAP );
+
+my $generic_with_roles;
+
+# Add in roles
+my $RecordClass = $Class;
+$RecordClass =~ s/_/:/g;
+if ($RecordClass->DOES("RT::Record::Role::Roles")) {
+    unless ($ROLE_MAP->{$RecordClass}) {
+        for my $role ($RecordClass->Roles) {
+            my $attrs = $RecordClass->Role($role);
+            $ROLE_MAP->{$RecordClass}{$role} = {
+                title => $role,
+                attribute => $attrs->{Column} || "$role.EmailAddress",
+                value => sub { return \($m->scomp("/Elements/ShowPrincipal", Object => $_[0]->RoleGroup($role) ) ) },
+            };
+            $ROLE_MAP->{$RecordClass}{$role . "s"} = $ROLE_MAP->{$RecordClass}{$role}
+                unless $attrs->{Single};
+        }
+    }
+    $generic_with_roles = { %{$COLUMN_MAP}, %{$ROLE_MAP->{$RecordClass}} };
+} else {
+    $generic_with_roles = { %{$COLUMN_MAP} };
+}
+
+$m->callback( COLUMN_MAP => $generic_with_roles );
 
 # first deal with class specific things
 if (RT::Interface::Web->ComponentPathIsSafe($Class) and $m->comp_exists("/Elements/$Class/ColumnMap")) {
-    my $class_map = $m->comp("/Elements/$Class/ColumnMap", Attr => $Attr, Name => $Name );
+    my $class_map = $m->comp("/Elements/$Class/ColumnMap", Attr => $Attr, Name => $Name, GenericMap => $generic_with_roles );
     return $class_map if defined $class_map;
 }
-return GetColumnMapEntry( Map => $COLUMN_MAP, Name => $Name, Attribute => $Attr );
+
+return GetColumnMapEntry( Map => $generic_with_roles, Name => $Name, Attribute => $Attr );
 
 </%INIT>