Фитчи

This commit is contained in:
n1rwana 2022-08-22 02:11:48 +03:00
parent 5b46485a73
commit 3dcfc5dd50
13 changed files with 114 additions and 54 deletions

View file

@ -92,7 +92,7 @@ class BugReport extends RowModel
return $this->getRecord()->reproduced; return $this->getRecord()->reproduced;
} }
function getCreationDate(): DateTime function getCreationTime(): DateTime
{ {
return new DateTime($this->getRecord()->created); return new DateTime($this->getRecord()->created);
} }

View file

@ -1,5 +1,6 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace openvk\Web\Models\Entities; namespace openvk\Web\Models\Entities;
use openvk\Web\Util\DateTime;
use openvk\Web\Models\{RowModel}; use openvk\Web\Models\{RowModel};
use openvk\Web\Models\Entities\{User, BugtrackerProduct}; use openvk\Web\Models\Entities\{User, BugtrackerProduct};
use openvk\Web\Models\Repositories\{Users, BugtrackerProducts}; use openvk\Web\Models\Repositories\{Users, BugtrackerProducts};
@ -43,4 +44,9 @@ class BugReportComment extends RowModel
{ {
return $this->getRecord()->point_actions; return $this->getRecord()->point_actions;
} }
function getCreationTime(): DateTime
{
return new DateTime($this->getRecord()->created);
}
} }

View file

@ -1,5 +1,6 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace openvk\Web\Models\Entities; namespace openvk\Web\Models\Entities;
use openvk\Web\Util\DateTime;
use openvk\Web\Models\{RowModel}; use openvk\Web\Models\{RowModel};
use openvk\Web\Models\Entities\{User}; use openvk\Web\Models\Entities\{User};
use openvk\Web\Models\Repositories\{Users}; use openvk\Web\Models\Repositories\{Users};
@ -37,4 +38,9 @@ class BugtrackerProduct extends RowModel
{ {
return (bool) $this->getRecord()->closed; return (bool) $this->getRecord()->closed;
} }
function getCreationTime(): DateTime
{
return new DateTime($this->getRecord()->created);
}
} }

View file

@ -1018,5 +1018,10 @@ class User extends RowModel
return (bool) $this->getRecord()->activated; return (bool) $this->getRecord()->activated;
} }
function isBtModerator(): bool
{
return $this->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL);
}
use Traits\TSubscribable; use Traits\TSubscribable;
} }

View file

@ -25,15 +25,20 @@ class BugtrackerProducts
return $this->toProduct($this->products->get($id)); return $this->toProduct($this->products->get($id));
} }
function getAll(): \Traversable function getAll(int $page = 1): \Traversable
{ {
foreach($this->products->order("id ASC") as $product) foreach($this->products->order("id ASC")->page($page, 5) as $product)
yield new BugtrackerProduct($product); yield new BugtrackerProduct($product);
} }
function getOpen(): \Traversable function getOpen(int $page = 1): \Traversable
{ {
foreach($this->products->where(["closed" => 0])->order("id ASC") as $product) foreach($this->products->where(["closed" => 0])->order("id ASC")->page($page, 5) as $product)
yield new BugtrackerProduct($product); yield new BugtrackerProduct($product);
} }
function getCount(): ?int
{
return sizeof($this->products->where(["closed" => 0]));
}
} }

View file

@ -51,12 +51,12 @@ class BugtrackerReports
yield new BugReport($report); yield new BugReport($report);
} }
function getCountByReporter(int $reporter_id) function getCountByReporter(int $reporter_id): ?int
{ {
return sizeof($this->reports->where(["deleted" => NULL, "reporter" => $reporter_id])); return sizeof($this->reports->where(["deleted" => NULL, "reporter" => $reporter_id]));
} }
function getSuccCountByReporter(int $reporter_id) function getSuccCountByReporter(int $reporter_id): ?int
{ {
return sizeof($this->reports->where(["deleted" => NULL, "reporter" => $reporter_id, "status" => "<= 4"])); return sizeof($this->reports->where(["deleted" => NULL, "reporter" => $reporter_id, "status" => "<= 4"]));
} }

