[Rt-commit] rtir branch, master, updated. 4.0.1rc1-178-g49fb3471

? sunnavy sunnavy at bestpractical.com
Thu Jun 4 16:34:55 EDT 2020


The branch, master has been updated
       via  49fb34712677d6bfc1b087fd5d1e778422610930 (commit)
       via  d27a060f0575c8a0abdba2b04c826b1afdbfe600 (commit)
       via  c447b3f812f33c5b0b6b84c72e8b412487839690 (commit)
       via  2695ba5267756182096c6f4ac52ecd1ce4de962a (commit)
      from  00d48ac1e1d542fc74ff222ddd80eec0b6d747e4 (commit)

Summary of changes:
 html/RTIR/Prefs/Home.html | 176 +++++++++++++++++++++++++++++++++-------------
 html/RTIR/index.html      |  11 ++-
 t/web/custom_frontpage.t  | 138 ++++++++++++++++++++++++++++++++++++
 3 files changed, 270 insertions(+), 55 deletions(-)
 create mode 100644 t/web/custom_frontpage.t

- Log -----------------------------------------------------------------
commit 2695ba5267756182096c6f4ac52ecd1ce4de962a
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Jun 5 03:53:43 2020 +0800

    Remove the session cache of the "RTIR at a glance" portlet lists
    
    This is to mirror similar changes in RT, and the purpose is to ensure
    that users who have not overridden the preference always get the most
    recent global configuration.
    
    See also RT commit 9582e25ab2

diff --git a/html/RTIR/Prefs/Home.html b/html/RTIR/Prefs/Home.html
index 7081f86d..98638619 100644
--- a/html/RTIR/Prefs/Home.html
+++ b/html/RTIR/Prefs/Home.html
@@ -64,11 +64,11 @@
 my @results;
 my $user = $session{'CurrentUser'}->UserObj;
 
-unless (exists $session{'my_rtir_portlets'}) {
-    my ($d_portlets) = RT::System->new($session{'CurrentUser'})->Attributes->Named('RTIR_HomepageSettings');
-    $session{'my_rtir_portlets'} = $user->Preferences('RTIR_HomepageSettings', $d_portlets->Content);
+my $portlets = $user->Preferences('RTIR_HomepageSettings');
+unless ($portlets) {
+    my ($defaults) = RT::System->new($session{'CurrentUser'})->Attributes->Named('RTIR_HomepageSettings');
+    $portlets = $defaults ? $defaults->Content : {};
 }
-my $portlets = $session{'my_rtir_portlets'};
 
 my %seen;
 
diff --git a/html/RTIR/index.html b/html/RTIR/index.html
index 77909674..0b855c80 100644
--- a/html/RTIR/index.html
+++ b/html/RTIR/index.html
@@ -51,14 +51,11 @@
 <& /Elements/MyRT, Portlets => $portlets &>
 <%INIT>
 
-# XXX: this should be automated!!!
-unless ( exists $session{'my_rtir_portlets'} ) {
-    my ($d_portlets) = RT::System->new( $session{'CurrentUser'} )->Attributes->Named('RTIR_HomepageSettings');
-    $session{'my_rtir_portlets'} = $session{'CurrentUser'}->UserObj->Preferences(
-        'RTIR_HomepageSettings', $d_portlets->Content
-    );
+my $portlets = $session{'CurrentUser'}->Preferences('RTIR_HomepageSettings');
+unless ($portlets) {
+    my ($defaults) = RT::System->new($session{'CurrentUser'})->Attributes->Named('RTIR_HomepageSettings');
+    $portlets = $defaults ? $defaults->Content : {};
 }
-my $portlets = $session{'my_rtir_portlets'};
 
 if ( defined $q && length $q ) {
 

commit c447b3f812f33c5b0b6b84c72e8b412487839690
Author: craig kaiser <craig at bestpractical.com>
Date:   Thu Jun 4 13:16:08 2020 -0400

    Use new search selection interface for editing RTIR home page

diff --git a/html/RTIR/Prefs/Home.html b/html/RTIR/Prefs/Home.html
index 98638619..7a47507f 100644
--- a/html/RTIR/Prefs/Home.html
+++ b/html/RTIR/Prefs/Home.html
@@ -49,18 +49,17 @@
 <& /Elements/Tabs &>
 <& /Elements/ListActions, actions => \@results &>
 
-% foreach my $pane ( @panes ) {
-<&|/Widgets/TitleBox,
-    title => loc('RTIR at a glance') .': '. loc( $pane->{Name} ),
-    bodyclass => ""
-&>
-<& /Widgets/SelectionBox:show, self => $pane &>
-</&>
-% }
+<form method="post" name="UpdateSearches" class="mx-auto max-width-lg">
+  <& /Widgets/SearchSelection,
+    pane_name => \%pane_name,
+    sections  => \@sections,
+    selected  => \%selected,
+    filters   => \@filters,
+  &>
+  <& /Elements/Submit, Name => "UpdateSearches", Label => loc('Save') &>
+</form>
 
 <%INIT>
-# XXX: copy&past of the similar RT's page
-
 my @results;
 my $user = $session{'CurrentUser'}->UserObj;
 
@@ -70,58 +69,139 @@ unless ($portlets) {
     $portlets = $defaults ? $defaults->Content : {};
 }
 
-my %seen;
+my @sections;
+my %item_for;
 
-my @items;
-foreach my $comp ( grep !$seen{$_}++, (RT->Config->Get('RTIR_HomepageComponents')) ) {
-    my $desc;
-    my $obj = $m->fetch_comp($comp);
-    $desc = $obj->attr_if_exists('Description') if $obj;
-    unless( $desc ) {
-        $desc = $comp;
-        $desc =~ s/^.*\///;
-    }
-    push @items, ["component-$comp", $desc];
-}
+my @components = map { type => "component", name => $_, label => loc($_) }, @{RT->Config->Get('RTIR_HomepageComponents')};
+
+$item_for{ $_->{type} }{ $_->{name} } = $_ for @components;
+
+push @sections, {
+    id    => 'components',
+    label => loc("Components"),
+    items => \@components,
+};
 
 my $sys = RT::System->new($session{'CurrentUser'});
 my @objs = ($sys);
 
-push @objs, RT::SavedSearch->new( $session{'CurrentUser'} )->_PrivacyObjects
+push @objs, RT::SavedSearch->new( $session{CurrentUser} )->ObjectsForLoading
     if $session{'CurrentUser'}->HasRight( Right  => 'LoadSavedSearch',
                                           Object => $RT::System );
 
 for my $object (@objs) {
+    my @items;
+    my $object_id = ref($object) . '-' . $object->Id;
+    $object_id = 'system' if $object eq $sys;
+
     for ($m->comp("/Search/Elements/SearchesForObject", Object => $object)) {
         my ($desc, $loc_desc, $search) = @$_;
-        my $SearchType = $search->Content->{'SearchType'} || 'Ticket';
+
+        my $SearchType = 'Ticket';
+        if ((ref($search->Content)||'') eq 'HASH') {
+            $SearchType = $search->Content->{'SearchType'}
+                if $search->Content->{'SearchType'};
+        }
+        else {
+            $RT::Logger->debug("Search ".$search->id." ($desc) appears to have no Content");
+        }
+
+        my $item;
         if ($object eq $sys && $SearchType eq 'Ticket') {
-            push @items, ["system-$desc", $loc_desc];
+            $item = { type => 'system', name => $desc, label => $loc_desc };
         }
         else {
-            my $oid = ref($object).'-'.$object->Id.'-SavedSearch-'.$search->Id;
-            my $type = ($SearchType eq 'Ticket')
-                ? 'Saved Search' : $SearchType; # loc
-            push @items, ["saved-$oid", loc($type).": $loc_desc"];
+            my $oid = $object_id.'-SavedSearch-'.$search->Id;
+            $item = { type => 'saved', name => $oid, search_type => $SearchType, label => $loc_desc };
         }
+
+        $item_for{ $item->{type} }{ $item->{name} } = $item;
+        push @items, $item;
     }
+
+    my $label = $object eq $sys           ? loc('System')
+                : $object->isa('RT::Group') ? $object->Label
+                                            : $object->Name;
+
+    push @sections, {
+        id    => $object_id,
+        label => $label,
+        items => [ sort { lc($a->{label}) cmp lc($b->{label}) } @items ],
+    };
 }
 
-my @panes = $m->comp(
-    '/Admin/Elements/ConfigureMyRT',
-    panes  => ['body', 'sidebar'],
-    Action => 'Home.html',
-    items => \@items,
-    current_portlets => $portlets,
-    OnSave => sub {
-        my ( $conf, $pane ) = @_;
-        my ($ok, $msg) = $user->SetPreferences( 'RTIR_HomepageSettings', $conf );
-        push @results, $ok ? loc('Preferences saved for [_1].', $pane) : $msg;
-        delete $session{'my_rtir_portlets'};
+my %selected;
+for my $pane (keys %$portlets) {
+    my @items;
+
+    for my $saved (@{ $portlets->{$pane} }) {
+        my $item = $item_for{ $saved->{type} }{ $saved->{name} };
+        if ($item) {
+            push @items, $item;
+        }
+        else {
+            push @results, loc('Unable to find [_1] [_2]', $saved->{type}, $saved->{name});
+        }
     }
+
+    $selected{$pane} = \@items;
+}
+
+my %pane_name = (
+    'body'    => loc('Body'),
+    'sidebar' => loc('Sidebar'),
+);
+
+my @filters = (
+    [ 'component' => loc('Components') ],
+    [ 'ticket'    => loc('Tickets') ],
+    [ 'chart'     => loc('Charts') ],
 );
 
-$m->comp ('/Widgets/SelectionBox:process', %ARGS, self => $_ ) for @panes;
+$m->callback(
+    CallbackName => 'Default',
+    pane_name    => \%pane_name,
+    sections     => \@sections,
+    selected     => \%selected,
+    filters      => \@filters,
+);
+
+if ($ARGS{UpdateSearches}) {
+    my $data = {
+        "panes"        => {
+            "body"    => [],
+            "sidebar" => []
+        }
+    };
+
+    foreach my $arg (qw{ body sidebar }) {
+        my $pane   = $arg;
+        my $values = $ARGS{$pane};
 
-MaybeRedirectForResults( Actions => \@results );
+        next unless $values;
+
+        # force value to an arrayref so we can handle both single and multiple members of each pane.
+        $values = [$values] unless ref $values;
+
+        foreach my $value ( @{$values} ) {
+            $value =~ m/^(\w+)-(.+)$/i;
+            my $type = $1;
+            my $name = $2;
+            push @{ $data->{panes}->{$pane} }, { type => $type, name => $name };
+        }
+    }
+
+    my ( $ok, $msg ) = $user->SetPreferences( 'RTIR_HomepageSettings', $data->{panes} );
+    if ( $ok ) {
+        push @results, loc("Preferences saved.");
+    }
+    else {
+        push @results, loc("Could not save preferences.");
+    }
+
+    MaybeRedirectForResults(
+        Actions   => \@results,
+        Path      => "/RTIR/Prefs/Home.html",
+    );
+}
 </%INIT>

commit d27a060f0575c8a0abdba2b04c826b1afdbfe600
Author: craig kaiser <craig at bestpractical.com>
Date:   Thu Jun 4 13:30:20 2020 -0400

    Add tests for new search selection UI for RTIR homepage

diff --git a/t/web/custom_frontpage.t b/t/web/custom_frontpage.t
new file mode 100644
index 00000000..437c8e37
--- /dev/null
+++ b/t/web/custom_frontpage.t
@@ -0,0 +1,138 @@
+use strict;
+use warnings;
+
+use RT::IR::Test tests => undef;
+my ($baseurl, $m) = RT::IR::Test->started_ok;
+
+my $url = $m->rt_base_url;
+
+my $user_obj = RT::User->new(RT->SystemUser);
+my ($ret, $msg) = $user_obj->LoadOrCreateByEmail('customer at example.com');
+ok($ret, 'ACL test user creation');
+$user_obj->SetName('customer');
+$user_obj->SetPrivileged(1);
+($ret, $msg) = $user_obj->SetPassword('customer');
+$user_obj->PrincipalObj->GrantRight(Right => 'LoadSavedSearch');
+$user_obj->PrincipalObj->GrantRight(Right => 'EditSavedSearches');
+$user_obj->PrincipalObj->GrantRight(Right => 'CreateSavedSearch');
+$user_obj->PrincipalObj->GrantRight(Right => 'ModifySelf');
+
+ok $m->login( customer => 'customer' ), "logged in";
+
+$m->get ( $url."Search/Build.html");
+
+#create a saved search
+$m->form_name ('BuildQuery');
+
+$m->field ( "ValueOfAttachment" => 'stupid');
+$m->field ( "SavedSearchDescription" => 'stupid tickets');
+$m->click_button (name => 'SavedSearchSave');
+
+$m->get ( $url.'RTIR/Prefs/Home.html' );
+$m->content_contains('stupid tickets', 'saved search listed in rt at a glance items');
+
+ok $m->login('root', 'password', logout => 1), 'we did log in as root';
+
+my $args = {
+    UpdateSearches => "Save",
+    dashboard_id   => "RTIR_HomepageSettings",
+    body           => [],
+    sidebar        => [],
+};
+
+# remove all portlets from the body pane except 'newest unowned tickets'
+push(
+    @{$args->{body}},
+    ( "system-Unowned Tickets", )
+);
+
+my $res = $m->post(
+    $url . 'RTIR/Prefs/Home.html',
+    $args,
+);
+
+is( $res->code, 200, "remove all portlets from body except 'newest unowned tickets'" );
+like( $m->uri, qr/results=[A-Za-z0-9]{32}/, 'URL redirected for results' );
+$m->content_contains( 'Preferences saved' );
+
+$m->get( $url."RTIR/" );
+$m->content_contains( 'newest unowned tickets', "'newest unowned tickets' is present" );
+$m->content_lacks( 'highest priority tickets', "'highest priority tickets' is not present" );
+$m->content_lacks( 'Bookmarked Tickets<span class="results-count">', "'Bookmarked Tickets' is not present" );  # 'Bookmarked Tickets' also shows up in the nav, so we need to be more specific
+$m->content_lacks( 'Quick ticket creation', "'Quick ticket creation' is not present" );
+
+# add back the previously removed portlets
+push(
+    @{$args->{body}},
+    ( "system-My Tickets", "system-Bookmarked Tickets", "component-QuickCreate" )
+);
+
+push(
+    @{$args->{sidebar}},
+    ( "component-MyReminders", "component-QueueList", "component-Dashboards", "component-RefreshHomepage", )
+);
+
+$res = $m->post(
+    $url . 'RTIR/Prefs/Home.html',
+    $args,
+);
+
+is( $res->code, 200, 'add back previously removed portlets' );
+like( $m->uri, qr/results=[A-Za-z0-9]{32}/, 'URL redirected for results' );
+$m->content_contains( 'Preferences saved' );
+
+$m->get( $url."RTIR/" );
+$m->content_contains( 'newest unowned tickets', "'newest unowned tickets' is present" );
+$m->content_contains( 'highest priority tickets', "'highest priority tickets' is present" );
+$m->content_contains( 'Bookmarked Tickets<span class="results-count">', "'Bookmarked Tickets' is present" );
+$m->content_contains( 'Quick ticket creation', "'Quick ticket creation' is present" );
+
+#create a saved search with special chars
+$m->get( $url . "Search/Build.html" );
+$m->form_name('BuildQuery');
+$m->field( "ValueOfAttachment"      => 'stupid' );
+$m->field( "SavedSearchDescription" => 'special chars [test] [_1] ~[_1~]' );
+$m->click_button( name => 'SavedSearchSave' );
+my ($name) = $m->content =~ /value="(RT::User-\d+-SavedSearch-\d+)"/;
+ok( $name, 'saved search name' );
+$m->get( $url . 'RTIR/Prefs/Home.html' );
+$m->content_contains( 'special chars [test] [_1] ~[_1~]',
+    'saved search listed in rt at a glance items' );
+
+# add saved search to body
+push(
+    @{$args->{body}},
+    ( "saved-" . $name )
+);
+
+$res = $m->post(
+    $url . 'RTIR/Prefs/Home.html',
+    $args,
+);
+
+is( $res->code, 200, 'add saved search to body' );
+like( $m->uri, qr/results=[A-Za-z0-9]{32}/, 'URL redirected for results' );
+$m->content_contains( 'Preferences saved' );
+
+$m->get( $url."RTIR/" );
+$m->content_like( qr/special chars \[test\] \d+ \[_1\]/,
+    'special chars in titlebox' );
+
+# Edit a system saved search to contain "[more]"
+{
+    my $search = RT::Attribute->new( RT->SystemUser );
+    $search->LoadByNameAndObject( Name => 'Search - My Tickets', Object => RT->System );
+    my ($id, $desc) = ($search->id, RT->SystemUser->loc($search->Description, '"N"'));
+    ok $id, 'loaded search attribute';
+
+    $m->get( $url."RTIR/" );
+    $m->follow_link_ok({ url_regex => qr"Prefs/Search\.html\?name=.+?Attribute-$id" }, 'Edit link');
+    $m->content_contains($desc, "found description: $desc");
+
+    ok +($search->SetDescription( $search->Description . " [more]" ));
+
+    $m->get_ok($m->uri); # "reload_ok"
+    $m->content_contains($desc . " [more]", "found description: $desc");
+}
+
+done_testing;

commit 49fb34712677d6bfc1b087fd5d1e778422610930
Merge: 00d48ac1 d27a060f
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Jun 5 04:21:58 2020 +0800

    Merge branch '5.0/search-selection'


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


More information about the rt-commit mailing list