mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-20 17:15:51 +02:00
Added ability to view part relations on a part info page
This commit is contained in:
parent
cc2332a83a
commit
7f612bc371
7 changed files with 143 additions and 0 deletions
|
@ -20,6 +20,7 @@ twig:
|
|||
avatar_helper: '@App\Services\UserSystem\UserAvatarHelper'
|
||||
available_themes: '%partdb.available_themes%'
|
||||
saml_enabled: '%partdb.saml.enabled%'
|
||||
part_preview_generator: '@App\Services\Attachments\PartPreviewGenerator'
|
||||
|
||||
when@test:
|
||||
twig:
|
||||
|
|
|
@ -136,5 +136,17 @@ class PartAssociation extends AbstractDBElement
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translation key for the type of this association.
|
||||
* If the type is set to OTHER, then the other_type field value is used.
|
||||
* @return string
|
||||
*/
|
||||
public function getTypeTranslationKey(): string
|
||||
{
|
||||
if ($this->type === AssociationType::OTHER) {
|
||||
return $this->other_type ?? 'Unknown';
|
||||
}
|
||||
return $this->type->getTranslationKey();
|
||||
}
|
||||
|
||||
}
|
|
@ -23,7 +23,9 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Entity\Parts\PartTraits;
|
||||
|
||||
use App\Entity\Parts\Part;
|
||||
use App\Entity\Parts\PartAssociation;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Symfony\Component\Validator\Constraints\Valid;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
@ -89,4 +91,18 @@ trait AssociationTrait
|
|||
{
|
||||
return $this->associated_parts_as_other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all associations where this part is the owned or other part.
|
||||
* @return Collection<PartAssociation>
|
||||
*/
|
||||
public function getAssociatedPartsAll(): Collection
|
||||
{
|
||||
return new ArrayCollection(
|
||||
array_merge(
|
||||
$this->associated_parts_as_owner->toArray(),
|
||||
$this->associated_parts_as_other->toArray()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -188,6 +188,15 @@
|
|||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro part_icon_link(part) %}
|
||||
{% set preview_attach = part_preview_generator.tablePreviewAttachment(part) %}
|
||||
{% if preview_attach %}
|
||||
<img src="{{ attachment_thumbnail(preview_attach, 'thumbnail_xs') }}" class="entity-image-xs" alt="Part image"
|
||||
{{ stimulus_controller('elements/hoverpic') }} data-thumbnail="{{ attachment_thumbnail(preview_attach) }}">
|
||||
{% endif %}
|
||||
<a href="{{ entity_url(part) }}">{{ part.name }}</a>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro entity_preview_sm(entity) %}
|
||||
{# @var entity \App\Entity\Contracts\HasMasterAttachmentInterface #}
|
||||
{% if entity.masterPictureAttachment and entity.masterPictureAttachment.picture and attachment_manager.fileExisting(entity.masterPictureAttachment) %}
|
||||
|
|
40
templates/parts/info/_associations.html.twig
Normal file
40
templates/parts/info/_associations.html.twig
Normal file
|
@ -0,0 +1,40 @@
|
|||
{% import "helper.twig" as helper %}
|
||||
|
||||
{% macro assoc_row(assoc) %}
|
||||
{# @var assoc \App\Entity\Parts\PartAssociation #}
|
||||
<tr>
|
||||
<td>{{ helper.part_icon_link(assoc.owner) }}</td>
|
||||
<td>{{ assoc.typeTranslationKey | trans }}</td>
|
||||
<td>{{ helper.part_icon_link(assoc.other) }}</td>
|
||||
<td>{{ assoc.comment }}</td>
|
||||
</tr>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro assoc_table(assocs, caption) %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover caption-top">
|
||||
<caption>{{ caption | trans }}:</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans %}part_association.table.from{% endtrans %}</th>
|
||||
<th>{% trans %}part_association.table.type{% endtrans %}</th>
|
||||
<th>{% trans %}part_association.table.to{% endtrans %}</th>
|
||||
<th>{% trans %}part_association.edit.comment{% endtrans %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for assoc in assocs %}
|
||||
{{ _self.assoc_row(assoc) }}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% if part.associatedPartsAsOwner is not empty %}
|
||||
{{ _self.assoc_table(part.associatedPartsAsOwner, 'part_association.table.from_this_part') }}
|
||||
{% endif %}
|
||||
|
||||
{% if part.associatedPartsAsOther is not empty %}
|
||||
{{ _self.assoc_table(part.associatedPartsAsOther, 'part_association.table.to_this_part') }}
|
||||
{% endif %}
|
|
@ -88,6 +88,17 @@
|
|||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if part.associatedPartsAll is not empty %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="associations-tab" data-bs-toggle="tab" href="#associations" role="tab">
|
||||
<i class="fas fas fa-circle-nodes fa-fw fa-fw"></i>
|
||||
{% trans %}part.edit.tab.associations{% endtrans %}
|
||||
<span class="badge bg-secondary">{{ part.associatedPartsAll | length }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
<li class="nav-item {% if datatable is null %}not-allowed{% endif %}">
|
||||
<a class="nav-link {% if datatable is null %}disabled{% endif %}" id="history-tab" data-bs-toggle="tab" href="#history" role="tab">
|
||||
<i class="fas fa-history"></i>
|
||||
|
@ -142,6 +153,12 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if part.associatedPartsAll is not empty %}
|
||||
<div class="tab-pane fade" id="associations" role="tabpanel" aria-labelledby="associations-tab">
|
||||
{% include "parts/info/_associations.html.twig" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="tab-pane fade" id="projects" role="tabpanel" aria-labelledby="projects-tab">
|
||||
{% include "parts/info/_projects.html.twig" %}
|
||||
</div>
|
||||
|
|
|
@ -11867,5 +11867,53 @@ Please note, that you can not impersonate a disabled user. If you try you will g
|
|||
<target>You can select here, how the chosen part is related to this part.</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="ulXO3uA" name="part_association.table.from_this_part">
|
||||
<segment>
|
||||
<source>part_association.table.from_this_part</source>
|
||||
<target>Associations from this part to others</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="hDksqGC" name="part_association.table.from">
|
||||
<segment>
|
||||
<source>part_association.table.from</source>
|
||||
<target>From</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="QyRxFA7" name="part_association.table.type">
|
||||
<segment>
|
||||
<source>part_association.table.type</source>
|
||||
<target>Relation</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="6ZyXTCs" name="part_association.table.to">
|
||||
<segment>
|
||||
<source>part_association.table.to</source>
|
||||
<target>To</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Lwwff7k" name="part_association.type.compatible">
|
||||
<segment>
|
||||
<source>part_association.type.compatible</source>
|
||||
<target>Is compatible with</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="tgOSN9E" name="part_association.table.to_this_part">
|
||||
<segment>
|
||||
<source>part_association.table.to_this_part</source>
|
||||
<target>Associations to this part from others</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="J2hj9bY" name="part_association.type.other">
|
||||
<segment>
|
||||
<source>part_association.type.other</source>
|
||||
<target>Other (custom value)</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="Sy57UAe" name="part_association.type.supersedes">
|
||||
<segment>
|
||||
<source>part_association.type.supersedes</source>
|
||||
<target>Supersedes</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue