Added basic log entry info page

This commit is contained in:
Jan Böhmer 2023-04-10 00:30:23 +02:00
parent e0e5fb3d5a
commit 4107535b19
8 changed files with 339 additions and 136 deletions

View file

@ -36,6 +36,7 @@ use App\Exceptions\EntityNotSupportedException;
use App\Repository\LogEntryRepository;
use App\Services\ElementTypeNameGenerator;
use App\Services\EntityURLGenerator;
use App\Services\LogSystem\LogTargetHelper;
use Doctrine\ORM\EntityManagerInterface;
use Omines\DataTablesBundle\Column\AbstractColumn;
use Symfony\Component\OptionsResolver\OptionsResolver;
@ -43,21 +44,11 @@ use Symfony\Contracts\Translation\TranslatorInterface;
class LogEntryTargetColumn extends AbstractColumn
{
protected EntityManagerInterface $em;
protected LogEntryRepository $entryRepository;
protected EntityURLGenerator $entityURLGenerator;
protected ElementTypeNameGenerator $elementTypeNameGenerator;
protected TranslatorInterface $translator;
private LogTargetHelper $logTargetHelper;
public function __construct(EntityManagerInterface $entityManager, EntityURLGenerator $entityURLGenerator,
ElementTypeNameGenerator $elementTypeNameGenerator, TranslatorInterface $translator)
public function __construct(LogTargetHelper $logTargetHelper)
{
$this->em = $entityManager;
$this->entryRepository = $entityManager->getRepository(AbstractLogEntry::class);
$this->entityURLGenerator = $entityURLGenerator;
$this->elementTypeNameGenerator = $elementTypeNameGenerator;
$this->translator = $translator;
$this->logTargetHelper = $logTargetHelper;
}
/**
@ -80,71 +71,9 @@ class LogEntryTargetColumn extends AbstractColumn
public function render($value, $context): string
{
if ($context instanceof UserNotAllowedLogEntry && $this->options['showAccessDeniedPath']) {
return htmlspecialchars($context->getPath());
}
/** @var AbstractLogEntry $context */
$target = $this->entryRepository->getTargetElement($context);
$tmp = '';
//The element is existing
if ($target instanceof NamedElementInterface && !empty($target->getName())) {
try {
$tmp = sprintf(
'<a href="%s">%s</a>',
$this->entityURLGenerator->infoURL($target),
$this->elementTypeNameGenerator->getTypeNameCombination($target, true)
);
} catch (EntityNotSupportedException $exception) {
$tmp = $this->elementTypeNameGenerator->getTypeNameCombination($target, true);
}
} elseif ($target instanceof AbstractDBElement) { //Target does not have a name
$tmp = sprintf(
'<i>%s</i>: %s',
$this->elementTypeNameGenerator->getLocalizedTypeLabel($target),
$target->getID()
);
} elseif (null === $target && $context->hasTarget()) { //Element was deleted
$tmp = sprintf(
'<i>%s</i>: %s [%s]',
$this->elementTypeNameGenerator->getLocalizedTypeLabel($context->getTargetClass()),
$context->getTargetID(),
$this->translator->trans('log.target_deleted')
);
}
//Add a hint to the associated element if possible
if (null !== $target && $this->options['show_associated']) {
if ($target instanceof Attachment && null !== $target->getElement()) {
$on = $target->getElement();
} elseif ($target instanceof AbstractParameter && null !== $target->getElement()) {
$on = $target->getElement();
} elseif ($target instanceof PartLot && null !== $target->getPart()) {
$on = $target->getPart();
} elseif ($target instanceof Orderdetail && null !== $target->getPart()) {
$on = $target->getPart();
} elseif ($target instanceof Pricedetail && null !== $target->getOrderdetail() && null !== $target->getOrderdetail()->getPart()) {
$on = $target->getOrderdetail()->getPart();
} elseif ($target instanceof ProjectBOMEntry && null !== $target->getProject()) {
$on = $target->getProject();
}
if (isset($on) && is_object($on)) {
try {
$tmp .= sprintf(
' (<a href="%s">%s</a>)',
$this->entityURLGenerator->infoURL($on),
$this->elementTypeNameGenerator->getTypeNameCombination($on, true)
);
} catch (EntityNotSupportedException $exception) {
$tmp .= ' ('.$this->elementTypeNameGenerator->getTypeNameCombination($target, true).')';
}
}
}
//Log is not associated with an element
return $tmp;
return $this->logTargetHelper->formatTarget($context, [
'showAccessDeniedPath' => $this->options['showAccessDeniedPath'],
'show_associated' => $this->options['show_associated'],
]);
}
}

