[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