View file

@ -23,29 +23,39 @@ final class BugtrackerPresenter extends OpenVKPresenter
function renderIndex(): void function renderIndex(): void
{ {
$this->assertUserLoggedIn(); $this->assertUserLoggedIn();
$this->template->mode = in_array($this->queryParam("act"), ["list", "show", "products", "new_product", "reporter", "new"]) ? $this->queryParam("act") : "list"; $this->template->mode = in_array($this->queryParam("act"), ["list", "products", "new_product", "reporter", "new"]) ? $this->queryParam("act") : "list";
if($this->queryParam("act") === "show")
$this->redirect("/bug" . $this->queryParam("id"));
$this->template->user = $this->user; $this->template->user = $this->user;
$this->template->page = (int) ($this->queryParam("p") ?? 1);
$this->template->all_products = $this->products->getAll();
$this->template->open_products = $this->products->getOpen(); $this->template->open_products = $this->products->getOpen();
if($this->template->mode === "reporter") { switch ($this->template->mode) {
$this->template->reporter = (new Users)->get((int) $this->queryParam("id")); case 'reporter':
$this->template->reporter_stats = [$this->reports->getCountByReporter((int) $this->queryParam("id")), $this->reports->getSuccCountByReporter((int) $this->queryParam("id"))]; $this->template->reporter = (new Users)->get((int) $this->queryParam("id"));
$this->template->reporter_stats = [$this->reports->getCountByReporter((int) $this->queryParam("id")), $this->reports->getSuccCountByReporter((int) $this->queryParam("id"))];
$this->template->page = (int) ($this->queryParam("p") ?? 1); $this->template->iterator = $this->reports->getByReporter((int) $this->queryParam("id"), $this->template->page);
$this->template->iterator = $this->reports->getByReporter((int) $this->queryParam("id")); $this->template->count = $this->reports->getCountByReporter((int) $this->queryParam("id"));
$this->template->count = $this->reports->getCountByReporter((int) $this->queryParam("id")); break;
} else {
$this->template->page = (int) ($this->queryParam("p") ?? 1); case 'products':
$this->template->count = $this->reports->getReportsCount((int) $this->queryParam("product")); $this->template->count = $this->products->getCount();
$this->template->iterator = $this->queryParam("product") $this->template->iterator = $this->products->getAll($this->template->page);
? $this->reports->getReports((int) $this->queryParam("product"), $this->template->page) break;
: $this->reports->getAllReports($this->template->page);
default:
$this->template->count = $this->reports->getReportsCount((int) $this->queryParam("product"));
$this->template->iterator = $this->queryParam("product")
? $this->reports->getReports((int) $this->queryParam("product"), $this->template->page)
: $this->reports->getAllReports($this->template->page);
break;
} }
$this->template->canAdminBugTracker = $this->user->identity->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL); $this->template->isModerator = $this->user->identity->isBtModerator();
} }
function renderView(int $id): void function renderView(int $id): void
@ -59,7 +69,7 @@ final class BugtrackerPresenter extends OpenVKPresenter
$this->template->reporter = $this->template->bug->getReporter(); $this->template->reporter = $this->template->bug->getReporter();
$this->template->comments = $this->comments->getByReport($this->template->bug); $this->template->comments = $this->comments->getByReport($this->template->bug);
$this->template->canAdminBugTracker = $this->user->identity->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL); $this->template->isModerator = $this->user->identity->isBtModerator();
} else { } else {
$this->flashFail("err", tr("bug_tracker_report_not_found")); $this->flashFail("err", tr("bug_tracker_report_not_found"));
} }
@ -127,12 +137,12 @@ final class BugtrackerPresenter extends OpenVKPresenter
function createComment(?BugReport $report, string $text, string $label = "", bool $is_moder = FALSE, bool $is_hidden = FALSE, string $point_actions = NULL) function createComment(?BugReport $report, string $text, string $label = "", bool $is_moder = FALSE, bool $is_hidden = FALSE, string $point_actions = NULL)
{ {
$moder = $this->user->identity->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL); $moder = $this->user->identity->isBtModerator();
if (!$text && !$label) if (!$text && !$label)
$this->flashFail("err", tr("error"), tr("bug_tracker_empty_comment")); $this->flashFail("err", tr("error"), tr("bug_tracker_empty_comment"));
if ($report->getRawStatus() == 6 && !$moder) if (in_array($report->getRawStatus(), [5, 6]) && !$moder)
$this->flashFail("err", tr("forbidden")); $this->flashFail("err", tr("forbidden"));
DB::i()->getContext()->table("bt_comments")->insert([ DB::i()->getContext()->table("bt_comments")->insert([
@ -142,7 +152,8 @@ final class BugtrackerPresenter extends OpenVKPresenter
"is_hidden" => $moder === $is_hidden, "is_hidden" => $moder === $is_hidden,
"point_actions" => $point_actions, "point_actions" => $point_actions,
"text" => $text, "text" => $text,
"label" => $label "label" => $label,
"created" => time()
]); ]);
$this->flashFail("succ", tr("bug_tracker_success"), tr("bug_tracker_comment_sent")); $this->flashFail("succ", tr("bug_tracker_success"), tr("bug_tracker_comment_sent"));
@ -192,7 +203,7 @@ final class BugtrackerPresenter extends OpenVKPresenter
$this->assertUserLoggedIn(); $this->assertUserLoggedIn();
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
$moder = $this->user->identity->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL); $moder = $this->user->identity->isBtModerator();
if (!$moder) if (!$moder)
$this->flashFail("err", tr("forbidden")); $this->flashFail("err", tr("forbidden"));

