Локализация

This commit is contained in:
n1rwana 2022-08-20 23:59:25 +03:00
parent 08859fadd8
commit 1699af5c40
6 changed files with 199 additions and 67 deletions

View file

@ -42,7 +42,16 @@ class BugReport extends RowModel
function getStatus(): string function getStatus(): string
{ {
$list = ["Открыт", "На рассмотрении", "В работе", "Исправлен", "Закрыт", "Требует корректировки", "Заблокирован", "Отклонён"]; $list = [
tr("bug_tracker_status_open"),
tr("bug_tracker_status_under_review"),
tr("bug_tracker_status_in_progress"),
tr("bug_tracker_status_fixed"),
tr("bug_tracker_status_closed"),
tr("bug_tracker_status_requires_adjustment"),
tr("bug_tracker_status_locked"),
tr("bug_tracker_status_rejected")
];
$status_id = $this->getRecord()->status; $status_id = $this->getRecord()->status;
return $list[$status_id]; return $list[$status_id];
@ -55,7 +64,14 @@ class BugReport extends RowModel
function getPriority(): string function getPriority(): string
{ {
$list = ["Пожелание", "Низкий", "Средний", "Высокий", "Критический", "Уязвимость"]; $list = [
tr("bug_tracker_priority_feature"),
tr("bug_tracker_priority_low"),
tr("bug_tracker_priority_medium"),
tr("bug_tracker_priority_high"),
tr("bug_tracker_priority_critical"),
tr("bug_tracker_priority_vulnerability")
];
$priority_id = $this->getRecord()->priority; $priority_id = $this->getRecord()->priority;
return $list[$priority_id]; return $list[$priority_id];
@ -80,4 +96,9 @@ class BugReport extends RowModel
{ {
return new DateTime($this->getRecord()->created); return new DateTime($this->getRecord()->created);
} }
function isDeleted(): bool
{
return (bool) $this->getRecord()->deleted;
}
} }

View file

@ -59,7 +59,7 @@ final class BugtrackerPresenter extends OpenVKPresenter
$this->template->canAdminBugTracker = $this->user->identity->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL); $this->template->canAdminBugTracker = $this->user->identity->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL);
} else { } else {
$this->flashFail("err", "Отчёт не найден. Возможно, он был удалён."); $this->flashFail("err", tr("bug_tracker_report_not_found"));
} }
} }
@ -71,7 +71,16 @@ final class BugtrackerPresenter extends OpenVKPresenter
$status = $this->postParam("status"); $status = $this->postParam("status");
$comment = $this->postParam("text"); $comment = $this->postParam("text");
$points = $this->postParam("points-count"); $points = $this->postParam("points-count");
$list = ["Открыт", "На рассмотрении", "В работе", "Исправлен", "Закрыт", "Требует корректировки", "Заблокирован", "Отклонён"]; $list = [
tr("bug_tracker_status_open"),
tr("bug_tracker_status_under_review"),
tr("bug_tracker_status_in_progress"),
tr("bug_tracker_status_fixed"),
tr("bug_tracker_status_closed"),
tr("bug_tracker_status_requires_adjustment"),
tr("bug_tracker_status_locked"),
tr("bug_tracker_status_rejected")
];
$report = (new BugtrackerReports)->get($report_id); $report = (new BugtrackerReports)->get($report_id);
$report->setStatus($status); $report->setStatus($status);
@ -81,8 +90,8 @@ final class BugtrackerPresenter extends OpenVKPresenter
$report->save(); $report->save();
$this->createComment($report, $comment, "Новый статус отчёта$list[$status]", TRUE); $this->createComment($report, $comment, tr("bug_tracker_new_report_status") . "$list[$status]", TRUE);
$this->flashFail("succ", "Изменения сохранены", "Новый статус отчёта$list[$status]"); $this->flashFail("succ", tr("changes_saved"), tr("bug_tracker_new_report_status") . "$list[$status]");
} }
function renderChangePriority(int $report_id): void function renderChangePriority(int $report_id): void
@ -93,7 +102,14 @@ final class BugtrackerPresenter extends OpenVKPresenter
$priority = $this->postParam("priority"); $priority = $this->postParam("priority");
$comment = $this->postParam("text"); $comment = $this->postParam("text");
$points = $this->postParam("points-count"); $points = $this->postParam("points-count");
$list = ["Пожелание", "Низкий", "Средний", "Высокий", "Критический", "Уязвимость"]; $list = [
tr("bug_tracker_priority_feature"),
tr("bug_tracker_priority_low"),
tr("bug_tracker_priority_medium"),
tr("bug_tracker_priority_high"),
tr("bug_tracker_priority_critical"),
tr("bug_tracker_priority_vulnerability")
];
$report = (new BugtrackerReports)->get($report_id); $report = (new BugtrackerReports)->get($report_id);
$report->setPriority($priority); $report->setPriority($priority);
@ -103,8 +119,8 @@ final class BugtrackerPresenter extends OpenVKPresenter
$report->save(); $report->save();
$this->createComment($report, $comment, "Новый приоритет отчёта$list[$priority]", TRUE); $this->createComment($report, $comment, tr("bug_tracker_new_report_priority") . "$list[$priority]", TRUE);
$this->flashFail("succ", "Изменения сохранены", "Новый приоритет отчёта$list[$priority]"); $this->flashFail("succ", tr("changes_saved"), tr("bug_tracker_new_report_priority") . "$list[$priority]");
} }
function createComment(?BugReport $report, string $text, string $label = "", bool $is_moder = FALSE, bool $is_hidden = FALSE) function createComment(?BugReport $report, string $text, string $label = "", bool $is_moder = FALSE, bool $is_hidden = FALSE)
@ -112,10 +128,10 @@ final class BugtrackerPresenter extends OpenVKPresenter
$moder = $this->user->identity->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL); $moder = $this->user->identity->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL);
if (!$text && !$label) if (!$text && !$label)
$this->flashFail("err", "Ошибка", "Комментарий не может быть пустым."); $this->flashFail("err", tr("error"), tr("bug_tracker_empty_comment"));
if ($report->getRawStatus() == 6 && !$moder) if ($report->getRawStatus() == 6 && !$moder)
$this->flashFail("err", "Ошибка доступа"); $this->flashFail("err", tr("forbidden"));
DB::i()->getContext()->table("bt_comments")->insert([ DB::i()->getContext()->table("bt_comments")->insert([
"report" => $report->getId(), "report" => $report->getId(),
@ -126,7 +142,7 @@ final class BugtrackerPresenter extends OpenVKPresenter
"label" => $label "label" => $label
]); ]);
$this->flashFail("succ", "Успех", "Комментарий отправлен."); $this->flashFail("succ", tr("bug_tracker_success"), tr("bug_tracker_comment_sent"));
} }
function renderAddComment(int $report_id): void function renderAddComment(int $report_id): void
@ -153,7 +169,7 @@ final class BugtrackerPresenter extends OpenVKPresenter
$device = $this->postParam("device"); $device = $this->postParam("device");
if (!$title || !$text || !$priority || !$product || !$device) if (!$title || !$text || !$priority || !$product || !$device)
$this->flashFail("err", "Ошибка", "Заполнены не все поля"); $this->flashFail("err", tr("error"), tr("bug_tracker_fields_error"));
$id = DB::i()->getContext()->table("bugs")->insert([ $id = DB::i()->getContext()->table("bugs")->insert([
"reporter" => $this->user->identity->getId(), "reporter" => $this->user->identity->getId(),
@ -176,7 +192,7 @@ final class BugtrackerPresenter extends OpenVKPresenter
$moder = $this->user->identity->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL); $moder = $this->user->identity->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL);
if (!$moder) if (!$moder)
$this->flashFail("err", "Ошибка доступа"); $this->flashFail("err", tr("forbidden"));
$title = $this->postParam("title"); $title = $this->postParam("title");
$description = $this->postParam("description"); $description = $this->postParam("description");
@ -198,10 +214,10 @@ final class BugtrackerPresenter extends OpenVKPresenter
$report = (new BugtrackerReports)->get($report_id); $report = (new BugtrackerReports)->get($report_id);
if ($report->getReporter()->getId() === $this->user->identity->getId()) if ($report->getReporter()->getId() === $this->user->identity->getId())
$this->flashFail("err", "Ошибка доступа"); $this->flashFail("err", tr("forbidden"));
DB::i()->getContext()->table("bugs")->where("id", $report_id)->update("reproduced", $report->getReproducedCount() + 1); DB::i()->getContext()->table("bugs")->where("id", $report_id)->update("reproduced", $report->getReproducedCount() + 1);
$this->flashFail("succ", "Успех", "Вы отметили, что у Вас получилось воспроизвести этот баг."); $this->flashFail("succ", tr("bug_tracker_success"), tr("bug_tracker_reproduced_text"));
} }
} }