View file

@ -44,6 +44,7 @@ use App\Exceptions\EntityNotSupportedException;
use App\Repository\LogEntryRepository;
use App\Services\ElementTypeNameGenerator;
use App\Services\EntityURLGenerator;
use App\Services\LogSystem\LogLevelHelper;
use App\Services\UserSystem\UserAvatarHelper;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\QueryBuilder;
@ -70,10 +71,11 @@ class LogDataTable implements DataTableTypeInterface
protected LogEntryRepository $logRepo;
protected Security $security;
protected UserAvatarHelper $userAvatarHelper;
protected LogLevelHelper $logLevelHelper;
public function __construct(ElementTypeNameGenerator $elementTypeNameGenerator, TranslatorInterface $translator,
UrlGeneratorInterface $urlGenerator, EntityURLGenerator $entityURLGenerator, EntityManagerInterface $entityManager,
Security $security, UserAvatarHelper $userAvatarHelper)
Security $security, UserAvatarHelper $userAvatarHelper, LogLevelHelper $logLevelHelper)
{
$this->elementTypeNameGenerator = $elementTypeNameGenerator;
$this->translator = $translator;
@ -82,6 +84,7 @@ class LogDataTable implements DataTableTypeInterface
$this->logRepo = $entityManager->getRepository(AbstractLogEntry::class);
$this->security = $security;
$this->userAvatarHelper = $userAvatarHelper;
$this->logLevelHelper = $logLevelHelper;
}
public function configureOptions(OptionsResolver $optionsResolver): void
@ -115,69 +118,18 @@ class LogDataTable implements DataTableTypeInterface
//This special $$rowClass column is used to set the row class depending on the log level. The class gets set by the frontend controller
$dataTable->add('dont_matter', RowClassColumn::class, [
'render' => static function ($value, AbstractLogEntry $context) {
switch ($context->getLevel()) {
case AbstractLogEntry::LEVEL_EMERGENCY:
case AbstractLogEntry::LEVEL_ALERT:
case AbstractLogEntry::LEVEL_CRITICAL:
case AbstractLogEntry::LEVEL_ERROR:
return 'table-danger';
case AbstractLogEntry::LEVEL_WARNING:
return 'table-warning';
case AbstractLogEntry::LEVEL_NOTICE:
return 'table-info';
default:
return '';
}
'render' => function ($value, AbstractLogEntry $context) {
return $this->logLevelHelper->logLevelToTableColorClass($context->getLevelString());
},
]);
$dataTable->add('symbol', TextColumn::class, [
'label' => '',
'className' => 'no-colvis',
'render' => static function ($value, AbstractLogEntry $context) {
switch ($context->getLevelString()) {
case LogLevel::DEBUG:
$symbol = 'fa-bug';
break;
case LogLevel::INFO:
$symbol = 'fa-info';
break;
case LogLevel::NOTICE:
$symbol = 'fa-flag';
break;
case LogLevel::WARNING:
$symbol = 'fa-exclamation-circle';
break;
case LogLevel::ERROR:
$symbol = 'fa-exclamation-triangle';
break;
case LogLevel::CRITICAL:
$symbol = 'fa-bolt';
break;
case LogLevel::ALERT:
$symbol = 'fa-radiation';
break;
case LogLevel::EMERGENCY:
$symbol = 'fa-skull-crossbones';
break;
default:
$symbol = 'fa-question-circle';
break;
}
'render' => function ($value, AbstractLogEntry $context) {
return sprintf(
'<i class="fas fa-fw %s" title="%s"></i>',
$symbol,
$this->logLevelHelper->logLevelToIconClass($context->getLevelString()),
$context->getLevelString()
);
},
@ -191,6 +143,12 @@ class LogDataTable implements DataTableTypeInterface
$dataTable->add('timestamp', LocaleDateTimeColumn::class, [
'label' => 'log.timestamp',
'timeFormat' => 'medium',
'render' => function (string $value, AbstractLogEntry $context) {
return sprintf('<a href="%s">%s</a>',
$this->urlGenerator->generate('log_details', ['id' => $context->getId()]),
$value
);
}
]);
$dataTable->add('type', TextColumn::class, [