View file

@ -60,7 +60,7 @@
<tbody> <tbody>
<tr> <tr>
<td class="label"><span class="nobold">{_bug_tracker_product}:</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="/bugtracker?act=products">{$bug->getProduct()->getCanonicalName()}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">{_bug_tracker_sent_by}: </span></td> <td class="label"><span class="nobold">{_bug_tracker_sent_by}: </span></td>
@ -77,9 +77,13 @@
<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">{_priority}:</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>
<tr>
<td class="label"><span class="nobold">{_created}:</span></td>
<td class="data"><a href="#">{$bug->getCreationTime()}</a></td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>
@ -149,7 +153,7 @@
{elseif $mode === "products"} {elseif $mode === "products"}
<table border="0" style="font-size: 11px; width: 100%;" class="post"> <table border="0" style="font-size: 11px; width: 100%;" class="post">
<tbody> <tbody>
<tr n:foreach="$all_products as $product"> <tr n:foreach="$iterator as $product">
<td width="54" > <td width="54" >
<center> <center>
<img src="/assets/packages/static/openvk/img/note_icon.png"> <img src="/assets/packages/static/openvk/img/note_icon.png">
@ -157,7 +161,7 @@
</td> </td>
<td width="92%" valign="top"> <td width="92%" valign="top">
<div class="post-author" href="#"> <div class="post-author" href="#">
<a href="#"> <a href="/bugtracker?product={$product->getId()}">
<b>{$product->getCanonicalName()}</b> <b>{$product->getCanonicalName()}</b>
<span>#{$product->getId()}</span> <span>#{$product->getId()}</span>
</a> </a>
@ -166,13 +170,13 @@
<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">{_bug_tracker_name}:</span></td> <td class="label"><span class="nobold">{_bug_tracker_product}:</span></td>
<td class="data"> <td class="data">
<a href="#">{$product->getCanonicalName()}</a> <a href="/bugtracker?product={$product->getId()}">{$product->getCanonicalName()}</a>
<b n:if="$product->isClosed()">({_bug_tracker_product_is_closed})</b> <b n:if="$product->isClosed()">({_bug_tracker_product_is_closed})</b>
</td> </td>
</tr> </tr>
<tr n:if="$canAdminBugTracker"> <tr n:if="$isModerator">
<td class="label"><span class="nobold">{_bug_tracker_product_created_by}: </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>
@ -180,7 +184,7 @@
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">{_bug_tracker_product_creation_date}:</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="#">{$product->getCreationTime()}</a></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -189,6 +193,15 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div style="padding: 8px;">
{include "../components/paginator.xml", conf => (object) [
"page" => $page,
"count" => $count,
"amount" => sizeof($iterator),
"perPage" => 5,
"atBottom" => true,
]}
</div>
{elseif $mode === "new_product"} {elseif $mode === "new_product"}
<form method="post" action="/bugtracker/createProduct"> <form method="post" action="/bugtracker/createProduct">
@ -212,7 +225,8 @@
</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>tr("bug_tracker_reporter_card_text", $reporter_stats[0], $reporter_stats[1])</div> <b n:if="$reporter->isBtModerator() AND $isModerator">[Модератор]</b>
<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">

View file

@ -10,6 +10,12 @@
{block content} {block content}
{if $bug AND !$bug->isDeleted()} {if $bug AND !$bug->isDeleted()}
<div n:if="in_array($bug->getRawStatus(), [4, 6]) AND $isModerator" class="user-alert">
Этот отчёт закрыт, и пользователь не может оставлять к нему комментарии. При необходимости Вы можете изменить его статус.
</div>
<div n:if="in_array($bug->getRawStatus(), [4, 6]) AND !$isModerator" class="user-alert">
Этот отчёт закрыт, и Вы больше не можете оставлять к нему комментарии.
</div>
<h4>{$bug->getCanonicalName()}</h4> <h4>{$bug->getCanonicalName()}</h4>
<div class="avatar-list-item" style="padding: 8px;"> <div class="avatar-list-item" style="padding: 8px;">
@ -20,7 +26,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">{_created}: {$bug->getCreationDate()}</div> <div class="subtitle">{_created}: {$bug->getCreationTime()}</div>
</div> </div>
</div> </div>
<hr color="#DAE1E8" size="1"> <hr color="#DAE1E8" size="1">
@ -44,11 +50,11 @@
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">{_status}:</span></td> <td class="label"><span class="nobold">{_status}:</span></td>
<td class="data"><a href="#" n:attr='onClick => $canAdminBugTracker ? "showBtStatusChangeDialog({$bug->getId()}, {$reporter->getCoins()}, \"{$csrfToken}\");" : false'>{$bug->getStatus()}</a></td> <td class="data"><a href="#" n:attr='onClick => $isModerator ? "showBtStatusChangeDialog({$bug->getId()}, {$reporter->getCoins()}, \"{$csrfToken}\");" : false'>{$bug->getStatus()}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">{_bug_tracker_priority}:</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()}, {$reporter->getCoins()}, \"{$csrfToken}\");" : false'>{$bug->getPriority()}</a></td> <td class="data"><a href="#" n:attr='onClick => $isModerator ? "showBtPriorityChangeDialog({$bug->getId()}, {$reporter->getCoins()}, \"{$csrfToken}\");" : false'>{$bug->getPriority()}</a></td>
</tr> </tr>
<tr> <tr>
<td class="label"><span class="nobold">{_bug_tracker_device}:</span></td> <td class="label"><span class="nobold">{_bug_tracker_device}:</span></td>
@ -57,8 +63,8 @@
</tbody> </tbody>
</table> </table>
<hr color="#DAE1E8" size="1"> <hr color="#DAE1E8" size="1">
<button n:if="$canAdminBugTracker" class="button" onClick="showBtStatusChangeDialog({$bug->getId()}, {$reporter->getCoins()}, {$csrfToken})">{_bug_tracker_change_status}</button> <button n:if="$isModerator" class="button" onClick="showBtStatusChangeDialog({$bug->getId()}, {$reporter->getCoins()}, {$csrfToken})">{_bug_tracker_change_status}</button>
<button n:if="$canAdminBugTracker" class="button" onClick="showBtPriorityChangeDialog({$bug->getId()}, {$reporter->getCoins()}, {$csrfToken})">{_bug_tracker_change_priority}</button> <button n:if="$isModerator" class="button" onClick="showBtPriorityChangeDialog({$bug->getId()}, {$reporter->getCoins()}, {$csrfToken})">{_bug_tracker_change_priority}</button>
<a n:if="$bug->getReporter()->getId() !== $user->identity->getId()" class="button" href="/bug{$bug->getId()}/reproduce"> <a n:if="$bug->getReporter()->getId() !== $user->identity->getId()" class="button" href="/bug{$bug->getId()}/reproduce">
{_bug_tracker_reproduced} {_bug_tracker_reproduced}
<span n:if="$bug->getReproducedCount() > 0">({$bug->getReproducedCount()})</span> <span n:if="$bug->getReproducedCount() > 0">({$bug->getReproducedCount()})</span>
@ -66,7 +72,7 @@
{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">
<div n:if="!$comment->isHidden() OR $comment->isHidden() AND $canAdminBugTracker" class="avatar-list-item" style="padding: 8px;"> <div n:if="!$comment->isHidden() OR $comment->isHidden() AND $isModerator" class="avatar-list-item" style="padding: 8px;">
<div class="avatar"> <div class="avatar">
<a href="/bugtracker?act=reporter&id={$comment->getAuthor()->getId()}"> <a href="/bugtracker?act=reporter&id={$comment->getAuthor()->getId()}">
<img class="ava" src="{$comment->isModer() ? 'https://vk.com/images/support15_specagent.png' : $comment->getAuthor()->getAvatarURL()}"> <img class="ava" src="{$comment->isModer() ? 'https://vk.com/images/support15_specagent.png' : $comment->getAuthor()->getAvatarURL()}">
@ -74,27 +80,31 @@
</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() ? "{_bug_tracker_moderator}" : $comment->getAuthor()->getCanonicalName()} {$comment->isModer() ? tr("bug_tracker_moderator") : $comment->getAuthor()->getCanonicalName()}
<a n:if="$comment->isModer() AND $canAdminBugTracker" href="{$comment->getAuthor()->getURL()}"> <a n:if="$comment->isModer() AND $isModerator" 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">({_bug_tracker_hidden_comment_span})</b> <b n:if="$comment->isHidden() AND $isModerator">({_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>
{$comment->getText()} {$comment->getText()}
</div> </div>
<b n:if="$canAdminBugTracker AND $comment->getBalanceChanges()">(действия с балансом: {$comment->getBalanceChanges() > 0 ? "+" : false}{$comment->getBalanceChanges()})</b> <div n:if="$isModerator AND $comment->getBalanceChanges()">
<b>(действия с балансом: {$comment->getBalanceChanges() > 0 ? "+" : false}{$comment->getBalanceChanges()})</b>
</div>
<span class="nobold">{$comment->getCreationTime()}</span>
</div> </div>
</div> </div>
<hr color="#DAE1E8" size="1"> <hr color="#DAE1E8" size="1">
</div> </div>
{/if} {/if}
<form n:if="$bug->getRawStatus() != 6 OR $bug->getRawStatus() == 6 AND $canAdminBugTracker" method="post" action="/bug{$bug->getId()}/addComment"> <form n:if="!in_array($bug->getRawStatus(), [4, 6]) OR in_array($bug->getRawStatus(), [4, 6]) AND $isModerator" method="post" action="/bug{$bug->getId()}/addComment">
<textarea name="text" style="width: 100%;resize: vertical;"></textarea><br /> <textarea name="text" style="width: 100%; resize: vertical;"></textarea><br />
<div style="float: right;"> <div style="float: right;">
<div n:if="$canAdminBugTracker" style="display: inline;"> <div n:if="$isModerator" 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">{_bug_tracker_comment_as_moderator}</label> <label for="is_moder">{_bug_tracker_comment_as_moderator}</label>