View file

@ -1,36 +1,36 @@
{extends "../@layout.xml"} {extends "../@layout.xml"}
{block title}Баг-трекер{/block} {block title}{_bug_tracker}{/block}
{block header} {block header}
Баг-трекер {_bug_tracker}
{/block} {/block}
{block content} {block content}
<div class="tabs"> <div class="tabs">
<div n:attr='id => $mode === "list" ? "activetabs" : false' class="tab"> <div n:attr='id => $mode === "list" ? "activetabs" : false' class="tab">
<a n:attr='id => $mode === "list" ? "act_tab_a" : false' href="/bugtracker"> <a n:attr='id => $mode === "list" ? "act_tab_a" : false' href="/bugtracker">
Отчёты {_bug_tracker_reports}
</a> </a>
</div> </div>
<div n:attr='id => $mode === "products" ? "activetabs" : false' class="tab"> <div n:attr='id => $mode === "products" ? "activetabs" : false' class="tab">
<a n:attr='id => $mode === "products" ? "act_tab_a" : false' href="/bugtracker?act=products"> <a n:attr='id => $mode === "products" ? "act_tab_a" : false' href="/bugtracker?act=products">
Продукты {_bug_tracker_products}
</a> </a>
</div> </div>
<div n:attr='id => $mode === "reporter" ? "activetabs" : false' class="tab"> <div n:attr='id => $mode === "reporter" ? "activetabs" : false' class="tab">
<a n:attr='id => $mode === "reporter" ? "act_tab_a" : false' href="/bugtracker?act=reporter&id={$user->id}"> <a n:attr='id => $mode === "reporter" ? "act_tab_a" : false' href="/bugtracker?act=reporter&id={$user->id}">
Карточка тестировщика {_bug_tracker_reporter_card}
</a> </a>
</div> </div>
<div n:if='in_array($mode, ["list", "new"])' n:attr='id => $mode === "new" ? "activetabs" : false' class="tab" style="float: right;"> <div n:if='in_array($mode, ["list", "new"])' n:attr='id => $mode === "new" ? "activetabs" : false' class="tab" style="float: right;">
<a n:attr='id => $mode === "new" ? "act_tab_a" : false' href="/bugtracker?act=new"> <a n:attr='id => $mode === "new" ? "act_tab_a" : false' href="/bugtracker?act=new">
Создать {_create}
</a> </a>
</div> </div>
<div n:if='in_array($mode, ["products", "new_product"])' n:attr='id => $mode === "new_product" ? "activetabs" : false' class="tab" style="float: right;"> <div n:if='in_array($mode, ["products", "new_product"])' n:attr='id => $mode === "new_product" ? "activetabs" : false' class="tab" style="float: right;">
<a n:attr='id => $mode === "new_product" ? "act_tab_a" : false' href="/bugtracker?act=new_product"> <a n:attr='id => $mode === "new_product" ? "act_tab_a" : false' href="/bugtracker?act=new_product">
Создать {_create}
</a> </a>
</div> </div>
</div> </div>
@ -59,25 +59,25 @@
<table id="basicInfo" class="ugc-table group_info" cellspacing="0" cellpadding="0" border="0"> <table id="basicInfo" class="ugc-table group_info" cellspacing="0" cellpadding="0" border="0">
<tbody> <tbody>
<tr> <tr>
<td class="label"><span class="nobold">Продукт:</span></td> <td class="label"><span class="nobold">{_bug_tracker_product}:</span></td>
<td class="data"><a href="#">{$bug->getProduct()->getCanonicalName()}</a></td> <td class="data"><a href="#">{$bug->getProduct()->getCanonicalName()}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Отправил: </span></td> <td class="label"><span class="nobold">{_bug_tracker_sent_by}: </span></td>
<td class="data"> <td class="data">
<a href="/bugtracker?act=reporter&id={$bug->getReporter()->getId()}">{$bug->getReporter()->getCanonicalName()}</a> <a href="/bugtracker?act=reporter&id={$bug->getReporter()->getId()}">{$bug->getReporter()->getCanonicalName()}</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Воспроизвелось:</span></td> <td class="label"><span class="nobold">{_bug_tracker_reproduced}:</span></td>
<td class="data"><a href="#">{tr("participants", $bug->getReproducedCount())}</a></td> <td class="data"><a href="#">{tr("participants", $bug->getReproducedCount())}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Статус:</span></td> <td class="label"><span class="nobold">{_status}:</span></td>
<td class="data"><a href="#">{$bug->getStatus()}</a></td> <td class="data"><a href="#">{$bug->getStatus()}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Приоритет:</span></td> <td class="label"><span class="nobold">{_priority}:</span></td>
<td class="data"><a href="#">{$bug->getPriority()}</a></td> <td class="data"><a href="#">{$bug->getPriority()}</a></td>
</tr> </tr>
</tbody> </tbody>
@ -101,44 +101,44 @@
<form method="post" action="/bugtracker/create"> <form method="post" action="/bugtracker/create">
<input name="title" type="text" placeholder="Название отчёта"> <input name="title" type="text" placeholder="Название отчёта">
<br><br> <br><br>
<textarea placeholder="Описание бага" name="text" style="width: 100%;resize: vertical;"></textarea> <textarea placeholder="{_bug_tracker_bug_description}" name="text" style="width: 100%; resize: vertical;"></textarea>
<br><br> <br><br>
<select name="product"> <select name="product">
<option disabled>Продукт</option> <option disabled>{_bug_tracker_product}</option>
<option n:foreach="$open_products as $product" value="{$product->getId()}">{$product->getCanonicalName()}</option> <option n:foreach="$open_products as $product" value="{$product->getId()}">{$product->getCanonicalName()}</option>
</select> </select>
<br><br> <br><br>
<h4>Приоритет</h4> <h4>{_bug_tracker_priority}</h4>
<table> <table>
<tbody> <tbody>
<tr> <tr>
<td><input type="radio" name="priority" value="0"></td> <td><input type="radio" name="priority" value="0"></td>
<td><label for="priority_1">Пожелание</label></td> <td><label for="priority_1">{_bug_tracker_priority_feature}</label></td>
</tr> </tr>
<tr> <tr>
<td><input type="radio" name="priority" value="1"></td> <td><input type="radio" name="priority" value="1"></td>
<td><label for="priority_2">Низкий</label></td> <td><label for="priority_2">{_bug_tracker_priority_low}</label></td>
</tr> </tr>
<tr> <tr>
<td><input type="radio" name="priority" value="2"></td> <td><input type="radio" name="priority" value="2"></td>
<td><label for="priority_3">Средний</label></td> <td><label for="priority_3">{_bug_tracker_priority_medium}</label></td>
</tr> </tr>
<tr> <tr>
<td><input type="radio" name="priority" value="3"></td> <td><input type="radio" name="priority" value="3"></td>
<td><label for="priority_4">Высокий</label></td> <td><label for="priority_4">{_bug_tracker_priority_high}</label></td>
</tr> </tr>
<tr> <tr>
<td><input type="radio" name="priority" value="4"></td> <td><input type="radio" name="priority" value="4"></td>
<td><label for="priority_5">Критический</label></td> <td><label for="priority_5">{_bug_tracker_priority_critical}</label></td>
</tr> </tr>
<tr> <tr>
<td><input type="radio" name="priority" value="5"></td> <td><input type="radio" name="priority" value="5"></td>
<td><label for="priority_6">Уязвимость</label></td> <td><label for="priority_6">{_bug_tracker_priority_vulnerability}</label></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<br> <br>
<input type="text" name="device" placeholder="Устройство"> <input type="text" name="device" placeholder="{_bug_tracker_device}">
<br> <br>
<br> <br>
<input type="hidden" name="hash" value="{$csrfToken}" /> <input type="hidden" name="hash" value="{$csrfToken}" />
@ -166,20 +166,20 @@
<table id="basicInfo" class="ugc-table group_info" cellspacing="0" cellpadding="0" border="0"> <table id="basicInfo" class="ugc-table group_info" cellspacing="0" cellpadding="0" border="0">
<tbody> <tbody>
<tr> <tr>
<td class="label"><span class="nobold">Название:</span></td> <td class="label"><span class="nobold">{_bug_tracker_name}:</span></td>
<td class="data"> <td class="data">
<a href="#">{$product->getCanonicalName()}</a> <a href="#">{$product->getCanonicalName()}</a>
<b n:if="$product->isClosed()">(закрыт)</b> <b n:if="$product->isClosed()">({_bug_tracker_product_is_closed})</b>
</td> </td>
</tr> </tr>
<tr n:if="$canAdminBugTracker"> <tr n:if="$canAdminBugTracker">
<td class="label"><span class="nobold">Создал: </span></td> <td class="label"><span class="nobold">{_bug_tracker_product_created_by}: </span></td>
<td class="data"> <td class="data">
<a href="/bugtracker?act=reporter&id={$product->getCreator()->getId()}">{$product->getCreator()->getCanonicalName()}</a> <a href="/bugtracker?act=reporter&id={$product->getCreator()->getId()}">{$product->getCreator()->getCanonicalName()}</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Дата создания:</span></td> <td class="label"><span class="nobold">{_bug_tracker_product_creation_date}:</span></td>
<td class="data"><a href="#">123</a></td> <td class="data"><a href="#">123</a></td>
</tr> </tr>
</tbody> </tbody>
@ -192,13 +192,13 @@
{elseif $mode === "new_product"} {elseif $mode === "new_product"}
<form method="post" action="/bugtracker/createProduct"> <form method="post" action="/bugtracker/createProduct">
<input type="text" name="title" placeholder="Название"> <input type="text" name="title" placeholder="{_bug_tracker_product_name}">
<br><br> <br><br>
<textarea placeholder="Описание продукта" name="description" style="width: 100%; resize: vertical;"></textarea> <textarea placeholder="{_bug_tracker_product_description}" name="description" style="width: 100%; resize: vertical;"></textarea>
<input type="hidden" name="hash" value="{$csrfToken}" /> <input type="hidden" name="hash" value="{$csrfToken}" />
<br><br> <br><br>
<input type="submit" value="Создать" class="button" style="float: right;" /> <input type="submit" value="{_create}" class="button" style="float: right;" />
<br><br> <br><br>
</form> </form>
@ -212,7 +212,7 @@
</div> </div>
<div class="info" style="width: 92%"> <div class="info" style="width: 92%">
<a href="{$reporter->getURL()}" class="title">{$reporter->getCanonicalName()}</a> <a href="{$reporter->getURL()}" class="title">{$reporter->getCanonicalName()}</a>
<div>тестировщик отправил {$reporter_stats[0]} отчётов, из них {$reporter_stats[1]} имеют положительный статус</div> <div>tr("bug_tracker_reporter_card_text", $reporter_stats[0], $reporter_stats[1])</div>
</div> </div>
</div> </div>
<table border="0" style="font-size: 11px; width: 100%;" class="post"> <table border="0" style="font-size: 11px; width: 100%;" class="post">
@ -234,25 +234,25 @@
<table id="basicInfo" class="ugc-table group_info" cellspacing="0" cellpadding="0" border="0"> <table id="basicInfo" class="ugc-table group_info" cellspacing="0" cellpadding="0" border="0">
<tbody> <tbody>
<tr> <tr>
<td class="label"><span class="nobold">Продукт:</span></td> <td class="label"><span class="nobold">{_bug_tracker_product}:</span></td>
<td class="data"><a href="#">{$bug->getProduct()->getCanonicalName()}</a></td> <td class="data"><a href="#">{$bug->getProduct()->getCanonicalName()}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Отправил: </span></td> <td class="label"><span class="nobold">{_bug_tracker_sent_by}: </span></td>
<td class="data"> <td class="data">
<a href="/bugtracker?act=reporter&id={$bug->getReporter()->getId()}">{$bug->getReporter()->getCanonicalName()}</a> <a href="/bugtracker?act=reporter&id={$bug->getReporter()->getId()}">{$bug->getReporter()->getCanonicalName()}</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Воспроизвелось:</span></td> <td class="label"><span class="nobold">{_bug_tracker_reproduced}:</span></td>
<td class="data"><a href="#">{tr("participants", $bug->getReproducedCount())}</a></td> <td class="data"><a href="#">{tr("participants", $bug->getReproducedCount())}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Статус:</span></td> <td class="label"><span class="nobold">{_status}:</span></td>
<td class="data"><a href="#">{$bug->getStatus()}</a></td> <td class="data"><a href="#">{$bug->getStatus()}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Приоритет:</span></td> <td class="label"><span class="nobold">{_bug_tracker_priority}:</span></td>
<td class="data"><a href="#">{$bug->getPriority()}</a></td> <td class="data"><a href="#">{$bug->getPriority()}</a></td>
</tr> </tr>
</tbody> </tbody>
@ -273,7 +273,7 @@
</div> </div>
</div> </div>
<div n:if="!$reporter"> <div n:if="!$reporter">
<center>Пользователь не найден.</center> <center>{_profile_not_found}</center>
</div> </div>
{/if} {/if}
{/block} {/block}

