mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 09:35:49 +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\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\Parts\MeasurementUnit;
|
use App\Entity\Parts\MeasurementUnit;
|
||||||
|
use App\Entity\UserSystem\User;
|
||||||
use App\Form\Type\StructuralEntityType;
|
use App\Form\Type\StructuralEntityType;
|
||||||
|
use App\Form\Type\UserSelectType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
|
@ -63,5 +65,16 @@ class StorelocationAdminForm extends BaseEntityAdminForm
|
||||||
'disable_not_selectable' => true,
|
'disable_not_selectable' => true,
|
||||||
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
'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;
|
namespace App\Form\Type\Helper;
|
||||||
|
|
||||||
use App\Entity\Attachments\AttachmentType;
|
use App\Entity\Attachments\AttachmentType;
|
||||||
|
use App\Entity\Base\AbstractDBElement;
|
||||||
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\Base\AbstractStructuralDBElement;
|
use App\Entity\Base\AbstractStructuralDBElement;
|
||||||
|
use App\Entity\Contracts\HasMasterAttachmentInterface;
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
|
use App\Entity\UserSystem\User;
|
||||||
|
use App\Form\Type\MasterPictureAttachmentType;
|
||||||
use App\Services\Attachments\AttachmentURLGenerator;
|
use App\Services\Attachments\AttachmentURLGenerator;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Symfony\Component\Intl\Currencies;
|
use Symfony\Component\Intl\Currencies;
|
||||||
|
@ -43,14 +48,18 @@ class StructuralEntityChoiceHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the choice attributes for the given AbstractStructuralDBElement.
|
* Generates the choice attributes for the given AbstractStructuralDBElement.
|
||||||
* @param AbstractStructuralDBElement $choice
|
* @param AbstractNamedDBElement $choice
|
||||||
* @param Options|array $options
|
* @param Options|array $options
|
||||||
* @return array|string[]
|
* @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
|
//Disable attribute if the choice is marked as not selectable
|
||||||
if (($options['disable_not_selectable'] ?? false) && $choice->isNotSelectable()) {
|
if (($options['disable_not_selectable'] ?? false) && $choice->isNotSelectable()) {
|
||||||
$tmp += ['disabled' => 'disabled'];
|
$tmp += ['disabled' => 'disabled'];
|
||||||
|
@ -71,8 +80,16 @@ class StructuralEntityChoiceHelper
|
||||||
'data-level' => $level,
|
'data-level' => $level,
|
||||||
'data-parent' => $choice->getParent() ? $choice->getParent()->getFullPath() : null,
|
'data-parent' => $choice->getParent() ? $choice->getParent()->getFullPath() : null,
|
||||||
'data-path' => $choice->getFullPath('->'),
|
'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())) {
|
if ($choice instanceof AttachmentType && !empty($choice->getFiletypeFilter())) {
|
||||||
$tmp += ['data-filetype_filter' => $choice->getFiletypeFilter()];
|
$tmp += ['data-filetype_filter' => $choice->getFiletypeFilter()];
|
||||||
|
@ -112,20 +129,20 @@ class StructuralEntityChoiceHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the choice label for the given AbstractStructuralDBElement.
|
* Returns the choice label for the given AbstractStructuralDBElement.
|
||||||
* @param AbstractStructuralDBElement $choice
|
* @param AbstractNamedDBElement $choice
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function generateChoiceLabel(AbstractStructuralDBElement $choice): string
|
public function generateChoiceLabel(AbstractNamedDBElement $choice): string
|
||||||
{
|
{
|
||||||
return $choice->getName();
|
return $choice->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the choice value for the given AbstractStructuralDBElement.
|
* Returns the choice value for the given AbstractStructuralDBElement.
|
||||||
* @param AbstractStructuralDBElement|null $element
|
* @param AbstractNamedDBElement|null $element
|
||||||
* @return string|int|null
|
* @return string|int|null
|
||||||
*/
|
*/
|
||||||
public function generateChoiceValue(?AbstractStructuralDBElement $element)
|
public function generateChoiceValue(?AbstractNamedDBElement $element)
|
||||||
{
|
{
|
||||||
if ($element === null) {
|
if ($element === null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -138,18 +155,21 @@ class StructuralEntityChoiceHelper
|
||||||
* So please do not change this!
|
* So please do not change this!
|
||||||
*/
|
*/
|
||||||
if ($element->getID() === null) {
|
if ($element->getID() === null) {
|
||||||
|
if ($element instanceof AbstractStructuralDBElement) {
|
||||||
//Must be the same as the separator in the choice_loader, otherwise this will not work!
|
//Must be the same as the separator in the choice_loader, otherwise this will not work!
|
||||||
return $element->getFullPath('->');
|
return $element->getFullPath('->');
|
||||||
}
|
}
|
||||||
|
return $element->getName();
|
||||||
|
}
|
||||||
|
|
||||||
return $element->getID();
|
return $element->getID();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param AbstractStructuralDBElement $element
|
* @param AbstractDBElement $element
|
||||||
* @return string|null
|
* @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
|
//Show entities that are not added to DB yet separately from other entities
|
||||||
if ($element->getID() === null) {
|
if ($element->getID() === null) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||||
namespace App\Form\Type;
|
namespace App\Form\Type;
|
||||||
|
|
||||||
use App\Entity\Attachments\AttachmentType;
|
use App\Entity\Attachments\AttachmentType;
|
||||||
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\Base\AbstractStructuralDBElement;
|
use App\Entity\Base\AbstractStructuralDBElement;
|
||||||
use App\Form\Type\Helper\StructuralEntityChoiceHelper;
|
use App\Form\Type\Helper\StructuralEntityChoiceHelper;
|
||||||
use App\Form\Type\Helper\StructuralEntityChoiceLoader;
|
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
|
'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
|
'subentities_of' => null, //Only show entities with the given parent class
|
||||||
'disable_not_selectable' => false, //Disable entries with not selectable property
|
'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);
|
return $this->choice_helper->generateChoiceValue($element);
|
||||||
}, //Use the element id as option value and for comparing items
|
}, //Use the element id as option value and for comparing items
|
||||||
'choice_loader' => function (Options $options) {
|
'choice_loader' => function (Options $options) {
|
||||||
|
@ -121,7 +122,7 @@ class StructuralEntityType extends AbstractType
|
||||||
return $this->choice_helper->generateChoiceAttr($choice, $options);
|
return $this->choice_helper->generateChoiceAttr($choice, $options);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
'group_by' => function (AbstractStructuralDBElement $element) {
|
'group_by' => function (AbstractNamedDBElement $element) {
|
||||||
return $this->choice_helper->generateGroupBy($element);
|
return $this->choice_helper->generateGroupBy($element);
|
||||||
},
|
},
|
||||||
'choice_translation_domain' => false, //Don't translate the entity names
|
'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;
|
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.
|
* 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
|
* @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]);
|
$item->tag(['groups', 'tree_list', $this->keyGenerator->generateKey(), $secure_class_name]);
|
||||||
/** @var StructuralDBElementRepository $repo */
|
/** @var StructuralDBElementRepository $repo */
|
||||||
$repo = $this->em->getRepository($class_name);
|
$repo = $this->em->getRepository($class_name);
|
||||||
|
|
||||||
return $repo->toNodesList($parent);
|
return $repo->toNodesList($parent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
{{ form_row(form.is_full) }}
|
{{ form_row(form.is_full) }}
|
||||||
{{ form_row(form.limit_to_existing_parts) }}
|
{{ form_row(form.limit_to_existing_parts) }}
|
||||||
{{ form_row(form.only_single_part) }}
|
{{ form_row(form.only_single_part) }}
|
||||||
|
{{ form_row(form.owner) }}
|
||||||
|
{{ form_row(form.part_owner_must_match) }}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -11205,5 +11205,17 @@ Element 3</target>
|
||||||
<target>About Me</target>
|
<target>About Me</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</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>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue