mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 11:08:45 +02:00
N°3190 - Edit n:n LinkedSetIndirect in object details using a tagset-like widget
- Add generic set block ui component - Add model link set (direct and indirect) attribute (display style) - Add model link set direct allowed values - Create link set viewer block UI (BlockLinksSetDisplayAsProperty) - Add set block ui factory for linkset - Add object factory and create new endpoint in object controller (with data binder) - Add link set model, link set repository and link set data transformer services
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Links\Indirect;
|
||||
|
||||
use ApplicationContext;
|
||||
use AttributeLinkedSet;
|
||||
use cmdbAbstractObject;
|
||||
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\HtmlFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
|
||||
use Combodo\iTop\Service\Links\LinkSetModel;
|
||||
use Combodo\iTop\Service\Links\LinkSetRepository;
|
||||
use ormLinkSet;
|
||||
use Twig\Environment;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Class BlockLinksSetDisplayAsProperty
|
||||
*
|
||||
* @internal
|
||||
* @since 3.1.0
|
||||
* @package Combodo\iTop\Application\UI\Links\Indirect
|
||||
*/
|
||||
class BlockLinksSetDisplayAsProperty extends UIContentBlock
|
||||
{
|
||||
public const BLOCK_CODE = 'ibo-block-links-set-as-property';
|
||||
|
||||
/** @var AttributeLinkedSet $oAttribute Attribute link set */
|
||||
private AttributeLinkedSet $oAttribute;
|
||||
|
||||
/** @var \ormLinkSet $oValue Link set value */
|
||||
private ormLinkSet $oValue;
|
||||
|
||||
/** @var string $sTargetClass Link set target class */
|
||||
private string $sTargetClass;
|
||||
|
||||
/** @var ?array $aObjectsData Links objects converted as array */
|
||||
private ?array $aObjectsData;
|
||||
|
||||
/** @var \Twig\Environment Twig environment */
|
||||
private Environment $oTwigEnv;
|
||||
|
||||
/** @var string $sAppContext Application context */
|
||||
private string $sAppContext;
|
||||
|
||||
/** @var string $sUIPage UI page */
|
||||
private string $sUIPage;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $sId block identifier
|
||||
* @param AttributeLinkedSet $oAttribute
|
||||
* @param ormLinkSet $oValue
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Twig\Error\LoaderError
|
||||
*/
|
||||
public function __construct(string $sId, AttributeLinkedSet $oAttribute, ormLinkSet $oValue)
|
||||
{
|
||||
parent::__construct($sId);
|
||||
|
||||
// retrieve parameters
|
||||
$this->oAttribute = $oAttribute;
|
||||
$this->oValue = $oValue;
|
||||
|
||||
// Initialization
|
||||
$this->Init();
|
||||
|
||||
// UI Initialization
|
||||
$this->InitUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Twig\Error\LoaderError
|
||||
*/
|
||||
private function Init()
|
||||
{
|
||||
// Link set model properties
|
||||
$this->sTargetClass = LinkSetModel::GetTargetClass($this->oAttribute);
|
||||
$sTargetField = LinkSetModel::GetTargetField($this->oAttribute);
|
||||
|
||||
// Get objects from linked data
|
||||
$this->aObjectsData = LinkSetRepository::LinksDbSetToTargetObjectArray($this->oValue, $this->sTargetClass, $sTargetField);
|
||||
|
||||
// Twig environment
|
||||
$this->oTwigEnv = TwigHelper::GetTwigEnvironment(TwigHelper::ENUM_TEMPLATES_BASE_PATH_BACKOFFICE);
|
||||
|
||||
$oAppContext = new ApplicationContext();
|
||||
$this->sAppContext = $oAppContext->GetForLink();
|
||||
$this->sUIPage = cmdbAbstractObject::ComputeStandardUIPage($this->sTargetClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* UI Initialization.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function InitUI()
|
||||
{
|
||||
// Error handling
|
||||
if ($this->aObjectsData === null) {
|
||||
$sMessage = "Error while displaying attribute {$this->oAttribute->GetCode()}";
|
||||
$this->AddSubBlock(HtmlFactory::MakeHtmlContent($sMessage));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Container
|
||||
$sHtml = '<span class="'.implode(' ', $this->oAttribute->GetCssClasses()).'">';
|
||||
|
||||
// Iterate throw data...
|
||||
foreach ($this->aObjectsData as $aItem) {
|
||||
|
||||
// Ignore obsolete data
|
||||
if (!utils::ShowObsoleteData() && $aItem['obsolescence_flag']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Generate template
|
||||
$sTemplate = TwigHelper::RenderTemplate($this->oTwigEnv, $aItem, 'application/object/set/set_renderer');
|
||||
|
||||
// Friendly name
|
||||
$sFriendlyNameForHtml = utils::HtmlEntities($aItem['friendlyname']);
|
||||
|
||||
// Append value
|
||||
$sHtml .= '<a'.$this->GenerateLinkUrl($aItem['key']).' class="attribute-set-item" data-label="'.$sFriendlyNameForHtml.'" data-tooltip-content="'.$sFriendlyNameForHtml.'">'.$sTemplate.'</a>';
|
||||
}
|
||||
|
||||
// Close container
|
||||
$sHtml .= '</span>';
|
||||
|
||||
// Make html block
|
||||
$this->AddSubBlock(HtmlFactory::MakeHtmlContent($sHtml));
|
||||
}
|
||||
|
||||
/**
|
||||
* GenerateLinkUrl.
|
||||
*
|
||||
* @param $id
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function GenerateLinkUrl($id): string
|
||||
{
|
||||
return ' href="'
|
||||
.utils::GetAbsoluteUrlAppRoot()
|
||||
."pages/$this->sUIPage?operation=details&class=$this->sTargetClass&id=$id&$this->sAppContext"
|
||||
.'" target="_blank"';
|
||||
}
|
||||
}
|
||||
118
sources/Application/UI/Links/Set/LinksSetUIBlockFactory.php
Normal file
118
sources/Application/UI/Links/Set/LinksSetUIBlockFactory.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2022 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop 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.
|
||||
*
|
||||
* iTop 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
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Links\Set;
|
||||
|
||||
use AttributeLinkedSet;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Input\Set\Set;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Input\Set\SetUIBlockFactory;
|
||||
use Combodo\iTop\Service\Links\LinksBulkDataPostProcessor;
|
||||
use Combodo\iTop\Service\Links\LinkSetDataTransformer;
|
||||
use Combodo\iTop\Service\Links\LinkSetModel;
|
||||
use Combodo\iTop\Service\Links\LinkSetRepository;
|
||||
use iDBObjectSetIterator;
|
||||
|
||||
/**
|
||||
* Class LinksSetUIBlockFactory
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @package Combodo\iTop\Application\UI\Links\Set
|
||||
*/
|
||||
class LinksSetUIBlockFactory extends SetUIBlockFactory
|
||||
{
|
||||
|
||||
/**
|
||||
* Make a link set block.
|
||||
*
|
||||
* @param string $sId Block identifier
|
||||
* @param AttributeLinkedSet $oAttDef Link set attribute definition
|
||||
* @param iDBObjectSetIterator $oDbObjectSet Link set value
|
||||
* @param string $sWizardHelperJsVarName Wizard helper name
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Input\Set\Set
|
||||
*/
|
||||
public static function MakeForLinkSet(string $sId, AttributeLinkedSet $oAttDef, iDBObjectSetIterator $oDbObjectSet, string $sWizardHelperJsVarName): Set
|
||||
{
|
||||
$sTargetClass = LinkSetModel::GetTargetClass($oAttDef);
|
||||
$sTargetField = LinkSetModel::GetTargetField($oAttDef);
|
||||
|
||||
// Set UI block for OQL
|
||||
$oSetUIBlock = SetUIBlockFactory::MakeForOQL($sId, $sTargetClass, $oAttDef->GetValuesDef()->GetFilterExpression(), $sWizardHelperJsVarName);
|
||||
|
||||
// Current value
|
||||
$aCurrentValues = LinkSetDataTransformer::Decode($oDbObjectSet, $sTargetClass, $sTargetField);
|
||||
|
||||
// Initial options data
|
||||
$aInitialOptions = LinkSetRepository::LinksDbSetToTargetObjectArray($oDbObjectSet, $sTargetClass, $sTargetField);
|
||||
if ($aInitialOptions !== null) {
|
||||
$oSetUIBlock->GetDataProvider()->SetOptions($aInitialOptions);
|
||||
// Set value
|
||||
$oSetUIBlock->SetValue(json_encode($aCurrentValues));
|
||||
} else {
|
||||
$oSetUIBlock->SetHasError(true);
|
||||
}
|
||||
|
||||
return $oSetUIBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a link set block for bulk modify.
|
||||
*
|
||||
* @param string $sId Block identifier
|
||||
* @param AttributeLinkedSet $oAttDef Link set attribute definition
|
||||
* @param iDBObjectSetIterator $oDbObjectSet Link set value
|
||||
* @param string $sWizardHelperJsVarName Wizard helper name
|
||||
* @param array $aBulkContext
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Input\Set\Set
|
||||
*/
|
||||
public static function MakeForBulkLinkSet(string $sId, AttributeLinkedSet $oAttDef, iDBObjectSetIterator $oDbObjectSet, string $sWizardHelperJsVarName, array $aBulkContext): Set
|
||||
{
|
||||
$oSetUIBlock = self::MakeForLinkSet($sId, $oAttDef, $oDbObjectSet, $sWizardHelperJsVarName);
|
||||
|
||||
// Bulk modify specific
|
||||
$oSetUIBlock->GetDataProvider()->SetGroupField('group');
|
||||
$oSetUIBlock->SetIsMultiValuesSynthesis(true);
|
||||
|
||||
// Data post processing
|
||||
$aBinderSettings = [
|
||||
'bulk_oql' => $aBulkContext['oql'],
|
||||
'link_class' => LinkSetModel::GetLinkedClass($oAttDef),
|
||||
'target_field' => LinkSetModel::GetTargetField($oAttDef),
|
||||
'origin_field' => $oAttDef->GetExtKeyToMe(),
|
||||
];
|
||||
|
||||
// Initial options
|
||||
$aOptions = $oSetUIBlock->GetDataProvider()->GetOptions();
|
||||
$aOptions = LinksBulkDataPostProcessor::Execute($aOptions, $aBinderSettings);
|
||||
$oSetUIBlock->GetDataProvider()->SetOptions($aOptions);
|
||||
|
||||
// Data provider post processor
|
||||
/** @var \Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider\AjaxDataProvider $oDataProvider */
|
||||
$oDataProvider = $oSetUIBlock->GetDataProvider();
|
||||
$oDataProvider->SetPostParam('data_post_processor', [
|
||||
'class_name' => addslashes(LinksBulkDataPostProcessor::class),
|
||||
'settings' => $aBinderSettings,
|
||||
]);
|
||||
|
||||
return $oSetUIBlock;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user