View file

@ -8,7 +8,7 @@
{/block} {/block}
{block content} {block content}
{if $bug} {if $bug AND !$bug->isDeleted()}
<h4>{$bug->getCanonicalName()}</h4> <h4>{$bug->getCanonicalName()}</h4>
<div class="avatar-list-item" style="padding: 8px;"> <div class="avatar-list-item" style="padding: 8px;">
@ -19,7 +19,7 @@
</div> </div>
<div class="info" style="width: 92%"> <div class="info" style="width: 92%">
<a href="/bugtracker?act=reporter&id={$reporter->getId()}" class="title">{$reporter->getCanonicalName()}</a> <a href="/bugtracker?act=reporter&id={$reporter->getId()}" class="title">{$reporter->getCanonicalName()}</a>
<div class="subtitle">создано: {$bug->getCreationDate()}</div> <div class="subtitle">{_created}: {$bug->getCreationDate()}</div>
</div> </div>
</div> </div>
<hr color="#DAE1E8" size="1"> <hr color="#DAE1E8" size="1">
@ -28,33 +28,36 @@
<table id="basicInfo" class="ugc-table group_info" cellspacing="0" cellpadding="0" border="0" style="width: 100%;"> <table id="basicInfo" class="ugc-table group_info" cellspacing="0" cellpadding="0" border="0" style="width: 100%;">
<tbody> <tbody>
<tr> <tr>
<td class="label"><span class="nobold">Отправил: </span></td> <td class="label"><span class="nobold">{_bug_tracker_sent_by}: </span></td>
<td class="data"> <td class="data">
<a href="/bugtracker?act=reporter&id={$bug->getReporter()->getId()}">{$bug->getReporter()->getCanonicalName()}</a> <a href="/bugtracker?act=reporter&id={$bug->getReporter()->getId()}">{$bug->getReporter()->getCanonicalName()}</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Воспроизвелось:</span></td> <td class="label"><span class="nobold">{_bug_tracker_reproduced}:</span></td>
<td class="data"><a href="#">{tr("participants", $bug->getReproducedCount())}</a></td> <td class="data"><a href="#">{tr("participants", $bug->getReproducedCount())}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Статус:</span></td> <td class="label"><span class="nobold">{_status}:</span></td>
<td class="data"><a href="#" n:attr='onClick => $canAdminBugTracker ? "showBtStatusChangeDialog({$bug->getId()}, \"{$csrfToken}\");" : false'>{$bug->getStatus()}</a></td> <td class="data"><a href="#" n:attr='onClick => $canAdminBugTracker ? "showBtStatusChangeDialog({$bug->getId()}, \"{$csrfToken}\");" : false'>{$bug->getStatus()}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Приоритет:</span></td> <td class="label"><span class="nobold">{_bug_tracker_priority}:</span></td>
<td class="data"><a href="#" n:attr='onClick => $canAdminBugTracker ? "showBtPriorityChangeDialog({$bug->getId()}, \"{$csrfToken}\");" : false'>{$bug->getPriority()}</a></td> <td class="data"><a href="#" n:attr='onClick => $canAdminBugTracker ? "showBtPriorityChangeDialog({$bug->getId()}, \"{$csrfToken}\");" : false'>{$bug->getPriority()}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">Устройство:</span></td> <td class="label"><span class="nobold">{_bug_tracker_device}:</span></td>
<td class="data"><a href="#">{$bug->getDevice()}</a></td> <td class="data"><a href="#">{$bug->getDevice()}</a></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<hr color="#DAE1E8" size="1"> <hr color="#DAE1E8" size="1">
<button n:if="$canAdminBugTracker" class="button" onClick="showBtStatusChangeDialog({$bug->getId()}, {$csrfToken})">Изменить статус</button> <button n:if="$canAdminBugTracker" class="button" onClick="showBtStatusChangeDialog({$bug->getId()}, {$csrfToken})">{_bug_tracker_change_status}</button>
<button n:if="$canAdminBugTracker" class="button" onClick="showBtPriorityChangeDialog({$bug->getId()}, {$csrfToken})">Изменить приоритет</button> <button n:if="$canAdminBugTracker" class="button" onClick="showBtPriorityChangeDialog({$bug->getId()}, {$csrfToken})">{_bug_tracker_change_priority}</button>
<a n:if="$bug->getReporter()->getId() !== $user->identity->getId()" class="button" href="/bug{$bug->getId()}/reproduce">Воспроизвелось</a> <a n:if="$bug->getReporter()->getId() !== $user->identity->getId()" class="button" href="/bug{$bug->getId()}/reproduce">
{_bug_tracker_reproduced}
<span n:if="$bug->getReproducedCount() > 0">({$bug->getReproducedCount()})</span>
</a>
{if sizeof($comments) > 0} {if sizeof($comments) > 0}
<hr color="#DAE1E8" size="1"> <hr color="#DAE1E8" size="1">
<div n:foreach="$comments as $comment"> <div n:foreach="$comments as $comment">
@ -66,12 +69,12 @@
</div> </div>
<div class="info" style="width: 90%;"> <div class="info" style="width: 90%;">
<a n:attr='href => $comment->isModer() ? false : "/bugtracker?act=reporter&id={$comment->getAuthor()->getId()}"' class="title"> <a n:attr='href => $comment->isModer() ? false : "/bugtracker?act=reporter&id={$comment->getAuthor()->getId()}"' class="title">
{$comment->isModer() ? "Модератор" : $comment->getAuthor()->getCanonicalName()} {$comment->isModer() ? "{_bug_tracker_moderator}" : $comment->getAuthor()->getCanonicalName()}
<a n:if="$comment->isModer() AND $canAdminBugTracker" href="{$comment->getAuthor()->getURL()}"> <a n:if="$comment->isModer() AND $canAdminBugTracker" href="{$comment->getAuthor()->getURL()}">
(<b>{$comment->getAuthor()->getCanonicalName()}</b>) (<b>{$comment->getAuthor()->getCanonicalName()}</b>)
</a> </a>
</a> </a>
<b n:if="$comment->isHidden() AND $canAdminBugTracker">(скрытый комментарий)</b> <b n:if="$comment->isHidden() AND $canAdminBugTracker">({_bug_tracker_hidden_comment_span})</b>
<br> <br>
<b n:if="$comment->getLabel()" class="post-author" style="display: inline-block; border-top: 0;">{$comment->getLabel()}</b> <b n:if="$comment->getLabel()" class="post-author" style="display: inline-block; border-top: 0;">{$comment->getLabel()}</b>
<div> <div>
@ -87,10 +90,10 @@
<div style="float: right;"> <div style="float: right;">
<div n:if="$canAdminBugTracker" style="display: inline;"> <div n:if="$canAdminBugTracker" style="display: inline;">
<input id="is_moder" type="checkbox" name="is_moder"> <input id="is_moder" type="checkbox" name="is_moder">
<label for="is_moder">От лица модератора</label> <label for="is_moder">{_bug_tracker_comment_as_moderator}</label>
<input id="is_hidden" type="checkbox" name="is_hidden"> <input id="is_hidden" type="checkbox" name="is_hidden">
<label for="is_hidden">Скрытый комментарий</label> <label for="is_hidden">{_bug_tracker_hidden_comment}</label>
</div> </div>
<input type="hidden" name="hash" value="{$csrfToken}" /> <input type="hidden" name="hash" value="{$csrfToken}" />
@ -100,7 +103,7 @@
</form> </form>
{else} {else}
<div> <div>
Отчёт не найден. Возможно, он был удалён. {_bug_tracker_report_not_found}
</div> </div>
{/if} {/if}

View file

@ -1046,3 +1046,49 @@
"cookies_popup_content" = "All kids love cookie, so this website uses Cookies to identify your session and nothing more. Check <a href='/privacy'>our privacy policy</a> for more information."; "cookies_popup_content" = "All kids love cookie, so this website uses Cookies to identify your session and nothing more. Check <a href='/privacy'>our privacy policy</a> for more information.";
"cookies_popup_agree" = "Accept"; "cookies_popup_agree" = "Accept";
/* Bugtracker */
"bug_tracker_reports" = "Reports";
"bug_tracker_products" = "Products";
"bug_tracker_reporter_card" = "Tester Card";
"bug_tracker_product" = "Product";
"bug_tracker_sent_by" = "Author";
"bug_tracker_reproduced" = "Reproduced for";
"bug_tracker_priority" = "Priority";
"bug_tracker_bug_description" = "Bug description";
"bug_tracker_priority_feature" = "Feature request";
"bug_tracker_priority_low" = "Low";
"bug_tracker_priority_medium" = "Medium";
"bug_tracker_priority_high" = "High";
"bug_tracker_priority_critical" = "Critical";
"bug_tracker_priority_vulnerability" = "Vulnerability";
"bug_tracker_device" = "Device";
"bug_tracker_product_name" = "Title";
"bug_tracker_product_is_closed" = "closed";
"bug_tracker_product_created_by" = "Created by";
"bug_tracker_product_creation_date" = "Creation date";
"bug_tracker_product_description" = "Product description";
"bug_tracker_reporter_card_text" = "the tester has sent $1 reports, of which $2 have a positive status";
"bug_tracker_change_status" = "Change Status";
"bug_tracker_change_priority" = "Change Priority";
"bug_tracker_moderator" = "Moderator";
"bug_tracker_hidden_comment_span" = "hidden comment";
"bug_tracker_comment_as_moderator" = "On behalf of the moderator";
"bug_tracker_hidden_comment" = "Hidden comment";
"bug_tracker_report_not_found" = "The report was not found. It may have been deleted.";
"bug_tracker_status_open" = "Open";
"bug_tracker_status_under_review" = "Under review":
"bug_tracker_status_in_progress" = "In progress";
"bug_tracker_status_fixed" = "Fixed";
"bug_tracker_status_closed" = "Closed";
"bug_tracker_status_requires_adjustment" = "Requires adjustment";
"bug_tracker_status_locked" = "Blocked";
"bug_tracker_status_rejected" = "Rejected";
"bug_tracker_new_report_status" = "New report status";
"bug_tracker_new_report_priority" = "New report priority";
"bug_tracker_empty_comment" = "The comment cannot be empty.";
"bug_tracker_success" = "Success";
"bug_tracker_comment_sent" = "The comment has been sent.";
"bug_tracker_fields_error" = "Not all fields are filled in.";
"bug_tracker_reproduced_text" = "You have indicated that this bug is reproducible for you";

