[Rt-commit] rt branch, 4.6/search-selection-next, repushed
Blaine Motsinger
blaine at bestpractical.com
Fri Jan 24 16:38:40 EST 2020
The branch 4.6/search-selection-next was deleted and repushed:
was acb4fdf66b83ddb0244f57bc1332ef415996d025
now 9a4a2ef097910c782a4604e5bfd2d2cd6185680f
1: e722e0841e ! 1: e169b539e6 Add RT-Extension-DashboardSelectionUI to core
@@ -1,8 +1,6 @@
-Author: Shawn M Moore <shawn at bestpractical.com>
+Author: Blaine Motsinger <blaine at bestpractical.com>
- New drag and drop UI for selecting searches for homepage and dashboards
-
- This is a rough draft :)
+ Add RT-Extension-DashboardSelectionUI to core
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
--- a/lib/RT/Interface/Web.pm
@@ -15,6 +13,368 @@
jquery.cookie.js
popper.min.js
bootstrap.min.js
+
+diff --git a/share/html/Admin/Global/MyRT.html b/share/html/Admin/Global/MyRT.html
+--- a/share/html/Admin/Global/MyRT.html
++++ b/share/html/Admin/Global/MyRT.html
+@@
+ %# those contributions and any derivatives thereof.
+ %#
+ %# END BPS TAGGED BLOCK }}}
+-<& /Admin/Elements/Header, Title => loc("RT at a glance") &>
++<& /Elements/Header, Title => $title &>
+ <& /Elements/Tabs &>
++<& /Elements/ListActions, actions => \@results &>
+
+-<& /Elements/ListActions, actions => \@actions &>
+-<br />
+-% for my $pane (@panes) {
+-<&|/Widgets/TitleBox, title => loc('RT at a glance').': '.loc($pane->{Name}), bodyclass => "" &>
+-<& /Widgets/SelectionBox:show, self => $pane &></&>
+-<br />
+-% }
+-<%init>
+-my @actions;
+-
+-my @items = map { [ "component-$_", loc($_) ] } sort @{ RT->Config->Get('HomepageComponents') };
+-my $sys = RT::System->new( $session{'CurrentUser'} );
+-# XXX: put this in savedsearches_to_portlet_items
+-for ( $m->comp( "/Search/Elements/SearchesForObject",
+- Object => $sys )) {
+- my ( $desc, $loc_desc, $search ) = @$_;
+- my $SearchType = $search->Content->{'SearchType'} || 'Ticket';
+- if ( $SearchType eq 'Ticket' ) {
+- push @items, [ "system-$desc", $loc_desc ];
+- } else {
+- my $oid = ref($sys) . '-' . $sys->Id . '-SavedSearch-' . $search->Id;
+- my $type = ( $SearchType eq 'Ticket' )
+- ? 'Saved Search' # loc
+- : $SearchType;
+- push @items, [ "saved-$oid", loc($type) . ": $loc_desc" ];
++<form method="post" action="<% RT->Config->Get('WebPath') %>/Helpers/UpdateDashboard" data-dashboard_id='MyRT' data-is_global=True>
++ <& /Widgets/SearchSelection,
++ pane_name => \%pane_name,
++ sections => \@sections,
++ selected => \%selected,
++ filters => \@filters,
++ &>
++ <input type="submit" class="button" name="UpdateSearches" value="<% loc('Save') %>" />
++</form>
++
++<%INIT>
++my @results;
++my $title = loc("Customize").' '.loc("Global RT at a glance");
++my $user = $session{'CurrentUser'}->UserObj;
++
++my $portlets;
++my ($defaults) = RT::System->new($session{'CurrentUser'})->Attributes->Named('HomepageSettings');
++$portlets = $defaults ? $defaults->Content : {};
++
++my @sections;
++my %item_for;
++
++my @components = map { type => "component", name => $_, label => loc($_) }, @{RT->Config->Get('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} )->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 = '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') {
++ $item = { type => 'system', name => $desc, label => $loc_desc };
++ }
++ else {
++ 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 ($default_portlets) = $sys->Attributes->Named('HomepageSettings');
+-
+-my $has_right = $session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'SuperUser');
+-
+-my @panes = $m->comp(
+- '/Admin/Elements/ConfigureMyRT',
+- panes => [
+- 'body', #loc
+- 'sidebar', #loc
+- ],
+- Action => 'MyRT.html',
+- items => \@items,
+- ReadOnly => !$has_right,
+- current_portlets => $default_portlets->Content,
+- OnSave => sub {
+- my ( $conf, $pane ) = @_;
+- if (!$has_right) {
+- push @actions, loc( 'Permission Denied' );
++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 {
+- $default_portlets->SetContent( $conf );
+- push @actions, loc( 'Global portlet [_1] saved.', $pane );
++ push @results, loc('Unable to find [_1] [_2]', $saved->{type}, $saved->{name});
+ }
+ }
+-);
+
+-$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_ )
+- for @panes;
++ $selected{$pane} = \@items;
++}
+
++my %pane_name = (
++ 'body' => loc('Body'),
++ 'sidebar' => loc('Sidebar'),
++);
+
+-</%init>
++my @filters = (
++ [ 'component' => loc('Components') ],
++ [ 'ticket' => loc('Tickets') ],
++ [ 'chart' => loc('Charts') ],
++);
++
++$m->callback(
++ CallbackName => 'Default',
++ pane_name => \%pane_name,
++ sections => \@sections,
++ selected => \%selected,
++ filters => \@filters,
++);
+
++</%INIT>
+
+diff --git a/share/html/Admin/Users/MyRT.html b/share/html/Admin/Users/MyRT.html
+--- a/share/html/Admin/Users/MyRT.html
++++ b/share/html/Admin/Users/MyRT.html
+@@
+ %# END BPS TAGGED BLOCK }}}
+ <& /Admin/Elements/Header, Title => $title &>
+ <& /Elements/Tabs &>
+-
+ <& /Elements/ListActions, actions => \@actions &>
+
+-<form method="post" action="MyRT.html">
+-<input type="hidden" name="id" value="<% $id %>" />
+-<input type="hidden" name="Reset" value="1" />
++<form method="post" action="<% RT->Config->Get('WebPath') %> /Helpers/UpdateDashboard" data-dashboard_id = "MyRT" data-user_id = '<% $id %>'>
++ <& /Widgets/SearchSelection,
++ pane_name => \%pane_name,
++ sections => \@sections,
++ selected => \%selected,
++ filters => \@filters,
++ &>
++<input type="hidden" name="id" value="<% $id %>"/>
++<input type"submit" class="button" name="UpdateSearches" value= "<% loc('Save') %>" >
+ <div class="form-row">
+ <div class="col-md-12">
+ <input type="submit" class="button form-control btn btn-primary" value="<%loc('Reset to default')%>">
+@@
+ </div>
+ </form>
+
+-<br />
+-
+-% for my $pane (@panes) {
+-<&|/Widgets/TitleBox, title => loc('RT at a glance').': '.loc($pane->{Name}), bodyclass => "" &>
+-<& /Widgets/SelectionBox:show, self => $pane &></&>
+-<br />
+-% }
+-
+ <%init>
+ my @actions;
+ my $UserObj = RT::User->new($session{'CurrentUser'});
+ $UserObj->Load($id) || Abort("Couldn't load user '" . ($id || '') . "'");
++my $user = RT::User->new($session{'CurrentUser'});
+ my $title = loc("RT at a glance for the user [_1]", $UserObj->Name);
+
+-if ($ARGS{Reset}) {
+- my ($ok, $msg) = $UserObj->SetPreferences('HomepageSettings', {});
+- push @actions, $ok ? loc('Preferences saved for user [_1].', $UserObj->Name) : $msg;
++my $portlets = $UserObj->Preferences('HomepageSettings');
++unless ($portlets) {
++ my ($defaults) = RT::System->new($session{'CurrentUser'})->Attributes->Named('HomepageSettings');
++ $portlets = $defaults ? $defaults->Content : {};
+ }
+
+-my ($default_portlets) = RT::System->new($session{'CurrentUser'})->Attributes->Named('HomepageSettings');
+-my $portlets = $UserObj->Preferences('HomepageSettings', $default_portlets ? $default_portlets->Content : {});
+-
+-my %allowed_components = map {$_ => 1} @{ RT->Config->Get('HomepageComponents') };
++my @sections;
++my %item_for;
+
+-my @items;
+-push @items, map {["component-$_", loc($_)]} sort keys %allowed_components;
++my @components = map { type => "component", name => $_, label => loc($_) }, @{RT->Config->Get('HomepageComponents')};
++$item_for{ $_->{type} }{ $_->{name} } = $_ for @components;
+
+-my $sys = RT::System->new( RT::CurrentUser->new($UserObj) );
++push @sections, {
++ id => 'components',
++ label => loc("Components"),
++ items => \@components,
++ };
++my $sys = RT::System->new($session{'CurrentUser'});
++$sys->Load($id) || Abort("Couldn't load user '" . ($id || '') . "'");
+ my @objs = ($sys);
++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;
+
+-push @objs, RT::SavedSearch->new( RT::CurrentUser->new( $UserObj ) )->ObjectsForLoading;
++ for ($m->comp("/Search/Elements/SearchesForObject", Object => $object)) {
++ my ($desc, $loc_desc, $search) = @$_;
+
+-for my $object (@objs) {
+- for ($m->comp("/Search/Elements/SearchesForObject", Object => $object)) {
+- my ($desc, $loc_desc, $search) = @$_;
+- my $SearchType = $search->Content->{'SearchType'} || 'Ticket';
+- if ($object eq $sys && $SearchType eq 'Ticket') {
+- push @items, ["system-$desc", $loc_desc];
++ 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') {
++ $item = { type => 'system', name => $desc, label => $loc_desc };
++ }
++ else {
++ 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 %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 {
+- my $oid = ref($object).'-'.$object->Id.'-SavedSearch-'.$search->Id;
+- my $type = ($SearchType eq 'Ticket')
+- ? 'Saved Search' # loc
+- : $SearchType;
+- push @items, ["saved-$oid", loc($type).": $loc_desc"];
++ push @actions, loc('Unable to find [_1] [_2]', $saved->{type}, $saved->{name});
+ }
+ }
+-}
+-
+-my @panes = $m->comp(
+- '/Admin/Elements/ConfigureMyRT',
+- panes => ['body', 'sidebar'],
+- Action => "MyRT.html?id=$id",
+- items => \@items,
+- current_portlets => $portlets,
+- OnSave => sub {
+- my ( $conf, $pane ) = @_;
+- my ($ok, $msg) = $UserObj->SetPreferences( 'HomepageSettings', $conf );
+- push @actions, $ok ? loc('Preferences [_1] for user [_2].', $pane, $UserObj->Name) : $msg;
++ $selected{$pane} = \@items;
+ }
++
++my %pane_name = (
++ 'body' => loc('Body'),
++ 'sidebar' => loc('Sidebar'),
+ );
+
+-$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_ )
+- for @panes;
++my @filters = (
++ [ 'component' => loc('Components') ],
++ [ 'ticket' => loc('Tickets') ],
++ [ 'chart' => loc('Charts') ],
++);
++$m->callback(
++ CallbackName => 'Default',
++ pane_name => \%pane_name,
++ sections => \@sections,
++ selected => \%selected,
++ filters => \@filters,
++);
+
+-</%init>
++</%INIT>
+ <%ARGS>
+-$id => undef
++ $id => undef
+ </%ARGS>
diff --git a/share/html/Dashboards/Elements/DashboardsForObject b/share/html/Dashboards/Elements/DashboardsForObject
--- a/share/html/Dashboards/Elements/DashboardsForObject
@@ -553,11 +913,24 @@
+<%INIT>
+my $args = JSON::from_json($content);
+my $id = $args->{dashboard_id};
++my $user_id = $args->{user_id};
++my $is_global = $args->{is_global};
+
+my ($ok, $msg);
+if ($id eq 'MyRT') {
-+ my $user = $session{CurrentUser}->UserObj;
-+ ($ok, $msg) = $user->SetPreferences('HomepageSettings', $args->{panes});
++ my $user = $session{CurrentUser};
++ if($user_id){
++ $user->Load($user_id);
++ ($ok, $msg) = $user->SetPreferences('HomepageSettings', $args->{panes});
++ }
++ elsif($is_global){
++ my $sys = RT::System->new($session{'CurrentUser'});
++ my ($default_portlets) = $sys->Attributes->Named('HomepageSettings');
++ ($ok, $msg) = $default_portlets->SetContent( $args->{panes} );
++ }
++ else{
++ ($ok, $msg) = $user->SetPreferences('HomepageSettings', $args->{panes});
++ }
+}
+else {
+ use RT::Dashboard;
@@ -867,7 +1240,7 @@
+ <div class="section">
+ <h3><% $label | n %></h3>
+ <ul>
-+% for my $item (@$items) {
++% for my $item (sort {$a->{'label'} cmp $b->{'label'}} @$items) {
+ <& /Elements/ShowSelectSearch, %$item &>
+% }
+ </ul>
@@ -880,6 +1253,7 @@
+<div class="clear"></div>
+
+<%INIT>
++use utf8;
+$m->callback(
+ CallbackName => 'Default',
+ sections => \@sections,
@@ -1043,17 +1417,26 @@
+
+ container.find('.destination ul').sortable({
+ connectWith: '.destination ul',
-+ containment: container.find('.destinations'),
+ placeholder: 'placeholder',
+ forcePlaceholderSize: true,
-+ axis: 'y',
+ cancel: '.remove',
+
+ // drag a clone of the source item
+ receive: function (e, ui) {
+ draggedIntoDestination = true;
+ copyHelper = null;
-+ }
++ },
++ over: function () {
++ removeIntent = false;
++ },
++ out: function () {
++ removeIntent = true;
++ },
++ beforeStop: function (event, ui) {
++ if(removeIntent == true){
++ ui.item.remove();
++ }
++ },
+ }).disableSelection().on('click', '.remove', function (e) {
+ e.preventDefault();
+ jQuery(e.target).closest('li').remove();
2: b2d3f14fd6 < -: ------- Add support for Drag and Drop UI to Admin->Global and Admin->Users
3: 2d3ab4dc92 < -: ------- Alpha sort items in the select from list
4: cad0f59072 < -: ------- Specify UTF-8 encoding
5: ab34697bf9 < -: ------- Remove line in JS limiting axis
6: acb4fdf66b < -: ------- Add drag out to remove from list functionality
-: ------- > 2: 9a4a2ef097 Upgrade jQuery ui sortable and add disableSelection
More information about the rt-commit
mailing list