mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°3537 run_query : replace main form by components
This commit is contained in:
@@ -175,12 +175,14 @@ return array(
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\GlobalSearch\\GlobalSearchFactory' => $baseDir . '/sources/application/UI/Base/Component/GlobalSearch/GlobalSearchFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\GlobalSearch\\GlobalSearchHelper' => $baseDir . '/sources/application/UI/Base/Component/GlobalSearch/GlobalSearchHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Html\\Html' => $baseDir . '/sources/application/UI/Base/Component/Html/Html.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\AbstractInput' => $baseDir . '/sources/application/UI/Base/Component/Input/AbstractInput.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Input' => $baseDir . '/sources/application/UI/Base/Component/Input/Input.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\InputFactory' => $baseDir . '/sources/application/UI/Base/Component/Input/InputFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\InputWithLabel' => $baseDir . '/sources/application/UI/Base/Component/Input/InputWithLabel.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\RichText\\RichText' => $baseDir . '/sources/application/UI/Base/Component/Input/RichText/RichText.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\Select' => $baseDir . '/sources/application/UI/Base/Component/Input/Select/Select.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\SelectOption' => $baseDir . '/sources/application/UI/Base/Component/Input/Select/SelectOption.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\TextArea' => $baseDir . '/sources/application/UI/Base/Component/Input/TextArea.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\Panel' => $baseDir . '/sources/application/UI/Base/Component/Panel/Panel.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\PanelEnhanced' => $baseDir . '/sources/application/UI/Base/Component/Panel/PanelEnhanced.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\PanelFactory' => $baseDir . '/sources/application/UI/Base/Component/Panel/PanelFactory.php',
|
||||
@@ -196,7 +198,6 @@ return array(
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\QuickCreate\\QuickCreate' => $baseDir . '/sources/application/UI/Base/Component/QuickCreate/QuickCreate.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\QuickCreate\\QuickCreateFactory' => $baseDir . '/sources/application/UI/Base/Component/QuickCreate/QuickCreateFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\QuickCreate\\QuickCreateHelper' => $baseDir . '/sources/application/UI/Base/Component/QuickCreate/QuickCreateHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\SearchBlock\\SearchBlock' => $baseDir . '/sources/application/UI/Base/Component/SearchBlock/SearchBlock.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Title\\Title' => $baseDir . '/sources/application/UI/Base/Component/Title/Title.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Title\\TitleFactory' => $baseDir . '/sources/application/UI/Base/Component/Title/TitleFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Title\\TitleForObjectDetails' => $baseDir . '/sources/application/UI/Base/Component/Title/TitleForObjectDetails.php',
|
||||
|
||||
@@ -405,12 +405,14 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\GlobalSearch\\GlobalSearchFactory' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/GlobalSearch/GlobalSearchFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\GlobalSearch\\GlobalSearchHelper' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/GlobalSearch/GlobalSearchHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Html\\Html' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Html/Html.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\AbstractInput' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Input/AbstractInput.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Input' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Input/Input.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\InputFactory' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Input/InputFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\InputWithLabel' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Input/InputWithLabel.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\RichText\\RichText' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Input/RichText/RichText.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\Select' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Input/Select/Select.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\SelectOption' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Input/Select/SelectOption.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\TextArea' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Input/TextArea.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\Panel' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Panel/Panel.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\PanelEnhanced' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Panel/PanelEnhanced.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Panel\\PanelFactory' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Panel/PanelFactory.php',
|
||||
@@ -426,7 +428,6 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\QuickCreate\\QuickCreate' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/QuickCreate/QuickCreate.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\QuickCreate\\QuickCreateFactory' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/QuickCreate/QuickCreateFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\QuickCreate\\QuickCreateHelper' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/QuickCreate/QuickCreateHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\SearchBlock\\SearchBlock' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/SearchBlock/SearchBlock.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Title\\Title' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Title/Title.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Title\\TitleFactory' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Title/TitleFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Title\\TitleForObjectDetails' => __DIR__ . '/../..' . '/sources/application/UI/Base/Component/Title/TitleForObjectDetails.php',
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Input\InputFactory;
|
||||
|
||||
require_once('../approot.inc.php');
|
||||
require_once(APPROOT.'/application/application.inc.php');
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
@@ -138,12 +142,9 @@ try
|
||||
foreach($oFilter->GetQueryParams() as $sParam => $foo)
|
||||
{
|
||||
$value = utils::ReadParam('arg_'.$sParam, null, true, 'raw_data');
|
||||
if (!is_null($value))
|
||||
{
|
||||
if (!is_null($value)) {
|
||||
$aArgs[$sParam] = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aArgs[$sParam] = '';
|
||||
}
|
||||
}
|
||||
@@ -152,9 +153,29 @@ try
|
||||
}
|
||||
}
|
||||
|
||||
$oP->add("<form method=\"post\">\n");
|
||||
$oP->add(Dict::S('UI:RunQuery:ExpressionToEvaluate')."<br/>\n");
|
||||
$oP->add("<textarea cols=\"120\" rows=\"8\" id=\"expression\" name=\"expression\">".htmlentities($sExpression, ENT_QUOTES, 'UTF-8')."</textarea>\n");
|
||||
$oQueryForm = new \Combodo\iTop\Application\UI\Base\Component\Form\Form();
|
||||
$oP->AddUiBlock($oQueryForm);
|
||||
|
||||
$oHiddenParams = new Html($oAppContext->GetForForm());
|
||||
$oQueryForm->AddSubBlock($oHiddenParams);
|
||||
|
||||
$oQueryTextarea = InputFactory::MakeForTextareaWithLabel(
|
||||
'expression',
|
||||
Dict::S('UI:RunQuery:ExpressionToEvaluate'),
|
||||
'expression',
|
||||
utils::HtmlEntities($sExpression),
|
||||
120, 8
|
||||
);
|
||||
$oQueryForm->AddSubBlock($oQueryTextarea);
|
||||
|
||||
$oQuerySubmit = ButtonFactory::MakeForPrimaryAction(
|
||||
Dict::S('UI:Button:Evaluate'),
|
||||
null,
|
||||
null,
|
||||
true
|
||||
);
|
||||
$oQueryForm->AddSubBlock($oQuerySubmit);
|
||||
|
||||
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot()."/js/jquery.hotkeys.js");
|
||||
$oP->add_ready_script(<<<EOF
|
||||
$("#expression").select();
|
||||
@@ -164,25 +185,18 @@ $("#expression").on("keydown", null, "ctrl+return", function() {
|
||||
EOF
|
||||
);
|
||||
|
||||
if (count($aArgs) > 0)
|
||||
{
|
||||
if (count($aArgs) > 0) {
|
||||
$oP->add("<div class=\"wizContainer\">\n");
|
||||
$oP->add("<h3>Query arguments</h3>\n");
|
||||
foreach($aArgs as $sParam => $sValue)
|
||||
{
|
||||
foreach ($aArgs as $sParam => $sValue) {
|
||||
$oP->p("$sParam: <input type=\"string\" name=\"arg_$sParam\" value=\"$sValue\">\n");
|
||||
}
|
||||
$oP->add("</div>\n");
|
||||
$oP->add("</div>\n");
|
||||
}
|
||||
|
||||
$oP->add("<input type=\"submit\" value=\"".Dict::S('UI:Button:Evaluate')."\" title=\"".Dict::S('UI:Button:Evaluate:Title')."\">\n");
|
||||
$oP->add($oAppContext->GetForForm());
|
||||
$oP->add("</form>\n");
|
||||
|
||||
if ($oFilter)
|
||||
{
|
||||
if ($oFilter) {
|
||||
$oP->add("<h3>Query results</h3>\n");
|
||||
|
||||
|
||||
$oResultBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$oResultBlock->Display($oP, 'runquery');
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Component\Input;
|
||||
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
|
||||
/**
|
||||
* @package Combodo\iTop\Application\UI\Base\Component\Input
|
||||
*/
|
||||
class AbstractInput extends UIBlock
|
||||
{
|
||||
/** @var string */
|
||||
protected $sName;
|
||||
/** @var string */
|
||||
protected $sValue;
|
||||
|
||||
public function GetName(): string
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
public function SetName(string $sName): AbstractInput
|
||||
{
|
||||
$this->sName = $sName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetValue(): ?string
|
||||
{
|
||||
return $this->sValue;
|
||||
}
|
||||
|
||||
public function SetValue(?string $sValue): AbstractInput
|
||||
{
|
||||
$this->sValue = $sValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -7,14 +7,12 @@
|
||||
namespace Combodo\iTop\Application\UI\Base\Component\Input;
|
||||
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
|
||||
/**
|
||||
* Class Input
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Base\Component\Input
|
||||
*/
|
||||
class Input extends UIBlock
|
||||
class Input extends AbstractInput
|
||||
{
|
||||
// Overloaded constants
|
||||
public const BLOCK_CODE = 'ibo-input';
|
||||
@@ -24,67 +22,15 @@ class Input extends UIBlock
|
||||
|
||||
/** @var string */
|
||||
protected $sType;
|
||||
/** @var string */
|
||||
protected $sName;
|
||||
/** @var string */
|
||||
protected $sValue;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetType(): string
|
||||
{
|
||||
return $this->sType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sType
|
||||
*
|
||||
* @return Input
|
||||
*/
|
||||
public function SetType(string $sType): Input
|
||||
{
|
||||
$this->sType = $sType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetName(): string
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
* @return Input
|
||||
*/
|
||||
public function SetName(string $sName): Input
|
||||
{
|
||||
$this->sName = $sName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetValue(): string
|
||||
{
|
||||
return $this->sValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return Input
|
||||
*/
|
||||
public function SetValue(string $sValue): Input
|
||||
{
|
||||
$this->sValue = $sValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -27,18 +27,38 @@ class InputFactory
|
||||
|
||||
public static function MakeForSelectWithLabel(string $sName, string $sLabel, ?string $sId = null): InputWithLabel
|
||||
{
|
||||
$oInput = new Select();
|
||||
$oInput = new Select($sId);
|
||||
$oInput->SetName($sName);
|
||||
|
||||
if (is_null($sId)) {
|
||||
$sId = $oInput->GetId();
|
||||
}
|
||||
$oInputWithLabel = new InputWithLabel($sLabel, $oInput, $sId);
|
||||
|
||||
|
||||
return $oInputWithLabel;
|
||||
}
|
||||
}
|
||||
|
||||
public static function MakeForTextareaWithLabel(
|
||||
string $sName, string $sLabel, ?string $sId = null, ?string $sValue = null,
|
||||
?int $iCols = null, ?int $iRows = null
|
||||
): InputWithLabel
|
||||
{
|
||||
$oTextArea = new TextArea($sValue, $sId, $iCols, $iRows);
|
||||
$oTextArea->SetName($sName);
|
||||
|
||||
if (is_null($sId)) {
|
||||
$sId = $oTextArea->GetId();
|
||||
}
|
||||
$oInputWithLabel = new InputWithLabel($sLabel, $oTextArea, $sId);
|
||||
|
||||
return $oInputWithLabel;
|
||||
}
|
||||
|
||||
public static function MakeForSelect(string $sName, ?string $sId = null): Select
|
||||
{
|
||||
$oInput = new Select($sId);
|
||||
$oInput->SetName($sName);
|
||||
|
||||
|
||||
return $oInput;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,38 +16,33 @@ class InputWithLabel extends UIBlock
|
||||
|
||||
/** @var string */
|
||||
protected $sLabel;
|
||||
/** @var \Combodo\iTop\Application\UI\Base\Component\Input\Input */
|
||||
/** @var \Combodo\iTop\Application\UI\Base\Component\Input\AbstractInput */
|
||||
protected $oInput;
|
||||
/** @var bool */
|
||||
protected $bHasBr;
|
||||
|
||||
/**
|
||||
* InputWithLabel constructor.
|
||||
*
|
||||
* @param string $sLabel
|
||||
* @param \Combodo\iTop\Application\UI\Base\Component\Input\Input $oInput
|
||||
*/
|
||||
public function __construct(string $sLabel, \Combodo\iTop\Application\UI\Base\Component\Input\Input $oInput, ?string $sId)
|
||||
public function __construct(string $sLabel, AbstractInput $oInput, ?string $sId, ?bool $bHasBr = null)
|
||||
{
|
||||
parent::__construct($sId);
|
||||
$this->sLabel = $sLabel;
|
||||
$this->oInput = $oInput;
|
||||
|
||||
if (is_null($bHasBr)) {
|
||||
$this->bHasBr = ($oInput instanceof TextArea);
|
||||
} else {
|
||||
$this->bHasBr = $bHasBr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Input\Input
|
||||
*/
|
||||
public function GetInput(): \Combodo\iTop\Application\UI\Base\Component\Input\Input
|
||||
public function GetInput(): AbstractInput
|
||||
{
|
||||
return $this->oInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Combodo\iTop\Application\UI\Base\Component\Input\Input $oInput
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetInput(\Combodo\iTop\Application\UI\Base\Component\Input\Input $oInput): InputWithLabel
|
||||
public function SetInput(AbstractInput $oInput): InputWithLabel
|
||||
{
|
||||
$this->oInput = $oInput;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -68,7 +63,12 @@ class InputWithLabel extends UIBlock
|
||||
public function SetLabel(string $sLabel): InputWithLabel
|
||||
{
|
||||
$this->sLabel = $sLabel;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function HasBr(): bool
|
||||
{
|
||||
return $this->bHasBr;
|
||||
}
|
||||
}
|
||||
56
sources/application/UI/Base/Component/Input/TextArea.php
Normal file
56
sources/application/UI/Base/Component/Input/TextArea.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Component\Input;
|
||||
|
||||
|
||||
/**
|
||||
* @package Combodo\iTop\Application\UI\Base\Component\Input
|
||||
*/
|
||||
class TextArea extends AbstractInput
|
||||
{
|
||||
// Overloaded constants
|
||||
public const BLOCK_CODE = 'ibo-textarea';
|
||||
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/components/input/input-textarea';
|
||||
|
||||
/** @var int */
|
||||
protected $iCols;
|
||||
/** @var int */
|
||||
protected $iRows;
|
||||
|
||||
public function __construct(?string $sValue, ?string $sId = null, ?int $iCols = null, ?int $iRows = null)
|
||||
{
|
||||
parent::__construct($sId);
|
||||
|
||||
$this->sValue = $sValue;
|
||||
$this->iCols = $iCols;
|
||||
$this->iRows = $iRows;
|
||||
}
|
||||
|
||||
public function GetCols(): int
|
||||
{
|
||||
return $this->iCols;
|
||||
}
|
||||
|
||||
public function SetCols(int $iCols): TextArea
|
||||
{
|
||||
$this->iCols = $iCols;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetRows(): int
|
||||
{
|
||||
return $this->iRows;
|
||||
}
|
||||
|
||||
public function SetRows(int $iRows): TextArea
|
||||
{
|
||||
$this->iRows = $iRows;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
8
templates/base/components/input/input-textarea.html.twig
Normal file
8
templates/base/components/input/input-textarea.html.twig
Normal file
@@ -0,0 +1,8 @@
|
||||
{% block iboInputLabel %}
|
||||
{% endblock %}
|
||||
{% block iboInput %}
|
||||
<textarea
|
||||
id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}"
|
||||
cols="{{ oUIBlock.GetCols() }}" rows="{{ oUIBlock.GetRows() }}"
|
||||
>{{ oUIBlock.GetValue()|raw }}</textarea>
|
||||
{% endblock %}
|
||||
@@ -1,4 +1,5 @@
|
||||
{% block iboInputLabel %}
|
||||
<label for="{{ oUIBlock.GetId() }}">{{ oUIBlock.GetLabel() }}</label>
|
||||
<label for="{{ oUIBlock.GetId() }}">{{ oUIBlock.GetLabel() }}</label>
|
||||
{% if oUIBlock.HasBr() %}<br>{% endif %}
|
||||
{{ render_block(oUIBlock.GetInput()) }}
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user