View file

@ -1105,3 +1105,49 @@
"cookies_popup_content" = "Все дети любят печенье, поэтому этот веб-сайт использует Cookies для того, чтобы идентифицировать вашу сессию и ничего более. Ознакомьтесь с нашей <a href='/privacy'>политикой конфиденциальности</a> для получения дополнительной информации."; "cookies_popup_content" = "Все дети любят печенье, поэтому этот веб-сайт использует Cookies для того, чтобы идентифицировать вашу сессию и ничего более. Ознакомьтесь с нашей <a href='/privacy'>политикой конфиденциальности</a> для получения дополнительной информации.";
"cookies_popup_agree" = "Согласен"; "cookies_popup_agree" = "Согласен";
/* Bugtracker */
"bug_tracker_reports" = "Отчёты";
"bug_tracker_products" = "Продукты";
"bug_tracker_reporter_card" = "Карточка тестировщика";
"bug_tracker_product" = "Продукт";
"bug_tracker_sent_by" = "Отправил";
"bug_tracker_reproduced" = "Воспроизвелось";
"bug_tracker_priority" = "Приоритет";
"bug_tracker_bug_description" = "Описание бага";
"bug_tracker_priority_feature" = "Пожелание";
"bug_tracker_priority_low" = "Низкий";
"bug_tracker_priority_medium" = "Средний";
"bug_tracker_priority_high" = "Высокий";
"bug_tracker_priority_critical" = "Критический";
"bug_tracker_priority_vulnerability" = "Уязвимость";
"bug_tracker_device" = "Устройство";
"bug_tracker_product_name" = "Название";
"bug_tracker_product_is_closed" = "закрыт";
"bug_tracker_product_created_by" = "Создал";
"bug_tracker_product_creation_date" = "Дата создания";
"bug_tracker_product_description" = "Описание продукта";
"bug_tracker_reporter_card_text" = "тестировщик отправил $1 отчётов, из них $2 имеют положительный статус";
"bug_tracker_change_status" = "Изменить статус";
"bug_tracker_change_priority" = "Изменить приоритет";
"bug_tracker_moderator" = "Модератор";
"bug_tracker_hidden_comment_span" = "скрытый комментарий";
"bug_tracker_comment_as_moderator" = "От лица модератора";
"bug_tracker_hidden_comment" = "Скрытый комментарий";
"bug_tracker_report_not_found" = "Отчёт не найден. Возможно, он был удалён.";
"bug_tracker_status_open" = "Открыт";
"bug_tracker_status_under_review" = "На рассмотрении":
"bug_tracker_status_in_progress" = "В работе";
"bug_tracker_status_fixed" = "Исправлен";
"bug_tracker_status_closed" = "Закрыт";
"bug_tracker_status_requires_adjustment" = "Требует корректировки";
"bug_tracker_status_locked" = "Заблокирован";
"bug_tracker_status_rejected" = "Отклонён";
"bug_tracker_new_report_status" = "Новый статус отчёта";
"bug_tracker_new_report_priority" = "Новый приоритет отчёта";
"bug_tracker_empty_comment" = "Комментарий не может быть пустым.";
"bug_tracker_success" = "Успех";
"bug_tracker_comment_sent" = "Комментарий отправлен.";
"bug_tracker_fields_error" = "Заполнены не все поля.";
"bug_tracker_reproduced_text" = "Вы отметили, что у Вас получилось воспроизвести этот баг.";