[Rt-commit] rt branch, 4.4/emailinput-autocomplete-exclude, created. rt-4.4.4-85-g90d615c9d6
Craig Kaiser
craig at bestpractical.com
Wed Jan 8 10:18:07 EST 2020
The branch, 4.4/emailinput-autocomplete-exclude has been created
at 90d615c9d6587ec0dc09487a4b4338e58913279e (commit)
- Log -----------------------------------------------------------------
commit 812dedd63c8549b09dc6b9240cbcb3168faa1c31
Author: Craig Kaiser <craig at bestpractical.com>
Date: Thu May 23 10:17:29 2019 -0400
Jump to unread message, if transaction is not loaded yet load it
If the load history as scroll feature is enabled and a user wants to
jump to an unread message the history leading to the unread transaction
may need to be loaded.
diff --git a/share/html/Ticket/Elements/ScrollShowHistory b/share/html/Ticket/Elements/ScrollShowHistory
index d2aca08a85..e30f1a57f3 100644
--- a/share/html/Ticket/Elements/ScrollShowHistory
+++ b/share/html/Ticket/Elements/ScrollShowHistory
@@ -77,103 +77,111 @@ my $oldestTransactionsFirst = RT->Config->Get("OldestTransactionsFirst", $sessio
</div>
<script type="text/javascript">
-jQuery(function(){
- var isLoading = false, // prevent multiple simultaneous load events
- disableLoading = false, // prevent repeated fruitless attempts
- loadDistanceFromBottom = 1500, // to load before bottom of page is reached
- lastTransactionId = null,
- hash = window.location.hash,
- hashTransactionId = null,
- loadAll = false;
-
- var oldestTransactionsFirst = <% $oldestTransactionsFirst || 0 %>;
-
- var removeLoadingMessage = function() {
- jQuery('.loading-message').remove();
- };
-
- var removeLoadLink = function() {
- jQuery('.error-load-history').remove();
- };
-
- var showLoadingMessage = function() {
- removeLoadingMessage();
- var loadingMessage = jQuery('<span class="loading-message">' +
- loc_key('loading') + '</span>');
- jQuery(".history-container").append(loadingMessage);
- };
-
- var loadingError = function(reason) {
- removeLoadingMessage();
- disableLoading = true;
- removeLoadLink();
- var loadLink = jQuery('<div class="error-load-history">' +
- loc_key('history_scroll_error') + ' ' + reason +
- '<br/><a href="#">' + loc_key('try_again') + '</a></div>');
- jQuery(".history-container").append(loadLink);
- };
-
- var loadHistoryPage = function() {
- if (isLoading || disableLoading) return;
-
- isLoading = true;
- showLoadingMessage();
-
- var queryString = '&oldestTransactionsFirst=' + oldestTransactionsFirst;
- if (lastTransactionId) queryString += '&lastTransactionId=' + lastTransactionId;
- if (loadAll) queryString += '&loadAll=1';
+var isLoading = false, // prevent multiple simultaneous load events
+ disableLoading = false, // prevent repeated fruitless attempts
+ loadDistanceFromBottom = 1500, // to load before bottom of page is reached
+ lastTransactionId = null,
+ hash = window.location.hash,
+ hashTransactionId = null,
+ loadAll = false;
+
+var oldestTransactionsFirst = <% $oldestTransactionsFirst || 0 %>;
+
+var removeLoadingMessage = function() {
+ jQuery('.loading-message').remove();
+};
+
+var removeLoadLink = function() {
+ jQuery('.error-load-history').remove();
+};
+
+var showLoadingMessage = function() {
+ removeLoadingMessage();
+ var loadingMessage = jQuery('<span class="loading-message">' +
+ loc_key('loading') + '</span>');
+ jQuery(".history-container").append(loadingMessage);
+};
+
+var loadingError = function(reason) {
+ removeLoadingMessage();
+ disableLoading = true;
+ removeLoadLink();
+ var loadLink = jQuery('<div class="error-load-history">' +
+ loc_key('history_scroll_error') + ' ' + reason +
+ '<br/><a href="#">' + loc_key('try_again') + '</a></div>');
+ jQuery(".history-container").append(loadLink);
+};
+
+function loadHistoryPage (path) {
+ if (isLoading || disableLoading) return;
+
+ if ( path ) {
+ hash = path;
+ }
+
+ isLoading = true;
+ showLoadingMessage();
+
+ var queryString = '&oldestTransactionsFirst=' + oldestTransactionsFirst;
+ if (lastTransactionId) queryString += '&lastTransactionId=' + lastTransactionId;
+ if (loadAll) queryString += '&loadAll=1';
+
+ // don't load all over and over again
+ loadAll = false;
+
+ // check for link to specific transaction and make sure we load enough to focus it
+ if (hash && !lastTransactionId) {
+ var matches = hash.match(/^#txn-(\d+)$/);
+ if (matches) {
+ hashTransactionId = matches[1];
+ queryString += '&focusTransactionId=' + hashTransactionId;
+ }
+ }
+
+ jQuery.ajax({
+ url: "<% $url |n %>" + queryString,
+ success: function(html) {
+ var transactions = jQuery(html).filter('div.transaction');
+ if(html && transactions.length) {
+ lastTransactionId = transactions.last().data('transactionId');
+ jQuery(".history-container").append(html);
+ if ( transactions.filter(':not(.hidden.end-of-history-list)').length == 0 ) {
+ // if none is visible, automatically load more
+ isLoading = false;
+ loadHistoryPage();
+ return;
+ }
- // don't load all over and over again
- loadAll = false;
+ if (hashTransactionId) { // focus transaction if we are following a link to it
+ hashTransactionId = null;
+ location.href = hash;
+ }
+ } else {
+ disableLoading = true;
- // check for link to specific transaction and make sure we load enough to focus it
- if (hash && !lastTransactionId) {
- var matches = hash.match(/^#txn-(\d+)$/);
- if (matches) {
- hashTransactionId = matches[1];
- queryString += '&focusTransactionId=' + hashTransactionId;
+ // hide 'Load All' link container if we're done loading
+ var loadAllHistoryContainer = jQuery('#LoadAllHistoryContainer');
+ loadAllHistoryContainer.hide();
}
- }
- jQuery.ajax({
- url: "<% $url |n %>" + queryString,
- success: function(html) {
- var transactions = jQuery(html).filter('div.transaction');
- if(html && transactions.length) {
- lastTransactionId = transactions.last().data('transactionId');
- jQuery(".history-container").append(html);
- if ( transactions.filter(':not(.hidden.end-of-history-list)').length == 0 ) {
- // if none is visible, automatically load more
- isLoading = false;
- loadHistoryPage();
- return;
- }
-
- if (hashTransactionId) { // focus transaction if we are following a link to it
- hashTransactionId = null;
- location.href = hash;
- }
- } else {
- disableLoading = true;
-
- // hide 'Load All' link container if we're done loading
- var loadAllHistoryContainer = jQuery('#LoadAllHistoryContainer');
- loadAllHistoryContainer.hide();
- }
+ isLoading = false;
+ removeLoadingMessage();
- isLoading = false;
- removeLoadingMessage();
+ // make sure we load all if we clicked the "Load All" button while we were already loading
+ if (loadAll) loadHistoryPage();
- // make sure we load all if we clicked the "Load All" button while we were already loading
- if (loadAll) loadHistoryPage();
- },
- error: function(xhr, reason) {
- isLoading = false;
- loadingError(reason);
+ if ( path ) {
+ window.location.href = path;
}
- });
- };
+ },
+ error: function(xhr, reason) {
+ isLoading = false;
+ loadingError(reason);
+ }
+ });
+};
+jQuery(function(){
var loadAllHistory = function() {
// hide link container
var loadAllHistoryContainer = jQuery('#LoadAllHistoryContainer');
diff --git a/share/html/Ticket/Elements/ShowUpdateStatus b/share/html/Ticket/Elements/ShowUpdateStatus
index 9c3bc43f90..a26b3d3980 100644
--- a/share/html/Ticket/Elements/ShowUpdateStatus
+++ b/share/html/Ticket/Elements/ShowUpdateStatus
@@ -52,7 +52,7 @@
<&|/l&>There are unread messages on this ticket.</&>
</span>
<span class="new-messages-buttons">
-<a class="button small-button" href="<% RT->Config->Get('WebPath') ."/$DisplayPath/Display.html?id=". $Ticket->id ."#txn-" . $txn->id |n %>"><&|/l&>Jump to Unread</&></a>
+<a class="button small-button" href="<% RT->Config->Get('WebPath') ."/$DisplayPath/Display.html?id=". $Ticket->id ."#txn-" . $txn->id |n %>" onclick="loadHistoryPage('<%"#txn-" . $txn->id%>')"><&|/l&>Jump to Unread</&></a>
<a class="button small-button" href="<% RT->Config->Get('WebPath') ."/$DisplayPath/Display.html?id=". $Ticket->id. "&MarkAsSeen=1" |n %>"><&|/l&>Mark as Seen</&></a>
<a class="button small-button" href="<% RT->Config->Get('WebPath') ."/$DisplayPath/Display.html?id=". $Ticket->id ."&MarkAsSeen=1&Anchor=txn-" . $txn->id |n %>"><&|/l&>Jump & Mark as Seen</&></a>
</span>
commit 4d1a4149ca9b6b44a3443796b0248c20308ca18b
Author: Craig Kaiser <craig at bestpractical.com>
Date: Fri May 24 15:45:38 2019 -0400
Allow saved searches to be sorted
Saved searches are saved in the database as attributes meaning that the
order by cols method usually available is not.
diff --git a/lib/RT/SavedSearches.pm b/lib/RT/SavedSearches.pm
index 224b20a242..d44b8594bb 100644
--- a/lib/RT/SavedSearches.pm
+++ b/lib/RT/SavedSearches.pm
@@ -109,6 +109,23 @@ sub LimitToPrivacy {
}
}
+
+=head2 SortSavedSearches
+
+Sort the list of saved searches. The default is to sort alphabetically.
+
+=cut
+
+sub SortSavedSearches {
+ my $self = shift;
+
+ # Work directly with the internal data structure since saved searches
+ # aren't fully backed by a DB table and can't support typical OrderBy, etc.
+ my @sorted = sort { lcfirst($a->Name) cmp lcfirst($b->Name) } @{$self->{'objects'}};
+ @{$self->{'objects'}} = @sorted;
+ return;
+}
+
RT::Base->_ImportOverlays();
1;
diff --git a/share/html/Elements/SavedSearches b/share/html/Elements/SavedSearches
index 1ef131c10b..9a519873e3 100644
--- a/share/html/Elements/SavedSearches
+++ b/share/html/Elements/SavedSearches
@@ -49,6 +49,7 @@
% foreach my $Object (@Objects) {
% my $SavedSearches = RT::SavedSearches->new($session{CurrentUser});
% $SavedSearches->LimitToPrivacy(join('-',ref($Object),$Object->Id),'Ticket');
+% $SavedSearches->SortSavedSearches();
% my $title;
% if (ref $Object eq 'RT::User' && $Object->Id == $session{CurrentUser}->Id) {
% $title = loc("My saved searches");
commit e83bbb5d6d1c201a0a41ed2f0ffe9f1a287a639c
Author: Craig Kaiser <craig at bestpractical.com>
Date: Sun Jul 14 12:41:23 2019 -0400
Initial demo of favorited transactions portlet
diff --git a/share/html/Elements/ShowTransaction b/share/html/Elements/ShowTransaction
index 790d026b18..129cf2e6c3 100644
--- a/share/html/Elements/ShowTransaction
+++ b/share/html/Elements/ShowTransaction
@@ -45,6 +45,13 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
+<span class="type">
+% if ( $Transaction->FirstAttribute('Favorited') && $Transaction->FirstAttribute('Favorited')->Content->{$session{'CurrentUser'}->Id } ) {
+ <a href="<% $DisplayPath %>?id=<% $Object->id %>&txt-favorite-remove=1&txn-id=<% $Transaction->id %>">Un-Favorite</a>
+% } else {
+ <a href="<% $DisplayPath %>?id=<% $Object->id %>&txt-favorite=1&txn-id=<% $Transaction->id %>">Favorite</a>
+% }
+</span>
<div class="<% join ' ', @classes %>" data-transaction-id="<% $Transaction->id %>">
<div class="metadata">
<span class="type">
diff --git a/share/html/Ticket/Display.html b/share/html/Ticket/Display.html
index 2681a38313..93acaa6ce6 100644
--- a/share/html/Ticket/Display.html
+++ b/share/html/Ticket/Display.html
@@ -160,6 +160,21 @@ if ($ARGS{'id'} eq 'new') {
my $SkipProcessing;
+ if ( $ARGS{'txt-favorite'} or $ARGS{'txt-favorite-remove'} && $ARGS{'txn-id'} ) {
+ my $txn = RT::Transaction->new($session{'CurrentUser'});
+ $txn->Load($ARGS{'txn-id'});
+
+ my $current_value = $txn->FirstAttribute('Favorited') ? $txn->FirstAttribute('Favorited')->Content : ();
+ if ( $ARGS{'txt-favorite'} ) {
+ $current_value->{$session{'CurrentUser'}->Id} = 1;
+ $txn->SetAttribute(Name => 'Favorited', Content => $current_value);
+ }
+ if ( $ARGS{'txt-favorite-remove'} ) {
+ $current_value->{$session{'CurrentUser'}->Id} = 0;
+ $txn->SetAttribute(Name => 'Favorited', Content => $current_value);
+ }
+ }
+
$TicketObj->Atomic(sub{
$m->callback( CallbackName => 'BeforeProcessArguments',
TicketObj => $TicketObj,
diff --git a/share/html/Ticket/Elements/Favorited b/share/html/Ticket/Elements/Favorited
new file mode 100644
index 0000000000..19856b21c2
--- /dev/null
+++ b/share/html/Ticket/Elements/Favorited
@@ -0,0 +1,33 @@
+<&| /Widgets/TitleBox, title => loc("Favorites"), class => 'ticket-info-reminders', &>
+<div>
+<%perl>
+my $txns = RT::Transactions->new($session{'CurrentUser'});
+$txns->LimitToTicket($Ticket->Id);
+
+while (my $tx = $txns->Next) {
+ my $attr = $tx->FirstAttribute('Favorited');
+ next unless $attr;
+
+ if ( $attr->Content->{$session{'CurrentUser'}->Id} ) {
+</%perl>
+ <div>
+ <a href="<% RT->Config->Get('WebPath') ."/Ticket/Display.html?id=".$Ticket->id."#txn-".$tx->id%>">
+ <% $m->comp( '/Elements/ShowTransaction',
+ %ARGS,
+ Object => $Ticket,
+ Transaction => $tx,
+ ShowHeaders => 0,
+ DisplayPath => $HTML::Mason::Commands::r->path_info
+ ) %>
+ </a>
+ </div>
+% }
+% }
+</div>
+</&>
+<%init>
+return unless $Ticket;
+</%init>
+<%args>
+$Ticket => undef
+</%args>
diff --git a/share/html/Ticket/Elements/ShowSummary b/share/html/Ticket/Elements/ShowSummary
index 5aaacb1f87..10566aa71e 100644
--- a/share/html/Ticket/Elements/ShowSummary
+++ b/share/html/Ticket/Elements/ShowSummary
@@ -64,6 +64,8 @@
class => 'ticket-info-people',
&><& /Ticket/Elements/ShowPeople, Ticket => $Ticket &></&>
% $m->callback( %ARGS, CallbackName => 'AfterPeople' );
+ <& Favorited, Ticket => $Ticket &>
+% $m->callback( %ARGS, CallbackName => 'AfterFavorites' );
<& /Ticket/Elements/ShowAttachments, Ticket => $Ticket, Attachments => $Attachments, Count => RT->Config->Get('AttachmentListCount') &>
% $m->callback( %ARGS, CallbackName => 'AfterAttachments' );
<& /Ticket/Elements/ShowRequestor, Ticket => $Ticket &>
commit 90d615c9d6587ec0dc09487a4b4338e58913279e
Author: Craig Kaiser <craig at bestpractical.com>
Date: Wed Jan 8 10:17:27 2020 -0500
Allow for string of user IDs to be passed for exclusion from autocomplete results
diff --git a/share/html/Elements/EmailInput b/share/html/Elements/EmailInput
index 078a2870c4..b38fe48e74 100644
--- a/share/html/Elements/EmailInput
+++ b/share/html/Elements/EmailInput
@@ -79,6 +79,10 @@
data-autocomplete-include-system
% }
+if ($Exclude) {
+ data-autocomplete-exclude="<% $Exclude %>"
+}
+
/>
% if ($EntryHint) {
<br>
@@ -97,4 +101,5 @@ $AutocompleteNobody => 0
$AutocompleteSystem => 0
$EntryHint => ''
$Placeholder => ''
+$Exclude => undef
</%ARGS>
-----------------------------------------------------------------------
More information about the rt-commit
mailing list