View file

@ -33,6 +33,8 @@ routes:
handler: "Support->delete" handler: "Support->delete"
- url: "/bugtracker" - url: "/bugtracker"
handler: "Bugtracker->index" handler: "Bugtracker->index"
- url: "/bugs"
handler: "Bugtracker->index"
- url: "/bug{num}" - url: "/bug{num}"
handler: "Bugtracker->view" handler: "Bugtracker->view"
- url: "/bug{num}/setStatus" - url: "/bug{num}/setStatus"

View file

@ -49,7 +49,8 @@ CREATE TABLE `bt_comments` (
`is_hidden` tinyint(1) DEFAULT NULL, `is_hidden` tinyint(1) DEFAULT NULL,
`text` longtext NOT NULL, `text` longtext NOT NULL,
`label` varchar(50) NOT NULL, `label` varchar(50) NOT NULL,
`point_actions` bigint(20) DEFAULT NULL `point_actions` bigint(20) DEFAULT NULL,
`created` bigint(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `bt_comments` ALTER TABLE `bt_comments`

View file

@ -381,7 +381,7 @@
"my_feed" = "My Feed"; "my_feed" = "My Feed";
"my_feedback" = "My Feedback"; "my_feedback" = "My Feedback";
"my_settings" = "My Settings"; "my_settings" = "My Settings";
"bug_tracker" = "Bug-tracker"; "bug_tracker" = "Bug tracker";
"menu_login" = "Login"; "menu_login" = "Login";
"menu_registration" = "Registration"; "menu_registration" = "Registration";
@ -1078,7 +1078,7 @@
"bug_tracker_hidden_comment" = "Hidden comment"; "bug_tracker_hidden_comment" = "Hidden comment";
"bug_tracker_report_not_found" = "The report was not found. It may have been deleted."; "bug_tracker_report_not_found" = "The report was not found. It may have been deleted.";
"bug_tracker_status_open" = "Open"; "bug_tracker_status_open" = "Open";
"bug_tracker_status_under_review" = "Under review": "bug_tracker_status_under_review" = "Under review";
"bug_tracker_status_in_progress" = "In progress"; "bug_tracker_status_in_progress" = "In progress";
"bug_tracker_status_fixed" = "Fixed"; "bug_tracker_status_fixed" = "Fixed";
"bug_tracker_status_closed" = "Closed"; "bug_tracker_status_closed" = "Closed";

View file

@ -1137,7 +1137,7 @@
"bug_tracker_hidden_comment" = "Скрытый комментарий"; "bug_tracker_hidden_comment" = "Скрытый комментарий";
"bug_tracker_report_not_found" = "Отчёт не найден. Возможно, он был удалён."; "bug_tracker_report_not_found" = "Отчёт не найден. Возможно, он был удалён.";
"bug_tracker_status_open" = "Открыт"; "bug_tracker_status_open" = "Открыт";
"bug_tracker_status_under_review" = "На рассмотрении": "bug_tracker_status_under_review" = "На рассмотрении";
"bug_tracker_status_in_progress" = "В работе"; "bug_tracker_status_in_progress" = "В работе";
"bug_tracker_status_fixed" = "Исправлен"; "bug_tracker_status_fixed" = "Исправлен";
"bug_tracker_status_closed" = "Закрыт"; "bug_tracker_status_closed" = "Закрыт";