mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 01:25:55 +02:00
Added UserSelectType and allow to set owner of a storage location
This commit is contained in:
parent
f101e1b184
commit
5f5541ca12
8 changed files with 142 additions and 36 deletions
|
@ -24,7 +24,9 @@ namespace App\Form\AdminPages;
|
|||
|
||||
use App\Entity\Base\AbstractNamedDBElement;
|
||||
use App\Entity\Parts\MeasurementUnit;
|
||||
use App\Entity\UserSystem\User;
|
||||
use App\Form\Type\StructuralEntityType;
|
||||
use App\Form\Type\UserSelectType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
|
@ -63,5 +65,16 @@ class StorelocationAdminForm extends BaseEntityAdminForm
|
|||
'disable_not_selectable' => true,
|
||||
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||
]);
|
||||
|
||||
$builder->add('owner', UserSelectType::class, [
|
||||
'required' => false,
|
||||
'label' => 'storelocation.owner.label',
|
||||
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||
]);
|
||||
$builder->add('part_owner_must_match', CheckboxType::class, [
|
||||
'required' => false,
|
||||
'label' => 'storelocation.part_owner_must_match.label',
|
||||
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,13 @@
|
|||
namespace App\Form\Type\Helper;
|
||||
|
||||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Entity\Base\AbstractDBElement;
|
||||
use App\Entity\Base\AbstractNamedDBElement;
|
||||
use App\Entity\Base\AbstractStructuralDBElement;
|
||||
use App\Entity\Contracts\HasMasterAttachmentInterface;
|
||||
use App\Entity\PriceInformations\Currency;
|
||||
use App\Entity\UserSystem\User;
|
||||
use App\Form\Type\MasterPictureAttachmentType;
|
||||
use App\Services\Attachments\AttachmentURLGenerator;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Intl\Currencies;
|
||||
|
@ -43,14 +48,18 @@ class StructuralEntityChoiceHelper
|
|||
|
||||
/**
|
||||
* Generates the choice attributes for the given AbstractStructuralDBElement.
|
||||
* @param AbstractStructuralDBElement $choice
|
||||
* @param AbstractNamedDBElement $choice
|
||||
* @param Options|array $options
|
||||
* @return array|string[]
|
||||
*/
|
||||
public function generateChoiceAttr(AbstractStructuralDBElement $choice, $options): array
|
||||
public function generateChoiceAttr(AbstractNamedDBElement $choice, $options): array
|
||||
{
|
||||
$tmp = [];
|
||||
$tmp = [
|
||||
'data-level' => 0,
|
||||
'data-path' => $choice->getName(),
|
||||
];
|
||||
|
||||
if ($choice instanceof AbstractStructuralDBElement) {
|
||||
//Disable attribute if the choice is marked as not selectable
|
||||
if (($options['disable_not_selectable'] ?? false) && $choice->isNotSelectable()) {
|
||||
$tmp += ['disabled' => 'disabled'];
|
||||
|
@ -71,8 +80,16 @@ class StructuralEntityChoiceHelper
|
|||
'data-level' => $level,
|
||||
'data-parent' => $choice->getParent() ? $choice->getParent()->getFullPath() : null,
|
||||
'data-path' => $choice->getFullPath('->'),
|
||||
'data-image' => $choice->getMasterPictureAttachment() ? $this->attachmentURLGenerator->getThumbnailURL($choice->getMasterPictureAttachment(), 'thumbnail_xs') : null,
|
||||
];
|
||||
}
|
||||
|
||||
if ($choice instanceof HasMasterAttachmentInterface) {
|
||||
$tmp['data-image'] = $choice->getMasterPictureAttachment() ?
|
||||
$this->attachmentURLGenerator->getThumbnailURL($choice->getMasterPictureAttachment(),
|
||||
'thumbnail_xs')
|
||||
: null
|
||||
;
|
||||
}
|
||||
|
||||
if ($choice instanceof AttachmentType && !empty($choice->getFiletypeFilter())) {
|
||||
$tmp += ['data-filetype_filter' => $choice->getFiletypeFilter()];
|
||||
|
@ -112,20 +129,20 @@ class StructuralEntityChoiceHelper
|
|||
|
||||
/**
|
||||
* Returns the choice label for the given AbstractStructuralDBElement.
|
||||
* @param AbstractStructuralDBElement $choice
|
||||
* @param AbstractNamedDBElement $choice
|
||||
* @return string
|
||||
*/
|
||||
public function generateChoiceLabel(AbstractStructuralDBElement $choice): string
|
||||
public function generateChoiceLabel(AbstractNamedDBElement $choice): string
|
||||
{
|
||||
return $choice->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the choice value for the given AbstractStructuralDBElement.
|
||||
* @param AbstractStructuralDBElement|null $element
|
||||
* @param AbstractNamedDBElement|null $element
|
||||
* @return string|int|null
|
||||
*/
|
||||
public function generateChoiceValue(?AbstractStructuralDBElement $element)
|
||||
public function generateChoiceValue(?AbstractNamedDBElement $element)
|
||||
{
|
||||
if ($element === null) {
|
||||
return null;
|
||||
|
@ -138,18 +155,21 @@ class StructuralEntityChoiceHelper
|
|||
* So please do not change this!
|
||||
*/
|
||||
if ($element->getID() === null) {
|
||||
if ($element instanceof AbstractStructuralDBElement) {
|
||||
//Must be the same as the separator in the choice_loader, otherwise this will not work!
|
||||
return $element->getFullPath('->');
|
||||
}
|
||||
return $element->getName();
|
||||
}
|
||||
|
||||
return $element->getID();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractStructuralDBElement $element
|
||||
* @param AbstractDBElement $element
|
||||
* @return string|null
|
||||
*/
|
||||
public function generateGroupBy(AbstractStructuralDBElement $element): ?string
|
||||
public function generateGroupBy(AbstractDBElement $element): ?string
|
||||
{
|
||||
//Show entities that are not added to DB yet separately from other entities
|
||||
if ($element->getID() === null) {
|
||||
|
|
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||
namespace App\Form\Type;
|
||||
|
||||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Entity\Base\AbstractNamedDBElement;
|
||||
use App\Entity\Base\AbstractStructuralDBElement;
|
||||
use App\Form\Type\Helper\StructuralEntityChoiceHelper;
|
||||
use App\Form\Type\Helper\StructuralEntityChoiceLoader;
|
||||
|
@ -105,7 +106,7 @@ class StructuralEntityType extends AbstractType
|
|||
'show_fullpath_in_subtext' => true, //When this is enabled, the full path will be shown in subtext
|
||||
'subentities_of' => null, //Only show entities with the given parent class
|
||||
'disable_not_selectable' => false, //Disable entries with not selectable property
|
||||
'choice_value' => function (?AbstractStructuralDBElement $element) {
|
||||
'choice_value' => function (?AbstractNamedDBElement $element) {
|
||||
return $this->choice_helper->generateChoiceValue($element);
|
||||
}, //Use the element id as option value and for comparing items
|
||||
'choice_loader' => function (Options $options) {
|
||||
|
@ -121,7 +122,7 @@ class StructuralEntityType extends AbstractType
|
|||
return $this->choice_helper->generateChoiceAttr($choice, $options);
|
||||
};
|
||||
},
|
||||
'group_by' => function (AbstractStructuralDBElement $element) {
|
||||
'group_by' => function (AbstractNamedDBElement $element) {
|
||||
return $this->choice_helper->generateGroupBy($element);
|
||||
},
|
||||
'choice_translation_domain' => false, //Don't translate the entity names
|
||||
|
|
47
src/Form/Type/UserSelectType.php
Normal file
47
src/Form/Type/UserSelectType.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 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/>.
|
||||
*/
|
||||
|
||||
namespace App\Form\Type;
|
||||
|
||||
use App\Entity\UserSystem\User;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\Options;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class UserSelectType extends AbstractType
|
||||
{
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'class' => User::class,
|
||||
'choice_label' => function (Options $options) {
|
||||
return function (User $choice, $key, $value) {
|
||||
return $choice->getFullName(true);
|
||||
};
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
public function getParent()
|
||||
{
|
||||
return StructuralEntityType::class;
|
||||
}
|
||||
}
|
|
@ -59,4 +59,14 @@ class NamedDBElementRepository extends DBElementRepository
|
|||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all nodes to use in a select box.
|
||||
* @return AbstractNamedDBElement[]
|
||||
*/
|
||||
public function toNodesList(): array
|
||||
{
|
||||
//All nodes are sorted by name
|
||||
return $this->findBy([], ['name' => 'ASC']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class NodesListBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets a flattened hierachical tree. Useful for generating option lists.
|
||||
* Gets a flattened hierarchical tree. Useful for generating option lists.
|
||||
* In difference to the Repository Function, the results here are cached.
|
||||
*
|
||||
* @param string $class_name the class name of the entity you want to retrieve
|
||||
|
@ -66,6 +66,7 @@ class NodesListBuilder
|
|||
$item->tag(['groups', 'tree_list', $this->keyGenerator->generateKey(), $secure_class_name]);
|
||||
/** @var StructuralDBElementRepository $repo */
|
||||
$repo = $this->em->getRepository($class_name);
|
||||
|
||||
return $repo->toNodesList($parent);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
{{ form_row(form.is_full) }}
|
||||
{{ form_row(form.limit_to_existing_parts) }}
|
||||
{{ form_row(form.only_single_part) }}
|
||||
{{ form_row(form.owner) }}
|
||||
{{ form_row(form.part_owner_must_match) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -11205,5 +11205,17 @@ Element 3</target>
|
|||
<target>About Me</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="WsHXARp" name="storelocation.owner.label">
|
||||
<segment>
|
||||
<source>storelocation.owner.label</source>
|
||||
<target>Owner</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="VQ97Dh0" name="storelocation.part_owner_must_match.label">
|
||||
<segment>
|
||||
<source>storelocation.part_owner_must_match.label</source>
|
||||
<target>Part Lot owner must match storage location owner</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue