{% extends "@UVDeskCoreFramework//Templates//layout.html.twig" %}
{% block title %}{{ '#' ~ ticket.id ~ ' ' ~ ticket.subject }}{% endblock %}
{% block templateCSS %}
<style>
.uv-aside-ticket-labels.label-list-block .uv-btn-label {
cursor: pointer;
}
.uv-main-info-update-block .uv-element-block {
margin: 10px 0px !important;
}
.uv-tab-ellipsis {
position: relative;
}
.uv-inner-section .uv-view .uv-ticket-section .uv-ticket-accordion .uv-ticket-wrapper {
display: block;
}
.uv-element-block.cc-bcc .uv-dropdown-container {
padding: 10px 20px 10px 20px;
}
.uv-action-buttons .uv-dropdown-list ul li {
padding: 5px 0px !important;
}
.uv-action-buttons{
margin-bottom: 40px !important;
}
.uv-ticket-reply .uv-element-block-textarea, .thread-edit-container .uv-element-block-textarea {
width: 100% !important;
max-width: 100% !important;
}
.thread-edit-container .uv-field-message {
color: #FF5656 !important;
}
.uv-element-block .mce-tinymce {
margin-top: 10px;
}
.uv-ticket-reply .uv-element-block-textarea .uv-field-message, .thread-edit-container .uv-element-block-textarea .uv-field-message {
margin-top: 15px;
}
.thread-edit-container {
margin-top: 10px;
}
.uv-ticket-viewer-bar{
transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
height: 0px;
}
.uv-ticket-viewer-bar.active{
height: 50px;
margin-bottom: 10px;
border-bottom: 1px dotted #f97278;
}
.uv-ticket-viewer-single {
display: inline-block;
margin-right: 5px;
}
.uv-ticket-viewer-single img {
width: 40px;
border-radius: 3px;
display: inline-block;
vertical-align: middle;
}
.uv-ticket-viewer-single.uv-first {
width: 40px;
height: 40px;
background-image: linear-gradient(to right, #f97278 0%, #f181bf 100%);
text-align: center;
vertical-align: top;
line-height: 30px;
border-radius: 20px;
}
.uv-ticket-viewer-close {
position: absolute;
top: 0px;
width: 40px;
height: 40px;
background: #f1f1f1;
text-align: center;
line-height: 35px;
border-radius: 2px;
opacity: .6;
text-indent: 6px;
}
.uv-ticket-viewer-list {
display: inline;
}
span.viewer-firstletter.img-thumbnail {
width: 40px;
height: 40px;
display: block;
text-align: center;
font-size: 20px;
font-style: italic;
border: 1px dotted;
border-radius: 4px;
line-height: 35px;
}
.uv-ticket-viewer-close {
display:none;
}
.uv-ticket-viewer-single:hover .uv-ticket-viewer-close {
display: block;
}
.uv-hide{
display: none;
}
.uv-info{
background: #7C70F4;
}
.uv-ticket-viewer-list .uv-icon-eye-light{
animation: jelly 0.8s infinite alternate ease-in-out;
}
.uv-aside-brick .uv-loader {
position: absolute;
transform: scale(0.5);
top: 22px;
right: 45px;
}
.uv-app-glyph-customfields {
width: 20px;
height: 20px;
background-position: center center;
background-repeat: no-repeat;
cursor: pointer;
display: inline-block;
vertical-align: middle;
margin: 5px 0px 5px 10px;
background-image: url("{{ asset('bundles/uvdeskcoreframework/images/app-glyph-custom.svg') }}");
}
.uv-no-threads {
padding: 80px 20px;
text-align: center;
}
.uv-ticket-strip-label {
position: relative;
}
input.input-copy-thread-link {
position: absolute;
bottom: 10px;
width: 400px;
}
.uv-ticket-action-bar-fixed{
position: fixed;
width: 100%;
background: #fff;
z-index: 999;
}
.uv-ticket-action-bar-fixed .uv-ticket-action-bar-rt{
position: fixed;
right: 0px;
margin-top: 10px;
}
.uv-ticket-action-bar-fixed + .uv-ticket-viewer-bar{
margin-top: 70px;
}
.uv-ticket-main {
word-wrap: break-word;
}
@media only screen and (max-width: 900px) {
.uv-ticket-action-bar-fixed{
position: relative;
}
.uv-ticket-action-bar-fixed + .uv-ticket-viewer-bar{
margin-top: 0px;
}
.uv-ticket-action-bar-fixed .uv-ticket-action-bar-rt{
position: relative;
}
}
.uv-icon-pin {
width: 18px;
height: 18px;
display: inline-block;
vertical-align: middle;
background-image: url("{{ asset('bundles/uvdeskcoreframework/images/uvdesk-sprite.svg') }}");
background-position: 0px -396px;
transition: transform .15s;
transform: scale(1);
}
.uv-icon-pinned {
background-position: -19px -396px;
}
.uv-header-fix{
display: inline-block;
margin: 0px 10px 0px 5px;
}
.uv-header-fix + .uv-tabs{
display: inline-block;
}
.uv-ticket-section span.uv-mail-status {
width: 16px;
height: 16px;
background: url('../../../../../bundles/webkuldefault/images/mail-status.png');
cursor: help;
}
.uv-ticket-section .uv-mail-status.uv-mail-processed {
background-position: 0 0;
}
.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 {
background-position: -38px 0;
}
.uv-ticket-section .uv-mail-status.uv-mail-spam,.uv-ticket-section .uv-mail-status.uv-mail-deferred,.uv-ticket-section .uv-mail-spamreport {
background-position: -55px 0;
}
.uv-ticket-section .uv-mail-status.uv-mail-bounce,.uv-ticket-section .uv-mail-status.uv-mail-dropped {
background-position: -73px 0;
}
@media only screen and (max-width: 1480px) {
.uv-inner-section .uv-view .uv-ticket-action-bar-fixed.uv-ticket-action-bar .uv-ticket-action-bar-rt{
width: auto;
}
}
@media only screen and (max-width: 1300px) {
.uv-header-fix{
margin: 0px 10px 0px 10px;
}
}
@media only screen and (max-width: 900px) {
.uv-ticket-action-bar-fixed{
position: relative;
}
.uv-ticket-action-bar-fixed + .uv-ticket-viewer-bar{
margin-top: 0px;
}
.uv-ticket-action-bar-fixed .uv-ticket-action-bar-rt{
position: relative;
}
.uv-inner-section .uv-view .uv-ticket-action-bar.uv-ticket-action-bar-fixed .uv-ticket-action-bar-lt{
width: 70%;
}
.uv-inner-section .uv-view .uv-ticket-action-bar.uv-ticket-action-bar-fixed .uv-ticket-action-bar-rt {
width: 21%;
padding-right: 33px;
}
.uv-header-fix{
display: none;
}
}
.uv-inner-section .uv-view .uv-ticket-scroll-region {
margin-bottom: 0px;
}
.uv-inner-section .uv-view .uv-ticket-action-bar.uv-ticket-action-bar-fixed .uv-ticket-action-bar-rt {
width: 21%;
padding-right: 33px;
}
@media print {
.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 {
display: none !important;
}
.uv-ticket-scroll-region {
overflow: visible;
margin-bottom: 0 !important;
}
.uv-paper {
padding-left: 0px !important; /* uv-view */
}
.uv-wrapper {
left: 0 !important;
margin: 0 !important;
}
.uv-inner-section .uv-view .uv-ticket-scroll-region .uv-ticket-main-rt {
width: 80%;
}
.uv-paper,.uv-view ,.uv-ticket-scroll-region, .uv-wrapper {
position: initial !important;
}
}
.uv-ticket-action-bar-rt .app-glyph {
display: inline-block;
vertical-align: middle;
margin-right: 10px;
cursor: pointer;
height: 20px;
width: 20px;
}
.uv-ticket-action-bar-rt .app-glyph:last-child {
margin-right: 0px;
}
blockquote {
background: #f9f9f9;
border-left: 4px solid #ccc;
margin: 1.5em 10px;
padding: 0.5em 10px;
quotes: "\201C""\201D""\2018""\2019";
}
blockquote:before {
color: #ccc;
content: open-quote;
font-size: 3em;
line-height: 0.1em;
margin-right: 0.05em;
vertical-align: -0.4em;
}
blockquote p {
display: inline;
}
.uv-dropdown-list ul li {
padding : 8px 0px !important;
}
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
}
::-webkit-scrollbar-thumb {
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
}
.uv-aside-select.search .uv-dropdown-list.uv-bottom-left, .uv-aside-select .uv-dropdown-list.uv-bottom-right {
top: 25px;
width: 100%;
}
.uv-aside-select.search .uv-dropdown-list ul{
padding: 0px 10px;
}
.uv-aside-select.search .uv-dropdown-container {
padding: 8px 10px 4px;
overflow-y: auto;
max-height: 280px;
border-bottom: solid 1px #D3D3D3;
}
.uv-aside-select.search .uv-dropdown-list ul.uv-agents-list li {
border-bottom: solid 1px #D3D3D3;
border-top:0px;
}
.uv-search-inline{
width: 100%;
}
.uv-dropdown-list ul.uv-search-list li:first-child {
border-top: none;
}
.uv-search-sm input.uv-search-field {
border: solid 1px #B1B1AE;
border-radius: 3px;
color: #333333;
font-size: 15px;
box-sizing: border-box;
padding: 7px 10px 9px 33px;
width: 100%;
}
</style>
{% endblock %}
{% block pageContent %}
<div class="uv-inner-section">
{# Ticket Sidebar #}
<div class="uv-aside" {% if app.request.cookies and app.request.cookies.get('uv-asideView') %}style="display: none;"{% endif %} >
<div class="uv-main-info-block">
<div class="uv-aside-head">
<div class="uv-aside-title">
<h6>{{ 'Ticket'|trans }} #{{ ticket.id }}</h6>
</div>
<div class="uv-aside-back">
<span onclick="history.length > 1 ? history.go(-1) : window.location = '{{ path("helpdesk_member_ticket_collection") }}';">{{ 'Back'|trans }}</span>
</div>
</div>
{# Ticket Information #}
<div class="uv-aside-brick">
{# Customer Details #}
<div class="uv-aside-customer-block">
<h3>{{ 'Customer Information'|trans }}</h3>
<div class="uv-aside-avatar">
{% if customer.thumbnail %}
<img src="{{ app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') }}{{ customer.thumbnail }}">
{% else %}
<img src="{{ asset(default_customer_image_path) }}">
{% endif %}
</div>
<div class="uv-aside-customer-info">
<span>{{ customer.name }}</span>
<span>{{ customer.email }}</span>
{% if customer.contactNumber %}
<span>{{ customer.contactNumber }}</span>
{% endif %}
{% if user_service.isAccessAuthorized('ROLE_AGENT_MANAGE_CUSTOMER') %}
<span class="uv-customize" data-toggle="tooltip" title="Edit Customer Information"></span>
{% endif %}
</div>
</div>
{# Ticket Details #}
<div class="uv-aside-ticket-block">
<div class="uv-aside-ticket-brick">
<h3>{{ 'Total Replies'|trans }}</h3>
<span class="uv-icon-replies"></span> <span>{{ totalReplies }}</span>
</div>
<div class="uv-aside-ticket-brick">
<h3>{{ 'TimeStamp'|trans }}</h3>
<span class="uv-icon-timestamp"></span> <span>{{ ticket_service.timeZoneConverter(initialThread.createdAt) }}</span>
</div>
<div class="uv-aside-ticket-brick">
<h3>{{ 'Channel'|trans }}</h3>
{% if ticket.source == 'email' %}
<span class="uv-icon-channel uv-channel-email"></span> <span>{{ 'Email'|trans }}</span>
{% elseif ticket.source == 'formbuilder' %}
<span class="uv-icon-channel uv-channel-form"></span> <span>{{ 'Formbuilder'|trans }}</span>
{% else %}
<span class="uv-icon-channel uv-channel-web"></span> <span>{{ 'Website'|trans }}</span>
{% endif %}
</div>
</div>
</div>
</div>
{# Edit Customer Info #}
{% if user_service.isAccessAuthorized('ROLE_AGENT_MANAGE_CUSTOMER') %}
<div class="uv-main-info-update-block uv-no-error-success-icon" style="display: none">
<div class="uv-aside-head">
<div class="uv-aside-title"><h6>{{ 'Edit Customer'|trans }}</h6></div>
<div class="uv-aside-back"><span>{{ 'Back'|trans }}</span></div>
</div>
<div class="uv-aside-brick">
<form method="post">
<input class="uv-field" name="id" type="hidden" value="{{ customer.id }}">
<div class="uv-element-block">
<label class="uv-field-label">{{ 'Name'|trans }}</label>
<div class="uv-field-block">
<input class="uv-field" name="name" type="text" value="{{ customer.name }}">
</div>
</div>
<div class="uv-element-block">
<label class="uv-field-label">{{ 'Email'|trans }}</label>
<div class="uv-field-block">
<input class="uv-field" name="email" type="text" value="{{ customer.email }}">
</div>
</div>
<div class="uv-element-block">
<label class="uv-field-label">{{ 'Contact Number'|trans }}</label>
<div class="uv-field-block">
<input class="uv-field" name="contactNumber" type="text" value="{{ customer.contactNumber }}">
</div>
</div>
<div class="uv-action-buttons">
<a class="uv-btn update-btn" href="#">{{ 'Update'|trans }}</a>
<a class="uv-btn cancel-btn" href="#">{{ 'Cancel'|trans }}</a>
</div>
<input type="hidden" name="_token" value="{{ csrf_token_generator.refreshToken('') }}"/>
</form>
</div>
</div>
{% endif %}
{# Edit Ticket #}
<div class="uv-aside-brick">
<div class="uv-aside-ticket-actions">
{# Update Ticket Agent #}
<div class="uv-aside-select search">
<label class="uv-aside-select-label">{{ 'Agent'|trans }}</label>
<div>
{% set agentName = ticketAgent ? ticketAgent.name : 'Not Assigned'|trans %}
{% if ticket.isTrashed == false and user_service.isAccessAuthorized('ROLE_AGENT_ASSIGN_TICKET') %}
<span class="uv-aside-select-value uv-dropdown-other uv-aside-drop-icon" data-id="{{ ticketAgent ? ticketAgent.id : '' }}">{{ agentName }}</span>
<div class="uv-dropdown-list uv-bottom-left">
<div class="uv-dropdown-container">
<label>{{ 'Agent'|trans }}</label>
<div class="uv-search-sm">
<input type="text" class="uv-search-field uv-search-inline" placeholder="{{ 'Search'|trans }}">
</div>
</div>
<ul class="uv-agents-list agent" data-action="agent">
{% for agent in user_service.getAgentPartialDataCollection() %}
<li data-index="{{ agent.id }}">
<img src="{{ agent.smallThumbnail != null ? app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') ~ agent.smallThumbnail : asset(default_agent_image_path) }}"/> {{ agent.name }}
</li>
{% endfor %}
</ul>
</div>
{% else %}
<span class="uv-aside-select-value">{{ agentName }}</span>
{% endif %}
</div>
</div>
{# Update Ticket Priority #}
<div class="uv-aside-select">
<label class="uv-aside-select-label">{{ 'Priority'|trans }}</label>
<div>
<span class="uv-list-ticket-priority" style="background: {{ ticket.priority.colorCode }}"></span>
{% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_PRIORITY') %}
<span class="uv-aside-select-value uv-dropdown-other uv-aside-drop-icon" data-id="{{ ticket.priority.id }}">{{ ticket.priority.description|trans }}</span>
<div class="uv-dropdown-list uv-bottom-left">
<div class="uv-dropdown-container">
<label>{{ 'Priority'|trans }}</label>
<ul class="priority" data-action="priority">
{% for priority in ticketPriorityCollection %}
<li data-index="{{ priority.id }}" data-color="{{ priority.colorCode }}"><a href="#">{{ priority.description|trans }}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% else %}
<span class="uv-aside-select-value">
{{ ticket.priority.description|trans }}
</span>
{% endif %}
</div>
</div>
{# Update Ticket Status #}
<div class="uv-aside-select">
<label class="uv-aside-select-label">{{ 'Status'|trans }}</label>
<div>
{% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}
<span class="uv-aside-select-value uv-dropdown-other uv-aside-drop-icon" data-id="{{ ticket.status.id }}">{{ ticket.status.description|trans }}</span>
<div class="uv-dropdown-list uv-bottom-left">
<div class="uv-dropdown-container">
<label>{{ 'Status'|trans }}</label>
<ul class="status" data-action="status">
{% for status in ticketStatusCollection %}
<li data-index="{{ status.id }}"><a href="#">{{ status.description|trans }}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% else %}
<span class="uv-aside-select-value">{{ ticket.status.description|trans }}</span>
{% endif %}
</div>
</div>
{# Update Ticket Type #}
<div class="uv-aside-select search">
<label class="uv-aside-select-label">{{ 'Type'|trans }}</label>
<div>
{% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_TYPE') %}
<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>
<div class="uv-dropdown-list uv-bottom-left">
<div class="uv-dropdown-container">
<label>{{ 'Type'|trans }}</label>
<div class="uv-search-sm">
<input type="text" class="uv-search-field uv-search-inline" placeholder="{{ 'Search'|trans }}">
</div>
</div>
<ul class="uv-search-list type" data-action="type">
{% for type in ticket_service.getTypes() %}
<li data-index="{{ type.id }}"><a href="#">{{ type.name }}</a></li>
{% endfor %}
</ul>
</div>
{% else %}
<span class="uv-aside-select-value">
{{ ticket.type ? ticket.type.code : 'Not Assigned'|trans }}
</span>
{% endif %}
</div>
</div>
{# Update Ticket Support Group #}
<div class="uv-aside-select search">
<label class="uv-aside-select-label">{{ 'Group'|trans }}</label>
<div>
{% if user_service.isAccessAuthorized('ROLE_AGENT_ASSIGN_TICKET_GROUP') %}
<span class="uv-aside-select-value uv-dropdown-other uv-aside-drop-icon" data-id="{{ ticket.supportGroup ? ticket.supportGroup.id : '-- --' }}">
{{ ticket.supportGroup ? ticket.supportGroup.name : 'Not Assigned'|trans }}
</span>
<div class="uv-dropdown-list uv-bottom-left">
<div class="uv-dropdown-container">
<label>{{ 'Group'|trans }}</label>
<div class="uv-search-sm">
<input type="text" class="uv-search-field uv-search-inline" placeholder="{{ 'Search'|trans }}">
</div>
</div>
<ul class="uv-search-list group" data-action="group">
<li data-index=""><a href="#">{{ 'Not Assigned'|trans }}</a></li>
{% for group in supportGroupCollection %}
<li data-index="{{ group.id }}"><a href="#">{{ group.name }}</a></li>
{% endfor %}
</ul>
</div>
{% else %}
<span class="uv-aside-select-value">
{{ ticket.supportGroup ? ticket.supportGroup.name : 'Not Assigned'|trans }}
</span>
{% endif %}
</div>
</div>
{# Update Ticket Support Team #}
<div class="uv-aside-select search">
<label class="uv-aside-select-label">{{ 'Team'|trans }}</label>
<div>
{% if user_service.isAccessAuthorized('ROLE_AGENT_ASSIGN_TICKET_GROUP') %}
<span class="uv-aside-select-value uv-dropdown-other uv-aside-drop-icon" data-id="{{ ticket.supportTeam ? ticket.supportTeam.id : '-- --' }}">
{{ ticket.supportTeam ? ticket.supportTeam.name : 'Not Assigned'|trans }}
</span>
<div class="uv-dropdown-list uv-bottom-left">
<div class="uv-dropdown-container">
<label>{{ 'Team'|trans }}</label>
<div class="uv-search-sm">
<input type="text" class="uv-search-field uv-search-inline" placeholder="{{ 'Search'|trans }}">
</div>
</div>
<ul class="uv-search-list team" data-action="team">
<li data-index=""><a href="#">{{ 'Not Assigned'|trans }}</a></li>
{% for team in supportTeamCollection %}
<li data-index="{{ team.id }}"><a href="#">{{ team.name }}</a></li>
{% endfor %}
</ul>
</div>
{% else %}
<span class="uv-aside-select-value">
{{ ticket.supportTeam ? ticket.supportTeam.name : 'Not Assigned'|trans }}
</span>
{% endif %}
</div>
</div>
</div>
</div>
{# Ticket Labels #}
<div class="uv-aside-brick">
<div class="uv-aside-ticket-labels label-list-block">
<div class="uv-element-block">
<label class="uv-field-label">{{ 'Labels'|trans }}</label>
<div class="uv-field-block">
<input class="uv-field uv-dropdown-other" type="text" data-type="label">
<div class="uv-dropdown-list uv-top-left">
<div class="uv-dropdown-container">
<label>{{ 'Filter With'|trans }}</label>
<ul class="">
<span class="uv-filter-info">{{ 'Type atleast 2 letters'|trans }}</span>
<span class="uv-no-results" style="display: none;">{{ 'No result found'|trans }}</span>
</ul>
</div>
</div>
</div>
</div>
<div class="label-list"></div>
</div>
</div>
{# Ticket Collaborators #}
<div class="uv-aside-brick collaborator-list-block">
<div class="uv-aside-ticket-labels">
<div class="uv-element-block">
<label class="uv-field-label">{{ 'Collaborators'|trans }}</label>
{% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_COLLABORATOR_TO_TICKET') %}
<div class="uv-field-block">
<input class="uv-field" type="text" name="email" type="text" value="" placeholder="{{ 'Type email to add'|trans }}">
</div>
{% endif %}
</div>
<div class="collaborator-list" style="margin-top: 10px"></div>
</div>
</div>
{# Ticket Tags #}
<div class="uv-aside-brick tag-list-block">
<div class="uv-aside-ticket-labels">
<div class="uv-element-block">
<label class="uv-field-label">{{ 'Tags'|trans }}</label>
{% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_TAG') %}
<div class="uv-field-block">
<input class="uv-field uv-dropdown-other" name="tag-name" type="text" data-type="tag" value="">
<div class="uv-dropdown-list uv-bottom-left">
<div class="uv-dropdown-container">
<label>{{ 'Filter With'|trans }}</label>
<ul class="">
<span class="uv-filter-info">{{ 'Type atleast 2 letters'|trans }}</span>
<span class="uv-no-results" style="display: none;">{{ 'No result found'|trans }}</span>
</ul>
</div>
</div>
</div>
{% endif %}
</div>
<div class="tag-list" style="margin-top: 10px"></div>
</div>
</div>
</div>
<div class="uv-view {% if app.request.cookies and app.request.cookies.get('uv-asideView') %}uv-aside-view{% endif %}" >
<div class="uv-ticket-scroll-region {% if app.request.cookies and app.request.cookies.get('uv-asideView') %}uv-aside-view-tv{% endif %}" >
{# Ticket Header CTA #}
<div class="uv-ticket-action-bar">
<div class="uv-ticket-action-bar-lt">
<div class="uv-header-fix"><a href="#" class="uv-icon-pin"></a></div>
{# Thread Actions #}
<div class="uv-tabs">
<ul>
{# Filter Threads #}
<li for="default" data-type="all" class="uv-tab-active">{{ 'All Threads'|trans }}</li>
<li for="default" data-type="reply">{{ 'Replies'|trans }}</li>
<li for="default" data-type="forward">{{ 'Forwards'|trans }}</li>
<li for="default" data-type="note">{{ 'Notes'|trans }}</li>
<li for="default" data-type="pinned">{{ 'Pinned'|trans }}</li>
{# Update Threads #}
{% if user_service.isAccessAuthorized('ROLE_AGENT_EDIT_TICKET') or user_service.isAccessAuthorized('ROLE_AGENT_DELETE_TICKET') %}
<li class="uv-tab-ellipsis uv-ticket-action">
<span class="uv-icon-ellipsis uv-dropdown-other"></span>
<div class="uv-dropdown-list uv-bottom-right">
<div class="uv-dropdown-container">
<ul class="priority" data-action="priority">
{% if user_service.isAccessAuthorized('ROLE_AGENT_EDIT_TICKET') %}
<li data-action="edit" class="uv-open-popup" data-target="edit-ticket-modal">{{ 'Edit Ticket'|trans }}</li>
{% endif %}
<li data-action="print">{{ 'Print Ticket'|trans }}</li>
{% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}
<li data-action="spam" data-index="6">{{ 'Mark as Spam'|trans }}</li>
<li data-action="closed" data-index="5">{{ 'Mark as Closed'|trans }}</li>
{% endif %}
{% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_TICKET') %}
<li data-action="delete" class="uv-text-danger">{{ 'Delete Ticket'|trans }}</li>
{% endif %}
</ul>
</div>
</div>
</li>
{% endif %}
</ul>
</div>
</div>
<div class="uv-ticket-action-bar-rt">
{{ uvdesk_extensibles.getRegisteredComponent("Webkul\\UVDesk\\CoreFrameworkBundle\\Tickets\\WidgetCollection").embedSideFilterIcons()|raw }}
</div>
</div>
{# Ticket Active Users #}
<div class="uv-ticket-viewer-bar">
<div class="uv-ticket-viewer-list">
<div class="uv-ticket-viewer-single uv-first" title="Currently active agents on ticket...">
<span class="uv-icon-eye-light"></span>
</div>
</div>
</div>
{# Ticket Header #}
<div class="uv-ticket-head">
<div class="uv-ticket-head-lt">
<span class="uv-star-large {{ ticket.isStarred ? 'uv-star-active' : '' }} uv-star uv-margin-right-5"></span>
</div>
<div class="uv-ticket-head-rt">
<h1>{{ ticket.subject }}</h1>
</div>
</div>
<div class="uv-ticket-strip">
<span>
<span class="uv-ticket-strip-label">{{ 'Created'|trans }} - </span>
<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>
</span>
<span>
<span class="uv-ticket-strip-label">{{ 'By'|trans }} - </span> {{ initialThread.user.name }}
{% if totalCustomerTickets %}
(<a id="more-tickets-btn" href="{{ path('helpdesk_member_ticket_collection') }}#customer/{{customer.id}}" target="_blank">{{ 'count more tickets'|trans({'count': totalCustomerTickets}) }}</a>)
{% endif %}
</span>
<span class="agent-info" style="{{ ticketAgent ? '' : 'display: none' }}">
<span class="uv-ticket-strip-label">{{ 'Agent'|trans }} - </span>
<span class="name">{{ ticketAgent ? ticketAgent.name : '' }}</span>
</span>
</div>
{# Thread Tab View #}
<div class="uv-tab-view uv-tab-view-active" id="default">
<div class="uv-ticket-section">
<div class="uv-ticket-main create">
<div class="uv-ticket-strip">
<span>
<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>
- {{ initialThread.user.name }} <span class="uv-ticket-strip-label">{{ 'created Ticket'|trans }}</span>
</span>
{% if initialThread.cc != '' %}
<div class="uv-ticket-strip">
<span><span class="uv-ticket-strip-label">{{ 'CC'|trans }} -</span> {{ initialThread.cc }}</span>
</div>
{% endif %}
</div>
<div class="uv-ticket-main-lt">
<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) }}">
</div>
<div class="uv-ticket-main-rt">
{% if initialThread.createdBy == 'customer' %}
<a href="{{ path('helpdesk_member_manage_customer_account') }}/{{ initialThread.user.id}}" class="uv-ticket-member-name">{{ initialThread.user.name }}</a>
{% else %}
{% if initialThread.user %}
<a href="{{ path('helpdesk_member_account') }}/{{ initialThread.user.id}}" class="uv-ticket-member-name">{{ initialThread.user.name }}</a>
{% else %}
<a class="uv-ticket-member-name">{{ initialThread.user.name }}</a>
{% endif %}
{% endif %}
{# Ticket Message #}
<div class="message">
<p>
{% if initialThread.message|striptags == initialThread.message %}
{{ initialThread.message|nl2br }}
{% else %}
{{ initialThread.message|raw }}
{% endif %}
</p>
</div>
{# Ticket Attachments #}
{% if initialThread.attachments|length %}
<div class="uv-ticket-uploads">
<h4>{{ 'Uploaded Files'|trans }}</h4>
<div class="uv-ticket-uploads-strip">
{% for attachment in initialThread.attachments %}
<a href="{{ attachment.downloadURL }}" target = "_blank" class="uv-ticket-uploads-brick uv-no-pointer-events" data-toggle="tooltip" title="{{ attachment.name }}">
<img src="{{ attachment.iconURL }}" class="uv-auto-pointer-events"/>
</a>
{% endfor %}
</div>
{% if initialThread.attachments|length > 1 %}
<div class="uv-upload-actions">
<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>
{% if initialThread.attachments|length %}
<a href="{{ path('helpdesk_member_ticket_download_attachment_zip') }}/{{ initialThread.id }}" target="_blank"><span class="uv-icon-attachment"></span> Download (as .zip)</a>
{% endif %}
</div>
{% endif %}
</div>
{% endif %}
</div>
</div>
<div class="uv-ticket-accordion">
<div class="uv-ticket-count-wrapper">
<span class="uv-ticket-count-stat">{{ totalReplies }}</span>
</div>
<div class="uv-ticket-wrapper thread-list"></div>
</div>
</div>
</div>
{# Reply Ticket View #}
<div class="uv-ticket-main uv-ticket-reply uv-no-error-success-icon">
<div class="uv-ticket-main-lt">
<span class="uv-icon-ellipsis"></span>
<img src="{{ currentUserDetails.thumbnail ? app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') ~ currentUserDetails.thumbnail : asset(default_agent_image_path) }}" />
</div>
<div class="uv-ticket-main-rt">
<span class="uv-ticket-member-name">{{ currentUserDetails.name }}</span>
<div class="uv-tabs">
<ul>
<li for="reply" class="uv-tab-active">{{ 'Reply'|trans }}</li>
<li for="forward">{{ 'Forward'|trans }}</li>
{% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_NOTE') %}
<li for='note'>{{ 'Note'|trans }}</li>
{% endif %}
</ul>
</div>
{# Ticket Thread | Add Reply #}
<div class="uv-tab-view uv-tab-view-active" id="reply">
<form enctype="multipart/form-data" method="post" action="{{ path('helpdesk_member_add_ticket_thread', {'ticketId': ticket.id }) }}">
<input name="threadType" value="reply" type="hidden">
<input name="status" value="" type="hidden" {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}class="reply-status"{% endif %}>
<div class="uv-element-block collaborators" style="display: none">
<label class="uv-field-label">{{ 'Collaborators'|trans }}</label>
<div class="uv-field-block"></div>
</div>
<div class="uv-element-block cc-bcc">
<label>
<div class="uv-checkbox">
<input type="checkbox" class="cc-bcc-toggle">
<span class="uv-checkbox-view"></span>
</div>
<span class="uv-checkbox-label">CC/BCC</span>
</label>
<div class="uv-field-block" style="display: none">
<div class="uv-group">
<input class="uv-group-field uv-dropdown-other preloaded uv-manual-enter" type="text">
<div class="uv-dropdown-list uv-bottom-left">
<div class="uv-dropdown-container">
<label>{{ 'Agent'|trans }}</label>
</div>
<ul class="uv-agents-list">
{% for agent in user_service.getAgentPartialDataCollection %}
<li data-id="{{ agent.email }}">
<img src="{{ agent.smallThumbnail ? app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') ~ agent.smallThumbnail : asset(default_agent_image_path) }}"/> {{agent.name}}
</li>
{% endfor %}
<li class="uv-no-results" style="display: none;">{{ 'No result found'|trans }}</li>
</ul>
</div>
<select class="uv-group-select cc-bcc-select">
<option value="bcc">{{ 'BCC'|trans }}</option>
<option value="cc">{{ 'CC'|trans }}</option>
</select>
</div>
<div class="cc-bcc-list"></div>
</div>
</div>
<div class="uv-element-block uv-element-block-textarea">
<label class="uv-field-label">{{ 'Write a reply'|trans }}</label>
<div class="uv-field-block">
<textarea class="uv-field" name="reply" id="reply-area">{{ ticket_service.getAgentDraftReply() }}</textarea>
</div>
</div>
<div class="uv-element-block attachment-block">
<label>
<span class="uv-file-label">{{ 'Add Attachment'|trans }}</span>
</label>
</div>
<div class="uv-action-buttons">
<div class="uv-dropdown next-view">
<input type="hidden" name="nextView" value="stay"/>
<div class="uv-dropdown-btn" style="padding: 9px 27px 9px 10px;">{{ 'Stay on ticket'|trans }}</div>
<div class="uv-dropdown-list uv-top-left" style="opacity: 1;">
<div class="uv-dropdown-container">
<label>{{ 'After Reply'|trans }}</label>
<ul>
<li data-value="stay">{{ 'Stay on ticket'|trans }}</li>
<li data-value="redirect">{{ 'Redirect to list'|trans }}</li>
</ul>
</div>
</div>
</div>
<div class="uv-dropdown reply">
<div class="uv-btn uv-dropdown-other">{{ 'Reply'|trans }} <span class="uv-icon-down-light"></span></div>
<div class="uv-dropdown-list uv-top-left">
<div class="uv-dropdown-container">
<label>{{ 'Reply'|trans }}</label>
<ul>
<li data-id="">{{ 'Submit'|trans }}</li>
{% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}
<li data-id="open">{{ 'Submit And Open'|trans }}</li>
<li data-id="pending">{{ 'Submit And Pending'|trans }}</li>
<li data-id="answered">{{ 'Submit And Answered'|trans }}</li>
<li data-id="resolved">{{ 'Submit And Resolved'|trans }}</li>
<li data-id="closed">{{ 'Submit And Closed'|trans }}</li>
{% endif %}
</ul>
</div>
</div>
</div>
</div>
</form>
</div>
{# Ticket Thread | Forward Thread #}
<div class="uv-tab-view" id="forward">
<form enctype="multipart/form-data" method="post" action="{{ path('helpdesk_member_add_ticket_thread', {'ticketId': ticket.id }) }}">
<input name="threadType" value="forward" type="hidden">
<input name="status" value="" type="hidden" {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}class="reply-status"{% endif %}>
<div class="uv-element-block">
<label class="uv-field-label">{{ 'Subject'|trans }}</label>
<div class="uv-field-block">
<input class="uv-field" type="text" name="subject">
</div>
</div>
<div class="uv-element-block to">
<label class="uv-field-label">{{ 'To'|trans }}</label>
<div class="uv-field-block">
<input class="uv-field uv-dropdown-other preloaded uv-to-message uv-manual-enter" type="text">
<div class="uv-dropdown-list uv-bottom-left">
<div class="uv-dropdown-container">
<label>{{ 'Agent'|trans }}</label>
</div>
<ul class="uv-agents-list">
{% for agent in user_service.getAgentPartialDataCollection %}
<li data-id="{{ agent.email }}">
<img src="{{ agent.smallThumbnail ? app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') ~ agent.smallThumbnail : asset(default_agent_image_path) }}"/> {{agent.name}}
</li>
{% endfor %}
<li class="uv-no-results" style="display: none;">{{ 'No result found'|trans }}</li>
</ul>
</div>
<div class="to-list"></div>
</div>
</div>
<div class="uv-element-block cc-bcc">
<label>
<div class="uv-checkbox">
<input type="checkbox" class="cc-bcc-toggle">
<span class="uv-checkbox-view"></span>
</div>
<span class="uv-checkbox-label">CC/BCC</span>
</label>
<div class="uv-field-block" style="display: none">
<div class="uv-group">
<input class="uv-group-field uv-dropdown-other preloaded uv-manual-enter" type="text">
<div class="uv-dropdown-list uv-bottom-left">
<div class="uv-dropdown-container"><label>{{ 'Agent'|trans }}</label></div>
<ul class="uv-agents-list">
{% for agent in user_service.getAgentPartialDataCollection %}
<li data-id="{{ agent.email }}">
<img src="{{ agent.smallThumbnail ? app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') ~ agent.smallThumbnail : asset(default_agent_image_path) }}"/> {{agent.name}}
</li>
{% endfor %}
<li class="uv-no-results" style="display: none;">{{ 'No result found'|trans }}</li>
</ul>
</div>
<select class="uv-group-select cc-bcc-select">
<option value="bcc">{{ 'BCC'|trans }}</option>
<option value="cc">{{ 'CC'|trans }}</option>
</select>
</div>
<div class="cc-bcc-list"></div>
</div>
</div>
<div class="uv-element-block uv-element-block-textarea">
<label class="uv-field-label">{{ 'Write a reply'|trans }}</label>
<div class="uv-field-block">
<textarea class="uv-field" name="reply" id="forward-area">{{ ticket_service.getAgentDraftReply() }}</textarea>
</div>
</div>
<div class="uv-element-block attachment-block">
<label><span class="uv-file-label">{{ 'Add Attachment'|trans }}</span></label>
</div>
<div class="uv-action-buttons">
<div class="uv-dropdown next-view">
<input type="hidden" name="nextView" value="stay"/>
<div class="uv-dropdown-btn" style="padding: 9px 27px 9px 10px;">{{ 'Stay on ticket'|trans }}</div>
<div class="uv-dropdown-list uv-top-left" style="opacity: 1;">
<div class="uv-dropdown-container">
<label>{{ 'After Reply'|trans }}</label>
<ul>
<li data-value="stay">{{ 'Stay on ticket'|trans }}</li>
<li data-value="redirect">{{ 'Redirect to list'|trans }}</li>
</ul>
</div>
</div>
</div>
<div class="uv-btn forward">{{ 'Forward'|trans }}</div>
</div>
</form>
</div>
{# Ticket Thread | Add Note #}
{% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_NOTE') %}
<div class="uv-tab-view" id="note">
<form enctype="multipart/form-data" method="post" action="{{ path('helpdesk_member_add_ticket_thread', {'ticketId': ticket.id }) }}">
<input name="threadType" value="note" type="hidden">
<input name="status" value="" type="hidden" {% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}class="reply-status"{% endif %}>
<div class="uv-element-block uv-element-block-textarea">
<label class="uv-field-label">{{ 'Write a reply'|trans }}</label>
<div class="uv-field-block">
<textarea class="uv-field" name="reply" id="note-area">{{ ticket_service.getAgentDraftReply() }}</textarea>
</div>
</div>
<div class="uv-element-block attachment-block">
<label><span class="uv-file-label">{{ 'Add Attachment'|trans }}</span></label>
</div>
<div class="uv-action-buttons">
<div class="uv-dropdown next-view">
<input type="hidden" name="nextView" value="stay"/>
<div class="uv-dropdown-btn" style="padding: 9px 27px 9px 10px;">{{ 'Stay on ticket'|trans }}</div>
<div class="uv-dropdown-list uv-top-left" style="opacity: 1;">
<div class="uv-dropdown-container">
<label>{{ 'After Reply'|trans }}</label>
<ul>
<li data-value="stay">{{ 'Stay on ticket'|trans }}</li>
<li data-value="redirect">{{ 'Redirect to list'|trans }}</li>
</ul>
</div>
</div>
</div>
<div class="uv-dropdown reply">
<div class="uv-btn uv-dropdown-other">{{ 'Reply'|trans}}<span class="uv-icon-down-light"></span></div>
<div class="uv-dropdown-list uv-top-left">
<div class="uv-dropdown-container">
<label>{{ 'Add Note'|trans }}</label>
<ul>
<li data-id="">{{ 'Submit'|trans }}</li>
{% if user_service.isAccessAuthorized('ROLE_AGENT_UPDATE_TICKET_STATUS') %}
<li data-id="open">{{ 'Submit And Open'|trans }}</li>
<li data-id="pending">{{ 'Submit And Pending'|trans }}</li>
<li data-id="answered">{{ 'Submit And Answered'|trans }}</li>
<li data-id="resolved">{{ 'Submit And Resolved'|trans }}</li>
<li data-id="closed">{{ 'Submit And Closed'|trans }}</li>
{% endif %}
</ul>
</div>
</div>
</div>
</div>
</form>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Bottom Action Block -->
<div class="uv-ticket-fixed-region">
<div class="uv-ticket-fixed-region-lt">
{{ uvdesk_extensibles.getRegisteredComponent("Webkul\\UVDesk\\CoreFrameworkBundle\\Tickets\\QuickActionButtonCollection").injectTemplates()|raw }}
{# <!-- Saved Replied-->
<div class="uv-dropdown saved-reply">
<div class="uv-dropdown-btn">{{ 'Saved Replies'|trans }}</div>
<div class="uv-dropdown-list uv-top-left">
<div class="uv-dropdown-container">
<label>{{ 'Saved Replies'|trans }}</label>
<ul>
<li data-id="">
<a href="{{ path('helpdesk_member_saved_replies') }}" target="_blank" style="color: #2750C4">{{ 'Create New'|trans }}</a>
</li>
{% for savedReply in ticket_service.getSavedReplies() %}
<li data-id="{{ savedReply.id }}">
{{ savedReply.name }}
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
<!-- //Saved Replied--> #}
{# <!--Code-->
<div class="uv-dropdown">
<div class="uv-dropdown-btn">{{ 'Prepared Responses'|trans }}</div>
<div class="uv-dropdown-list uv-top-left">
<div class="uv-dropdown-container prepared-responses">
<label>{{ 'Prepared Responses'|trans }}</label>
<ul>
<li>
<a class="create-new" href="{{path('prepare_response_action')}}" target="_blank" style="color: #2750C4">{{ 'Create New'|trans }}</a>
</li>
{% set preparedResponses = ticket_service.getManualWorkflow() %}
{% for workflow in preparedResponses %}
<li>
<a href="{{ path('helpdesk_member_ticket_prepared_response_xhr') }}/{{ ticket.id }}/{{ workflow.id }}">
{{ workflow.name }}
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
<!--//Code--> #}
</div>
<div class="uv-ticket-fixed-region-rt"></div>
</div>
<!-- //Bottom Action Block -->
</div>
</div>
{# Edit Ticket #}
{% if user_service.isAccessAuthorized('ROLE_AGENT_EDIT_TICKET') %}
<div class="uv-pop-up-overlay uv-no-error-success-icon" id="edit-ticket-modal">
<div class="uv-pop-up-box uv-pop-up-wide">
<span class="uv-pop-up-close"></span>
<h2>{{ 'Edit Ticket'|trans }}</h2>
{# Edit Ticket Form #}
<form method="post" action="{{ path('helpdesk_member_update_ticket_details_xhr', {'ticketId': ticket.id}) }}" id="edit-ticket-form">
<div class="uv-element-block">
<label class="uv-field-label">{{ 'Subject'|trans }}</label>
<div class="uv-field-block">
<input type="text" name="subject" class="uv-field" value="{{ ticket.subject }}" />
</div>
</div>
<div class="uv-element-block">
<label class="uv-field-label">{{ 'Reply'|trans }}</label>
<div class="uv-field-block">
{% if initialThread.message|striptags == initialThread.message %}
<textarea name="reply" id="uv-edit-create-thread" class="uv-field">{{ initialThread.message|nl2br }}</textarea>
%} {% else %}
<textarea name="reply" id="uv-edit-create-thread" class="uv-field">{{ initialThread.message|raw }}</textarea>
{% endif %}
</div>
</div>
<div class="uv-pop-up-actions">
<input class="uv-btn update" href="#" value="Update" type="submit">
<input class="uv-btn cancel" href="#" value="Discard" type="button">
</div>
</form>
</div>
</div>
{% endif %}
{{ uvdesk_extensibles.getRegisteredComponent("Webkul\\UVDesk\\CoreFrameworkBundle\\Tickets\\WidgetCollection").embedSideFilterContent()|raw }}
{% endblock %}
{% block footer %}
{{ parent() }}
{{ include('@UVDeskCoreFramework\\Templates\\attachment.html.twig') }}
{{ include("@UVDeskCoreFramework/Templates/tinyMCE.html.twig") }}
<script id="thread_list_empty_tmp" type="text/template">
<div class="uv-no-threads">{{ 'Nothing interesting here...'|trans }}</div>
</script>
<script>
$(document).ready(function() {
$("#filterSavedreplies").on("keyup", function() {
if (this.value.length && this.value.length != '') {
var that = this;
$("#listSavedReplies li").hide().filter(function() {
return $(this).html().toLowerCase().indexOf(that.value.toLowerCase()) !== -1;
}).show();
} else {
$("#listSavedReplies li").show()
}
});
$(".uv-dropdown-btn").click(function(event) {
setTimeout(function() {
$(".uv-search-inline").focus();
}, 100);
});
});
</script>
<script id="thread_list_item_tmp" type="text/template">
<div class="uv-ticket-strip">
<span>
<% if(typeof(mailStatus) != 'undefined' && mailStatus) { %>
<a href="https://support.uvdesk.com/en/blog/uvdesk-ticket-delivery-status" target="_blank">
<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>
</a>
<% } %>
<span class="timeago uv-margin-0" data-timestamp="<%- timestamp %>" title="<%- formatedCreatedAt %>">
<%- formatedCreatedAt %>
</span>
- <%- fullname %>
<span class="uv-ticket-strip-label">
<% if(threadType == 'reply') { %>
{{ 'replied'|trans }}
<% } else if(threadType == 'note') { %>
{{ 'added note'|trans }}
<% } else if(threadType == 'forward') { %>
{{ 'forwarded'|trans }}
<% } %>
- <a href="#thread/<%- id %>" id="thread<%- id %>" class="copy-thread-link">#<%- id %></a>
</span>
</span>
<% if((replyTo && threadType == 'forward') || cc || bcc) { %>
<div class="uv-ticket-strip">
<% if(replyTo && threadType == 'forward') { %>
<span><span class="uv-ticket-strip-label">{{ 'TO'|trans }} -</span> <%- replyTo %></span>
<% } if(cc) { %>
<span><span class="uv-ticket-strip-label">{{ 'CC'|trans }} -</span> <%- cc %></span>
<% } if(bcc) { %>
<span><span class="uv-ticket-strip-label">{{ 'BCC'|trans }} -</span> <%- bcc %></span>
<% } %>
</div>
<% } %>
</div>
<div class="uv-ticket-strip uv-margin-top-5" <% if(!bookmark && !isLocked) { %>style="display: none"<% } %> >
<span <% if(!bookmark) { %>style="display: none"<% } %> >
<span class="uv-icon-pinned"></span>
{{ 'Pinned'|trans }}
</span>
<span <% if(!isLocked) { %>style="display: none"<% } %> >
<span class="uv-icon-locked"></span>
{{ 'Locked'|trans }}
</span>
</div>
<div class="uv-ticket-main-lt">
<span class="uv-thread-action">
<span class="uv-icon-ellipsis uv-dropdown-other"></span>
<div class="uv-dropdown-list uv-bottom-left">
<div class="uv-dropdown-container">
<ul>
{% if user_service.isAccessAuthorized('ROLE_AGENT_EDIT_THREAD_NOTE') %}
<% if (userType != 'system' && userType != 'System') { %>
<li data-action="edit">{{ 'Edit Thread'|trans }}</li>
<% } %>
{% endif %}
{% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_THREAD_NOTE') %}
<li data-action="delete">{{ 'Delete Thread'|trans }}</li>
{% endif %}
<li data-action="forward">{{ 'Forward'|trans }}</li>
<% if(bookmark) { %>
<li data-action="pin" data-id="1">{{ 'Unpin Thread'|trans }}</li>
<% } else { %>
<li data-action="pin" data-id="0">{{ 'Pin Thread'|trans }}</li>
<% } %>
<% if(threadType != 'note') { %>
{% if user_service.isAccessAuthorized('ROLE_AGENT_MANAGE_LOCK_AND_UNLOCK_THREAD') %}
<% if(isLocked) { %>
<li data-action="lock" data-id="1">{{ 'Unlock Thread'|trans }}</li>
<% } else { %>
<li data-action="lock" data-id="0">{{ 'Lock Thread'|trans }}</li>
<% } %>
{% endif %}
<% } %>
<li style="display: none;" data-action="translate">{{ 'Translate Thread'|trans }}</li>
</ul>
</div>
</div>
</span>
<span class="p-relative">
</span>
<% if (userType != 'system' && userType != 'System') { %>
<% if(user && user.smallThumbnail != null) { %>
<img src="{{ app.request.scheme ~'://' ~ app.request.httpHost ~ asset('') }}<%- user.smallThumbnail %>" />
<% } else { %>
<img src="<% if(userType == 'agent') { %> {{ asset(default_agent_image_path) }} <% } else { %> {{ asset(default_customer_image_path) }} <% } %>" />
<% } %>
<% } else { %>
<img src="{{ asset(default_helpdesk_image_path) }}" />
<% } %>
</div>
<div class="uv-ticket-main-rt">
<% if(userType == 'customer') { %>
<a <% if(user) { %>href="{{ path('helpdesk_member_manage_customer_account') }}/<%- user.id %>"<% } %> class="uv-ticket-member-name">
<%- fullname %>
</a>
<% } else if(userType == 'agent') { %>
<a <% if(user) { %>href="{{ path('helpdesk_member_account') }}/<%- user.id %>"<% } %> class="uv-ticket-member-name">
<%- fullname %>
</a>
<% } else { %>
<span class="uv-ticket-member-name">
<%- fullname %>
</span>
<% } %>
<!-- Message Block -->
<div class="message">
<%= reply %>
</div>
<!-- Attachment Block -->
<% if(attachments.length) { %>
<div class="uv-ticket-uploads">
<h4>{{ 'Uploaded Files'|trans }}</h4>
<div class="uv-ticket-uploads-strip">
<% _.each(attachments, function(file) { %>
<a href="<%-file.downloadURL %>" target ="_blank" class="uv-ticket-uploads-brick uv-no-pointer-events" data-toggle="tooltip" title="<%- file.name %>">
<img src="<%-file.iconURL %>" class="uv-auto-pointer-events">
</a>
<% }) %>
</div>
<% if (attachments.length > 1) { %>
<div class="thread-attachments-zip pull-left">
<div class="uv-upload-actions">
<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>
<% if(attachments.length > 0) { %>
<a href="{{ path('helpdesk_member_ticket_download_attachment_zip') }}/<%- id %>" target="_blank"><span class="uv-icon-attachment"></span> {{ 'Download (as .zip)'|trans }}</a>
<% } %>
</div>
</div>
<% } %>
</div>
<% } %>
</div>
</script>
<script id="edit_thread_tmp" type="text/template">
<div class="thread-edit-container">
<div class="uv-element-block uv-element-block-textarea">
<div class="uv-field-block">
<textarea id="uv-edit-thread">
</textarea>
</div>
</div>
<div class="uv-action-buttons">
<a class="uv-btn cancel-edit" type="button">{{ 'Cancel'|trans }}</a>
<a class="uv-btn saveThread" type="button" style="margin-right: 10px;">{{ 'Update'|trans }}</a>
</div>
</div>
</script>
<script id="ticket_quick_navigation_tmp" type="text/template">
<% if(prev) { %>
<a class="uv-btn-stroke" href="{{ path('helpdesk_member_ticket') }}/<%- prev %>">
<span class="uv-icon-previous"></span>
{{ 'Previous Ticket'|trans }}
</a>
<% } else { %>
<a class="uv-btn-stroke" disabled="disabled">
<span class="uv-icon-previous"></span>
{{ 'Previous Ticket'|trans }}
</a>
<% } %>
<% if(next) { %>
<a class="uv-btn-stroke" href="{{ path('helpdesk_member_ticket') }}/<%- next %>">
{{ 'Next Ticket'|trans }}
<span class="uv-icon-next"></span>
</a>
<% } else { %>
<a class="uv-btn-stroke" disabled="disabled">
{{ 'Next Ticket'|trans }}
<span class="uv-icon-next"></span>
</a>
<% } %>
</script>
<script type="text/javascript">
uvdesk = {
ticket: {}
};
var ticketApp = {};
viewerImages = function() {
if (typeof($().viewer == 'function')) {
$('.uv-ticket-uploads .uv-ticket-uploads-strip').viewer({
'url': 'data-url',
'downloadBase': "{{ path('helpdesk_member_ticket_download_attachment') }}",
'download': 'data-download',
});
}
};
$(function () {
var threadIds = [];
viewerImages();
_.extend(Backbone.Model.prototype, Backbone.Validation.mixin);
// Ticket Model
var TicketModel = Backbone.Model.extend({
idAttribute : "id",
urlRoot : "{{ path('helpdesk_member_update_ticket_attributes_xhr') }}",
validation: {
'email': [{
required: true,
msg: '{{ "This field is mandatory" | trans}}'
},{
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])?)*$/,
msg: 'Please enter a valid email'
}],
'subject' : {
required : true,
msg : '{{ "This field is mandatory" | trans}}'
},
'reply' : {
fn: function(value) {
if(!tinyMCE.get("uv-edit-create-thread"))
return false;
var html = tinyMCE.get("uv-edit-create-thread").getContent();
if(app.appView.stripHTML(html) != '') {
return false;
}
return true;
},
msg : '{{ "This field is mandatory" | trans}}'
}
},
});
// Thread Model
var ThreadModel = Backbone.Model.extend({
idAttribute : "id",
defaults : {
hasTask : 0,
task: null
}
});
// Customer Model
var CustomerModel = Backbone.Model.extend({
validation: {
'name': [{
required: true,
msg: '{{ "This field is mandatory" }}'
}, {
pattern: /^((?![!@#$%^&*()<_+]).)*$/,
msg: '{{ "This field must have characters only"}}'
}],
'email': [{
required: true,
msg: '{{ "This field is mandatory" | trans}}'
},{
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])?)*$/,
msg: '{{ "Email address is invalid" | trans}}'
}],
'contactNumber': function(value) {
if(value != undefined && value !== '') {
if (!value.match('^\\s*(?:\\+?(\\d{1,3}))?[-. (]*(\\d{3})[-. )]*(\\d{3})[-. ]*(\\d{4})(?: *x(\\d+))?\\s*$'))
return 'Contact number is invalid';
}
}
},
urlRoot : "{{ path('helpdesk_member_manage_customer_account') }}"
});
// Ticket Collaborator Model
var CollaboratorModel = Backbone.Model.extend({
idAttribute : "id",
validation: {
'email': [{
required: true,
msg: '{{ "This field is mandatory" | trans}}'
},{
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])?)*$/,
msg: '{{ "Please enter a valid email" | trans}}'
}]
},
defaults : {
ticketId : {{ ticket.id }},
email: ''
},
parse: function (resp, options) {
return resp.collaborator;
},
urlRoot : "{{ path('helpdesk_member_ticket_manage_collaborators_xhr') }}"
});
// Ticket Tag Model
var TagModel = Backbone.Model.extend({
idAttribute : "id",
defaults : {
ticketId : {{ ticket.id }}
},
parse: function (resp, options) {
return resp.tag;
},
urlRoot : "{{ path('helpdesk_member_ticket_create_tag_xhr') }}"
});
// Ticket Label Model
var LabelModel = Backbone.Model.extend({
idAttribute : "id",
defaults : {
ticketId : {{ ticket.id }}
},
parse: function (resp, options) {
return resp.label;
},
urlRoot : "{{ path('helpdesk_member_ticket_add_label_xhr') }}"
});
// Ticket Thread Collection
var ThreadCollection = AppCollection.extend({
model : ThreadModel,
mode: "infinite",
url : "{{ path('helpdesk_member_thread_collection_xhr', {'ticketId': ticket.id}) }}",
firstScrollCheck: false,
threadRequestedId: false,
template : $("#thread_list_empty_tmp").html(),
parseRecords: function (resp, options) {
return resp.threads;
},
syncData : function() {
type = $(".uv-ticket-action-bar-lt .uv-tabs .uv-tab-active").attr('data-type')
var self = this;
var data = {
threadType: type
};
if(this.threadRequestedId)
data.threadRequestedId = this.threadRequestedId;
app.appView.showLoader()
this.fetch({
data : data,
remove: false,
success: function(model, response) {
app.appView.hideLoader();
self.threadRequestedId = false;
pagination.renderPagination(response.pagination);
threadCollection.state.currentPage = parseInt(response.pagination.current) + 1;
if(response.pagination.totalCount <= 0){
this.$('.uv-ticket-wrapper.thread-list').html(self.template);
}
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
}
}).done(function(){
viewerImages();
if(!self.firstScrollCheck){
self.firstScrollCheck = true;
var fragment = Backbone.history.fragment.trim();
if(fragment == '') {
router.scrollPage('#reply');
} else
router.scrollPage('#' + fragment.replace('thread/', 'thread'));
}
});
}
});
// Ticket Collaborator Collection
var CollaboratorCollection = Backbone.PageableCollection.extend({
model : CollaboratorModel
});
// Ticket Tag Collection
var TagCollection = Backbone.PageableCollection.extend({
model : TagModel,
isTagExist : function(name) {
var flag = 1;
_.each(tagCollection.models, function (item) {
if(item.get('name').toUpperCase() == name.toUpperCase())
flag = 0;
}, this);
return flag;
}
});
// Ticket Label Collection
var LabelCollection = Backbone.PageableCollection.extend({
model : TagModel,
isLabelExist : function(name) {
var flag = 1;
_.each(labelCollection.models, function (item) {
if(item.get('name').toUpperCase() == name.toUpperCase())
flag = 0;
}, this);
return flag;
}
});
// Customer Form View
var CustomerForm = Backbone.View.extend({
events : {
'click .uv-btn.update-btn' : "saveCustomer",
'blur input': 'formChanegd',
'click .cancel-btn': 'backToInfo',
'click .uv-aside-back': 'backToInfo'
},
initialize : function() {
Backbone.Validation.bind(this);
},
formChanegd: function(e) {
this.model.set(Backbone.$(e.currentTarget).attr('name'), Backbone.$(e.currentTarget).val())
this.model.isValid([Backbone.$(e.currentTarget).attr('name')])
},
saveCustomer: function (e) {
e.preventDefault();
currentElement = Backbone.$(e.currentTarget);
this.model.clear();
this.model.set(this.$el.find('form').serializeObject());
self = this;
if(this.model.isValid(true)) {
app.appView.showLoader();
currentElement.attr('disabled', 'disabled');
this.model.save({}, {
success: function (model, response, options) {
app.appView.hideLoader();
currentElement.removeAttr("disabled");
if(response.alertClass == "success") {
app.appView.renderResponseAlert(response);
$('.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>")
self.backToInfo();
} else if(response.errors) {
self.addErrors(JSON.parse(response.errors));
} else if(response.alertMessage) {
app.appView.renderResponseAlert(response);
}
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
app.appView.hideLoader();
app.appView.renderResponseAlert(warningResponse);
}
});
}
},
addErrors: function(jsonContext) {
for (var field in jsonContext) {
Backbone.Validation.callbacks.invalid(this, field, jsonContext[field], 'input');
}
},
backToInfo: function(e) {
if(e)
e.preventDefault()
$('.uv-main-info-update-block').hide()
$('.uv-main-info-block').show()
},
});
// Ticket View
var TicketView = Backbone.View.extend({
el: $('.uv-wrapper'),
stopDraftSaveFlag: 0,
events: {
'click .uv-ticket-action .uv-dropdown-list li[data-action="spam"], .uv-ticket-action .uv-dropdown-list li[data-action="closed"]': 'masrkSpamAndClosed',
'click .uv-aside-ticket-actions .uv-aside-select .uv-dropdown-list li': 'editTicketProperty',
'click .uv-aside-customer-info .uv-customize': 'showCustomerUpdateBlock',
'click .uv-ticket-head .uv-star-large': 'updateStar',
'click .uv-ticket-action-bar .uv-tabs li': 'filterThread',
'click .uv-ticket-action .uv-dropdown-list li[data-action="delete"]': 'confirmRemove',
'click .uv-ticket-action .uv-dropdown-list li[data-action="lock"]': 'lockAndUnlockThread',
'click .uv-element-block.collaborators .uv-btn-tag': 'removeCcCollaborator',
'keypress .uv-element-block.to .uv-dropdown-other': 'addToInput',
'click .uv-element-block.to .uv-dropdown-list li': 'addTo',
'click .to-list .uv-btn-tag': 'removeTo',
'change .uv-element-block.cc-bcc .cc-bcc-toggle': 'showCcBccBlock',
'keypress .uv-element-block.cc-bcc .uv-group-field.uv-dropdown-other': 'addCcBccInput',
'click .uv-element-block.cc-bcc .uv-dropdown-list li': 'addCcBcc',
'click .cc-bcc-list .uv-btn-tag, .to-list .uv-btn-tag': 'removeEmail',
'click .next-view .uv-dropdown-list li': 'setNextView',
'click .uv-dropdown.reply .uv-dropdown-list li, .uv-btn.forward': 'validateForm',
'click #edit-ticket-modal .uv-btn.update': 'updateTicket',
'click .message .uv-icon-ellipsis': 'showReplyQuote',
'input .uv-aside-brick .uv-field.uv-dropdown-other': 'searchFilterXhr',
'click .uv-dropdown-container.prepared-responses a:not(.create-new)': 'confirmPreparedResponses',
'click .uv-header-fix': 'fixheader',
'click .uv-ticket-action .uv-dropdown-list li[data-action="print"]': 'printTicket',
'blur .uv-manual-enter': 'enterManualAdd',
},
ticketNavigationTemplate : _.template($("#ticket_quick_navigation_tmp").html()),
loaderTemplate : _.template($("#loader-tmp").html()),
targetPreparedResponseUrl: '',
initialize: function() {
Backbone.Validation.bind(this);
InitTinyMce('#uv-edit-create-thread');
$('.uv-ticket-fixed-region .uv-ticket-fixed-region-rt').html(this.ticketNavigationTemplate(ticketNavigation))
var threadTab = localStorage.getItem("threadTab");
if(threadTab){
$('.uv-ticket-action-bar-lt .uv-tabs li').removeClass('uv-tab-active');
$('.uv-ticket-action-bar-lt .uv-tabs [data-type="' + threadTab + '"]').addClass('uv-tab-active');
}
nextView = localStorage.getItem("nextView");
if(nextView) {
$(".next-view input").val(nextView)
$(".next-view .uv-dropdown-btn").text($("#reply .next-view .uv-dropdown-list li[data-value='" + nextView + "']").text())
}
if(!localStorage.getItem('ticketTour')) {
$('.uv-ticket-tour').show()
}
this.fixheaderInit();
},
printTicket: function(e) {
window.print();
},
enterManualAdd: function(e) {
var target = $(e.target);
if(target.val()) {
var e = $.Event("keypress");
e.which = 13; //choose the one you want
target.trigger(e);
}
},
fixheader: function(e){
e.preventDefault();
var header = localStorage.getItem("fixHeader");
header = !(header == 'true');
localStorage.setItem("fixHeader", header);
this.fixheaderInit();
},
fixheaderInit: function(){
var header = localStorage.getItem("fixHeader");
if(header == 'true'){
$('a.uv-icon-pin').addClass('uv-icon-pinned');
$('.uv-ticket-action-bar').addClass('uv-ticket-action-bar-fixed');
}else{
$('a.uv-icon-pin').removeClass('uv-icon-pinned');
$('.uv-ticket-action-bar').removeClass('uv-ticket-action-bar-fixed');
}
},
masrkSpamAndClosed: function(e) {
var currentElement = Backbone.$(e.currentTarget);
var value = currentElement.attr('data-index');
$(".uv-aside-select .uv-dropdown-list ul.status li[data-index='" + value + "']").trigger('click')
},
editTicketProperty: function(e) {
var currentElement = Backbone.$(e.currentTarget);
var uvSelect = currentElement.parents('.uv-aside-select');
var field = currentElement.parent().attr('data-action');
var value = currentElement.attr('data-index');
if(uvSelect.find('.uv-aside-select-value').attr('data-id') != value) {
var name = currentElement.text().trim();
app.appView.showLoader();
this.model.save({attribute: field, value: value, id: this.model.id}, {
patch: true,
success: function (model, response, options) {
uvSelect.find('.uv-aside-select-value').attr('data-id', value).text(name)
if(field == 'priority') {
uvSelect.find('.uv-list-ticket-priority').attr('style', 'background:' + currentElement.attr('data-color'));
} else if(field == 'agent') {
$('.uv-ticket-strip .agent-info').show()
$('.uv-ticket-strip .agent-info .name').text(name)
}
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
var response = warningResponse;
if(xhr.responseJSON)
response = xhr.responseJSON;
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
}
});
}
},
showCustomerUpdateBlock: function() {
$('.uv-main-info-update-block').show()
$('.uv-main-info-block').hide()
},
updateStar: function(e) {
e.preventDefault();
var currentElement = Backbone.$(e.currentTarget);
currentElement.toggleClass('uv-star-active')
this.model.save({id: this.model.id}, {
patch: true,
url : "{{ path('helpdesk_member_bookmark_ticket_xhr') }}",
success: function (model, response, options) {
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
}
});
},
filterThread: function(e) {
var currentElement = Backbone.$(e.currentTarget);
if(type = currentElement.attr('data-type')) {
localStorage.setItem("threadTab", type);
if(type != 'all')
$('.uv-ticket-main.create').hide()
else
$('.uv-ticket-main.create').show()
$('.uv-ticket-wrapper.thread-list').html('')
models = []
threadCollection.each(function(model) {
models.push(model)
})
total = threadCollection.models.length;
count = 0;
if(total) {
_.each(models, function (model) {
threadCollection.remove(model)
count++;
if(total == count) {
threadCollection.reset()
threadCollection.state.currentPage = 1;
threadCollection.syncData()
}
});
} else {
threadCollection.reset()
threadCollection.state.currentPage = 1;
threadCollection.syncData()
}
}
},
confirmRemove: function(e) {
app.appView.openConfirmModal(this);
},
removeItem : function() {
if(this.model.attributes.isTrashed)
window.location.href = "{{ path('helpdesk_member_delete_ticket', {'ticketId': ticket.id}) }}";
else
window.location.href = "{{ path('helpdesk_member_trash_ticket', {'ticketId': ticket.id}) }}";
},
addCCCollaborators: function() {
if(collaboratorCollection.length) {
var collaboratorContainer = $('.uv-element-block.collaborators');
collaboratorContainer.find('.uv-field-block').html('');
collaboratorContainer.show()
_.each(collaboratorCollection.models, function (item) {
var json = item.attributes;
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>")
}, this);
}
},
removeCcCollaborator: function(e) {
e.preventDefault()
Backbone.$(e.currentTarget).parent().remove();
var collaboratorContainer = $('.uv-element-block.collaborators');
if(!collaboratorContainer.find('.uv-btn-tag').length)
collaboratorContainer.hide()
},
addToInput: function(e) {
var inputElement = Backbone.$(e.currentTarget);
var currentTab = inputElement.parents('.uv-tab-view');
var email = inputElement.val().trim();
if (e.which === 13 && email) {
e.preventDefault()
if(!this.model.preValidate({name: 'email', email: email})) {
inputElement.val('').trigger('input')
inputElement.removeClass('uv-dropdown-btn-active')
inputElement.siblings('.uv-dropdown-list').hide()
if(!currentTab.find(".to-list input[value='" + email + "'].to").length) {
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>")
}
}
}
},
addTo: function(e) {
var currentTab = Backbone.$(e.currentTarget).parents('.uv-tab-view');
var email = Backbone.$(e.currentTarget).attr('data-id');
if(!currentTab.find(".to-list input[value='" + email + "'].to").length) {
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>")
}
},
showCcBccBlock: function(e) {
var currentElement = Backbone.$(e.currentTarget);
var currentTab = currentElement.parents('.uv-tab-view');
if(currentElement.is(':checked')) {
currentTab.find('.uv-element-block.cc-bcc').find('.uv-field-block').show()
} else {
currentTab.find('.uv-element-block.cc-bcc').find('.uv-field-block').hide()
currentTab.find('.uv-element-block .cc-bcc-list').html('')
}
},
addCcBccInput: function(e) {
var inputElement = Backbone.$(e.currentTarget);
var currentTab = inputElement.parents('.uv-tab-view');
var email = inputElement.val().trim();
if (e.which === 13 && email) {
e.preventDefault()
type = currentTab.find('.cc-bcc-select option:selected').text()
if(!this.model.preValidate({name: 'email', email: email})) {
inputName = $('.cc-bcc-select').val()
inputElement.val('').trigger('input')
inputElement.removeClass('uv-dropdown-btn-active')
inputElement.siblings('.uv-dropdown-list').hide()
if(!currentTab.find(".cc-bcc-list input[value='" + email + "']." + inputName).length) {
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>")
}
}
}
},
addCcBcc: function(e) {
var currentTab = Backbone.$(e.currentTarget).parents('.uv-tab-view');
var email = Backbone.$(e.currentTarget).attr('data-id');
type = currentTab.find('.cc-bcc-select option:selected').text()
inputName = currentTab.find('.cc-bcc-select').val()
if(!currentTab.find(".cc-bcc-list input[value='" + email + "']." + inputName).length) {
currentTab.find('.uv-element-block.cc-bcc .uv-group-field.uv-dropdown-other').val('').trigger('input')
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>")
}
},
removeEmail: function(e) {
e.preventDefault()
Backbone.$(e.currentTarget).parent().remove();
},
setNextView: function(e) {
var currentElement = Backbone.$(e.currentTarget);
var nextView = currentElement.attr('data-value');
localStorage.setItem("nextView", nextView);
$(".next-view input").val(nextView)
$(".next-view .uv-dropdown-btn").text(currentElement.text())
},
validateForm : function(e) {
e.preventDefault();
var element = Backbone.$(e.currentTarget);
formType = element.parents('.uv-tab-view.uv-tab-view-active').attr('id');
form = element.parents('form');
form.find('.reply-status').val(element.attr('data-id'));
form.find('.uv-field-message').remove()
var html = tinyMCE.get(formType + "-area").getContent();
if(app.appView.htmlText(html) != '' || -1 != html.indexOf('<img')) {
if(formType == 'forward') {
if(!form.find(".to-list input.to").length) {
$('.uv-element-block.to').append("<span class='uv-field-message'>{{ 'This field is mandatory'|trans }}</span>")
} else {
this.stopDraftSaveFlag = 1;
app.appView.showLoader();
tinyMCE.activeEditor.uploadImages(function(response) {
app.appView.hideLoader();
form.submit();
$('.uv-btn.forward').attr('disabled', 'disabled');
});
}
} else {
this.stopDraftSaveFlag = 1;
if(localStorage) {
localStorage.setItem("threadTab", "all");
}
app.appView.showLoader();
tinyMCE.activeEditor.uploadImages(function(response) {
app.appView.hideLoader();
form.submit();
$('.uv-dropdown.reply').find('.uv-btn').attr('disabled', 'disabled');
});
}
} else {
form.find('.uv-element-block-textarea').append("<span class='uv-field-message'>{{ 'This field is mandatory'|trans }}</span>");
if(formType == 'forward') {
if(!form.find(".to-list input.to").length) {
$('.uv-element-block.to').append("<span class='uv-field-message'>{{ 'This field is mandatory'|trans }}</span>")
}
}
}
},
updateTicket: function(e) {
e.preventDefault();
this.model.set($('#edit-ticket-modal form').serializeObject());
if(this.model.isValid(['subject', 'reply'])) {
$('#edit-ticket-modal form').find('.uv-btn').attr('disabled', 'disabled');
$('#edit-ticket-modal form').submit();
}
},
showReplyQuote: function(e) {
Backbone.$(e.currentTarget).next().toggle();
},
searchFilterXhr: _.debounce(function(e) {
currentElement = Backbone.$(e.currentTarget);
var parent = currentElement.parent();
if($('.uv-dropdown-other.uv-dropdown-btn-active').parent().attr('id') != parent.attr('id'))
return;
parent.find("li:not(.uv-no-results, .uv-filter-info)").remove();
parent.find(".uv-filter-info").show()
if(currentElement.val().length > 1) {
parent.append(this.loaderTemplate())
parent.find('.uv-filter-info').text("{% trans %}Searching{% endtrans %} ...")
if(self.xhrReq)
self.xhrReq.abort();
self.xhrReq = $.ajax({
url : "{{ path('helpdesk_member_ticket_search_filter_options') }}",
type : 'GET',
data: {"type" : currentElement.attr('data-type'), "query": currentElement.val()},
dataType : 'json',
success : function(response) {
self.xhrReq = 0;
parent.find('.uv-loader').remove()
parent.find('.uv-filter-info').text("{{ 'Type atleast 2 letters'|trans }}").hide();
if(response.length == 0) {
parent.find('.uv-no-results').show();
parent.find('.uv-no-results').disabled = true;
} else {
parent.find('.uv-no-results').hide();
_.each(response, function(item) {
parent.find('.uv-dropdown-list ul').append("<li data-id='" + item.id + "'>" + item.name + "</li>")
});
}
},
error: function (xhr) {
self.xhrReq = 0;
parent.find('.uv-loader').remove()
parent.find('.uv-no-results').hide();
parent.find('.uv-filter-info').text("{{ 'Type atleast 2 letters'|trans }}").show();
if(url = xhr.getResponseHeader('Location'))
window.location = url;
}
});
} else {
parent.find('.uv-no-results').hide();
}
},1000)
});
// Ticket Thread View
var ThreadItem = Backbone.View.extend({
tagName : "div",
className : "uv-ticket-main",
template : _.template($("#thread_list_item_tmp").html()),
editThreadTemplate : _.template($("#edit_thread_tmp").html()),
events : {
'click .uv-thread-action .uv-dropdown-list li[data-action="delete"]': 'confirmRemove',
'click .uv-thread-action .uv-dropdown-list li[data-action="lock"]': 'lockAndUnlockThread',
'click .uv-thread-action .uv-dropdown-list li[data-action="pin"]': 'pinThread',
'click .uv-thread-action .uv-dropdown-list li[data-action="mark"]': 'markForTask',
'click .uv-thread-action .uv-dropdown-list li[data-action="forward"]' : 'forwardThread',
'click .uv-thread-action .uv-dropdown-list li[data-action="edit"]' : 'editThread',
'click .uv-btn.cancel-edit' : 'cancelEdit',
'click .uv-btn.saveThread' : 'updateThread',
'click .copy-thread-link' : 'copyThreadLink',
'blur .input-copy-thread-link': 'removeCopyThreadLink'
},
render : function () {
this.$el.html(this.template(this.model.toJSON()));
this.$el.addClass("thread-" + this.model.id)
if(this.model.attributes.threadType == 'note')
this.$el.addClass('uv-ticket-note')
return this;
},
unrender : function(response) {
if(response.alertMessage != undefined) {
var self = this;
{# threadCollection.models.remove(this.model); #}
threadCollection.models = threadCollection.models.filter(thread => {
if(thread.id == self.model.id) {
return false;
}
return true;
});
this.remove();
threadCollection.syncData();
app.appView.renderResponseAlert(response);
}
},
confirmRemove: function(e) {
app.appView.openConfirmModal(this);
},
removeItem : function() {
self = this;
var index = threadIds.indexOf(this.model.id);
if (index > -1)
threadIds.splice(index, 1);
app.appView.showLoader();
this.model.destroy({
url : "{{ path('helpdesk_member_thread_xhr') }}/" + this.model.id,
data : { 'ticketId' : ticketModel.attributes.id },
success : function (model, response, options) {
app.appView.hideLoader();
self.unrender(response);
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
var response = warningResponse;
if(xhr.responseJSON)
response = xhr.responseJSON;
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
}
});
},
lockAndUnlockThread :function(e) {
self = this;
currentElement = Backbone.$(e.currentTarget);
var isLocked = 0;
if(this.model.get('isLocked')) {
this.model.set('isLocked', 0);
currentElement.attr('data-id', isLocked).text("{{ 'Lock Thread'|trans }}");
} else {
isLocked = 1;
this.model.set('isLocked', 1);
currentElement.attr('data-id', isLocked).text("{{ 'Unlock Thread'|trans }}");
}
app.appView.showLoader();
this.model.save({
isLocked: isLocked,
id: this.model.id,
ticketId: ticketModel.attributes.id,
updateType: 'lock'
}, {
patch: true,
url : "{{ path('helpdesk_member_thread_xhr') }}/" + this.model.id,
success : function (model, response, options) {
self.toggleThreadPropertyIcon()
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
var response = warningResponse;
if(xhr.responseJSON)
response = xhr.responseJSON;
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
}
});
},
pinThread :function(e) {
self = this;
currentElement = Backbone.$(e.currentTarget);
var bookmark = 0;
if(this.model.get('bookmark')) {
this.model.set('bookmark', 0);
currentElement.attr('data-id', bookmark).text("{{ 'Pin Thread'|trans }}");
} else {
bookmark = 1;
this.model.set('bookmark', 1);
currentElement.attr('data-id', bookmark).text("{{ 'Unpin Thread'|trans }}");
}
app.appView.showLoader();
this.model.save({
bookmark: bookmark,
id: this.model.id,
ticketId: ticketModel.attributes.id,
updateType: 'bookmark'
}, {
patch: true,
url : "{{ path('helpdesk_member_thread_xhr') }}/" + this.model.id,
success : function (model, response, options) {
self.toggleThreadPropertyIcon()
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
var response = warningResponse;
if(xhr.responseJSON)
response = xhr.responseJSON;
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
}
});
},
forwardThread : function(e) {
var element = Backbone.$(e.currentTarget);
tinymce.get('forward-area').setContent(this.model.attributes.reply);
$('#forward-area').parent().find('img').removeAttr('crossorigin');
$(".uv-tabs li[for='forward']").trigger('click');
$('.uv-ticket-scroll-region').animate({
scrollTop: $('#default').outerHeight()
}, 'slow');
},
cancelEdit : function(e) {
this.initEditThread();
tinymce.get('uv-edit-thread').destroy()
},
editThread : function(e) {
$('.thread-edit-container .cancel-edit').trigger('click');
this.initEditThread();
this.$el.find('.message').hide().after(this.editThreadTemplate());
this.$el.find('.uv-ticket-uploads').hide()
InitTinyMce('#uv-edit-thread');
tinymce.get('uv-edit-thread').setContent(this.model.attributes.reply);
this.$el.find('img').removeAttr('crossorigin');
},
initEditThread: function() {
$('.thread-edit-container').remove();
messageElement = this.$el.find('.message');
messageElement.show();
this.$el.find('.uv-ticket-uploads').show()
},
updateThread : function(e) {
e.preventDefault();
var currentElement = Backbone.$(e.currentTarget);
parent = currentElement.parents('.thread-edit-container')
parent.find('.uv-field-message').remove()
var html = tinyMCE.get("uv-edit-thread").getContent();
if(app.appView.stripHTML(html) != '') {
var self = this;
currentElement.attr("disabled", "disabled");
this.model.set('reply', html);
app.appView.showLoader()
this.model.save({}, {
url : "{{ path('helpdesk_member_thread_update_xhr') }}/" + this.model.id,
success : function (model, response, options) {
app.appView.hideLoader()
messageElement = self.$el.find('.message');
if(response.alertClass == 'success') {
messageElement.html(self.model.attributes.reply).show();
messageElement.find('.uv-icon-ellipsis').remove();
messageElement.find('.helpdesk_blockquote').eq(0).before("<span class='uv-icon-ellipsis uv-ellipsis-mirror'></span>").hide();
}
self.initEditThread();
tinymce.get('uv-edit-thread').destroy()
app.appView.renderResponseAlert(response);
},
error: function (model, xhr, options) {
self.initEditThread();
tinymce.get('uv-edit-thread').destroy()
if(url = xhr.getResponseHeader('Location'))
window.location = url;
var response = warningResponse;
if(xhr.responseJSON)
response = xhr.responseJSON;
app.appView.hideLoader()
app.appView.renderResponseAlert(response);
}
});
} else {
this.$el.find('.uv-element-block-textarea').append("<span class='uv-field-message'>{{ 'This field is mandatory'|trans }}</span>");
}
},
toggleCreateTaskBar : function() {
if(threadIds.length) {
$("#uv-task-view").css('right', '0px');
$("#uv-task-view .uv-create-task").show()
$("#uv-task-view .uv-task-list").hide()
} else {
$("#uv-task-view").css('right', '-300px');
$("#uv-task-view .uv-create-task").hide()
$("#uv-task-view .uv-task-list").show()
}
},
copyThreadLink: function(e){
_.delay(function(){
$(e.currentTarget).before('<input type="text" class="input-copy-thread-link uv-field" value="' + window.location.href + '"/>');
$(e.currentTarget).prev().focus().select();
}, 100);
},
removeCopyThreadLink: function(e){
$(e.currentTarget).remove();
},
toggleThreadPropertyIcon: function(e) {
if(jQuery.inArray(this.model.id, threadIds) !== -1 || this.model.get('bookmark') || this.model.get('isLocked')) {
this.$el.find('.uv-icon-pinned').parents('.uv-ticket-strip').show()
} else {
this.$el.find('.uv-icon-pinned').parents('.uv-ticket-strip').hide()
}
if(jQuery.inArray(this.model.id, threadIds) !== -1)
this.$el.find('.uv-icon-marked-task').parent().show()
else
this.$el.find('.uv-icon-marked-task').parent().hide()
if(this.model.get('bookmark'))
this.$el.find('.uv-icon-pinned').parent().show()
else
this.$el.find('.uv-icon-pinned').parent().hide()
if(this.model.get('isLocked'))
this.$el.find('.uv-icon-locked').parent().show()
else
this.$el.find('.uv-icon-locked').parent().hide()
}
});
// Ticket Thread List
var ThreadList = Backbone.View.extend({
el : $(".thread-list"),
initialize : function() {
this.listenTo(threadCollection.fullCollection, "add", this.renderThread);
},
renderThread : function (item) {
var threadItem = new ThreadItem({
model: item
});
if(item.id < threadCollection.fullCollection.at(0).id)
this.$el.prepend(threadItem.render().el);
else
this.$el.append(threadItem.render().el);
threadItem.$el.find('.helpdesk_blockquote').eq(0).before("<span class='uv-icon-ellipsis uv-ellipsis-mirror'></span>").hide();
//emojifyRun();
this.$el.find('img').removeAttr('crossorigin');
this.$el.find('div.message a').attr('target', '_blank');
app.appView.relativeTime();
}
});
// Ticket Pagination View
var Pagination = Backbone.View.extend({
el: $('.uv-ticket-accordion'),
events: {
'click .uv-ticket-count-stat': 'loadMore',
},
renderPagination: function(pagination) {
if(pagination.totalCount - pagination.lastItemNumber > 0 && pagination.lastItemNumber > 0) {
var remain = pagination.totalCount - pagination.lastItemNumber;
$('.uv-ticket-count-stat').text(remain)
$('.uv-ticket-accordion').removeClass('uv-ticket-accordion-expanded').removeClass('uv-ticket-accordion-no-count')
} else {
$('.uv-ticket-accordion').addClass('uv-ticket-accordion-expanded').addClass('uv-ticket-accordion-no-count')
}
},
loadMore: function() {
threadCollection.syncData();
}
});
// Ticket collaborator Item View
var CollaboratorItem = Backbone.View.extend({
tagName : "a",
className: 'uv-btn-tag',
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 %}"),
events : {
'click .uv-tag' : 'confirmRemove'
},
render : function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
unrender : function(response) {
if(response.alertMessage != undefined) {
app.appView.renderResponseAlert(response);
}
},
removeItem: function() {
{% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_COLLABORATOR_TO_TICKET') %}
self = this;
app.appView.showLoader();
this.model.destroy({
data : { 'ticketId' : this.model.attributes.ticketId },
success : function (model, response, options) {
app.appView.hideLoader();
self.$el.remove();
self.unrender(response);
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
var response = warningResponse;
if(xhr.responseJSON)
response = xhr.responseJSON;
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
}
});
{% endif %}
},
confirmRemove: function(e) {
e.preventDefault();
{% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_COLLABORATOR_TO_TICKET') %}
app.appView.openConfirmModal(this);
{% endif %}
}
});
// Ticket Collaborator View
var CollaboratorList = Backbone.View.extend({
el : $(".collaborator-list-block"),
events : {
'keypress .uv-field' : 'addCollaborator',
'focusout .uv-field' : 'removeErrorClass'
},
initialize : function() {
//Backbone.Validation.bind(this);
},
render : function() {
this.$el.find(".collaborator-list").html('');
var self = this;
collaboratorOptionHtml = '';
if(collaboratorCollection.length) {
_.each(collaboratorCollection.models, function (item) {
this.renderCollaborator(item);
}, this);
}
ticketView.addCCCollaborators()
},
renderCollaborator : function (item) {
var collaborator = new CollaboratorItem({
model: item
});
this.$el.find('.collaborator-list').append(collaborator.render().el);
},
removeErrorClass: function(e) {
var inputElement = Backbone.$(e.currentTarget);
inputElement.removeClass('uv-field-error');
inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
},
addCollaborator : function(e) {
{% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_COLLABORATOR_TO_TICKET') %}
var inputElement = Backbone.$(e.currentTarget);
inputElement.removeClass('uv-field-error');
inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
var text = inputElement.val().trim();
if (e.which === 13 && text) {
this.model = new CollaboratorModel();
self = this;
this.model.set({email: text})
if(this.model.isValid(true)) {
app.appView.showLoader();
this.model.save({},{
success : function (model, response, options) {
inputElement.val('');
if(response.alertClass == "success") {
collaboratorCollection.add(model);
}
self.render();
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
var response = warningResponse;
if(xhr.responseJSON)
response = xhr.responseJSON;
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
}
});
} else {
inputElement.addClass('uv-field-error');
if(text)
inputElement.parents('.uv-element-block').append("<span class='uv-field-message'>{{ 'Email address is invalid'|trans }}</span>");
}
}
{% endif %}
}
});
// Ticket Tag Item View
var TagItem = Backbone.View.extend({
tagName : "a",
className : "uv-btn-tag",
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>"),
events : {
'click .uv-tag' : "confirmRemove"
},
render : function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
unrender : function(response) {
if(response.alertMessage != undefined) {
tagListView.render();
app.appView.renderResponseAlert(response);
}
},
removeItem : function () {
{% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_TAG') %}
self = this;
app.appView.showLoader();
this.model.destroy({
data : { 'ticketId' : ticketModel.id } ,
success : function (model, response, options) {
app.appView.hideLoader();
self.$el.remove();
self.unrender(response);
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
var response = warningResponse;
if(xhr.responseJSON)
response = xhr.responseJSON;
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
}
});
{% endif %}
},
confirmRemove: function(e) {
e.preventDefault();
{% if user_service.isAccessAuthorized('ROLE_AGENT_DELETE_TAG') %}
app.appView.openConfirmModal(this)
{% endif %}
}
});
// Ticket Tag View
var TagList = Backbone.View.extend({
el : $(".tag-list-block"),
events : {
'keypress .uv-field' : 'addTag',
'focusout .uv-field' : 'removeErrorClass',
'click .uv-dropdown-list li': 'addTag'
},
render : function() {
var self = this;
this.$el.find(".tag-list").html('');
if(tagCollection.length) {
_.each(tagCollection.models, function (item) {
this.renderTag(item);
}, this);
}
},
renderTag : function (item) {
var tag = new TagItem({
model: item
});
this.$el.find('.tag-list').append(tag.render().el);
},
addTag : function(e) {
{% if user_service.isAccessAuthorized('ROLE_AGENT_ADD_TAG') %}
var currentElement = Backbone.$(e.currentTarget);
if(currentElement.is('li')) {
var inputElement = currentElement.parents('.uv-field-block').find('.uv-dropdown-other');
var text = currentElement.text().trim();
} else {
var inputElement = currentElement;
var text = inputElement.val().trim();
}
inputElement.removeClass('uv-field-error');
inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
if (currentElement.is('li') || (e.which === 13 && text)) {
if(text.length <= 20) {
if(tagCollection.isTagExist(text)) {
var self = this;
inputElement.val('');
this.model = new TagModel();
this.model.set({name:text});
self = this;
app.appView.showLoader();
this.model.save({}, {
success: function (model, response, options) {
inputElement.parent().find("li:not(.uv-no-results)").remove()
inputElement.parent().find(".uv-no-results").show()
if(!currentElement.is('li')) {
inputElement.trigger('click')
}
if(response.alertClass == "success") {
tagCollection.add(model);
self.render();
}
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
var response = warningResponse;
if(xhr.responseJSON)
response = xhr.responseJSON;
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
}
});
} else {
inputElement.addClass('uv-field-error');
inputElement.parents('.uv-element-block').append("<span class='uv-field-message'>{{ 'Tag with same name already exist'|trans }}</span>");
}
} else {
inputElement.addClass('uv-field-error');
inputElement.parents('.uv-element-block').append("<span class='uv-field-message'>{{ 'Text length should be less than 20 charactors'|trans }}</span>");
}
}
{% endif %}
},
removeErrorClass: function(e) {
var inputElement = Backbone.$(e.currentTarget);
inputElement.removeClass('uv-field-error');
inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
},
});
// Ticket Label Item View
var LabelItem = Backbone.View.extend({
tagName : "a",
className : "uv-btn-label",
template : _.template("<span class='uv-tag'><span class='uv-icon-remove-before'></span><%- name %></span>"),
events : {
'click .uv-tag' : "confirmRemove"
},
render : function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
unrender : function(response) {
if(response.alertMessage != undefined) {
labelListView.render();
app.appView.renderResponseAlert(response);
}
},
removeItem : function () {
self = this;
app.appView.showLoader();
this.model.destroy({
url : "{{ path('helpdesk_member_update_ticket_attributes_xhr') }}",
data : { attribute :'label', 'ticketId': ticketModel.id, 'labelId': this.model.get('id') },
success : function (model, response, options) {
app.appView.hideLoader();
self.$el.remove();
self.unrender(response);
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
var response = warningResponse;
if(xhr.responseJSON)
response = xhr.responseJSON;
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
}
});
},
confirmRemove: function(e) {
e.preventDefault();
app.appView.openConfirmModal(this)
}
});
// Ticket Label View
var LabelList = Backbone.View.extend({
el : $(".label-list-block"),
events : {
'keypress .uv-field' : 'addLabel',
'focusout .uv-field' : 'removeErrorClass',
'click .uv-dropdown-list li': 'addLabel'
},
render : function() {
var self = this;
this.$el.find(".label-list").html('');
if(labelCollection.length) {
_.each(labelCollection.models, function (item) {
this.renderLabel(item);
}, this);
}
},
renderLabel : function (item) {
var label = new LabelItem({
model: item
});
lavelItem = label.render().el;
$(lavelItem).attr('style', 'background:' + item.attributes.color)
this.$el.find('.label-list').append(lavelItem);
},
addLabel : function(e) {
var currentElement = Backbone.$(e.currentTarget);
if(currentElement.is('li')) {
var inputElement = currentElement.parents('.uv-field-block').find('.uv-dropdown-other');
var text = currentElement.text().trim();
} else {
var inputElement = currentElement;
var text = inputElement.val().trim();
}
inputElement.removeClass('uv-field-error');
inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
if (currentElement.is('li') || (e.which === 13 && text)) {
if(text.length <= 20) {
if(labelCollection.isLabelExist(text)) {
var self = this;
inputElement.val('');
this.model = new LabelModel();
this.model.set({name:text});
self = this;
app.appView.showLoader();
this.model.save({}, {
success: function (model, response, options) {
inputElement.parent().find("li:not(.uv-no-results)").remove()
inputElement.parent().find(".uv-no-results").show()
if(!currentElement.is('li')) {
inputElement.trigger('click')
}
if(response.alertClass == "success") {
labelCollection.add(model);
self.render();
}
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
},
error: function (model, xhr, options) {
if(url = xhr.getResponseHeader('Location'))
window.location = url;
var response = warningResponse;
if(xhr.responseJSON)
response = xhr.responseJSON;
app.appView.hideLoader();
app.appView.renderResponseAlert(response);
}
});
} else {
inputElement.addClass('uv-field-error');
inputElement.parents('.uv-element-block').append("<span class='uv-field-message'>{{ 'Label with same name already exist'|trans }}</span>");
}
} else {
inputElement.addClass('uv-field-error');
inputElement.parents('.uv-element-block').append("<span class='uv-field-message'>{{ 'Text length should be less than 20 charactors'|trans }}</span>");
}
}
},
removeErrorClass: function(e) {
var inputElement = Backbone.$(e.currentTarget);
inputElement.removeClass('uv-field-error');
inputElement.parents('.uv-element-block').find('.uv-field-message').remove()
},
});
// Ticket Router
var Router = Backbone.Router.extend({
routes: {
'thread/:thread' : 'threadRequestedId'
},
threadRequestedId: function(thread){
threadCollection.threadRequestedId = thread;
},
scrollPage : function(divId) {
if($(divId).length){
$('li a[href="'+divId+'"]').trigger('click');
$('.uv-ticket-scroll-region').animate({
scrollTop: $(divId).offset().top
}, 'slow');
} else if(divId == '#') { //scroll to last thread added
if(threadCollection.fullCollection.length)
this.scrollPage('#thread' + threadCollection.fullCollection.at(0).id);
}
}
});
var customerForm = new CustomerForm({
el : $(".uv-main-info-update-block"),
model : new CustomerModel()
});
var ticketNavigation = $.parseJSON('{{ ticketNavigationIteration|json_encode|raw }}');
var ticketModel = new TicketModel({
id : "{{ ticket.id }}",
status : "{{ ticket.status.id }}",
priority : "{{ ticket.priority.id }}",
group : "{{ ticket.supportGroup ? ticket.supportGroup.id : '' }}",
subGroup : "{{ ticket.supportTeam ? ticket.supportTeam.id : '' }}",
agent : "",
profileImage : "",
isTrashed : "{{ ticket.isTrashed }}"
});
ticketApp.ticketView = ticketView = new TicketView({
model: ticketModel
});
uvdesk.ticket.model = ticketModel;
threadCollection = new ThreadCollection();
var threadList = new ThreadList();
var pagination = new Pagination();
var collaboratorCollection = new CollaboratorCollection($.parseJSON('{{ ticket_service.getTicketCollaborators(ticket.id)|json_encode|raw }}'));
var collaboratorList = new CollaboratorList();
collaboratorList.render();
var tagCollection = new TagCollection($.parseJSON('{{ ticket_service.getTicketTagsById(ticket.id)|json_encode|raw }}'));
var tagListView = new TagList();
tagListView.render();
var labelCollection = new LabelCollection($.parseJSON('{{ ticket_service.getTicketLabels(ticket.id)|json_encode|raw }}'));
var labelListView = new LabelList();
labelListView.render();
var router = new Router();
Backbone.history.start({push_state:true});
threadCollection.syncData();
});
</script>
<script>
var sfTinyMceNew = $.extend({}, sfTinyMce);
var toolbarOptions = sfTinyMce.options.toolbar;
sfTinyMce.init({
selector : '.uv-ticket-reply textarea',
toolbar: toolbarOptions + ' | translate',
mentions : getMentions(),
images_upload_url: "",
setup: function(editor) {
editor.on('keydown', function(e) { /** for pageup, pagedown keys **/
if(e.keyCode == 34 || e.keyCode == 33){
e.preventDefault();
}
});
addTranslateButton(editor);
}
});
function InitTinyMce(selector) {
let sfTinyMceNew2 = $.extend({}, sfTinyMceNew);
sfTinyMceNew2.init({
selector : selector,
mentions : getMentions(),
setup: function(editor) {
addTranslateButton(editor);
}
});
}
function getMentions(){
return {
delimiter: ['#'],
items: 15,
source: function(){
return [
{
name : "{{ 'Ticket Id'|trans }}",
value : "{{ ticket.id }}",
},
{
name : "{{ 'Subject'|trans }}",
value : "{{ ticket.subject|replace({"\n":' ', "\r":' '}) }}",
},
{
name : "{{ 'Status'|trans }}",
value : "{{ ticket.status.description }}",
},
{
name : "{{ 'Priority'|trans }}",
value : "{{ ticket.priority.description|trans }}",
},
{
name : "{{ 'Type'|trans }}",
value : "{{ ticket.type ? ticket.type.description : 'Not Assigned'|trans }}",
},
{
name : "{{ 'Group'|trans }}",
value : "{{ ticket.supportGroup ? ticket.supportGroup.description : 'Not Assigned'|trans }}",
},
{
name : "{{ 'Team'|trans }}",
value : "{{ ticket.supportTeam ? ticket.supportTeam.description : 'Not Assigned'|trans }}",
},
{
name : "{{ 'Customer Name'|trans }}",
value : "{{ customer.name }}",
},
{
name : "{{ 'Customer Email'|trans }}",
value : "{{ customer.email }}",
},
{
name : "{{ 'Agent Name'|trans }}",
value : "{{ ticketAgent.name is defined ? ticketAgent.name : 'Not Assigned'|trans }}",
},
{
name : "{{ 'Agent Email'|trans }}",
value : "{{ ticketAgent.email is defined ? ticketAgent.email : 'Not Assigned'|trans }}",
}
];
},
insert: function(item) {
return '<span>' + item.value + '</span>';
}
};
}
</script>
{% endblock %}