mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-22 01:49:05 +02:00
Implement a filter for Log Table (part 1)
This commit is contained in:
parent
017b0f717e
commit
c7f5c23374
12 changed files with 444 additions and 23 deletions
|
@ -42,6 +42,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\DataTables\Filters\LogFilter;
|
||||||
use App\DataTables\LogDataTable;
|
use App\DataTables\LogDataTable;
|
||||||
use App\Entity\Base\AbstractDBElement;
|
use App\Entity\Base\AbstractDBElement;
|
||||||
use App\Entity\LogSystem\AbstractLogEntry;
|
use App\Entity\LogSystem\AbstractLogEntry;
|
||||||
|
@ -49,6 +50,7 @@ use App\Entity\LogSystem\CollectionElementDeleted;
|
||||||
use App\Entity\LogSystem\ElementCreatedLogEntry;
|
use App\Entity\LogSystem\ElementCreatedLogEntry;
|
||||||
use App\Entity\LogSystem\ElementDeletedLogEntry;
|
use App\Entity\LogSystem\ElementDeletedLogEntry;
|
||||||
use App\Entity\LogSystem\ElementEditedLogEntry;
|
use App\Entity\LogSystem\ElementEditedLogEntry;
|
||||||
|
use App\Form\Filters\LogFilterType;
|
||||||
use App\Services\LogSystem\EventUndoHelper;
|
use App\Services\LogSystem\EventUndoHelper;
|
||||||
use App\Services\LogSystem\TimeTravel;
|
use App\Services\LogSystem\TimeTravel;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
@ -86,7 +88,17 @@ class LogController extends AbstractController
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('@system.show_logs');
|
$this->denyAccessUnlessGranted('@system.show_logs');
|
||||||
|
|
||||||
$table = $dataTable->createFromType(LogDataTable::class)
|
$formRequest = clone $request;
|
||||||
|
$formRequest->setMethod('GET');
|
||||||
|
$filter = new LogFilter();
|
||||||
|
|
||||||
|
$filterForm = $this->createForm(LogFilterType::class, $filter, ['method' => 'GET']);
|
||||||
|
|
||||||
|
$filterForm->handleRequest($formRequest);
|
||||||
|
|
||||||
|
$table = $dataTable->createFromType(LogDataTable::class, [
|
||||||
|
'filter' => $filter,
|
||||||
|
])
|
||||||
->handleRequest($request);
|
->handleRequest($request);
|
||||||
|
|
||||||
if ($table->isCallback()) {
|
if ($table->isCallback()) {
|
||||||
|
@ -95,6 +107,7 @@ class LogController extends AbstractController
|
||||||
|
|
||||||
return $this->render('LogSystem/log_list.html.twig', [
|
return $this->render('LogSystem/log_list.html.twig', [
|
||||||
'datatable' => $table,
|
'datatable' => $table,
|
||||||
|
'filterForm' => $filterForm->createView(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ use App\DataTables\Filters\Constraints\BooleanConstraint;
|
||||||
use App\DataTables\Filters\Constraints\DateTimeConstraint;
|
use App\DataTables\Filters\Constraints\DateTimeConstraint;
|
||||||
use App\DataTables\Filters\Constraints\EntityConstraint;
|
use App\DataTables\Filters\Constraints\EntityConstraint;
|
||||||
use App\DataTables\Filters\Constraints\InstanceOfConstraint;
|
use App\DataTables\Filters\Constraints\InstanceOfConstraint;
|
||||||
|
use App\DataTables\Filters\Constraints\IntConstraint;
|
||||||
use App\DataTables\Filters\Constraints\NumberConstraint;
|
use App\DataTables\Filters\Constraints\NumberConstraint;
|
||||||
use App\DataTables\Filters\Constraints\TextConstraint;
|
use App\DataTables\Filters\Constraints\TextConstraint;
|
||||||
use App\Entity\Attachments\AttachmentType;
|
use App\Entity\Attachments\AttachmentType;
|
||||||
|
@ -40,7 +41,7 @@ class AttachmentFilter implements FilterInterface
|
||||||
|
|
||||||
public function __construct(NodesListBuilder $nodesListBuilder)
|
public function __construct(NodesListBuilder $nodesListBuilder)
|
||||||
{
|
{
|
||||||
$this->dbId = new NumberConstraint('attachment.id');
|
$this->dbId = new IntConstraint('attachment.id');
|
||||||
$this->name = new TextConstraint('attachment.name');
|
$this->name = new TextConstraint('attachment.name');
|
||||||
$this->targetType = new InstanceOfConstraint('attachment');
|
$this->targetType = new InstanceOfConstraint('attachment');
|
||||||
$this->attachmentType = new EntityConstraint($nodesListBuilder, AttachmentType::class, 'attachment.attachment_type');
|
$this->attachmentType = new EntityConstraint($nodesListBuilder, AttachmentType::class, 'attachment.attachment_type');
|
||||||
|
|
|
@ -9,7 +9,7 @@ class ChoiceConstraint extends AbstractConstraint
|
||||||
public const ALLOWED_OPERATOR_VALUES = ['ANY', 'NONE'];
|
public const ALLOWED_OPERATOR_VALUES = ['ANY', 'NONE'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string[] The values to compare to
|
* @var string[]|int[] The values to compare to
|
||||||
*/
|
*/
|
||||||
protected $value;
|
protected $value;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class ChoiceConstraint extends AbstractConstraint
|
||||||
protected $operator;
|
protected $operator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string[]
|
* @return string[]|int[]
|
||||||
*/
|
*/
|
||||||
public function getValue(): array
|
public function getValue(): array
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ class ChoiceConstraint extends AbstractConstraint
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string[] $value
|
* @param string[]|int[] $value
|
||||||
* @return ChoiceConstraint
|
* @return ChoiceConstraint
|
||||||
*/
|
*/
|
||||||
public function setValue(array $value): ChoiceConstraint
|
public function setValue(array $value): ChoiceConstraint
|
||||||
|
|
|
@ -36,18 +36,22 @@ class EntityConstraint extends AbstractConstraint
|
||||||
protected $value;
|
protected $value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param NodesListBuilder $nodesListBuilder
|
* @param NodesListBuilder|null $nodesListBuilder
|
||||||
* @param class-string<T> $class
|
* @param class-string $class
|
||||||
* @param string $property
|
* @param string $property
|
||||||
* @param string|null $identifier
|
* @param string|null $identifier
|
||||||
* @param $value
|
* @param null $value
|
||||||
* @param string $operator
|
* @param string $operator
|
||||||
*/
|
*/
|
||||||
public function __construct(NodesListBuilder $nodesListBuilder, string $class, string $property, string $identifier = null, $value = null, string $operator = '')
|
public function __construct(?NodesListBuilder $nodesListBuilder, string $class, string $property, string $identifier = null, $value = null, string $operator = '')
|
||||||
{
|
{
|
||||||
$this->nodesListBuilder = $nodesListBuilder;
|
$this->nodesListBuilder = $nodesListBuilder;
|
||||||
$this->class = $class;
|
$this->class = $class;
|
||||||
|
|
||||||
|
if ($nodesListBuilder === null && $this->isStructural()) {
|
||||||
|
throw new \InvalidArgumentException('NodesListBuilder must be provided for structural entities');
|
||||||
|
}
|
||||||
|
|
||||||
parent::__construct($property, $identifier);
|
parent::__construct($property, $identifier);
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
$this->operator = $operator;
|
$this->operator = $operator;
|
||||||
|
|
110
src/DataTables/Filters/LogFilter.php
Normal file
110
src/DataTables/Filters/LogFilter.php
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\DataTables\Filters;
|
||||||
|
|
||||||
|
use App\DataTables\Filters\Constraints\ChoiceConstraint;
|
||||||
|
use App\DataTables\Filters\Constraints\DateTimeConstraint;
|
||||||
|
use App\DataTables\Filters\Constraints\EntityConstraint;
|
||||||
|
use App\DataTables\Filters\Constraints\InstanceOfConstraint;
|
||||||
|
use App\DataTables\Filters\Constraints\IntConstraint;
|
||||||
|
use App\DataTables\Filters\Constraints\NumberConstraint;
|
||||||
|
use App\Entity\UserSystem\User;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
|
||||||
|
class LogFilter implements FilterInterface
|
||||||
|
{
|
||||||
|
use CompoundFilterTrait;
|
||||||
|
|
||||||
|
/** @var DateTimeConstraint */
|
||||||
|
protected $timestamp;
|
||||||
|
|
||||||
|
/** @var IntConstraint */
|
||||||
|
protected $dbId;
|
||||||
|
|
||||||
|
/** @var ChoiceConstraint */
|
||||||
|
protected $level;
|
||||||
|
|
||||||
|
/** @var InstanceOfConstraint */
|
||||||
|
protected $eventType;
|
||||||
|
|
||||||
|
/** @var ChoiceConstraint */
|
||||||
|
protected $targetType;
|
||||||
|
|
||||||
|
/** @var IntConstraint */
|
||||||
|
protected $targetId;
|
||||||
|
|
||||||
|
/** @var EntityConstraint */
|
||||||
|
protected $user;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->timestamp = new DateTimeConstraint('log.timestamp');
|
||||||
|
$this->dbId = new IntConstraint('log.id');
|
||||||
|
$this->level = new ChoiceConstraint('log.level');
|
||||||
|
$this->eventType = new InstanceOfConstraint('log');
|
||||||
|
$this->user = new EntityConstraint(null, User::class, 'log.user');
|
||||||
|
|
||||||
|
$this->targetType = new ChoiceConstraint('log.target_type');
|
||||||
|
$this->targetId = new IntConstraint('log.target_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function apply(QueryBuilder $queryBuilder): void
|
||||||
|
{
|
||||||
|
$this->applyAllChildFilters($queryBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTimeConstraint
|
||||||
|
*/
|
||||||
|
public function getTimestamp(): DateTimeConstraint
|
||||||
|
{
|
||||||
|
return $this->timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IntConstraint|NumberConstraint
|
||||||
|
*/
|
||||||
|
public function getDbId()
|
||||||
|
{
|
||||||
|
return $this->dbId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ChoiceConstraint
|
||||||
|
*/
|
||||||
|
public function getLevel(): ChoiceConstraint
|
||||||
|
{
|
||||||
|
return $this->level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return InstanceOfConstraint
|
||||||
|
*/
|
||||||
|
public function getEventType(): InstanceOfConstraint
|
||||||
|
{
|
||||||
|
return $this->eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ChoiceConstraint
|
||||||
|
*/
|
||||||
|
public function getTargetType(): ChoiceConstraint
|
||||||
|
{
|
||||||
|
return $this->targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IntConstraint
|
||||||
|
*/
|
||||||
|
public function getTargetId(): IntConstraint
|
||||||
|
{
|
||||||
|
return $this->targetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUser(): EntityConstraint
|
||||||
|
{
|
||||||
|
return $this->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -47,6 +47,8 @@ use App\DataTables\Column\LocaleDateTimeColumn;
|
||||||
use App\DataTables\Column\LogEntryExtraColumn;
|
use App\DataTables\Column\LogEntryExtraColumn;
|
||||||
use App\DataTables\Column\LogEntryTargetColumn;
|
use App\DataTables\Column\LogEntryTargetColumn;
|
||||||
use App\DataTables\Column\RevertLogColumn;
|
use App\DataTables\Column\RevertLogColumn;
|
||||||
|
use App\DataTables\Filters\AttachmentFilter;
|
||||||
|
use App\DataTables\Filters\LogFilter;
|
||||||
use App\Entity\Base\AbstractDBElement;
|
use App\Entity\Base\AbstractDBElement;
|
||||||
use App\Entity\Contracts\TimeTravelInterface;
|
use App\Entity\Contracts\TimeTravelInterface;
|
||||||
use App\Entity\LogSystem\AbstractLogEntry;
|
use App\Entity\LogSystem\AbstractLogEntry;
|
||||||
|
@ -61,6 +63,7 @@ use App\Services\ElementTypeNameGenerator;
|
||||||
use App\Services\EntityURLGenerator;
|
use App\Services\EntityURLGenerator;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider;
|
||||||
use Omines\DataTablesBundle\Adapter\Doctrine\ORMAdapter;
|
use Omines\DataTablesBundle\Adapter\Doctrine\ORMAdapter;
|
||||||
use Omines\DataTablesBundle\Column\TextColumn;
|
use Omines\DataTablesBundle\Column\TextColumn;
|
||||||
use Omines\DataTablesBundle\DataTable;
|
use Omines\DataTablesBundle\DataTable;
|
||||||
|
@ -97,10 +100,12 @@ class LogDataTable implements DataTableTypeInterface
|
||||||
$optionsResolver->setDefaults([
|
$optionsResolver->setDefaults([
|
||||||
'mode' => 'system_log',
|
'mode' => 'system_log',
|
||||||
'filter_elements' => [],
|
'filter_elements' => [],
|
||||||
|
'filter' => null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$optionsResolver->setAllowedTypes('filter_elements', ['array', 'object']);
|
$optionsResolver->setAllowedTypes('filter_elements', ['array', 'object']);
|
||||||
$optionsResolver->setAllowedTypes('mode', 'string');
|
$optionsResolver->setAllowedTypes('mode', 'string');
|
||||||
|
$optionsResolver->setAllowedTypes('filter', LogFilter::class);
|
||||||
|
|
||||||
$optionsResolver->setNormalizer('filter_elements', static function (Options $options, $value) {
|
$optionsResolver->setNormalizer('filter_elements', static function (Options $options, $value) {
|
||||||
if (!is_array($value)) {
|
if (!is_array($value)) {
|
||||||
|
@ -192,8 +197,8 @@ class LogDataTable implements DataTableTypeInterface
|
||||||
'label' => $this->translator->trans('log.level'),
|
'label' => $this->translator->trans('log.level'),
|
||||||
'visible' => 'system_log' === $options['mode'],
|
'visible' => 'system_log' === $options['mode'],
|
||||||
'propertyPath' => 'levelString',
|
'propertyPath' => 'levelString',
|
||||||
'render' => static function (string $value, AbstractLogEntry $context) {
|
'render' => function (string $value, AbstractLogEntry $context) {
|
||||||
return $value;
|
return $this->translator->trans('log.level.'.$value);
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -271,9 +276,24 @@ class LogDataTable implements DataTableTypeInterface
|
||||||
'query' => function (QueryBuilder $builder) use ($options): void {
|
'query' => function (QueryBuilder $builder) use ($options): void {
|
||||||
$this->getQuery($builder, $options);
|
$this->getQuery($builder, $options);
|
||||||
},
|
},
|
||||||
|
'criteria' => [
|
||||||
|
function (QueryBuilder $builder) use ($options): void {
|
||||||
|
$this->buildCriteria($builder, $options);
|
||||||
|
},
|
||||||
|
new SearchCriteriaProvider(),
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function buildCriteria(QueryBuilder $builder, array $options): void
|
||||||
|
{
|
||||||
|
if (!empty($options['filter'])) {
|
||||||
|
$filter = $options['filter'];
|
||||||
|
$filter->apply($builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
protected function getQuery(QueryBuilder $builder, array $options): void
|
protected function getQuery(QueryBuilder $builder, array $options): void
|
||||||
{
|
{
|
||||||
$builder->distinct()->select('log')
|
$builder->distinct()->select('log')
|
||||||
|
@ -281,6 +301,7 @@ class LogDataTable implements DataTableTypeInterface
|
||||||
->from(AbstractLogEntry::class, 'log')
|
->from(AbstractLogEntry::class, 'log')
|
||||||
->leftJoin('log.user', 'user');
|
->leftJoin('log.user', 'user');
|
||||||
|
|
||||||
|
/* Do this here as we don't want to show up the global count of all log entries in the footer line, with these modes */
|
||||||
if ('last_activity' === $options['mode']) {
|
if ('last_activity' === $options['mode']) {
|
||||||
$builder->where('log INSTANCE OF '.ElementCreatedLogEntry::class)
|
$builder->where('log INSTANCE OF '.ElementCreatedLogEntry::class)
|
||||||
->orWhere('log INSTANCE OF '.ElementDeletedLogEntry::class)
|
->orWhere('log INSTANCE OF '.ElementDeletedLogEntry::class)
|
||||||
|
|
|
@ -447,6 +447,6 @@ abstract class AbstractLogEntry extends AbstractDBElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new InvalidArgumentException('No target ID for this class is existing!');
|
throw new InvalidArgumentException('No target ID for this class is existing! (Class: '.$class.')');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ use App\Form\Filters\Constraints\BooleanConstraintType;
|
||||||
use App\Form\Filters\Constraints\DateTimeConstraintType;
|
use App\Form\Filters\Constraints\DateTimeConstraintType;
|
||||||
use App\Form\Filters\Constraints\InstanceOfConstraintType;
|
use App\Form\Filters\Constraints\InstanceOfConstraintType;
|
||||||
use App\Form\Filters\Constraints\NumberConstraintType;
|
use App\Form\Filters\Constraints\NumberConstraintType;
|
||||||
use App\Form\Filters\Constraints\StructuralEntityConstraintType;
|
use App\Form\Filters\Constraints\UserEntityConstraintType;
|
||||||
use App\Form\Filters\Constraints\TextConstraintType;
|
use App\Form\Filters\Constraints\TextConstraintType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ResetType;
|
use Symfony\Component\Form\Extension\Core\Type\ResetType;
|
||||||
|
@ -73,7 +73,7 @@ class AttachmentFilterType extends AbstractType
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$builder->add('attachmentType', StructuralEntityConstraintType::class, [
|
$builder->add('attachmentType', UserEntityConstraintType::class, [
|
||||||
'label' => 'attachment.attachment_type',
|
'label' => 'attachment.attachment_type',
|
||||||
'entity_class' => AttachmentType::class
|
'entity_class' => AttachmentType::class
|
||||||
]);
|
]);
|
||||||
|
|
153
src/Form/Filters/LogFilterType.php
Normal file
153
src/Form/Filters/LogFilterType.php
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form\Filters;
|
||||||
|
|
||||||
|
use App\DataTables\Filters\LogFilter;
|
||||||
|
use App\Entity\Attachments\Attachment;
|
||||||
|
use App\Entity\Attachments\AttachmentType;
|
||||||
|
use App\Entity\Devices\Device;
|
||||||
|
use App\Entity\Devices\DevicePart;
|
||||||
|
use App\Entity\LabelSystem\LabelProfile;
|
||||||
|
use App\Entity\LogSystem\AbstractLogEntry;
|
||||||
|
use App\Entity\LogSystem\CollectionElementDeleted;
|
||||||
|
use App\Entity\LogSystem\DatabaseUpdatedLogEntry;
|
||||||
|
use App\Entity\LogSystem\ElementCreatedLogEntry;
|
||||||
|
use App\Entity\LogSystem\ElementDeletedLogEntry;
|
||||||
|
use App\Entity\LogSystem\ElementEditedLogEntry;
|
||||||
|
use App\Entity\LogSystem\InstockChangedLogEntry;
|
||||||
|
use App\Entity\LogSystem\SecurityEventLogEntry;
|
||||||
|
use App\Entity\LogSystem\UserLoginLogEntry;
|
||||||
|
use App\Entity\LogSystem\UserLogoutLogEntry;
|
||||||
|
use App\Entity\LogSystem\UserNotAllowedLogEntry;
|
||||||
|
use App\Entity\Parameters\AbstractParameter;
|
||||||
|
use App\Entity\Parts\Category;
|
||||||
|
use App\Entity\Parts\Footprint;
|
||||||
|
use App\Entity\Parts\Manufacturer;
|
||||||
|
use App\Entity\Parts\MeasurementUnit;
|
||||||
|
use App\Entity\Parts\Part;
|
||||||
|
use App\Entity\Parts\PartLot;
|
||||||
|
use App\Entity\Parts\Storelocation;
|
||||||
|
use App\Entity\Parts\Supplier;
|
||||||
|
use App\Entity\PriceInformations\Currency;
|
||||||
|
use App\Entity\PriceInformations\Orderdetail;
|
||||||
|
use App\Entity\PriceInformations\Pricedetail;
|
||||||
|
use App\Entity\UserSystem\Group;
|
||||||
|
use App\Entity\UserSystem\User;
|
||||||
|
use App\Form\Filters\Constraints\ChoiceConstraintType;
|
||||||
|
use App\Form\Filters\Constraints\DateTimeConstraintType;
|
||||||
|
use App\Form\Filters\Constraints\InstanceOfConstraintType;
|
||||||
|
use App\Form\Filters\Constraints\NumberConstraintType;
|
||||||
|
use App\Form\Filters\Constraints\StructuralEntityConstraintType;
|
||||||
|
use App\Form\Filters\Constraints\UserEntityConstraintType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ResetType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class LogFilterType extends AbstractType
|
||||||
|
{
|
||||||
|
protected const LEVEL_CHOICES = [
|
||||||
|
'log.level.debug' => AbstractLogEntry::LEVEL_DEBUG,
|
||||||
|
'log.level.info' => AbstractLogEntry::LEVEL_INFO,
|
||||||
|
'log.level.notice' => AbstractLogEntry::LEVEL_NOTICE,
|
||||||
|
'log.level.warning' => AbstractLogEntry::LEVEL_WARNING,
|
||||||
|
'log.level.error' => AbstractLogEntry::LEVEL_ERROR,
|
||||||
|
'log.level.critical' => AbstractLogEntry::LEVEL_CRITICAL,
|
||||||
|
'log.level.alert' => AbstractLogEntry::LEVEL_ALERT,
|
||||||
|
'log.level.emergency' => AbstractLogEntry::LEVEL_EMERGENCY,
|
||||||
|
];
|
||||||
|
|
||||||
|
protected const TARGET_TYPE_CHOICES = [
|
||||||
|
'log.type.collection_element_deleted' => CollectionElementDeleted::class,
|
||||||
|
'log.type.database_updated' => DatabaseUpdatedLogEntry::class,
|
||||||
|
'log.type.element_created' => ElementCreatedLogEntry::class,
|
||||||
|
'log.type.element_deleted' => ElementDeletedLogEntry::class,
|
||||||
|
'log.type.element_edited' => ElementEditedLogEntry::class,
|
||||||
|
'log.type.security' => SecurityEventLogEntry::class,
|
||||||
|
'log.type.user_login' => UserLoginLogEntry::class,
|
||||||
|
'log.type.user_logout' => UserLogoutLogEntry::class,
|
||||||
|
'log.type.user_not_allowed' => UserNotAllowedLogEntry::class,
|
||||||
|
|
||||||
|
//Legacy entries
|
||||||
|
'log.type.instock_changed' => InstockChangedLogEntry::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'compound' => true,
|
||||||
|
'data_class' => LogFilter::class,
|
||||||
|
'csrf_protection' => false,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->add('dbId', NumberConstraintType::class, [
|
||||||
|
'label' => 'part.filter.dbId',
|
||||||
|
'min' => 1,
|
||||||
|
'step' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$builder->add('timestamp', DateTimeConstraintType::class, [
|
||||||
|
'label' => 'log.timestamp',
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$builder->add('level', ChoiceConstraintType::class, [
|
||||||
|
'label' => 'log.level',
|
||||||
|
'choices' => self::LEVEL_CHOICES,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$builder->add('eventType', InstanceOfConstraintType::class, [
|
||||||
|
'label' => 'log.type',
|
||||||
|
'choices' => self::TARGET_TYPE_CHOICES
|
||||||
|
]);
|
||||||
|
|
||||||
|
$builder->add('user', StructuralEntityConstraintType::class, [
|
||||||
|
'label' => 'log.user',
|
||||||
|
'entity_class' => User::class,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$builder->add('targetType', ChoiceConstraintType::class, [
|
||||||
|
'label' => 'log.target_type',
|
||||||
|
'choices' => [
|
||||||
|
'user.label' => AbstractLogEntry::targetTypeClassToID(User::class),
|
||||||
|
'attachment.label' => AbstractLogEntry::targetTypeClassToID(Attachment::class),
|
||||||
|
'attachment_type.label' => AbstractLogEntry::targetTypeClassToID(AttachmentType::class),
|
||||||
|
'category.label' => AbstractLogEntry::targetTypeClassToID(Category::class),
|
||||||
|
'device.label' => AbstractLogEntry::targetTypeClassToID(Device::class),
|
||||||
|
'device_part.label' => AbstractLogEntry::targetTypeClassToID(DevicePart::class),
|
||||||
|
'footprint.label' => AbstractLogEntry::targetTypeClassToID(Footprint::class),
|
||||||
|
'group.label' => AbstractLogEntry::targetTypeClassToID(Group::class),
|
||||||
|
'manufacturer.label' => AbstractLogEntry::targetTypeClassToID(Manufacturer::class),
|
||||||
|
'part.label' => AbstractLogEntry::targetTypeClassToID(Part::class),
|
||||||
|
'storelocation.label' => AbstractLogEntry::targetTypeClassToID(Storelocation::class),
|
||||||
|
'supplier.label' => AbstractLogEntry::targetTypeClassToID(Supplier::class),
|
||||||
|
'part_lot.label' => AbstractLogEntry::targetTypeClassToID(PartLot::class),
|
||||||
|
'currency.label' => AbstractLogEntry::targetTypeClassToID(Currency::class),
|
||||||
|
'orderdetail.label' => AbstractLogEntry::targetTypeClassToID(Orderdetail::class),
|
||||||
|
'pricedetail.label' => AbstractLogEntry::targetTypeClassToID(Pricedetail::class),
|
||||||
|
'measurement_unit.label' => AbstractLogEntry::targetTypeClassToID(MeasurementUnit::class),
|
||||||
|
'parameter.label' => AbstractLogEntry::targetTypeClassToID(AbstractParameter::class),
|
||||||
|
'label_profile.label' => AbstractLogEntry::targetTypeClassToID(LabelProfile::class),
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$builder->add('targetId', NumberConstraintType::class, [
|
||||||
|
'label' => 'log.target_id',
|
||||||
|
'min' => 1,
|
||||||
|
'step' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$builder->add('submit', SubmitType::class, [
|
||||||
|
'label' => 'filter.submit',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$builder->add('discard', ResetType::class, [
|
||||||
|
'label' => 'filter.discard',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ use App\Form\Filters\Constraints\ChoiceConstraintType;
|
||||||
use App\Form\Filters\Constraints\DateTimeConstraintType;
|
use App\Form\Filters\Constraints\DateTimeConstraintType;
|
||||||
use App\Form\Filters\Constraints\NumberConstraintType;
|
use App\Form\Filters\Constraints\NumberConstraintType;
|
||||||
use App\Form\Filters\Constraints\ParameterConstraintType;
|
use App\Form\Filters\Constraints\ParameterConstraintType;
|
||||||
use App\Form\Filters\Constraints\StructuralEntityConstraintType;
|
use App\Form\Filters\Constraints\UserEntityConstraintType;
|
||||||
use App\Form\Filters\Constraints\TagsConstraintType;
|
use App\Form\Filters\Constraints\TagsConstraintType;
|
||||||
use App\Form\Filters\Constraints\TextConstraintType;
|
use App\Form\Filters\Constraints\TextConstraintType;
|
||||||
use Svg\Tag\Text;
|
use Svg\Tag\Text;
|
||||||
|
@ -54,12 +54,12 @@ class PartFilterType extends AbstractType
|
||||||
'label' => 'part.edit.description',
|
'label' => 'part.edit.description',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$builder->add('category', StructuralEntityConstraintType::class, [
|
$builder->add('category', UserEntityConstraintType::class, [
|
||||||
'label' => 'part.edit.category',
|
'label' => 'part.edit.category',
|
||||||
'entity_class' => Category::class
|
'entity_class' => Category::class
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$builder->add('footprint', StructuralEntityConstraintType::class, [
|
$builder->add('footprint', UserEntityConstraintType::class, [
|
||||||
'label' => 'part.edit.footprint',
|
'label' => 'part.edit.footprint',
|
||||||
'entity_class' => Footprint::class
|
'entity_class' => Footprint::class
|
||||||
]);
|
]);
|
||||||
|
@ -96,7 +96,7 @@ class PartFilterType extends AbstractType
|
||||||
'min' => 0,
|
'min' => 0,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$builder->add('measurementUnit', StructuralEntityConstraintType::class, [
|
$builder->add('measurementUnit', UserEntityConstraintType::class, [
|
||||||
'label' => 'part.edit.partUnit',
|
'label' => 'part.edit.partUnit',
|
||||||
'entity_class' => MeasurementUnit::class
|
'entity_class' => MeasurementUnit::class
|
||||||
]);
|
]);
|
||||||
|
@ -114,7 +114,7 @@ class PartFilterType extends AbstractType
|
||||||
* Manufacturer tab
|
* Manufacturer tab
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$builder->add('manufacturer', StructuralEntityConstraintType::class, [
|
$builder->add('manufacturer', UserEntityConstraintType::class, [
|
||||||
'label' => 'part.edit.manufacturer.label',
|
'label' => 'part.edit.manufacturer.label',
|
||||||
'entity_class' => Manufacturer::class
|
'entity_class' => Manufacturer::class
|
||||||
]);
|
]);
|
||||||
|
@ -145,7 +145,7 @@ class PartFilterType extends AbstractType
|
||||||
* Purchasee informations
|
* Purchasee informations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$builder->add('supplier', StructuralEntityConstraintType::class, [
|
$builder->add('supplier', UserEntityConstraintType::class, [
|
||||||
'label' => 'supplier.label',
|
'label' => 'supplier.label',
|
||||||
'entity_class' => Manufacturer::class
|
'entity_class' => Manufacturer::class
|
||||||
]);
|
]);
|
||||||
|
@ -163,7 +163,7 @@ class PartFilterType extends AbstractType
|
||||||
/*
|
/*
|
||||||
* Stocks tabs
|
* Stocks tabs
|
||||||
*/
|
*/
|
||||||
$builder->add('storelocation', StructuralEntityConstraintType::class, [
|
$builder->add('storelocation', UserEntityConstraintType::class, [
|
||||||
'label' => 'storelocation.label',
|
'label' => 'storelocation.label',
|
||||||
'entity_class' => Storelocation::class
|
'entity_class' => Storelocation::class
|
||||||
]);
|
]);
|
||||||
|
@ -210,7 +210,7 @@ class PartFilterType extends AbstractType
|
||||||
'min' => 0,
|
'min' => 0,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$builder->add('attachmentType', StructuralEntityConstraintType::class, [
|
$builder->add('attachmentType', UserEntityConstraintType::class, [
|
||||||
'label' => 'attachment.attachment_type',
|
'label' => 'attachment.attachment_type',
|
||||||
'entity_class' => AttachmentType::class
|
'entity_class' => AttachmentType::class
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -3,5 +3,52 @@
|
||||||
{% block title %}{% trans %}log.list.title{% endtrans %}{% endblock %}
|
{% block title %}{% trans %}log.list.title{% endtrans %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<div class="accordion mb-3" id="listAccordion">
|
||||||
|
<div class="accordion-item">
|
||||||
|
<div class="accordion-header">
|
||||||
|
<button class="accordion-button collapsed py-2" data-bs-toggle="collapse" data-bs-target="#searchInfo" disabled>
|
||||||
|
<i class="fa-solid fa-binoculars fa-fw"></i>
|
||||||
|
{% trans %}log.list.title{% endtrans %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="searchInfo" class="accordion-collapse collapse" data-bs-parent="#listAccordion">
|
||||||
|
<div class="accordion-body">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="accordion-item">
|
||||||
|
<div class="accordion-header">
|
||||||
|
<button class="accordion-button collapsed py-2" type="button" data-bs-toggle="collapse" data-bs-target="#filterFormCollapse" aria-expanded="false" aria-controls="filterFormCollapse"><i class="fa-solid fa-filter fa-fw"></i> {% trans %}filter.title{% endtrans %}</button>
|
||||||
|
</div>
|
||||||
|
<div id="filterFormCollapse" class="accordion-collapse collapse" data-bs-parent="#listAccordion">
|
||||||
|
<div class="accordion-body">
|
||||||
|
{{ form_start(filterForm, {"attr": {"data-controller": "helpers--form-cleanup", "data-action": "helpers--form-cleanup#submit"}}) }}
|
||||||
|
|
||||||
|
{{ form_row(filterForm.dbId) }}
|
||||||
|
{{ form_row(filterForm.timestamp) }}
|
||||||
|
{{ form_row(filterForm.eventType) }}
|
||||||
|
{{ form_row(filterForm.level) }}
|
||||||
|
{{ form_row(filterForm.targetType) }}
|
||||||
|
{{ form_row(filterForm.targetId) }}
|
||||||
|
|
||||||
|
{{ form_row(filterForm.submit) }}
|
||||||
|
{{ form_row(filterForm.discard) }}
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-sm-9 offset-sm-3">
|
||||||
|
<button type="button" class="btn btn-danger" {{ stimulus_action('helpers/form_cleanup', 'clearAll') }}>{% trans %}filter.clear_filters{% endtrans %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ form_end(filterForm) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% include "LogSystem/_log_table.html.twig" %}
|
{% include "LogSystem/_log_table.html.twig" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -9699,5 +9699,77 @@ Element 3</target>
|
||||||
<target>Associated element type</target>
|
<target>Associated element type</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
|
<unit id="nUZamS5" name="log.level.debug">
|
||||||
|
<segment>
|
||||||
|
<source>log.level.debug</source>
|
||||||
|
<target>Debug</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="ZPxm2Ee" name="log.level.info">
|
||||||
|
<segment>
|
||||||
|
<source>log.level.info</source>
|
||||||
|
<target>Info</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="NVXjDhG" name="log.level.notice">
|
||||||
|
<segment>
|
||||||
|
<source>log.level.notice</source>
|
||||||
|
<target>Notice</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="9ObjWuR" name="log.level.warning">
|
||||||
|
<segment>
|
||||||
|
<source>log.level.warning</source>
|
||||||
|
<target>Warning</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="WxMwuLP" name="log.level.error">
|
||||||
|
<segment>
|
||||||
|
<source>log.level.error</source>
|
||||||
|
<target>Error</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="idch78J" name="log.level.critical">
|
||||||
|
<segment>
|
||||||
|
<source>log.level.critical</source>
|
||||||
|
<target>Critical</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="jehoQTd" name="log.level.alert">
|
||||||
|
<segment>
|
||||||
|
<source>log.level.alert</source>
|
||||||
|
<target>Alert</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="XvKEDM0" name="log.level.emergency">
|
||||||
|
<segment>
|
||||||
|
<source>log.level.emergency</source>
|
||||||
|
<target>Emergency</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="sEvRe10" name="log.type.security">
|
||||||
|
<segment>
|
||||||
|
<source>log.type.security</source>
|
||||||
|
<target>Security related event</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="gJDmvym" name="log.type.instock_changed">
|
||||||
|
<segment>
|
||||||
|
<source>log.type.instock_changed</source>
|
||||||
|
<target>[LEGACY] Instock changed</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="4Od2HUk" name="device_part.label">
|
||||||
|
<segment>
|
||||||
|
<source>device_part.label</source>
|
||||||
|
<target>Device part</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
|
<unit id="lJZCHHM" name="log.target_id">
|
||||||
|
<segment>
|
||||||
|
<source>log.target_id</source>
|
||||||
|
<target>Target element ID</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue