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

Open in your IDE?
  1. {% extends "@UVDeskCoreFramework//Templates//layout.html.twig" %}
  2. {% block title %}{{ '#' ~ ticket.id ~ ' ' ~ ticket.subject }}{% endblock %}
  3. {% block templateCSS %}
  4.     <style>
  5.         .uv-aside-ticket-labels.label-list-block .uv-btn-label {
  6.             cursor: pointer;
  7.         }
  8.         .uv-main-info-update-block .uv-element-block {
  9.             margin: 10px 0px !important;
  10.         }
  11.         .uv-tab-ellipsis {
  12.             position: relative;
  13.         }
  14.         .uv-inner-section .uv-view .uv-ticket-section .uv-ticket-accordion .uv-ticket-wrapper {
  15.             display: block;
  16.         }
  17.         .uv-element-block.cc-bcc .uv-dropdown-container {
  18.             padding: 10px 20px 10px 20px;
  19.         }
  20.         .uv-action-buttons .uv-dropdown-list ul li {
  21.             padding: 5px 0px !important;
  22.         }
  23.         .uv-action-buttons{
  24.             margin-bottom: 40px !important;
  25.         }
  26.         .uv-ticket-reply .uv-element-block-textarea, .thread-edit-container .uv-element-block-textarea {
  27.             width: 100% !important;
  28.             max-width: 100% !important;
  29.         }
  30.         .thread-edit-container .uv-field-message {
  31.             color: #FF5656 !important;
  32.         }
  33.         .uv-element-block .mce-tinymce {
  34.             margin-top: 10px;
  35.         }
  36.         .uv-ticket-reply .uv-element-block-textarea .uv-field-message, .thread-edit-container .uv-element-block-textarea .uv-field-message {
  37.             margin-top: 15px;
  38.         }
  39.         .thread-edit-container {
  40.             margin-top: 10px;
  41.         }
  42.         .uv-ticket-viewer-bar{
  43.             transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  44.             position: relative;
  45.             overflow: hidden;
  46.             height: 0px;
  47.         }
  48.         .uv-ticket-viewer-bar.active{
  49.             height: 50px;
  50.             margin-bottom: 10px;
  51.             border-bottom: 1px dotted #f97278;
  52.         }
  53.         .uv-ticket-viewer-single {
  54.             display: inline-block;
  55.             margin-right: 5px;
  56.         }
  57.         .uv-ticket-viewer-single img {
  58.             width: 40px;
  59.             border-radius: 3px;
  60.             display: inline-block;
  61.             vertical-align: middle;
  62.         }
  63.         .uv-ticket-viewer-single.uv-first {
  64.             width: 40px;
  65.             height: 40px;
  66.             background-image: linear-gradient(to right, #f97278 0%, #f181bf 100%);
  67.             text-align: center;
  68.             vertical-align: top;
  69.             line-height: 30px;
  70.             border-radius: 20px;
  71.         }
  72.         .uv-ticket-viewer-close {
  73.             position: absolute;
  74.             top: 0px;
  75.             width: 40px;
  76.             height: 40px;
  77.             background: #f1f1f1;
  78.             text-align: center;
  79.             line-height: 35px;
  80.             border-radius: 2px;
  81.             opacity: .6;
  82.             text-indent: 6px;
  83.         }
  84.         .uv-ticket-viewer-list {
  85.             display: inline;
  86.         }
  87.         span.viewer-firstletter.img-thumbnail {
  88.             width: 40px;
  89.             height: 40px;
  90.             display: block;
  91.             text-align: center;
  92.             font-size: 20px;
  93.             font-style: italic;
  94.             border: 1px dotted;
  95.             border-radius: 4px;
  96.             line-height: 35px;
  97.         }
  98.         .uv-ticket-viewer-close {
  99.             display:none;
  100.         }
  101.         .uv-ticket-viewer-single:hover .uv-ticket-viewer-close {
  102.             display: block;
  103.         }
  104.         .uv-hide{
  105.             display: none;
  106.         }
  107.         .uv-info{
  108.             background: #7C70F4;
  109.         }
  110.         .uv-ticket-viewer-list .uv-icon-eye-light{
  111.             animation: jelly 0.8s infinite alternate ease-in-out;
  112.         }
  113.         .uv-aside-brick .uv-loader {
  114.             position: absolute;
  115.             transform: scale(0.5);
  116.             top: 22px;
  117.             right: 45px;
  118.         }
  119.         .uv-app-glyph-customfields {
  120.             width: 20px;
  121.             height: 20px;
  122.             background-position: center center;
  123.             background-repeat: no-repeat;
  124.             cursor: pointer;
  125.             display: inline-block;
  126.             vertical-align: middle;
  127.             margin: 5px 0px 5px 10px;
  128.             background-image: url("{{ asset('bundles/uvdeskcoreframework/images/app-glyph-custom.svg') }}");
  129.         }
  130.         .uv-no-threads {
  131.             padding: 80px 20px;
  132.             text-align: center;
  133.         }
  134.         .uv-ticket-strip-label {
  135.             position: relative;
  136.         }
  137.         input.input-copy-thread-link {
  138.             position: absolute;
  139.             bottom: 10px;
  140.             width: 400px;
  141.         }
  142.         .uv-ticket-action-bar-fixed{
  143.             position: fixed;
  144.             width: 100%;
  145.             background: #fff;
  146.             z-index: 999;
  147.         }
  148.         .uv-ticket-action-bar-fixed .uv-ticket-action-bar-rt{
  149.             position: fixed;
  150.             right: 0px;
  151.             margin-top: 10px;
  152.         }
  153.         .uv-ticket-action-bar-fixed + .uv-ticket-viewer-bar{
  154.             margin-top: 70px;
  155.         }
  156.         .uv-ticket-main {
  157.             word-wrap: break-word;
  158.         }
  159.         @media only screen and (max-width: 900px) {
  160.             .uv-ticket-action-bar-fixed{
  161.                 position: relative;
  162.             }
  163.             .uv-ticket-action-bar-fixed + .uv-ticket-viewer-bar{
  164.                 margin-top: 0px;
  165.             }
  166.             .uv-ticket-action-bar-fixed .uv-ticket-action-bar-rt{
  167.                 position: relative;
  168.             }
  169.         }
  170.         .uv-icon-pin {
  171.             width: 18px;
  172.             height: 18px;
  173.             display: inline-block;
  174.             vertical-align: middle;
  175.             background-image: url("{{ asset('bundles/uvdeskcoreframework/images/uvdesk-sprite.svg') }}");
  176.             background-position: 0px -396px;
  177.             transition: transform .15s;
  178.             transform: scale(1);
  179.         }
  180.         .uv-icon-pinned {
  181.             background-position: -19px -396px;
  182.         }
  183.         .uv-header-fix{
  184.             display: inline-block;
  185.             margin: 0px 10px 0px 5px;
  186.         }
  187.         .uv-header-fix + .uv-tabs{
  188.             display: inline-block;
  189.         }
  190.         .uv-ticket-section span.uv-mail-status {
  191.             width: 16px;
  192.             height: 16px;
  193.             background: url('../../../../../bundles/webkuldefault/images/mail-status.png');
  194.             cursor: help;
  195.         }
  196.         .uv-ticket-section .uv-mail-status.uv-mail-processed {
  197.             background-position: 0 0;
  198.         }
  199.         .uv-ticket-section .uv-mail-status.uv-mail-open,.uv-ticket-section .uv-mail-status.uv-mail-delivered,.uv-ticket-section .uv-mail-status.uv-mail-click {
  200.             background-position: -38px 0;
  201.         }
  202.         .uv-ticket-section .uv-mail-status.uv-mail-spam,.uv-ticket-section .uv-mail-status.uv-mail-deferred,.uv-ticket-section .uv-mail-spamreport {
  203.             background-position: -55px 0;
  204.         }
  205.         .uv-ticket-section .uv-mail-status.uv-mail-bounce,.uv-ticket-section .uv-mail-status.uv-mail-dropped {
  206.             background-position: -73px 0;
  207.         }
  208.         @media only screen and (max-width: 1480px) {
  209.             .uv-inner-section .uv-view .uv-ticket-action-bar-fixed.uv-ticket-action-bar .uv-ticket-action-bar-rt{
  210.                 width: auto;
  211.             }
  212.         }
  213.         @media only screen and (max-width: 1300px) {
  214.             .uv-header-fix{
  215.                 margin: 0px 10px 0px 10px;
  216.             }
  217.         }
  218.         @media only screen and (max-width: 900px) {
  219.             .uv-ticket-action-bar-fixed{
  220.                 position: relative;
  221.             }
  222.             .uv-ticket-action-bar-fixed + .uv-ticket-viewer-bar{
  223.                 margin-top: 0px;
  224.             }
  225.             .uv-ticket-action-bar-fixed .uv-ticket-action-bar-rt{
  226.                 position: relative;
  227.             }
  228.             .uv-inner-section .uv-view .uv-ticket-action-bar.uv-ticket-action-bar-fixed .uv-ticket-action-bar-lt{
  229.                 width: 70%;
  230.             }
  231.             .uv-inner-section .uv-view .uv-ticket-action-bar.uv-ticket-action-bar-fixed .uv-ticket-action-bar-rt {
  232.                 width: 21%;
  233.                 padding-right: 33px;
  234.             }
  235.             .uv-header-fix{
  236.                 display: none;
  237.             }
  238.         }
  239.         .uv-inner-section .uv-view .uv-ticket-scroll-region {
  240.             margin-bottom: 0px;
  241.         }
  242.         .uv-inner-section .uv-view .uv-ticket-action-bar.uv-ticket-action-bar-fixed .uv-ticket-action-bar-rt {
  243.             width: 21%;
  244.             padding-right: 33px;
  245.         }
  246.         @media print {
  247.             .uv-navbar,.uv-ticket-action-bar, .uv-sidebar, .uv-aside>.uv-aside-brick, .uv-aside-back, .uv-ticket-fixed-region, .uv-ticket-main.uv-ticket-reply, .uv-upload-actions, .uv-filter-view, .uv-dropdown-list>.uv-dropdown-container,.uv-notifications-wrapper,.uv-pop-up-overlay,.uv-loader-view, .uv-loader, .uv-navbar,.uv-ticket-count-wrapper {
  248.                 display: none !important;
  249.             }
  250.             .uv-ticket-scroll-region {
  251.                 overflow: visible;
  252.                 margin-bottom: 0 !important;
  253.             }
  254.             .uv-paper {
  255.                 padding-left: 0px !important; /* uv-view */
  256.             }
  257.             .uv-wrapper {
  258.                 left: 0 !important;
  259.                 margin: 0 !important;
  260.             }
  261.             .uv-inner-section .uv-view .uv-ticket-scroll-region  .uv-ticket-main-rt {
  262.                 width: 80%;
  263.             }
  264.             .uv-paper,.uv-view ,.uv-ticket-scroll-region, .uv-wrapper  {
  265.                 position: initial !important;
  266.             }
  267.         }
  268.         .uv-ticket-action-bar-rt .app-glyph {
  269.             display: inline-block;
  270.             vertical-align: middle;
  271.             margin-right: 10px;
  272.             cursor: pointer;
  273.             height: 20px;
  274.             width: 20px;
  275.         }
  276.         .uv-ticket-action-bar-rt .app-glyph:last-child {
  277.             margin-right: 0px;
  278.         }
  279.         blockquote {
  280.             background: #f9f9f9;
  281.             border-left: 4px solid #ccc;
  282.             margin: 1.5em 10px;
  283.             padding: 0.5em 10px;
  284.             quotes: "\201C""\201D""\2018""\2019";
  285.         }
  286.         blockquote:before {
  287.             color: #ccc;
  288.             content: open-quote;
  289.             font-size: 3em;
  290.             line-height: 0.1em;
  291.             margin-right: 0.05em;
  292.             vertical-align: -0.4em;
  293.         }
  294.         blockquote p {
  295.             display: inline;
  296.         }
  297.         .uv-dropdown-list ul li {
  298.             padding : 8px 0px !important;
  299.         }
  300.         ::-webkit-scrollbar {
  301.             width: 6px;
  302.         }
  303.         ::-webkit-scrollbar-track {
  304.             -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
  305.         }
  306.         ::-webkit-scrollbar-thumb {
  307.             -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
  308.         }
  309.         .uv-aside-select.search .uv-dropdown-list.uv-bottom-left, .uv-aside-select .uv-dropdown-list.uv-bottom-right {
  310.             top: 25px;
  311.             width: 100%;
  312.         }
  313.         .uv-aside-select.search .uv-dropdown-list ul{
  314.             padding: 0px 10px;
  315.         }
  316.         .uv-aside-select.search .uv-dropdown-container {
  317.             padding: 8px 10px 4px;
  318.             overflow-y: auto;
  319.             max-height: 280px;
  320.             border-bottom: solid 1px #D3D3D3;
  321.         }
  322.         .uv-aside-select.search .uv-dropdown-list ul.uv-agents-list li {
  323.             border-bottom: solid 1px #D3D3D3;
  324.             border-top:0px;
  325.         }
  326.         .uv-search-inline{
  327.             width: 100%;
  328.         }
  329.         .uv-dropdown-list ul.uv-search-list li:first-child {
  330.             border-top: none;
  331.         }
  332.         .uv-search-sm input.uv-search-field { 
  333.            border: solid 1px #B1B1AE;
  334.            border-radius: 3px;
  335.            color: #333333;
  336.            font-size: 15px;
  337.            box-sizing: border-box;
  338.            padding: 7px 10px 9px 33px;
  339.            width: 100%;
  340.         }
  341.         
  342.     </style>
  343. {% endblock %}
  344. {% block pageContent %}
  345.     <div class="uv-inner-section">
  346.         {# Ticket Sidebar #}
  347.         <div class="uv-aside" {% if app.request.cookies and app.request.cookies.get('uv-asideView') %}style="display: none;"{% endif %} >
  348.             <div class="uv-main-info-block">
  349.                 <div class="uv-aside-head">
  350.                     <div class="uv-aside-title">
  351.                         <h6>{{ 'Ticket'|trans }} #{{ ticket.id }}</h6>
  352.                     </div>
  353.                     <div class="uv-aside-back">
  354.                         <span onclick="history.length > 1 ? history.go(-1) : window.location = '{{ path("helpdesk_member_ticket_collection") }}';">{{ 'Back'|trans }}</span>
  355.                     </div>
  356.                 </div>
  357.                 {# Ticket Information #}
  358.                 <div class="uv-aside-brick">
  359.                     {# Customer Details #}
  360.                     <div class="uv-aside-customer-block">
  361.                         <h3>{{ 'Customer Information'|trans }}</h3>
  362.                         <div class="uv-aside-avatar">
  363.                             {% if customer.thumbnail %}
  364.                                 <img src="{{ app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') }}{{ customer.thumbnail }}">
  365.                             {% else %}
  366.                                 <img src="{{ asset(default_customer_image_path) }}">
  367.                             {% endif %}
  368.                         </div>
  369.                         <div class="uv-aside-customer-info">
  370.                             <span>{{ customer.name }}</span>
  371.                             <span>{{ customer.email }}</span>
  372.                             {% if customer.contactNumber %}
  373.                                 <span>{{ customer.contactNumber }}</span>
  374.                             {% endif %}
  375.                             {% if user_service.isAccessAuthorized('ROLE_AGENT_MANAGE_CUSTOMER') %}
  376.                                 <span class="uv-customize" data-toggle="tooltip" title="Edit Customer Information"></span>
  377.                             {% endif %}
  378.                         </div>
  379.                     </div>
  380.                     {# Ticket Details #}
  381.                     <div class="uv-aside-ticket-block">
  382.                         <div class="uv-aside-ticket-brick">
  383.                             <h3>{{ 'Total Replies'|trans }}</h3>
  384.                             <span class="uv-icon-replies"></span> <span>{{ totalReplies }}</span>
  385.                         </div>
  386.                         <div class="uv-aside-ticket-brick">
  387.                             <h3>{{ 'TimeStamp'|trans }}</h3>
  388.                             <span class="uv-icon-timestamp"></span> <span>{{ ticket_service.timeZoneConverter(initialThread.createdAt) }}</span>
  389.                         </div>
  390.                         <div class="uv-aside-ticket-brick">
  391.                             <h3>{{ 'Channel'|trans }}</h3>
  392.                             {% if ticket.source == 'email' %}
  393.                                 <span class="uv-icon-channel uv-channel-email"></span> <span>{{ 'Email'|trans }}</span>
  394.                             {% elseif ticket.source == 'formbuilder' %}
  395.                                 <span class="uv-icon-channel uv-channel-form"></span> <span>{{ 'Formbuilder'|trans }}</span>
  396.                             {% else %}
  397.                             <span class="uv-icon-channel uv-channel-web"></span> <span>{{ 'Website'|trans }}</span>
  398.                             {% endif %}
  399.                         </div>
  400.                     </div>
  401.                 </div>
  402.             </div>
  403.             {# Edit Customer Info #}
  404.             {% if user_service.isAccessAuthorized('ROLE_AGENT_MANAGE_CUSTOMER') %}
  405.                 <div class="uv-main-info-update-block uv-no-error-success-icon" style="display: none">
  406.                     <div class="uv-aside-head">
  407.                         <div class="uv-aside-title"><h6>{{ 'Edit Customer'|trans }}</h6></div>
  408.                         <div class="uv-aside-back"><span>{{ 'Back'|trans }}</span></div>
  409.                     </div>
  410.                     <div class="uv-aside-brick">
  411.                         <form method="post">
  412.                             <input class="uv-field" name="id" type="hidden" value="{{ customer.id }}">
  413.                             <div class="uv-element-block">
  414.                                 <label class="uv-field-label">{{ 'Name'|trans }}</label>
  415.                                 <div class="uv-field-block">
  416.                                     <input class="uv-field" name="name" type="text" value="{{ customer.name }}">
  417.                                 </div>
  418.                             </div>
  419.                             <div class="uv-element-block">
  420.                                 <label class="uv-field-label">{{ 'Email'|trans }}</label>
  421.                                 <div class="uv-field-block">
  422.                                     <input class="uv-field" name="email" type="text" value="{{ customer.email }}">
  423.                                 </div>
  424.                             </div>
  425.                             <div class="uv-element-block">
  426.                                 <label class="uv-field-label">{{ 'Contact Number'|trans }}</label>
  427.                                 <div class="uv-field-block">
  428.                                     <input class="uv-field" name="contactNumber" type="text" value="{{ customer.contactNumber }}">
  429.                                 </div>
  430.                             </div>
  431.                             <div class="uv-action-buttons">
  432.                                 <a class="uv-btn update-btn" href="#">{{ 'Update'|trans }}</a>
  433.                                 <a class="uv-btn cancel-btn" href="#">{{ 'Cancel'|trans }}</a>
  434.                             </div>
  435.                             <input type="hidden" name="_token" value="{{ csrf_token_generator.refreshToken('') }}"/>
  436.                         </form>
  437.                     </div>
  438.                 </div>
  439.             {% endif %}
  440.             {# Edit Ticket #}
  441.             <div class="uv-aside-brick">
  442.                 <div class="uv-aside-ticket-actions">
  443.                     {# Update Ticket Agent #}
  444.                     <div class="uv-aside-select search">
  445.                         <label class="uv-aside-select-label">{{ 'Agent'|trans }}</label>
  446.                         <div>
  447.                             {% set agentName = ticketAgent ? ticketAgent.name : 'Not Assigned'|trans %}
  448.                             {% if ticket.isTrashed == false and user_service.isAccessAuthorized('ROLE_AGENT_ASSIGN_TICKET') %}
  449.                                 <span class="uv-aside-select-value uv-dropdown-other uv-aside-drop-icon" data-id="{{ ticketAgent ? ticketAgent.id : '' }}">{{ agentName }}</span>
  450.                                 <div class="uv-dropdown-list uv-bottom-left">
  451.                                     <div class="uv-dropdown-container">
  452.                                         <label>{{ 'Agent'|trans }}</label>
  453.                                         <div class="uv-search-sm">
  454.                                             <input type="text" class="uv-search-field uv-search-inline" placeholder="{{ 'Search'|trans }}">
  455.                                         </div>
  456.                                     </div>
  457.                                     <ul class="uv-agents-list agent" data-action="agent">
  458.                                         {% for agent in user_service.getAgentPartialDataCollection() %}
  459.                                             <li data-index="{{ agent.id }}">
  460.                                                 <img src="{{ agent.smallThumbnail != null ? app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') ~ agent.smallThumbnail : asset(default_agent_image_path) }}"/> {{ agent.name }}
  461.                                             </li>
  462.                                         {% endfor %}
  463.                                     </ul>
  464.                                 </div>
  465.                             {% else %}
  466.                                 <span class="uv-aside-select-value">{{ agentName }}</span>
  467.                             {% endif %}
  468.                         </div>
  469.                     </div>
  470.                     {# Update Ticket Priority #}
  471.                     <div class="uv-aside-select">
  472.                         <label class="uv-aside-select-label">{{ 'Priority'|trans }}</label>
  473.                         <div>
  474.                             <span class="uv-list-ticket-priority" style="background: {{ ticket.priority.colorCode }}"></span>
  475.                             {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_PRIORITY') %}
  476.                                 <span class="uv-aside-select-value uv-dropdown-other uv-aside-drop-icon" data-id="{{ ticket.priority.id }}">{{ ticket.priority.description|trans }}</span>
  477.                                 <div class="uv-dropdown-list uv-bottom-left">
  478.                                     <div class="uv-dropdown-container">
  479.                                         <label>{{ 'Priority'|trans }}</label>
  480.                                         <ul class="priority" data-action="priority">
  481.                                             {% for priority in ticketPriorityCollection %}
  482.                                                 <li data-index="{{ priority.id }}" data-color="{{ priority.colorCode }}"><a href="#">{{ priority.description|trans }}</a></li>
  483.                                             {% endfor %}
  484.                                         </ul>
  485.                                     </div>
  486.                                 </div>
  487.                             {% else %}
  488.                                 <span class="uv-aside-select-value">
  489.                                     {{ ticket.priority.description|trans }}
  490.                                 </span>
  491.                             {% endif %}
  492.                         </div>
  493.                     </div>
  494.                     {# Update Ticket Status #}
  495.                     <div class="uv-aside-select">
  496.                         <label class="uv-aside-select-label">{{ 'Status'|trans }}</label>
  497.                         <div>
  498.                             {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}
  499.                                 <span class="uv-aside-select-value uv-dropdown-other uv-aside-drop-icon" data-id="{{ ticket.status.id }}">{{ ticket.status.description|trans }}</span>
  500.                                 <div class="uv-dropdown-list uv-bottom-left">
  501.                                     <div class="uv-dropdown-container">
  502.                                         <label>{{ 'Status'|trans }}</label>
  503.                                         <ul class="status" data-action="status">
  504.                                             {% for status in ticketStatusCollection %}
  505.                                                 <li data-index="{{ status.id }}"><a href="#">{{ status.description|trans }}</a></li>
  506.                                             {% endfor %}
  507.                                         </ul>
  508.                                     </div>
  509.                                 </div>
  510.                             {% else %}
  511.                                 <span class="uv-aside-select-value">{{ ticket.status.description|trans }}</span>
  512.                             {% endif %}
  513.                         </div>
  514.                     </div>
  515.                     {# Update Ticket Type #}
  516.                     <div class="uv-aside-select search">
  517.                         <label class="uv-aside-select-label">{{ 'Type'|trans }}</label>
  518.                         <div>
  519.                             {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_TYPE') %}
  520.                                 <span class="uv-aside-select-value uv-dropdown-other uv-aside-drop-icon" data-id="{{ ticket.type ? ticket.type.id : '-- --' }}">{{ ticket.type ? ticket.type.code : 'Not Assigned'|trans }}</span>
  521.                                 <div class="uv-dropdown-list uv-bottom-left">
  522.                                     <div class="uv-dropdown-container">
  523.                                         <label>{{ 'Type'|trans }}</label>
  524.                                         <div class="uv-search-sm">
  525.                                             <input type="text" class="uv-search-field uv-search-inline" placeholder="{{ 'Search'|trans }}">
  526.                                         </div>
  527.                                     </div>
  528.                                     <ul class="uv-search-list type" data-action="type">
  529.                                         {% for type in ticket_service.getTypes()  %}
  530.                                             <li data-index="{{ type.id }}"><a href="#">{{ type.name }}</a></li>
  531.                                         {% endfor %}
  532.                                     </ul>
  533.                                 </div>
  534.                             {% else %}
  535.                                 <span class="uv-aside-select-value">
  536.                                     {{ ticket.type ? ticket.type.code : 'Not Assigned'|trans }}
  537.                                 </span>
  538.                             {% endif %}
  539.                         </div>
  540.                     </div>
  541.                     {# Update Ticket Support Group #}
  542.                     <div class="uv-aside-select search">
  543.                         <label class="uv-aside-select-label">{{ 'Group'|trans }}</label>
  544.                         <div>
  545.                             {% if user_service.isAccessAuthorized('ROLE_AGENT_ASSIGN_TICKET_GROUP') %}
  546.                                 <span class="uv-aside-select-value uv-dropdown-other uv-aside-drop-icon" data-id="{{ ticket.supportGroup ? ticket.supportGroup.id : '-- --' }}">
  547.                                     {{ ticket.supportGroup ? ticket.supportGroup.name : 'Not Assigned'|trans }}
  548.                                 </span>
  549.                                 <div class="uv-dropdown-list uv-bottom-left">
  550.                                     <div class="uv-dropdown-container">
  551.                                         <label>{{ 'Group'|trans }}</label>
  552.                                         <div class="uv-search-sm">
  553.                                             <input type="text" class="uv-search-field uv-search-inline" placeholder="{{ 'Search'|trans }}">
  554.                                         </div>
  555.                                     </div>
  556.                                     <ul class="uv-search-list group" data-action="group">
  557.                                         <li data-index=""><a href="#">{{ 'Not Assigned'|trans }}</a></li>
  558.                                         {% for group in supportGroupCollection %}
  559.                                             <li data-index="{{ group.id }}"><a href="#">{{ group.name }}</a></li>
  560.                                         {% endfor %}
  561.                                     </ul>
  562.                                 </div>
  563.                             {% else %}
  564.                                 <span class="uv-aside-select-value">
  565.                                     {{ ticket.supportGroup ? ticket.supportGroup.name : 'Not Assigned'|trans }}
  566.                                 </span>
  567.                             {% endif %}
  568.                         </div>
  569.                     </div>
  570.                     {# Update Ticket Support Team #}
  571.                     <div class="uv-aside-select search">
  572.                         <label class="uv-aside-select-label">{{ 'Team'|trans }}</label>
  573.                         <div>
  574.                             {% if user_service.isAccessAuthorized('ROLE_AGENT_ASSIGN_TICKET_GROUP') %}
  575.                                 <span class="uv-aside-select-value uv-dropdown-other uv-aside-drop-icon" data-id="{{ ticket.supportTeam ? ticket.supportTeam.id : '-- --' }}">
  576.                                     {{ ticket.supportTeam ? ticket.supportTeam.name : 'Not Assigned'|trans }}
  577.                                 </span>
  578.                                 <div class="uv-dropdown-list uv-bottom-left">
  579.                                     <div class="uv-dropdown-container">
  580.                                         <label>{{ 'Team'|trans }}</label>
  581.                                         <div class="uv-search-sm">
  582.                                             <input type="text" class="uv-search-field uv-search-inline" placeholder="{{ 'Search'|trans }}">
  583.                                         </div>
  584.                                     </div>
  585.                                     <ul class="uv-search-list team" data-action="team">
  586.                                         <li data-index=""><a href="#">{{ 'Not Assigned'|trans }}</a></li>
  587.                                         {% for team in supportTeamCollection %}
  588.                                             <li data-index="{{ team.id }}"><a href="#">{{ team.name }}</a></li>
  589.                                         {% endfor %}
  590.                                     </ul>
  591.                                 </div>
  592.                             {% else %}
  593.                                 <span class="uv-aside-select-value">
  594.                                     {{ ticket.supportTeam ? ticket.supportTeam.name : 'Not Assigned'|trans }}
  595.                                 </span>
  596.                             {% endif %}
  597.                         </div>
  598.                     </div>
  599.                 </div>
  600.             </div>
  601.             {# Ticket Labels #}
  602.             <div class="uv-aside-brick">
  603.                 <div class="uv-aside-ticket-labels label-list-block">
  604.                     <div class="uv-element-block">
  605.                         <label class="uv-field-label">{{ 'Labels'|trans }}</label>
  606.                         <div class="uv-field-block">
  607.                             <input class="uv-field uv-dropdown-other" type="text" data-type="label">
  608.                             <div class="uv-dropdown-list uv-top-left">
  609.                                 <div class="uv-dropdown-container">
  610.                                     <label>{{ 'Filter With'|trans }}</label>
  611.                                     <ul class="">
  612.                                         <span class="uv-filter-info">{{ 'Type atleast 2 letters'|trans }}</span>
  613.                                         <span class="uv-no-results" style="display: none;">{{ 'No result found'|trans }}</span>
  614.                                     </ul>
  615.                                 </div>
  616.                             </div>
  617.                         </div>
  618.                     </div>
  619.                     <div class="label-list"></div>
  620.                 </div>
  621.             </div>
  622.             {# Ticket Collaborators #}
  623.             <div class="uv-aside-brick collaborator-list-block">
  624.                 <div class="uv-aside-ticket-labels">
  625.                     <div class="uv-element-block">
  626.                         <label class="uv-field-label">{{ 'Collaborators'|trans }}</label>
  627.                         {% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_COLLABORATOR_TO_TICKET') %}
  628.                             <div class="uv-field-block">
  629.                                 <input class="uv-field" type="text" name="email" type="text" value="" placeholder="{{ 'Type email to add'|trans }}">
  630.                             </div>
  631.                         {% endif %}
  632.                     </div>
  633.                     <div class="collaborator-list" style="margin-top: 10px"></div>
  634.                 </div>
  635.             </div>
  636.             {# Ticket Tags #}
  637.             <div class="uv-aside-brick tag-list-block">
  638.                 <div class="uv-aside-ticket-labels">
  639.                     <div class="uv-element-block">
  640.                         <label class="uv-field-label">{{ 'Tags'|trans }}</label>
  641.                         {% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_TAG') %}
  642.                             <div class="uv-field-block">
  643.                                 <input class="uv-field uv-dropdown-other" name="tag-name" type="text" data-type="tag" value="">
  644.                                 <div class="uv-dropdown-list uv-bottom-left">
  645.                                     <div class="uv-dropdown-container">
  646.                                         <label>{{ 'Filter With'|trans }}</label>
  647.                                         <ul class="">
  648.                                             <span class="uv-filter-info">{{ 'Type atleast 2 letters'|trans }}</span>
  649.                                             <span class="uv-no-results" style="display: none;">{{ 'No result found'|trans }}</span>
  650.                                         </ul>
  651.                                     </div>
  652.                                 </div>
  653.                             </div>
  654.                         {% endif %}
  655.                     </div>
  656.                     <div class="tag-list" style="margin-top: 10px"></div>
  657.                 </div>
  658.             </div>
  659.         </div>
  660.         <div class="uv-view {% if app.request.cookies and app.request.cookies.get('uv-asideView') %}uv-aside-view{% endif %}" >
  661.             <div class="uv-ticket-scroll-region {% if app.request.cookies and app.request.cookies.get('uv-asideView') %}uv-aside-view-tv{% endif %}" >
  662.                 {# Ticket Header CTA #}
  663.                 <div class="uv-ticket-action-bar">
  664.                     <div class="uv-ticket-action-bar-lt">
  665.                         <div class="uv-header-fix"><a href="#" class="uv-icon-pin"></a></div>
  666.                         {# Thread Actions #}
  667.                         <div class="uv-tabs">
  668.                             <ul>
  669.                                 {# Filter Threads #}
  670.                                 <li for="default" data-type="all" class="uv-tab-active">{{ 'All Threads'|trans }}</li>
  671.                                 <li for="default" data-type="reply">{{ 'Replies'|trans }}</li>
  672.                                 <li for="default" data-type="forward">{{ 'Forwards'|trans }}</li>
  673.                                 <li for="default" data-type="note">{{ 'Notes'|trans }}</li>
  674.                                 <li for="default" data-type="pinned">{{ 'Pinned'|trans }}</li>
  675.                                 {# Update Threads #}
  676.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_EDIT_TICKET') or user_service.isAccessAuthorized('ROLE_AGENT_DELETE_TICKET') %}
  677.                                     <li class="uv-tab-ellipsis uv-ticket-action">
  678.                                         <span class="uv-icon-ellipsis uv-dropdown-other"></span>
  679.                                         <div class="uv-dropdown-list uv-bottom-right">
  680.                                             <div class="uv-dropdown-container">
  681.                                                 <ul class="priority" data-action="priority">
  682.                                                     {% if user_service.isAccessAuthorized('ROLE_AGENT_EDIT_TICKET') %}
  683.                                                         <li data-action="edit" class="uv-open-popup" data-target="edit-ticket-modal">{{ 'Edit Ticket'|trans }}</li>
  684.                                                     {% endif %}
  685.                                                     <li data-action="print">{{ 'Print Ticket'|trans }}</li>
  686.                                                     {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}
  687.                                                         <li data-action="spam" data-index="6">{{ 'Mark as Spam'|trans }}</li>
  688.                                                         <li data-action="closed" data-index="5">{{ 'Mark as Closed'|trans }}</li>
  689.                                                     {% endif %}
  690.                                                     {% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_TICKET') %}
  691.                                                         <li data-action="delete" class="uv-text-danger">{{ 'Delete Ticket'|trans }}</li>
  692.                                                     {% endif %}
  693.                                                 </ul>
  694.                                             </div>
  695.                                         </div>
  696.                                     </li>
  697.                                 {% endif %}
  698.                             </ul>
  699.                         </div>
  700.                     </div>
  701.                     <div class="uv-ticket-action-bar-rt">
  702.                         {{ uvdesk_extensibles.getRegisteredComponent("Webkul\\UVDesk\\CoreFrameworkBundle\\Tickets\\WidgetCollection").embedSideFilterIcons()|raw }}
  703.                     </div>
  704.                 </div>
  705.                 {# Ticket Active Users #}
  706.                 <div class="uv-ticket-viewer-bar">
  707.                     <div class="uv-ticket-viewer-list">
  708.                         <div class="uv-ticket-viewer-single uv-first" title="Currently active agents on ticket...">
  709.                             <span class="uv-icon-eye-light"></span>
  710.                         </div>
  711.                     </div>
  712.                 </div>
  713.                 {# Ticket Header #}
  714.                 <div class="uv-ticket-head">
  715.                     <div class="uv-ticket-head-lt">
  716.                         <span class="uv-star-large {{ ticket.isStarred ? 'uv-star-active' : '' }} uv-star uv-margin-right-5"></span>
  717.                     </div>
  718.                     <div class="uv-ticket-head-rt">
  719.                         <h1>{{ ticket.subject }}</h1>
  720.                     </div>
  721.                 </div>
  722.                 <div class="uv-ticket-strip">
  723.                     <span>
  724.                         <span class="uv-ticket-strip-label">{{ 'Created'|trans }} - </span>
  725.                         <span class="timeago uv-margin-0" data-timestamp="{{ ticket.createdAt.getTimestamp() }}" title="{{ ticket.createdAt.format('d-m-Y h:ia') }}">{{ ticket_service.timeZoneConverter(initialThread.createdAt) }}</span>
  726.                     </span>
  727.                     <span>
  728.                         <span class="uv-ticket-strip-label">{{ 'By'|trans }} - </span> {{ initialThread.user.name }}
  729.                         {% if totalCustomerTickets %}
  730.                             (<a id="more-tickets-btn" href="{{ path('helpdesk_member_ticket_collection') }}#customer/{{customer.id}}" target="_blank">{{ 'count more tickets'|trans({'count': totalCustomerTickets}) }}</a>)
  731.                         {% endif %}
  732.                     </span>
  733.                     <span class="agent-info" style="{{ ticketAgent ? '' : 'display: none' }}">
  734.                         <span class="uv-ticket-strip-label">{{ 'Agent'|trans }} - </span>
  735.                         <span class="name">{{ ticketAgent ? ticketAgent.name : '' }}</span>
  736.                     </span>
  737.                 </div>
  738.                 {# Thread Tab View #}
  739.                 <div class="uv-tab-view uv-tab-view-active" id="default">
  740.                     <div class="uv-ticket-section">
  741.                         <div class="uv-ticket-main create">
  742.                             <div class="uv-ticket-strip">
  743.                                 <span>
  744.                                     <span class="timeago uv-margin-0" data-timestamp="{{ ticket.createdAt.getTimestamp() }}" title="{{ ticket.createdAt.format('d-m-Y h:ia') }}">{{ ticket_service.timeZoneConverter(ticket.createdAt) }}</span>
  745.                                     - {{ initialThread.user.name }} <span class="uv-ticket-strip-label">{{ 'created Ticket'|trans }}</span>
  746.                                 </span>
  747.                                 {% if initialThread.cc != '' %}
  748.                                     <div class="uv-ticket-strip">
  749.                                         <span><span class="uv-ticket-strip-label">{{ 'CC'|trans }} -</span> {{ initialThread.cc }}</span>
  750.                                     </div>
  751.                                 {% endif %}      
  752.                             </div>
  753.                             <div class="uv-ticket-main-lt">
  754.                                <img src="{{ initialThread.user.thumbnail ? app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') ~ (initialThread.user.thumbnail) : initialThread.createdBy == 'customer' ? asset(default_customer_image_path) : asset(default_agent_image_path) }}">
  755.                             </div>
  756.                             <div class="uv-ticket-main-rt">
  757.                                 {% if initialThread.createdBy == 'customer' %}
  758.                                     <a href="{{ path('helpdesk_member_manage_customer_account') }}/{{ initialThread.user.id}}" class="uv-ticket-member-name">{{ initialThread.user.name }}</a>
  759.                                 {% else %}
  760.                                     {% if initialThread.user %}
  761.                                         <a href="{{ path('helpdesk_member_account') }}/{{ initialThread.user.id}}" class="uv-ticket-member-name">{{ initialThread.user.name }}</a>
  762.                                     {% else %}
  763.                                         <a class="uv-ticket-member-name">{{ initialThread.user.name }}</a>
  764.                                     {% endif %}
  765.                                 {% endif %}
  766.                                 {# Ticket Message #}
  767.                                 <div class="message">
  768.                                     <p>
  769.                                         {% if initialThread.message|striptags == initialThread.message %}
  770.                                             {{ initialThread.message|nl2br }}
  771.                                         {% else %}
  772.                                             {{ initialThread.message|raw }}
  773.                                         {% endif %}
  774.                                     </p>
  775.                                 </div>
  776.                                 {# Ticket Attachments #}
  777.                                 {% if initialThread.attachments|length %}
  778.                                     <div class="uv-ticket-uploads">
  779.                                         <h4>{{ 'Uploaded Files'|trans }}</h4>
  780.                                         <div class="uv-ticket-uploads-strip">
  781.                                             {% for attachment in initialThread.attachments %}
  782.                                                 <a href="{{ attachment.downloadURL }}" target = "_blank" class="uv-ticket-uploads-brick uv-no-pointer-events" data-toggle="tooltip" title="{{ attachment.name }}">
  783.                                                     <img src="{{ attachment.iconURL }}"  class="uv-auto-pointer-events"/>
  784.                                                 </a>
  785.                                             {% endfor %}
  786.                                         </div>
  787.                                         {% if initialThread.attachments|length > 1 %}
  788.                                             <div class="uv-upload-actions">
  789.                                                 <a href="#" class="uv-open-in-files" data-thread="{{ initialThread.id }}" style="display: none"><span class="uv-icon-open-in-files"></span>{{ 'Open in Files'|trans }}</a>
  790.                                                 {% if initialThread.attachments|length %}
  791.                                                     <a href="{{ path('helpdesk_member_ticket_download_attachment_zip') }}/{{ initialThread.id }}" target="_blank"><span class="uv-icon-attachment"></span> Download (as .zip)</a>
  792.                                                 {% endif %}
  793.                                             </div>
  794.                                         {% endif %}
  795.                                     </div>
  796.                                 {% endif %}
  797.                             </div>
  798.                         </div>
  799.                         <div class="uv-ticket-accordion">
  800.                             <div class="uv-ticket-count-wrapper">
  801.                                 <span class="uv-ticket-count-stat">{{ totalReplies }}</span>
  802.                             </div>
  803.                             <div class="uv-ticket-wrapper thread-list"></div>
  804.                         </div>
  805.                     </div>
  806.                 </div>
  807.                 {# Reply Ticket View #}
  808.                 <div class="uv-ticket-main uv-ticket-reply uv-no-error-success-icon">
  809.                     <div class="uv-ticket-main-lt">
  810.                         <span class="uv-icon-ellipsis"></span>
  811.                         <img src="{{ currentUserDetails.thumbnail ? app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') ~ currentUserDetails.thumbnail : asset(default_agent_image_path) }}" />
  812.                     </div>
  813.                     <div class="uv-ticket-main-rt">
  814.                         <span class="uv-ticket-member-name">{{ currentUserDetails.name }}</span>
  815.                         <div class="uv-tabs">
  816.                             <ul>
  817.                                 <li for="reply" class="uv-tab-active">{{ 'Reply'|trans }}</li>
  818.                                 <li for="forward">{{ 'Forward'|trans }}</li>
  819.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_NOTE') %}
  820.                                     <li for='note'>{{ 'Note'|trans }}</li>
  821.                                 {% endif %}
  822.                             </ul>
  823.                         </div>
  824.                         {# Ticket Thread | Add Reply #}
  825.                         <div class="uv-tab-view uv-tab-view-active" id="reply">
  826.                             <form enctype="multipart/form-data" method="post" action="{{ path('helpdesk_member_add_ticket_thread', {'ticketId': ticket.id }) }}">
  827.                                 <input name="threadType" value="reply" type="hidden">
  828.                                 <input name="status" value="" type="hidden" {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}class="reply-status"{% endif %}>
  829.                                 <div class="uv-element-block collaborators" style="display: none">
  830.                                     <label class="uv-field-label">{{ 'Collaborators'|trans }}</label>
  831.                                     <div class="uv-field-block"></div>
  832.                                 </div>
  833.                                 <div class="uv-element-block cc-bcc">
  834.                                     <label>
  835.                                         <div class="uv-checkbox">
  836.                                             <input type="checkbox" class="cc-bcc-toggle">
  837.                                             <span class="uv-checkbox-view"></span>
  838.                                         </div>
  839.                                         <span class="uv-checkbox-label">CC/BCC</span>
  840.                                     </label>
  841.                                     <div class="uv-field-block" style="display: none">
  842.                                         <div class="uv-group">
  843.                                             <input class="uv-group-field uv-dropdown-other preloaded uv-manual-enter" type="text">
  844.                                             <div class="uv-dropdown-list uv-bottom-left">
  845.                                                 <div class="uv-dropdown-container">
  846.                                                     <label>{{ 'Agent'|trans }}</label>
  847.                                                 </div>
  848.                                                 <ul class="uv-agents-list">
  849.                                                     {% for agent in user_service.getAgentPartialDataCollection %}
  850.                                                         <li data-id="{{ agent.email }}">
  851.                                                             <img src="{{ agent.smallThumbnail ? app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') ~ agent.smallThumbnail : asset(default_agent_image_path) }}"/> {{agent.name}}
  852.                                                         </li>
  853.                                                     {% endfor %}
  854.                                                     <li class="uv-no-results" style="display: none;">{{ 'No result found'|trans }}</li>
  855.                                                 </ul>
  856.                                             </div>
  857.                                             <select class="uv-group-select cc-bcc-select">
  858.                                                 <option value="bcc">{{ 'BCC'|trans }}</option>
  859.                                                 <option value="cc">{{ 'CC'|trans }}</option>
  860.                                             </select>
  861.                                         </div>
  862.                                         <div class="cc-bcc-list"></div>
  863.                                     </div>
  864.                                 </div>
  865.                                 <div class="uv-element-block uv-element-block-textarea">
  866.                                     <label class="uv-field-label">{{ 'Write a reply'|trans }}</label>
  867.                                     <div class="uv-field-block">
  868.                                         <textarea class="uv-field" name="reply" id="reply-area">{{ ticket_service.getAgentDraftReply() }}</textarea>
  869.                                     </div>
  870.                                 </div>
  871.                                 <div class="uv-element-block attachment-block">
  872.                                     <label>
  873.                                         <span class="uv-file-label">{{ 'Add Attachment'|trans }}</span>
  874.                                     </label>
  875.                                 </div>
  876.                                 <div class="uv-action-buttons">
  877.                                     <div class="uv-dropdown next-view">
  878.                                         <input type="hidden" name="nextView" value="stay"/>
  879.                                         <div class="uv-dropdown-btn" style="padding: 9px 27px 9px 10px;">{{ 'Stay on ticket'|trans }}</div>
  880.                                         <div class="uv-dropdown-list uv-top-left" style="opacity: 1;">
  881.                                             <div class="uv-dropdown-container">
  882.                                                 <label>{{ 'After Reply'|trans }}</label>
  883.                                                 <ul>
  884.                                                     <li data-value="stay">{{ 'Stay on ticket'|trans }}</li>
  885.                                                     <li data-value="redirect">{{ 'Redirect to list'|trans }}</li>
  886.                                                 </ul>
  887.                                             </div>
  888.                                         </div>
  889.                                     </div>
  890.                                     <div class="uv-dropdown reply">
  891.                                         <div class="uv-btn uv-dropdown-other">{{ 'Reply'|trans }} <span class="uv-icon-down-light"></span></div>
  892.                                         <div class="uv-dropdown-list uv-top-left">
  893.                                             <div class="uv-dropdown-container">
  894.                                                 <label>{{ 'Reply'|trans }}</label>
  895.                                                 <ul>
  896.                                                     <li data-id="">{{ 'Submit'|trans }}</li>
  897.                                                     {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}
  898.                                                         <li data-id="open">{{ 'Submit And Open'|trans }}</li>
  899.                                                         <li data-id="pending">{{ 'Submit And Pending'|trans }}</li>
  900.                                                         <li data-id="answered">{{ 'Submit And Answered'|trans }}</li>
  901.                                                         <li data-id="resolved">{{ 'Submit And Resolved'|trans }}</li>
  902.                                                         <li data-id="closed">{{ 'Submit And Closed'|trans }}</li>
  903.                                                     {% endif %}
  904.                                                 </ul>
  905.                                             </div>
  906.                                         </div>
  907.                                     </div>
  908.                                 </div>
  909.                             </form>
  910.                         </div>
  911.                         {# Ticket Thread | Forward Thread #}
  912.                         <div class="uv-tab-view" id="forward">
  913.                             <form enctype="multipart/form-data" method="post" action="{{ path('helpdesk_member_add_ticket_thread', {'ticketId': ticket.id }) }}">
  914.                                 <input name="threadType" value="forward" type="hidden">
  915.                                 <input name="status" value="" type="hidden" {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}class="reply-status"{% endif %}>
  916.                                 <div class="uv-element-block">
  917.                                     <label class="uv-field-label">{{ 'Subject'|trans }}</label>
  918.                                     <div class="uv-field-block">
  919.                                         <input class="uv-field" type="text" name="subject">
  920.                                     </div>
  921.                                 </div>
  922.                                 <div class="uv-element-block to">
  923.                                     <label class="uv-field-label">{{ 'To'|trans }}</label>
  924.                                     <div class="uv-field-block">
  925.                                         <input class="uv-field uv-dropdown-other preloaded uv-to-message uv-manual-enter" type="text">
  926.                                         <div class="uv-dropdown-list uv-bottom-left">
  927.                                             <div class="uv-dropdown-container">
  928.                                                 <label>{{ 'Agent'|trans }}</label>
  929.                                             </div>
  930.                                             <ul class="uv-agents-list">
  931.                                                 {% for agent in user_service.getAgentPartialDataCollection %}
  932.                                                     <li data-id="{{ agent.email }}">
  933.                                                         <img src="{{ agent.smallThumbnail ? app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') ~ agent.smallThumbnail : asset(default_agent_image_path) }}"/> {{agent.name}}
  934.                                                     </li>
  935.                                                 {% endfor %}
  936.                                                 <li class="uv-no-results" style="display: none;">{{ 'No result found'|trans }}</li>
  937.                                             </ul>
  938.                                         </div>
  939.                                         <div class="to-list"></div>
  940.                                     </div>
  941.                                 </div>
  942.                                 <div class="uv-element-block cc-bcc">
  943.                                     <label>
  944.                                         <div class="uv-checkbox">
  945.                                             <input type="checkbox" class="cc-bcc-toggle">
  946.                                             <span class="uv-checkbox-view"></span>
  947.                                         </div>
  948.                                         <span class="uv-checkbox-label">CC/BCC</span>
  949.                                     </label>
  950.                                     <div class="uv-field-block" style="display: none">
  951.                                         <div class="uv-group">
  952.                                             <input class="uv-group-field uv-dropdown-other preloaded uv-manual-enter" type="text">
  953.                                             <div class="uv-dropdown-list uv-bottom-left">
  954.                                                 <div class="uv-dropdown-container"><label>{{ 'Agent'|trans }}</label></div>
  955.                                                 <ul class="uv-agents-list">
  956.                                                     {% for agent in user_service.getAgentPartialDataCollection %}
  957.                                                         <li data-id="{{ agent.email }}">
  958.                                                             <img src="{{ agent.smallThumbnail ? app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') ~ agent.smallThumbnail : asset(default_agent_image_path) }}"/> {{agent.name}}
  959.                                                         </li>
  960.                                                     {% endfor %}
  961.                                                     <li class="uv-no-results" style="display: none;">{{ 'No result found'|trans }}</li>
  962.                                                 </ul>
  963.                                             </div>
  964.                                             <select class="uv-group-select cc-bcc-select">
  965.                                                 <option value="bcc">{{ 'BCC'|trans }}</option>
  966.                                                 <option value="cc">{{ 'CC'|trans }}</option>
  967.                                             </select>
  968.                                         </div>
  969.                                         <div class="cc-bcc-list"></div>
  970.                                     </div>
  971.                                 </div>
  972.                                 <div class="uv-element-block uv-element-block-textarea">
  973.                                     <label class="uv-field-label">{{ 'Write a reply'|trans }}</label>
  974.                                     <div class="uv-field-block">
  975.                                         <textarea class="uv-field" name="reply" id="forward-area">{{ ticket_service.getAgentDraftReply() }}</textarea>
  976.                                     </div>
  977.                                 </div>
  978.                                 <div class="uv-element-block attachment-block">
  979.                                     <label><span class="uv-file-label">{{ 'Add Attachment'|trans }}</span></label>
  980.                                 </div>
  981.                                 <div class="uv-action-buttons">
  982.                                     <div class="uv-dropdown next-view">
  983.                                         <input type="hidden" name="nextView" value="stay"/>
  984.                                         <div class="uv-dropdown-btn" style="padding: 9px 27px 9px 10px;">{{ 'Stay on ticket'|trans }}</div>
  985.                                         <div class="uv-dropdown-list uv-top-left" style="opacity: 1;">
  986.                                             <div class="uv-dropdown-container">
  987.                                                 <label>{{ 'After Reply'|trans }}</label>
  988.                                                 <ul>
  989.                                                     <li data-value="stay">{{ 'Stay on ticket'|trans }}</li>
  990.                                                     <li data-value="redirect">{{ 'Redirect to list'|trans }}</li>
  991.                                                 </ul>
  992.                                             </div>
  993.                                         </div>
  994.                                     </div>
  995.                                     <div class="uv-btn forward">{{ 'Forward'|trans }}</div>
  996.                                 </div>
  997.                             </form>
  998.                         </div>
  999.                         {# Ticket Thread | Add Note #}
  1000.                         {% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_NOTE') %}
  1001.                             <div class="uv-tab-view" id="note">
  1002.                                 <form enctype="multipart/form-data" method="post" action="{{ path('helpdesk_member_add_ticket_thread', {'ticketId': ticket.id }) }}">
  1003.                                     <input name="threadType" value="note" type="hidden">
  1004.                                     <input name="status" value="" type="hidden" {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}class="reply-status"{% endif %}>
  1005.                                     <div class="uv-element-block uv-element-block-textarea">
  1006.                                         <label class="uv-field-label">{{ 'Write a reply'|trans }}</label>
  1007.                                         <div class="uv-field-block">
  1008.                                             <textarea class="uv-field" name="reply" id="note-area">{{ ticket_service.getAgentDraftReply() }}</textarea>
  1009.                                         </div>
  1010.                                     </div>
  1011.                                     <div class="uv-element-block attachment-block">
  1012.                                         <label><span class="uv-file-label">{{ 'Add Attachment'|trans }}</span></label>
  1013.                                     </div>
  1014.                                     <div class="uv-action-buttons">
  1015.                                         <div class="uv-dropdown next-view">
  1016.                                             <input type="hidden" name="nextView" value="stay"/>
  1017.                                             <div class="uv-dropdown-btn" style="padding: 9px 27px 9px 10px;">{{ 'Stay on ticket'|trans }}</div>
  1018.                                             <div class="uv-dropdown-list uv-top-left" style="opacity: 1;">
  1019.                                                 <div class="uv-dropdown-container">
  1020.                                                     <label>{{ 'After Reply'|trans }}</label>
  1021.                                                     <ul>
  1022.                                                         <li data-value="stay">{{ 'Stay on ticket'|trans }}</li>
  1023.                                                         <li data-value="redirect">{{ 'Redirect to list'|trans }}</li>
  1024.                                                     </ul>
  1025.                                                 </div>
  1026.                                             </div>
  1027.                                         </div>
  1028.                                         <div class="uv-dropdown reply">
  1029.                                             <div class="uv-btn uv-dropdown-other">{{ 'Reply'|trans}}<span class="uv-icon-down-light"></span></div>
  1030.                                             <div class="uv-dropdown-list uv-top-left">
  1031.                                                 <div class="uv-dropdown-container">
  1032.                                                     <label>{{ 'Add Note'|trans }}</label>
  1033.                                                     <ul>
  1034.                                                         <li data-id="">{{ 'Submit'|trans }}</li>
  1035.                                                         {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}
  1036.                                                             <li data-id="open">{{ 'Submit And Open'|trans }}</li>
  1037.                                                             <li data-id="pending">{{ 'Submit And Pending'|trans }}</li>
  1038.                                                             <li data-id="answered">{{ 'Submit And Answered'|trans }}</li>
  1039.                                                             <li data-id="resolved">{{ 'Submit And Resolved'|trans }}</li>
  1040.                                                             <li data-id="closed">{{ 'Submit And Closed'|trans }}</li>
  1041.                                                         {% endif %}
  1042.                                                     </ul>
  1043.                                                 </div>
  1044.                                             </div>
  1045.                                         </div>
  1046.                                     </div>
  1047.                                 </form>
  1048.                             </div>
  1049.                         {% endif %}
  1050.                     </div>
  1051.                 </div>
  1052.             </div>
  1053.             <!-- Bottom Action Block -->
  1054.             <div class="uv-ticket-fixed-region">
  1055.                 <div class="uv-ticket-fixed-region-lt">
  1056.                     {{ uvdesk_extensibles.getRegisteredComponent("Webkul\\UVDesk\\CoreFrameworkBundle\\Tickets\\QuickActionButtonCollection").injectTemplates()|raw }}
  1057.                     {# <!-- Saved Replied-->
  1058.                     <div class="uv-dropdown saved-reply">
  1059.                         <div class="uv-dropdown-btn">{{ 'Saved Replies'|trans }}</div>
  1060.                         <div class="uv-dropdown-list uv-top-left">
  1061.                             <div class="uv-dropdown-container">
  1062.                                 <label>{{ 'Saved Replies'|trans }}</label>
  1063.                                 <ul>
  1064.                                     <li data-id="">
  1065.                                         <a href="{{ path('helpdesk_member_saved_replies') }}" target="_blank" style="color: #2750C4">{{ 'Create New'|trans }}</a>
  1066.                                     </li>
  1067.                                     {% for savedReply in ticket_service.getSavedReplies() %}
  1068.                                         <li data-id="{{ savedReply.id }}">
  1069.                                             {{ savedReply.name }}
  1070.                                         </li>
  1071.                                     {% endfor %}
  1072.                                 </ul>
  1073.                             </div>
  1074.                         </div>
  1075.                     </div>
  1076.                     <!-- //Saved Replied--> #}
  1077.                     {# <!--Code-->
  1078.                     <div class="uv-dropdown">
  1079.                         <div class="uv-dropdown-btn">{{ 'Prepared Responses'|trans }}</div>
  1080.                         <div class="uv-dropdown-list uv-top-left">
  1081.                         <div class="uv-dropdown-container prepared-responses">
  1082.                             <label>{{ 'Prepared Responses'|trans }}</label>
  1083.                             <ul>
  1084.                                 <li>
  1085.                                     <a class="create-new" href="{{path('prepare_response_action')}}" target="_blank" style="color: #2750C4">{{ 'Create New'|trans }}</a>
  1086.                                 </li>
  1087.                                 {% set preparedResponses = ticket_service.getManualWorkflow() %}
  1088.                                 {% for workflow in preparedResponses %}
  1089.                                     <li>
  1090.                                         <a href="{{ path('helpdesk_member_ticket_prepared_response_xhr') }}/{{ ticket.id }}/{{ workflow.id }}">
  1091.                                             {{ workflow.name }}
  1092.                                         </a>
  1093.                                     </li>
  1094.                                 {% endfor %}
  1095.                             </ul>
  1096.                         </div>
  1097.                         </div>
  1098.                     </div>
  1099.                     <!--//Code--> #}
  1100.                 </div>
  1101.                 <div class="uv-ticket-fixed-region-rt"></div>
  1102.             </div>
  1103.             <!-- //Bottom Action Block -->
  1104.         </div>
  1105.     </div>
  1106.     {# Edit Ticket #}
  1107.     {% if user_service.isAccessAuthorized('ROLE_AGENT_EDIT_TICKET') %}
  1108.         <div class="uv-pop-up-overlay uv-no-error-success-icon" id="edit-ticket-modal">
  1109.             <div class="uv-pop-up-box uv-pop-up-wide">
  1110.                 <span class="uv-pop-up-close"></span>
  1111.                 <h2>{{ 'Edit Ticket'|trans }}</h2>
  1112.                 {# Edit Ticket Form #}
  1113.                 <form method="post" action="{{ path('helpdesk_member_update_ticket_details_xhr', {'ticketId': ticket.id}) }}" id="edit-ticket-form">
  1114.                     <div class="uv-element-block">
  1115.                         <label class="uv-field-label">{{ 'Subject'|trans }}</label>
  1116.                         <div class="uv-field-block">
  1117.                             <input type="text" name="subject" class="uv-field" value="{{ ticket.subject }}" />
  1118.                         </div>
  1119.                     </div>
  1120.                     
  1121.                     <div class="uv-element-block">
  1122.                         <label class="uv-field-label">{{ 'Reply'|trans }}</label>
  1123.                         <div class="uv-field-block">
  1124.                             {% if initialThread.message|striptags == initialThread.message %}
  1125.                                 <textarea name="reply" id="uv-edit-create-thread" class="uv-field">{{ initialThread.message|nl2br }}</textarea>
  1126.                             %} {% else %}
  1127.                                 <textarea name="reply" id="uv-edit-create-thread" class="uv-field">{{ initialThread.message|raw }}</textarea>
  1128.                             {% endif %}
  1129.                         </div>
  1130.                     </div>
  1131.                     <div class="uv-pop-up-actions">
  1132.                         <input class="uv-btn update" href="#" value="Update" type="submit">
  1133.                         <input class="uv-btn cancel" href="#" value="Discard" type="button">
  1134.                     </div>
  1135.                 </form>
  1136.             </div>
  1137.         </div>
  1138.     {% endif %}
  1139.     {{ uvdesk_extensibles.getRegisteredComponent("Webkul\\UVDesk\\CoreFrameworkBundle\\Tickets\\WidgetCollection").embedSideFilterContent()|raw }}
  1140. {% endblock %}
  1141. {% block footer %}
  1142.     {{ parent() }}
  1143.     {{ include('@UVDeskCoreFramework\\Templates\\attachment.html.twig') }}
  1144.     {{ include("@UVDeskCoreFramework/Templates/tinyMCE.html.twig") }}
  1145.     <script id="thread_list_empty_tmp" type="text/template">
  1146.         <div class="uv-no-threads">{{ 'Nothing interesting here...'|trans }}</div>
  1147.     </script>
  1148.     <script> 
  1149.         $(document).ready(function() {
  1150.             $("#filterSavedreplies").on("keyup", function() {
  1151.                 if (this.value.length && this.value.length != '') {
  1152.                     var that = this;
  1153.                     $("#listSavedReplies li").hide().filter(function() {
  1154.                         return $(this).html().toLowerCase().indexOf(that.value.toLowerCase()) !== -1;
  1155.                     }).show();
  1156.                 } else {
  1157.                     $("#listSavedReplies li").show()
  1158.                 }
  1159.             });
  1160.             $(".uv-dropdown-btn").click(function(event) {
  1161.                 setTimeout(function() {
  1162.                     $(".uv-search-inline").focus();
  1163.                 }, 100);
  1164.             });
  1165.         });
  1166.     </script>
  1167.     <script id="thread_list_item_tmp" type="text/template">
  1168.         <div class="uv-ticket-strip">
  1169.             <span>
  1170.                 <% if(typeof(mailStatus) != 'undefined' && mailStatus) { %>
  1171.                     <a href="https://support.uvdesk.com/en/blog/uvdesk-ticket-delivery-status" target="_blank">
  1172.                         <span class="uv-mail-status uv-mail-<%- mailStatus.split(',')[0] %>" <% if(mailStatus !== 'pending') { %>data-toggle="tooltip" data-placement="right" title="{{ 'Mail status:'|trans }} <%- mailStatus.split(',')[0] %> <% if(mailStatus.split(',').length > 1) { print('Reason:' + mailStatus.split(',')[1] ); } %> "<% } %> ></span>
  1173.             </a>
  1174.             <% } %>
  1175.             <span class="timeago uv-margin-0" data-timestamp="<%- timestamp %>" title="<%- formatedCreatedAt %>">
  1176.                     <%- formatedCreatedAt %>
  1177.                 </span>
  1178.             - <%- fullname %>
  1179.             <span class="uv-ticket-strip-label">
  1180.                 <% if(threadType == 'reply') { %>
  1181.                     {{ 'replied'|trans }}
  1182.                 <% } else if(threadType == 'note') { %>
  1183.                     {{ 'added note'|trans }}
  1184.                 <% } else if(threadType == 'forward') { %>
  1185.                     {{ 'forwarded'|trans }}
  1186.                 <% } %>
  1187.                 - <a href="#thread/<%- id %>" id="thread<%- id %>" class="copy-thread-link">#<%- id %></a>
  1188.                 </span>
  1189.             </span>
  1190.             <% if((replyTo && threadType ==  'forward') || cc || bcc) { %>
  1191.                 <div class="uv-ticket-strip">
  1192.                     <% if(replyTo && threadType ==  'forward') { %>
  1193.                     <span><span class="uv-ticket-strip-label">{{ 'TO'|trans }} -</span> <%- replyTo %></span>
  1194.                     <% } if(cc) { %>
  1195.                     <span><span class="uv-ticket-strip-label">{{ 'CC'|trans }} -</span> <%- cc %></span>
  1196.                     <% } if(bcc) { %>
  1197.                     <span><span class="uv-ticket-strip-label">{{ 'BCC'|trans }} -</span> <%- bcc %></span>
  1198.                     <% } %>
  1199.                 </div>
  1200.             <% } %>
  1201.         </div>
  1202.         <div class="uv-ticket-strip uv-margin-top-5" <% if(!bookmark && !isLocked) { %>style="display: none"<% } %> >
  1203.             <span <% if(!bookmark) { %>style="display: none"<% } %> >
  1204.                     <span class="uv-icon-pinned"></span>
  1205.                     {{ 'Pinned'|trans }}
  1206.                     </span>
  1207.             <span <% if(!isLocked) { %>style="display: none"<% } %> >
  1208.                 <span class="uv-icon-locked"></span>
  1209.                 {{ 'Locked'|trans }}
  1210.             </span>
  1211.         </div>
  1212.         <div class="uv-ticket-main-lt">
  1213.             <span class="uv-thread-action">
  1214.                 <span class="uv-icon-ellipsis uv-dropdown-other"></span>
  1215.                 <div class="uv-dropdown-list uv-bottom-left">
  1216.                     <div class="uv-dropdown-container">
  1217.                         <ul>
  1218.                             {% if user_service.isAccessAuthorized('ROLE_AGENT_EDIT_THREAD_NOTE') %}
  1219.                                 <% if (userType != 'system' && userType != 'System') { %>
  1220.                                     <li data-action="edit">{{ 'Edit Thread'|trans }}</li>
  1221.                                 <% } %>
  1222.                             {% endif %}
  1223.                             {% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_THREAD_NOTE') %}
  1224.                                 <li data-action="delete">{{ 'Delete Thread'|trans }}</li>
  1225.                             {% endif %}
  1226.                             <li data-action="forward">{{ 'Forward'|trans }}</li>
  1227.                             <% if(bookmark) { %>
  1228.                                 <li data-action="pin" data-id="1">{{ 'Unpin Thread'|trans }}</li>
  1229.                             <% } else { %>
  1230.                                 <li data-action="pin" data-id="0">{{ 'Pin Thread'|trans }}</li>
  1231.                             <% } %>
  1232.                             <% if(threadType != 'note') { %>
  1233.                                 {% if user_service.isAccessAuthorized('ROLE_AGENT_MANAGE_LOCK_AND_UNLOCK_THREAD') %}
  1234.                                     <% if(isLocked) { %>
  1235.                                         <li data-action="lock" data-id="1">{{ 'Unlock Thread'|trans }}</li>
  1236.                                     <% } else { %>
  1237.                                         <li data-action="lock" data-id="0">{{ 'Lock Thread'|trans }}</li>
  1238.                                     <% } %>
  1239.                                 {% endif %}
  1240.                             <% } %>
  1241.                             <li style="display: none;" data-action="translate">{{ 'Translate Thread'|trans }}</li>
  1242.                         </ul>
  1243.                     </div>
  1244.                 </div>
  1245.             </span>
  1246.             <span class="p-relative">
  1247.                 
  1248.             </span>
  1249.             <% if (userType != 'system' && userType != 'System') { %>
  1250.                 <% if(user && user.smallThumbnail != null) { %>
  1251.                     <img src="{{ app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') }}<%- user.smallThumbnail %>" />
  1252.                 <% } else { %>
  1253.                     <img src="<% if(userType == 'agent') { %> {{ asset(default_agent_image_path) }} <% } else { %> {{ asset(default_customer_image_path) }} <% } %>" />
  1254.                 <% } %>
  1255.             <% } else { %>
  1256.                 <img src="{{ asset(default_helpdesk_image_path) }}" />
  1257.             <% } %>
  1258.         </div>
  1259.         <div class="uv-ticket-main-rt">
  1260.             <% if(userType == 'customer') { %>
  1261.                 <a <% if(user) { %>href="{{ path('helpdesk_member_manage_customer_account') }}/<%- user.id %>"<% } %> class="uv-ticket-member-name">
  1262.                 <%- fullname %>
  1263.                 </a>
  1264.             <% } else if(userType == 'agent') { %>
  1265.                 <a <% if(user) { %>href="{{ path('helpdesk_member_account') }}/<%- user.id %>"<% } %> class="uv-ticket-member-name">
  1266.                 <%- fullname %>
  1267.                 </a>
  1268.             <% } else { %>
  1269.                 <span class="uv-ticket-member-name">
  1270.                     <%- fullname %>
  1271.                 </span>
  1272.             <% } %>
  1273.             <!-- Message Block -->
  1274.             <div class="message">
  1275.                 <%= reply %>
  1276.             </div>
  1277.             <!-- Attachment Block -->
  1278.             <% if(attachments.length) { %>
  1279.             <div class="uv-ticket-uploads">
  1280.                 <h4>{{ 'Uploaded Files'|trans }}</h4>
  1281.                 <div class="uv-ticket-uploads-strip">
  1282.                     <% _.each(attachments, function(file) { %>
  1283.                     <a href="<%-file.downloadURL %>" target ="_blank" class="uv-ticket-uploads-brick uv-no-pointer-events" data-toggle="tooltip" title="<%- file.name %>">
  1284.                         <img src="<%-file.iconURL %>" class="uv-auto-pointer-events">
  1285.                     </a>
  1286.                     <% }) %>
  1287.                 </div>
  1288.                 <% if (attachments.length > 1) { %>
  1289.                 <div class="thread-attachments-zip pull-left">
  1290.                     <div class="uv-upload-actions">
  1291.                         <a href="#" class="uv-open-in-files" data-thread="<%- id %>" style="display: none"><span class="uv-icon-open-in-files"></span>{{ 'Open in Files'|trans }}</a>
  1292.                         <% if(attachments.length > 0) { %>
  1293.                         <a href="{{ path('helpdesk_member_ticket_download_attachment_zip') }}/<%- id %>" target="_blank"><span class="uv-icon-attachment"></span> {{ 'Download (as .zip)'|trans }}</a>
  1294.                         <% } %>
  1295.                     </div>
  1296.                 </div>
  1297.                 <% } %>
  1298.             </div>
  1299.             <% } %>
  1300.         </div>
  1301.     </script>
  1302.     <script id="edit_thread_tmp" type="text/template">
  1303.         <div class="thread-edit-container">
  1304.             <div class="uv-element-block uv-element-block-textarea">
  1305.                 <div class="uv-field-block">
  1306.                     <textarea id="uv-edit-thread">
  1307.                     </textarea>
  1308.                 </div>
  1309.             </div>
  1310.             <div class="uv-action-buttons">
  1311.                 <a class="uv-btn cancel-edit" type="button">{{ 'Cancel'|trans }}</a>
  1312.                 <a class="uv-btn saveThread" type="button" style="margin-right: 10px;">{{ 'Update'|trans }}</a>
  1313.             </div>
  1314.         </div>
  1315.     </script>
  1316.     <script id="ticket_quick_navigation_tmp" type="text/template">
  1317.         <% if(prev) { %>
  1318.             <a class="uv-btn-stroke" href="{{ path('helpdesk_member_ticket') }}/<%- prev %>">
  1319.                 <span class="uv-icon-previous"></span>
  1320.                 {{ 'Previous Ticket'|trans }}
  1321.             </a>
  1322.         <% } else { %>
  1323.             <a class="uv-btn-stroke" disabled="disabled">
  1324.                 <span class="uv-icon-previous"></span>
  1325.                 {{ 'Previous Ticket'|trans }}
  1326.             </a>
  1327.         <% } %>
  1328.         <% if(next) { %>
  1329.             <a class="uv-btn-stroke" href="{{ path('helpdesk_member_ticket') }}/<%- next %>">
  1330.                 {{ 'Next Ticket'|trans }}
  1331.                 <span class="uv-icon-next"></span>
  1332.             </a>
  1333.         <% } else { %>
  1334.             <a class="uv-btn-stroke" disabled="disabled">
  1335.                 {{ 'Next Ticket'|trans }}
  1336.                 <span class="uv-icon-next"></span>
  1337.             </a>
  1338.         <% } %>
  1339.     </script>
  1340.     <script type="text/javascript">
  1341.         uvdesk = {
  1342.             ticket: {}
  1343.         };
  1344.         var ticketApp = {};
  1345.         viewerImages = function() {
  1346.             if (typeof($().viewer == 'function')) {
  1347.                 $('.uv-ticket-uploads .uv-ticket-uploads-strip').viewer({
  1348.                     'url': 'data-url',
  1349.                     'downloadBase': "{{ path('helpdesk_member_ticket_download_attachment') }}",
  1350.                     'download': 'data-download',
  1351.                 });
  1352.             }
  1353.         };
  1354.         $(function () {
  1355.             var threadIds = [];
  1356.             viewerImages();
  1357.             _.extend(Backbone.Model.prototype, Backbone.Validation.mixin);
  1358.             // Ticket Model
  1359.             var TicketModel = Backbone.Model.extend({
  1360.                 idAttribute : "id",
  1361.                 urlRoot : "{{ path('helpdesk_member_update_ticket_attributes_xhr') }}",
  1362.                 validation: {
  1363.                     'email': [{
  1364.                         required: true,
  1365.                         msg: '{{ "This field is mandatory" | trans}}'
  1366.                     },{
  1367.                         pattern: /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
  1368.                         msg: 'Please enter a valid email'
  1369.                     }],
  1370.                     'subject' : {
  1371.                         required : true,
  1372.                         msg : '{{ "This field is mandatory" | trans}}'
  1373.                     },
  1374.                     'reply' : {
  1375.                         fn: function(value) {
  1376.                             if(!tinyMCE.get("uv-edit-create-thread"))
  1377.                                 return false;
  1378.                             var html = tinyMCE.get("uv-edit-create-thread").getContent();
  1379.                             if(app.appView.stripHTML(html) != '') {
  1380.                                 return false;
  1381.                             }
  1382.                             return true;
  1383.                         },
  1384.                         msg : '{{ "This field is mandatory" | trans}}'
  1385.                     }
  1386.                 },
  1387.             });
  1388.             // Thread Model
  1389.             var ThreadModel = Backbone.Model.extend({
  1390.                 idAttribute : "id",
  1391.                 defaults : {
  1392.                     hasTask : 0,
  1393.                     task: null
  1394.                 }
  1395.             });
  1396.             // Customer Model
  1397.             var CustomerModel = Backbone.Model.extend({
  1398.                 validation: {
  1399.                     'name': [{
  1400.                         required: true,
  1401.                         msg: '{{ "This field is mandatory" }}'
  1402.                     }, {
  1403.                         pattern: /^((?![!@#$%^&*()<_+]).)*$/,
  1404.                         msg: '{{ "This field must have characters only"}}'
  1405.                     }],
  1406.                     'email': [{
  1407.                         required: true,
  1408.                         msg: '{{ "This field is mandatory" | trans}}'
  1409.                     },{
  1410.                         pattern: /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
  1411.                         msg: '{{ "Email address is invalid" | trans}}'
  1412.                     }],
  1413.                     'contactNumber': function(value) {
  1414.                         if(value != undefined && value !== '') {
  1415.                             if (!value.match('^\\s*(?:\\+?(\\d{1,3}))?[-. (]*(\\d{3})[-. )]*(\\d{3})[-. ]*(\\d{4})(?: *x(\\d+))?\\s*$'))
  1416.                                 return 'Contact number is invalid';
  1417.                         }
  1418.                     }
  1419.                 },
  1420.                 urlRoot : "{{ path('helpdesk_member_manage_customer_account') }}"
  1421.             });
  1422.             // Ticket Collaborator Model
  1423.             var CollaboratorModel = Backbone.Model.extend({
  1424.                 idAttribute : "id",
  1425.                 validation: {
  1426.                     'email': [{
  1427.                         required: true,
  1428.                         msg: '{{ "This field is mandatory" | trans}}'
  1429.                     },{
  1430.                         pattern: /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
  1431.                         msg: '{{ "Please enter a valid email" | trans}}'
  1432.                     }]
  1433.                 },
  1434.                 defaults : {
  1435.                     ticketId : {{ ticket.id }},
  1436.                     email: ''
  1437.                 },
  1438.                 parse: function (resp, options) {
  1439.                     return resp.collaborator;
  1440.                 },
  1441.                 urlRoot : "{{ path('helpdesk_member_ticket_manage_collaborators_xhr') }}"
  1442.             });
  1443.             // Ticket Tag Model
  1444.             var TagModel = Backbone.Model.extend({
  1445.                 idAttribute : "id",
  1446.                 defaults : {
  1447.                     ticketId : {{ ticket.id }}
  1448.                 },
  1449.                 parse: function (resp, options) {
  1450.                     return resp.tag;
  1451.                 },
  1452.                 urlRoot : "{{ path('helpdesk_member_ticket_create_tag_xhr') }}"
  1453.             });
  1454.             // Ticket Label Model
  1455.             var LabelModel = Backbone.Model.extend({
  1456.                 idAttribute : "id",
  1457.                 defaults : {
  1458.                     ticketId : {{ ticket.id }}
  1459.                 },
  1460.                 parse: function (resp, options) {
  1461.                     return resp.label;
  1462.                 },
  1463.                 urlRoot : "{{ path('helpdesk_member_ticket_add_label_xhr') }}"
  1464.             });
  1465.             // Ticket Thread Collection
  1466.             var ThreadCollection = AppCollection.extend({
  1467.                 model : ThreadModel,
  1468.                 mode: "infinite",
  1469.                 url : "{{ path('helpdesk_member_thread_collection_xhr', {'ticketId': ticket.id}) }}",
  1470.                 firstScrollCheck: false,
  1471.                 threadRequestedId: false,
  1472.                 template : $("#thread_list_empty_tmp").html(),
  1473.                 parseRecords: function (resp, options) {
  1474.                     return resp.threads;
  1475.                 },
  1476.                 syncData : function() {
  1477.                     type = $(".uv-ticket-action-bar-lt .uv-tabs .uv-tab-active").attr('data-type')
  1478.                     var self = this;
  1479.                     var data = {
  1480.                         threadType: type
  1481.                     };
  1482.                     if(this.threadRequestedId)
  1483.                         data.threadRequestedId = this.threadRequestedId;
  1484.                     app.appView.showLoader()
  1485.                     this.fetch({
  1486.                         data : data,
  1487.                         remove: false,
  1488.                         success: function(model, response) {
  1489.                             app.appView.hideLoader();
  1490.                             self.threadRequestedId = false;
  1491.                             pagination.renderPagination(response.pagination);
  1492.                             threadCollection.state.currentPage = parseInt(response.pagination.current) + 1;
  1493.                             if(response.pagination.totalCount <= 0){
  1494.                                 this.$('.uv-ticket-wrapper.thread-list').html(self.template);
  1495.                             }
  1496.                         },
  1497.                         error: function (model, xhr, options) {
  1498.                             if(url = xhr.getResponseHeader('Location'))
  1499.                                 window.location = url;
  1500.                         }
  1501.                     }).done(function(){
  1502.                         viewerImages();
  1503.                         if(!self.firstScrollCheck){
  1504.                             self.firstScrollCheck = true;
  1505.                             var fragment = Backbone.history.fragment.trim();
  1506.                             if(fragment == '') {
  1507.                                 router.scrollPage('#reply');
  1508.                             } else
  1509.                                 router.scrollPage('#' + fragment.replace('thread/', 'thread'));
  1510.                         }
  1511.                     });
  1512.                 }
  1513.             });
  1514.             // Ticket Collaborator Collection
  1515.             var CollaboratorCollection = Backbone.PageableCollection.extend({
  1516.                 model : CollaboratorModel
  1517.             });
  1518.             // Ticket Tag Collection
  1519.             var TagCollection = Backbone.PageableCollection.extend({
  1520.                 model : TagModel,
  1521.                 isTagExist : function(name) {
  1522.                     var flag = 1;
  1523.                     _.each(tagCollection.models, function (item) {
  1524.                         if(item.get('name').toUpperCase() == name.toUpperCase())
  1525.                             flag = 0;
  1526.                     }, this);
  1527.                     return flag;
  1528.                 }
  1529.             });
  1530.             // Ticket Label Collection
  1531.             var LabelCollection = Backbone.PageableCollection.extend({
  1532.                 model : TagModel,
  1533.                 isLabelExist : function(name) {
  1534.                     var flag = 1;
  1535.                     _.each(labelCollection.models, function (item) {
  1536.                         if(item.get('name').toUpperCase() == name.toUpperCase())
  1537.                             flag = 0;
  1538.                     }, this);
  1539.                     return flag;
  1540.                 }
  1541.             });
  1542.             // Customer Form View
  1543.             var CustomerForm = Backbone.View.extend({
  1544.                 events : {
  1545.                     'click .uv-btn.update-btn' : "saveCustomer",
  1546.                     'blur input': 'formChanegd',
  1547.                     'click .cancel-btn': 'backToInfo',
  1548.                     'click .uv-aside-back': 'backToInfo'
  1549.                 },
  1550.                 initialize : function() {
  1551.                     Backbone.Validation.bind(this);
  1552.                 },
  1553.                 formChanegd: function(e) {
  1554.                     this.model.set(Backbone.$(e.currentTarget).attr('name'), Backbone.$(e.currentTarget).val())
  1555.                     this.model.isValid([Backbone.$(e.currentTarget).attr('name')])
  1556.                 },
  1557.                 saveCustomer: function (e) {
  1558.                     e.preventDefault();
  1559.                     currentElement = Backbone.$(e.currentTarget);
  1560.                     this.model.clear();
  1561.                     this.model.set(this.$el.find('form').serializeObject());
  1562.                     self = this;
  1563.                     if(this.model.isValid(true)) {
  1564.                         app.appView.showLoader();
  1565.                         currentElement.attr('disabled', 'disabled');
  1566.                         this.model.save({}, {
  1567.                             success: function (model, response, options) {
  1568.                                 app.appView.hideLoader();
  1569.                                 currentElement.removeAttr("disabled");
  1570.                                 if(response.alertClass == "success") {
  1571.                                     app.appView.renderResponseAlert(response);
  1572.                                     $('.uv-aside-customer-info').html("<span>" + self.model.attributes.name + "</span><span>" + self.model.attributes.email + "</span><span>" + self.model.attributes.contactNumber + "</span><span class='uv-customize'></span>")
  1573.                                     self.backToInfo();
  1574.                                 } else if(response.errors) {
  1575.                                     self.addErrors(JSON.parse(response.errors));
  1576.                                 } else if(response.alertMessage) {
  1577.                                     app.appView.renderResponseAlert(response);
  1578.                                 }
  1579.                             },
  1580.                             error: function (model, xhr, options) {
  1581.                                 if(url = xhr.getResponseHeader('Location'))
  1582.                                     window.location = url;
  1583.                                 app.appView.hideLoader();
  1584.                                 app.appView.renderResponseAlert(warningResponse);
  1585.                             }
  1586.                         });
  1587.                     }
  1588.                 },
  1589.                 addErrors: function(jsonContext) {
  1590.                     for (var field in jsonContext) {
  1591.                         Backbone.Validation.callbacks.invalid(this, field, jsonContext[field], 'input');
  1592.                     }
  1593.                 },
  1594.                 backToInfo: function(e) {
  1595.                     if(e)
  1596.                         e.preventDefault()
  1597.                     $('.uv-main-info-update-block').hide()
  1598.                     $('.uv-main-info-block').show()
  1599.                 },
  1600.             });
  1601.             // Ticket View
  1602.             var TicketView = Backbone.View.extend({
  1603.                 el: $('.uv-wrapper'),
  1604.                 stopDraftSaveFlag: 0,
  1605.                 events: {
  1606.                     'click .uv-ticket-action .uv-dropdown-list li[data-action="spam"], .uv-ticket-action .uv-dropdown-list li[data-action="closed"]': 'masrkSpamAndClosed',
  1607.                     'click .uv-aside-ticket-actions .uv-aside-select .uv-dropdown-list li': 'editTicketProperty',
  1608.                     'click .uv-aside-customer-info .uv-customize': 'showCustomerUpdateBlock',
  1609.                     'click .uv-ticket-head .uv-star-large': 'updateStar',
  1610.                     'click .uv-ticket-action-bar .uv-tabs li': 'filterThread',
  1611.                     'click .uv-ticket-action .uv-dropdown-list li[data-action="delete"]': 'confirmRemove',
  1612.                     'click .uv-ticket-action .uv-dropdown-list li[data-action="lock"]': 'lockAndUnlockThread',
  1613.                     'click .uv-element-block.collaborators .uv-btn-tag': 'removeCcCollaborator',
  1614.                     'keypress .uv-element-block.to .uv-dropdown-other': 'addToInput',
  1615.                     'click .uv-element-block.to .uv-dropdown-list li': 'addTo',
  1616.                     'click .to-list .uv-btn-tag': 'removeTo',
  1617.                     'change .uv-element-block.cc-bcc .cc-bcc-toggle': 'showCcBccBlock',
  1618.                     'keypress .uv-element-block.cc-bcc .uv-group-field.uv-dropdown-other': 'addCcBccInput',
  1619.                     'click .uv-element-block.cc-bcc .uv-dropdown-list li': 'addCcBcc',
  1620.                     'click .cc-bcc-list .uv-btn-tag, .to-list .uv-btn-tag': 'removeEmail',
  1621.                     'click .next-view .uv-dropdown-list li': 'setNextView',
  1622.                     'click .uv-dropdown.reply .uv-dropdown-list li, .uv-btn.forward': 'validateForm',
  1623.                     'click #edit-ticket-modal .uv-btn.update': 'updateTicket',
  1624.                     'click .message .uv-icon-ellipsis': 'showReplyQuote',
  1625.                     'input .uv-aside-brick .uv-field.uv-dropdown-other': 'searchFilterXhr',
  1626.                     'click .uv-dropdown-container.prepared-responses a:not(.create-new)': 'confirmPreparedResponses',
  1627.                     'click .uv-header-fix': 'fixheader',
  1628.                     'click .uv-ticket-action .uv-dropdown-list li[data-action="print"]': 'printTicket',
  1629.                     'blur .uv-manual-enter': 'enterManualAdd',
  1630.                 },
  1631.                 ticketNavigationTemplate : _.template($("#ticket_quick_navigation_tmp").html()),
  1632.                 loaderTemplate : _.template($("#loader-tmp").html()),
  1633.                 targetPreparedResponseUrl: '',
  1634.                 initialize: function() {
  1635.                     Backbone.Validation.bind(this);
  1636.                     InitTinyMce('#uv-edit-create-thread');
  1637.                     $('.uv-ticket-fixed-region .uv-ticket-fixed-region-rt').html(this.ticketNavigationTemplate(ticketNavigation))
  1638.                     var threadTab = localStorage.getItem("threadTab");
  1639.                     if(threadTab){
  1640.                         $('.uv-ticket-action-bar-lt .uv-tabs li').removeClass('uv-tab-active');
  1641.                         $('.uv-ticket-action-bar-lt .uv-tabs [data-type="' + threadTab + '"]').addClass('uv-tab-active');
  1642.                     }
  1643.                     nextView = localStorage.getItem("nextView");
  1644.                     if(nextView) {
  1645.                         $(".next-view input").val(nextView)
  1646.                         $(".next-view .uv-dropdown-btn").text($("#reply .next-view .uv-dropdown-list li[data-value='" + nextView + "']").text())
  1647.                     }
  1648.                     if(!localStorage.getItem('ticketTour')) {
  1649.                         $('.uv-ticket-tour').show()
  1650.                     }
  1651.                     this.fixheaderInit();
  1652.                 },
  1653.                 printTicket: function(e) {
  1654.                     window.print();
  1655.                 },
  1656.                 enterManualAdd: function(e) {
  1657.                     var target = $(e.target);
  1658.                     if(target.val()) {
  1659.                         var e = $.Event("keypress");
  1660.                         e.which = 13; //choose the one you want
  1661.                         target.trigger(e);
  1662.                     }
  1663.                 },
  1664.                 fixheader: function(e){
  1665.                     e.preventDefault();
  1666.                     var header = localStorage.getItem("fixHeader");
  1667.                     header = !(header == 'true');
  1668.                     localStorage.setItem("fixHeader", header);
  1669.                     this.fixheaderInit();
  1670.                 },
  1671.                 fixheaderInit: function(){
  1672.                     var header = localStorage.getItem("fixHeader");
  1673.                     if(header == 'true'){
  1674.                         $('a.uv-icon-pin').addClass('uv-icon-pinned');
  1675.                         $('.uv-ticket-action-bar').addClass('uv-ticket-action-bar-fixed');
  1676.                     }else{
  1677.                         $('a.uv-icon-pin').removeClass('uv-icon-pinned');
  1678.                         $('.uv-ticket-action-bar').removeClass('uv-ticket-action-bar-fixed');
  1679.                     }
  1680.                 },
  1681.                 masrkSpamAndClosed: function(e) {
  1682.                     var currentElement = Backbone.$(e.currentTarget);
  1683.                     var value = currentElement.attr('data-index');
  1684.                     $(".uv-aside-select .uv-dropdown-list ul.status li[data-index='" + value + "']").trigger('click')
  1685.                 },
  1686.                 editTicketProperty: function(e) {
  1687.                     var currentElement = Backbone.$(e.currentTarget);
  1688.                     var uvSelect = currentElement.parents('.uv-aside-select');
  1689.                     var field = currentElement.parent().attr('data-action');
  1690.                     var value = currentElement.attr('data-index');
  1691.                     if(uvSelect.find('.uv-aside-select-value').attr('data-id') != value) {
  1692.                         var name = currentElement.text().trim();
  1693.                         app.appView.showLoader();
  1694.                         this.model.save({attribute: field, value: value, id: this.model.id}, {
  1695.                             patch: true,
  1696.                             success: function (model, response, options) {
  1697.                                 uvSelect.find('.uv-aside-select-value').attr('data-id', value).text(name)
  1698.                                 if(field == 'priority') {
  1699.                                     uvSelect.find('.uv-list-ticket-priority').attr('style', 'background:' + currentElement.attr('data-color'));
  1700.                                 } else if(field == 'agent') {
  1701.                                     $('.uv-ticket-strip .agent-info').show()
  1702.                                     $('.uv-ticket-strip .agent-info .name').text(name)
  1703.                                 }
  1704.                                 app.appView.hideLoader();
  1705.                                 app.appView.renderResponseAlert(response);
  1706.                             },
  1707.                             error: function (model, xhr, options) {
  1708.                                 if(url = xhr.getResponseHeader('Location'))
  1709.                                     window.location = url;
  1710.                                 var response = warningResponse;
  1711.                                 if(xhr.responseJSON)
  1712.                                     response = xhr.responseJSON;
  1713.                                 app.appView.hideLoader();
  1714.                                 app.appView.renderResponseAlert(response);
  1715.                             }
  1716.                         });
  1717.                     }
  1718.                 },
  1719.                 showCustomerUpdateBlock: function() {
  1720.                     $('.uv-main-info-update-block').show()
  1721.                     $('.uv-main-info-block').hide()
  1722.                 },
  1723.                 updateStar: function(e) {
  1724.                     e.preventDefault();
  1725.                     var currentElement = Backbone.$(e.currentTarget);
  1726.                     currentElement.toggleClass('uv-star-active')
  1727.                     this.model.save({id: this.model.id}, {
  1728.                         patch: true,
  1729.                         url : "{{ path('helpdesk_member_bookmark_ticket_xhr') }}",
  1730.                         success: function (model, response, options) {
  1731.                         },
  1732.                         error: function (model, xhr, options) {
  1733.                             if(url = xhr.getResponseHeader('Location'))
  1734.                                 window.location = url;
  1735.                         }
  1736.                     });
  1737.                 },
  1738.                 filterThread: function(e) {
  1739.                     var currentElement = Backbone.$(e.currentTarget);
  1740.                     if(type = currentElement.attr('data-type')) {
  1741.                         localStorage.setItem("threadTab", type);
  1742.                         if(type != 'all')
  1743.                             $('.uv-ticket-main.create').hide()
  1744.                         else
  1745.                             $('.uv-ticket-main.create').show()
  1746.                         $('.uv-ticket-wrapper.thread-list').html('')
  1747.                         models = []
  1748.                         threadCollection.each(function(model) {
  1749.                             models.push(model)
  1750.                         })
  1751.                         total = threadCollection.models.length;
  1752.                         count = 0;
  1753.                         if(total) {
  1754.                             _.each(models, function (model) {
  1755.                                 threadCollection.remove(model)
  1756.                                 count++;
  1757.                                 if(total == count) {
  1758.                                     threadCollection.reset()
  1759.                                     threadCollection.state.currentPage = 1;
  1760.                                     threadCollection.syncData()
  1761.                                 }
  1762.                             });
  1763.                         } else {
  1764.                             threadCollection.reset()
  1765.                             threadCollection.state.currentPage = 1;
  1766.                             threadCollection.syncData()
  1767.                         }
  1768.                     }
  1769.                 },
  1770.                 confirmRemove: function(e) {
  1771.                     app.appView.openConfirmModal(this);
  1772.                 },
  1773.                 removeItem : function() {
  1774.                     if(this.model.attributes.isTrashed)
  1775.                         window.location.href = "{{ path('helpdesk_member_delete_ticket', {'ticketId': ticket.id}) }}";
  1776.                     else
  1777.                         window.location.href = "{{ path('helpdesk_member_trash_ticket', {'ticketId': ticket.id}) }}";
  1778.                 },
  1779.                 addCCCollaborators: function() {
  1780.                     if(collaboratorCollection.length) {
  1781.                         var collaboratorContainer = $('.uv-element-block.collaborators');
  1782.                         collaboratorContainer.find('.uv-field-block').html('');
  1783.                         collaboratorContainer.show()
  1784.                         _.each(collaboratorCollection.models, function (item) {
  1785.                             var json = item.attributes;
  1786.                             collaboratorContainer.find('.uv-field-block').append("<span><input type='hidden' name='cccol[]' value='" + json.email + "'/><a class='uv-btn-tag' href='#'><span class='uv-icon-remove-dark-before'></span>" + json.name + "</a></span>")
  1787.                         }, this);
  1788.                     }
  1789.                 },
  1790.                 removeCcCollaborator: function(e) {
  1791.                     e.preventDefault()
  1792.                     Backbone.$(e.currentTarget).parent().remove();
  1793.                     var collaboratorContainer = $('.uv-element-block.collaborators');
  1794.                     if(!collaboratorContainer.find('.uv-btn-tag').length)
  1795.                         collaboratorContainer.hide()
  1796.                 },
  1797.                 addToInput: function(e) {
  1798.                     var inputElement = Backbone.$(e.currentTarget);
  1799.                     var currentTab = inputElement.parents('.uv-tab-view');
  1800.                     var email = inputElement.val().trim();
  1801.                     if (e.which === 13 && email) {
  1802.                         e.preventDefault()
  1803.                         if(!this.model.preValidate({name: 'email', email: email})) {
  1804.                             inputElement.val('').trigger('input')
  1805.                             inputElement.removeClass('uv-dropdown-btn-active')
  1806.                             inputElement.siblings('.uv-dropdown-list').hide()
  1807.                             if(!currentTab.find(".to-list input[value='" + email + "'].to").length) {
  1808.                                 currentTab.find('.to-list').append("<span><input type='hidden' name='to[]' value='" + email + "' class='to'/><a class='uv-btn-tag' href='#'><span class='uv-icon-remove-dark-before'></span>" + email + "</span></a></span>")
  1809.                             }
  1810.                         }
  1811.                     }
  1812.                 },
  1813.                 addTo: function(e) {
  1814.                     var currentTab = Backbone.$(e.currentTarget).parents('.uv-tab-view');
  1815.                     var email =  Backbone.$(e.currentTarget).attr('data-id');
  1816.                     if(!currentTab.find(".to-list input[value='" + email + "'].to").length) {
  1817.                         currentTab.find('.to-list').append("<span><input type='hidden' name='to[]' value='" + email + "' class='to'/><a class='uv-btn-tag' href='#'><span class='uv-icon-remove-dark-before'></span>" + email + "</span></a></span>")
  1818.                     }
  1819.                 },
  1820.                 showCcBccBlock: function(e) {
  1821.                     var currentElement = Backbone.$(e.currentTarget);
  1822.                     var currentTab = currentElement.parents('.uv-tab-view');
  1823.                     if(currentElement.is(':checked')) {
  1824.                         currentTab.find('.uv-element-block.cc-bcc').find('.uv-field-block').show()
  1825.                     } else {
  1826.                         currentTab.find('.uv-element-block.cc-bcc').find('.uv-field-block').hide()
  1827.                         currentTab.find('.uv-element-block .cc-bcc-list').html('')
  1828.                     }
  1829.                 },
  1830.                 addCcBccInput: function(e) {
  1831.                     var inputElement = Backbone.$(e.currentTarget);
  1832.                     var currentTab = inputElement.parents('.uv-tab-view');
  1833.                     var email = inputElement.val().trim();
  1834.                     if (e.which === 13 && email) {
  1835.                         e.preventDefault()
  1836.                         type = currentTab.find('.cc-bcc-select option:selected').text()
  1837.                         if(!this.model.preValidate({name: 'email', email: email})) {
  1838.                             inputName = $('.cc-bcc-select').val()
  1839.                             inputElement.val('').trigger('input')
  1840.                             inputElement.removeClass('uv-dropdown-btn-active')
  1841.                             inputElement.siblings('.uv-dropdown-list').hide()
  1842.                             if(!currentTab.find(".cc-bcc-list input[value='" + email + "']." + inputName).length) {
  1843.                                 currentTab.find('.cc-bcc-list').append("<span><input type='hidden' name='" + inputName + "[]' value='" + email + "' class='" + inputName + "'/><a class='uv-btn-tag uv-lowercase' href='#'><span class='uv-icon-remove-dark-before'></span><span class='uv-uppercase' style='margin-right: 4px;'>" + type + ":</span>" + email + "</a></span>")
  1844.                             }
  1845.                         }
  1846.                     }
  1847.                 },
  1848.                 addCcBcc: function(e) {
  1849.                     var currentTab = Backbone.$(e.currentTarget).parents('.uv-tab-view');
  1850.                     var email =  Backbone.$(e.currentTarget).attr('data-id');
  1851.                     type = currentTab.find('.cc-bcc-select option:selected').text()
  1852.                     inputName = currentTab.find('.cc-bcc-select').val()
  1853.                     if(!currentTab.find(".cc-bcc-list input[value='" + email + "']." + inputName).length) {
  1854.                         currentTab.find('.uv-element-block.cc-bcc .uv-group-field.uv-dropdown-other').val('').trigger('input')
  1855.                         currentTab.find('.cc-bcc-list').append("<span><input type='hidden' name='" + inputName + "[]' value='" + email + "' class='" + inputName + "'/><a class='uv-btn-tag uv-lowercase' href='#'><span class='uv-icon-remove-dark-before'></span><span class='uv-uppercase' style='margin-right: 4px;'>" + type + ":</span>" + email + "</a></span>")
  1856.                     }
  1857.                 },
  1858.                 removeEmail: function(e) {
  1859.                     e.preventDefault()
  1860.                     Backbone.$(e.currentTarget).parent().remove();
  1861.                 },
  1862.                 setNextView: function(e) {
  1863.                     var currentElement = Backbone.$(e.currentTarget);
  1864.                     var nextView = currentElement.attr('data-value');
  1865.                     localStorage.setItem("nextView", nextView);
  1866.                     $(".next-view input").val(nextView)
  1867.                     $(".next-view .uv-dropdown-btn").text(currentElement.text())
  1868.                 },
  1869.                 validateForm : function(e) {
  1870.                     e.preventDefault();
  1871.                     var element = Backbone.$(e.currentTarget);
  1872.                     formType = element.parents('.uv-tab-view.uv-tab-view-active').attr('id');
  1873.                     form = element.parents('form');
  1874.                     form.find('.reply-status').val(element.attr('data-id'));
  1875.                     form.find('.uv-field-message').remove()
  1876.                     var html = tinyMCE.get(formType + "-area").getContent();
  1877.                     if(app.appView.htmlText(html) != '' || -1 != html.indexOf('<img')) {
  1878.                         if(formType == 'forward') {
  1879.                             if(!form.find(".to-list input.to").length) {
  1880.                                 $('.uv-element-block.to').append("<span class='uv-field-message'>{{ 'This field is mandatory'|trans }}</span>")
  1881.                             } else {
  1882.                                 this.stopDraftSaveFlag = 1;
  1883.                                 app.appView.showLoader();
  1884.                                 tinyMCE.activeEditor.uploadImages(function(response) {
  1885.                                     app.appView.hideLoader();
  1886.                                     form.submit();
  1887.                                     $('.uv-btn.forward').attr('disabled', 'disabled');
  1888.                                 });
  1889.                             }
  1890.                         } else {
  1891.                             this.stopDraftSaveFlag = 1;
  1892.                             if(localStorage) {
  1893.                                 localStorage.setItem("threadTab", "all");
  1894.                             }
  1895.                             app.appView.showLoader();
  1896.                             tinyMCE.activeEditor.uploadImages(function(response) {
  1897.                                 app.appView.hideLoader();
  1898.                                 form.submit();
  1899.                                 $('.uv-dropdown.reply').find('.uv-btn').attr('disabled', 'disabled');
  1900.                             });
  1901.                         }
  1902.                     } else {
  1903.                         form.find('.uv-element-block-textarea').append("<span class='uv-field-message'>{{ 'This field is mandatory'|trans }}</span>");
  1904.                         if(formType == 'forward') {
  1905.                             if(!form.find(".to-list input.to").length) {
  1906.                                 $('.uv-element-block.to').append("<span class='uv-field-message'>{{ 'This field is mandatory'|trans }}</span>")
  1907.                             }
  1908.                         }
  1909.                     }
  1910.                 },
  1911.                 updateTicket: function(e) {
  1912.                     e.preventDefault();
  1913.                     this.model.set($('#edit-ticket-modal form').serializeObject());
  1914.                     if(this.model.isValid(['subject', 'reply'])) {
  1915.                         $('#edit-ticket-modal form').find('.uv-btn').attr('disabled', 'disabled');
  1916.                         $('#edit-ticket-modal form').submit();
  1917.                     }
  1918.                 },
  1919.                 showReplyQuote: function(e) {
  1920.                     Backbone.$(e.currentTarget).next().toggle();
  1921.                 },
  1922.                 searchFilterXhr: _.debounce(function(e) {
  1923.                     currentElement = Backbone.$(e.currentTarget);
  1924.                     var parent = currentElement.parent();
  1925.                     if($('.uv-dropdown-other.uv-dropdown-btn-active').parent().attr('id') != parent.attr('id'))
  1926.                         return;
  1927.                     parent.find("li:not(.uv-no-results, .uv-filter-info)").remove();
  1928.                     parent.find(".uv-filter-info").show()
  1929.                     if(currentElement.val().length > 1) {
  1930.                         parent.append(this.loaderTemplate())
  1931.                         parent.find('.uv-filter-info').text("{% trans %}Searching{% endtrans %} ...")
  1932.                         if(self.xhrReq)
  1933.                             self.xhrReq.abort();
  1934.                         self.xhrReq = $.ajax({
  1935.                             url : "{{ path('helpdesk_member_ticket_search_filter_options') }}",
  1936.                             type : 'GET',
  1937.                             data: {"type" : currentElement.attr('data-type'), "query": currentElement.val()},
  1938.                             dataType : 'json',
  1939.                             success : function(response) {
  1940.                                 self.xhrReq = 0;
  1941.                                 parent.find('.uv-loader').remove()
  1942.                                 parent.find('.uv-filter-info').text("{{ 'Type atleast 2 letters'|trans }}").hide();
  1943.                                 if(response.length == 0) {
  1944.                                     parent.find('.uv-no-results').show();
  1945.                                     parent.find('.uv-no-results').disabled = true;
  1946.                                 } else {
  1947.                                     parent.find('.uv-no-results').hide();
  1948.                                     _.each(response, function(item) {
  1949.                                         parent.find('.uv-dropdown-list ul').append("<li data-id='" + item.id + "'>" + item.name + "</li>")
  1950.                                     });
  1951.                                 }
  1952.                             },
  1953.                             error: function (xhr) {
  1954.                                 self.xhrReq = 0;
  1955.                                 parent.find('.uv-loader').remove()
  1956.                                 parent.find('.uv-no-results').hide();
  1957.                                 parent.find('.uv-filter-info').text("{{ 'Type atleast 2 letters'|trans }}").show();
  1958.                                 if(url = xhr.getResponseHeader('Location'))
  1959.                                     window.location = url;
  1960.                             }
  1961.                         });
  1962.                     } else {
  1963.                         parent.find('.uv-no-results').hide();
  1964.                     }
  1965.                 },1000)
  1966.             });
  1967.             // Ticket Thread View
  1968.             var ThreadItem = Backbone.View.extend({
  1969.                 tagName : "div",
  1970.                 className : "uv-ticket-main",
  1971.                 template : _.template($("#thread_list_item_tmp").html()),
  1972.                 editThreadTemplate : _.template($("#edit_thread_tmp").html()),
  1973.                 events : {
  1974.                     'click .uv-thread-action .uv-dropdown-list li[data-action="delete"]': 'confirmRemove',
  1975.                     'click .uv-thread-action .uv-dropdown-list li[data-action="lock"]': 'lockAndUnlockThread',
  1976.                     'click .uv-thread-action .uv-dropdown-list li[data-action="pin"]': 'pinThread',
  1977.                     'click .uv-thread-action .uv-dropdown-list li[data-action="mark"]': 'markForTask',
  1978.                     'click .uv-thread-action .uv-dropdown-list li[data-action="forward"]' : 'forwardThread',
  1979.                     'click .uv-thread-action .uv-dropdown-list li[data-action="edit"]' : 'editThread',
  1980.                     'click .uv-btn.cancel-edit' : 'cancelEdit',
  1981.                     'click .uv-btn.saveThread' : 'updateThread',
  1982.                     'click .copy-thread-link' : 'copyThreadLink',
  1983.                     'blur .input-copy-thread-link': 'removeCopyThreadLink'
  1984.                 },
  1985.                 render : function () {
  1986.                     this.$el.html(this.template(this.model.toJSON()));
  1987.                     this.$el.addClass("thread-" + this.model.id)
  1988.                     if(this.model.attributes.threadType == 'note')
  1989.                         this.$el.addClass('uv-ticket-note')
  1990.                     return this;
  1991.                 },
  1992.                 unrender : function(response) {
  1993.                     if(response.alertMessage != undefined) {
  1994.                         var self = this;
  1995.                         {# threadCollection.models.remove(this.model); #}
  1996.                         threadCollection.models = threadCollection.models.filter(thread => {
  1997.                             if(thread.id == self.model.id) {
  1998.                                 return false;
  1999.                             }
  2000.                             return true;
  2001.                         });
  2002.                         this.remove();
  2003.                         threadCollection.syncData();
  2004.                         app.appView.renderResponseAlert(response);
  2005.                     }
  2006.                 },
  2007.                 confirmRemove: function(e) {
  2008.                     app.appView.openConfirmModal(this);
  2009.                 },
  2010.                 removeItem : function() {
  2011.                     self = this;
  2012.                     var index = threadIds.indexOf(this.model.id);
  2013.                     if (index > -1)
  2014.                         threadIds.splice(index, 1);
  2015.                     app.appView.showLoader();
  2016.                     this.model.destroy({
  2017.                         url : "{{ path('helpdesk_member_thread_xhr') }}/" + this.model.id,
  2018.                         data : { 'ticketId' : ticketModel.attributes.id },
  2019.                         success : function (model, response, options) {
  2020.                             app.appView.hideLoader();
  2021.                             self.unrender(response);
  2022.                         },
  2023.                         error: function (model, xhr, options) {
  2024.                             if(url = xhr.getResponseHeader('Location'))
  2025.                                 window.location = url;
  2026.                             var response = warningResponse;
  2027.                             if(xhr.responseJSON)
  2028.                                 response = xhr.responseJSON;
  2029.                             app.appView.hideLoader();
  2030.                             app.appView.renderResponseAlert(response);
  2031.                         }
  2032.                     });
  2033.                 },
  2034.                 lockAndUnlockThread :function(e) {
  2035.                     self = this;
  2036.                     currentElement = Backbone.$(e.currentTarget);
  2037.                     var isLocked = 0;
  2038.                     if(this.model.get('isLocked')) {
  2039.                         this.model.set('isLocked', 0);
  2040.                         currentElement.attr('data-id', isLocked).text("{{ 'Lock Thread'|trans }}");
  2041.                     } else {
  2042.                         isLocked = 1;
  2043.                         this.model.set('isLocked', 1);
  2044.                         currentElement.attr('data-id', isLocked).text("{{ 'Unlock Thread'|trans }}");
  2045.                     }
  2046.                     app.appView.showLoader();
  2047.                     this.model.save({
  2048.                         isLocked: isLocked,
  2049.                         id: this.model.id,
  2050.                         ticketId: ticketModel.attributes.id,
  2051.                         updateType: 'lock'
  2052.                     }, {
  2053.                         patch: true,
  2054.                         url : "{{ path('helpdesk_member_thread_xhr') }}/" + this.model.id,
  2055.                         success : function (model, response, options) {
  2056.                             self.toggleThreadPropertyIcon()
  2057.                             app.appView.hideLoader();
  2058.                             app.appView.renderResponseAlert(response);
  2059.                         },
  2060.                         error: function (model, xhr, options) {
  2061.                             if(url = xhr.getResponseHeader('Location'))
  2062.                                 window.location = url;
  2063.                             var response = warningResponse;
  2064.                             if(xhr.responseJSON)
  2065.                                 response = xhr.responseJSON;
  2066.                             app.appView.hideLoader();
  2067.                             app.appView.renderResponseAlert(response);
  2068.                         }
  2069.                     });
  2070.                 },
  2071.                 pinThread :function(e) {
  2072.                     self = this;
  2073.                     currentElement = Backbone.$(e.currentTarget);
  2074.                     var bookmark = 0;
  2075.                     if(this.model.get('bookmark')) {
  2076.                         this.model.set('bookmark', 0);
  2077.                         currentElement.attr('data-id', bookmark).text("{{ 'Pin Thread'|trans }}");
  2078.                     } else {
  2079.                         bookmark = 1;
  2080.                         this.model.set('bookmark', 1);
  2081.                         currentElement.attr('data-id', bookmark).text("{{ 'Unpin Thread'|trans }}");
  2082.                     }
  2083.                     app.appView.showLoader();
  2084.                     this.model.save({
  2085.                         bookmark: bookmark,
  2086.                         id: this.model.id,
  2087.                         ticketId: ticketModel.attributes.id,
  2088.                         updateType: 'bookmark'
  2089.                     }, {
  2090.                         patch: true,
  2091.                         url : "{{ path('helpdesk_member_thread_xhr') }}/" + this.model.id,
  2092.                         success : function (model, response, options) {
  2093.                             self.toggleThreadPropertyIcon()
  2094.                             app.appView.hideLoader();
  2095.                             app.appView.renderResponseAlert(response);
  2096.                         },
  2097.                         error: function (model, xhr, options) {
  2098.                             if(url = xhr.getResponseHeader('Location'))
  2099.                                 window.location = url;
  2100.                             var response = warningResponse;
  2101.                             if(xhr.responseJSON)
  2102.                                 response = xhr.responseJSON;
  2103.                             app.appView.hideLoader();
  2104.                             app.appView.renderResponseAlert(response);
  2105.                         }
  2106.                     });
  2107.                 },
  2108.                 forwardThread : function(e) {
  2109.                     var element = Backbone.$(e.currentTarget);
  2110.                     tinymce.get('forward-area').setContent(this.model.attributes.reply);
  2111.                     $('#forward-area').parent().find('img').removeAttr('crossorigin');
  2112.                     $(".uv-tabs li[for='forward']").trigger('click');
  2113.                     $('.uv-ticket-scroll-region').animate({
  2114.                         scrollTop: $('#default').outerHeight()
  2115.                     }, 'slow');
  2116.                 },
  2117.                 cancelEdit : function(e) {
  2118.                     this.initEditThread();
  2119.                     tinymce.get('uv-edit-thread').destroy()
  2120.                 },
  2121.                 editThread : function(e) {
  2122.                     $('.thread-edit-container .cancel-edit').trigger('click');
  2123.                     this.initEditThread();
  2124.                     this.$el.find('.message').hide().after(this.editThreadTemplate());
  2125.                     this.$el.find('.uv-ticket-uploads').hide()
  2126.                     InitTinyMce('#uv-edit-thread');
  2127.                     tinymce.get('uv-edit-thread').setContent(this.model.attributes.reply);
  2128.                     this.$el.find('img').removeAttr('crossorigin');
  2129.                 },
  2130.                 initEditThread: function() {
  2131.                     $('.thread-edit-container').remove();
  2132.                     messageElement = this.$el.find('.message');
  2133.                     messageElement.show();
  2134.                     this.$el.find('.uv-ticket-uploads').show()
  2135.                 },
  2136.                 updateThread : function(e) {
  2137.                     e.preventDefault();
  2138.                     var currentElement = Backbone.$(e.currentTarget);
  2139.                     parent = currentElement.parents('.thread-edit-container')
  2140.                     parent.find('.uv-field-message').remove()
  2141.                     var html = tinyMCE.get("uv-edit-thread").getContent();
  2142.                     if(app.appView.stripHTML(html) != '') {
  2143.                         var self = this;
  2144.                         currentElement.attr("disabled", "disabled");
  2145.                         this.model.set('reply', html);
  2146.                         app.appView.showLoader()
  2147.                         this.model.save({}, {
  2148.                             url : "{{ path('helpdesk_member_thread_update_xhr') }}/" + this.model.id,
  2149.                             success : function (model, response, options) {
  2150.                                 app.appView.hideLoader()
  2151.                                 messageElement = self.$el.find('.message');
  2152.                                 if(response.alertClass == 'success') {
  2153.                                     messageElement.html(self.model.attributes.reply).show();
  2154.                                     messageElement.find('.uv-icon-ellipsis').remove();
  2155.                                     messageElement.find('.helpdesk_blockquote').eq(0).before("<span class='uv-icon-ellipsis uv-ellipsis-mirror'></span>").hide();
  2156.                                 }
  2157.                                 self.initEditThread();
  2158.                                 tinymce.get('uv-edit-thread').destroy()
  2159.                                 app.appView.renderResponseAlert(response);
  2160.                             },
  2161.                             error: function (model, xhr, options) {
  2162.                                 self.initEditThread();
  2163.                                 tinymce.get('uv-edit-thread').destroy()
  2164.                                 if(url = xhr.getResponseHeader('Location'))
  2165.                                     window.location = url;
  2166.                                 var response = warningResponse;
  2167.                                 if(xhr.responseJSON)
  2168.                                     response = xhr.responseJSON;
  2169.                                 app.appView.hideLoader()
  2170.                                 app.appView.renderResponseAlert(response);
  2171.                             }
  2172.                         });
  2173.                     } else {
  2174.                         this.$el.find('.uv-element-block-textarea').append("<span class='uv-field-message'>{{ 'This field is mandatory'|trans }}</span>");
  2175.                     }
  2176.                 },
  2177.                 toggleCreateTaskBar : function() {
  2178.                     if(threadIds.length) {
  2179.                         $("#uv-task-view").css('right', '0px');
  2180.                         $("#uv-task-view .uv-create-task").show()
  2181.                         $("#uv-task-view .uv-task-list").hide()
  2182.                     } else {
  2183.                         $("#uv-task-view").css('right', '-300px');
  2184.                         $("#uv-task-view .uv-create-task").hide()
  2185.                         $("#uv-task-view .uv-task-list").show()
  2186.                     }
  2187.                 },
  2188.                 copyThreadLink: function(e){
  2189.                     _.delay(function(){
  2190.                         $(e.currentTarget).before('<input type="text" class="input-copy-thread-link uv-field" value="' + window.location.href + '"/>');
  2191.                         $(e.currentTarget).prev().focus().select();
  2192.                     }, 100);
  2193.                 },
  2194.                 removeCopyThreadLink: function(e){
  2195.                     $(e.currentTarget).remove();
  2196.                 },
  2197.                 toggleThreadPropertyIcon: function(e) {
  2198.                     if(jQuery.inArray(this.model.id, threadIds) !== -1 || this.model.get('bookmark') || this.model.get('isLocked')) {
  2199.                         this.$el.find('.uv-icon-pinned').parents('.uv-ticket-strip').show()
  2200.                     } else {
  2201.                         this.$el.find('.uv-icon-pinned').parents('.uv-ticket-strip').hide()
  2202.                     }
  2203.                     if(jQuery.inArray(this.model.id, threadIds) !== -1)
  2204.                         this.$el.find('.uv-icon-marked-task').parent().show()
  2205.                     else
  2206.                         this.$el.find('.uv-icon-marked-task').parent().hide()
  2207.                     if(this.model.get('bookmark'))
  2208.                         this.$el.find('.uv-icon-pinned').parent().show()
  2209.                     else
  2210.                         this.$el.find('.uv-icon-pinned').parent().hide()
  2211.                     if(this.model.get('isLocked'))
  2212.                         this.$el.find('.uv-icon-locked').parent().show()
  2213.                     else
  2214.                         this.$el.find('.uv-icon-locked').parent().hide()
  2215.                 }
  2216.             });
  2217.             // Ticket Thread List
  2218.             var ThreadList = Backbone.View.extend({
  2219.                 el : $(".thread-list"),
  2220.                 initialize : function() {
  2221.                     this.listenTo(threadCollection.fullCollection, "add", this.renderThread);
  2222.                 },
  2223.                 renderThread : function (item) {
  2224.                     var threadItem = new ThreadItem({
  2225.                         model: item
  2226.                     });
  2227.                     if(item.id < threadCollection.fullCollection.at(0).id)
  2228.                         this.$el.prepend(threadItem.render().el);
  2229.                     else
  2230.                         this.$el.append(threadItem.render().el);
  2231.                     threadItem.$el.find('.helpdesk_blockquote').eq(0).before("<span class='uv-icon-ellipsis uv-ellipsis-mirror'></span>").hide();
  2232.                     //emojifyRun();
  2233.                     this.$el.find('img').removeAttr('crossorigin');
  2234.                     this.$el.find('div.message a').attr('target', '_blank');
  2235.                     app.appView.relativeTime();
  2236.                 }
  2237.             });
  2238.             // Ticket Pagination View
  2239.             var Pagination = Backbone.View.extend({
  2240.                 el: $('.uv-ticket-accordion'),
  2241.                 events: {
  2242.                     'click .uv-ticket-count-stat': 'loadMore',
  2243.                 },
  2244.                 renderPagination: function(pagination) {
  2245.                     if(pagination.totalCount - pagination.lastItemNumber > 0 && pagination.lastItemNumber > 0) {
  2246.                         var remain = pagination.totalCount - pagination.lastItemNumber;
  2247.                         $('.uv-ticket-count-stat').text(remain)
  2248.                         $('.uv-ticket-accordion').removeClass('uv-ticket-accordion-expanded').removeClass('uv-ticket-accordion-no-count')
  2249.                     } else {
  2250.                         $('.uv-ticket-accordion').addClass('uv-ticket-accordion-expanded').addClass('uv-ticket-accordion-no-count')
  2251.                     }
  2252.                 },
  2253.                 loadMore: function() {
  2254.                     threadCollection.syncData();
  2255.                 }
  2256.             });
  2257.             // Ticket collaborator Item View
  2258.             var CollaboratorItem = Backbone.View.extend({
  2259.                 tagName : "a",
  2260.                 className: 'uv-btn-tag',
  2261.                 template : _.template("{% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_COLLABORATOR_FROM_TICKET') %}<span class='uv-tag'><span class='uv-icon-remove-dark-before'></span><%- name %></span>{% else %}<span class='uv-tag-delete'><%- name %></span>{% endif %}"),
  2262.                 events : {
  2263.                     'click .uv-tag' : 'confirmRemove'
  2264.                 },
  2265.                 render : function () {
  2266.                     this.$el.html(this.template(this.model.toJSON()));
  2267.                     return this;
  2268.                 },
  2269.                 unrender : function(response) {
  2270.                     if(response.alertMessage != undefined) {
  2271.                         app.appView.renderResponseAlert(response);
  2272.                     }
  2273.                 },
  2274.                 removeItem: function() {
  2275.                     {% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_COLLABORATOR_TO_TICKET') %}
  2276.                         self = this;
  2277.                         app.appView.showLoader();
  2278.                         this.model.destroy({
  2279.                             data : { 'ticketId' : this.model.attributes.ticketId },
  2280.                             success : function (model, response, options) {
  2281.                                 app.appView.hideLoader();
  2282.                                 self.$el.remove();
  2283.                                 self.unrender(response);
  2284.                             },
  2285.                             error: function (model, xhr, options) {
  2286.                                 if(url = xhr.getResponseHeader('Location'))
  2287.                                     window.location = url;
  2288.                                 var response = warningResponse;
  2289.                                 if(xhr.responseJSON)
  2290.                                     response = xhr.responseJSON;
  2291.                                 app.appView.hideLoader();
  2292.                                 app.appView.renderResponseAlert(response);
  2293.                             }
  2294.                         });
  2295.                     {% endif %}
  2296.                 },
  2297.                 confirmRemove: function(e) {
  2298.                     e.preventDefault();
  2299.                     {% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_COLLABORATOR_TO_TICKET') %}
  2300.                         app.appView.openConfirmModal(this);
  2301.                     {% endif %}
  2302.                 }
  2303.             });
  2304.             // Ticket Collaborator View
  2305.             var CollaboratorList = Backbone.View.extend({
  2306.                 el : $(".collaborator-list-block"),
  2307.                 events : {
  2308.                     'keypress .uv-field' : 'addCollaborator',
  2309.                     'focusout .uv-field' : 'removeErrorClass'
  2310.                 },
  2311.                 initialize : function() {
  2312.                     //Backbone.Validation.bind(this);
  2313.                 },
  2314.                 render : function() {
  2315.                     this.$el.find(".collaborator-list").html('');
  2316.                     var self = this;
  2317.                     collaboratorOptionHtml = '';
  2318.                     if(collaboratorCollection.length) {
  2319.                         _.each(collaboratorCollection.models, function (item) {
  2320.                             this.renderCollaborator(item);
  2321.                         }, this);
  2322.                     }
  2323.                     ticketView.addCCCollaborators()
  2324.                 },
  2325.                 renderCollaborator : function (item) {
  2326.                     var collaborator = new CollaboratorItem({
  2327.                         model: item
  2328.                     });
  2329.                     this.$el.find('.collaborator-list').append(collaborator.render().el);
  2330.                 },
  2331.                 removeErrorClass: function(e) {
  2332.                     var inputElement = Backbone.$(e.currentTarget);
  2333.                     inputElement.removeClass('uv-field-error');
  2334.                     inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
  2335.                 },
  2336.                 addCollaborator : function(e) {
  2337.                     {% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_COLLABORATOR_TO_TICKET') %}
  2338.                         var inputElement = Backbone.$(e.currentTarget);
  2339.                         inputElement.removeClass('uv-field-error');
  2340.                         inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
  2341.                         var text = inputElement.val().trim();
  2342.                         if (e.which === 13 && text) {
  2343.                             this.model = new CollaboratorModel();
  2344.                             self = this;
  2345.                             this.model.set({email: text})
  2346.                             if(this.model.isValid(true)) {
  2347.                                 app.appView.showLoader();
  2348.                                 this.model.save({},{
  2349.                                     success : function (model, response, options) {
  2350.                                         inputElement.val('');
  2351.                                         if(response.alertClass == "success") {
  2352.                                             collaboratorCollection.add(model);
  2353.                                         }
  2354.                                         self.render();
  2355.                                         app.appView.hideLoader();
  2356.                                         app.appView.renderResponseAlert(response);
  2357.                                     },
  2358.                                     error: function (model, xhr, options) {
  2359.                                         if(url = xhr.getResponseHeader('Location'))
  2360.                                             window.location = url;
  2361.                                         var response = warningResponse;
  2362.                                         if(xhr.responseJSON)
  2363.                                             response = xhr.responseJSON;
  2364.                                         app.appView.hideLoader();
  2365.                                         app.appView.renderResponseAlert(response);
  2366.                                     }
  2367.                                 });
  2368.                             } else {
  2369.                                 inputElement.addClass('uv-field-error');
  2370.                                 if(text)
  2371.                                     inputElement.parents('.uv-element-block').append("<span class='uv-field-message'>{{ 'Email address is invalid'|trans }}</span>");
  2372.                             }
  2373.                         }
  2374.                     {% endif %}
  2375.                 }
  2376.             });
  2377.             // Ticket Tag Item View
  2378.             var TagItem = Backbone.View.extend({
  2379.                 tagName : "a",
  2380.                 className : "uv-btn-tag",
  2381.                 template : _.template("<span class='uv-tag'>{% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_TAG') %}<span class='uv-icon-remove-dark-before'></span>{% endif %}<%- name %></span>"),
  2382.                 events : {
  2383.                     'click .uv-tag' : "confirmRemove"
  2384.                 },
  2385.                 render : function () {
  2386.                     this.$el.html(this.template(this.model.toJSON()));
  2387.                     return this;
  2388.                 },
  2389.                 unrender : function(response) {
  2390.                     if(response.alertMessage != undefined) {
  2391.                         tagListView.render();
  2392.                         app.appView.renderResponseAlert(response);
  2393.                     }
  2394.                 },
  2395.                 removeItem : function () {
  2396.                     {% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_TAG') %}
  2397.                     self = this;
  2398.                     app.appView.showLoader();
  2399.                     this.model.destroy({
  2400.                         data : { 'ticketId' : ticketModel.id } ,
  2401.                         success : function (model, response, options) {
  2402.                             app.appView.hideLoader();
  2403.                             self.$el.remove();
  2404.                             self.unrender(response);
  2405.                         },
  2406.                         error: function (model, xhr, options) {
  2407.                             if(url = xhr.getResponseHeader('Location'))
  2408.                                 window.location = url;
  2409.                             var response = warningResponse;
  2410.                             if(xhr.responseJSON)
  2411.                                 response = xhr.responseJSON;
  2412.                             app.appView.hideLoader();
  2413.                             app.appView.renderResponseAlert(response);
  2414.                         }
  2415.                     });
  2416.                     {% endif %}
  2417.                 },
  2418.                 confirmRemove: function(e) {
  2419.                     e.preventDefault();
  2420.                     {% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_TAG') %}
  2421.                     app.appView.openConfirmModal(this)
  2422.                     {% endif %}
  2423.                 }
  2424.             });
  2425.             // Ticket Tag View
  2426.             var TagList = Backbone.View.extend({
  2427.                 el : $(".tag-list-block"),
  2428.                 events : {
  2429.                     'keypress .uv-field' : 'addTag',
  2430.                     'focusout .uv-field' : 'removeErrorClass',
  2431.                     'click .uv-dropdown-list li': 'addTag'
  2432.                 },
  2433.                 render : function() {
  2434.                     var self = this;
  2435.                     this.$el.find(".tag-list").html('');
  2436.                     if(tagCollection.length) {
  2437.                         _.each(tagCollection.models, function (item) {
  2438.                             this.renderTag(item);
  2439.                         }, this);
  2440.                     }
  2441.                 },
  2442.                 renderTag : function (item) {
  2443.                     var tag = new TagItem({
  2444.                         model: item
  2445.                     });
  2446.                     this.$el.find('.tag-list').append(tag.render().el);
  2447.                 },
  2448.                 addTag : function(e) {
  2449.                     {% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_TAG') %}
  2450.                         var currentElement = Backbone.$(e.currentTarget);
  2451.                         if(currentElement.is('li')) {
  2452.                             var inputElement = currentElement.parents('.uv-field-block').find('.uv-dropdown-other');
  2453.                             var text = currentElement.text().trim();
  2454.                         } else {
  2455.                             var inputElement = currentElement;
  2456.                             var text = inputElement.val().trim();
  2457.                         }
  2458.                         inputElement.removeClass('uv-field-error');
  2459.                         inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
  2460.                         if (currentElement.is('li') || (e.which === 13 && text)) {
  2461.                             if(text.length <= 20) {
  2462.                                 if(tagCollection.isTagExist(text)) {
  2463.                                     var self = this;
  2464.                                     inputElement.val('');
  2465.                                     this.model = new TagModel();
  2466.                                     this.model.set({name:text});
  2467.                                     self = this;
  2468.                                     app.appView.showLoader();
  2469.                                     this.model.save({}, {
  2470.                                         success: function (model, response, options) {
  2471.                                             inputElement.parent().find("li:not(.uv-no-results)").remove()
  2472.                                             inputElement.parent().find(".uv-no-results").show()
  2473.                                             if(!currentElement.is('li')) {
  2474.                                                 inputElement.trigger('click')
  2475.                                             }
  2476.                                             if(response.alertClass == "success") {
  2477.                                                 tagCollection.add(model);
  2478.                                                 self.render();
  2479.                                             }
  2480.                                             app.appView.hideLoader();
  2481.                                             app.appView.renderResponseAlert(response);
  2482.                                         },
  2483.                                         error: function (model, xhr, options) {
  2484.                                             if(url = xhr.getResponseHeader('Location'))
  2485.                                                 window.location = url;
  2486.                                             var response = warningResponse;
  2487.                                             if(xhr.responseJSON)
  2488.                                                 response = xhr.responseJSON;
  2489.                                             app.appView.hideLoader();
  2490.                                             app.appView.renderResponseAlert(response);
  2491.                                         }
  2492.                                     });
  2493.                                 } else {
  2494.                                     inputElement.addClass('uv-field-error');
  2495.                                     inputElement.parents('.uv-element-block').append("<span class='uv-field-message'>{{ 'Tag with same name already exist'|trans }}</span>");
  2496.                                 }
  2497.                             } else {
  2498.                                 inputElement.addClass('uv-field-error');
  2499.                                 inputElement.parents('.uv-element-block').append("<span class='uv-field-message'>{{ 'Text length should be less than 20 charactors'|trans }}</span>");
  2500.                             }
  2501.                         }
  2502.                     {% endif %}
  2503.                 },
  2504.                 removeErrorClass: function(e) {
  2505.                     var inputElement = Backbone.$(e.currentTarget);
  2506.                     inputElement.removeClass('uv-field-error');
  2507.                     inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
  2508.                 },
  2509.             });
  2510.             // Ticket Label Item View
  2511.             var LabelItem = Backbone.View.extend({
  2512.                 tagName : "a",
  2513.                 className : "uv-btn-label",
  2514.                 template : _.template("<span class='uv-tag'><span class='uv-icon-remove-before'></span><%- name %></span>"),
  2515.                 events : {
  2516.                     'click .uv-tag' : "confirmRemove"
  2517.                 },
  2518.                 render : function () {
  2519.                     this.$el.html(this.template(this.model.toJSON()));
  2520.                     return this;
  2521.                 },
  2522.                 unrender : function(response) {
  2523.                     if(response.alertMessage != undefined) {
  2524.                         labelListView.render();
  2525.                         app.appView.renderResponseAlert(response);
  2526.                     }
  2527.                 },
  2528.                 removeItem : function () {
  2529.                     self = this;
  2530.                     app.appView.showLoader();
  2531.                     this.model.destroy({
  2532.                         url : "{{ path('helpdesk_member_update_ticket_attributes_xhr') }}",
  2533.                         data : { attribute :'label', 'ticketId': ticketModel.id, 'labelId': this.model.get('id') },
  2534.                         success : function (model, response, options) {
  2535.                             app.appView.hideLoader();
  2536.                             self.$el.remove();
  2537.                             self.unrender(response);
  2538.                         },
  2539.                         error: function (model, xhr, options) {
  2540.                             if(url = xhr.getResponseHeader('Location'))
  2541.                                 window.location = url;
  2542.                             var response = warningResponse;
  2543.                             if(xhr.responseJSON)
  2544.                                 response = xhr.responseJSON;
  2545.                             app.appView.hideLoader();
  2546.                             app.appView.renderResponseAlert(response);
  2547.                         }
  2548.                     });
  2549.                 },
  2550.                 confirmRemove: function(e) {
  2551.                     e.preventDefault();
  2552.                     app.appView.openConfirmModal(this)
  2553.                 }
  2554.             });
  2555.             // Ticket Label View
  2556.             var LabelList = Backbone.View.extend({
  2557.                 el : $(".label-list-block"),
  2558.                 events : {
  2559.                     'keypress .uv-field' : 'addLabel',
  2560.                     'focusout .uv-field' : 'removeErrorClass',
  2561.                     'click .uv-dropdown-list li': 'addLabel'
  2562.                 },
  2563.                 render : function() {
  2564.                     var self = this;
  2565.                     this.$el.find(".label-list").html('');
  2566.                     if(labelCollection.length) {
  2567.                         _.each(labelCollection.models, function (item) {
  2568.                             this.renderLabel(item);
  2569.                         }, this);
  2570.                     }
  2571.                 },
  2572.                 renderLabel : function (item) {
  2573.                     var label = new LabelItem({
  2574.                         model: item
  2575.                     });
  2576.                     lavelItem = label.render().el;
  2577.                     $(lavelItem).attr('style', 'background:' + item.attributes.color)
  2578.                     this.$el.find('.label-list').append(lavelItem);
  2579.                 },
  2580.                 addLabel : function(e) {
  2581.                     var currentElement = Backbone.$(e.currentTarget);
  2582.                     if(currentElement.is('li')) {
  2583.                         var inputElement = currentElement.parents('.uv-field-block').find('.uv-dropdown-other');
  2584.                         var text = currentElement.text().trim();
  2585.                     } else {
  2586.                         var inputElement = currentElement;
  2587.                         var text = inputElement.val().trim();
  2588.                     }
  2589.                     inputElement.removeClass('uv-field-error');
  2590.                     inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
  2591.                     if (currentElement.is('li') || (e.which === 13 && text)) {
  2592.                         if(text.length <= 20) {
  2593.                             if(labelCollection.isLabelExist(text)) {
  2594.                                 var self = this;
  2595.                                 inputElement.val('');
  2596.                                 this.model = new LabelModel();
  2597.                                 this.model.set({name:text});
  2598.                                 self = this;
  2599.                                 app.appView.showLoader();
  2600.                                 this.model.save({}, {
  2601.                                     success: function (model, response, options) {
  2602.                                         inputElement.parent().find("li:not(.uv-no-results)").remove()
  2603.                                         inputElement.parent().find(".uv-no-results").show()
  2604.                                         if(!currentElement.is('li')) {
  2605.                                             inputElement.trigger('click')
  2606.                                         }
  2607.                                         if(response.alertClass == "success") {
  2608.                                             labelCollection.add(model);
  2609.                                             self.render();
  2610.                                         }
  2611.                                         app.appView.hideLoader();
  2612.                                         app.appView.renderResponseAlert(response);
  2613.                                     },
  2614.                                     error: function (model, xhr, options) {
  2615.                                         if(url = xhr.getResponseHeader('Location'))
  2616.                                             window.location = url;
  2617.                                         var response = warningResponse;
  2618.                                         if(xhr.responseJSON)
  2619.                                             response = xhr.responseJSON;
  2620.                                         app.appView.hideLoader();
  2621.                                         app.appView.renderResponseAlert(response);
  2622.                                     }
  2623.                                 });
  2624.                             } else {
  2625.                                 inputElement.addClass('uv-field-error');
  2626.                                 inputElement.parents('.uv-element-block').append("<span class='uv-field-message'>{{ 'Label with same name already exist'|trans }}</span>");
  2627.                             }
  2628.                         } else {
  2629.                             inputElement.addClass('uv-field-error');
  2630.                             inputElement.parents('.uv-element-block').append("<span class='uv-field-message'>{{ 'Text length should be less than 20 charactors'|trans }}</span>");
  2631.                         }
  2632.                     }
  2633.                 },
  2634.                 removeErrorClass: function(e) {
  2635.                     var inputElement = Backbone.$(e.currentTarget);
  2636.                     inputElement.removeClass('uv-field-error');
  2637.                     inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
  2638.                 },
  2639.             });
  2640.             // Ticket Router
  2641.             var Router = Backbone.Router.extend({
  2642.                 routes: {
  2643.                     'thread/:thread' : 'threadRequestedId'
  2644.                 },
  2645.                 threadRequestedId: function(thread){
  2646.                     threadCollection.threadRequestedId = thread;
  2647.                 },
  2648.                 scrollPage : function(divId) {
  2649.                     if($(divId).length){
  2650.                         $('li a[href="'+divId+'"]').trigger('click');
  2651.                         $('.uv-ticket-scroll-region').animate({
  2652.                             scrollTop: $(divId).offset().top
  2653.                         }, 'slow');
  2654.                     } else if(divId == '#') { //scroll to last thread added
  2655.                         if(threadCollection.fullCollection.length)
  2656.                             this.scrollPage('#thread' + threadCollection.fullCollection.at(0).id);
  2657.                     }
  2658.                 }
  2659.             });
  2660.             var customerForm = new CustomerForm({
  2661.                 el : $(".uv-main-info-update-block"),
  2662.                 model : new CustomerModel()
  2663.             });
  2664.             var ticketNavigation = $.parseJSON('{{ ticketNavigationIteration|json_encode|raw }}');
  2665.             var ticketModel = new TicketModel({
  2666.                 id : "{{ ticket.id }}",
  2667.                 status : "{{ ticket.status.id }}",
  2668.                 priority : "{{ ticket.priority.id }}",
  2669.                 group : "{{ ticket.supportGroup ? ticket.supportGroup.id : '' }}",
  2670.                 subGroup : "{{ ticket.supportTeam ? ticket.supportTeam.id : '' }}",
  2671.                 agent : "",
  2672.                 profileImage : "",
  2673.                 isTrashed : "{{ ticket.isTrashed }}"
  2674.             });
  2675.             ticketApp.ticketView = ticketView = new TicketView({
  2676.                 model: ticketModel
  2677.             });
  2678.             uvdesk.ticket.model = ticketModel;
  2679.             threadCollection = new ThreadCollection();
  2680.             var threadList = new ThreadList();
  2681.             var pagination = new Pagination();
  2682.             var collaboratorCollection = new CollaboratorCollection($.parseJSON('{{ ticket_service.getTicketCollaborators(ticket.id)|json_encode|raw }}'));
  2683.             var collaboratorList = new CollaboratorList();
  2684.             collaboratorList.render();
  2685.             var tagCollection = new TagCollection($.parseJSON('{{ ticket_service.getTicketTagsById(ticket.id)|json_encode|raw }}'));
  2686.             var tagListView = new TagList();
  2687.             tagListView.render();
  2688.             var labelCollection = new LabelCollection($.parseJSON('{{ ticket_service.getTicketLabels(ticket.id)|json_encode|raw }}'));
  2689.             var labelListView = new LabelList();
  2690.             labelListView.render();
  2691.             var router = new Router();
  2692.             Backbone.history.start({push_state:true});
  2693.             threadCollection.syncData();
  2694.         });
  2695.     </script>
  2696.     <script>
  2697.         var sfTinyMceNew = $.extend({}, sfTinyMce);
  2698.         var toolbarOptions = sfTinyMce.options.toolbar;
  2699.         sfTinyMce.init({
  2700.             selector : '.uv-ticket-reply textarea',
  2701.             toolbar: toolbarOptions + ' | translate',
  2702.             mentions : getMentions(),
  2703.             images_upload_url: "",
  2704.             setup: function(editor) {
  2705.                 editor.on('keydown', function(e) { /** for pageup, pagedown keys **/
  2706.                     if(e.keyCode == 34 || e.keyCode == 33){
  2707.                         e.preventDefault();
  2708.                     }
  2709.                 });
  2710.                 addTranslateButton(editor);
  2711.             }
  2712.         });
  2713.         function InitTinyMce(selector) {
  2714.             let sfTinyMceNew2 = $.extend({}, sfTinyMceNew);
  2715.             sfTinyMceNew2.init({
  2716.                 selector : selector,
  2717.                 mentions : getMentions(),
  2718.                 setup: function(editor) {
  2719.                     addTranslateButton(editor);
  2720.                 }
  2721.             });
  2722.         }
  2723.         function getMentions(){
  2724.             return {
  2725.                 delimiter: ['#'],
  2726.                 items: 15,
  2727.                 source: function(){
  2728.                     return [
  2729.                         {
  2730.                             name : "{{ 'Ticket Id'|trans }}",
  2731.                             value : "{{ ticket.id }}",
  2732.                         },
  2733.                         {
  2734.                             name : "{{ 'Subject'|trans }}",
  2735.                             value : "{{ ticket.subject|replace({"\n":' ', "\r":' '}) }}",
  2736.                         },
  2737.                         {
  2738.                             name : "{{ 'Status'|trans }}",
  2739.                             value : "{{ ticket.status.description }}",
  2740.                         },
  2741.                         {
  2742.                             name : "{{ 'Priority'|trans }}",
  2743.                             value : "{{ ticket.priority.description|trans }}",
  2744.                         },
  2745.                         {
  2746.                             name : "{{ 'Type'|trans }}",
  2747.                             value : "{{ ticket.type ? ticket.type.description : 'Not Assigned'|trans }}",
  2748.                         },
  2749.                         {
  2750.                             name : "{{ 'Group'|trans }}",
  2751.                             value : "{{ ticket.supportGroup ? ticket.supportGroup.description : 'Not Assigned'|trans }}",
  2752.                         },
  2753.                         {
  2754.                             name : "{{ 'Team'|trans }}",
  2755.                             value : "{{ ticket.supportTeam ? ticket.supportTeam.description : 'Not Assigned'|trans }}",
  2756.                         },
  2757.                         {
  2758.                             name : "{{ 'Customer Name'|trans }}",
  2759.                             value : "{{ customer.name }}",
  2760.                         },
  2761.                         {
  2762.                             name : "{{ 'Customer Email'|trans }}",
  2763.                             value : "{{ customer.email }}",
  2764.                         },
  2765.                         {
  2766.                             name : "{{ 'Agent Name'|trans }}",
  2767.                             value : "{{ ticketAgent.name is defined ? ticketAgent.name : 'Not Assigned'|trans }}",
  2768.                         },
  2769.                         {
  2770.                             name : "{{ 'Agent Email'|trans }}",
  2771.                             value : "{{ ticketAgent.email is defined ? ticketAgent.email : 'Not Assigned'|trans }}",
  2772.                         }
  2773.                     ];
  2774.                 },
  2775.                 insert: function(item) {
  2776.                     return '<span>' + item.value + '</span>';
  2777.                 }
  2778.             };
  2779.         }
  2780.     </script>
  2781. {% endblock %}