vendor/uvdesk/core-framework/Resources/views/ticketList.html.twig line 1

Open in your IDE?
  1. {% extends "@UVDeskCoreFramework//Templates//layout.html.twig" %}
  2. {% block title %}{{ 'Tickets'|trans }}{% endblock %}
  3. {% block templateCSS %}
  4.     <style>
  5.         .pagination {
  6.         display: flex;
  7.         justify-content: center;
  8.         margin-top: 10px;
  9.         }
  10.         .pagination a,
  11.         .pagination span {
  12.         display: inline-block;
  13.         padding: 5px 10px;
  14.         margin-right: 5px;
  15.         color: #333;
  16.         text-decoration: none;
  17.         background-color: #eee;
  18.         border-radius: 3px;
  19.         cursor: pointer;
  20.         }
  21.         .pagination a:hover {
  22.         background-color: #ccc;
  23.         }
  24.         .pagination span.current {
  25.         font-weight: bold;
  26.         }
  27.         .pagination a.disabled,
  28.         .pagination span.disabled {
  29.         cursor: not-allowed;
  30.         opacity: 0.6;
  31.         }
  32.         .pagination .dots {
  33.         margin-right: 10px;
  34.         }
  35.         .modal {
  36.         display: none;
  37.         position: fixed;
  38.         z-index: 9999;
  39.         left: 0;
  40.         top: 0;
  41.         width: 100%;
  42.         height: 100%;
  43.         overflow: auto;
  44.   
  45.         }
  46.         .modal-content {
  47.         background-color: white;
  48.         margin: 0 auto;
  49.         margin-top: 10%;
  50.         padding: 20px;
  51.         border: 1px solid #888;
  52.         width: 60%;
  53.         max-height: 80%;
  54.         overflow-y: auto;
  55.         position: relative;
  56.         }
  57.         .close {
  58.         color: #aaa;
  59.         position: absolute;
  60.         top: 10px;
  61.         right: 20px;
  62.         font-size: 28px;
  63.         font-weight: bold;
  64.         }
  65.         .close:hover,
  66.         .close:focus {
  67.         color: black;
  68.         text-decoration: none;
  69.         cursor: pointer;
  70.         }
  71.         table {
  72.         width: 100%;
  73.         border-collapse: collapse;
  74.         }
  75.         th, td {
  76.         padding: 8px;
  77.         text-align: left;
  78.         border-bottom: 1px solid #ddd;
  79.         }
  80.         
  81.      .icon-container {
  82.             width: 40px;
  83.             height: 40px;
  84.             position: relative;
  85.         }
  86.         .status-circle {
  87.             width: 15px;
  88.             height: 15px;
  89.             border-radius: 50%;
  90.             background-color: green;
  91.             border: 2px solid white;
  92.             bottom: 0;
  93.             right: 0;
  94.             position: absolute;
  95.         }
  96.         .userOnlineImg{
  97.             height: 100%;
  98.             width: 100%;
  99.             border-radius: 50%;
  100.         }
  101.         .uv-dropdown.asset-visibility li input {
  102.             z-index: 100;
  103.         }
  104.         .uv-dropdown.asset-visibility ul li label {
  105.             color: #333333;
  106.             font-size: 17px;
  107.             font-weight: 500;
  108.             text-transform: capitalize;
  109.             cursor: pointer;
  110.             margin: auto;
  111.         }
  112.         .uv-table td a {
  113.             color: #333333;
  114.         }
  115.         .uv-table.uv-list-view table tbody td.uv-width-100 {
  116.             width: 100px !important;
  117.         }
  118.         .uv-table.uv-list-view td[data-index="agent"] {
  119.             white-space: nowrap;
  120.         }
  121.         .uv-view:not(.uv-stack-view) .uv-table td a {
  122.             display: inline-block;
  123.             width: 100%;
  124.         }
  125.         .uv-action-bar-col-lt.uv-width-100 {
  126.             width: 100% !important;
  127.         }
  128.         #quick-view-modal .uv-view {
  129.             padding: 0;
  130.             overflow-y: visible;
  131.             display: inline-block;
  132.             position: relative;
  133.         }
  134.         #quick-view-modal .uv-view .uv-ticket-section {
  135.             margin-top: 0;
  136.         }
  137.         #quick-view-modal .uv-ticket-head {
  138.             border-top: 1px solid #d3d3d3;
  139.             padding-top: 10px;
  140.             padding-bottom: 10px;
  141.         }
  142.         #quick-view-modal .uv-ticket-strip {
  143.             padding-bottom: 0;
  144.         }
  145.         #quick-view-modal .uv-ticket-strip .uv-btn-tag {
  146.             margin-bottom: 0;
  147.         }
  148.         #quick-view-modal .quick-view-navigation {
  149.             position: absolute;
  150.             right: 50px;
  151.             top: 9px;
  152.         }
  153.         #quick-view-modal .quick-view-navigation ~ a {
  154.             width: calc(100% - 100px);
  155.             display: inline-block;
  156.         }
  157.         #quick-view-modal .uv-btn-tag[disabled="disabled"] {
  158.             opacity: .4;
  159.             cursor: not-allowed;
  160.             border-color: #B1B1AE !important;
  161.         }
  162.         #quick-view-modal .uv-loader {
  163.             transform: scale(0.5);
  164.             top: 14px;
  165.             right: 60px;
  166.         }
  167.         tr.unread {
  168.             background: #f1f1f1;
  169.         }
  170.         .uv-table table tbody tr.not-assigned td {
  171.             border-bottom: 1px solid #ffcacc;
  172.         }
  173.         @media screen and (max-width: 500px) {
  174.             .uv-action-bar label {
  175.                 display: inline-block;
  176.             }
  177.         }
  178.         
  179.           /* Estilos para el sistema de alertas de tickets */
  180.         .ticket-alert-overlay {
  181.             display: none;
  182.             position: fixed;
  183.             z-index: 10000;
  184.             left: 0;
  185.             top: 0;
  186.             width: 100%;
  187.             height: 100%;
  188.             background-color: rgba(0, 0, 0, 0.5);
  189.         }
  190.         .ticket-alert-modal {
  191.             background-color: white;
  192.             margin: 5% auto;
  193.             padding: 0;
  194.             border-radius: 8px;
  195.             width: 80%;
  196.             max-width: 600px;
  197.             max-height: 80%;
  198.             overflow-y: auto;
  199.             box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
  200.         }
  201.         .ticket-alert-header {
  202.             background: linear-gradient(135deg, #ff6b6b, #ee5a24);
  203.             color: white;
  204.             padding: 20px;
  205.             border-radius: 8px 8px 0 0;
  206.             position: relative;
  207.         }
  208.         .ticket-alert-header h3 {
  209.             margin: 0;
  210.             font-size: 1.5em;
  211.             font-weight: 600;
  212.         }
  213.         .ticket-alert-close {
  214.             position: absolute;
  215.             top: 15px;
  216.             right: 20px;
  217.             background: none;
  218.             border: none;
  219.             color: white;
  220.             font-size: 24px;
  221.             cursor: pointer;
  222.             font-weight: bold;
  223.         }
  224.         .ticket-alert-close:hover {
  225.             opacity: 0.8;
  226.         }
  227.         .ticket-alert-body {
  228.             padding: 20px;
  229.         }
  230.         .ticket-alert-section {
  231.             margin-bottom: 25px;
  232.         }
  233.         .ticket-alert-section h4 {
  234.             color: #333;
  235.             margin-bottom: 15px;
  236.             font-size: 1.2em;
  237.             font-weight: 600;
  238.             border-bottom: 2px solid #ff6b6b;
  239.             padding-bottom: 8px;
  240.         }
  241.         .ticket-alert-section h4::before {
  242.             content: "⚠️";
  243.             margin-right: 8px;
  244.         }
  245.         .ticket-alert-list {
  246.             list-style: none;
  247.             padding: 0;
  248.             margin: 0;
  249.         }
  250.         .ticket-alert-item {
  251.             background: #f8f9fa;
  252.             border: 1px solid #e9ecef;
  253.             border-radius: 6px;
  254.             padding: 15px;
  255.             margin-bottom: 10px;
  256.             display: flex;
  257.             justify-content: space-between;
  258.             align-items: center;
  259.             transition: all 0.3s ease;
  260.         }
  261.         .ticket-alert-item:hover {
  262.             background: #e9ecef;
  263.             border-color: #ff6b6b;
  264.             transform: translateY(-2px);
  265.             box-shadow: 0 4px 12px rgba(255, 107, 107, 0.2);
  266.         }
  267.         .ticket-alert-info {
  268.             flex: 1;
  269.         }
  270.         .ticket-alert-id {
  271.             display: block;
  272.             font-weight: 600;
  273.             color: #333;
  274.             margin-bottom: 5px;
  275.         }
  276.         .ticket-alert-subject {
  277.             display: block;
  278.             color: #666;
  279.             font-size: 0.9em;
  280.         }
  281.         .ticket-alert-days {
  282.             background: #ff6b6b;
  283.             color: white;
  284.             padding: 5px 12px;
  285.             border-radius: 20px;
  286.             font-weight: 600;
  287.             font-size: 0.9em;
  288.             white-space: nowrap;
  289.         }
  290.         .ticket-alert-actions {
  291.             display: flex;
  292.             gap: 10px;
  293.             justify-content: flex-end;
  294.             margin-top: 20px;
  295.             padding-top: 20px;
  296.             border-top: 1px solid #e9ecef;
  297.         }
  298.         .ticket-alert-btn {
  299.             padding: 10px 20px;
  300.             border: none;
  301.             border-radius: 6px;
  302.             cursor: pointer;
  303.             font-weight: 600;
  304.             transition: all 0.3s ease;
  305.             text-decoration: none;
  306.             display: inline-block;
  307.         }
  308.         .ticket-alert-btn-primary {
  309.             background: #ff6b6b;
  310.             color: white;
  311.         }
  312.         .ticket-alert-btn-primary:hover {
  313.             background: #ee5a24;
  314.             transform: translateY(-2px);
  315.         }
  316.         .ticket-alert-btn-secondary {
  317.             background: #6c757d;
  318.             color: white;
  319.         }
  320.         .ticket-alert-btn-secondary:hover {
  321.             background: #5a6268;
  322.         }
  323.         .ticket-alert-btn-remind {
  324.             background: #ffc107;
  325.             color: #212529;
  326.         }
  327.         .ticket-alert-btn-remind:hover {
  328.             background: #e0a800;
  329.         }
  330.         .ticket-alert-empty {
  331.             text-align: center;
  332.             color: #666;
  333.             font-style: italic;
  334.             padding: 40px 20px;
  335.         }
  336.         /* Indicador de alerta en el sidebar */
  337.         .alert-indicator {
  338.             position: absolute;
  339.             top: -5px;
  340.             right: -5px;
  341.             background: #ff6b6b;
  342.             color: white;
  343.             border-radius: 50%;
  344.             width: 20px;
  345.             height: 20px;
  346.             display: flex;
  347.             align-items: center;
  348.             justify-content: center;
  349.             font-size: 12px;
  350.             font-weight: bold;
  351.             animation: pulse 2s infinite;
  352.         }
  353.         @keyframes pulse {
  354.             0% {
  355.                 transform: scale(1);
  356.                 box-shadow: 0 0 0 0 rgba(255, 107, 107, 0.7);
  357.             }
  358.             70% {
  359.                 transform: scale(1.1);
  360.                 box-shadow: 0 0 0 10px rgba(255, 107, 107, 0);
  361.             }
  362.             100% {
  363.                 transform: scale(1);
  364.                 box-shadow: 0 0 0 0 rgba(255, 107, 107, 0);
  365.             }
  366.         }
  367.         
  368.         
  369.     </style>
  370. {% endblock %}
  371. {% block pageContent %}
  372.     {# Quick View Popup #}
  373.     <div class="uv-pop-up-overlay" id="quick-view-modal">
  374.         <div class="uv-pop-up-box uv-pop-up-wide"></div>
  375.     </div>
  376.     <div class="uv-inner-section">
  377.         {# Ticket Sidebar #}
  378.         <div class="uv-aside" {% if app.request.cookies and app.request.cookies.get('uv-asideView') %} style="display: none;" {% endif %} >
  379.             <div class="uv-aside-default">
  380.                 <div class="uv-aside-head">
  381.                     <div class="uv-aside-title">
  382.                         <h6>{{ 'Tickets'|trans }}</h6>
  383.                     </div>
  384.                     <div class="uv-aside-back">
  385.                         <span onclick="history.length > 1 ? history.go(-1) : window.location = '{{ path("helpdesk_member_dashboard") }}';">{{ 'Back'|trans }}</span>
  386.                     </div>
  387.                 </div>
  388.                 <div class="uv-aside-nav">
  389.                     <ul>
  390.                         {# Predefined Label List #}
  391.                         <ul class="predefined-label-list uv-aside-list">
  392.                             <li>
  393.                                 <a href="#" class="uv-aside-active">{{ 'All'|trans }} <span class="uv-flag-gray uv-flag-dark">0</span></a>
  394.                                 {# Status ticket count list #}
  395.                                 <ul class="status-list">
  396.                                     <li>
  397.                                         <a href="#" data-id="1" class="uv-aside-nav-active"><span class="name">{{ 'Open'|trans }}</span><span class="uv-flag-gray">0</span></a>
  398.                                     </li>
  399.                                   
  400.                                     <li>
  401.                                         <a href="#" data-id="2"><span class="name">{{ 'Pending'|trans }}</span><span class="uv-flag-gray">0</span></a>
  402.                                     </li>
  403.                                     <li>
  404.                                         <a href="#" data-id="6"><span class="name">{{ 'Answered'|trans }}</span><span class="uv-flag-gray">0</span></a>
  405.                                     </li>
  406.                                     <li>
  407.                                         <a href="#" data-id="3"><span class="name">{{ 'Resolved'|trans }}</span><span class="uv-flag-gray">0</span></a>
  408.                                     </li>
  409.                                     <li>
  410.                                         <a href="#" data-id="4"><span class="name">{{ 'Closed'|trans }}</span><span class="uv-flag-gray">0</span></a>
  411.                                     </li>
  412.                                    
  413.                                     <li>
  414.                                         <a href="#" data-id="5"><span class="name">{{ 'Spam'|trans }}</span><span class="uv-flag-gray">0</span></a>
  415.                                     </li>
  416.                                 </ul>
  417.                             </li>
  418.                             <li>
  419.                                 <a href="#new">{{ 'New'|trans }} <span class="uv-flag-gray uv-flag-dark">0</span></a>
  420.                             </li>
  421.                             <li>
  422.                                 <a href="#unassigned">{{ 'UnAssigned'|trans }} <span class="uv-flag-gray uv-flag-dark">0</span></a>
  423.                             </li>
  424.                             <li>
  425.                                 <a href="#notreplied">{{ 'UnAnswered'|trans }} <span class="uv-flag-gray uv-flag-dark">0</span></a>
  426.                             </li>
  427.                             <li>
  428.                                 <a href="#mine">{{ 'My Tickets'|trans }} <span class="uv-flag-gray uv-flag-dark">0</span></a>
  429.                             </li>
  430.                             <li>
  431.                                 <a href="#starred">{{ 'Starred'|trans }} <span class="uv-flag-gray uv-flag-dark">0</span></a>
  432.                             </li>
  433.                             <li>
  434.                                 <a href="#trashed" style="border-bottom: none">{{ 'Trashed'|trans }} <span class="uv-flag-gray uv-flag-dark">0</span></a>
  435.                             </li>
  436.                         </ul>
  437.                         {# Custom Label List #}
  438.                         <ul class="uv-aside-custom"></ul>
  439.                     </ul>
  440.                 </div>
  441.                {#<a class="uv-btn-small add-new-label" href="#"><span class="uv-icon-add"></span> {{ 'Label'|trans }}</a>#}
  442.             </div>
  443.             <!-- Label add and edit -->
  444.             <div class="uv-add-edit-label" style="display: block"></div>
  445.          <label>{{ 'Users Online'|trans }}</label>
  446.             <ul style="list-style-type: none; padding:5px" >
  447.                 {% for user in user_service.getUsersOnline %}
  448.                     <li data-id="{{user.id}}"  >
  449.                        <div class="icon-container">
  450.                                {% if user.imagePath != null %}
  451.                                    <img class="userOnlineImg" src="{{ app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') }}{{ user.imagePath}}"/>
  452.                                {% else %}
  453.                                    <img class="userOnlineImg" src="{{ asset(default_agent_image_path) }}" alt=""/>
  454.                                {% endif %}
  455.                             <div class='status-circle'></div>
  456.                        </div>
  457.                        <span >  {{ user.firstName }}</span>
  458.                        <span>  <p style="color:blue;font-size:12px;"> ({{ user.team }}) -  <span style="color:green;font-size:12px;"> Open Tickets: {{ user.countTicket }} </span> </p> </span>
  459.                     </li>
  460.                 {% endfor %}
  461.             </ul>
  462.         </div>
  463.         {# Ticket List #}
  464.         <div class="uv-view {% if app.request.cookies and app.request.cookies.get('uv-asideView') %} uv-aside-view {% endif %}">
  465.             <h1>{{ 'Tickets'|trans }}</h1>
  466.             
  467.             <ul style="list-style-type: none; padding:5px">
  468.             {% set page = app.request.query.get('page', 1) %}
  469.             {% set perPage = 10 %} <!-- Número de tickets por página -->
  470.             {% set ticketsData = user_service.getAnsweredTickets(page, perPage) %}
  471.             {% set tickets = ticketsData.result %}
  472.             {% set totalRows = ticketsData.totalRows %}
  473.             {% set totalPages = (totalRows / perPage)|round(0, 'ceil') %}
  474.             {% if user_service.isAccessAuthorized('ROLE_ADMIN') %}
  475.                 <label>{{ 'Tickets answered more than 15 days ago'|trans }}: <a href="#" onclick="showTicketModal()">{{ totalRows }} tickets</a></label>
  476.             {% endif %}
  477.                 <!-- Modal -->
  478.                 <div id="ticketModal" class="modal">
  479.                     <div class="modal-content">
  480.                         <span class="close" onclick="closeTicketModal()">&times;</span>
  481.                         <div class="modal-body">
  482.                             <table>
  483.                                 <thead>
  484.                                     <tr>
  485.                                         <th>ID</th>
  486.                                         <th>UPDATED</th>
  487.                                         <th>DAYS</th>
  488.                                         <th>CLOSE TICKET</th>
  489.                                     </tr>
  490.                                 </thead>
  491.                                 <tbody>
  492.                                     {% for ticket in tickets %}
  493.                                         <tr>
  494.                                             <td><a target="_blank" href="https://softguard.com/tks/public/es/member/ticket/view/{{ ticket.id }}">{{ ticket.id }}-{{ticket.numeracion}}</a></td>
  495.                                             <td>{{ ticket.updated_at|date("d-m-Y") }}</td>
  496.                                             <td>{{ ticket.dias_diferencia }}</td>
  497.                                             <td>
  498.                                                 <form enctype="multipart/form-data" method="post" action="{{ path('helpdesk_member_add_ticket_thread', {'ticketId': ticket.id }) }}">
  499.                                                     <input name="threadType" value="reply" type="hidden">
  500.                                                     <input name="status" value="Closed by autoclose" type="hidden" {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}class="reply-status"{% endif %}>
  501.                                                     
  502.                                                     <div class="uv-element-block uv-element-block-textarea" style="display: none !important;">
  503.                                                         <label class="uv-field-label">{{ 'Write a reply'|trans }}</label>
  504.                                                         <div class="uv-field-block">
  505.                                                             <textarea class="uv-field" name="reply"  id="note-area">Closed by autoclose</textarea>
  506.                                                         </div>
  507.                                                     </div>
  508.                                                     <div class="uv-dropdown next-view">
  509.                                                         <input type="hidden" name="nextView" value="redirect"/>
  510.                                                     </div>
  511.                                                                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}
  512.                                                                                     <button style="background-color:#767676; color:#FFF; margin:5px; padding: 10px !important;" type="submit" data-id="closed">{{ 'Closed by autoclose'|trans }}</button>
  513.                                                                                 {% endif %}
  514.                                            
  515.                                                 </form>
  516.                                             </td>
  517.                                         </tr>
  518.                                     {% endfor %}
  519.                                 </tbody>
  520.                             </table>
  521.                         </div>
  522.                              <!-- Paginación -->
  523.                         <div class="pagination">
  524.                             {% if totalPages > 1 %}
  525.                                 {% for p in 1..totalPages %}
  526.                                     {% if p == page %}
  527.                                         <span>{{ p }}</span>
  528.                                     {% else %}
  529.                                         <a href="?page={{ p }}">{{ p }}</a>
  530.                                     {% endif %}
  531.                                 {% endfor %}
  532.                             {% endif %}
  533.                         </div>
  534.                     </div>
  535.                   
  536.                 </div>
  537.              
  538.             </ul>
  539.            <div class="ticket-alert-overlay" id="ticketAlertModal">
  540.                 <div class="ticket-alert-modal">
  541.                     <div class="ticket-alert-header">
  542.                         <h3>⚠️ {{ 'Ticket Alerts'|trans }}</h3>
  543.                         <button class="ticket-alert-close" onclick="closeTicketAlert()">&times;</button>
  544.                     </div>
  545.                     <div class="ticket-alert-body" id="ticketAlertBody">
  546.                         <!-- El contenido se cargará dinámicamente -->
  547.                     </div>
  548.                     <div class="ticket-alert-actions">
  549.                         <button class="ticket-alert-btn ticket-alert-btn-secondary" onclick="closeTicketAlert()">
  550.                             {{ 'Close'|trans }}
  551.                         </button>
  552.                     </div>
  553.                 </div>
  554.             </div>
  555.             
  556.             {# Action Bar #}
  557.             <div class="uv-action-bar">
  558.                 {# Select all checkbox #}
  559.                 <div class="uv-action-select-wrapper">
  560.                     <label class="uv-vertical-align uv-margin-left-27">
  561.                         <div class="uv-checkbox">
  562.                             <input type="checkbox" class="select-all-checkbox"><span class="uv-checkbox-view"></span>
  563.                         </div>
  564.                     </label>
  565.                 </div>
  566.                 {# Filter Options #}
  567.                 <div class="uv-action-col-wrapper">
  568.                     {# Ticket Sort | Asset Visibility #}
  569.                     <div class="uv-action-bar-col-lt">
  570.                         <div class="filter">
  571.                             {# Sort By #}
  572.                             <div class="uv-dropdown sort">
  573.                                 <div class="uv-dropdown-btn uv-vertical-align uv-margin-right-5">{{ 'Sort By:'|trans }} {{ 'Last Replied'|trans }}</div>
  574.                                 <div class="uv-dropdown-list uv-bottom-left">
  575.                                     <div class="uv-dropdown-container">
  576.                                         <label>{{ 'Sort By'|trans }}</label>
  577.                                         <ul></ul>
  578.                                     </div>
  579.                                 </div>
  580.                             </div>
  581.                             {# Assets Visibilities #}
  582.                             <div class="uv-dropdown asset-visibility">
  583.                                 <div class="uv-dropdown-btn uv-vertical-align uv-margin-right-5">{{ 'Assets Visibility'|trans }}</div>
  584.                                 <div class="uv-dropdown-list uv-bottom-left" style="width: 215px;">
  585.                                     <div class="uv-dropdown-container">
  586.                                         <label>{{ 'Assets Visibility'|trans }}</label>
  587.                                         <ul>
  588.                                             {# Subject #}
  589.                                             <li class="uv-dropdown-checkbox">
  590.                                                 <label>
  591.                                                     <div class="uv-checkbox">
  592.                                                         <input type="checkbox" id="subject" name="assetVisibility[]" value="subject" checked>
  593.                                                         <span class="uv-checkbox-view uv-checkbox-dwn"></span>
  594.                                                     </div>
  595.                                                 </label>
  596.                                                 <label for="subject">{{ 'Subject'|trans }}</label>
  597.                                             </li>
  598.                                             {# Reference #}
  599.                                             <li class="uv-dropdown-checkbox">
  600.                                                 <label>
  601.                                                     <div class="uv-checkbox">
  602.                                                         <input type="checkbox" id="reference" name="assetVisibility[]" value="reference" checked>
  603.                                                         <span class="uv-checkbox-view uv-checkbox-dwn"></span>
  604.                                                     </div>
  605.                                                 </label>
  606.                                                 <label for="reference">{{ 'Reference'|trans }}</label>
  607.                                             </li>
  608.                                             {# Ticket Source #}
  609.                                             <li class="uv-dropdown-checkbox">
  610.                                                 <label>
  611.                                                     <div class="uv-checkbox">
  612.                                                         <input type="checkbox" id="source" name="assetVisibility[]" value="source" checked>
  613.                                                         <span class="uv-checkbox-view uv-checkbox-dwn"></span>
  614.                                                     </div>
  615.                                                 </label>
  616.                                                 <label for="source">{{ 'Channel/Source'|trans }}</label>
  617.                                             </li>
  618.                                             {# Ticket Customer Name #}
  619.                                             <li class="uv-dropdown-checkbox">
  620.                                                 <label>
  621.                                                     <div class="uv-checkbox">
  622.                                                         <input type="checkbox" id="customer-name" name="assetVisibility[]" value="customer-name" checked>
  623.                                                         <span class="uv-checkbox-view uv-checkbox-dwn"></span>
  624.                                                     </div>
  625.                                                 </label>
  626.                                                 <label for="customer-name">{{ 'Customer Name'|trans }}</label>
  627.                                             </li>
  628.                                             {# Ticket Customer Email #}
  629.                                             <li class="uv-dropdown-checkbox">
  630.                                                 <label>
  631.                                                     <div class="uv-checkbox">
  632.                                                         <input type="checkbox" id="customer-email" name="assetVisibility[]" value="customer-email" checked>
  633.                                                         <span class="uv-checkbox-view uv-checkbox-dwn"></span>
  634.                                                     </div>
  635.                                                 </label>
  636.                                                 <label for="customer-email">{{ 'Customer Email'|trans }}</label>
  637.                                             </li>
  638.                                             {# Ticket Timestamp #}
  639.                                             <li class="uv-dropdown-checkbox">
  640.                                                 <label>
  641.                                                     <div class="uv-checkbox">
  642.                                                         <input type="checkbox" id="timestamp" name="assetVisibility[]" value="timestamp" checked>
  643.                                                         <span class="uv-checkbox-view uv-checkbox-dwn"></span>
  644.                                                     </div>
  645.                                                 </label>
  646.                                                 <label for="timestamp">{{ 'Timestamp'|trans }}</label>
  647.                                             </li>
  648.                                             {# Ticket Group #}
  649.                                             <li class="uv-dropdown-checkbox">
  650.                                                 <label>
  651.                                                     <div class="uv-checkbox">
  652.                                                         <input type="checkbox" id="group" name="assetVisibility[]" value="group" checked>
  653.                                                         <span class="uv-checkbox-view uv-checkbox-dwn"></span>
  654.                                                     </div>
  655.                                                 </label>
  656.                                                 <label for="group">{{ 'Group'|trans }}</label>
  657.                                             </li>
  658.                                             {# Ticket Team #}
  659.                                             <li class="uv-dropdown-checkbox">
  660.                                                 <label>
  661.                                                     <div class="uv-checkbox">
  662.                                                         <input type="checkbox" id="team" name="assetVisibility[]" value="team" checked>
  663.                                                         <span class="uv-checkbox-view uv-checkbox-dwn"></span>
  664.                                                     </div>
  665.                                                 </label>
  666.                                                 <label for="team">{{ 'Team'|trans }}</label>
  667.                                             </li>
  668.                                             {# Ticket Type #}
  669.                                             <li class="uv-dropdown-checkbox">
  670.                                                 <label>
  671.                                                     <div class="uv-checkbox">
  672.                                                         <input type="checkbox" id="type1" name="assetVisibility[]" value="type1" checked>
  673.                                                         <span class="uv-checkbox-view uv-checkbox-dwn"></span>
  674.                                                     </div>
  675.                                                 </label>
  676.                                                 <label for="type1">{{ 'Type'|trans }}</label>
  677.                                             </li>
  678.                                             {# Ticket Replies #}
  679.                                             <li class="uv-dropdown-checkbox">
  680.                                                 <label>
  681.                                                     <div class="uv-checkbox">
  682.                                                         <input type="checkbox" id="replies" name="assetVisibility[]" value="replies" checked>
  683.                                                         <span class="uv-checkbox-view uv-checkbox-dwn"></span>
  684.                                                     </div>
  685.                                                 </label>
  686.                                                 <label for="replies">{{ 'Replies'|trans }}</label>
  687.                                             </li>
  688.                                             {# Ticket Agent #}
  689.                                             <li class="uv-dropdown-checkbox">
  690.                                                 <label>
  691.                                                     <div class="uv-checkbox">
  692.                                                         <input type="checkbox" id="agent" name="assetVisibility[]" value="agent" checked>
  693.                                                         <span class="uv-checkbox-view uv-checkbox-dwn"></span>
  694.                                                     </div>
  695.                                                 </label>
  696.                                                 <label for="agent">{{ 'Agent'|trans }}</label>
  697.                                             </li>
  698.                                         </ul>
  699.                                     </div>
  700.                                 </div>
  701.                             </div>
  702.                         </div>
  703.                     </div>
  704.                     {# Ticket Mass Action #}
  705.                     <div class="uv-action-bar-col-lt" style="display: none">
  706.                         <!-- Mass action -->
  707.                         <div class="mass-action">
  708.                             <div class="property-block">
  709.                                 {# Update Assigned Support Agent #}
  710.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_ASSIGN_TICKET') %}
  711.                                     <div class="uv-dropdown">
  712.                                         <div class="uv-dropdown-btn uv-vertical-align uv-margin-right-5">{{ 'Agent'|trans }}</div>
  713.                                         <div class="uv-dropdown-list uv-bottom-left">
  714.                                             <div class="uv-dropdown-container">
  715.                                                 <label>{{ 'Agent'|trans }}</label>
  716.                                                 <div class="uv-search-sm">
  717.                                                     <input type="text" class="uv-search-field" placeholder="Search">
  718.                                                 </div>
  719.                                             </div>
  720.                                             <ul class="uv-agents-list agent" data-action="agent">
  721.                         <li data-index="-1">
  722.                                                     {{ 'Not Assigned'|trans }}
  723.                                                 </li>
  724.                                                 {% for agent in user_service.getAgentPartialDataCollection() %}
  725.                                                     <li data-index="{{ agent.id }}">
  726.                                                         {% if agent.smallThumbnail != null %}
  727.                                                             <img src="{{ app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') }}{{ agent.smallThumbnail }}"/>
  728.                                                         {% else %}
  729.                                                             <img src="{{ asset(default_agent_image_path) }}" alt=""/>
  730.                                                         {% endif %}
  731.                                                         {{ agent.name }}
  732.                                                     </li>
  733.                                                 {% endfor %}
  734.                                             </ul>
  735.                                         </div>
  736.                                     </div>
  737.                                 {% endif %}
  738.                                 {# Update Assigned Support Group #}
  739.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_ASSIGN_TICKET_GROUP') %}
  740.                                     <div class="uv-dropdown">
  741.                                         <div class="uv-dropdown-btn uv-vertical-align uv-margin-right-5">{{ 'Group'|trans }}</div>
  742.                                         <div class="uv-dropdown-list uv-bottom-left">
  743.                                             <div class="uv-dropdown-container">
  744.                                                 <label>{{ 'Group'|trans }}</label>
  745.                                                 <div class="uv-search-sm">
  746.                                                     <input type="text" class="uv-search-field" placeholder="Search">
  747.                                                 </div>
  748.                                             </div>
  749.                                             <ul class="uv-search-list group" data-action="group">
  750.                                                 {% for group in user_service.getSupportGroups() %}
  751.                                                     <li data-index="{{ group.id }}"><a href="#">{{ group.name }}</a></li>
  752.                                                 {% endfor %}
  753.                                             </ul>
  754.                                         </div>
  755.                                     </div>
  756.                                 {% endif %}
  757.                                 {# Update Assigned Support Team #}
  758.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_ASSIGN_TICKET_GROUP') %}
  759.                                     <div class="uv-dropdown">
  760.                                         <div class="uv-dropdown-btn uv-vertical-align uv-margin-right-5">{{ 'Team'|trans }}</div>
  761.                                         <div class="uv-dropdown-list uv-bottom-left">
  762.                                             <div class="uv-dropdown-container">
  763.                                                 <label>{{ 'Team'|trans }}</label>
  764.                                                 <div class="uv-search-sm">
  765.                                                     <input type="text" class="uv-search-field" placeholder="Search">
  766.                                                 </div>
  767.                                             </div>
  768.                                             <ul class="uv-search-list team" data-action="team">
  769.                                                 {% for team in user_service.getSupportTeams() %}
  770.                                                     <li data-index="{{ team.id }}"><a href="#">{{ team.name }}</a></li>
  771.                                                 {% endfor %}
  772.                                             </ul>
  773.                                         </div>
  774.                                     </div>
  775.                                 {% endif %}
  776.                                 {# Update Ticket Status #}
  777.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}
  778.                                     <div class="uv-dropdown">
  779.                                         <div class="uv-dropdown-btn uv-vertical-align uv-margin-right-5">{{ 'Status'|trans }}</div>
  780.                                         <div class="uv-dropdown-list uv-bottom-left">
  781.                                             <div class="uv-dropdown-container">
  782.                                                 <label>{{ 'Status'|trans }}</label>
  783.                                                 <ul class="status" data-action="status">
  784.                                                     {% for status in ticketStatusCollection %}
  785.                                                         <li data-index="{{ status.id }}">
  786.                                                                <a href="#" >{{ status.description|trans }}</a>
  787.                                                         </li>
  788.                                                     {% endfor %}
  789.                                                 </ul>
  790.                                             </div>
  791.                                         </div>
  792.                                     </div>
  793.                                 {% endif %}
  794.                                 {# Update Ticket Type #}
  795.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_TYPE') %}
  796.                                     <div class="uv-dropdown">
  797.                                         <div class="uv-dropdown-btn uv-vertical-align uv-margin-right-5">{{ 'Type'|trans }}</div>
  798.                                         <div class="uv-dropdown-list uv-bottom-left">
  799.                                             <div class="uv-dropdown-container">
  800.                                                 <label>{{ 'Type'|trans }}</label>
  801.                                                 <div class="uv-search-sm">
  802.                                                     <input type="text" class="uv-search-field" placeholder="{{ 'Search'|trans }}">
  803.                                                 </div>
  804.                                             </div>
  805.                                             <ul class="uv-search-list type" data-action="type">
  806.                                                 {% for type in ticketTypeCollection %}
  807.                                                     <li data-index="{{ type.id }}"><a href="#">{{ type.description }}</a></li>
  808.                                                 {% endfor %}
  809.                                             </ul>
  810.                                         </div>
  811.                                     </div>
  812.                                 {% endif %}
  813.                                 {# Update Priority #}
  814.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_PRIORITY') %}
  815.                                     <div class="uv-dropdown">
  816.                                         <div class="uv-dropdown-btn uv-vertical-align uv-margin-right-5">{{ 'Priority'|trans }}</div>
  817.                                         <div class="uv-dropdown-list uv-bottom-left">
  818.                                             <div class="uv-dropdown-container">
  819.                                                 <label>{{ 'Priority'|trans }}</label>
  820.                                                 <ul class="priority" data-action="priority">
  821.                                                     {% for priority in ticketPriorityCollection %}
  822.                                                         <li data-index="{{ priority.id }}"><a href="#">{{ priority.description|trans }}</a></li>
  823.                                                     {% endfor %}
  824.                                                 </ul>
  825.                                             </div>
  826.                                         </div>
  827.                                     </div>
  828.                                 {% endif %}
  829.                                 {# Update Label #}
  830.                                 <div class="uv-dropdown">
  831.                                     <div class="uv-dropdown-btn uv-vertical-align uv-margin-right-5">{{ 'Label'|trans }}</div>
  832.                                     <div class="uv-dropdown-list uv-bottom-left">
  833.                                         <div class="uv-dropdown-container">
  834.                                             <label>{{ 'Label'|trans }}</label>
  835.                                             <div class="uv-search-sm">
  836.                                                 <input type="text" class="uv-search-field" placeholder="Search">
  837.                                             </div>
  838.                                         </div>
  839.                                         <ul class="uv-search-list label" data-action="label"></ul>
  840.                                     </div>
  841.                                 </div>
  842.                                 {# Trashe Tickets #}
  843.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_TICKET') %}
  844.                                     <a class="uv-btn-stroke uv-margin-right-5" id="mass-delete" data-action="trashed" style="margin-left: 5px;">{{ 'Delete'|trans }}</a>
  845.                                 {% endif %}
  846.                             </div>
  847.                             {# For Trashed Tickets #}
  848.                             <div class="trashed-block" style="display: none">
  849.                                 {# Restore Tickets #}
  850.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_RESTORE_TICKET') %}
  851.                                     <a class="uv-btn-stroke uv-margin-right-5" id="mass-restore" data-action="restore" style="margin-left: 5px;">{{ 'Restore'|trans }}</a>
  852.                                 {% endif %}
  853.                                 {# Delete Tickets Forever #}
  854.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_TICKET') %}
  855.                                     <a class="uv-btn-stroke uv-margin-right-5" id="mass-delete-forever" data-action="delete" style="margin-left: 5px;">{{ 'Delete Forever'|trans }}</a>
  856.                                 {% endif %}
  857.                             </div>
  858.                         </div>
  859.                     </div>
  860.                     {# Ticket Search | Filter Extras #}
  861.                     <div class="uv-action-bar-col-rt">
  862.                         <!-- Search Tickets -->
  863.                         <input type="text" class="uv-search-inline" placeholder="{{ 'Search'|trans }}">
  864.                         <!-- Extra Filters -->
  865.                         <div class="uv-btn-stroke uv-margin-left-15 filter-view-trigger" data-target="uv-filter-view"><span class="uv-icon-filter"></span>{{ 'Filter View'|trans }}</div>
  866.                     </div>
  867.                 </div>
  868.             </div>
  869.             {# Ticket List #}
  870.             <div class="uv-table uv-list-view">
  871.                 <table>
  872.                     <thead>
  873.                     <tr>
  874.                         <th class="uv-width-140"></th>
  875.                         <th>{{ 'ID'|trans }}</th>
  876.                         <th class="uv-min-width-300" data-index="subject">{{ 'Subject'|trans }}</th>
  877.                         <th class="uv-min-width-300" data-index="reference">{{ 'Reference'|trans }}</th>
  878.                         <th data-index="customer-name">{{ 'Customer Name'|trans }}</th>
  879.                         <th data-index="customer-email">{{ 'Customer Email'|trans }}</th>
  880.                         <th data-index="timestamp">{{ 'Timestamp'|trans }}</th>
  881.                         <th data-index="group">{{ 'Group'|trans }}</th>
  882.                         <th data-index="team">{{ 'Team'|trans }}</th>
  883.                         <th data-index="type1">{{ 'Type'|trans }}</th>
  884.                         <th data-index="replies">{{ 'Replies'|trans }}</th>
  885.                         <th data-index="agent">{{ 'Agent'|trans }}</th>
  886.                     </tr>
  887.                     </thead>
  888.                     <tbody></tbody>
  889.                 </table>
  890.                 <div class="navigation"></div>
  891.             </div>
  892.         </div>
  893.         {# Extra Filters #}
  894.         <div class="uv-filter-view" id="uv-filter-view">
  895.             {# Filter Head #}
  896.             <div class="uv-filter-head">
  897.                 <div class="uv-filter-title">
  898.                     <h6>{{ 'Tickets'|trans }}</h6>
  899.                     <span>{{ 'Save set of filters as a preset to stay more productive'|trans }}</span>
  900.                 </div>
  901.                 <div class="uv-filter-toggle" id="filter-close-trigger"><span></span></div>
  902.             </div>
  903.             {# Filter Content #}
  904.             <div class="uv-filter-paper">
  905.                 {# Filters #}
  906.                 <div class="uv-filter-options">
  907.                     <script>
  908.                         var userFilters = {};
  909.                     </script>
  910.                     {# Saved Filters #}
  911.                     <div class="uv-element-block" style="border-bottom: 1px solid #D3D3D3; padding-bottom: 5px;">
  912.                         <label class="uv-field-label">{{ 'Saved Filters'|trans }}</label>
  913.                         <div class="uv-field-block">
  914.                             <div class="uv-customize-wrapper">
  915.                                 <select class="uv-select uv-select-70" id="saved-filter">
  916.                                     {% set filters = app.user.agentInstance.userSavedFilters %}
  917.                                     {% if filters|length %}
  918.                                         <option value="">-- Saved Filter --</option>
  919.                                         {% for userFilter in filters %}
  920.                                             <option value="{{userFilter.id}}">{{userFilter.name}}</option>
  921.                                         {% endfor %}
  922.                                     {% else %}
  923.                                         <option value="">{{ 'No saved filter created'|trans }}</option>
  924.                                     {% endif %}
  925.                                 </select>
  926.                                 {% for userFilter in app.user.agentInstance.userSavedFilters %}
  927.                                     <script>
  928.                                         {% set isDefault = 0 %}
  929.                                         {% if app.user.agentInstance.defaultFiltering == userFilter.id %}
  930.                                         {% set isDefault = 1 %}
  931.                                         {% endif %}
  932.                                         userFilters[{{userFilter.id}}] = {{ {'id': userFilter.id, 'name': userFilter.name, 'route': userFilter.route, 'is_default': isDefault}|json_encode|raw }};
  933.                                     </script>
  934.                                 {% endfor %}
  935.                                 <span class="uv-customize" style="display: none" data-toggle="tooltip" title="{{ 'Edit Saved Filter'|trans }}"></span>
  936.                             </div>
  937.                         </div>
  938.                     </div>
  939.                     {% set filterContext = {} %}
  940.                     {# agent #}
  941.                     <div class="uv-element-block">
  942.                         <label class="uv-field-label">{{ 'Agent'|trans }}</label>
  943.                         <div class="uv-field-block" id="agent-filter">
  944.                             <input class="uv-field uv-dropdown-other preloaded" type="text" data-filter-type="agent" id="agent-filter-input">
  945.                             <div class="uv-dropdown-list uv-bottom-left">
  946.                                 <div class="uv-dropdown-container">
  947.                                     <label>{{ 'Filter With'|trans }}</label>
  948.                                 </div>
  949.                                 <ul class="uv-agents-list">
  950.                                     {% set options = [] %}
  951.                                     {% for agent in user_service.getAgentsPartialDetails %}
  952.                                         {% set options = options|merge([{'id': agent.id, 'name': agent.name}]) %}
  953.                                         <li data-id="{{agent.id}}">
  954.                                             {% if agent.smallThumbnail != null %}
  955.                                                 <img src="{{ app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') }}{{ agent.smallThumbnail }}"/>
  956.                                             {% else %}
  957.                                                 <img src="{{ asset(default_agent_image_path) }}"/>
  958.                                             {% endif %}
  959.                                             {{agent.name}}
  960.                                         </li>
  961.                                     {% endfor %}
  962.                                     <li class="uv-no-results" style="display: none;">
  963.                                         {{ 'No result found'|trans }}
  964.                                     </li>
  965.                                     {% set filterContext = filterContext|merge({'agent':options}) %}
  966.                                 </ul>
  967.                             </div>
  968.                             <div class="uv-filtered-tags"></div>
  969.                         </div>
  970.                     </div>
  971.                     <div class="uv-element-block">
  972.                         <label class="uv-field-label">{{ 'Customer'|trans }}</label>
  973.                         <div class="uv-field-block" id="customer-filter">
  974.                             <input class="uv-field uv-dropdown-other" type="text" data-filter-type="customer" id="customer-filter-input">
  975.                             <div class="uv-dropdown-list uv-bottom-left">
  976.                                 <div class="uv-dropdown-container">
  977.                                     <label>{{ 'Filter With'|trans }}</label>
  978.                                 </div>
  979.                                 <ul class="uv-agents-list">
  980.                                     <li class="uv-filter-info">
  981.                                         {{ 'Type atleast 2 letters'|trans }}
  982.                                     </li>
  983.                                     <li class="uv-no-results" style="display: none;">
  984.                                         {{ 'No result found'|trans }}
  985.                                     </li>
  986.                                 </ul>
  987.                             </div>
  988.                             <div class="uv-filtered-tags"></div>
  989.                         </div>
  990.                     </div>
  991.                     <div class="uv-element-block">
  992.                         <label class="uv-field-label">{{ 'Group'|trans }}</label>
  993.                         <div class="uv-field-block" id="group-filter">
  994.                             <input class="uv-field uv-dropdown-other preloaded" type="text" data-filter-type="group" id="group-filter-input">
  995.                             <div class="uv-dropdown-list uv-bottom-left">
  996.                                 <div class="uv-dropdown-container">
  997.                                     <label>{{ 'Filter With'|trans }}</label>
  998.                                     <ul class="">
  999.                                         {% set options = [] %}
  1000.                                         {% for group in user_service.getSupportGroups() %}
  1001.                                             {% set options = options|merge([{'id': group.id, 'name': group.name}]) %}
  1002.                                             <li data-id="{{group.id}}">
  1003.                                                 {{group.name}}
  1004.                                             </li>
  1005.                                         {% endfor %}
  1006.                                         <li class="uv-no-results" style="display: none;">
  1007.                                             {{ 'No result found'|trans }}
  1008.                                         </li>
  1009.                                         {% set filterContext = filterContext|merge({'group':options}) %}
  1010.                                     </ul>
  1011.                                 </div>
  1012.                             </div>
  1013.                             <div class="uv-filtered-tags"></div>
  1014.                         </div>
  1015.                     </div>
  1016.                     <div class="uv-element-block">
  1017.                         <label class="uv-field-label">{{ 'Team'|trans }}</label>
  1018.                         <div class="uv-field-block" id="team-filter">
  1019.                             <input class="uv-field uv-dropdown-other preloaded" type="text" data-filter-type="team" id="team-filter-input">
  1020.                             <div class="uv-dropdown-list uv-bottom-left">
  1021.                                 <div class="uv-dropdown-container">
  1022.                                     <label>{{ 'Filter With'|trans }}</label>
  1023.                                     <ul class="">
  1024.                                         {% set options = [] %}
  1025.                                         {% for team in user_service.getSupportTeams() %}
  1026.                                             {% set options = options|merge([{'id': team.id, 'name': team.name}]) %}
  1027.                                             <li data-id="{{team.id}}">
  1028.                                                 {{team.name}}
  1029.                                             </li>
  1030.                                         {% endfor %}
  1031.                                         <li class="uv-no-results" style="display: none;">
  1032.                                             {{ 'No result found'|trans }}
  1033.                                         </li>
  1034.                                         {% set filterContext = filterContext|merge({'team':options}) %}
  1035.                                     </ul>
  1036.                                 </div>
  1037.                             </div>
  1038.                             <div class="uv-filtered-tags"></div>
  1039.                         </div>
  1040.                     </div>
  1041.                     <div class="uv-element-block">
  1042.                         <label class="uv-field-label">{{ 'Type'|trans }}</label>
  1043.                         <div class="uv-field-block" id="type-filter">
  1044.                             <input class="uv-field uv-dropdown-other preloaded" type="text" data-filter-type="type" id="type-filter-input">
  1045.                             <div class="uv-dropdown-list uv-bottom-left">
  1046.                                 <div class="uv-dropdown-container">
  1047.                                     <label>{{ 'Filter With'|trans }}</label>
  1048.                                     <ul class="">
  1049.                                         {% set options = [] %}
  1050.                                         {% for type in ticket_service.getTypes() %}
  1051.                                             {% set options = options|merge([{'id': type.id, 'name': type.name}]) %}
  1052.                                             <li data-id="{{type.id}}">
  1053.                                                 {{type.name}}
  1054.                                             </li>
  1055.                                         {% endfor %}
  1056.                                         <li class="uv-no-results" style="display: none;">
  1057.                                             {{ 'No result found'|trans }}
  1058.                                         </li>
  1059.                                         {% set filterContext = filterContext|merge({'type':options}) %}
  1060.                                     </ul>
  1061.                                 </div>
  1062.                             </div>
  1063.                             <div class="uv-filtered-tags"></div>
  1064.                         </div>
  1065.                     </div>
  1066.                     <div class="uv-element-block">
  1067.                         <label class="uv-field-label">{{ 'Priority'|trans }}</label>
  1068.                         <div class="uv-field-block" id="priority-filter">
  1069.                             <input class="uv-field uv-dropdown-other preloaded" type="text" data-filter-type="priority" id="priority-filter-input">
  1070.                             <div class="uv-dropdown-list uv-bottom-left">
  1071.                                 <div class="uv-dropdown-container">
  1072.                                     <label>{{ 'Filter With'|trans }}</label>
  1073.                                     <ul class="">
  1074.                                         {% set options = [] %}
  1075.                                         {% for priority in ticket_service.getPriorities() %}
  1076.                                             {% set options = options|merge([{'id': priority.id, 'name': priority.code, 'color': priority.colorCode}]) %}
  1077.                                             <li data-id="{{priority.id}}">
  1078.                                                 {{ priority.code|trans }}
  1079.                                             </li>
  1080.                                         {% endfor %}
  1081.                                         <li class="uv-no-results" style="display: none;">
  1082.                                             {{ 'No result found'|trans }}
  1083.                                         </li>
  1084.                                         {% set filterContext = filterContext|merge({'priority':options}) %}
  1085.                                     </ul>
  1086.                                 </div>
  1087.                             </div>
  1088.                             <div class="uv-filtered-tags"></div>
  1089.                         </div>
  1090.                     </div>
  1091.                     <div class="uv-element-block">
  1092.                         <label class="uv-field-label">{{ 'Tag'|trans }}</label>
  1093.                         <div class="uv-field-block" id="tag-filter">
  1094.                             <input class="uv-field uv-dropdown-other" type="text" data-filter-type="tag" id="tag-filter-input">
  1095.                             <div class="uv-dropdown-list uv-bottom-left">
  1096.                                 <div class="uv-dropdown-container">
  1097.                                     <label>{{ 'Filter With'|trans }}</label>
  1098.                                     <ul class="">
  1099.                                         <li class="uv-filter-info">
  1100.                                             {{ 'Type atleast 2 letters'|trans }}
  1101.                                         </li>
  1102.                                         <li class="uv-no-results" style="display: none;">
  1103.                                             {{ 'No result found'|trans }}
  1104.                                         </li>
  1105.                                     </ul>
  1106.                                 </div>
  1107.                             </div>
  1108.                             <div class="uv-filtered-tags"></div>
  1109.                         </div>
  1110.                     </div>
  1111.                     <div class="uv-element-block">
  1112.                         <label class="uv-field-label">{{ 'Source'|trans }}</label>
  1113.                         <div class="uv-field-block" id="source-filter">
  1114.                             <input class="uv-field uv-dropdown-other preloaded" type="text" data-filter-type="source" id="source-filter-input">
  1115.                             <div class="uv-dropdown-list uv-bottom-left">
  1116.                                 <div class="uv-dropdown-container">
  1117.                                     <label>{{ 'Filter With'|trans }}</label>
  1118.                                     <ul class="">
  1119.                                         {% set options = [] %}
  1120.                                         {% for key, source in ticket_service.getAllSources() %}
  1121.                                             {% set options = options|merge([{'id': key, 'name': source}]) %}
  1122.                                             <li data-id="{{key}}">
  1123.                                                 {{ source|trans }}
  1124.                                             </li>
  1125.                                         {% endfor %}
  1126.                                         <li class="uv-no-results" style="display: none;">
  1127.                                             {{ 'No result found'|trans }}
  1128.                                         </li>
  1129.                                         {% set filterContext = filterContext|merge({'source': options}) %}
  1130.                                     </ul>
  1131.                                 </div>
  1132.                             </div>
  1133.                             <div class="uv-filtered-tags"></div>
  1134.                         </div>
  1135.                     </div>
  1136.                     <div class="uv-element-block">
  1137.                         <label class="uv-field-label">{{ 'Before'|trans }}</label>
  1138.                         <div class="uv-field-block range" id="before-filter">
  1139.                             <input class="uv-field uv-date-picker" type="text" data-filter-type="before" id="before-filter-input">
  1140.                         </div>
  1141.                     </div>
  1142.                     <div class="uv-element-block">
  1143.                         <label class="uv-field-label">{{ 'After'|trans }}</label>
  1144.                         <div class="uv-field-block range" id="after-filter">
  1145.                             <input class="uv-field uv-date-picker" type="text" data-filter-type="after" id="after-filter-input">
  1146.                         </div>
  1147.                     </div>
  1148.                     <div class="uv-element-block">
  1149.                         <label class="uv-field-label">{{ 'Replies less than'|trans }}</label>
  1150.                         <div class="uv-field-block" id="reply-filter">
  1151.                             <input class="uv-field" type="number" min="1" data-filter-type="replies-less" id="repliesLess-filter-input">
  1152.                         </div>
  1153.                     </div>
  1154.                     <div class="uv-element-block">
  1155.                         <label class="uv-field-label">{{ 'Replies more than'|trans }}</label>
  1156.                         <div class="uv-field-block" id="reply-filter">
  1157.                             <input class="uv-field" type="number" min="0" data-filter-type="replies-more" id="repliesMore-filter-input">
  1158.                         </div>
  1159.                     </div>
  1160.                     <div class="uv-action-buttons">
  1161.                     </div>
  1162.                     {# Clear Filters #}
  1163.                     <a class="uv-btn-remove" href="#"><span class="uv-icon-discard"></span> {{ 'Clear All'|trans }}</a>
  1164.                 </div>
  1165.                 {# Add|Edit Filter #}
  1166.                 <div class="uv-filter-edit" style="display: none;"></div>
  1167.             </div>
  1168.             <script type="text/javascript">
  1169.                 var filterContext = {{ filterContext|json_encode|raw }}
  1170.             </script>
  1171.         </div>
  1172.     </div>
  1173. {% endblock %}
  1174. {% block footer %}
  1175.     {{ parent() }}
  1176.     {# Sort Ticket View Template #}
  1177.     <script id="ticket_list_sorting_tmp" type="text/template">
  1178.         <li class="<% if(sort == 'ticket.id') { %>uv-drop-list-active<% } %>">
  1179.             <a href="#<% if(queryString != '') { %><%= queryString %>/<% } %><% if(page) { %>page/<%= page %><% } else { %>page/1<% } %>/sort/ticket.id/<% if(sort == 'ticket.id') { %><% if(direction) { %>direction/<%= direction %><% } else { %>direction/desc<% } %><% } else { %>direction/asc<% } %>" data-field="ticket.id">
  1180.                 {% trans %}Ticket Id{% endtrans %}
  1181.                 <% if(sort == 'ticket.id') { %>
  1182.                 <span class="uv-sorting <% if(direction == 'asc') { %> descend <% } else { %> ascend <% } %>"></span>
  1183.                 <% } %>
  1184.             </a>
  1185.         </li>
  1186.         <li class="<% if(sort == 'ticket.updatedAt') { %>uv-drop-list-active<% } %>">
  1187.             <a href="#<% if(queryString != '') { %><%= queryString %>/<% } %><% if(page) { %>page/<%= page %><% } else { %>page/1<% } %>/sort/ticket.updatedAt/<% if(sort == 'ticket.updatedAt') { %><% if(direction) { %>direction/<%= direction %><% } else { %>direction/desc<% } %><% } else { %>direction/asc<% } %>" data-field="ticket.updatedAt">
  1188.                 {% trans %}Last Replied{% endtrans %}
  1189.                 <% if(sort == 'ticket.updatedAt') { %>
  1190.                 <span class="uv-sorting <% if(direction == 'asc') { %> descend <% } else { %> ascend <% } %>"></span>
  1191.                 <% } %>
  1192.             </a>
  1193.         </li>
  1194.         <li class="<% if(sort == 'agentName') { %>uv-drop-list-active<% } %>">
  1195.             <a href="#<% if(queryString != '') { %><%= queryString %>/<% } %><% if(page) { %>page/<%= page %><% } else { %>page/1<% } %>/sort/agentName/<% if(sort == 'agentName') { %><% if(direction) { %>direction/<%= direction %><% } else { %>direction/desc<% } %><% } else { %>direction/asc<% } %>" data-field="agentName">
  1196.                 {% trans %}Assign To{% endtrans %}
  1197.                 <% if(sort == 'agentName') { %>
  1198.                 <span class="uv-sorting <% if(direction == 'asc') { %> descend <% } else { %> ascend <% } %>"></span>
  1199.                 <% } %>
  1200.             </a>
  1201.         </li>
  1202.         <li class="<% if(sort == 'customerEmail') { %>uv-drop-list-active<% } %>">
  1203.             <a href="#<% if(queryString != '') { %><%= queryString %>/<% } %><% if(page) { %>page/<%= page %><% } else { %>page/1<% } %>/sort/customerEmail/<% if(sort == 'customerEmail') { %><% if(direction) { %>direction/<%= direction %><% } else { %>direction/desc<% } %><% } else { %>direction/asc<% } %>" data-field="customerEmail">
  1204.                 {% trans %}Customer Email{% endtrans %}
  1205.                 <% if(sort == 'customerEmail') { %>
  1206.                 <span class="uv-sorting <% if(direction == 'asc') { %> descend <% } else { %> ascend <% } %>"></span>
  1207.                 <% } %>
  1208.             </a>
  1209.         </li>
  1210.         <li class="<% if(sort == 'customerName') { %>uv-drop-list-active<% } %>">
  1211.             <a href="#<% if(queryString != '') { %><%= queryString %>/<% } %><% if(page) { %>page/<%= page %><% } else { %>page/1<% } %>/sort/customerName/<% if(sort == 'customerName') { %><% if(direction) { %>direction/<%= direction %><% } else { %>direction/desc<% } %><% } else { %>direction/asc<% } %>" data-field="customerName">
  1212.                 {% trans %}Customer Name{% endtrans %}
  1213.                 <% if(sort == 'customerName') { %>
  1214.                 <span class="uv-sorting <% if(direction == 'asc') { %> descend <% } else { %> ascend <% } %>"></span>
  1215.                 <% } %>
  1216.             </a>
  1217.         </li>
  1218.     </script>
  1219.     {# Ticket Status List Template #}
  1220.     <script id="ticket_status_list_tmp" type="text/template">
  1221.         <ul class="status-list">
  1222.             {% for status in ticketStatusCollection %}
  1223.                {#} {% if status.id== 1 or status.id== 3 or status.id== 5  %}{#}
  1224.                     <li>
  1225.                         <a href="#" 
  1226.                             
  1227.                          
  1228.                             class="<% if(active == {{ status.id }} {% if status.id == 1 %} || active == 0{% endif %}) { %>uv-aside-nav-active<% } %>" data-id="{{ status.id }}">
  1229.                        
  1230.                       
  1231.                             
  1232.                           <% if(status && status[1] != undefined &&  status[{{ status.id }}] > 0 && ( {{ status.id }} === 7 || {{ status.id }} === 8 ) ) { %>
  1233.                                    <span class="name"  style="background-color: #f10808;color: white;">{{ status.description|trans }}</span>
  1234.                                 <% } else { %>
  1235.                                     <span class="name">{{ status.description|trans }}</span>
  1236.                                 <% } %>
  1237.                             <span class="uv-flag-gray">
  1238.                                 <% if(status && status[1] != undefined) { %>
  1239.                                     <%= status[{{ status.id }}] %>
  1240.                                 <% } else { %>
  1241.                                     0
  1242.                                 <% } %>
  1243.                             </span>
  1244.                         </a>
  1245.                     </li>
  1246.               {#} {% endif %}{#}
  1247.             {% endfor %}
  1248.         </ul>
  1249.     </script>
  1250.     {# Default Ticket Label View Template #}
  1251.     <script id="predefined_label_tmp" type="text/template">
  1252.         {% if user_service.isAccessAuthorized('ROLE_ADMIN') %}
  1253.             
  1254.             <li>
  1255.                 <a href="#" <% if (active == '') { %> class="uv-aside-active" <% } %>>
  1256.                 {{ 'All'|trans }}
  1257.                 <span class="uv-flag-gray uv-flag-dark"><%= labelDetails.predefind.all %></span>
  1258.                 </a>
  1259.             </li>
  1260.             {#}
  1261.             <li>
  1262.                 <a href="#new" <% if(active == 'new') { %> class="uv-aside-active" <% } %> >
  1263.                 {{ 'New'|trans }}
  1264.                 <span class="uv-flag-gray uv-flag-dark">
  1265.                         <%= labelDetails.predefind.new %>
  1266.                     </span>
  1267.                 </a>
  1268.             </li>
  1269.             <li>
  1270.                 <a href="#unassigned" <% if(active == 'unassigned') { %> class="uv-aside-active" <% } %> >
  1271.                 {{ 'UnAssigned'|trans }}
  1272.                 <span class="uv-flag-gray uv-flag-dark">
  1273.                         <%= labelDetails.predefind.unassigned %>
  1274.                     </span>
  1275.                 </a>
  1276.             </li>
  1277.             <li>
  1278.                 <a href="#notreplied" <% if(active == 'notreplied') { %> class="uv-aside-active" <% } %> >
  1279.                 {{ 'UnAnswered'|trans }}
  1280.                 <span class="uv-flag-gray uv-flag-dark">
  1281.                         <%= labelDetails.predefind.notreplied %>
  1282.                     </span>
  1283.                 </a>
  1284.             </li>
  1285.             <li>
  1286.                 <a href="#mine" <% if(active == 'mine') { %> class="uv-aside-active" <% } %> >
  1287.                 {{ 'My Tickets'|trans }}
  1288.                 <span class="uv-flag-gray uv-flag-dark">
  1289.                         <%= labelDetails.predefind.mine %>
  1290.                     </span>
  1291.                 </a>
  1292.             </li>
  1293.             <li>
  1294.                 <a href="#starred" <% if(active == 'starred') { %> class="uv-aside-active" <% } %> >
  1295.                 {{ 'Starred'|trans }}
  1296.                 <span class="uv-flag-gray uv-flag-dark">
  1297.                         <%= labelDetails.predefind.starred %>
  1298.                     </span>
  1299.                 </a>
  1300.             </li>
  1301.             <li>
  1302.                 <a href="#trashed" <% if(active == 'trashed') { %> class="uv-aside-active" <% } %>>
  1303.                 {{ 'Trashed'|trans }}
  1304.                 <span class="uv-flag-gray uv-flag-dark">
  1305.                         <%= labelDetails.predefind.trashed %>
  1306.                     </span>
  1307.                 </a>
  1308.             </li>
  1309.              {#}
  1310.         {% else %}
  1311.             <li>
  1312.                 <a href="#" <% if (active == '') { %> class="uv-aside-active" <% } %>>
  1313.                 {{ 'All'|trans }}
  1314.                 <span class="uv-flag-gray uv-flag-dark"><%= labelDetails.predefind.all %></span>
  1315.                 </a>
  1316.             </li>
  1317.          {#   <li>
  1318.                 <a href="#mine" <% if(active == 'mine') { %> class="uv-aside-active" <% } %> >
  1319.                 {{ 'My Tickets'|trans }}
  1320.                 <span class="uv-flag-gray uv-flag-dark">
  1321.                         <%= labelDetails.predefind.mine %>
  1322.                     </span>
  1323.                 </a>
  1324.             </li>#}
  1325.             
  1326.         {% endif %}
  1327.                
  1328.     </script>
  1329.     {# Custom Ticket Label View Template #}
  1330.     <script id="custom_label_tmp" type="text/template">
  1331.         <a href="#label/<%= id %>"  data-id="<%= id %>">
  1332.             <%- name %>
  1333.             <span class="uv-flag-gray" style="<% if(colorCode) { %>background-color:<%= colorCode %><% } %>">
  1334.                 <%= count %>
  1335.             </span>
  1336.         </a>
  1337.         <span class="uv-customize" data-target="uv-task-view" data-toggle="tooltip" title="{{ 'Edit Label'|trans }}"></span>
  1338.     </script>
  1339.     {# Add|Edit Ticket Label View Template #}
  1340.     <script id="add_edit_label_tmp" type="text/template">
  1341.         <div class="uv-aside-head">
  1342.             <div class="uv-aside-title">
  1343.                 <% if(id) { %>
  1344.                 <h6>{{ 'Edit Label'|trans }}</h6>
  1345.                 <% } else { %>
  1346.                 <h6>{{ 'Add Label'|trans }}</h6>
  1347.                 <% } %>
  1348.             </div>
  1349.             <div class="uv-aside-back" id="back-to-labels">
  1350.                 <span>{{ 'Back'|trans }}</span>
  1351.             </div>
  1352.         </div>
  1353.         <div class="uv-aside-option" data-id="<%= id %>">
  1354.             <div class="uv-element-block">
  1355.                 <label class="uv-field-label">{{ 'Name'|trans }}</label>
  1356.                 <div class="uv-field-block">
  1357.                     <input class="uv-field" type="text" value="<%- name %>" />
  1358.                 </div>
  1359.             </div>
  1360.             <div class="uv-element-block">
  1361.                 <label class="uv-field-label">{{ 'Choose a Color'|trans }}</label>
  1362.                 <div class="uv-field-block">
  1363.                     <% colors = ['#337CFF','#FEBF00','#E5549F','#27B6BB','#FB8A3F','#43AF52'] %>
  1364.                     <% for(var colorTemp in colors) { %>
  1365.                     <span class="uv-color-block <% if(colorCode == colors[colorTemp]) { %>uv-color-active<% } %>" data-color="<%- colors[colorTemp] %>" style="background:<%- colors[colorTemp] %>"></span>
  1366.                     <% } %>
  1367.                 </div>
  1368.             </div>
  1369.             <div>
  1370.                 <a class="uv-btn add-update-btn" href="#">
  1371.                     <% if(id) { %>
  1372.                     {{ 'Update'|trans }}
  1373.                     <% } else { %>
  1374.                     {{ 'Create'|trans }}
  1375.                     <% } %>
  1376.                 </a>
  1377.             </div>
  1378.             <% if(id) { %>
  1379.             <a class="uv-btn-remove"><span class="uv-icon-discard"></span>{{ 'Remove Label'|trans }}</a>
  1380.             <% } %>
  1381.         </div>
  1382.     </script>
  1383.     {# Add|Edit Saved Ticket Filter View Template #}
  1384.     <script id="add_edit_saved_filter_tmp" type="text/template">
  1385.         <form>
  1386.             <div class="uv-filter-edit-head">
  1387.                 <div class="uv-filter-edit-title">
  1388.                     <h6>
  1389.                         <% if(id) { %>
  1390.                         <input type="hidden" name="id" id="filter-id" value="<%= id %>"/>
  1391.                         {{ 'Edit Saved Filter'|trans }}
  1392.                         <% } else { %>
  1393.                         {{ 'New Saved Filter'|trans }}
  1394.                         <% } %>
  1395.                     </h6>
  1396.                 </div>
  1397.                 <div class="uv-filter-edit-back back-to-filter">
  1398.                     <span>{{ 'Back'|trans }}</span>
  1399.                 </div>
  1400.             </div>
  1401.             <div class="uv-element-block">
  1402.                 <label class="uv-field-label">{{ 'Name'|trans }}</label>
  1403.                 <div class="uv-field-block">
  1404.                     <input class="uv-field name" name="name" type="text" value="<%- name %>" />
  1405.                 </div>
  1406.             </div>
  1407.             <div class="uv-element-block">
  1408.                 <label>
  1409.                     <div class="uv-checkbox">
  1410.                         <input type="checkbox" name="is_default" <% if(is_default) { %>checked<% } %> />
  1411.                         <span class="uv-checkbox-view"></span>
  1412.                     </div>
  1413.                     <span class="uv-checkbox-label">{{ 'Is Default'|trans }}</span>
  1414.                 </label>
  1415.             </div>
  1416.             <div class="uv-filters-group">
  1417.                 <% _.each(filters, function(filter, key){ %>
  1418.                 <div class="uv-element-block" data-filter="<%= key %>">
  1419.                     <label class="uv-field-label"><%- filter.name %></label>
  1420.                     <div class="uv-field-block">
  1421.                         <% _.each(filter.options, function(option){ %>
  1422.                         <a class="uv-btn-tag" href="#" data-id="<%= option.id %>">
  1423.                             <%- option.name %>
  1424.                             <span class="uv-icon-remove-dark"></span>
  1425.                         </a>
  1426.                         <% }); %>
  1427.                     </div>
  1428.                 </div>
  1429.                 <% }); %>
  1430.                 <div class="uv-action-buttons">
  1431.                     <% if(id) { %>
  1432.                     <a class="uv-btn-remove"><span class="uv-icon-discard"></span>{{ 'Remove Saved Filter'|trans }}</a>
  1433.                     <% } %>
  1434.                 </div>
  1435.             </div>
  1436.             <div class="uv-action-buttons">
  1437.                 <a class="uv-btn <% if(id) { %>update-filter<% } else { %>save-filter<% } %>" href="#">
  1438.                     <% if(id) { %>
  1439.                     {{ 'Update'|trans }}
  1440.                     <% } else { %>
  1441.                     {{ 'Create'|trans }}
  1442.                     <% } %>
  1443.                 </a>
  1444.                 <a class="uv-btn back-to-filter" href="#">{{ 'Cancel'|trans }}</a>
  1445.             </div>
  1446.         </form>
  1447.     </script>
  1448.     {# Quick View Ticket View Template #}
  1449.     <script id="ticket_quick_view_tmp" type="text/template">
  1450.         <div class="uv-pull-right quick-view-navigation">
  1451.             <div class="uv-loader" style="display: none">
  1452.                 <span></span>
  1453.                 <span></span>
  1454.                 <span></span>
  1455.             </div>
  1456.             <% if(previous) { %>
  1457.             <span class="uv-btn-tag uv-icon-nav-pre" data-id="<%= previous %>">
  1458.                 </span>
  1459.             <% } else { %>
  1460.             <span class="uv-btn-tag uv-icon-nav-pre" disabled="disabled">
  1461.                 </span>
  1462.             <% } %>
  1463.             <% if(next) { %>
  1464.             <span class="uv-btn-tag uv-icon-nav-nxt"  data-id="<%= next %>">
  1465.                 </span>
  1466.             <% } else { %>
  1467.             <span class="uv-btn-tag uv-icon-nav-nxt" disabled="disabled">
  1468.                 </span>
  1469.             <% } %>
  1470.         </div>
  1471.         <span class="uv-pop-up-close"></span>
  1472.         <a href="<%= path %>"><h2>{{ 'Ticket Info'|trans }} #<%= id %></h2></a>
  1473.         <div class="uv-pop-up-body uv-inner-section">
  1474.             <div class="uv-view">
  1475.                 <div class="uv-ticket-head">
  1476.                     <div class="uv-ticket-strip">
  1477.                         <span>
  1478.                             <span class="uv-ticket-strip-label">
  1479.                                 {{ 'Timestamp'|trans }} -
  1480.                             </span>
  1481.                             <span class="uv-margin-0">
  1482.                                 <%= formatedCreatedAt %>
  1483.                             </span>
  1484.                         </span>
  1485.                         <span>
  1486.                             <span class="uv-ticket-strip-label">
  1487.                                 {{ 'By'|trans }} -
  1488.                             </span>
  1489.                             <%- createThread.user.name %>
  1490.                         </span>
  1491.                         <% if(agent) { %>
  1492.                         <span class="agent-info" style="">
  1493.                                 <span class="uv-ticket-strip-label">
  1494.                                     {{ 'Agent'|trans }} -
  1495.                                 </span>
  1496.                                 <span class="name"><%- agent.name %></span>
  1497.                             </span>
  1498.                         <% } %>
  1499.                     </div>
  1500.                     <div class="uv-ticket-strip">
  1501.                         <span class="uv-btn-tag">
  1502.                             {{ 'Priority'|trans }}
  1503.                             - <%- priority.description %>
  1504.                         </span>
  1505.                         <span class="uv-btn-tag">
  1506.                             {{ 'Status'|trans }}
  1507.                             - <%- status.description %>
  1508.                         </span>
  1509.                         <% if(lastReplyAgentName) { %>
  1510.                         <span class="uv-btn-tag">
  1511.                                 {{ 'Last Replied Agent'|trans }}
  1512.                                 - <%- lastReplyAgentName.name.split(" ")[0] %>
  1513.                             </span>
  1514.                         <% } %>
  1515.                     </div>
  1516.                 </div>
  1517.                 <div class="uv-ticket-head">
  1518.                     <h1><%- subject %></h1>
  1519.                 </div>
  1520.                 <div class="uv-ticket-section">
  1521.                     <div class="uv-ticket-main create">
  1522.                         <div class="uv-ticket-strip">
  1523.                             <span>
  1524.                                 <span class="uv-margin-0 timeago" data-timestamp="<%= createThread.timestamp %>" title="<%= createThread.formatedCreatedAt %>"><%= createThread.formatedCreatedAt %></span>
  1525.                                 - <%- createThread.user.name %>
  1526.                                 <span class="uv-ticket-strip-label">
  1527.                                     {{ 'created Ticket'|trans }}
  1528.                                 </span>
  1529.                             </span>
  1530.                         </div>
  1531.                         <div class="uv-ticket-main-lt">
  1532.                             <% if (createThread.user.smallThumbnail != null) { %>
  1533.                                 <img class='border' src="{{ app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') }}<%= createThread.user.smallThumbnail %>"/>
  1534.                             <% } else { %>
  1535.                                 <% if (createThread.createdBy == 'customer') { %>
  1536.                                     <img class='border' src="{{ asset(default_customer_image_path) }}"/>
  1537.                                 <% } else { %>
  1538.                                     <img class='border' src="{{ asset(default_agent_image_path) }}"/>
  1539.                                 <% } %>
  1540.                             <% } %>
  1541.                         </div>
  1542.                         <div class="uv-ticket-main-rt">
  1543.                             <% if(createThread.createdBy == 'customer') { %>
  1544.                             <a href="{{ path('helpdesk_member_manage_customer_account') }}/<%= createThread.user.id %>" class="uv-ticket-member-name">
  1545.                                 <% } else { %>
  1546.                                 <% if(createThread.user) { %>
  1547.                                 <a href="{{ path('helpdesk_member_account') }}/<%= createThread.user.id %>" class="uv-ticket-member-name">
  1548.                                     <% } else { %>
  1549.                                     <a class="uv-ticket-member-name">
  1550.                                         <% } %>
  1551.                                         <% } %>
  1552.                                         <%- createThread.user.name %>
  1553.                                     </a>
  1554.                                     <div class="message">
  1555.                                         <p>
  1556.                                             <%= createThread.reply %>
  1557.                                         </p>
  1558.                                     </div>
  1559.                                     <!-- Attachment Block -->
  1560.                                     <% if(createThread.attachments.length) { %>
  1561.                                     <div class="uv-ticket-uploads">
  1562.                                         <h4>{{ 'Uploaded Files'|trans }}</h4>
  1563.                                         <div class="uv-ticket-uploads-strip">
  1564.                                             <% _.each(createThread.attachments, function(file) { %>
  1565.                                             <a href="<%-file.downloadURL %>" target ="_blank" class="uv-ticket-uploads-brick uv-no-pointer-events" data-toggle="tooltip" title="<%- file.name %>">
  1566.                                                 <img src="<%-file.iconURL %>" class="uv-auto-pointer-events">
  1567.                                             </a>
  1568.                                             <% }) %>
  1569.                                         </div>
  1570.                                         <% if(createThread.attachments.length >1) { %>
  1571.                                         <div class="thread-attachments-zip pull-left">
  1572.                                             <div class="uv-upload-actions">
  1573.                                                 <a href="{{ path('helpdesk_member_ticket_download_attachment_zip') }}/<%= createThread.id %>" target="_blank"><span class="uv-icon-attachment"></span> {{ 'Download (as .zip)'|trans }}</a>
  1574.                                             </div>
  1575.                                         </div>
  1576.                                         <% } %>
  1577.                                     </div>
  1578.                                     <% } %>
  1579.                                     <!-- //Attachment Block -->
  1580.                         </div>
  1581.                     </div>
  1582.                     <% if(lastReply) { %>
  1583.                     <div class="uv-ticket-main">
  1584.                         <div class="uv-ticket-strip">
  1585.                                 <span>
  1586.                                     <span class="uv-margin-0 timeago" data-timestamp="<%= lastReply.timestamp %>" title="<%= lastReply.formatedCreatedAt %>"><%= lastReply.formatedCreatedAt %></span>
  1587.                                     - <%- lastReply.user.name %>
  1588.                                     <span class="uv-ticket-strip-label">
  1589.                                         {{ 'made last reply'|trans }}
  1590.                                     </span>
  1591.                                 </span>
  1592.                         </div>
  1593.                         <div class="uv-ticket-main-lt">
  1594.                             <% if (lastReply.user.smallThumbnail != null) { %>
  1595.                                 <img class='border' src="{{ app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') }}<%= lastReply.user.smallThumbnail %>"/>
  1596.                             <% } else { %>
  1597.                                 <% if (lastReply.createdBy == 'customer') { %>
  1598.                                     <img class='border' src="{{ asset(default_customer_image_path) }}"/>
  1599.                                 <% } else { %>
  1600.                                     <img class='border' src="{{ asset(default_agent_image_path) }}"/>
  1601.                                 <% } %>
  1602.                             <% } %>
  1603.                         </div>
  1604.                         <div class="uv-ticket-main-rt">
  1605.                             <% if(lastReply.createdBy == 'customer') { %>
  1606.                             <a href="{{ path('helpdesk_member_manage_customer_account') }}/<%= lastReply.user.id %>" class="uv-ticket-member-name">
  1607.                                 <% } else { %>
  1608.                                 <% if(lastReply.user) { %>
  1609.                                 <a href="{{ path('helpdesk_member_account') }}/<%= lastReply.user.id %>" class="uv-ticket-member-name">
  1610.                                     <% } else { %>
  1611.                                     <a class="uv-ticket-member-name">
  1612.                                         <% } %>
  1613.                                         <% } %>
  1614.                                         <%- lastReply.user.name %>
  1615.                                     </a>
  1616.                                     <div class="message">
  1617.                                         <p>
  1618.                                             <%= lastReply.reply %>
  1619.                                         </p>
  1620.                                     </div>
  1621.                                     <!-- Attachment Block -->
  1622.                                     <% if(lastReply.attachments.length) { %>
  1623.                                     <div class="uv-ticket-uploads">
  1624.                                         <h4>{{ 'Uploaded Files'|trans }}</h4>
  1625.                                         <div class="uv-ticket-uploads-strip">
  1626.                                             <% _.each(lastReply.attachments, function(file) { %>
  1627.                                             <a href="<%-file.downloadURL %>" target ="_blank" class="uv-ticket-uploads-brick uv-no-pointer-events" data-toggle="tooltip" title="<%- file.name %>">
  1628.                                                 <img src="<%-file.iconURL %>" class="uv-auto-pointer-events">
  1629.                                             </a>
  1630.                                             <% }) %>
  1631.                                         </div>
  1632.                                         <% if(lastReply.attachments.length> 1) { %>
  1633.                                         <div class="thread-attachments-zip pull-left">
  1634.                                             <div class="uv-upload-actions">
  1635.                                                 <a href="{{ path('helpdesk_member_ticket_download_attachment_zip') }}/<%= lastReply.id %>" target="_blank"><span class="uv-icon-attachment"></span> {{ 'Download (as .zip)'|trans }}</a>
  1636.                                             </div>
  1637.                                         </div>
  1638.                                         <% } %>
  1639.                                     </div>
  1640.                                     <% } %>
  1641.                                     <!-- //Attachment Block -->
  1642.                         </div>
  1643.                     </div>
  1644.                     <% } %>
  1645.                 </div>
  1646.             </div>
  1647.         </div>
  1648.     </script>
  1649.     {# Ticket List Item View Template #}
  1650.     <script id="ticket_list_item_tmp" type="text/template">
  1651.         <td class="uv-width-200 uv-no-content">
  1652.             <span class="uv-list-ticket-priority" style="<% if(priority) { %>background: <%=priority.colorCode %><% } %>;">
  1653.                    <%- priority.description %>
  1654.             </span>
  1655.             <label class="uv-vertical-align uv-margin-right-5">
  1656.                 <div class="uv-checkbox">
  1657.                     <input type="checkbox" class="mass-action-checkbox" value="<%= id %>"/>
  1658.                     <span class="uv-checkbox-view"></span>
  1659.                 </div>
  1660.             </label>
  1661.             <% if(customer.esUltra) { %>
  1662.             <span  style="font-size:10px;background:gray;color:white;padding:2px;margin:2px;border-radius:5px;">
  1663.                      <%- customer.esUltra ? 'U':'' %>
  1664.                 </span>
  1665.             <% } %>
  1666.             <% if(customer.timezone) { %>
  1667.             <span  style="font-size:10px;background:gray;color:white;padding:2px;margin:2px;border-radius:5px;">
  1668.                      <%- customer.timezone %>
  1669.             </span>
  1670.             <% } %>
  1671.             
  1672.         </td>
  1673.         <td data-value="{{ 'ID'|trans }}" class="uv-width-100">
  1674.             <a href="<%= path %>">
  1675.                 #<%= id %>
  1676.             </a>
  1677.         </td>
  1678.         <td style="<%- subtype?.code === 'Incident with signal reception' ? 'background: red;' : '' %>"  data-index="subject"  role="tooltip"  data-placement="bottom" title=" <%- lastReply && lastReply.length <= 300 ? lastReply : lastReply.substr(0, 300) + '...'  %>" data-value="{{ 'Subject'|trans }}">
  1679.                 <a href="<%= path %>">
  1680.                     <%- subject && subject.length <= 300 ? subject : subject.substr(0, 300) + '...'  %>
  1681.                 </a>
  1682.              
  1683.          </td>
  1684.         <td data-index="reference" role="tooltip" data-placement="bottom" title=" <%- lastReply && lastReply.length <= 300 ? lastReply : lastReply.substr(0, 300) + '...'  %>" data-value="{{ 'Reference'|trans }}">
  1685.                 <a href="<%= path %>">
  1686.                     <%- reference  %>
  1687.                 </a>
  1688.              
  1689.          </td>
  1690.         <td data-value="{{ 'Customer Name'|trans }}" data-index="customer-name">
  1691.             <a href="<%= path %>">
  1692.                 <%- customer.name %>
  1693.             </a>
  1694.         </td>
  1695.         <td data-value="{{ 'Customer Email'|trans }}" data-index="customer-email">
  1696.             <a href="<%= path %>">
  1697.                 <%- customer.email %>
  1698.             </a>
  1699.         </td>
  1700.         <td data-value="{{ 'Timestamp'|trans }}" data-index="timestamp">
  1701.             <a href="<%= path %>" class="timeago" data-timestamp="<%= timestamp %>" title="<%= formatedCreatedAt %>">
  1702.                 <%= formatedCreatedAt %>
  1703.             </a>
  1704.         </td>
  1705.         <td data-value="{{ 'Group'|trans }}" data-index="group">
  1706.             <a href="<%= path %>">
  1707.                 <% if(group) { %>
  1708.                 <%- group %>
  1709.                 <% } else { %>
  1710.                 {{ 'N/A'|trans }}
  1711.                 <% } %>
  1712.             </a>
  1713.         </td>
  1714.         <td data-value="{{ 'Team'|trans }}" data-index="team">
  1715.             <a href="<%= path %>">
  1716.                 <% if(team) { %>
  1717.                 <%- team %>
  1718.                 <% } else { %>
  1719.                 {{ 'N/A'|trans }}
  1720.                 <% } %>
  1721.             </a>
  1722.         </td>
  1723.         <td data-value="{{ 'Type'|trans }}" data-index="type1">
  1724.             <a href="<%= path %>">
  1725.                 <% if(type) { %>
  1726.                 <%- type %>
  1727.                 <% } else { %>
  1728.                 {{ 'N/A'|trans }}
  1729.                 <% } %>
  1730.             </a>
  1731.         </td>
  1732.         <td data-value="{{ 'Replies'|trans }}" data-index="replies">
  1733.             <a href="<%= path %>">
  1734.                 <%= totalThreads %>
  1735.             </a>
  1736.         </td>
  1737.         <td data-value="{{ 'Agent'|trans }}" data-index="agent">
  1738.             <a href="<%= path %>">
  1739.                 <% if(agent) { %>
  1740.                 <% if(agent.smallThumbnail != null) { %>
  1741.                 <img src="{{ app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') }}<%= agent.smallThumbnail %>" alt=""/>
  1742.                 <% } else { %>
  1743.                 <img src="{{ asset(default_agent_image_path) }}" alt=""/>
  1744.                 <% } %>
  1745.                 <%- agent.name %>
  1746.                 <% } else { %>
  1747.                 {{ 'Unassigned'|trans }}
  1748.                 <% } %>
  1749.             </a>
  1750.         </td>
  1751.     </script>
  1752.     <script type="text/javascript">
  1753.         refresh();
  1754.         function refresh(){
  1755.             function reload() {
  1756.                 location.reload()
  1757.             }
  1758.             setInterval(reload, 60000);
  1759.         };
  1760.         var isPageJustLoaded = true;
  1761.         var globalMessageResponse = "";
  1762.         var currentUserId = "{{ user_service.getCurrentUser().id }}";
  1763.         var pathToTicket = "{{ path('helpdesk_member_ticket', {'ticketId': 'replaceId' }) }}";
  1764.         $(() => {
  1765.             $('#before-filter-input').datetimepicker({
  1766.                 format: 'DD-MM-YYYY',
  1767.                 maxDate: 'now',
  1768.                 useCurrent: false,
  1769.             });
  1770.             $('#after-filter-input').datetimepicker({
  1771.                 format: 'DD-MM-YYYY',
  1772.                 maxDate: 'now',
  1773.                 useCurrent: false,
  1774.             });
  1775.             // Ticket Model
  1776.             var TicketModel = Backbone.Model.extend({
  1777.                 idAttribute: "id",
  1778.                 defaults: {
  1779.                     path: "",
  1780.                 },
  1781.                 urlRoot: "{{ path('helpdesk_member_ticket_xhr') }}"
  1782.             });
  1783.             // Ticket Label Model
  1784.             var LabelModel = Backbone.Model.extend({
  1785.                 idAttribute: "id",
  1786.                 defaults: {
  1787.                     count: 0,
  1788.                 },
  1789.                 parse: function (resp, options) {
  1790.                     return JSON.parse(resp.label);
  1791.                 },
  1792.                 urlRoot: "{{ path('helpdesk_member_ticket_label_xhr') }}"
  1793.             });
  1794.             // Ticket Quick View Model
  1795.             var TicketQuickViewModel = Backbone.Model.extend({
  1796.                 idAttribute: "id",
  1797.                 defaults: {
  1798.                     path: "",
  1799.                     isSynced: false
  1800.                 }
  1801.             });
  1802.             // Side Filter Model
  1803.             var SideFilterModel = Backbone.Model.extend({
  1804.                 updateModel: function(type,json) {
  1805.                     if(this.has(type)) {
  1806.                         context = this.get(type)
  1807.                         savedOptionsIds = [];
  1808.                         _.each(context, function (option) {
  1809.                             savedOptionsIds.push(parseInt(option.id))
  1810.                         })
  1811.                         if(jQuery.inArray(parseInt(json.id), savedOptionsIds) == -1) {
  1812.                             context.push(json);
  1813.                             this.set(type, context)
  1814.                         }
  1815.                     } else {
  1816.                         this.set(type, [json])
  1817.                     }
  1818.                 },
  1819.                 loadFilterOptions: function(data) {
  1820.                     var self = this;
  1821.                     $.ajax({
  1822.                         url : "{{ path('helpdesk_member_ticket_collection_load_filter_options_xhr') }}",
  1823.                         type : 'POST',
  1824.                         data: data,
  1825.                         dataType : 'json',
  1826.                         success : function(response) {
  1827.                             _.each(response,function(filter,key) {
  1828.                                 _.each(filter, function (item) {
  1829.                                     self.updateModel(key,item)
  1830.                                 })
  1831.                             })
  1832.                             sideFilter.render();
  1833.                         },
  1834.                         error: function (xhr) {
  1835.                             if(url = xhr.getResponseHeader('Location'))
  1836.                                 window.location = url;
  1837.                         }
  1838.                     });
  1839.                 }
  1840.             });
  1841.             // Ticket Label Collection
  1842.             var LabelCollection = Backbone.Collection.extend({
  1843.                 model: LabelModel,
  1844.                 isLabelExist: function(labelName, labelId) {
  1845.                     var flag = 1;
  1846.                     _.each(this.models, function (item) {
  1847.                         if(item.get('name').toUpperCase() == labelName.toUpperCase() && item.id != labelId)
  1848.                             flag = 0;
  1849.                     }, this);
  1850.                     return flag;
  1851.                 }
  1852.             });
  1853.             // Ticket Collection
  1854.             var TicketCollection = AppCollection.extend({
  1855.                 model: TicketModel,
  1856.                 url: "{{ path('helpdesk_member_ticket_collection_xhr') }}",
  1857.                 filterParameters: {
  1858.                     label: "",
  1859.                     new: "",
  1860.                     unassigned: "",
  1861.                     notreplied: "",
  1862.                     mine: "",
  1863.                     starred: "",
  1864.                     trashed: "",
  1865.                     label: "",
  1866.                     status: "",
  1867.                     search: "",
  1868.                     agent: "",
  1869.                     customer: "",
  1870.                     priority: "",
  1871.                     type: "",
  1872.                     group: "",
  1873.                     team: "",
  1874.                     tag: "",
  1875.                     mailbox : "",
  1876.                     source : "",
  1877.                     after: "",
  1878.                     before: "",
  1879.                     repliesLess: "",
  1880.                     repliesMore: "",
  1881.                 },
  1882.                 parseRecords: function (response, options) {
  1883.                     return response.tickets;
  1884.                 },
  1885.                 syncData: function() {
  1886.                     app.appView.showLoader();
  1887.                     $('.select-all-checkbox').prop('checked', false);
  1888.                     this.fetch({
  1889.                         data: this.getValidParameters(),
  1890.                         reset: true,
  1891.                         success: function(model, response) {
  1892.                             ticketQuickViewCollection.reset()
  1893.                             app.appView.hideLoader();
  1894.                             var ticketListView = new TicketList();
  1895.                             app.pager.paginationData = response.pagination;
  1896.                             var url = app.pager.paginationData.url;
  1897.                             if(ticketCollection.length == 0 && app.pager.paginationData.current != "0")
  1898.                                 router.navigate(url.replace('replacePage', app.pager.paginationData.last),{trigger: true});
  1899.                             else {
  1900.                                 app.pager.render();
  1901.                                 statusListDetails = response.tabs;
  1902.                                 labelDetails = response.labels;
  1903.                                 labelListView.render();
  1904.                             }
  1905.                             if (globalMessageResponse) {
  1906.                                 app.appView.renderResponseAlert(globalMessageResponse);
  1907.                             }
  1908.                             globalMessageResponse = null;
  1909.                             sideFilter.backToFilter()
  1910.                         },
  1911.                         error: function (model, xhr, options) {
  1912.                             app.appView.hideLoader();
  1913.                             if(url = xhr.getResponseHeader('Location'))
  1914.                                 window.location = url;
  1915.                         }
  1916.                     });
  1917.                 },
  1918.                 batchOperation: function(data) {
  1919.                     var self = this;
  1920.                     app.appView.showLoader();
  1921.                     $.ajax({
  1922.                         url : "{{ path('helpdesk_member_ticket_collection_mass_action_xhr') }}",
  1923.                         type : 'POST',
  1924.                         data : {data : data},
  1925.                         dataType : 'json',
  1926.                         success : function(response) {
  1927.                             app.appView.hideLoader();
  1928.                             globalMessageResponse = response;
  1929.                             self.syncData();
  1930.                         },
  1931.                         error: function (xhr) {
  1932.                             if(url = xhr.getResponseHeader('Location'))
  1933.                                 window.location = url;
  1934.                             var response = warningResponse;
  1935.                             if(xhr.responseJSON)
  1936.                                 response = xhr.responseJSON;
  1937.                             app.appView.hideLoader();
  1938.                             app.appView.renderResponseAlert(response);
  1939.                             $('.mass-action-checkbox').prop('checked', false);
  1940.                         }
  1941.                     });
  1942.                 }
  1943.             });
  1944.             // Ticket Quick View Collection
  1945.             var TicketQuickViewCollection = Backbone.Collection.extend({
  1946.                 model: TicketQuickViewModel,
  1947.                 isModelSynced: function(id) {
  1948.                     if (model = this.get(id)) {
  1949.                         if (parseInt(model.attributes.isSynced)) {
  1950.                             return model;
  1951.                         }
  1952.                     }
  1953.                     return false;
  1954.                 },
  1955.                 initialize: function() {
  1956.                     _.bindAll(this, 'getNextPrev', 'nextElement', 'previousElement');
  1957.                 },
  1958.                 getNextPrev : function(id) {
  1959.                     var data = {};
  1960.                     currentModel = ticketQuickViewCollection.get(id)
  1961.                     data['next'] = (model = this.nextElement(currentModel)) ? model.id : 0;
  1962.                     data['previous'] = (model = this.previousElement(currentModel)) ? model.id : 0;
  1963.                     return data;
  1964.                 },
  1965.                 nextElement: function(model) {
  1966.                     var index = ticketQuickViewCollection.indexOf(model);
  1967.                     if ((index + 1) === ticketQuickViewCollection.length)
  1968.                         return 0;
  1969.                     return ticketQuickViewCollection.at(index + 1);
  1970.                 },
  1971.                 previousElement: function(model) {
  1972.                     var index = ticketQuickViewCollection.indexOf(model);
  1973.                     if (index === 0 )
  1974.                         return 0;
  1975.                     return ticketQuickViewCollection.at(index - 1);
  1976.                 }
  1977.             });
  1978.             // Filter
  1979.             var Filter = app.Filter.extend({
  1980.                 defaultSortIndex: 'ticket.updatedAt',
  1981.                 sortText: "{% trans %}Sort By:{% endtrans %} ",
  1982.                 defaultSortText: "{% trans %}Sort By:{% endtrans %} {% trans %}Last Replied{% endtrans %}",
  1983.                 template : _.template($("#ticket_list_sorting_tmp").html()),
  1984.                 events : {
  1985.                     'keyup .uv-search-inline' : 'search',
  1986.                     'change .asset-visibility input[type="checkbox"]': 'filterAssetsVisibility'
  1987.                 },
  1988.                 filterAssetsVisibilityOnLoad: function() {
  1989.                     if(localStorage.getItem('assets-visibility')) {
  1990.                         var assets = JSON.parse(localStorage.getItem('assets-visibility'));
  1991.                         $.each(assets, function(asset, assetVal) {
  1992.                             if(assetVal) {
  1993.                                 $('span[data-index="' + asset + '"], td[data-index="' +asset + '"], th[data-index="' + asset + '"]').show()
  1994.                                 $('#' + asset).prop('checked', true);
  1995.                             } else {
  1996.                                 $('span[data-index="' + asset + '"], td[data-index="' +asset + '"], th[data-index="' + asset + '"]').hide()
  1997.                                 $('#' + asset).prop('checked', false);
  1998.                             }
  1999.                         })
  2000.                     }
  2001.                 },
  2002.                 filterAssetsVisibility: function(e) {
  2003.                     var assets = {};
  2004.                  
  2005.                     $('.asset-visibility input').each(function() {
  2006.                         var asset = $(this).val();
  2007.                         if($(this).is(':checked')) {
  2008.                             assets[asset] = 1;
  2009.                             $('span[data-index="' + asset + '"], td[data-index="' + asset + '"], th[data-index="' + asset + '"]').show()
  2010.                         } else {
  2011.                             assets[asset] = 0;
  2012.                             $('span[data-index="' + asset + '"], td[data-index="' + asset + '"], th[data-index="' + asset + '"]').hide()
  2013.                         }
  2014.                     });
  2015.                     localStorage.setItem('assets-visibility', JSON.stringify(assets));
  2016.                 },
  2017.                 search : _.debounce(function(e) {
  2018.                     this.collection.reset();
  2019.                     this.collection.state.currentPage = null;
  2020.                     this.collection.filterParameters.search = Backbone.$(e.target).val();
  2021.                     var queryString = app.appView.buildQuery($.param(this.collection.getValidParameters()));
  2022.                     router.navigate(queryString,{trigger: true});
  2023.                 }, 1000)
  2024.             });
  2025.             // Side Filter View
  2026.             var SideFilter = Backbone.View.extend({
  2027.                 el: $(".uv-filter-view"),
  2028.                 isRecurrsiveCalls: 0,
  2029.                 isReadyFlag: 0,
  2030.                 appliedFilterOptions: {},
  2031.                 tempAppliedFilterOptions: {},
  2032.                 events: {
  2033.                     'change #saved-filter': 'applySavedFilter',
  2034.                     'input .uv-field-block input' : 'searchFilterOption',
  2035.                     'click .uv-dropdown-list li' : 'applyFilter',
  2036.                     'dp.change .range input': 'applyFilter',
  2037.                     'click .uv-filtered-tags .uv-btn-tag' : 'removeFilter',
  2038.                     'change .custom-filter' : 'filterByCustom',
  2039.                     'change #repliesLess-filter-input' : 'filterByRepliesLessThan',
  2040.                     'change #repliesMore-filter-input' : 'filterByRepliesMoreThan',
  2041.                     'keyup .search-custom, change .search-custom' : 'filterByCustom',
  2042.                     'click .new-saved-reply, .edit-saved-reply, .uv-filter-paper .uv-customize': 'addEditSavedReply',
  2043.                     'click .back-to-filter': 'backToFilter',
  2044.                     'click .uv-filter-edit .uv-btn-tag': 'removeSavedFilterOption',
  2045.                     'click .uv-filter-edit .save-filter, .uv-filter-edit .update-filter' : "saveSavedFilter",
  2046.                     'click .uv-filter-edit .uv-action-buttons .uv-btn-remove': 'removeSavedFilter'
  2047.                 },
  2048.                 loaderTemplate: _.template($("#loader-tmp").html()),
  2049.                 addEditSavedReplyTemplate: _.template($("#add_edit_saved_filter_tmp").html()),
  2050.                 checkOptionAvailable: function() {
  2051.                     this.isReadyFlag = 0;
  2052.                     var self = this;
  2053.                     var fetchOptions = {};
  2054.                     _.each(ticketCollection.filterParameters, function (filter,key) {
  2055.                         if(jQuery.inArray(key, ['customer','tag','label']) !== -1) {
  2056.                             if(filter != null && filter != '') {
  2057.                                 filter = filter.split(',');
  2058.                                 if(typeof fetchOptions[key] === 'undefined')
  2059.                                     fetchOptions[key] = [];
  2060.                                 savedOptionsIds = [];
  2061.                                 if(sideFilterModel.has(key)) {
  2062.                                     _.each(sideFilterModel.get(key), function (option) {
  2063.                                         savedOptionsIds.push(parseInt(option.id))
  2064.                                     })
  2065.                                 }
  2066.                                 _.each(filter, function (item) {
  2067.                                     if(jQuery.inArray(parseInt(item), savedOptionsIds) == -1) {
  2068.                                         fetchOptions[key].push(parseInt(item));
  2069.                                         self.isReadyFlag = 1;
  2070.                                     }
  2071.                                 })
  2072.                             }
  2073.                         }
  2074.                     });
  2075.                     return fetchOptions;
  2076.                 },
  2077.                 render: function() {
  2078.                     fetchOptions = this.checkOptionAvailable();
  2079.                     if(this.isReadyFlag && !this.isRecurrsiveCalls) {
  2080.                         this.isReadyFlag = 0;
  2081.                         this.isRecurrsiveCalls = 1;
  2082.                         sideFilterModel.loadFilterOptions(fetchOptions)
  2083.                     } else {
  2084.                         var appliedFilterOptions = {};
  2085.                         $('.uv-filtered-tags').html("")
  2086.                         var self = this;
  2087.                         var displayFlag = 0;
  2088.                         _.each(ticketCollection.filterParameters, function (filter, key) {
  2089.                             if(jQuery.inArray(key, ['customer', 'agent', 'priority', 'type', 'group', 'team', 'tag', 'mailbox', 'source', 'after', 'before', 'repliesLess', 'repliesMore']) !== -1) {
  2090.                                 if(filter != null && filter != '') {
  2091.                                     displayFlag = 1;
  2092.                                     filter = filter.split(',');
  2093.                                     appliedFilterOptions[key] = {'name': key.charAt(0).toUpperCase() + key.slice(1)};
  2094.                                     appliedFilterOptions[key]['options'] = [];
  2095.                                     _.each(filter, function (value) {
  2096.                                         if(key == 'after' || key == 'before' || key == 'repliesLess' || key == 'repliesMore') {
  2097.                                             $("#" + key + "-filter-input").val(filter)
  2098.                                             appliedFilterOptions[key]['options'].push({'id': filter, 'name': filter});
  2099.                                         } else {
  2100.                                             savedOptions = sideFilterModel.get(key)
  2101.                                             _.each(savedOptions, function (item) {
  2102.                                                 if(item.id == value) {
  2103.                                                     appliedFilterOptions[key]['options'].push({'id': item.id, 'name': item.name});
  2104.                                                     parent = $('#'+key+'-filter')
  2105.                                                     parent.find('.uv-filtered-tags').append("<a class='uv-btn-tag' href='#' data-id='" + item.id + "'>" + item.name + "<span class='uv-icon-remove-dark'></span></a>")
  2106.                                                     parent.find('input').val('')
  2107.                                                 }
  2108.                                             })
  2109.                                         }
  2110.                                     });
  2111.                                 }
  2112.                             } else if(jQuery.inArray(key, ['new','unassigned','notreplied','mine','starred','trashed']) !== -1) {
  2113.                                 if(filter != null && filter != '') {
  2114.                                     displayFlag = 1;
  2115.                                     appliedFilterOptions[key] = {'name': "{{ 'Label'|trans }}"};
  2116.                                     appliedFilterOptions[key]['options'] = [];
  2117.                                     var optionName = (key == 'mine') ? "{% trans %}Assigned to me{% endtrans %}" : key.charAt(0).toUpperCase() + key.slice(1);
  2118.                                     appliedFilterOptions[key]['options'].push({'id': key, 'name': optionName});
  2119.                                 } else {
  2120.                                     if(!ticketCollection.filterParameters.new && !ticketCollection.filterParameters.unassigned && !ticketCollection.filterParameters.notreplied && !ticketCollection.filterParameters.mine && !ticketCollection.filterParameters.starred && !ticketCollection.filterParameters.trashed &&! ticketCollection.filterParameters.label) {
  2121.                                         appliedFilterOptions['all'] = {'name': "{{ 'Label'|trans }}"};
  2122.                                         appliedFilterOptions['all']['options'] = [];
  2123.                                         appliedFilterOptions['all']['options'].push({'id': 1, 'name': "{{ 'All'|trans }}"});
  2124.                                     }
  2125.                                 }
  2126.                             } else if(key == 'label') {
  2127.                                 if(filter != null && filter != '') {
  2128.                                     displayFlag = 1;
  2129.                                     var labelModel = labelCollection.get(filter);
  2130.                                     appliedFilterOptions[key] = {'name': "{{ 'Label'|trans }}"};
  2131.                                     appliedFilterOptions[key]['options'] = [];
  2132.                                     if(labelModel) {
  2133.                                         appliedFilterOptions[key]['options'] = [];
  2134.                                         appliedFilterOptions[key]['options'].push({'id': labelModel.attributes.id, 'name': labelModel.attributes.name});
  2135.                                     } else {
  2136.                                         savedOptions = sideFilterModel.get(key)
  2137.                                         _.each(savedOptions, function (item) {
  2138.                                             if(item.id == filter) {
  2139.                                                 appliedFilterOptions[key]['options'].push({'id': item.id, 'name': item.name});
  2140.                                             }
  2141.                                         });
  2142.                                     }
  2143.                                 } else {
  2144.                                     if(!ticketCollection.filterParameters.new && !ticketCollection.filterParameters.unassigned && !ticketCollection.filterParameters.notreplied && !ticketCollection.filterParameters.mine && !ticketCollection.filterParameters.starred && !ticketCollection.filterParameters.trashed &&! ticketCollection.filterParameters.label) {
  2145.                                         appliedFilterOptions['all'] = {'name': "{{ 'Label'|trans }}"};
  2146.                                         appliedFilterOptions['all']['options'] = [];
  2147.                                         appliedFilterOptions['all']['options'].push({'id': 1, 'name': "{{ 'All'|trans }}"});
  2148.                                     }
  2149.                                 }
  2150.                             } else if(key == 'status') {
  2151.                                 appliedFilterOptions[key] = {'name': "{{ 'Status'|trans }}"};
  2152.                                 appliedFilterOptions[key]['options'] = []
  2153.                                 if(filter != null && filter != '' && filter != 1) {
  2154.                                     displayFlag = 1;
  2155.                                     appliedFilterOptions[key]['options'].push({'id': filter, 'name': $(".status-list li a[data-id='" + filter + "'] .name").text().trim()});
  2156.                                 } else {
  2157.                                     appliedFilterOptions[key]['options'].push({'id': 1,'name': "{{ 'Open'|trans }}"});
  2158.                                 }
  2159.                             } else if(key == 'search') {
  2160.                                 if(filter != null && filter != '') {
  2161.                                     displayFlag = 1;
  2162.                                     appliedFilterOptions[key] = {'name': "{{ 'Search Query'|trans }}"};
  2163.                                     appliedFilterOptions[key]['options'] = [];
  2164.                                     appliedFilterOptions[key]['options'].push({'id': filter, 'name': filter});
  2165.                                 }
  2166.                             } else if(key == 'custom') {
  2167.                                 if(filter != null && filter != '') {
  2168.                                     self.$el.find('[data-filter="custom"]').remove();
  2169.                                     displayFlag = 1;
  2170.                                     var realKey = key;
  2171.                                     var checkBoxStore = Array();
  2172.                                     var dataValueValueSeprator = '_';
  2173.                                     var columnSeperator = '|';
  2174.                                     var multiOptions = filter.split(columnSeperator);
  2175.                                     var multiKeyValue, multiKeyValueValue, ele, newEle;
  2176.                                     _.each(multiOptions, function(valueData, indexData) {
  2177.                                         if(!valueData)
  2178.                                             return;
  2179.                                         multiKeyValue = valueData.split(dataValueValueSeprator);
  2180.                                         multiKeyValueValue = multiKeyValue[1].split(',');
  2181.                                         eleSelector = '[data-value="' + multiKeyValue[0] + '"]';
  2182.                                         ele = $(eleSelector);
  2183.                                         if(ele[0].type == 'radio') {
  2184.                                             var dataValue = multiKeyValue[0];
  2185.                                             name = ele.parents('.uv-element-block:not(.radio)').find('label:first').text().trim()
  2186.                                             value =  $(eleSelector + '[value="' + multiKeyValue[1] + '"]').parent().next().text();
  2187.                                             appliedFilterOptions['z-'+dataValue] = {'name': name, 'type': 'radio'};
  2188.                                             appliedFilterOptions['z-'+dataValue]['options'] = [];
  2189.                                             appliedFilterOptions['z-'+dataValue]['options'].push({'id': multiKeyValue[1], 'name': value});
  2190.                                         } else if(ele[0].type == 'checkbox') {
  2191.                                             var dataValue = multiKeyValue[0];
  2192.                                             if($.inArray(dataValue, checkBoxStore) >= 0)
  2193.                                                 return;
  2194.                                             checkBoxStore.push(dataValue);
  2195.                                             name = ele.parents('.uv-element-block:not(.checkbox)').find('label:first').text().trim()
  2196.                                             appliedFilterOptions['z-'+dataValue] = {'name': name, 'type': 'checkbox'};
  2197.                                             appliedFilterOptions['z-'+dataValue]['options'] = [];
  2198.                                             var optionName, optionValue;
  2199.                                             _.each(multiKeyValueValue, function(value) {
  2200.                                                 newEle = $(eleSelector + '[value="' + value + '"]')
  2201.                                                 optionValue = dataValue + dataValueValueSeprator + newEle.val();
  2202.                                                 optionName = newEle.parent().next().text();
  2203.                                                 if(optionValue && optionName) {
  2204.                                                     appliedFilterOptions['z-'+dataValue]['options'].push({'id': value, 'name': optionName});
  2205.                                                 }
  2206.                                             });
  2207.                                         } else if(ele[0].type == 'select-multiple') {
  2208.                                             var dataValue = multiKeyValue[0];
  2209.                                             filter = multiKeyValueValue;
  2210.                                             key = ele.attr('id');
  2211.                                             name = ele.parents('.uv-element-block').find('label:first').text().trim()
  2212.                                             appliedFilterOptions['z-'+dataValue] = {'name': name, 'type': 'select-multiple'};
  2213.                                             appliedFilterOptions['z-'+dataValue]['options'] = [];
  2214.                                             _.each(filter, function (value) {
  2215.                                                 var optionName;
  2216.                                                 if(optionName = $("#"+key+" option[value='" + value + "']").text()) {
  2217.                                                     appliedFilterOptions['z-'+dataValue]['options'].push({'id': value, 'name': optionName});
  2218.                                                 }
  2219.                                             });
  2220.                                         } else if(ele[0].type == 'text' || ele[0].type == 'number') {
  2221.                                             filter = multiKeyValue[1];
  2222.                                             if(filter != null && filter != '') {
  2223.                                                 filter = filter.replace(/\+/g,' ');
  2224.                                                 displayFlag = 1;
  2225.                                                 var dataValue = ele.attr('data-value');
  2226.                                                 name = ele.parents('.uv-element-block').find('label:first').text().trim()
  2227.                                                 appliedFilterOptions['z-'+dataValue] = {'name': name, 'type': ele[0].type};
  2228.                                                 appliedFilterOptions['z-'+dataValue]['options'] = [];
  2229.                                                 appliedFilterOptions['z-'+dataValue]['options'].push({'id': 1, 'name': filter});
  2230.                                             }
  2231.                                         }
  2232.                                     })
  2233.                                 }
  2234.                             }
  2235.                             if('after' == key || 'before' == key || 'repliesLess' == key || 'repliesMore' == key) {
  2236.                                 $('#'+ key +'-filter-input').val(filter);
  2237.                             }
  2238.                         })
  2239.                         if(displayFlag) {
  2240.                             self.$el.find('.uv-filter-options .uv-action-buttons').html("")
  2241.                             if($("#saved-filter").val() != null && $("#saved-filter").val() != '' && Backbone.history.getFragment() == userFilters[$("#saved-filter").val()]['route']) {
  2242.                                 self.$el.find('.uv-filter-options .uv-action-buttons').append("<a class='uv-btn edit-saved-reply' href='#'>{{ 'Edit'|trans }}</a>").show();
  2243.                                 $('.uv-filter-paper .uv-customize').show()
  2244.                             } else {
  2245.                                 self.$el.find('.uv-filter-options .uv-action-buttons').append("<a class='uv-btn new-saved-reply' href='#'>{{ 'New'|trans }}</a>").show();
  2246.                                 if($("#saved-filter").val() != null && $("#saved-filter").val() != '') {
  2247.                                     self.$el.find('.uv-filter-options .uv-action-buttons').append("<a class='uv-btn edit-saved-reply' href='#'>{{ 'Update'|trans }}</a>").show();
  2248.                                     $('.uv-filter-paper .uv-customize').show()
  2249.                                 } else {
  2250.                                     $('.uv-filter-paper .uv-customize').hide()
  2251.                                 }
  2252.                             }
  2253.                         } else {
  2254.                             $('.uv-filter-paper .uv-customize').hide()
  2255.                         }
  2256.                         this.appliedFilterOptions = appliedFilterOptions;
  2257.                         this.tempAppliedFilterOptions = jQuery.extend(true, {}, appliedFilterOptions);
  2258.                     }
  2259.                 },
  2260.                 searchFilterOption: function(e) {
  2261.                     self = this;
  2262.                     currentElement = Backbone.$(e.currentTarget);
  2263.                     dropdown = currentElement.siblings('.uv-dropdown-list');
  2264.                     var filterType =  currentElement.attr('data-filter-type');
  2265.                     if(jQuery.inArray(filterType, ['customer', 'tag']) !== -1) {
  2266.                         self.searchFilterXhr(currentElement);
  2267.                     }
  2268.                 },
  2269.                 searchFilterXhr: _.debounce(function(currentElement) {
  2270.                     var parent = currentElement.parent();
  2271.                     if($('.uv-dropdown-other.uv-dropdown-btn-active').parent().attr('id') != parent.attr('id'))
  2272.                         return;
  2273.                     parent.find("li:not(.uv-no-results, .uv-filter-info)").remove();
  2274.                     parent.find(".uv-filter-info").show()
  2275.                     if(currentElement.val().length > 1) {
  2276.                         parent.append(this.loaderTemplate())
  2277.                         parent.find('.uv-filter-info').text("{% trans %}Searching{% endtrans %} ...")
  2278.                         if(self.xhrReq)
  2279.                             self.xhrReq.abort();
  2280.                         self.xhrReq = $.ajax({
  2281.                             url : "{{ path('helpdesk_member_ticket_collection_search_filter_options_xhr') }}",
  2282.                             type : 'GET',
  2283.                             data: {"type" : currentElement.attr('data-filter-type'), "query" : currentElement.val(), 'not' : ticketCollection.filterParameters[currentElement.attr('data-filter-type')]},
  2284.                             dataType : 'json',
  2285.                             success : function(response) {
  2286.                                 self.xhrReq = 0;
  2287.                                 parent.find('.uv-loader').remove()
  2288.                                 parent.find('.uv-filter-info').text("{{ 'Type atleast 2 letters'|trans }}").hide();
  2289.                                 if(response.length == 0) {
  2290.                                     parent.find('.uv-no-results').show()
  2291.                                 } else {
  2292.                                     parent.find('.uv-no-results').hide();
  2293.                                     _.each(response, function(item) {
  2294.                                         if(currentElement.attr('data-filter-type') == 'customer') {
  2295.                                             var img = item.smallThumbnail ? item.smallThumbnail : "{{ asset(default_customer_image_path) }}";
  2296.                                             parent.find('.uv-dropdown-list ul').append("<li data-id='" + item.id + "'><img src='" + img + "'/>" + item.name + "</li>")
  2297.                                         } else
  2298.                                             parent.find('.uv-dropdown-list ul').append("<li data-id='" + item.id + "'>" + item.name + "</li>")
  2299.                                     });
  2300.                                 }
  2301.                             },
  2302.                             error: function (xhr) {
  2303.                                 self.xhrReq = 0;
  2304.                                 parent.find('.uv-loader').remove()
  2305.                                 parent.find('.uv-no-results').hide();
  2306.                                 parent.find('.uv-filter-info').text("{{ 'Type atleast 2 letters'|trans }}").show();
  2307.                                 if(url = xhr.getResponseHeader('Location'))
  2308.                                     window.location = url;
  2309.                             }
  2310.                         });
  2311.                     } else {
  2312.                         parent.find('.uv-no-results').hide();
  2313.                     }
  2314.                 },1000),
  2315.                 applySavedFilter: function(e) {
  2316.                     var element = Backbone.$(e.currentTarget);
  2317.                     if(element.val() != "") {
  2318.                         var element = Backbone.$(e.currentTarget);
  2319.                         router.navigate(userFilters[element.val()]['route'], {trigger: true});
  2320.                     } else {
  2321.                         router.navigate('', {trigger: true});
  2322.                     }
  2323.                 },
  2324.                 applyFilter: function(e) {
  2325.                     currentElement = Backbone.$(e.currentTarget);
  2326.                     if(currentElement.attr("data-id")) {
  2327.                         var flag = 1;
  2328.                         parent = currentElement.parents(".uv-field-block");
  2329.                         filterType = parent.find('input').attr('data-filter-type');
  2330.                         if(filterType == "customer" || filterType == 'tag') {
  2331.                             sideFilterModel.updateModel(filterType, {'id': currentElement.attr('data-id'), 'name': currentElement.text()})
  2332.                             parent.find(".uv-no-results").hide()
  2333.                             parent.find(".uv-filter-info").show().text("{{ 'Type atleast 2 letters'|trans }}")
  2334.                             parent.find("li:not(.uv-no-results, .uv-filter-info)").remove();
  2335.                         } else {
  2336.                             if(ticketCollection.filterParameters[filterType]) {
  2337.                                 ids = ticketCollection.filterParameters[filterType].split(',')
  2338.                                 if(jQuery.inArray(currentElement.attr('data-id'), ids) !== -1)
  2339.                                     flag = 0;
  2340.                             }
  2341.                         }
  2342.                         parent.find('input').val('')
  2343.                         if(jQuery.inArray(filterType, ['agent', 'priority', 'type', 'group', 'team', 'mailbox', 'source']) !== -1) {
  2344.                             parent.find("li:not(.uv-no-results)").show()
  2345.                         }
  2346.                         if(flag) {
  2347.                             parent.find('.uv-filtered-tags').append("<a class='uv-btn-tag' href='#' data-id='" + currentElement.attr('data-id') + "'>"+currentElement.text()+"<span class='uv-icon-remove-dark'></span></a>")
  2348.                             ticketCollection.state.order = null;
  2349.                             ticketCollection.state.sortKey = null;
  2350.                             ticketCollection.state.currentPage = null;
  2351.                             ticketCollection.filterParameters[filterType] = this.joinTagValues(parent.find(".uv-filtered-tags"));
  2352.                             var queryString = app.appView.buildQuery($.param(ticketCollection.getValidParameters()));
  2353.                             router.navigate(queryString, {trigger: true});
  2354.                         }
  2355.                     } else {
  2356.                         filterType = currentElement.attr('data-filter-type');
  2357.                         if(filterType == 'before' || filterType == "after") {
  2358.                             ticketCollection.state.order = null;
  2359.                             ticketCollection.state.sortKey = null;
  2360.                             ticketCollection.state.currentPage = null;
  2361.                             ticketCollection.filterParameters[filterType] = currentElement.val();
  2362.                             var queryString = app.appView.buildQuery($.param(ticketCollection.getValidParameters()));
  2363.                             router.navigate(queryString, {trigger: true});
  2364.                         }
  2365.                     }
  2366.                 },
  2367.                 removeFilter: function(e) {
  2368.                     e.preventDefault()
  2369.                     currentElement = Backbone.$(e.currentTarget);
  2370.                     filterType = currentElement.parents('.uv-field-block').find('input').attr('data-filter-type')
  2371.                     var options = ticketCollection.filterParameters[filterType];
  2372.                     options = options.split(',');
  2373.                     var index = options.indexOf(currentElement.attr('data-id'));
  2374.                     options.splice(index, 1);
  2375.                     ticketCollection.state.order = null;
  2376.                     ticketCollection.state.sortKey = null;
  2377.                     ticketCollection.state.currentPage = null;
  2378.                     ticketCollection.filterParameters[filterType] = options.join(',');
  2379.                     currentElement.remove()
  2380.                     var queryString = app.appView.buildQuery($.param(ticketCollection.getValidParameters()));
  2381.                     router.navigate(queryString, {trigger: true});
  2382.                 },
  2383.                 joinTagValues: function(parent) {
  2384.                     var ids = new Array();
  2385.                     parent.find('.uv-btn-tag').each(function() {
  2386.                         ids.push($(this).attr('data-id'))
  2387.                     });
  2388.                     return ids.join();
  2389.                 },
  2390.                 filterByRepliesMoreThan: _.debounce(function(e) {
  2391.                     ticketCollection.state.order = null;
  2392.                     ticketCollection.state.sortKey = null;
  2393.                     ticketCollection.state.currentPage = null;
  2394.                     ticketCollection.filterParameters.repliesMore = $(e.target).val();
  2395.                     var queryString = app.appView.buildQuery($.param(ticketCollection.getValidParameters()));
  2396.                     router.navigate(queryString, { trigger: true });
  2397.                 }, 1000),
  2398.                 filterByRepliesLessThan: _.debounce(function(e) {
  2399.                     ticketCollection.state.order = null;
  2400.                     ticketCollection.state.sortKey = null;
  2401.                     ticketCollection.state.currentPage = null;
  2402.                     ticketCollection.filterParameters.repliesLess = $(e.target).val();
  2403.                     var queryString = app.appView.buildQuery($.param(ticketCollection.getValidParameters()));
  2404.                     router.navigate(queryString, { trigger: true });
  2405.                 }, 1000),
  2406.                 filterByCustom: _.debounce(function(e) {
  2407.                     var custom = '';
  2408.                     var checkBoxStore = Array();
  2409.                     var indexValueSeperator = '_';
  2410.                     var columnSeperator = '|';
  2411.                     Backbone.$('.custom-filter').each(function(){
  2412.                         if($(this).context.type == 'radio' && $(this).is(':checked')) {
  2413.                             custom += $(this).attr('data-value') + indexValueSeperator + $(this).val() + columnSeperator;
  2414.                         } else if($(this).context.type == 'checkbox' && $(this).is(':checked')) {
  2415.                             var checkboxValue = Array();
  2416.                             var dataValue = $(this).attr('data-value');
  2417.                             if($.inArray(dataValue, checkBoxStore) >= 0)
  2418.                                 return;
  2419.                             $.each($('[data-value="'+ dataValue +'"]:checked'), function() {
  2420.                                 checkboxValue.push($(this).val());
  2421.                             });
  2422.                             checkBoxStore.push(dataValue);
  2423.                             custom += dataValue + indexValueSeperator + checkboxValue.join() + columnSeperator;
  2424.                         } else if($(this).context.type == 'select-multiple' && $(this).val()) {
  2425.                             custom += $(this).attr('data-value') + indexValueSeperator + $(this).val().join() + columnSeperator;
  2426.                         }
  2427.                     })
  2428.                     Backbone.$('.search-custom').each(function(){
  2429.                         if($(this).val()){
  2430.                             custom += $(this).attr('data-value') + indexValueSeperator + $(this).val() + columnSeperator;
  2431.                         }
  2432.                     })
  2433.                     custom = custom.replace(/\|$/, '');
  2434.                     ticketCollection.state.order = null;
  2435.                     ticketCollection.state.sortKey = null;
  2436.                     ticketCollection.state.currentPage = null;
  2437.                     ticketCollection.filterParameters.custom = custom;
  2438.                     var queryString = app.appView.buildQuery($.param(ticketCollection.getValidParameters()));
  2439.                     router.navigate(queryString,{trigger: true});
  2440.                 }, 1000),
  2441.                 backToFilter: function(e) {
  2442.                     console.log('backtofilter');
  2443.                     if(e)
  2444.                         e.preventDefault()
  2445.                     this.$el.find('.uv-filter-options').show()
  2446.                     this.$el.find('.uv-filter-edit').hide()
  2447.                 },
  2448.                 addEditSavedReply: function(e) {
  2449.                     e.preventDefault()
  2450.                     var context = {};
  2451.                     this.tempAppliedFilterOptions = jQuery.extend(true, {}, this.appliedFilterOptions);
  2452.                     if(Backbone.$(e.currentTarget).is('.new-saved-reply')) {
  2453.                         context = {'id': 0, 'name': '', 'is_default': 0, 'filters': this.tempAppliedFilterOptions};
  2454.                     } else {
  2455.                         context = userFilters[$("#saved-filter").val()];
  2456.                         context.filters = this.tempAppliedFilterOptions;
  2457.                         userFilters[$("#saved-filter").val()]
  2458.                     }
  2459.                     $('.uv-filter-edit').html('')
  2460.                     $('.uv-filter-edit').append(this.addEditSavedReplyTemplate(context));
  2461.                     this.$el.find('.uv-filter-options').hide()
  2462.                     this.$el.find('.uv-filter-edit').show()
  2463.                 },
  2464.                 removeSavedFilterOption: function(e) {
  2465.                     e.preventDefault()
  2466.                     var parent = Backbone.$(e.currentTarget).parents('.uv-element-block');
  2467.                     var elementIndex = Backbone.$(e.currentTarget).index();
  2468.                     var filterType = parent.attr('data-filter');
  2469.                     var filterId = Backbone.$(e.currentTarget).attr('data-id');
  2470.                     delete this.tempAppliedFilterOptions[filterType]['options'][elementIndex]
  2471.                     Backbone.$(e.currentTarget).remove()
  2472.                     if(!parent.find('.uv-btn-tag').length) {
  2473.                         parent.remove()
  2474.                         delete this.tempAppliedFilterOptions[filterType];
  2475.                     }
  2476.                     if(this.getSavedFilterRoute() == '') {
  2477.                         this.backToFilter();
  2478.                     }
  2479.                 },
  2480.                 saveSavedFilter: function(e) {
  2481.                     e.preventDefault()
  2482.                     if(Backbone.$(e.currentTarget).hasClass('save-filter'))
  2483.                         this.saveFilterAjax('POST')
  2484.                     else {
  2485.                         this.saveFilterAjax('PUT')
  2486.                     }
  2487.                 },
  2488.                 saveFilterAjax: function(method) {
  2489.                     var inputElement = $('.uv-filter-edit input.name');
  2490.                     inputElement.removeClass('uv-field-error');
  2491.                     $('.uv-field-message').remove()
  2492.                     if(inputElement.val() != undefined && inputElement.val() == '') {
  2493.                         inputElement.addClass('uv-field-error');
  2494.                         inputElement.parent().after("<span class='uv-field-message'>{{ 'This field is mandatory'|trans }}</span>");
  2495.                     } else {
  2496.                         var data = $('.uv-filter-edit form').serializeObject();
  2497.                         data['route'] = this.getSavedFilterRoute();
  2498.                         app.appView.showLoader();
  2499.                         self = this;
  2500.                         $.ajax({
  2501.                             url : "{{ path('helpdesk_member_saved_filters_xhr') }}",
  2502.                             type : method,
  2503.                             data: data,
  2504.                             dataType : 'json',
  2505.                             success : function(response) {
  2506.                                 app.appView.hideLoader();
  2507.                                 userFilters[response.filter.id] = response.filter;
  2508.                                 $("#saved-filter").html("<option value=''>-- {{ 'Saved Filter'|trans }} --</option>")
  2509.                                 _.each(userFilters, function(filter, key) {
  2510.                                     if(response.filter.is_default && filter.id != response.filter.id)
  2511.                                         userFilters[key]['is_default'] = 0;
  2512.                                     var selected = '';
  2513.                                     if(response.filter.id == filter.id)
  2514.                                         selected = "selected";
  2515.                                     $("#saved-filter").append("<option value='" + filter.id + "' selected='" + selected + "''>" + filter.name + "</option>")
  2516.                                 })
  2517.                                 $("#saved-filter").val(response.filter.id)
  2518.                                 app.appView.renderResponseAlert(response);
  2519.                                 self.render();
  2520.                                 self.backToFilter();
  2521.                             },
  2522.                             error: function (xhr) {
  2523.                                 app.appView.hideLoader();
  2524.                                 if(url = xhr.getResponseHeader('Location'))
  2525.                                     window.location = url;
  2526.                             }
  2527.                         });
  2528.                     }
  2529.                 },
  2530.                 getSavedFilterRoute: function() {
  2531.                     var filterParameters = {};
  2532.                     temp = [];
  2533.                     _.each(this.tempAppliedFilterOptions, function (filter, key) {
  2534.                         if(jQuery.inArray(key, ['customer', 'agent', 'priority', 'type', 'group', 'team', 'tag', 'mailbox', 'source', 'after', 'before', 'repliesLess', 'repliesMore']) !== -1) {
  2535.                             var ids = [];
  2536.                             _.each(filter['options'], function (item) {
  2537.                                 ids.push(item.id)
  2538.                             });
  2539.                             filterParameters[key] = ids.join(',')
  2540.                         } else if(jQuery.inArray(key, ['new','unassigned','notreplied','mine','starred','trashed']) !== -1) {
  2541.                             filterParameters[key] = 1;
  2542.                         } else if(jQuery.inArray(key, ['label', 'status', 'search']) !== -1) {
  2543.                             _.each(filter['options'], function (item) {
  2544.                                 filterParameters[key] = item.id;
  2545.                             });
  2546.                         } else {
  2547.                             custom = key.split("z-")
  2548.                             tempKey = custom[1];
  2549.                             if(filter.type == 'text' || filter.type == 'number') {
  2550.                                 _.each(filter['options'], function (item) {
  2551.                                     temp.push(tempKey + '_' + item.name)
  2552.                                 });
  2553.                             } else if(filter.type == 'radio') {
  2554.                                 var ids = [];
  2555.                                 _.each(filter['options'], function (item) {
  2556.                                     ids.push(item.id)
  2557.                                 });
  2558.                                 temp.push(tempKey + '_' + ids.join(','))
  2559.                             } else if(filter.type == 'checkbox' || filter.type == 'select-multiple') {
  2560.                                 var ids = [];
  2561.                                 _.each(filter['options'], function (item) {
  2562.                                     ids.push(item.id)
  2563.                                 });
  2564.                                 temp.push(tempKey + '_' + ids.join(','))
  2565.                             }
  2566.                         }
  2567.                     })
  2568.                     if(temp.length)
  2569.                         filterParameters['custom'] = temp.join('|');
  2570.                     return app.appView.buildQuery($.param(filterParameters));
  2571.                 },
  2572.                 removeSavedFilter: function(e) {
  2573.                     e.preventDefault()
  2574.                     self = this;
  2575.                     app.appView.showLoader();
  2576.                     $.ajax({
  2577.                         url : "{{ path('helpdesk_member_saved_filters_xhr') }}/" + $("#saved-filter").val(),
  2578.                         type : 'DELETE',
  2579.                         dataType : 'json',
  2580.                         success : function(response) {
  2581.                             app.appView.hideLoader();
  2582.                             delete userFilters[$("#saved-filter").val()];
  2583.                             $("#saved-filter").html("<option value=''>-- {{ 'Saved Filter'|trans }} --</option>")
  2584.                             _.each(userFilters, function(filter, key) {
  2585.                                 $("#saved-filter").append("<option value='" + filter.id + "'>" + filter.name + "</option>")
  2586.                             })
  2587.                             $("#saved-filter").val('')
  2588.                             app.appView.renderResponseAlert(response);
  2589.                             self.render();
  2590.                             self.backToFilter();
  2591.                         },
  2592.                         error: function (xhr) {
  2593.                             app.appView.hideLoader();
  2594.                             if(url = xhr.getResponseHeader('Location'))
  2595.                                 window.location = url;
  2596.                         }
  2597.                     });
  2598.                 }
  2599.             });
  2600.             // Ticket Label Item View
  2601.             var LabelItemView = Backbone.View.extend({
  2602.                 tagName: 'li',
  2603.                 className: 'uv-customize-wrapper',
  2604.                 template: _.template($("#custom_label_tmp").html()),
  2605.                 events: {
  2606.                     'click .delete': 'confirmRemove',
  2607.                     'click .label-color.dropdown .fa-caret-down' : 'showUpdateLabelPopup'
  2608.                 },
  2609.                 render: function() {
  2610.                     this.$el.html(this.template(this.model.toJSON()));
  2611.                     if (ticketCollection.filterParameters.label != '') {
  2612.                         if (ticketCollection.filterParameters.label == this.model.id) {
  2613.                             this.$el.find('a').addClass('uv-aside-active');
  2614.                         }
  2615.                     }
  2616.                     return this;
  2617.                 }
  2618.             });
  2619.             // Ticket List Item View
  2620.             var TicketItem = Backbone.View.extend({
  2621.                 tagName: "tr",
  2622.                 template: _.template($("#ticket_list_item_tmp").html()),
  2623.                 events: {
  2624.                     'click .uv-star': "updateStar",
  2625.                 },
  2626.                 render: function () {
  2627.                     this.model.set({
  2628.                         path: pathToTicket.replace('replaceId', this.model.attributes.id + '-' + this.model.attributes.numeracion)
  2629.                     });
  2630.                     if(this.model.attributes.numeracion){
  2631.                         this.model.set('id', this.model.attributes.id + '-' + this.model.attributes.numeracion)
  2632.                     }
  2633.                     this.$el.html(this.template(this.model.toJSON()));
  2634.                     if (this.model.attributes.status.id == 1) {
  2635.                         this.$el.addClass('unread')
  2636.                     }
  2637.                     if (!this.model.attributes.agent) {
  2638.                         this.$el.addClass('not-assigned')
  2639.                     }
  2640.                     return this;
  2641.                 },
  2642.                 updateStar: function(e) {
  2643.                     e.preventDefault();
  2644.                     if (Backbone.$(e.currentTarget).hasClass('uv-star-active')) {
  2645.                         Backbone.$(e.currentTarget).removeClass('uv-star-active');
  2646.                     } else {
  2647.                         Backbone.$(e.currentTarget).addClass('uv-star-active');
  2648.                     }
  2649.                     this.model.save({
  2650.                         id: this.model.id
  2651.                     }, {
  2652.                         patch: true,
  2653.                         url: "{{ path('helpdesk_member_bookmark_ticket_xhr') }}",
  2654.                         success: function (model, response, options) {},
  2655.                         error: function (model, xhr, options) {
  2656.                             if (url = xhr.getResponseHeader('Location')) {
  2657.                                 window.location = url;
  2658.                             }
  2659.                         }
  2660.                     });
  2661.                 }
  2662.             });
  2663.             // Ticket List View
  2664.             var TicketList = Backbone.View.extend({
  2665.                 el: $(".uv-table table"),
  2666.                 initialize: function() {
  2667.                     this.render();
  2668.                 },
  2669.                 events: {
  2670.                     'change .mass-action-checkbox' : 'showBulkOptions',
  2671.                 },
  2672.                 showBulkOptions: function() {
  2673.                     var count = 0;
  2674.                     this.$el.find('.mass-action-checkbox').each(function() {
  2675.                         if ($(this).is(':checked')) {
  2676.                             count++;
  2677.                         }
  2678.                     });
  2679.                     if (count == $('.mass-action-checkbox').length) {
  2680.                         $('.select-all-checkbox').prop('checked', true);
  2681.                     } else {
  2682.                         $('.select-all-checkbox').prop('checked', false);
  2683.                     }
  2684.                     if (count) {
  2685.                         $('.uv-action-bar .filter').parent().hide();
  2686.                         $('.uv-action-bar .mass-action').parent().addClass("uv-width-100").show();
  2687.                         $('.uv-action-bar-col-rt').hide()
  2688.                     } else {
  2689.                         $('.uv-action-bar .mass-action').parent().removeClass("uv-width-100").hide();
  2690.                         $('.uv-action-bar .filter').parent().show();
  2691.                         $('.uv-action-bar-col-rt').show();
  2692.                     }
  2693.                 },
  2694.                 render: function () {
  2695.                     this.$el.find('tbody').html('');
  2696.                     if (ticketCollection.length) {
  2697.                         $('.select-all-checkbox').prop( "disabled", false );
  2698.                         _.each(ticketCollection.models, function (item) {
  2699.                             ticketQuickViewCollection.add(new TicketQuickViewModel({id: item.id}))
  2700.                             this.renderTicket(item);
  2701.                         }, this);
  2702.                     } else {
  2703.                         $('.select-all-checkbox').prop( "disabled", true );
  2704.                         this.$el.find('tbody').append("<tr style='text-align: center;'><td colspan='11'>{% trans %}No Record Found{% endtrans %}</td></tr>")
  2705.                     }
  2706.                     filter.filterAssetsVisibilityOnLoad()
  2707.                     app.appView.relativeTime()
  2708.                 },
  2709.                 renderTicket: function (item) {
  2710.                     var ticketItem = new TicketItem({
  2711.                         model: item
  2712.                     });
  2713.                     this.$el.find('tbody').append(ticketItem.render().el);
  2714.                 }
  2715.             });
  2716.             // Ticket Label List View
  2717.             var LabelListView = Backbone.View.extend({
  2718.                 el: $(".uv-aside"),
  2719.                 template: _.template($("#predefined_label_tmp").html()),
  2720.                 statusTemplate: _.template($("#ticket_status_list_tmp").html()),
  2721.                 addEditLabelTemplate: _.template($("#add_edit_label_tmp").html()),
  2722.                 events: {
  2723.                     'click .status-list li a': "filterByStatus",
  2724.                     'click .add-new-label, .uv-customize': 'addEditLabel',
  2725.                     'click #back-to-labels': 'backToLabels',
  2726.                     'click .uv-color-block': 'setLabelColor',
  2727.                     'click .add-update-btn': 'saveLabel',
  2728.                     'click .uv-add-edit-label .uv-btn-remove': 'removeLabel'
  2729.                 },
  2730.                 render: function() {
  2731.                     var active = "";
  2732.                     if (ticketCollection.filterParameters.new != '') {
  2733.                         active = "new";
  2734.                     } else if (ticketCollection.filterParameters.unassigned != '') {
  2735.                         active = "unassigned";
  2736.                     } else if (ticketCollection.filterParameters.notreplied != '') {
  2737.                         active = "notreplied";
  2738.                     }
  2739.                     if (ticketCollection.filterParameters.mine != '') {
  2740.                         active = "mine";
  2741.                     } else if (ticketCollection.filterParameters.starred != '') {
  2742.                         active = "starred";
  2743.                     } else if (ticketCollection.filterParameters.trashed != '') {
  2744.                         active = "trashed";
  2745.                     } else if (ticketCollection.filterParameters.label != '') {
  2746.                         active = "label";
  2747.                     }
  2748.                     var data = {
  2749.                         'labelDetails' : labelDetails,
  2750.                         'active' : active
  2751.                     }
  2752.                     this.$el.find('.predefined-label-list').html(this.template(data));
  2753.                     labelCollection.reset();
  2754.                     labelCollection.set(labelDetails.custom);
  2755.                     this.updateMassLabelList()
  2756.                 },
  2757.                 updateMassLabelList: function() {
  2758.                     this.$el.find('.uv-aside-custom').html('');
  2759.                     var labelOptionHtml = "";
  2760.                     if(labelCollection.length) {
  2761.                         _.each(labelCollection.models, function (item) {
  2762.                             this.renderLabelItem(item);
  2763.                             labelOptionHtml = labelOptionHtml + "<li data-index='" + item.id + "'><a href='#'>" + item.attributes.name + "</a></li>";
  2764.                         }, this);
  2765.                     }
  2766.                     labelOptionHtml = labelOptionHtml ? labelOptionHtml : "<li data-index='0'>{{ 'No Label Created'|trans }}</li>";
  2767.                     $(".mass-action ul.label").html(labelOptionHtml);
  2768.                     this.renderStatus();
  2769.                 },
  2770.                 renderLabelItem : function (item) {
  2771.                     var labelItem = new LabelItemView({
  2772.                         model: item
  2773.                     });
  2774.                     this.$el.find('.uv-aside-custom').append(labelItem.render().el);
  2775.                 },
  2776.                 renderStatus : function() {
  2777.                     if(typeof ticketCollection.filterParameters.status == "undefined" || ticketCollection.filterParameters.status == null)
  2778.                         var active = 0;
  2779.                     else
  2780.                         var active = ticketCollection.filterParameters.status;
  2781.                     this.$el.find('.uv-aside-active').parent().find('.status-list').remove()
  2782.                     this.$el.find('.uv-aside-active').parent().append(this.statusTemplate({status : statusListDetails, active : active}));
  2783.                 },
  2784.                 filterByStatus : function(e) {
  2785.                     e.preventDefault()
  2786.                     ticketCollection.reset();
  2787.                     ticketCollection.state.order = null;
  2788.                     ticketCollection.state.sortKey = null;
  2789.                     ticketCollection.state.currentPage = null;
  2790.                     ticketCollection.filterParameters.status = Backbone.$(e.currentTarget).attr('data-id');
  2791.                     var queryString = app.appView.buildQuery($.param(ticketCollection.getValidParameters()));
  2792.                     router.navigate(queryString, {trigger: true});
  2793.                 },
  2794.                 addEditLabel: function(e) {
  2795.                     e.preventDefault()
  2796.                     currentElement = Backbone.$(e.currentTarget);
  2797.                     if(currentElement.hasClass('add-new-label'))
  2798.                         $('.uv-add-edit-label').html(this.addEditLabelTemplate({id : 0, name : '', colorCode: ''}))
  2799.                     else
  2800.                         $('.uv-add-edit-label').html(this.addEditLabelTemplate(labelCollection.get(currentElement.siblings('a').attr('data-id')).toJSON()))
  2801.                     $('.uv-aside-default').hide()
  2802.                     $('.uv-add-edit-label').show()
  2803.                 },
  2804.                 backToLabels: function(e) {
  2805.                     if(e)
  2806.                         e.preventDefault()
  2807.                     $('.uv-aside-default').show()
  2808.                     $('.uv-add-edit-label').hide()
  2809.                 },
  2810.                 setLabelColor: function(e) {
  2811.                     $('.uv-color-block').removeClass('uv-color-active');
  2812.                     Backbone.$(e.currentTarget).addClass('uv-color-active');
  2813.                 },
  2814.                 saveLabel : function(e) {
  2815.                     e.preventDefault()
  2816.                     var inputElement = $('.uv-add-edit-label input');
  2817.                     inputElement.removeClass('uv-field-error');
  2818.                     $('.uv-field-message').remove()
  2819.                     var labelName = app.appView.stripHTML(inputElement.val());
  2820.                     if(labelName == "") {
  2821.                         inputElement.addClass('uv-field-error');
  2822.                         inputElement.parent().after("<span class='uv-field-message'>{{ 'This field is mandatory'|trans }}</span>");
  2823.                     } else {
  2824.                         var labelId = parseInt($('.uv-aside-option').attr('data-id'))
  2825.                         model = labelId ? labelCollection.get(labelId) : new LabelModel()
  2826.                         model.set({name: labelName, colorCode: $('.uv-color-block.uv-color-active').attr('data-color')});
  2827.                         self = this;
  2828.                         var flag = labelCollection.isLabelExist(labelName, labelId);
  2829.                         if(flag) {
  2830.                             app.appView.showLoader();
  2831.                             model.save({}, {
  2832.                                 success: function (model, response, options) {
  2833.                                     app.appView.hideLoader();
  2834.                                     if(response.alertClass == "success") {
  2835.                                         if(!labelId) {
  2836.                                             labelCollection.add(model);
  2837.                                         }
  2838.                                         self.updateMassLabelList()
  2839.                                         app.appView.renderResponseAlert(response);
  2840.                                     } else {
  2841.                                         inputElement.addClass('uv-field-error');
  2842.                                         inputElement.parent().after("<span class='uv-field-message'>" + response.alertMessage + "</span>");
  2843.                                     }
  2844.                                     self.backToLabels();
  2845.                                 },
  2846.                                 error: function (model, xhr, options) {
  2847.                                     if(url = xhr.getResponseHeader('Location'))
  2848.                                         window.location = url;
  2849.                                     app.appView.hideLoader();
  2850.                                     app.appView.renderResponseAlert(warningResponse);
  2851.                                 }
  2852.                             });
  2853.                         } else {
  2854.                             inputElement.parent().after("<span class='uv-field-message'>{{ 'Label with same name already exist.'|trans }}</span>");
  2855.                         }
  2856.                     }
  2857.                 },
  2858.                 removeLabel: function(e) {
  2859.                     e.preventDefault()
  2860.                     self = this;
  2861.                     app.appView.showLoader();
  2862.                     model = labelCollection.get($('.uv-aside-option').attr('data-id'))
  2863.                     model.destroy({
  2864.                         success : function (model, response, options) {
  2865.                             app.appView.hideLoader();
  2866.                             self.updateMassLabelList()
  2867.                             app.appView.renderResponseAlert(response);
  2868.                             self.backToLabels();
  2869.                         },
  2870.                         error: function (model, xhr, options) {
  2871.                             if(url = xhr.getResponseHeader('Location'))
  2872.                                 window.location = url;
  2873.                             app.appView.hideLoader();
  2874.                             app.appView.renderResponseAlert(warningResponse);
  2875.                         }
  2876.                     });
  2877.                 }
  2878.             });
  2879.             // Bulk Action View
  2880.             var BulkActionView = Backbone.View.extend({
  2881.                 el: $(".mass-action"),
  2882.                 currentEvent: null,
  2883.                 events: {
  2884.                     'click ul li, #mass-restore': 'massAction',
  2885.                     'click #mass-delete, #mass-delete-forever': 'confirmRemove',
  2886.                     'click #mass-restore': 'confirmRestore'
  2887.                 },
  2888.                 massAction: function(e) {
  2889.                     e.preventDefault();
  2890.                     if(!parseInt(Backbone.$(e.currentTarget).attr('data-index')))
  2891.                         return;
  2892.                     var data = {};
  2893.                     data['actionType'] = Backbone.$(e.currentTarget).parents('ul').attr('data-action') ? Backbone.$(e.currentTarget).parents('ul').attr('data-action') : Backbone.$(e.currentTarget).attr('data-action');
  2894.                     data['targetId'] = Backbone.$(e.currentTarget).attr('data-index');
  2895.                     data['ids'] = this.getCheckedTicketIds();
  2896.                     ticketCollection.batchOperation(data);
  2897.                     this.hideBulkOptions();
  2898.                 },
  2899.                 removeItem: function(e) {
  2900.                     var data = {};
  2901.                     if(Backbone.$(this.currentEvent.currentTarget).is("#mass-delete"))
  2902.                         data['actionType'] = "trashed";
  2903.                     else if(Backbone.$(this.currentEvent.currentTarget).is("#mass-delete-forever"))
  2904.                         data['actionType'] = "delete";
  2905.                     data['ids'] = this.getCheckedTicketIds();
  2906.                     ticketCollection.batchOperation(data);
  2907.                     this.hideBulkOptions();
  2908.                 },
  2909.                 restoreItem: function(e) {
  2910.                     var data = {};
  2911.                     data['actionType'] = "restored";
  2912.                     data['ids'] = this.getCheckedTicketIds();
  2913.                     ticketCollection.batchOperation(data);
  2914.                     this.hideBulkOptions();
  2915.                 },
  2916.                 getCheckedTicketIds: function() {
  2917.                     var ids = new Array();
  2918.                     $('.mass-action-checkbox').each(function() {
  2919.                         if($(this).is(':checked')) {
  2920.                             ids.push($(this).val());
  2921.                         }
  2922.                     });
  2923.                     return ids;
  2924.                 },
  2925.                 confirmRemove: function(e) {
  2926.                     e.preventDefault();
  2927.                     this.currentEvent = e;
  2928.                     app.appView.openConfirmModal(this)
  2929.                 },
  2930.                 confirmRestore: function(e) {
  2931.                     e.preventDefault();
  2932.                     app.appView.openConfirmModal(this, 'restoreItem')
  2933.                 },
  2934.                 hideBulkOptions : function() {
  2935.                     $('.uv-action-bar .mass-action').parent().removeClass("uv-width-100").hide();
  2936.                     $('.uv-action-bar .filter').parent().show();
  2937.                     $('.uv-action-bar-col-rt').show()
  2938.                 }
  2939.             });
  2940.             var PageView = Backbone.View.extend({
  2941.                 el: '.uv-paper',
  2942.                 events : {
  2943.                     'change .select-all-checkbox' : 'selectAll',
  2944.                     'click .uv-quick-view-trigger, .quick-view-navigation .uv-btn-tag': 'navigateQuickView',
  2945.                 },
  2946.                 quickViewTemplate: _.template($("#ticket_quick_view_tmp").html()),
  2947.                 navigateQuickView : function(e) {
  2948.                     e.preventDefault();
  2949.                     //$("#quick-view-modal .uv-loader").hide()
  2950.                     var currentElement = Backbone.$(e.currentTarget);
  2951.                     ticketId = currentElement.attr('data-id');
  2952.                     if(ticketId) {
  2953.                         if(model = ticketQuickViewCollection.isModelSynced(ticketId)) {
  2954.                             this.renderQuickView(model.toJSON())
  2955.                         } else {
  2956.                             var self = this;
  2957.                             if(currentElement.hasClass("uv-quick-view-trigger"))
  2958.                                 app.appView.showLoader();
  2959.                             if(ticketQuickViewCollection.get(ticketId)) {
  2960.                                 navData = ticketQuickViewCollection.getNextPrev(ticketId);
  2961.                                 requiredNext = (!navData.next && app.pager.paginationData.next) ? 1 : 0;
  2962.                                 requiredPrev = (!navData.previous && app.pager.paginationData.previous) ? 1 : 0;
  2963.                             } else
  2964.                                 requiredNext = requiredPrev = 1;
  2965.                             if(self.xhrReq)
  2966.                                 self.xhrReq.abort();
  2967.                             $("#quick-view-modal .uv-loader").show()
  2968.                             self.xhrReq = $.ajax({
  2969.                                 url : "{{ path('helpdesk_member_ticket_quick_view_xhr') }}",
  2970.                                 type : 'GET',
  2971.                                 data : {ticketId : ticketId, next: requiredNext, previous: requiredPrev},
  2972.                                 dataType : 'json',
  2973.                                 success : function(response) {
  2974.                                     self.xhrReq = 0;
  2975.                                     if(currentElement.hasClass("uv-quick-view-trigger"))
  2976.                                         app.appView.hideLoader();
  2977.                                     if(response.next == undefined)
  2978.                                         response.next = navData.next
  2979.                                     if(response.previous == undefined)
  2980.                                         response.previous = navData.previous
  2981.                                     response.isSynced = 1
  2982.                                     response.path = pathToTicket.replace('replaceId', response.incrementId);
  2983.                                     if(ticketQuickViewCollection.get(ticketId))
  2984.                                         ticketQuickViewCollection.set(response,{remove: false})
  2985.                                     else
  2986.                                         ticketQuickViewCollection.add(new TicketQuickViewModel(response))
  2987.                                     self.renderQuickView(response)
  2988.                                 },
  2989.                                 error: function (xhr) {
  2990.                                     self.xhrReq = 0;
  2991.                                     if(url = xhr.getResponseHeader('Location'))
  2992.                                         window.location = url;
  2993.                                     app.appView.hideLoader();
  2994.                                 }
  2995.                             });
  2996.                         }
  2997.                     }
  2998.                 },
  2999.                 renderQuickView: function(response) {
  3000.                     $('#quick-view-modal .uv-pop-up-box').html(this.quickViewTemplate(response));
  3001.                     app.appView.openModal('quick-view-modal')
  3002.                     $('#quick-view-modal .message').find('img').removeAttr('crossorigin');
  3003.                     $('#quick-view-modal .message').find('.uv-icon-ellipsis').remove();
  3004.                     $('#quick-view-modal .message').find('.helpdesk_blockquote').eq(0).before("<span class='uv-icon-ellipsis uv-ellipsis-mirror'></span>").hide();
  3005.                     app.appView.relativeTime();
  3006.                 },
  3007.                 selectAll : function(e) {
  3008.                     if(Backbone.$(e.currentTarget).is(':checked')) {
  3009.                         $('.mass-action-checkbox').prop('checked', true);
  3010.                         $('.uv-action-bar .filter').parent().hide();
  3011.                         $('.uv-action-bar .mass-action').parent().addClass("uv-width-100").show();
  3012.                         $('.uv-action-bar-col-rt').hide()
  3013.                     } else {
  3014.                         var count = 0;
  3015.                         $('.mass-action-checkbox').each(function() {
  3016.                             if($(this).is(':checked'))
  3017.                                 count++;
  3018.                         });
  3019.                         if(count == $('.mass-action-checkbox').length) {
  3020.                             $('.mass-action-checkbox').prop('checked', false);
  3021.                             $('.uv-action-bar .filter').parent().show();
  3022.                             $('.uv-action-bar .mass-action').parent().removeClass("uv-width-100").hide();
  3023.                             $('.uv-action-bar-col-rt').show()
  3024.                         }
  3025.                     }
  3026.                 },
  3027.             });
  3028.             // Ticket Router
  3029.             Router = Backbone.Router.extend({
  3030.                 routes: {
  3031.                     'page/:number(/sort/:sortField)(/direction/:order)' : 'paginate',
  3032.                     'status/:status(/search/:query)(/agent/:agent)(/customer/:customer)(/priority/:priority)(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByStatus',
  3033.                     'search/:query(/agent/:agent)(/customer/:customer)(/priority/:priority)(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByQuery',
  3034.                     'agent/:agent(/customer/:customer)(/priority/:priority)(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByAgent',
  3035.                     'customer/:customer(/priority/:priority)(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByCustomer',
  3036.                     'priority/:priority(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByPriority',
  3037.                     'type/:type(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByType',
  3038.                     'group/:group(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByGroup',
  3039.                     'team/:team(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterBySubGroup',
  3040.                     'tag/:tag(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByTags',
  3041.                     'mailbox/:mailbox(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByMailbox',
  3042.                     'source/:source(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterBySource',
  3043.                     'after/:after(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByAfter',
  3044.                     'before/:before(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByBefore',
  3045.                     'repliesLess/:repliesLess(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByRepliesLesserCount',
  3046.                     'repliesMore/:repliesMore(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByRepliesGreaterCount',
  3047.                     'custom/:custom(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByCustom',
  3048.                     'label/:labelId(/status/:status)(/search/:query)(/agent/:agent)(/customer/:customer)(/priority/:priority)(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterByLabel',
  3049.                     'new(/status/:status)(/search/:query)(/agent/:agent)(/customer/:customer)(/priority/:priority)(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterNew',
  3050.                     'unassigned(/status/:status)(/search/:query)(/agent/:agent)(/customer/:customer)(/priority/:priority)(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterUnassigned',
  3051.                     'notreplied(/status/:status)(/search/:query)(/agent/:agent)(/customer/:customer)(/priority/:priority)(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterNotReplied',
  3052.                     'mine(/status/:status)(/search/:query)(/agent/:agent)(/customer/:customer)(/priority/:priority)(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterMine',
  3053.                     'starred(/status/:status)(/search/:query)(/agent/:agent)(/customer/:customer)(/priority/:priority)(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterstarred',
  3054.                     'trashed(/status/:status)(/search/:query)(/agent/:agent)(/customer/:customer)(/priority/:priority)(/type/:type)(/group/:group)(/team/:team)(/tag/:tag)(/mailbox/:mailbox)(/source/:source)(/after/:after)(/before/:before)(/repliesLess/:repliesLess)(/repliesMore/:repliesMore)(/custom/:custom)(/page/:number)(/sort/:sortField)(/direction/:order)': 'filterTrashed',
  3055.                     '': 'initializeList'
  3056.                 },
  3057.                 initializeList : function() {
  3058.                     $("#saved-filter").val('');
  3059.                     this.resetParams('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '');
  3060.                     this.fetch(null, null, null);
  3061.                 },
  3062.                 paginate : function(number,sortField,order) {
  3063.                     this.resetParams('','','','','','','','','','','','','','','','','','','','','', '');
  3064.                     this.fetch(number,sortField,order);
  3065.                 },
  3066.                 filterByLabel : function(labelId,status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3067.                     this.resetParams(labelId,'','','','','','',status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3068.                     this.fetch(number,sortField,order);
  3069.                 },
  3070.                 filterNew : function(status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3071.                     this.resetParams('',1,'','','','','',status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3072.                     this.fetch(number,sortField,order);
  3073.                 },
  3074.                 filterUnassigned : function(status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3075.                     this.resetParams('','',1,'','','','',status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3076.                     this.fetch(number,sortField,order);
  3077.                 },
  3078.                 filterNotReplied: function(status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3079.                     this.resetParams('','','',1,'','','',status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3080.                     this.fetch(number,sortField,order);
  3081.                 },
  3082.                 filterMine : function(status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3083.                     this.resetParams('','','','',currentUserId,'','',status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3084.                     this.fetch(number,sortField,order);
  3085.                 },
  3086.                 filterstarred : function(status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3087.                     this.resetParams('','','','','',1,'',status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3088.                     this.fetch(number,sortField,order);
  3089.                 },
  3090.                 filterTrashed : function(status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3091.                     this.resetParams('','','','','','',1,status,query,agent,customer,priority,type,group,team,tag,mailbox,source,custom);
  3092.                     this.fetch(number,sortField,order);
  3093.                 },
  3094.                 filterByStatus : function(status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3095.                     this.resetParams('','','','','','','',status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3096.                     this.fetch(number,sortField,order);
  3097.                 },
  3098.                 filterByQuery : function(query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3099.                     this.resetParams('','','','','','','','',query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3100.                     this.fetch(number,sortField,order);
  3101.                 },
  3102.                 filterByAgent : function(agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3103.                     this.resetParams('','','','','','','','','',agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3104.                     this.fetch(number,sortField,order);
  3105.                 },
  3106.                 filterByCustomer : function(customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3107.                     this.resetParams('','','','','','','','','','',customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3108.                     this.fetch(number,sortField,order);
  3109.                 },
  3110.                 filterByPriority : function(priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3111.                     this.resetParams('','','','','','','','','','','',priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3112.                     this.fetch(number,sortField,order);
  3113.                 },
  3114.                 filterByType : function(type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3115.                     this.resetParams('','','','','','','','','','','','',type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3116.                     this.fetch(number,sortField,order);
  3117.                 },
  3118.                 filterByGroup : function(group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3119.                     this.resetParams('','','','','','','','','','','','','',group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3120.                     this.fetch(number,sortField,order);
  3121.                 },
  3122.                 filterBySubGroup : function(team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3123.                     this.resetParams('','','','','','','','','','','','','','',team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3124.                     this.fetch(number,sortField,order);
  3125.                 },
  3126.                 filterByTags : function(tag,mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3127.                     this.resetParams('','','','','','','','','','','','','','','',tag,mailbox,source,after,before,repliesLess,repliesMore,custom);
  3128.                     this.fetch(number,sortField,order);
  3129.                 },
  3130.                 filterByMailbox : function(mailbox,source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3131.                     this.resetParams('','','','','','','','','','','','','','','','',mailbox,source,after,before,repliesLess,repliesMore,custom);
  3132.                     this.fetch(number,sortField,order);
  3133.                 },
  3134.                 filterBySource: function(source,after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3135.                     this.resetParams('','','','','','','','','','','','','','','','','',source,after,before,repliesLess,repliesMore,custom);
  3136.                     this.fetch(number,sortField,order);
  3137.                 },
  3138.                 filterByAfter: function(after,before,repliesLess,repliesMore,custom,number,sortField,order) {
  3139.                     this.resetParams('','','','','','','','','','','','','','','','','','',after,before,repliesLess,repliesMore,custom);
  3140.                     this.fetch(number,sortField,order);
  3141.                 },
  3142.                 filterByBefore: function(before,repliesLess,repliesMore,custom,number,sortField,order) {
  3143.                     this.resetParams('','','','','','','','','','','','','','','','','','','',before,repliesLess,repliesMore,custom);
  3144.                     this.fetch(number,sortField,order);
  3145.                 },
  3146.                 filterByRepliesLesserCount: function(repliesLess, repliesMore, custom, number, sortField, order) {
  3147.                     this.resetParams('','','','','','','','','','','','','','','','','','','','',repliesLess,repliesMore,custom);
  3148.                     this.fetch(number,sortField,order);
  3149.                 },
  3150.                 filterByRepliesGreaterCount: function(repliesMore, custom, number, sortField, order) {
  3151.                     this.resetParams('','','','','','','','','','','','','','','','','','','','','',repliesMore,custom);
  3152.                     this.fetch(number,sortField,order);
  3153.                 },
  3154.                 filterByCustom : function(custom, number, sortField, order) {
  3155.                     this.resetParams('','','','','','','','','','','','','','','','','','','','','','',custom);
  3156.                     this.fetch(number,sortField,order);
  3157.                 },
  3158.                 fetch: function(number, sortField, order) {
  3159.                     ticketCollection.state.currentPage = number;
  3160.                     filter.sortCollection(sortField, order);
  3161.                     ticketCollection.syncData();
  3162.                 },
  3163.                 resetParams : function(labelId,newLabel,unassigned,notreplied,mine,starred,trashed,status,query,agent,customer,priority,type,group,team,tag,mailbox,source,after,before,repliesLess,repliesMore,custom) {
  3164.                     _.each(userFilters, function(filter, index) {
  3165.                         if(Backbone.history.getFragment() == filter['route']) {
  3166.                             $("#saved-filter").val(index);
  3167.                         }
  3168.                     });
  3169.                     isPageJustLoaded = false;
  3170.                     if(query != null)
  3171.                         query = query.replace(/\+/g,' ');
  3172.                     bulkAction.hideBulkOptions();
  3173.                     ticketCollection.filterParameters.label = labelId;
  3174.                     ticketCollection.filterParameters.new = newLabel;
  3175.                     ticketCollection.filterParameters.unassigned = unassigned;
  3176.                     ticketCollection.filterParameters.notreplied = notreplied;
  3177.                     ticketCollection.filterParameters.mine = mine;
  3178.                     ticketCollection.filterParameters.starred = starred;
  3179.                     ticketCollection.filterParameters.trashed = trashed;
  3180.                     ticketCollection.filterParameters.search = query;
  3181.                     $(".uv-search-inline").val(query);
  3182.                     ticketCollection.filterParameters.status = status;
  3183.                     ticketCollection.filterParameters.agent = agent;
  3184.                     ticketCollection.filterParameters.customer = customer;
  3185.                     ticketCollection.filterParameters.priority = priority;
  3186.                     ticketCollection.filterParameters.type = type;
  3187.                     ticketCollection.filterParameters.group = group;
  3188.                     ticketCollection.filterParameters.team = team;
  3189.                     ticketCollection.filterParameters.tag = tag;
  3190.                     ticketCollection.filterParameters.mailbox = mailbox;
  3191.                     ticketCollection.filterParameters.source = source;
  3192.                     ticketCollection.filterParameters.after = after;
  3193.                     ticketCollection.filterParameters.before = before;
  3194.                     ticketCollection.filterParameters.repliesLess = repliesLess;
  3195.                     ticketCollection.filterParameters.repliesMore = repliesMore;
  3196.                     ticketCollection.filterParameters.custom = custom;
  3197.                     $('.custom-fields').find('input[type="text"]').val('');
  3198.                     $('.custom-fields').find('select').val('');
  3199.                     $('.custom-fields').find('input[type="radio"]').prop('checked', false);
  3200.                     $('.custom-fields').find('input[type="checkbox"]').prop('checked', false);
  3201.                     if(custom) {
  3202.                         custom = custom.replace(/\+/g,' ');
  3203.                         var indexValueSeperator = '_';
  3204.                         var columnSeperator = '|';
  3205.                         var multiOptions = custom.split(columnSeperator);
  3206.                         var multiKeyValue, multiKeyValueValue, ele;
  3207.                         _.each(multiOptions, function(valueData, indexData) {
  3208.                             if(!valueData)
  3209.                                 return;
  3210.                             multiKeyValue = valueData.split(indexValueSeperator);
  3211.                             multiKeyValueValue = multiKeyValue[1].split(',');
  3212.                             ele = $('[data-value="' + multiKeyValue[0] + '"]');
  3213.                             if(ele[0].type == 'radio') {
  3214.                                 $('[data-value="' + multiKeyValue[0] + '"][value="' + multiKeyValue[1] + '"]').prop('checked', true);
  3215.                             } else if(ele[0].type == 'checkbox') {
  3216.                                 _.each(ele, function(eleElements) {
  3217.                                     if(multiKeyValueValue.indexOf(eleElements.value) > -1) {
  3218.                                         $(eleElements).prop('checked', true);
  3219.                                     }
  3220.                                 });
  3221.                             } else if(ele[0].type == 'select-multiple') {
  3222.                                 ele.val(multiKeyValueValue);
  3223.                             } else if(ele[0].type == 'text') {
  3224.                                 ele.val(multiKeyValue[1]);
  3225.                             }
  3226.                         })
  3227.                     }
  3228.                     if(trashed) {
  3229.                         $('.property-block').hide();
  3230.                         $('.trashed-block').show();
  3231.                     } else {
  3232.                         $('.property-block').show();
  3233.                         $('.trashed-block').hide();
  3234.                     }
  3235.                     sideFilter.isRecurrsiveCalls = 0;
  3236.                     sideFilter.render();
  3237.                 }
  3238.             });
  3239.             var router = new Router();
  3240.             var pageview = new PageView;
  3241.             var bulkAction = new BulkActionView();
  3242.             var sideFilterModel = new SideFilterModel(filterContext)
  3243.             var sideFilter = new SideFilter();
  3244.             var ticketCollection = new TicketCollection();
  3245.             var ticketQuickViewCollection = new TicketQuickViewCollection();
  3246.             var labelCollection = new LabelCollection();
  3247.             var labelListView = new LabelListView()
  3248.             var filter = new Filter({collection : ticketCollection});
  3249.             Backbone.history.start({
  3250.                 push_state:true
  3251.             });
  3252.         });
  3253.     </script>
  3254.     
  3255.     <script>
  3256.             document.addEventListener("DOMContentLoaded", function() {
  3257.               // Verifica si existe una cookie que indica que el modal debe mantenerse abierto
  3258.               var modalOpenCookie = getCookie("modalOpen");
  3259.               if (modalOpenCookie === "true") {
  3260.                 showTicketModal();
  3261.                 // Elimina la cookie para que el modal no se abra automáticamente en futuras visitas
  3262.                 document.cookie = "modalOpen=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
  3263.               }
  3264.             });
  3265.             function getCookie(name) {
  3266.               var cookieName = name + "=";
  3267.               var cookieArray = document.cookie.split(";");
  3268.               for (var i = 0; i < cookieArray.length; i++) {
  3269.                 var cookie = cookieArray[i].trim();
  3270.                 if (cookie.indexOf(cookieName) === 0) {
  3271.                   return cookie.substring(cookieName.length, cookie.length);
  3272.                 }
  3273.               }
  3274.               return "";
  3275.             }
  3276.             function showTicketModal() {
  3277.               document.cookie = "modalOpen=true";
  3278.               var modal = document.getElementById("ticketModal");
  3279.               modal.style.display = "block";
  3280.             }
  3281.             function closeTicketModal() {
  3282.               document.cookie = "modalOpen=false";
  3283.               var modal = document.getElementById("ticketModal");
  3284.               modal.style.display = "none";
  3285.               history.replaceState({}, document.title, window.location.pathname);
  3286.             }
  3287.     </script>
  3288. <script>
  3289.     // Traducciones para el sistema de alertas
  3290.     const ticketAlertTranslations = {
  3291.         overdueMessage: '{{ "There are overdue tickets!"|trans }}',
  3292.         ticketStatus: '{{ "ticket(s) have been in status"|trans }}',
  3293.         forMoreThan: '{{ "for more than"|trans }}',
  3294.         days: '{{ "days"|trans }}',
  3295.         noTicketsRequireAttention: '{{ "No tickets require attention"|trans }}'
  3296.     };
  3297.     
  3298.     // Sistema de Alertas de Tickets con comparación de fechas
  3299.     class TicketAlertSystem {
  3300.         constructor() {
  3301.             this.currentUserId = "{{ user_service.getCurrentUser().id }}";
  3302.             this.checkInterval = null;
  3303.             this.reminderTimeout = null;
  3304.             this.overdueData = {};
  3305.             this.config = {
  3306.                 interval: 1800000, // valor por defecto 30 min
  3307.                 enabled: true,
  3308.                 days_threshold: 3
  3309.             };
  3310.             this.storageKey = 'ticket_alert_last_shown_' + this.currentUserId;
  3311.             this.init();
  3312.         }
  3313.         
  3314.         async init() {
  3315.             await this.loadConfig();
  3316.             this.startPeriodicCheck();
  3317.             this.setupModalEvents();
  3318.             document.addEventListener('DOMContentLoaded', () => {
  3319.                 setTimeout(() => {
  3320.                     this.checkAlerts();
  3321.                 }, 2000);
  3322.             });
  3323.         }
  3324.         
  3325.         setupModalEvents() {
  3326.             // Prevenir que el modal se cierre al hacer clic en el overlay
  3327.             const modal = document.getElementById('ticketAlertModal');
  3328.             if (modal) {
  3329.                 modal.addEventListener('click', (e) => {
  3330.                     // Si el clic fue en el overlay (no en el modal), prevenir el cierre
  3331.                     if (e.target === modal) {
  3332.                         e.preventDefault();
  3333.                         e.stopPropagation();
  3334.                         return false;
  3335.                     }
  3336.                 });
  3337.                 
  3338.                 // Prevenir que el modal se cierre con la tecla Escape
  3339.                 document.addEventListener('keydown', (e) => {
  3340.                     if (e.key === 'Escape' && modal.style.display === 'block') {
  3341.                         e.preventDefault();
  3342.                         e.stopPropagation();
  3343.                         return false;
  3344.                     }
  3345.                 });
  3346.             }
  3347.         }
  3348.         
  3349.         async loadConfig() {
  3350.             try {
  3351.                 const response = await fetch('{{ path("helpdesk_member_ticket_alert_config_api") }}', {
  3352.                     method: 'GET',
  3353.                     headers: {
  3354.                         'Content-Type': 'application/json',
  3355.                         'X-Requested-With': 'XMLHttpRequest'
  3356.                     }
  3357.                 });
  3358.                 if (response.ok) {
  3359.                     const data = await response.json();
  3360.                     this.config = data;
  3361.                 }
  3362.             } catch (e) {
  3363.                 // Si falla, usa valores por defecto
  3364.             }
  3365.         }
  3366.         
  3367.         startPeriodicCheck() {
  3368.             // Verificar cada 30 segundos si debe mostrar la alerta
  3369.             this.checkInterval = setInterval(() => {
  3370.                 this.checkAlerts();
  3371.             }, 30000); // 30 segundos
  3372.         }
  3373.         
  3374.         shouldShowAlert() {
  3375.             const lastShown = localStorage.getItem(this.storageKey);
  3376.             if (!lastShown) {
  3377.                 return true; // Primera vez, mostrar alerta
  3378.             }
  3379.             
  3380.             // Detectar si es formato antiguo (español) y limpiarlo
  3381.             if (lastShown.includes('/') && lastShown.includes(',')) {
  3382.                 console.log('Formato de fecha antiguo detectado, limpiando localStorage...');
  3383.                 localStorage.removeItem(this.storageKey);
  3384.                 return true; // Mostrar alerta inmediatamente después de limpiar
  3385.             }
  3386.             
  3387.             const lastShownDate = new Date(lastShown);
  3388.             const currentDate = new Date();
  3389.             const timeDiff = currentDate.getTime() - lastShownDate.getTime();
  3390.             
  3391.             console.log('Última alerta mostrada:', lastShown);
  3392.             console.log('Fecha actual:', currentDate.toISOString());
  3393.             console.log('Diferencia de tiempo (ms):', timeDiff);
  3394.             console.log('Intervalo configurado (ms):', this.config.interval);
  3395.             console.log('¿Debe mostrar alerta?:', timeDiff >= this.config.interval);
  3396.             
  3397.             // Si ha pasado más tiempo que el intervalo configurado, mostrar alerta
  3398.             return timeDiff >= this.config.interval;
  3399.         }
  3400.         
  3401.         markAlertAsShown() {
  3402.             const now = new Date();
  3403.             // Usar formato ISO 8601 para máxima compatibilidad
  3404.             const dateString = now.toISOString();
  3405.             localStorage.setItem(this.storageKey, dateString);
  3406.             console.log('Alerta marcada como mostrada:', dateString);
  3407.         }
  3408.         
  3409.         async checkAlerts() {
  3410.             // Solo verificar si debe mostrar la alerta
  3411.             if (!this.shouldShowAlert()) {
  3412.                 return;
  3413.             }
  3414.             
  3415.             try {
  3416.                 const response = await fetch('{{ path("helpdesk_member_ticket_alerts_xhr") }}', {
  3417.                     method: 'GET',
  3418.                     headers: {
  3419.                         'Content-Type': 'application/json',
  3420.                         'X-Requested-With': 'XMLHttpRequest'
  3421.                     }
  3422.                 });
  3423.                 if (response.ok) {
  3424.                     const data = await response.json();
  3425.                     this.overdueData = data.overdue || {};
  3426.                 } else {
  3427.                     console.error('Error fetching ticket alerts:', response.status);
  3428.                     this.overdueData = {};
  3429.                 }
  3430.             } catch (error) {
  3431.                 console.error('Error fetching ticket alerts:', error);
  3432.                 this.overdueData = {};
  3433.             }
  3434.             
  3435.             this.updateIndicators();
  3436.             if (this.hasAlerts()) {
  3437.                 this.showAlert();
  3438.                 this.markAlertAsShown(); // Marcar como mostrada
  3439.             }
  3440.         }
  3441.         
  3442.         hasAlerts() {
  3443.             return Object.keys(this.overdueData).length > 0;
  3444.         }
  3445.         
  3446.         updateIndicators() {
  3447.             const pendingIndicator = document.getElementById('pending-alert-indicator');
  3448.             const resolvedIndicator = document.getElementById('resolved-alert-indicator');
  3449.             if (pendingIndicator) pendingIndicator.style.display = 'none';
  3450.             if (resolvedIndicator) resolvedIndicator.style.display = 'none';
  3451.         }
  3452.         
  3453.         showAlert() {
  3454.             const modal = document.getElementById('ticketAlertModal');
  3455.             const body = document.getElementById('ticketAlertBody');
  3456.             const aside = document.querySelector('.uv-inner-section .uv-aside');
  3457.             if (aside) aside.style.zIndex = '1';
  3458.             if (!modal || !body) return;
  3459.             
  3460.             let html = '';
  3461.             if (this.hasAlerts()) {
  3462.                 html += `<div style="font-size:1.2em;font-weight:bold;margin-bottom:10px;">${ticketAlertTranslations.overdueMessage}</div>`;
  3463.                 html += '<ul style="padding-left:20px;">';
  3464.                 for (const [status, count] of Object.entries(this.overdueData)) {
  3465.                     const ticketText = count > 1 ? 'tickets' : 'ticket';
  3466.                     html += `<li>${count} ${ticketText} ${ticketAlertTranslations.ticketStatus} "${status}" ${ticketAlertTranslations.forMoreThan} ${this.config.days_threshold} ${ticketAlertTranslations.days}.</li>`;
  3467.                 }
  3468.                 html += '</ul>';
  3469.             } else {
  3470.                 html = `<div class="ticket-alert-empty">${ticketAlertTranslations.noTicketsRequireAttention}</div>`;
  3471.             }
  3472.             body.innerHTML = html;
  3473.             modal.style.display = 'block';
  3474.         }
  3475.         
  3476.         setReminder() {
  3477.             this.closeAlert();
  3478.             this.reminderTimeout = setTimeout(() => {
  3479.                 if (this.hasAlerts()) {
  3480.                     this.showAlert();
  3481.                 }
  3482.             }, 60 * 60 * 1000);
  3483.         }
  3484.         
  3485.         closeAlert() {
  3486.             const modal = document.getElementById('ticketAlertModal');
  3487.             const aside = document.querySelector('.uv-inner-section .uv-aside');
  3488.             if (aside) aside.style.zIndex = '4';
  3489.             if (modal) {
  3490.                 modal.style.display = 'none';
  3491.             }
  3492.         }
  3493.         
  3494.         viewAllTickets() {
  3495.             this.closeAlert();
  3496.             router.navigate('mine', {trigger: true});
  3497.         }
  3498.         
  3499.         destroy() {
  3500.             if (this.checkInterval) {
  3501.                 clearInterval(this.checkInterval);
  3502.             }
  3503.             if (this.reminderTimeout) {
  3504.                 clearTimeout(this.reminderTimeout);
  3505.             }
  3506.         }
  3507.     }
  3508.     function closeTicketAlert() {
  3509.         if (window.ticketAlertSystem) {
  3510.             window.ticketAlertSystem.closeAlert();
  3511.         }
  3512.     }
  3513.     function setReminder() {
  3514.         if (window.ticketAlertSystem) {
  3515.             window.ticketAlertSystem.setReminder();
  3516.         }
  3517.     }
  3518.     function viewAllTickets() {
  3519.         if (window.ticketAlertSystem) {
  3520.             window.ticketAlertSystem.viewAllTickets();
  3521.         }
  3522.     }
  3523.     document.addEventListener('DOMContentLoaded', function() {
  3524.         window.ticketAlertSystem = new TicketAlertSystem();
  3525.     });
  3526.     window.addEventListener('beforeunload', function() {
  3527.         if (window.ticketAlertSystem) {
  3528.             window.ticketAlertSystem.destroy();
  3529.         }
  3530.     });
  3531.     
  3532.     // Función para limpiar manualmente el localStorage (útil para debugging)
  3533.     function clearTicketAlertStorage() {
  3534.         const userId = "{{ user_service.getCurrentUser().id }}";
  3535.         const storageKey = 'ticket_alert_last_shown_' + userId;
  3536.         localStorage.removeItem(storageKey);
  3537.         console.log('localStorage limpiado para usuario:', userId);
  3538.     }
  3539.     
  3540.     // Función para verificar el estado del localStorage
  3541.     function checkTicketAlertStorage() {
  3542.         const userId = "{{ user_service.getCurrentUser().id }}";
  3543.         const storageKey = 'ticket_alert_last_shown_' + userId;
  3544.         const lastShown = localStorage.getItem(storageKey);
  3545.         console.log('Estado del localStorage:', {
  3546.             storageKey: storageKey,
  3547.             lastShown: lastShown,
  3548.             hasValue: !!lastShown,
  3549.             isOldFormat: lastShown ? (lastShown.includes('/') && lastShown.includes(',')) : false
  3550.         });
  3551.     }
  3552.     </script>
  3553. {% endblock %}