One of the things stopping my team switching over to OTRS is the lack of an overall Status view showing _all_ open (inc. new) tickets no matter whether they are locked or not and who is working on them.
I have done a very quick hack to show you the sort of thing I am thinking about. This patch adds a new StatusView page. I only did the Standard theme since it needs a lot more work but is functional. *** otrs/Kernel/Config/Modules.pm Thu Oct 3 22:10:13 2002 --- ../otrs/Kernel/Config/Modules.pm Fri Oct 11 16:39:06 2002 *************** *** 32,37 **** --- 32,38 ---- # web agent middle ware modules use Kernel::Modules::AgentQueueView; + use Kernel::Modules::AgentStatusView; use Kernel::Modules::AgentMove; use Kernel::Modules::AgentZoom; use Kernel::Modules::AgentAttachment; *** otrs/Kernel/Output/HTML/Agent.pm Mon Sep 23 14:53:44 2002 --- ../otrs/Kernel/Output/HTML/Agent.pm Mon Oct 14 12:55:06 2002 *************** *** 1016,1021 **** --- 1016,1043 ---- return $Output; } # -- + sub AgentStatusView { + my $Self = shift; + my %Param = @_; + # create & return output + return $Self->Output(TemplateFile => 'AgentStatusView', Data => \%Param); + } + # -- + sub AgentStatusViewTable { + my $Self = shift; + my %Param = @_; + $Param{Age} = $Self->CustomerAge(Age => $Param{Age}, Space => ' ') || 0; + # do html quoteing + foreach (qw(State Queue Owner Lock)) { + $Param{$_} = $Self->Ascii2Html(Text => $Param{$_}, Max => 16); + } + foreach (qw(Subject)) { + $Param{$_} = $Self->Ascii2Html(Text => $Param{$_}, Max => 20); + } + # create & return output + return $Self->Output(TemplateFile => 'AgentStatusViewTable', Data => \%Param); + } + # -- 1; *** otrs/Kernel/Output/HTML/Standard/AgentNavigationBar.dtl Thu Oct 3 22:15:07 2002 --- ../otrs/Kernel/Output/HTML/Standard/AgentNavigationBar.dtl Mon Oct 14 13:43:16 2002 *************** *** 27,32 **** --- 27,33 ---- <br> $Env{"Box0"}<a href="$Env{"Baselink"}&Action=AgentQueueView">$Text{"QueueView"}</a>$Env{"Box1"} $Env{"Box0"}<a href="$Env{"Baselink"}&Action=AgentPhone">$Text{"PhoneView"}</a>$Env{"Box1"} + $Env{"Box0"}<a href="$Env{"Baselink"}&Action=AgentStatusView">$Text{"StatusView"}</a>$Env{"Box1"} </td> <td align="right" width="60%"> $Env{"Box0"}<a href="$Env{"Baselink"}&Action=AgentUtilities">$Text{"Utilities"}</a>$Env{"Box1"} And finally here are new new files: Kernel/Modules/AgentStatusView.pm --------------------------------------------------------------------------------------------------- # -- # Kernel/Modules/AgentStatusView.pm - status for all open tickets # # -- # $Id$ # -- # This software comes with ABSOLUTELY NO WARRANTY. For details, see # the enclosed file COPYING for license information (GPL). If you # did not receive this file, see http://www.gnu.org/licenses/gpl.txt. # -- package Kernel::Modules::AgentStatusView; use strict; use vars qw($VERSION); $VERSION = '$Revision: 1.20 $'; $VERSION =~ s/^.*:\s(\d+\.\d+)\s.*$/$1/; # -- sub new { my $Type = shift; my %Param = @_; # allocate new hash for object my $Self = {}; bless ($Self, $Type); # get common opjects foreach (keys %Param) { $Self->{$_} = $Param{$_}; } # check all needed objects foreach ( 'ParamObject', 'DBObject', 'QueueObject', 'LayoutObject', 'ConfigObject', 'LogObject', 'UserObject', ) { die "Got no $_" if (!$Self->{$_}); } # -- # get config data # -- # default viewable tickets a page $Self->{ViewableTickets} = $Self->{ConfigObject}->Get('ViewableTickets'); # viewable tickets a page $Self->{Limit} = $Self->{ParamObject}->GetParam(Param => 'Limit') || $Self->{ViewableTickets}; # sure is sure! $Self->{MaxLimit} = $Self->{ConfigObject}->Get('MaxLimit') || 300; if ($Self->{Limit} > $Self->{MaxLimit}) { $Self->{Limit} = $Self->{MaxLimit}; } # -- # all static variables # -- $Self->{ViewableLocks} = $Self->{ConfigObject}->Get('ViewableLocks') || die 'No Config entry "ViewableLocks"!'; $Self->{ViewableStats} = $Self->{ConfigObject}->Get('ViewableStats') || die 'No Config entry "ViewableStats"!'; $Self->{ViewableSenderTypes} = $Self->{ConfigObject}->Get('ViewableSenderTypes') || die 'No Config entry "ViewableSenderTypes"!'; $Self->{CustomQueue} = $Self->{ConfigObject}->Get('CustomQueue') || '???'; return $Self; } # -- sub Run { my $Self = shift; my %Param = @_; my $QueueID = $Self->{QueueID}; # -- # store last screen # -- if (!$Self->{SessionObject}->UpdateSessionID( SessionID => $Self->{SessionID}, Key => 'LastScreen', Value => $Self->{RequestedURL}, )) { my $Output = $Self->{LayoutObject}->Header(Title => 'Error'); $Output .= $Self->{LayoutObject}->Error(); $Output .= $Self->{LayoutObject}->Footer(); return $Output; } # starting with page ... my $Refresh = ''; if ($Self->{UserRefreshTime}) { $Refresh = 60 * $Self->{UserRefreshTime}; } my $Output = $Self->{LayoutObject}->Header( Title => 'QueueView', Refresh => $Refresh, ); # get user lock data my %LockedData = $Self->{TicketObject}->GetLockedCount(UserID => $Self->{UserID}); # build NavigationBar $Output .= $Self->{LayoutObject}->NavigationBar(LockData => \%LockedData); # -- # build queue view ... # -- my @ViewableQueueIDs = (); if ($QueueID == 0) { @ViewableQueueIDs = $Self->{QueueObject}->GetAllCustomQueues( UserID => $Self->{UserID} ); } else { @ViewableQueueIDs = ($QueueID); } # to get the output faster! print $Output; $Output = ''; # -- # get data (viewable tickets...) # -- my @ViewableTickets = (); if (@ViewableQueueIDs) { my @ViewableLocks = @{$Self->{ViewableLocks}}; my @ViewableStats = @{$Self->{ViewableStats}}; my $SQL = "SELECT st.id, st.queue_id FROM " . " ticket st, ticket_state tsd " . " WHERE " . " tsd.id = st.ticket_state_id " . " AND " . " tsd.name in ( ${\(join ', ', @ViewableStats)} ) " . " AND " . " st.queue_id in ( ${\(join ', ', @ViewableQueueIDs)} ) " . " ORDER BY st.ticket_priority_id DESC, st.create_time_unix ASC "; $Self->{DBObject}->Prepare(SQL => $SQL, Limit => $Self->{Limit}); while (my @RowTmp = $Self->{DBObject}->FetchrowArray()) { my $Data = { TicketID => $RowTmp[0], TicketQueueID => $RowTmp[1], }; push (@ViewableTickets, $Data); } } # -- # show ticket's # -- my $OutputTable = ""; foreach my $DataTmp (@ViewableTickets) { my %Data = %$DataTmp; $OutputTable .= ShowTicketStatus($Self, %Data, QueueID => $QueueID, ); } $Output .= $Self->{LayoutObject}->AgentStatusView( StatusTable => $OutputTable); # get page footer $Output .= $Self->{LayoutObject}->Footer(); # return page return $Output; } # -- # ShowTicket # -- sub ShowTicketStatus { my $Self = shift; my %Param = @_; my $TicketID = $Param{TicketID} || return; my $QueueID = $Param{QueueID} || 0; my $TicketQueueID = $Param{TicketQueueID} || ''; my $Output = ''; # -- # get articles # -- my @ShownViewableTicket = (); my $SQL = "SELECT sa.ticket_id, sa.a_subject, " . " st.create_time_unix, st.user_id, " . " st.customer_id, sq.name as queue, sa.id as article_id, " . " st.id, st.tn, sp.name, sd.name as state, st.queue_id, " . " st.create_time, ". " su.$Self->{ConfigObject}->{DatabaseUserTableUser} " . " FROM " . " article sa, ticket st, ticket_priority sp, ticket_state sd, " . " article_sender_type sdt, queue sq, " . " $Self->{ConfigObject}->{DatabaseUserTable} su " . " WHERE " . " sa.ticket_id = st.id " . " AND " . " sa.article_sender_type_id = sdt.id " . " AND " . " sq.id = st.queue_id" . " AND " . " sp.id = st.ticket_priority_id " . " AND " . " st.ticket_state_id = sd.id " . " AND " . " sa.ticket_id = $TicketID " . " AND " . " su.$Self->{ConfigObject}->{DatabaseUserTableUserID} = st.user_id " . " AND " . " sdt.name in ( ${\(join ', ', @{$Self->{ViewableSenderTypes}})} ) " . " ORDER BY sa.create_time DESC "; $Self->{DBObject}->Prepare(SQL => $SQL, Limit => 1); while (my $Data = $Self->{DBObject}->FetchrowHashref() ) { my $Age = time() - $$Data{create_time_unix}; my $TicketOverTime = ''; if ($$Data{escalation_time} && !$$Data{ticket_answered}) { $TicketOverTime = (time() - ($$Data{incoming_time} + ($$Data{escalation_time}*60))); } if ($$Data{a_content_type} && $$Data{a_content_type} =~ /charset=(.*)(| |\n)/i) { $$Data{ContentCharset} = $1; } if ($$Data{a_content_type} && $$Data{a_content_type} =~ /^(.+?\/.+?)( |;)/i) { $$Data{MimeType} = $1; } # Condense down the subject my $TicketHook = $Self->{ConfigObject}->Get('TicketHook'); my $subject = $$Data{a_subject}; $subject =~ s/^RE:*//i; $subject =~ s/\[${TicketHook}:\s*\d+\]//; $Output .= $Self->{LayoutObject}->AgentStatusViewTable( TicketNumber => $$Data{tn}, Priority => $$Data{name}, State => $$Data{state}, TicketID => $$Data{id}, ArticleID => $$Data{article_id}, Owner => $$Data{login}, Subject => $subject, Age => $Age, TicketOverTime => $TicketOverTime, Created => $$Data{create_time}, QueueID => $QueueID, Queue => $$Data{queue}, CustomerID => $$Data{customer_id}, ); push (@ShownViewableTicket, $$Data{id}); } # if there is no customer article avalible! Error! my $Hit = 0; foreach (@ShownViewableTicket) { if ($_ == $TicketID) { $Hit = 1; } } if ($Hit == 0) { $Output .= $Self->{LayoutObject}->Error( Message => "No customer article found!! (TicketID=$TicketID)", Comment => 'Please contact your admin', ); $Self->{LogObject}->Log( Priority => 'error', Message => "No customer article found!! (TicketID=$TicketID)", Comment => 'Please contact your admin', ); } # return page return $Output; } # -- 1; ------------------------------------------------------------------------------------------------ Kernel/Output/HTML/Standard/AgentStatusViewTable.dtl ------------------------------------------------------------------------------------------------ # -- # AgentStatusViewTable.dtl # -- # $Id$ # -- # This software comes with ABSOLUTELY NO WARRANTY. For details, see # the enclosed file COPYING for license information (GPL). If you # did not receive this file, see http://www.gnu.org/licenses/gpl.txt. # -- <!-- start record --> <tr> <td align="center"><a href="$Env{"Baselink"}&Action=AgentZoom&TicketID=$Data{"TicketID"}&QueueID=$Data{"QueueID"}">$Data{"TicketNumber"}</a></td> <td>$Data{"Age"}</td> <td>$Data{"Subject"}</td> <td>$Data{"State"}</td> <td>$Data{"Queue"}</td> <td>$Data{"Owner"}</td> <td>$Data{"CustomerId"}</td> </tr> <!-- end record --> --------------------------------------------------------------------------------------------------- Kernel/Output/HTML/Standard/AgentStatusView.dtl ---------------------------------------------------------------------------------------------------- # -- # AgentStatusView.dtl - # Copyright (C) 2001 Martin Edenhofer <[EMAIL PROTECTED]> # -- # $Id$ # -- # This software comes with ABSOLUTELY NO WARRANTY. For details, see # the enclosed file COPYING for license information (GPL). If you # did not receive this file, see http://www.gnu.org/licenses/gpl.txt. # -- <!-- start form --> <table border="0" width="100%" cellspacing="0" cellpadding="3" cols="2"> <tr> <td align="left" bgcolor="$Env{"BGTableColor0"}"> <b><font color="$Env{"FontColor1"}">$Env{"Box0"}$Text{"Ticket Status"}$Env{"Box1"}</font></b> </font> </td> <td align="right" bgcolor="$Env{"BGTableColor0"}"> <b><font color="$Env{"FontColor1"}">-</font></b> </font> </td> </tr> </table> <table border="0" width="100%" cellspacing="0" cellpadding="3"> <tr bgcolor="$Env{"BGTableColor1"}"> <td align="center" valign="top"> <table border="0" width="100%" cellspacing="0" cellpadding="3" cols="5"> <tr> <th width="15%">$Config{"TicketHook"}</th> <th width="35%">$Text{"Age"}</th> <th width="70%">$Text{"Subject"}</th> <th width="10%">$Text{"State"}</th> <th width="15%">$Text{"Queue"}</th> <th width="15%">$Text{"Owner"}</th> <th width="10%">$Text{"CustomerId"}</th> </tr> $Data{"StatusTable"} </table> </td> </tr> </table> <!-- end form --> --------------------------------------------------------------------------------------------------- PS, Does the mailing list accept attachments or is there a better place to post such patches? -- Phil Davis IT Action _______________________________________________ OTRS mailing list: otrs - Webpage: http://otrs.org/ Archive: http://lists.otrs.org/pipermail/otrs To unsubscribe: http://lists.otrs.org/cgi-bin/listinfo/otrs