mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-03-01 12:59:36 +00:00
Unterstützung für Projekt- und Baugruppensuche zum QuickSearch-Suggest hinzufügen
This commit is contained in:
parent
4911b5bf24
commit
74513b748d
23 changed files with 519 additions and 50 deletions
|
|
@ -128,7 +128,8 @@ class AssemblyController extends AbstractController
|
|||
], $additonal_template_vars));
|
||||
}
|
||||
|
||||
#[Route(path: '/{id}/info', name: 'assembly_info', requirements: ['id' => '\d+'])]
|
||||
#[Route(path: '/{id}/info', name: 'assembly_info')]
|
||||
#[Route(path: '/{id}', requirements: ['id' => '\d+'])]
|
||||
public function info(Assembly $assembly, Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('read', $assembly);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@ class ProjectController extends AbstractController
|
|||
) {
|
||||
}
|
||||
|
||||
#[Route(path: '/{id}/info', name: 'project_info', requirements: ['id' => '\d+'])]
|
||||
#[Route(path: '/{id}/info', name: 'project_info')]
|
||||
#[Route(path: '/{id}', requirements: ['id' => '\d+'])]
|
||||
public function info(Project $project, Request $request, ProjectBuildHelper $buildHelper, TableSettings $tableSettings): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('read', $project);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ namespace App\Controller;
|
|||
|
||||
use App\Entity\AssemblySystem\Assembly;
|
||||
use App\Entity\Parameters\AbstractParameter;
|
||||
use App\Entity\ProjectSystem\Project;
|
||||
use App\Services\Attachments\ProjectPreviewGenerator;
|
||||
use App\Settings\MiscSettings\IpnSuggestSettings;
|
||||
use App\Services\Attachments\AssemblyPreviewGenerator;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
|
@ -124,7 +126,10 @@ class TypeaheadController extends AbstractController
|
|||
public function parts(
|
||||
EntityManagerInterface $entityManager,
|
||||
PartPreviewGenerator $previewGenerator,
|
||||
ProjectPreviewGenerator $projectPreviewGenerator,
|
||||
AssemblyPreviewGenerator $assemblyPreviewGenerator,
|
||||
AttachmentURLGenerator $attachmentURLGenerator,
|
||||
Request $request,
|
||||
string $query = ""
|
||||
): JsonResponse {
|
||||
$this->denyAccessUnlessGranted('@parts.read');
|
||||
|
|
@ -133,18 +138,20 @@ class TypeaheadController extends AbstractController
|
|||
|
||||
$parts = $partRepository->autocompleteSearch($query, 100);
|
||||
|
||||
/** @var Part[]|Assembly[] $data */
|
||||
$data = [];
|
||||
foreach ($parts as $part) {
|
||||
//Determine the picture to show:
|
||||
$preview_attachment = $previewGenerator->getTablePreviewAttachment($part);
|
||||
if($preview_attachment instanceof Attachment) {
|
||||
$preview_url = $attachmentURLGenerator->getThumbnailURL($preview_attachment, 'thumbnail_sm');
|
||||
$preview_url = $attachmentURLGenerator->getThumbnailURL($preview_attachment);
|
||||
} else {
|
||||
$preview_url = '';
|
||||
}
|
||||
|
||||
/** @var Part $part */
|
||||
$data[] = [
|
||||
'type' => 'part',
|
||||
'id' => $part->getID(),
|
||||
'name' => $part->getName(),
|
||||
'category' => $part->getCategory() instanceof Category ? $part->getCategory()->getName() : 'Unknown',
|
||||
|
|
@ -154,6 +161,64 @@ class TypeaheadController extends AbstractController
|
|||
];
|
||||
}
|
||||
|
||||
$multiDataSources = $request->query->getBoolean('multidatasources');
|
||||
|
||||
if ($multiDataSources) {
|
||||
if ($this->isGranted('@projects.read')) {
|
||||
$projectRepository = $entityManager->getRepository(Project::class);
|
||||
|
||||
$projects = $projectRepository->autocompleteSearch($query, 100);
|
||||
|
||||
foreach ($projects as $project) {
|
||||
$preview_attachment = $projectPreviewGenerator->getTablePreviewAttachment($project);
|
||||
|
||||
if ($preview_attachment instanceof Attachment) {
|
||||
$preview_url = $attachmentURLGenerator->getThumbnailURL($preview_attachment);
|
||||
} else {
|
||||
$preview_url = '';
|
||||
}
|
||||
|
||||
/** @var Project $project */
|
||||
$data[] = [
|
||||
'type' => 'project',
|
||||
'id' => $project->getID(),
|
||||
'name' => $project->getName(),
|
||||
'category' => '',
|
||||
'footprint' => '',
|
||||
'description' => mb_strimwidth($project->getDescription(), 0, 127, '...'),
|
||||
'image' => $preview_url,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->isGranted('@assemblies.read')) {
|
||||
$assemblyRepository = $entityManager->getRepository(Assembly::class);
|
||||
|
||||
$assemblies = $assemblyRepository->autocompleteSearch($query, 100);
|
||||
|
||||
foreach ($assemblies as $assembly) {
|
||||
$preview_attachment = $assemblyPreviewGenerator->getTablePreviewAttachment($assembly);
|
||||
|
||||
if ($preview_attachment instanceof Attachment) {
|
||||
$preview_url = $attachmentURLGenerator->getThumbnailURL($preview_attachment);
|
||||
} else {
|
||||
$preview_url = '';
|
||||
}
|
||||
|
||||
/** @var Assembly $assembly */
|
||||
$data[] = [
|
||||
'type' => 'assembly',
|
||||
'id' => $assembly->getID(),
|
||||
'name' => $assembly->getName(),
|
||||
'category' => '',
|
||||
'footprint' => '',
|
||||
'description' => mb_strimwidth($assembly->getDescription(), 0, 127, '...'),
|
||||
'image' => $preview_url,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new JsonResponse($data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ class PartSearchFilter implements FilterInterface
|
|||
}
|
||||
if ($this->assembly) {
|
||||
$fields_to_search[] = '_assembly.name';
|
||||
$fields_to_search[] = '_assembly.ipn';
|
||||
}
|
||||
|
||||
return $fields_to_search;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@ class AssemblyRepository extends StructuralDBElementRepository
|
|||
$qb = $this->createQueryBuilder('assembly');
|
||||
$qb->select('assembly')
|
||||
->where('ILIKE(assembly.name, :query) = TRUE')
|
||||
->orWhere('ILIKE(assembly.description, :query) = TRUE');
|
||||
->orWhere('ILIKE(assembly.description, :query) = TRUE')
|
||||
->orWhere('ILIKE(assembly.ipn, :query) = TRUE');
|
||||
|
||||
$qb->setParameter('query', '%'.$query.'%');
|
||||
|
||||
|
|
|
|||
|
|
@ -51,4 +51,18 @@ class DeviceRepository extends StructuralDBElementRepository
|
|||
//Prevent user from deleting devices, to not accidentally remove filled devices from old versions
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function autocompleteSearch(string $query, int $max_limits = 50): array
|
||||
{
|
||||
$qb = $this->createQueryBuilder('p');
|
||||
$qb->select('p')
|
||||
->where('ILIKE(p.name, :query) = TRUE');
|
||||
|
||||
$qb->setParameter('query', '%'.$query.'%');
|
||||
|
||||
$qb->setMaxResults($max_limits);
|
||||
$qb->orderBy('NATSORT(p.name)', 'ASC');
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
93
src/Services/Attachments/ProjectPreviewGenerator.php
Normal file
93
src/Services/Attachments/ProjectPreviewGenerator.php
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Attachments;
|
||||
|
||||
use App\Entity\Attachments\Attachment;
|
||||
use App\Entity\ProjectSystem\Project;
|
||||
|
||||
class ProjectPreviewGenerator
|
||||
{
|
||||
public function __construct(protected AttachmentManager $attachmentHelper)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of attachments that can be used for previewing the project ordered by priority.
|
||||
*
|
||||
* @param Project $project the project for which the attachments should be determined
|
||||
*
|
||||
* @return (Attachment|null)[]
|
||||
*
|
||||
* @psalm-return list<Attachment|null>
|
||||
*/
|
||||
public function getPreviewAttachments(Project $project): array
|
||||
{
|
||||
$list = [];
|
||||
|
||||
//Master attachment has top priority
|
||||
$attachment = $project->getMasterPictureAttachment();
|
||||
if ($this->isAttachmentValidPicture($attachment)) {
|
||||
$list[] = $attachment;
|
||||
}
|
||||
|
||||
//Then comes the other images of the project
|
||||
foreach ($project->getAttachments() as $attachment) {
|
||||
//Dont show the master attachment twice
|
||||
if ($this->isAttachmentValidPicture($attachment) && $attachment !== $project->getMasterPictureAttachment()) {
|
||||
$list[] = $attachment;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines what attachment should be used for previewing a project (especially in project table).
|
||||
* The returned attachment is guaranteed to be existing and be a picture.
|
||||
*
|
||||
* @param Project $project The project for which the attachment should be determined
|
||||
*/
|
||||
public function getTablePreviewAttachment(Project $project): ?Attachment
|
||||
{
|
||||
$attachment = $project->getMasterPictureAttachment();
|
||||
if ($this->isAttachmentValidPicture($attachment)) {
|
||||
return $attachment;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a attachment is exising and a valid picture.
|
||||
*
|
||||
* @param Attachment|null $attachment the attachment that should be checked
|
||||
*
|
||||
* @return bool true if the attachment is valid
|
||||
*/
|
||||
protected function isAttachmentValidPicture(?Attachment $attachment): bool
|
||||
{
|
||||
return $attachment instanceof Attachment
|
||||
&& $attachment->isPicture()
|
||||
&& $this->attachmentHelper->isFileExisting($attachment);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue