1%# BEGIN BPS TAGGED BLOCK {{{ 2%# 3%# COPYRIGHT: 4%# 5%# This software is Copyright (c) 1996-2021 Best Practical Solutions, LLC 6%# <sales@bestpractical.com> 7%# 8%# (Except where explicitly superseded by other copyright notices) 9%# 10%# 11%# LICENSE: 12%# 13%# This work is made available to you under the terms of Version 2 of 14%# the GNU General Public License. A copy of that license should have 15%# been provided with this software, but in any event can be snarfed 16%# from www.gnu.org. 17%# 18%# This work is distributed in the hope that it will be useful, but 19%# WITHOUT ANY WARRANTY; without even the implied warranty of 20%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21%# General Public License for more details. 22%# 23%# You should have received a copy of the GNU General Public License 24%# along with this program; if not, write to the Free Software 25%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26%# 02110-1301 or visit their web page on the internet at 27%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. 28%# 29%# 30%# CONTRIBUTION SUBMISSION POLICY: 31%# 32%# (The following paragraph is not intended to limit the rights granted 33%# to you to modify and distribute this software under the terms of 34%# the GNU General Public License and is only of importance to you if 35%# you choose to contribute your changes and enhancements to the 36%# community by submitting them to Best Practical Solutions, LLC.) 37%# 38%# By intentionally submitting any modifications, corrections or 39%# derivatives to this work, or any other work intended for use with 40%# Request Tracker, to Best Practical Solutions, LLC, you confirm that 41%# you are the copyright holder for those contributions and you grant 42%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, 43%# royalty-free, perpetual, license to use, copy, create derivative 44%# works based on those contributions, and sublicense and distribute 45%# those contributions and any derivatives thereof. 46%# 47%# END BPS TAGGED BLOCK }}} 48<%args> 49$Ticket => undef 50$id => undef 51$ShowCompleted => 0 52$Edit => 0 53$ShowSave => 1 54</%args> 55<%init> 56 57$Ticket = LoadTicket($id) if ($id); 58my $resolve_status = $Ticket->LifecycleObj->ReminderStatusOnResolve; 59 60my $count_reminders = RT::Reminders->new($session{'CurrentUser'}); 61$count_reminders->Ticket($Ticket->id); 62my $count_tickets = $count_reminders->Collection; 63if (!$ShowCompleted) { 64 # XXX: don't break encapsulation if we can avoid it 65 $count_tickets->FromSQL(q{Type = "reminder" AND RefersTo = "} . $Ticket->id . qq{" AND Status != "$resolve_status" }); 66} 67my $has_reminders = $count_tickets->Count; 68 69# We've made changes, let's reload our search 70my $reminder_collection = $count_reminders->Collection; 71</%init> 72<input type="hidden" class="hidden" name="id" value="<% $Ticket->id %>" /> 73<input type="hidden" class="hidden" name="update-reminders" value="1" /> 74% my $editable = 0; 75% if ($has_reminders) { 76<div class="form-row reminder-headers p-2 mt-0"> 77% if ( $Edit ) { 78 <&|/l&>Reminders</&> 79% } else { 80 <div class="col-4"> 81 <&|/l&>Reminder</&> 82 </div> 83 <div class="col-4"> 84 <&|/l&>Due</&> 85 </div> 86 <div class="col-4"> 87 <&|/l&>Owner</&> 88 </div> 89% } 90</div> 91% my $i = 0; 92% while ( my $reminder = $reminder_collection->Next ) { 93<div class="form-row mt-0"> 94% $i++; 95% if ( $reminder->Status eq $resolve_status && !$ShowCompleted ) { 96 <input type="hidden" class="hidden" name="Complete-Reminder-<% $reminder->id %>" value="1" /> 97% $i++; 98% } 99% else { 100% $editable = 1 if !$editable && $reminder->CurrentUserHasRight( 'ModifyTicket' ); 101% if ($Edit) { 102<& SELF:EditEntry, Reminder => $reminder, Ticket => $Ticket, Index => $i &> 103% } else { 104<& SELF:ShowEntry, Reminder => $reminder, Ticket => $Ticket, Index => $i &> 105% } 106% } 107</div> 108% } 109% if ( $editable ) { 110<div class="form-row mt-0"> 111 <i class="mt-2 ml-2"><&|/l&>(Check box to complete)</&></i> 112</div> 113% } 114<hr class="mt-2 mb-2"> 115% } else { 116 117%# we must always include resolved reminders due to the browser 118%# checkbox-with-false-value issue 119% while ( my $reminder = $reminder_collection->Next ) { 120% if ( $reminder->Status eq $resolve_status && !$ShowCompleted ) { 121<input type="hidden" class="hidden" name="Complete-Reminder-<% $reminder->id %>" value="1" /> 122% } 123% } 124% } 125 126% if (lc $Ticket->Status ne "deleted" and $Ticket->QueueObj->CurrentUserHasRight('CreateTicket') and $Ticket->CurrentUserHasRight('ModifyTicket') ) { 127<& SELF:NewReminder, Ticket => $Ticket &> 128% $editable = 1; 129% } 130 131% if ( $editable && $ShowSave ) { 132<div class="form-row mt-0"> 133 <div class="col-12"> 134 <div class="save"><input type="submit" class="button form-control btn btn-primary" value="<&|/l&>Save</&>" /></div> 135 </div> 136</div> 137% } 138<%method NewReminder> 139<%args> 140$Ticket 141</%args> 142<div class="form-row"> 143 <div class="col-12"> 144 <&|/l&>New reminder:</&> 145 <div class="form-row"> 146 <div class="label col-2"> 147 <&|/l&>Subject</&>: 148 </div> 149 <div class="value col-9"> 150 <input type="text" class="form-control reminder-subject" name="NewReminder-Subject" id="NewReminder-Subject" /> 151 </div> 152 </div> 153 <div class="form-row"> 154 <div class="label col-2"> 155 <&|/l&>Owner</&>: 156 </div> 157 <div class="value col-9"> 158 <div class="selectowner"> 159 <& /Elements/SelectOwner, Name => 'NewReminder-Owner', QueueObj => $Ticket->QueueObj, Default=>$session{'CurrentUser'}->id, DefaultValue => 0 &> 160 </div> 161 </div> 162 </div> 163 <div class="form-row"> 164 <div class="label col-2"> 165 <&|/l&>Due</&>: 166 </div> 167 <div class="value col-9"> 168 <& /Elements/SelectDate, Name => "NewReminder-Due", Default => "" &> 169 </div> 170 </div> 171 </div> 172</div> 173</%method> 174<%method EditEntry> 175<%args> 176$Reminder 177$Ticket 178$Index 179</%args> 180 181 <div class="col-12 <% $Index%2 ? 'oddline' : 'evenline' %>" id="reminder-<% $Reminder->id %>"> 182% unless ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { 183 <input class="custom-control-input" name="Complete-Reminder-<% $Reminder->id %>" type="hidden" 184 value=<% $Reminder->Status eq $Reminder->LifecycleObj->ReminderStatusOnResolve ? 1 : 0 %> 185 /> 186% } 187 <div class="form-row m-0 pb-2 pt-2"> 188 <div class="col-1"> 189 <div class="custom-control custom-checkbox"> 190 <input class="custom-control-input" type="checkbox" value="1" id="Complete-Reminder-<% $Reminder->id %>" name="Complete-Reminder-<% $Reminder->id %>" <% $Reminder->Status eq $Reminder->LifecycleObj->ReminderStatusOnResolve ? 'checked="checked"' : '' |n %> 191% unless ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { 192disabled="disabled" 193% } 194 /> 195 <label class="custom-control-label" for="Complete-Reminder-<% $Reminder->id %>"></label> 196 </div> 197 </div> 198 <div class="label col-1"> 199 <&|/l&>Subject</&>: 200 </div> 201 <div class="value col-9"> 202 <input type="text" class="reminder-subject form-control" name="Reminder-Subject-<% $Reminder->id %>" value="<% $Reminder->Subject %>" 203% unless ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { 204readonly="readonly" 205% } 206 /> 207 </div> 208 </div> 209 <div class="form-row m-0 pb-2"> 210 <div class="label col-2"> 211 <&|/l&>Owner</&>: 212 </div> 213 <div class="value col-9"> 214 <div class="row"> 215 <div class="col-auto"> 216 <div class="selectowner"> 217 <& /Elements/SelectOwner, Name => 'Reminder-Owner-'.$Reminder->id, QueueObj => $Ticket->QueueObj, Default => $Reminder->Owner, DefaultValue => 0 &> 218 </div> 219 </div> 220 <div class="label col-auto"> 221 <&|/l&>Due</&>: 222 </div> 223 <div class="value"> 224% if ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { 225 <div class="float-left"> 226 <& /Elements/SelectDate, Name => 'Reminder-Due-'.$Reminder->id &> 227 </div> 228 <div class="float-left ml-3"> 229 <span class="current-value form-control">(<% $Reminder->DueObj->AsString %>)</span> 230 </div> 231% } 232 </div> 233 </div> 234 </div> 235 </div> 236 237 </div> 238</%method> 239<%method ShowEntry> 240<%args> 241$Reminder 242$Ticket 243$Index 244</%args> 245% my $dueobj = $Reminder->DueObj; 246% my $overdue = $dueobj->IsSet && $dueobj->Diff < 0 ? 1 : 0; 247 248<div class="col-12 <% $Index%2 ? 'oddline' : 'evenline' %>" id="reminder-<% $Reminder->id %>"> 249 <div class="form-row m-0 pb-2 pt-2"> 250% unless ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { 251 <div class="col-4"> 252 <input name="Complete-Reminder-<% $Reminder->id %>" type="hidden" 253 value=<% $Reminder->Status eq $Reminder->LifecycleObj->ReminderStatusOnResolve ? 1 : 0 %> 254 /> 255 </div> 256% } 257 <div class="col-4"> 258 <div class="custom-control custom-checkbox"> 259 <input class="custom-control-input" type="checkbox" value="1" id="Complete-Reminder-<% $Reminder->id %>" name="Complete-Reminder-<% $Reminder->id %>" <% $Reminder->Status eq $Reminder->LifecycleObj->ReminderStatusOnResolve ? 'checked="checked"' : '' |n %> 260% unless ( $Reminder->CurrentUserHasRight('ModifyTicket') ) { 261 disabled="disabled" 262% } 263 /> 264 <label class="custom-control-label" for="Complete-Reminder-<% $Reminder->id %>"><% $Reminder->Subject %></label> 265 </div> 266 </div> 267 268 <div class="col-4"> 269 <% $overdue ? '<span class="overdue">' : '' |n %><% $dueobj->AgeAsString || loc('Not set') %><% $overdue ? '</span>' : '' |n %> 270 </div> 271 <div class="col-4"> 272 <& /Elements/ShowUser, User => $Reminder->OwnerObj &> 273 </div> 274 </div> 275</div> 276</%method> 277