mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-24 18:58:46 +02:00
Show preview pictures as carousel on part info page.
This commit is contained in:
parent
07dcbc0464
commit
2d4def2836
5 changed files with 96 additions and 14 deletions
|
@ -34,6 +34,7 @@ use App\Entity\Parts\Category;
|
||||||
use App\Entity\Parts\Part;
|
use App\Entity\Parts\Part;
|
||||||
use App\Form\Part\PartBaseType;
|
use App\Form\Part\PartBaseType;
|
||||||
use App\Services\AttachmentHelper;
|
use App\Services\AttachmentHelper;
|
||||||
|
use App\Services\Attachments\PartPreviewGenerator;
|
||||||
use App\Services\PricedetailHelper;
|
use App\Services\PricedetailHelper;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
@ -55,15 +56,17 @@ class PartController extends AbstractController
|
||||||
* @param AttachmentHelper $attachmentHelper
|
* @param AttachmentHelper $attachmentHelper
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function show(Part $part, AttachmentHelper $attachmentHelper, PricedetailHelper $pricedetailHelper)
|
public function show(Part $part, AttachmentHelper $attachmentHelper, PricedetailHelper $pricedetailHelper, PartPreviewGenerator $previewGenerator)
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('read', $part);
|
$this->denyAccessUnlessGranted('read', $part);
|
||||||
|
|
||||||
return $this->render('Parts/info/show_part_info.html.twig',
|
return $this->render(
|
||||||
|
'Parts/info/show_part_info.html.twig',
|
||||||
[
|
[
|
||||||
'part' => $part,
|
'part' => $part,
|
||||||
'attachment_helper' => $attachmentHelper,
|
'attachment_helper' => $attachmentHelper,
|
||||||
'pricedetail_helper' => $pricedetailHelper
|
'pricedetail_helper' => $pricedetailHelper,
|
||||||
|
'pictures' => $previewGenerator->getPreviewAttachments($part)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,7 @@ class PartsDataTable implements DataTableTypeInterface
|
||||||
->add('picture', TextColumn::class, [
|
->add('picture', TextColumn::class, [
|
||||||
'label' => '',
|
'label' => '',
|
||||||
'render' => function ($value, Part $context) {
|
'render' => function ($value, Part $context) {
|
||||||
$preview_attachment = $this->previewGenerator->previewAttachment($context);
|
$preview_attachment = $this->previewGenerator->getTablePreviewAttachment($context);
|
||||||
if ($preview_attachment === null) {
|
if ($preview_attachment === null) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,13 +48,70 @@ class PartPreviewGenerator
|
||||||
$this->attachmentHelper = $attachmentHelper;
|
$this->attachmentHelper = $attachmentHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of attachments that can be used for previewing the part ordered by priority.
|
||||||
|
* The priority is: Part MasterAttachment -> Footprint MasterAttachment -> Category MasterAttachment
|
||||||
|
* -> Storelocation Attachment -> MeasurementUnit Attachment -> ManufacturerAttachment
|
||||||
|
* @param Part $part The part for which the attachments should be determined.
|
||||||
|
* @return Attachment[]
|
||||||
|
*/
|
||||||
|
public function getPreviewAttachments(Part $part) : array
|
||||||
|
{
|
||||||
|
$list = [];
|
||||||
|
|
||||||
|
//Master attachment has top priority
|
||||||
|
$attachment = $part->getMasterPictureAttachment();
|
||||||
|
if ($this->isAttachmentValidPicture($attachment)) {
|
||||||
|
$list[] = $attachment;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($part->getFootprint() !== null) {
|
||||||
|
$attachment = $part->getFootprint()->getMasterPictureAttachment();
|
||||||
|
if ($this->isAttachmentValidPicture($attachment)) {
|
||||||
|
$list[] = $attachment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($part->getCategory() !== null) {
|
||||||
|
$attachment = $part->getCategory()->getMasterPictureAttachment();
|
||||||
|
if ($this->isAttachmentValidPicture($attachment)) {
|
||||||
|
$list[] = $attachment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($part->getPartLots() as $lot) {
|
||||||
|
if ($lot->getStorageLocation() !== null) {
|
||||||
|
$attachment = $lot->getStorageLocation()->getMasterPictureAttachment();
|
||||||
|
if ($this->isAttachmentValidPicture($attachment)) {
|
||||||
|
$list[] = $attachment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($part->getPartUnit() !== null) {
|
||||||
|
$attachment = $part->getPartUnit()->getMasterPictureAttachment();
|
||||||
|
if ($this->isAttachmentValidPicture($attachment)) {
|
||||||
|
$list[] = $attachment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($part->getManufacturer() !== null) {
|
||||||
|
$attachment = $part->getManufacturer()->getMasterPictureAttachment();
|
||||||
|
if ($this->isAttachmentValidPicture($attachment)) {
|
||||||
|
$list[] = $attachment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines what attachment should be used for previewing a part (especially in part table).
|
* Determines what attachment should be used for previewing a part (especially in part table).
|
||||||
* The returned attachment is guaranteed to be existing and be a picture.
|
* The returned attachment is guaranteed to be existing and be a picture.
|
||||||
* @param Part $part The part for which the attachment should be determined
|
* @param Part $part The part for which the attachment should be determined
|
||||||
* @return Attachment|null
|
* @return Attachment|null
|
||||||
*/
|
*/
|
||||||
public function previewAttachment(Part $part) : ?Attachment
|
public function getTablePreviewAttachment(Part $part) : ?Attachment
|
||||||
{
|
{
|
||||||
//First of all we check if the master attachment of the part is set (and a picture)
|
//First of all we check if the master attachment of the part is set (and a picture)
|
||||||
$attachment = $part->getMasterPictureAttachment();
|
$attachment = $part->getMasterPictureAttachment();
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
{% import "helper.twig" as helper %}
|
{% import "helper.twig" as helper %}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3 col-lg-4">
|
||||||
{% if part.masterPictureAttachment and part.masterPictureAttachment.picture %}
|
{% include "Parts/info/_picture.html.twig" %}
|
||||||
<img src="{{ part.masterPictureAttachment | entityURL('file_view') }}" class="img-fluid img-thumbnail bg-light" alt="Part main image" height="300" width="300">
|
|
||||||
{% else %}
|
|
||||||
<img src="{{ asset('img/part_placeholder.svg') }}" class="img-fluid img-thumbnail bg-light" alt="Part main image" height="300" width="300">
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9 col-lg-8">
|
||||||
<h5 class="text-muted pt-2" title="{% trans %}manufacturer.label{% endtrans %}">
|
<h5 class="text-muted pt-2" title="{% trans %}manufacturer.label{% endtrans %}">
|
||||||
{% if part.manufacturer %}
|
{% if part.manufacturer %}
|
||||||
{% if part.manufacturer.id is not null %}
|
{% if part.manufacturer.id is not null %}
|
||||||
|
|
26
templates/Parts/info/_picture.html.twig
Normal file
26
templates/Parts/info/_picture.html.twig
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{% if not pictures is empty %}
|
||||||
|
{# <img src="{{ part.masterPictureAttachment | entityURL('file_view') }}" class="img-fluid img-thumbnail bg-light" alt="Part main image" height="300" width="300"> #}
|
||||||
|
|
||||||
|
<div id="pictureCarousel" class="carousel slide mb-2" data-interval="false">
|
||||||
|
<div class="carousel-inner">
|
||||||
|
{% for pic in pictures %}
|
||||||
|
<div class="carousel-item {% if loop.first %}active{% endif %}">
|
||||||
|
<img class="d-block w-100 img-fluid img-thumbnail bg-light" src="{{ pic | entityURL('file_view') }}" alt="">
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% if pictures | length > 1 %}
|
||||||
|
<a class="carousel-control-prev" href="#pictureCarousel" role="button" data-slide="prev">
|
||||||
|
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
|
||||||
|
<span class="sr-only">{% trans %}part.info.prev_picture{% endtrans %}</span>
|
||||||
|
</a>
|
||||||
|
<a class="carousel-control-next" href="#pictureCarousel" role="button" data-slide="next">
|
||||||
|
<span class="carousel-control-next-icon" aria-hidden="true"></span>
|
||||||
|
<span class="sr-only">{% trans %}part.info.next_picture{% endtrans %}</span>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<img src="{{ asset('img/part_placeholder.svg') }}" class="img-fluid img-thumbnail bg-light mb-2" alt="Part main image" height="300" width="300">
|
||||||
|
{% endif %}
|
Loading…
Add table
Add a link
Reference in a new issue