Support: Give users the ability to close tickets themselves (#925)

* User can close ticket (#879)

* Localization

* Update SupportPresenter.php

* Update View.xml
This commit is contained in:
n1rwana 2023-08-11 02:11:40 +03:00 committed by GitHub
parent 8ca3de8afa
commit 7f46d683c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 52 additions and 5 deletions

View file

@ -385,7 +385,7 @@ final class SupportPresenter extends OpenVKPresenter
$agent->setNumerate((int) $this->postParam("number") ?? NULL); $agent->setNumerate((int) $this->postParam("number") ?? NULL);
$agent->setIcon($this->postParam("avatar")); $agent->setIcon($this->postParam("avatar"));
$agent->save(); $agent->save();
$this->flashFail("succ", "Успех", "Профиль отредактирован."); $this->flashFail("succ", tr("agent_profile_edited"));
} else { } else {
$agent = new SupportAgent; $agent = new SupportAgent;
$agent->setAgent($this->user->identity->getId()); $agent->setAgent($this->user->identity->getId());
@ -393,7 +393,27 @@ final class SupportPresenter extends OpenVKPresenter
$agent->setNumerate((int) $this->postParam("number") ?? NULL); $agent->setNumerate((int) $this->postParam("number") ?? NULL);
$agent->setIcon($this->postParam("avatar")); $agent->setIcon($this->postParam("avatar"));
$agent->save(); $agent->save();
$this->flashFail("succ", "Успех", "Профиль создан. Теперь пользователи видят Ваши псевдоним и аватарку вместо стандартных аватарки и номера."); $this->flashFail("succ", tr("agent_profile_created_1"), tr("agent_profile_created_2"));
} }
} }
function renderCloseTicket(int $id): void
{
$this->assertUserLoggedIn();
$this->assertNoCSRF();
$this->willExecuteWriteAction();
$ticket = $this->tickets->get($id);
if($ticket->isDeleted() === 1 || $ticket->getType() === 2 || $ticket->getUserId() !== $this->user->id) {
header("HTTP/1.1 403 Forbidden");
header("Location: /support/view/" . $id);
exit;
}
$ticket->setType(2);
$ticket->save();
$this->flashFail("succ", tr("ticket_changed"), tr("ticket_changed_comment"));
}
} }

View file

@ -55,7 +55,6 @@
<input name="name" type="text" value="{$agent->getCanonicalName()}" placeholder="{_helpdesk_agent} #777" /> <input name="name" type="text" value="{$agent->getCanonicalName()}" placeholder="{_helpdesk_agent} #777" />
<br/><br/> <br/><br/>
<label for="number">{_helpdesk_show_number}?</label> <label for="number">{_helpdesk_show_number}?</label>
{$agent->isShowNumber()}
<select name="number"> <select name="number">
<option value="1" n:attr="selected => $agent->isShowNumber() === 1 ? true : false">{_yes}</option> <option value="1" n:attr="selected => $agent->isShowNumber() === 1 ? true : false">{_yes}</option>
<option value="0" n:attr="selected => $agent->isShowNumber() === 0 ? true : false">{_no}</option> <option value="0" n:attr="selected => $agent->isShowNumber() === 0 ? true : false">{_no}</option>
@ -71,7 +70,7 @@
</div> </div>
</div> </div>
{else} {else}
<h4>Создать</h4> <h4>{_create}</h4>
<br/> <br/>
<form method="post" action="/support/agent{$agent_id}/edit"> <form method="post" action="/support/agent{$agent_id}/edit">
<label for="name">{_helpdesk_showing_name}</label> <label for="name">{_helpdesk_showing_name}</label>

View file

@ -19,7 +19,7 @@
<a n:attr="id => ($act === 'closed' ? 'act_tab_a' : 'ki')" href="?act=closed">{_support_closed}</a> <a n:attr="id => ($act === 'closed' ? 'act_tab_a' : 'ki')" href="?act=closed">{_support_closed}</a>
</div> </div>
<div class="tab"> <div class="tab">
<a href="/support/agent{$thisUser->getId()}">Мой профиль</a> <a href="/support/agent{$thisUser->getId()}">{_agent_profile}</a>
</div> </div>
{/block} {/block}

View file

@ -27,6 +27,14 @@
function errorHandler(id, mark) { function errorHandler(id, mark) {
document.getElementById("markText-" + id).innerHTML = {_error}; document.getElementById("markText-" + id).innerHTML = {_error};
} }
function closeTicket() {
let url = `/support/ticket${{$ticket->getId()}}/close?hash=${{urlencode($csrfToken)}}`;
$.ajax(url, {
error: () => alert(tr("error")),
success: () => location.reload()
});
}
</script> </script>
{if $ticket->isDeleted() == 0} {if $ticket->isDeleted() == 0}
@ -34,6 +42,11 @@
<a href="#" style="font-size:13px;"><b>{$ticket->getName()}</b></a> <a href="#" style="font-size:13px;"><b>{$ticket->getName()}</b></a>
<br />{_status}: {$ticket->getStatus()} <br />{_status}: {$ticket->getStatus()}
</div> </div>
{if $ticket->getType() === 1}
<div class="post-author" style="border-top: none; padding: 14px; margin-top: 14px;">
{_you_can_close_this_ticket_1} <a onClick="closeTicket()">{_you_can_close_this_ticket_2}</a>.
</div>
{/if}
<div class="text" style="padding-top: 10px; border-bottom: #ECECEC solid 1px;"> <div class="text" style="padding-top: 10px; border-bottom: #ECECEC solid 1px;">
{$ticket->getText()|noescape} {$ticket->getText()|noescape}
<br /></br> <br /></br>

View file

@ -35,6 +35,8 @@ routes:
handler: "Support->agent" handler: "Support->agent"
- url: "/support/agent{num}/edit" - url: "/support/agent{num}/edit"
handler: "Support->editAgent" handler: "Support->editAgent"
- url: "/support/ticket{num}/close"
handler: "Support->closeTicket"
- url: "/language" - url: "/language"
handler: "About->language" handler: "About->language"
- url: "/language/{text}.js" - url: "/language/{text}.js"

View file

@ -915,6 +915,13 @@
"banned_in_support_1" = "Sorry, <b>$1</b>, but now you can't create tickets."; "banned_in_support_1" = "Sorry, <b>$1</b>, but now you can't create tickets.";
"banned_in_support_2" = "And the reason for this is simple: <b>$1</b>. Unfortunately, this time we had to take away this opportunity from you forever."; "banned_in_support_2" = "And the reason for this is simple: <b>$1</b>. Unfortunately, this time we had to take away this opportunity from you forever.";
"you_can_close_this_ticket_1" = "If you have no more questions, you can ";
"you_can_close_this_ticket_2" = "close this ticket";
"agent_profile_created_1" = "Profile created";
"agent_profile_created_2" = "Now users see your customized name and avatar instead of the default ones.";
"agent_profile_edited" = "Profile edited";
"agent_profile" = "My Agent Card";
/* Invite */ /* Invite */
"invite" = "Invite"; "invite" = "Invite";

View file

@ -842,6 +842,12 @@
"ticket_changed_comment" = "Изменения вступят силу через несколько секунд."; "ticket_changed_comment" = "Изменения вступят силу через несколько секунд.";
"banned_in_support_1" = "Извините, <b>$1</b>, но теперь вам нельзя создавать обращения."; "banned_in_support_1" = "Извините, <b>$1</b>, но теперь вам нельзя создавать обращения.";
"banned_in_support_2" = "А причина этому проста: <b>$1</b>. К сожалению, на этот раз нам пришлось отобрать у вас эту возможность навсегда."; "banned_in_support_2" = "А причина этому проста: <b>$1</b>. К сожалению, на этот раз нам пришлось отобрать у вас эту возможность навсегда.";
"you_can_close_this_ticket_1" = "Если у Вас больше нет вопросов, Вы можете ";
"you_can_close_this_ticket_2" = "закрыть этот тикет";
"agent_profile_created_1" = "Профиль создан";
"agent_profile_created_2" = "Теперь пользователи видят Ваши псевдоним и аватарку вместо стандартных аватарки и номера.";
"agent_profile_edited" = "Профиль отредактирован";
"agent_profile" = "Карточка агента";
/* Invite */ /* Invite */