mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-18 23:08:46 +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:
@@ -41,8 +41,12 @@ use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
|
|||||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinksViewTable;
|
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinksViewTable;
|
||||||
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinksViewTable;
|
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinksViewTable;
|
||||||
|
use Combodo\iTop\Application\UI\Links\Set\LinksSetUIBlockFactory;
|
||||||
use Combodo\iTop\Renderer\BlockRenderer;
|
use Combodo\iTop\Renderer\BlockRenderer;
|
||||||
|
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||||
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
||||||
|
use Combodo\iTop\Service\Links\LinkSetDataTransformer;
|
||||||
|
use Combodo\iTop\Service\Links\LinkSetModel;
|
||||||
|
|
||||||
|
|
||||||
define('OBJECT_PROPERTIES_TAB', 'ObjectProperties');
|
define('OBJECT_PROPERTIES_TAB', 'ObjectProperties');
|
||||||
@@ -663,10 +667,11 @@ HTML
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display mode
|
// Process only link set attributes with tab display style
|
||||||
if (!$oAttDef->IsLinkset()) {
|
$bIsLinkSetWithDisplayStyleTab = is_a($oAttDef, AttributeLinkedSet::class) && $oAttDef->GetDisplayStyle() === LINKSET_DISPLAY_STYLE_TAB;
|
||||||
|
if (!$oAttDef->IsLinkset() || !$bIsLinkSetWithDisplayStyleTab) {
|
||||||
continue;
|
continue;
|
||||||
} // Process only linkset attributes...
|
}
|
||||||
|
|
||||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||||
|
|
||||||
@@ -897,7 +902,8 @@ HTML
|
|||||||
// the caller may override some flags if needed
|
// the caller may override some flags if needed
|
||||||
$iFlags = $iFlags | $aExtraFlags[$sAttCode];
|
$iFlags = $iFlags | $aExtraFlags[$sAttCode];
|
||||||
}
|
}
|
||||||
if ((!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0) && !($oAttDef instanceof AttributeDashboard)) {
|
$bIsLinkSetWithDisplayStyleTab = is_a($oAttDef, AttributeLinkedSet::class) && $oAttDef->GetDisplayStyle() === LINKSET_DISPLAY_STYLE_TAB;
|
||||||
|
if ((($iFlags & OPT_ATT_HIDDEN) == 0) && !($oAttDef instanceof AttributeDashboard) && !$bIsLinkSetWithDisplayStyleTab) {
|
||||||
$sInputId = $this->m_iFormId.'_'.$sAttCode;
|
$sInputId = $this->m_iFormId.'_'.$sAttCode;
|
||||||
if ($oAttDef->IsWritable()) {
|
if ($oAttDef->IsWritable()) {
|
||||||
$sInputType = '';
|
$sInputType = '';
|
||||||
@@ -905,8 +911,8 @@ HTML
|
|||||||
// State attribute is always read-only from the UI
|
// State attribute is always read-only from the UI
|
||||||
$sHTMLValue = $this->GetAsHTML($sAttCode);
|
$sHTMLValue = $this->GetAsHTML($sAttCode);
|
||||||
$val = array(
|
$val = array(
|
||||||
'label' => '<label>'.$oAttDef->GetLabel().'</label>',
|
'label' => '<label>'.$oAttDef->GetLabel().'</label>',
|
||||||
'value' => $sHTMLValue,
|
'value' => $sHTMLValue,
|
||||||
'input_id' => $sInputId,
|
'input_id' => $sInputId,
|
||||||
'comments' => $sComments,
|
'comments' => $sComments,
|
||||||
'infos' => $sInfos,
|
'infos' => $sInfos,
|
||||||
@@ -935,7 +941,11 @@ HTML
|
|||||||
} else {
|
} else {
|
||||||
$sValue = $this->Get($sAttCode);
|
$sValue = $this->Get($sAttCode);
|
||||||
$sDisplayValue = $this->GetEditValue($sAttCode);
|
$sDisplayValue = $this->GetEditValue($sAttCode);
|
||||||
|
// transfer bulk context to components as it can be needed (linked set)
|
||||||
$aArgs = array('this' => $this, 'formPrefix' => $sPrefix);
|
$aArgs = array('this' => $this, 'formPrefix' => $sPrefix);
|
||||||
|
if (array_key_exists('bulk_context', $aExtraParams)) {
|
||||||
|
$aArgs['bulk_context'] = $aExtraParams['bulk_context'];
|
||||||
|
}
|
||||||
$sHTMLValue = "".self::GetFormElementForField(
|
$sHTMLValue = "".self::GetFormElementForField(
|
||||||
$oPage, $sClass, $sAttCode, $oAttDef, $sValue,
|
$oPage, $sClass, $sAttCode, $oAttDef, $sValue,
|
||||||
$sDisplayValue, $sInputId, '', $iFlags, $aArgs,
|
$sDisplayValue, $sInputId, '', $iFlags, $aArgs,
|
||||||
@@ -2019,7 +2029,15 @@ HTML
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sHTMLValue = '';
|
$sHTMLValue = '';
|
||||||
if (!$oAttDef->IsExternalField()) {
|
|
||||||
|
// attributes not compatible with bulk modify
|
||||||
|
$bAttNotCompatibleWithBulk = array_key_exists('bulk_context', $aArgs) && !$oAttDef->IsBulkModifyCompatible();
|
||||||
|
if ($bAttNotCompatibleWithBulk) {
|
||||||
|
$oTagSetBlock = new Html('<span class="ibo-bulk--bulk-modify--incompatible-attribute">'.Dict::S('UI:Bulk:modify:IncompatibleAttribute').'</span>');
|
||||||
|
$sHTMLValue = ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oTagSetBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$oAttDef->IsExternalField() && !$bAttNotCompatibleWithBulk) {
|
||||||
$bMandatory = 'false';
|
$bMandatory = 'false';
|
||||||
if ((!$oAttDef->IsNullAllowed()) || ($iFlags & OPT_ATT_MANDATORY)) {
|
if ((!$oAttDef->IsNullAllowed()) || ($iFlags & OPT_ATT_MANDATORY)) {
|
||||||
$bMandatory = 'true';
|
$bMandatory = 'true';
|
||||||
@@ -2313,17 +2331,29 @@ EOF
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'LinkedSet':
|
case 'LinkedSet':
|
||||||
$sInputType = self::ENUM_INPUT_TYPE_LINKEDSET;
|
if ($oAttDef->GetDisplayStyle() === LINKSET_DISPLAY_STYLE_PROPERTY) {
|
||||||
if ($oAttDef->IsIndirect()) {
|
if (array_key_exists('bulk_context', $aArgs)) {
|
||||||
$oWidget = new UILinksWidget($sClass, $sAttCode, $iId, $sNameSuffix,
|
$oTagSetBlock = LinksSetUIBlockFactory::MakeForBulkLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['bulk_context']);
|
||||||
$oAttDef->DuplicatesAllowed());
|
} else {
|
||||||
|
$oTagSetBlock = LinksSetUIBlockFactory::MakeForLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName);
|
||||||
|
}
|
||||||
|
$oTagSetBlock->SetName("attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}");
|
||||||
|
$aEventsList[] = 'validate';
|
||||||
|
$aEventsList[] = 'change';
|
||||||
|
$sHTMLValue = ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oTagSetBlock);
|
||||||
} else {
|
} else {
|
||||||
$oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iId, $sNameSuffix);
|
$sInputType = self::ENUM_INPUT_TYPE_LINKEDSET;
|
||||||
|
if ($oAttDef->IsIndirect()) {
|
||||||
|
$oWidget = new UILinksWidget($sClass, $sAttCode, $iId, $sNameSuffix,
|
||||||
|
$oAttDef->DuplicatesAllowed());
|
||||||
|
} else {
|
||||||
|
$oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iId, $sNameSuffix);
|
||||||
|
}
|
||||||
|
$aEventsList[] = 'validate';
|
||||||
|
$aEventsList[] = 'change';
|
||||||
|
$oObj = $aArgs['this'] ?? null;
|
||||||
|
$sHTMLValue = $oWidget->Display($oPage, $value, array(), $sFormPrefix, $oObj);
|
||||||
}
|
}
|
||||||
$aEventsList[] = 'validate';
|
|
||||||
$aEventsList[] = 'change';
|
|
||||||
$oObj = isset($aArgs['this']) ? $aArgs['this'] : null;
|
|
||||||
$sHTMLValue = $oWidget->Display($oPage, $value, array(), $sFormPrefix, $oObj);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Document':
|
case 'Document':
|
||||||
@@ -3550,17 +3580,14 @@ EOF
|
|||||||
protected function GetFieldAsHtml($sClass, $sAttCode, $sStateAttCode)
|
protected function GetFieldAsHtml($sClass, $sAttCode, $sStateAttCode)
|
||||||
{
|
{
|
||||||
$retVal = null;
|
$retVal = null;
|
||||||
if ($this->IsNew())
|
if ($this->IsNew()) {
|
||||||
{
|
|
||||||
$iFlags = $this->GetInitialStateAttributeFlags($sAttCode);
|
$iFlags = $this->GetInitialStateAttributeFlags($sAttCode);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$iFlags = $this->GetAttributeFlags($sAttCode);
|
$iFlags = $this->GetAttributeFlags($sAttCode);
|
||||||
}
|
}
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
if ((!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0) && !($oAttDef instanceof AttributeDashboard))
|
$bIsLinkSetWithDisplayStyleTab = is_a($oAttDef, AttributeLinkedSet::class) && $oAttDef->GetDisplayStyle() === LINKSET_DISPLAY_STYLE_TAB;
|
||||||
{
|
if ((($iFlags & OPT_ATT_HIDDEN) == 0) && !($oAttDef instanceof AttributeDashboard) && !$bIsLinkSetWithDisplayStyleTab) {
|
||||||
// First prepare the label
|
// First prepare the label
|
||||||
// - Attribute description
|
// - Attribute description
|
||||||
$sDescription = $oAttDef->GetDescription();
|
$sDescription = $oAttDef->GetDescription();
|
||||||
@@ -3989,14 +4016,17 @@ HTML;
|
|||||||
foreach ($value['to_be_created'] as $aData)
|
foreach ($value['to_be_created'] as $aData)
|
||||||
{
|
{
|
||||||
$sSubClass = $aData['class'];
|
$sSubClass = $aData['class'];
|
||||||
if (($sLinkedClass == $sSubClass) || (is_subclass_of($sSubClass, $sLinkedClass)))
|
if (($sLinkedClass == $sSubClass) || (is_subclass_of($sSubClass, $sLinkedClass))) {
|
||||||
{
|
|
||||||
$aObjData = $aData['data'];
|
$aObjData = $aData['data'];
|
||||||
$oLink = MetaModel::NewObject($sSubClass);
|
// Avoid duplicates on bulk modify
|
||||||
$oLink->UpdateObjectFromArray($aObjData);
|
if (!in_array($aObjData[$oAttDef->GetExtKeyToRemote()], $oLinkSet->GetColumnAsArray($oAttDef->GetExtKeyToRemote(), false))
|
||||||
$oLinkSet->AddItem($oLink);
|
|| $oAttDef->DuplicatesAllowed()) {
|
||||||
|
$oLink = MetaModel::NewObject($sSubClass);
|
||||||
|
$oLink->UpdateObjectFromArray($aObjData);
|
||||||
|
$oLinkSet->AddItem($oLink);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (array_key_exists('to_be_added', $value) && (count($value['to_be_added']) > 0))
|
if (array_key_exists('to_be_added', $value) && (count($value['to_be_added']) > 0))
|
||||||
{
|
{
|
||||||
@@ -4202,28 +4232,29 @@ HTML;
|
|||||||
|
|
||||||
case 'LinkedSet':
|
case 'LinkedSet':
|
||||||
/** @var AttributeLinkedSet $oAttDef */
|
/** @var AttributeLinkedSet $oAttDef */
|
||||||
|
if ($oAttDef->GetDisplayStyle() === LINKSET_DISPLAY_STYLE_PROPERTY) {
|
||||||
|
$sLinkedClass = LinkSetModel::GetLinkedClass($oAttDef);
|
||||||
|
$sTargetField = LinkSetModel::GetTargetField($oAttDef);
|
||||||
|
$aOperations = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_operations", '{}', 'raw_data'), true);
|
||||||
|
$value = LinkSetDataTransformer::Encode($aOperations, $sLinkedClass, $sTargetField);
|
||||||
|
break;
|
||||||
|
}
|
||||||
$aRawToBeCreated = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbc", '{}',
|
$aRawToBeCreated = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbc", '{}',
|
||||||
'raw_data'), true);
|
'raw_data'), true);
|
||||||
$aToBeCreated = array();
|
$aToBeCreated = array();
|
||||||
foreach($aRawToBeCreated as $aData)
|
foreach ($aRawToBeCreated as $aData) {
|
||||||
{
|
|
||||||
$sSubFormPrefix = $aData['formPrefix'];
|
$sSubFormPrefix = $aData['formPrefix'];
|
||||||
$sObjClass = isset($aData['class']) ? $aData['class'] : $oAttDef->GetLinkedClass();
|
$sObjClass = isset($aData['class']) ? $aData['class'] : $oAttDef->GetLinkedClass();
|
||||||
$aObjData = array();
|
$aObjData = array();
|
||||||
foreach($aData as $sKey => $value)
|
foreach ($aData as $sKey => $value) {
|
||||||
{
|
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches)) {
|
||||||
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches))
|
|
||||||
{
|
|
||||||
$oLinkAttDef = MetaModel::GetAttributeDef($sObjClass, $aMatches[1]);
|
$oLinkAttDef = MetaModel::GetAttributeDef($sObjClass, $aMatches[1]);
|
||||||
// Recursing over n:n link datetime attributes
|
// Recursing over n:n link datetime attributes
|
||||||
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
||||||
if ($oLinkAttDef instanceof AttributeDateTime)
|
if ($oLinkAttDef instanceof AttributeDateTime) {
|
||||||
{
|
|
||||||
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix,
|
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix,
|
||||||
$aMatches[1], $sObjClass, $aData);
|
$aMatches[1], $sObjClass, $aData);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aObjData[$aMatches[1]] = $value;
|
$aObjData[$aMatches[1]] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4234,25 +4265,19 @@ HTML;
|
|||||||
$aRawToBeModified = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbm", '{}',
|
$aRawToBeModified = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbm", '{}',
|
||||||
'raw_data'), true);
|
'raw_data'), true);
|
||||||
$aToBeModified = array();
|
$aToBeModified = array();
|
||||||
foreach($aRawToBeModified as $iObjKey => $aData)
|
foreach($aRawToBeModified as $iObjKey => $aData) {
|
||||||
{
|
|
||||||
$sSubFormPrefix = $aData['formPrefix'];
|
$sSubFormPrefix = $aData['formPrefix'];
|
||||||
$sObjClass = isset($aData['class']) ? $aData['class'] : $oAttDef->GetLinkedClass();
|
$sObjClass = isset($aData['class']) ? $aData['class'] : $oAttDef->GetLinkedClass();
|
||||||
$aObjData = array();
|
$aObjData = array();
|
||||||
foreach($aData as $sKey => $value)
|
foreach($aData as $sKey => $value) {
|
||||||
{
|
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches)) {
|
||||||
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches))
|
|
||||||
{
|
|
||||||
$oLinkAttDef = MetaModel::GetAttributeDef($sObjClass, $aMatches[1]);
|
$oLinkAttDef = MetaModel::GetAttributeDef($sObjClass, $aMatches[1]);
|
||||||
// Recursing over n:n link datetime attributes
|
// Recursing over n:n link datetime attributes
|
||||||
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
||||||
if ($oLinkAttDef instanceof AttributeDateTime)
|
if ($oLinkAttDef instanceof AttributeDateTime) {
|
||||||
{
|
|
||||||
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix,
|
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix,
|
||||||
$aMatches[1], $sObjClass, $aData);
|
$aMatches[1], $sObjClass, $aData);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$aObjData[$aMatches[1]] = $value;
|
$aObjData[$aMatches[1]] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4261,13 +4286,13 @@ HTML;
|
|||||||
}
|
}
|
||||||
|
|
||||||
$value = array(
|
$value = array(
|
||||||
'to_be_created' => $aToBeCreated,
|
'to_be_created' => $aToBeCreated,
|
||||||
'to_be_modified' => $aToBeModified,
|
'to_be_modified' => $aToBeModified,
|
||||||
'to_be_deleted' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbd", '[]',
|
'to_be_deleted' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbd", '[]',
|
||||||
'raw_data'), true),
|
'raw_data'), true),
|
||||||
'to_be_added' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tba", '[]',
|
'to_be_added' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tba", '[]',
|
||||||
'raw_data'), true),
|
'raw_data'), true),
|
||||||
'to_be_removed' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbr", '[]',
|
'to_be_removed' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbr", '[]',
|
||||||
'raw_data'), true),
|
'raw_data'), true),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@@ -4275,7 +4300,9 @@ HTML;
|
|||||||
case 'Set':
|
case 'Set':
|
||||||
case 'TagSet':
|
case 'TagSet':
|
||||||
$sTagSetJson = utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}", null, 'raw_data');
|
$sTagSetJson = utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}", null, 'raw_data');
|
||||||
|
if ($sTagSetJson !== null) { // bulk modify, direct linked set not handled
|
||||||
$value = json_decode($sTagSetJson, true);
|
$value = json_decode($sTagSetJson, true);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -4896,13 +4923,12 @@ HTML
|
|||||||
$sOQL = "SELECT $sClass WHERE id IN (".$sSelectedObj.")";
|
$sOQL = "SELECT $sClass WHERE id IN (".$sSelectedObj.")";
|
||||||
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL));
|
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL));
|
||||||
|
|
||||||
// Compute the distribution of the values for each field to determine which of the "scalar" fields are homogeneous
|
// Compute the distribution of the values for each field to determine which of the "scalar or linked set" fields are homogeneous
|
||||||
$aList = MetaModel::ListAttributeDefs($sClass);
|
$aList = MetaModel::ListAttributeDefs($sClass);
|
||||||
$aValues = array();
|
$aValues = array();
|
||||||
foreach($aList as $sAttCode => $oAttDef)
|
foreach($aList as $sAttCode => $oAttDef)
|
||||||
{
|
{
|
||||||
if ($oAttDef->IsScalar())
|
if ($oAttDef->IsBulkModifyCompatible()) {
|
||||||
{
|
|
||||||
$aValues[$sAttCode] = array();
|
$aValues[$sAttCode] = array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4910,26 +4936,27 @@ HTML
|
|||||||
{
|
{
|
||||||
foreach($aList as $sAttCode => $oAttDef)
|
foreach($aList as $sAttCode => $oAttDef)
|
||||||
{
|
{
|
||||||
if ($oAttDef->IsScalar() && $oAttDef->IsWritable())
|
if ($oAttDef->IsBulkModifyCompatible() && $oAttDef->IsWritable()) {
|
||||||
{
|
|
||||||
$currValue = $oObj->Get($sAttCode);
|
$currValue = $oObj->Get($sAttCode);
|
||||||
if ($oAttDef instanceof AttributeCaseLog)
|
$editValue = '';
|
||||||
{
|
if ($oAttDef instanceof AttributeCaseLog) {
|
||||||
$currValue = ''; // Put a single scalar value to force caselog to mock a new entry. For more info see N°1059.
|
$currValue = ''; // Put a single scalar value to force caselog to mock a new entry. For more info see N°1059.
|
||||||
}
|
} elseif ($currValue instanceof ormSet) {
|
||||||
elseif ($currValue instanceof ormSet)
|
|
||||||
{
|
|
||||||
$currValue = $oAttDef->GetEditValue($currValue, $oObj);
|
$currValue = $oAttDef->GetEditValue($currValue, $oObj);
|
||||||
|
} else if ($currValue instanceof ormLinkSet) {
|
||||||
|
$sHtmlValue = $oAttDef->GetAsHTML($currValue);
|
||||||
|
$editValue = $oAttDef->GetEditValue($currValue, $oObj);
|
||||||
|
$currValue = $sHtmlValue;
|
||||||
}
|
}
|
||||||
if (is_object($currValue))
|
if (is_object($currValue)) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
} // Skip non scalar values...
|
} // Skip non scalar values...
|
||||||
if (!array_key_exists($currValue, $aValues[$sAttCode]))
|
if (!array_key_exists($currValue, $aValues[$sAttCode]))
|
||||||
{
|
{
|
||||||
$aValues[$sAttCode][$currValue] = array(
|
$aValues[$sAttCode][$currValue] = array(
|
||||||
'count' => 1,
|
'count' => 1,
|
||||||
'display' => $oObj->GetAsHTML($sAttCode),
|
'display' => $oObj->GetAsHTML($sAttCode),
|
||||||
|
'edit_value' => $editValue,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -4971,7 +4998,7 @@ HTML
|
|||||||
$sFieldList = "['{$sFormPrefix}".implode("','{$sFormPrefix}", $aDependents)."']";
|
$sFieldList = "['{$sFormPrefix}".implode("','{$sFormPrefix}", $aDependents)."']";
|
||||||
$oP->add_ready_script("$('#enable_{$sFormPrefix}{$sAttCode}').on('change', function(evt, sFormId) { return PropagateCheckBox( this.checked, $sFieldList, false); } );\n");
|
$oP->add_ready_script("$('#enable_{$sFormPrefix}{$sAttCode}').on('change', function(evt, sFormId) { return PropagateCheckBox( this.checked, $sFieldList, false); } );\n");
|
||||||
}
|
}
|
||||||
if ($oAttDef->IsScalar() && $oAttDef->IsWritable()) {
|
if ($oAttDef->IsBulkModifyCompatible() && $oAttDef->IsWritable()) {
|
||||||
if ($oAttDef->GetEditClass() == 'One Way Password') {
|
if ($oAttDef->GetEditClass() == 'One Way Password') {
|
||||||
|
|
||||||
$sTip = Dict::S('UI:Component:Field:BulkModify:UnknownValues:Tooltip');
|
$sTip = Dict::S('UI:Component:Field:BulkModify:UnknownValues:Tooltip');
|
||||||
@@ -4987,7 +5014,13 @@ HTML
|
|||||||
reset($aValues[$sAttCode]);
|
reset($aValues[$sAttCode]);
|
||||||
$aKeys = array_keys($aValues[$sAttCode]);
|
$aKeys = array_keys($aValues[$sAttCode]);
|
||||||
$currValue = $aKeys[0]; // The only value is the first key
|
$currValue = $aKeys[0]; // The only value is the first key
|
||||||
$oDummyObj->Set($sAttCode, $currValue);
|
if ($oAttDef->GetEditClass() == 'LinkedSet') {
|
||||||
|
$oOrmLinkSet = $oDummyObj->Get($sAttCode);
|
||||||
|
LinkSetDataTransformer::StringToOrmLinkSet($aValues[$sAttCode][$currValue]['edit_value'], $oOrmLinkSet);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$oDummyObj->Set($sAttCode, $currValue);
|
||||||
|
}
|
||||||
$aComments[$sAttCode] = '';
|
$aComments[$sAttCode] = '';
|
||||||
$sValueCheckbox = '';
|
$sValueCheckbox = '';
|
||||||
if ($sAttCode != MetaModel::GetStateAttributeCode($sClass) || !MetaModel::HasLifecycle($sClass)) {
|
if ($sAttCode != MetaModel::GetStateAttributeCode($sClass) || !MetaModel::HasLifecycle($sClass)) {
|
||||||
@@ -5035,6 +5068,12 @@ HTML
|
|||||||
$oTagSet->GenerateDiffFromArray($aTagCodes);
|
$oTagSet->GenerateDiffFromArray($aTagCodes);
|
||||||
}
|
}
|
||||||
$oDummyObj->Set($sAttCode, $oTagSet);
|
$oDummyObj->Set($sAttCode, $oTagSet);
|
||||||
|
} else if ($oAttDef->GetEditClass() == 'LinkedSet') {
|
||||||
|
$oOrmLinkSet = $oDummyObj->Get($sAttCode);
|
||||||
|
foreach ($aMultiValues as $key => $sValue) {
|
||||||
|
LinkSetDataTransformer::StringToOrmLinkSet($sValue['edit_value'], $oOrmLinkSet);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$oDummyObj->Set($sAttCode, null);
|
$oDummyObj->Set($sAttCode, null);
|
||||||
}
|
}
|
||||||
@@ -5070,15 +5109,18 @@ HTML
|
|||||||
|
|
||||||
$aParams = array
|
$aParams = array
|
||||||
(
|
(
|
||||||
'fieldsComments' => $aComments,
|
'fieldsComments' => $aComments,
|
||||||
'noRelations' => true,
|
'noRelations' => true,
|
||||||
'custom_operation' => $sCustomOperation,
|
'custom_operation' => $sCustomOperation,
|
||||||
'custom_button' => Dict::S('UI:Button:PreviewModifications'),
|
'custom_button' => Dict::S('UI:Button:PreviewModifications'),
|
||||||
'selectObj' => $sSelectedObj,
|
'selectObj' => $sSelectedObj,
|
||||||
'nbBulkObj' => $iAllowedCount,
|
'nbBulkObj' => $iAllowedCount,
|
||||||
'preview_mode' => true,
|
'preview_mode' => true,
|
||||||
'disabled_fields' => $sDisableFields,
|
'disabled_fields' => $sDisableFields,
|
||||||
'disable_plugins' => true,
|
'disable_plugins' => true,
|
||||||
|
'bulk_context' => [
|
||||||
|
'oql' => $sOQL,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
$aParams = $aParams + $aContextData; // merge keeping associations
|
$aParams = $aParams + $aContextData; // merge keeping associations
|
||||||
|
|
||||||
|
|||||||
@@ -60,16 +60,20 @@ class WizardHelper
|
|||||||
// special handling for lists
|
// special handling for lists
|
||||||
// assumes this is handled as an array of objects
|
// assumes this is handled as an array of objects
|
||||||
// thus encoded in json like: [ { name:'link1', 'id': 123}, { name:'link2', 'id': 124}...]
|
// thus encoded in json like: [ { name:'link1', 'id': 123}, { name:'link2', 'id': 124}...]
|
||||||
$aData = json_decode($value, true); // true means decode as a hash array (not an object)
|
if (!is_array($value)) {
|
||||||
|
$aData = json_decode($value, true); // true means decode as a hash array (not an object)
|
||||||
|
} else {
|
||||||
|
$aData = $value;
|
||||||
|
}
|
||||||
|
|
||||||
// Check what are the meaningful attributes
|
// Check what are the meaningful attributes
|
||||||
$aFields = $this->GetLinkedWizardStructure($oAttDef);
|
$aFields = $this->GetLinkedWizardStructure($oAttDef);
|
||||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||||
$aLinkedObjectsArray = array();
|
$aLinkedObjectsArray = array();
|
||||||
if (!is_array($aData))
|
if (!is_array($aData)) {
|
||||||
{
|
echo("aData: '$aData' (value: '$value')\n");
|
||||||
echo ("aData: '$aData' (value: '$value')\n");
|
|
||||||
}
|
}
|
||||||
foreach($aData as $aLinkedObject)
|
foreach ($aData as $aLinkedObject)
|
||||||
{
|
{
|
||||||
$oLinkedObj = MetaModel::NewObject($sLinkedClass);
|
$oLinkedObj = MetaModel::NewObject($sLinkedClass);
|
||||||
foreach($aFields as $sLinkedAttCode)
|
foreach($aFields as $sLinkedAttCode)
|
||||||
|
|||||||
@@ -5,12 +5,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use Combodo\iTop\Application\UI\Base\Component\FieldBadge\FieldBadgeUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\FieldBadge\FieldBadgeUIBlockFactory;
|
||||||
|
use Combodo\iTop\Application\UI\Links\Indirect\BlockLinksSetDisplayAsProperty;
|
||||||
use Combodo\iTop\Form\Field\LabelField;
|
use Combodo\iTop\Form\Field\LabelField;
|
||||||
use Combodo\iTop\Form\Field\TextAreaField;
|
use Combodo\iTop\Form\Field\TextAreaField;
|
||||||
use Combodo\iTop\Form\Form;
|
use Combodo\iTop\Form\Form;
|
||||||
use Combodo\iTop\Form\Validator\NotEmptyExtKeyValidator;
|
use Combodo\iTop\Form\Validator\NotEmptyExtKeyValidator;
|
||||||
use Combodo\iTop\Form\Validator\Validator;
|
use Combodo\iTop\Form\Validator\Validator;
|
||||||
use Combodo\iTop\Renderer\BlockRenderer;
|
use Combodo\iTop\Renderer\BlockRenderer;
|
||||||
|
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||||
|
use Combodo\iTop\Service\Links\LinkSetModel;
|
||||||
|
|
||||||
require_once('MyHelpers.class.inc.php');
|
require_once('MyHelpers.class.inc.php');
|
||||||
require_once('ormdocument.class.inc.php');
|
require_once('ormdocument.class.inc.php');
|
||||||
@@ -92,6 +95,9 @@ define('LINKSET_EDITMODE_ADDREMOVE', 4); // The "linked" objects can be added/re
|
|||||||
define('LINKSET_RELATIONTYPE_PROPERTY', 'property');
|
define('LINKSET_RELATIONTYPE_PROPERTY', 'property');
|
||||||
define('LINKSET_RELATIONTYPE_LINK', 'link');
|
define('LINKSET_RELATIONTYPE_LINK', 'link');
|
||||||
|
|
||||||
|
define('LINKSET_DISPLAY_STYLE_PROPERTY', 'property');
|
||||||
|
define('LINKSET_DISPLAY_STYLE_TAB', 'tab');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attributes implementing this interface won't be accepted as `group by` field
|
* Attributes implementing this interface won't be accepted as `group by` field
|
||||||
*
|
*
|
||||||
@@ -140,6 +146,15 @@ abstract class AttributeDefinition
|
|||||||
|
|
||||||
abstract public function GetEditClass();
|
abstract public function GetEditClass();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array Css classes
|
||||||
|
* @since 3.1.0 N°3190
|
||||||
|
*/
|
||||||
|
public function GetCssClasses(): array
|
||||||
|
{
|
||||||
|
return $this->aCSSClasses;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the search widget type corresponding to this attribute
|
* Return the search widget type corresponding to this attribute
|
||||||
*
|
*
|
||||||
@@ -361,6 +376,18 @@ abstract class AttributeDefinition
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the attribute can be used in bulk modify.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 3.1.0 N°3190
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static function IsBulkModifyCompatible(): bool
|
||||||
|
{
|
||||||
|
return static::IsScalar();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the attribute value is a set of related objects (1-N or N-N)
|
* Returns true if the attribute value is a set of related objects (1-N or N-N)
|
||||||
*
|
*
|
||||||
@@ -1417,6 +1444,7 @@ class AttributeLinkedSet extends AttributeDefinition
|
|||||||
public function __construct($sCode, $aParams)
|
public function __construct($sCode, $aParams)
|
||||||
{
|
{
|
||||||
parent::__construct($sCode, $aParams);
|
parent::__construct($sCode, $aParams);
|
||||||
|
$this->aCSSClasses[] = 'attribute-set';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function ListExpectedParams()
|
public static function ListExpectedParams()
|
||||||
@@ -1430,6 +1458,12 @@ class AttributeLinkedSet extends AttributeDefinition
|
|||||||
return "LinkedSet";
|
return "LinkedSet";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public static function IsBulkModifyCompatible(): bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function IsWritable()
|
public function IsWritable()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -1447,7 +1481,26 @@ class AttributeLinkedSet extends AttributeDefinition
|
|||||||
|
|
||||||
public function GetValuesDef()
|
public function GetValuesDef()
|
||||||
{
|
{
|
||||||
return $this->Get("allowed_values");
|
$oValSetDef = $this->Get("allowed_values");
|
||||||
|
if (!$oValSetDef) {
|
||||||
|
// Let's propose every existing value
|
||||||
|
$oValSetDef = new ValueSetObjects('SELECT '.LinkSetModel::GetTargetClass($this));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $oValSetDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetEditValue($value, $oHostObj = null)
|
||||||
|
{
|
||||||
|
/** @var ormLinkSet $value * */
|
||||||
|
if ($value->Count() === 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return linked objects key as string **/
|
||||||
|
$aValues = $value->GetValues();
|
||||||
|
|
||||||
|
return implode(' ', $aValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetPrerequisiteAttributes($sClass = null)
|
public function GetPrerequisiteAttributes($sClass = null)
|
||||||
@@ -1532,6 +1585,15 @@ class AttributeLinkedSet extends AttributeDefinition
|
|||||||
return $this->GetOptional('relation_type', LINKSET_RELATIONTYPE_LINK);
|
return $this->GetOptional('relation_type', LINKSET_RELATIONTYPE_LINK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string see LINKSET_DISPLAY_STYLE_* constants
|
||||||
|
* @since 3.1.0 N°3190
|
||||||
|
*/
|
||||||
|
public function GetDisplayStyle()
|
||||||
|
{
|
||||||
|
return $this->GetOptional('display_style', LINKSET_DISPLAY_STYLE_TAB);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return boolean
|
||||||
* @since 3.1.0 N°5563
|
* @since 3.1.0 N°5563
|
||||||
@@ -1566,49 +1628,30 @@ class AttributeLinkedSet extends AttributeDefinition
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @inheritDoc * */
|
||||||
* @param string $sValue
|
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true): string
|
||||||
* @param \DBObject $oHostObject
|
|
||||||
* @param bool $bLocalize
|
|
||||||
*
|
|
||||||
* @return string|null
|
|
||||||
*
|
|
||||||
* @throws \CoreException
|
|
||||||
*/
|
|
||||||
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true)
|
|
||||||
{
|
{
|
||||||
if (is_object($sValue) && ($sValue instanceof ormLinkSet))
|
try {
|
||||||
{
|
|
||||||
$sValue->Rewind();
|
/** @var ormLinkSet $sValue */
|
||||||
$aItems = array();
|
if ($sValue->Count() === 0) {
|
||||||
while ($oObj = $sValue->Fetch())
|
return '';
|
||||||
{
|
|
||||||
// Show only relevant information (hide the external key to the current object)
|
|
||||||
$aAttributes = array();
|
|
||||||
foreach(MetaModel::ListAttributeDefs($this->GetLinkedClass()) as $sAttCode => $oAttDef)
|
|
||||||
{
|
|
||||||
if ($sAttCode == $this->GetExtKeyToMe())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ($oAttDef->IsExternalField())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$sAttValue = $oObj->GetAsHTML($sAttCode);
|
|
||||||
if (strlen($sAttValue) > 0)
|
|
||||||
{
|
|
||||||
$aAttributes[] = $sAttValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$sAttributes = implode(', ', $aAttributes);
|
|
||||||
$aItems[] = $sAttributes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return implode('<br/>', $aItems);
|
$oLinkSetBlock = new BlockLinksSetDisplayAsProperty($this->GetCode(), $this, $sValue);
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return ConsoleBlockRenderer::RenderBlockTemplates($oLinkSetBlock);
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
$sMessage = "Error while displaying attribute {$this->GetCode()}";
|
||||||
|
IssueLog::Error($sMessage, IssueLog::CHANNEL_DEFAULT, [
|
||||||
|
'host_object_class' => $this->GetHostClass(),
|
||||||
|
'host_object_key' => $oHostObject->GetKey(),
|
||||||
|
'attribute' => $this->GetCode(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $sMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2361,6 +2404,13 @@ class AttributeLinkedSetIndirect extends AttributeLinkedSet
|
|||||||
|
|
||||||
return $oRet;
|
return $oRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public static function IsBulkModifyCompatible(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -847,11 +847,30 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
|||||||
}
|
}
|
||||||
$oLinkSet = new DBObjectSet($oLinkSearch);
|
$oLinkSet = new DBObjectSet($oLinkSearch);
|
||||||
$oLinkSet->SetShowObsoleteData($bShowObsolete);
|
$oLinkSet->SetShowObsoleteData($bShowObsolete);
|
||||||
if ($this->HasDelta())
|
if ($this->HasDelta()) {
|
||||||
{
|
|
||||||
$oLinkSet->AddObjectArray($this->aAdded);
|
$oLinkSet->AddObjectArray($this->aAdded);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $oLinkSet;
|
return $oLinkSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetValues.
|
||||||
|
*
|
||||||
|
* @return array of tag codes
|
||||||
|
*/
|
||||||
|
public function GetValues()
|
||||||
|
{
|
||||||
|
$aValues = array();
|
||||||
|
foreach ($this->aPreserved as $sTagCode => $oTag) {
|
||||||
|
$aValues[] = $sTagCode;
|
||||||
|
}
|
||||||
|
foreach ($this->aAdded as $sTagCode => $oTag) {
|
||||||
|
$aValues[] = $sTagCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
sort($aValues);
|
||||||
|
|
||||||
|
return $aValues;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,5 +3,7 @@
|
|||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@import "bulk/all";
|
||||||
@import "display-block/all";
|
@import "display-block/all";
|
||||||
|
@import "linked-set/all";
|
||||||
@import "tabular-fields/all";
|
@import "tabular-fields/all";
|
||||||
6
css/backoffice/application/bulk/_all.scss
Normal file
6
css/backoffice/application/bulk/_all.scss
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import "bulk-modify";
|
||||||
14
css/backoffice/application/bulk/_bulk-modify.scss
Normal file
14
css/backoffice/application/bulk/_bulk-modify.scss
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
.ibo-bulk--bulk-modify--incompatible-attribute {
|
||||||
|
|
||||||
|
&:before{
|
||||||
|
margin-right: $ibo-vendors-selectize--item--icon--margin-right;
|
||||||
|
@extend %fa-solid-base;
|
||||||
|
content: '\f05a';
|
||||||
|
color: $ibo-color-information-500;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
css/backoffice/application/linked-set/_all.scss
Normal file
6
css/backoffice/application/linked-set/_all.scss
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import "linked-set-selector";
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
.ibo-linked-set--bulk-tooltip-info {
|
||||||
|
font-size: $ibo-font-size-100;
|
||||||
|
&:before{
|
||||||
|
margin-right: $ibo-vendors-selectize--item--icon--margin-right;
|
||||||
|
@extend %fa-solid-base;
|
||||||
|
content: '\f05a';
|
||||||
|
color: $ibo-color-information-500;
|
||||||
|
}
|
||||||
|
}
|
||||||
85
css/backoffice/vendors/_selectize.scss
vendored
85
css/backoffice/vendors/_selectize.scss
vendored
@@ -4,10 +4,95 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$ibo-vendors-selectize-input--color: $ibo-color-grey-900 !default;
|
$ibo-vendors-selectize-input--color: $ibo-color-grey-900 !default;
|
||||||
|
$ibo-vendors-selectize-control--plugin-add-button--add-option--right: $ibo-spacing-0 !default;
|
||||||
|
$ibo-vendors-selectize-control--plugin-add-button--add-option--height: 100% !default;
|
||||||
|
$ibo-vendors-selectize-control--plugin-add-button--add-option--width: $ibo-size-350 !default;
|
||||||
|
$ibo-vendors-selectize-control--plugin-add-button--add-option--color: $ibo-color-grey-900 !default;
|
||||||
|
|
||||||
|
$ibo-vendors-selectize--item--icon--margin-right: $ibo-spacing-200 !default;
|
||||||
|
|
||||||
|
$ibo-vendors-selectize--item--add--background-color: $ibo-color-green-100 !default;
|
||||||
|
$ibo-vendors-selectize--item--add--icon--color: $ibo-color-green-900 !default;
|
||||||
|
|
||||||
|
$ibo-vendors-selectize--item--remove--background-color: $ibo-color-red-100 !default;
|
||||||
|
$ibo-vendors-selectize--item--remove--icon--color: $ibo-color-red-800 !default;
|
||||||
|
|
||||||
|
$ibo-vendors-selectize--item--ignore-partial--background-color: $ibo-color-grey-200 !default;
|
||||||
|
|
||||||
|
$ibo-vendors-selectize--input-error--border: 1px solid $ibo-color-red-600 !default;
|
||||||
|
|
||||||
.selectize-dropdown-content {
|
.selectize-dropdown-content {
|
||||||
max-height: unset; /* Overloaded as it will be handled by the _input-select.scss partial */
|
max-height: unset; /* Overloaded as it will be handled by the _input-select.scss partial */
|
||||||
}
|
}
|
||||||
.selectize-input input{
|
.selectize-input input{
|
||||||
color: $ibo-vendors-selectize-input--color;
|
color: $ibo-vendors-selectize-input--color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.selectize-control.plugin-combodo_add_button{
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.selectize-add-option {
|
||||||
|
position: absolute;
|
||||||
|
right: $ibo-vendors-selectize-control--plugin-add-button--add-option--right;
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: $ibo-vendors-selectize-control--plugin-add-button--add-option--height;
|
||||||
|
width: $ibo-vendors-selectize-control--plugin-add-button--add-option--width;
|
||||||
|
z-index: 1;
|
||||||
|
color: $ibo-vendors-selectize-control--plugin-add-button--add-option--color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Simple options renderer
|
||||||
|
|
||||||
|
.simple-option-renderer--container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple-option-renderer--container--icon {
|
||||||
|
width: 25px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simple-option-renderer--container--label {
|
||||||
|
margin-left: 3px;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.selectize-input{
|
||||||
|
.attribute-set-item{
|
||||||
|
>* {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
&.item-add::before,&.item-remove::before{
|
||||||
|
@extend %fa-solid-base;
|
||||||
|
margin-right: $ibo-vendors-selectize--item--icon--margin-right;
|
||||||
|
}
|
||||||
|
&.item-add{
|
||||||
|
background-color: $ibo-vendors-selectize--item--add--background-color !important;
|
||||||
|
&::before{
|
||||||
|
color: $ibo-vendors-selectize--item--add--icon--color;
|
||||||
|
content: '\f067';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.item-remove{
|
||||||
|
background-color: $ibo-vendors-selectize--item--remove--background-color !important;
|
||||||
|
&::before{
|
||||||
|
color: $ibo-vendors-selectize--item--remove--icon--color;
|
||||||
|
content: '\f1f8';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.item-ignore-partial{
|
||||||
|
background-color: $ibo-vendors-selectize--item--ignore-partial--background-color !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.selectize-input-error{
|
||||||
|
border: $ibo-vendors-selectize--input-error--border;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
25
dictionaries/ui/application/bulk/en.dictionary.itop.bulk.php
Normal file
25
dictionaries/ui/application/bulk/en.dictionary.itop.bulk.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2013-2021 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
Dict::Add('EN US', 'English', 'English', array(
|
||||||
|
|
||||||
|
// Bulk modify
|
||||||
|
'UI:Bulk:modify:IncompatibleAttribute' => 'This attribute can\'t be edited in bulk context',
|
||||||
|
|
||||||
|
));
|
||||||
25
dictionaries/ui/application/bulk/fr.dictionary.itop.bulk.php
Normal file
25
dictionaries/ui/application/bulk/fr.dictionary.itop.bulk.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2013-2021 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
Dict::Add('FR FR', 'French', 'Français', array(
|
||||||
|
|
||||||
|
// Bulk modify
|
||||||
|
'UI:Bulk:modify:IncompatibleAttribute' => 'Cet attribut ne peut être édité dans une modification en masse',
|
||||||
|
|
||||||
|
));
|
||||||
@@ -17,17 +17,31 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Display DataTable
|
|
||||||
Dict::Add('EN US', 'English', 'English', array(
|
Dict::Add('EN US', 'English', 'English', array(
|
||||||
'UI:Links:ActionRow:Detach' => 'Detach',
|
|
||||||
'UI:Links:ActionRow:Detach+' => 'Detach this object',
|
// Action row
|
||||||
'UI:Links:ActionRow:Detach:Confirmation' => 'Do you really want to detach <b>{item}</b> from current object ?',
|
'UI:Links:ActionRow:Detach' => 'Detach',
|
||||||
'UI:Links:ActionRow:Delete' => 'Delete',
|
'UI:Links:ActionRow:Detach+' => 'Detach this object',
|
||||||
'UI:Links:ActionRow:Delete+' => 'Delete this object',
|
'UI:Links:ActionRow:Detach:Confirmation' => 'Do you really want to detach <b>{item}</b> from current object ?',
|
||||||
'UI:Links:ActionRow:Delete:Confirmation' => 'Do you really want to delete <b>{item}</b> from current object ?',
|
'UI:Links:ActionRow:Delete' => 'Delete',
|
||||||
'UI:Links:ActionRow:Modify' => 'Modify',
|
'UI:Links:ActionRow:Delete+' => 'Delete this object',
|
||||||
'UI:Links:ActionRow:Modify+' => 'Modify this object',
|
'UI:Links:ActionRow:Delete:Confirmation' => 'Do you really want to delete <b>{item}</b> from current object ?',
|
||||||
'UI:Links:ActionRow:Modify:Modal:Title' => 'Modify a link',
|
'UI:Links:ActionRow:Modify' => 'Modify',
|
||||||
'UI:Links:New:Modal:Title' => 'Creation of a link',
|
'UI:Links:ActionRow:Modify+' => 'Modify this object',
|
||||||
'UI:Links:New:Button:Tooltip' => 'Add a new link',
|
'UI:Links:ActionRow:Modify:Modal:Title' => 'Modify a link',
|
||||||
|
|
||||||
|
// New
|
||||||
|
'UI:Links:New:Modal:Title' => 'Creation of a link',
|
||||||
|
'UI:Links:New:Button:Tooltip' => 'Add a new link',
|
||||||
|
|
||||||
|
// Bulk
|
||||||
|
'UI:Links:Bulk:LinkWillBeCreatedForAllObjects' => 'Link all objects',
|
||||||
|
'UI:Links:Bulk:LinkWillBeDeletedFromAllObjects' => 'Unlink all objects',
|
||||||
|
'UI:Links:Bulk:LinkWillBeCreatedFor1Object' => 'Link one object',
|
||||||
|
'UI:Links:Bulk:LinkWillBeDeletedFrom1Object' => 'Unlink one object',
|
||||||
|
'UI:Links:Bulk:LinkWillBeCreatedForXObjects' => 'Link {count} objects',
|
||||||
|
'UI:Links:Bulk:LinkWillBeDeletedFromXObjects' => 'Unlink {count} objects',
|
||||||
|
'UI:Links:Bulk:LinkExistForAllObjects' => 'All objets are already linked',
|
||||||
|
'UI:Links:Bulk:LinkExistForOneObject' => 'One object is linked',
|
||||||
|
'UI:Links:Bulk:LinkExistForXObjects' => '{count} objects are linked',
|
||||||
));
|
));
|
||||||
@@ -17,12 +17,24 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Display DataTable
|
|
||||||
Dict::Add('FR FR', 'French', 'Français', array(
|
Dict::Add('FR FR', 'French', 'Français', array(
|
||||||
'UI:Links:ActionRow:Detach' => 'Détacher',
|
|
||||||
'UI:Links:ActionRow:Detach+' => 'Détacher cet objet',
|
// Action row
|
||||||
'UI:Links:ActionRow:Detach:Confirmation' => 'Voulez-vous détacher <b>{item}</b> de l\'objet courant ?',
|
'UI:Links:ActionRow:Detach' => 'Détacher',
|
||||||
'UI:Links:ActionRow:Delete' => 'Supprimer',
|
'UI:Links:ActionRow:Detach+' => 'Détacher cet objet',
|
||||||
'UI:Links:ActionRow:Delete+' => 'Supprimer cet objet',
|
'UI:Links:ActionRow:Detach:Confirmation' => 'Voulez-vous détacher <b>{item}</b> de l\'objet courant ?',
|
||||||
'UI:Links:ActionRow:Delete:Confirmation' => 'Voulez-vous supprimer <b>{item}</b> de l\'objet courant ?',
|
'UI:Links:ActionRow:Delete' => 'Supprimer',
|
||||||
|
'UI:Links:ActionRow:Delete+' => 'Supprimer cet objet',
|
||||||
|
'UI:Links:ActionRow:Delete:Confirmation' => 'Voulez-vous supprimer <b>{item}</b> de l\'objet courant ?',
|
||||||
|
|
||||||
|
// Bulk
|
||||||
|
'UI:Links:Bulk:LinkWillBeCreatedForAllObjects' => 'Lier à tous les objets',
|
||||||
|
'UI:Links:Bulk:LinkWillBeDeletedFromAllObjects' => 'Détacher de tous les objets',
|
||||||
|
'UI:Links:Bulk:LinkWillBeCreatedFor1Object' => 'Lier à un objet',
|
||||||
|
'UI:Links:Bulk:LinkWillBeDeletedFrom1Object' => 'Détacher de un objet',
|
||||||
|
'UI:Links:Bulk:LinkWillBeCreatedForXObjects' => 'Lier à {count} objets',
|
||||||
|
'UI:Links:Bulk:LinkWillBeDeletedFromXObjects' => 'Détacher de {count} objets',
|
||||||
|
'UI:Links:Bulk:LinkExistForAllObjects' => 'Tous les objets sont déjà liés',
|
||||||
|
'UI:Links:Bulk:LinkExistForOneObject' => 'Un objet est lié',
|
||||||
|
'UI:Links:Bulk:LinkExistForXObjects' => '{count} objets sont liés',
|
||||||
));
|
));
|
||||||
60
js/selectize/plugin_combodo_add_button.js
Normal file
60
js/selectize/plugin_combodo_add_button.js
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
Selectize.define("combodo_add_button", function (aOptions) {
|
||||||
|
|
||||||
|
// Selectize instance
|
||||||
|
let oSelf = this;
|
||||||
|
|
||||||
|
// Plugin options
|
||||||
|
aOptions = $.extend({
|
||||||
|
title: "Add Option",
|
||||||
|
className: "selectize-add-option",
|
||||||
|
label: "+",
|
||||||
|
html: function () {
|
||||||
|
return (
|
||||||
|
'<a class="' + this.className + ' fas fa-plus" title="' + this.title + '"></a>'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
aOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
// Override setup function
|
||||||
|
oSelf.setup = (function () {
|
||||||
|
let oOriginal = oSelf.setup;
|
||||||
|
return function () {
|
||||||
|
oOriginal.apply(oSelf, arguments);
|
||||||
|
oSelf.$buttonAdd = $(aOptions.html());
|
||||||
|
oSelf.$wrapper.append(oSelf.$buttonAdd);
|
||||||
|
if(oSelf.settings.hasOwnProperty('onAdd')) {
|
||||||
|
oSelf.on('add', oSelf.settings['onAdd']);
|
||||||
|
oSelf.$buttonAdd.on('click', function(){
|
||||||
|
oSelf.trigger( "add");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
oSelf.$buttonAdd.css({
|
||||||
|
opacity: .5,
|
||||||
|
cursor: 'default'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
});
|
||||||
62
js/selectize/plugin_combodo_auto_position.js
Normal file
62
js/selectize/plugin_combodo_auto_position.js
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
Selectize.define("combodo_auto_position", function (aOptions) {
|
||||||
|
|
||||||
|
// Selectize instance
|
||||||
|
let oSelf = this;
|
||||||
|
|
||||||
|
// Plugin options
|
||||||
|
aOptions = $.extend({
|
||||||
|
maxDropDownHeight: 200,
|
||||||
|
},
|
||||||
|
aOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
// override settings
|
||||||
|
oSelf.settings.dropdownParent = 'body';
|
||||||
|
|
||||||
|
// Override position dropdown function
|
||||||
|
oSelf.positionDropdown = (function () {
|
||||||
|
return function () {
|
||||||
|
let iRefHeight = oSelf.$dropdown.outerHeight() < aOptions.maxDropDownHeight ?
|
||||||
|
oSelf.$dropdown.outerHeight() : aOptions.maxDropDownHeight;
|
||||||
|
|
||||||
|
if(oSelf.$control.offset().top + oSelf.$control.outerHeight() + iRefHeight > window.innerHeight){
|
||||||
|
|
||||||
|
oSelf.$dropdown.css({
|
||||||
|
top: oSelf.$control.offset().top - iRefHeight,
|
||||||
|
left: oSelf.$control.offset().left,
|
||||||
|
width: oSelf.$wrapper.outerWidth(),
|
||||||
|
'max-height': `${aOptions.maxDropDownHeight}px`,
|
||||||
|
'overflow-y': 'auto',
|
||||||
|
'border-top': '1px solid #d0d0d0',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
oSelf.$dropdown.css({
|
||||||
|
top: oSelf.$control.offset().top + oSelf.$control.outerHeight(),
|
||||||
|
left: oSelf.$control.offset().left,
|
||||||
|
width: oSelf.$wrapper.outerWidth(),
|
||||||
|
'max-height': `${aOptions.maxDropDownHeight}px`,
|
||||||
|
'overflow-y': 'auto'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
|
||||||
|
});
|
||||||
280
js/selectize/plugin_combodo_multi_values_synthesis.js
Normal file
280
js/selectize/plugin_combodo_multi_values_synthesis.js
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
Selectize.define("combodo_multi_values_synthesis", function (aOptions) {
|
||||||
|
|
||||||
|
// Selectize instance
|
||||||
|
let oSelf = this;
|
||||||
|
oSelf.require("combodo_update_operations");
|
||||||
|
|
||||||
|
// Plugin options
|
||||||
|
aOptions = $.extend({
|
||||||
|
tooltip_links_will_be_created_for_all_objects: 'Links will be created for all objects',
|
||||||
|
tooltip_links_will_be_deleted_from_all_objects: 'Links will be deleted from all objects',
|
||||||
|
tooltip_links_will_be_created_for_one_object: 'Links will be created for one object',
|
||||||
|
tooltip_links_will_be_deleted_from_one_object: 'Links will be deleted from one object',
|
||||||
|
tooltip_links_will_be_created_for_x_objects: 'Links will be created for {count} objects',
|
||||||
|
tooltip_links_will_be_deleted_from_x_objects: 'Links will be deleted from {count} objects',
|
||||||
|
tooltip_links_exist_for_all_objects: 'Links exist for all objects',
|
||||||
|
tooltip_links_exist_for_one_object: 'Links exist for one object',
|
||||||
|
tooltip_links_exist_for_x_objects: 'Links exist for some objects'
|
||||||
|
},
|
||||||
|
aOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
// Items operations
|
||||||
|
const OPERATIONS = {
|
||||||
|
add: 'add',
|
||||||
|
remove: 'remove',
|
||||||
|
ignore: 'ignore',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Items states css classes
|
||||||
|
const ITEMS_CLASSES = {
|
||||||
|
add: 'item-add',
|
||||||
|
remove: 'item-remove',
|
||||||
|
ignore_all: 'item-ignore-all',
|
||||||
|
ignore_partial: 'item-ignore-partial'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Local operations
|
||||||
|
let aOperations = {};
|
||||||
|
|
||||||
|
// Override addItem function
|
||||||
|
oSelf.addItem = (function () {
|
||||||
|
let oOriginal = oSelf.addItem;
|
||||||
|
return function () {
|
||||||
|
|
||||||
|
oOriginal.apply(this, arguments);
|
||||||
|
|
||||||
|
// Retrieve item and item element
|
||||||
|
const sItemValue = arguments[0];
|
||||||
|
const $Item = oSelf.getItem(sItemValue);
|
||||||
|
|
||||||
|
// Restore operation if exist and return
|
||||||
|
if(typeof(aOperations[sItemValue]) !== 'undefined'){
|
||||||
|
if(aOperations[sItemValue] === OPERATIONS.add){
|
||||||
|
oSelf.Add($Item, sItemValue);
|
||||||
|
}
|
||||||
|
else if(aOperations[sItemValue] === OPERATIONS.remove){
|
||||||
|
oSelf.Remove($Item, sItemValue);
|
||||||
|
}
|
||||||
|
else if(aOperations[sItemValue] === OPERATIONS.ignore){
|
||||||
|
oSelf.Ignore($Item, sItemValue);
|
||||||
|
}
|
||||||
|
// Element exist in default selection,
|
||||||
|
// click allow user to switch between add or ignore states
|
||||||
|
if(oSelf.settings.initial.includes(sItemValue)) {
|
||||||
|
oSelf.listenClick($Item, sItemValue);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no operation to restore
|
||||||
|
if(!oSelf.settings.initial.includes(sItemValue)) {
|
||||||
|
|
||||||
|
// Element doesn't exist in initial value, we mark it as added
|
||||||
|
oSelf.Add($Item, sItemValue);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
// Element exist, we restore it
|
||||||
|
oSelf.Ignore($Item, sItemValue);
|
||||||
|
|
||||||
|
// Element exist in default selection,
|
||||||
|
// click allow user to switch between add or ignore states
|
||||||
|
oSelf.listenClick($Item, sItemValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Override removeItem function
|
||||||
|
oSelf.removeItem = (function () {
|
||||||
|
let oOriginal = oSelf.removeItem;
|
||||||
|
return function () {
|
||||||
|
|
||||||
|
// Retrieve item and item element
|
||||||
|
const sItem = arguments[0];
|
||||||
|
const $Item = oSelf.getItem(sItem);
|
||||||
|
|
||||||
|
// Element doesn't exist in default selection,
|
||||||
|
if(!oSelf.settings.initial.includes(sItem)) {
|
||||||
|
|
||||||
|
// Remove operation
|
||||||
|
delete aOperations[sItem];
|
||||||
|
|
||||||
|
// Call original remove function (element will be removed of the input)
|
||||||
|
oOriginal.apply(this, arguments);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
// Store remove operation (element will NOT be removed)
|
||||||
|
oSelf.Remove($Item, sItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Override updateOperations function
|
||||||
|
oSelf.updateOperations = (function () {
|
||||||
|
let oOriginal = oSelf.updateOperations;
|
||||||
|
return function () {
|
||||||
|
|
||||||
|
// Call original updateOperations function
|
||||||
|
oOriginal.apply(this, arguments);
|
||||||
|
|
||||||
|
// Iterate throw local operations...
|
||||||
|
const aCurrentOptions = Object.values(oSelf.options);
|
||||||
|
for (const [key, value] of Object.entries(aOperations)) {
|
||||||
|
oSelf.operations[key] = {
|
||||||
|
operation: value,
|
||||||
|
data: CombodoGlobalToolbox.ExtractArrayItemsContainingThisKeyAndValue(aCurrentOptions, oSelf.settings.valueField, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Declare listenClick function
|
||||||
|
oSelf.listenClick = (function () {
|
||||||
|
return function ($item, sItem) {
|
||||||
|
|
||||||
|
// Listen item element click event
|
||||||
|
$item.on('click', function(){
|
||||||
|
|
||||||
|
// If element has operation
|
||||||
|
if(aOperations[sItem] === OPERATIONS.add || aOperations[sItem] === OPERATIONS.remove) {
|
||||||
|
|
||||||
|
// Restore state
|
||||||
|
oSelf.Ignore($item, sItem);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
// No need to add
|
||||||
|
if(oSelf.options[sItem]['full'])
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Add element
|
||||||
|
oSelf.Add($item, sItem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Declare Add function
|
||||||
|
oSelf.Add = (function () {
|
||||||
|
return function ($item, sItem) {
|
||||||
|
aOperations[sItem] = OPERATIONS.add;
|
||||||
|
oSelf.updateOperationsInput();
|
||||||
|
oSelf.ResetElementClass($item);
|
||||||
|
oSelf.UpdateAllTooltip($item, sItem);
|
||||||
|
$item.addClass(ITEMS_CLASSES.add);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Declare Remove function
|
||||||
|
oSelf.Remove = (function () {
|
||||||
|
return function ($item, sItem) {
|
||||||
|
aOperations[sItem] = OPERATIONS.remove;
|
||||||
|
oSelf.updateOperationsInput();
|
||||||
|
oSelf.ResetElementClass($item);
|
||||||
|
oSelf.UpdateRemoveTooltip($item, sItem);
|
||||||
|
$item.addClass(ITEMS_CLASSES.remove);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Declare Ignore function
|
||||||
|
oSelf.Ignore = (function () {
|
||||||
|
return function ($item, sItem) {
|
||||||
|
aOperations[sItem] = OPERATIONS.ignore;
|
||||||
|
oSelf.updateOperationsInput();
|
||||||
|
oSelf.ResetElementClass($item);
|
||||||
|
oSelf.UpdateIgnoreTooltip($item, sItem);
|
||||||
|
oSelf.options[sItem]['full'] ?
|
||||||
|
$item.addClass(ITEMS_CLASSES.ignore_all) :
|
||||||
|
$item.addClass(ITEMS_CLASSES.ignore_partial);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Declare ResetElementClass function
|
||||||
|
oSelf.ResetElementClass = (function () {
|
||||||
|
return function ($item) {
|
||||||
|
$item.removeClass(Object.values(ITEMS_CLASSES));
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Update add tooltip
|
||||||
|
oSelf.UpdateAllTooltip = (function () {
|
||||||
|
return function ($item, sItem) {
|
||||||
|
const iOccurrence = oSelf.options[sItem]['occurrence'];
|
||||||
|
let sTooltip = '';
|
||||||
|
if(oSelf.options[sItem]['empty']){
|
||||||
|
sTooltip = aOptions.tooltip_links_will_be_created_for_all_objects;
|
||||||
|
}
|
||||||
|
else if(iOccurrence === '1'){
|
||||||
|
sTooltip = aOptions.tooltip_links_will_be_created_for_one_object;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sTooltip = aOptions.tooltip_links_will_be_created_for_x_objects.replaceAll('{count}', iOccurrence);
|
||||||
|
}
|
||||||
|
oSelf.CreateTooltip($item, sItem, sTooltip);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Update remove tooltip
|
||||||
|
oSelf.UpdateRemoveTooltip = (function () {
|
||||||
|
return function ($item, sItem) {
|
||||||
|
const iOccurrence = oSelf.options[sItem]['occurrence'];
|
||||||
|
let sTooltip = '';
|
||||||
|
if(oSelf.options[sItem]['full']){
|
||||||
|
sTooltip = aOptions.tooltip_links_will_be_deleted_from_all_objects;
|
||||||
|
}
|
||||||
|
else if(oSelf.options[sItem]['occurrence'] === '1'){
|
||||||
|
sTooltip = aOptions.tooltip_links_will_be_deleted_from_one_object;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sTooltip = aOptions.tooltip_links_will_be_deleted_from_x_objects.replaceAll('{count}', iOccurrence);
|
||||||
|
}
|
||||||
|
oSelf.CreateTooltip($item, sItem, sTooltip);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Update ignore tooltip
|
||||||
|
oSelf.UpdateIgnoreTooltip = (function () {
|
||||||
|
return function ($item, sItem) {
|
||||||
|
const iOccurrence = oSelf.options[sItem]['occurrence'];
|
||||||
|
let sTooltip = '';
|
||||||
|
if(oSelf.options[sItem]['full']){
|
||||||
|
sTooltip = aOptions.tooltip_links_exist_for_all_objects;
|
||||||
|
}
|
||||||
|
else if(iOccurrence === '1'){
|
||||||
|
sTooltip = aOptions.tooltip_links_exist_for_one_object;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sTooltip = aOptions.tooltip_links_exist_for_x_objects.replaceAll('{count}', iOccurrence);
|
||||||
|
}
|
||||||
|
oSelf.CreateTooltip($item, sItem, sTooltip);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Update ignore tooltip
|
||||||
|
oSelf.CreateTooltip = (function () {
|
||||||
|
return function ($item, sItem, sTooltip) {
|
||||||
|
$item.attr('data-tooltip-content', oSelf.options[sItem][this.settings.tooltipField] + '<br><span class="ibo-linked-set--bulk-tooltip-info">' + sTooltip + '</span>');
|
||||||
|
$item.attr('data-tooltip-html-enabled', true);
|
||||||
|
CombodoTooltip.InitTooltipFromMarkup($item, true);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
});
|
||||||
112
js/selectize/plugin_combodo_update_operations.js
Normal file
112
js/selectize/plugin_combodo_update_operations.js
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
Selectize.define("combodo_update_operations", function () {
|
||||||
|
|
||||||
|
// Selectize instance
|
||||||
|
let oSelf = this;
|
||||||
|
|
||||||
|
// Plugin variables
|
||||||
|
oSelf.bIsInitialized = false;
|
||||||
|
oSelf.operations = {};
|
||||||
|
|
||||||
|
// Override setup function
|
||||||
|
oSelf.setup = (function () {
|
||||||
|
let oOriginal = oSelf.setup;
|
||||||
|
return function () {
|
||||||
|
oOriginal.apply(oSelf, arguments);
|
||||||
|
oSelf.$operationsInput = $(`<input type="hidden" value="{}" name="${oSelf.$input.attr('name')}_operations">`)
|
||||||
|
oSelf.$wrapper.append(oSelf.$operationsInput);
|
||||||
|
oSelf.bIsInitialized = true;
|
||||||
|
oSelf.updateOperationsInput();
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Override addItem function
|
||||||
|
oSelf.addItem = (function () {
|
||||||
|
let oOriginal = oSelf.addItem;
|
||||||
|
return function () {
|
||||||
|
oOriginal.apply(this, arguments);
|
||||||
|
if(oSelf.bIsInitialized && !arguments[1]){
|
||||||
|
this.updateOperationsInput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Override removeItem function
|
||||||
|
oSelf.removeItem = (function () {
|
||||||
|
let oOriginal = oSelf.removeItem;
|
||||||
|
return function () {
|
||||||
|
oOriginal.apply(this, arguments);
|
||||||
|
if(oSelf.bIsInitialized){
|
||||||
|
this.updateOperationsInput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Declare updateOperationsInput function
|
||||||
|
oSelf.updateOperationsInput = (function () {
|
||||||
|
return function () {
|
||||||
|
|
||||||
|
// update operations
|
||||||
|
oSelf.updateOperations();
|
||||||
|
|
||||||
|
// setup in progress
|
||||||
|
if(typeof(oSelf.$operationsInput) === 'undefined'){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update operations input
|
||||||
|
oSelf.$operationsInput.val(JSON.stringify(oSelf.operations));
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Declare updateOperations function
|
||||||
|
oSelf.updateOperations = (function () {
|
||||||
|
return function () {
|
||||||
|
|
||||||
|
// Reset operations
|
||||||
|
oSelf.operations = {};
|
||||||
|
|
||||||
|
// Reference data
|
||||||
|
const aCurrentItems = Object.values(oSelf.items);
|
||||||
|
const aCurrentOptions = Object.values(oSelf.options);
|
||||||
|
|
||||||
|
// Scan items in current value and not in initial value
|
||||||
|
aCurrentItems.forEach(function(e){
|
||||||
|
if(!oSelf.settings.initial.includes(e)){
|
||||||
|
oSelf.operations[e] = {
|
||||||
|
operation: 'add',
|
||||||
|
data: CombodoGlobalToolbox.ExtractArrayItemsContainingThisKeyAndValue(aCurrentOptions, oSelf.settings.valueField, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// scan items in initial value and not in current value
|
||||||
|
oSelf.settings.initial.forEach(function(e){
|
||||||
|
if(!aCurrentItems.includes(e)){
|
||||||
|
oSelf.operations[e] = {
|
||||||
|
operation: 'remove',
|
||||||
|
data: CombodoGlobalToolbox.ExtractArrayItemsContainingThisKeyAndValue(aCurrentOptions, oSelf.settings.valueField, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
});
|
||||||
99
js/utils.js
99
js/utils.js
@@ -759,6 +759,105 @@ const CombodoGlobalToolbox = {
|
|||||||
oCurrentDate = new Date();
|
oCurrentDate = new Date();
|
||||||
}
|
}
|
||||||
while ((oCurrentDate - oDate) < iDuration);
|
while ((oCurrentDate - oDate) < iDuration);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a template and inject data into it.
|
||||||
|
*
|
||||||
|
* This rendering engine is aimed to produce client side template rendering.
|
||||||
|
*
|
||||||
|
* markups with attributes:
|
||||||
|
* data-template-attr-{title|name|for}: set dom element attribute with corresponding datavalue
|
||||||
|
* data-template-text: set dom element text with corresponding data value
|
||||||
|
* data-template-condition: set dom element visibility depending on data value
|
||||||
|
* data-template-css-{background-image}: set dom element css property with corresponding data value
|
||||||
|
* data-template-add-class: add class to dom element with corresponding data value
|
||||||
|
*
|
||||||
|
* @since 3.1.0
|
||||||
|
*
|
||||||
|
* @param sTemplateId
|
||||||
|
* @param aData
|
||||||
|
* @param sTemplateClass
|
||||||
|
* @returns {*|jQuery|HTMLElement|JQuery<HTMLElement>}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
RenderTemplate: function(sTemplateId, aData, sTemplateClass = null)
|
||||||
|
{
|
||||||
|
let sHtml = '<div>' + $(sTemplateId).html() + '</div>';
|
||||||
|
|
||||||
|
// Create element
|
||||||
|
let oElement = $(sHtml);
|
||||||
|
if(sTemplateClass !== null){
|
||||||
|
oElement.addClass(sTemplateClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attribute replacement
|
||||||
|
let aAttrElements = ['title', 'name', 'for'];
|
||||||
|
aAttrElements.forEach(function(e){
|
||||||
|
$(`[data-template-attr-${e}]`, oElement).each(function(){
|
||||||
|
$(this).attr(e, aData[$(this).attr(`data-template-attr-${e}`)]);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// CSS replacement
|
||||||
|
let aCssElements = ['background-image'];
|
||||||
|
aCssElements.forEach(function(e){
|
||||||
|
$(`[data-template-css-${e}]`, oElement).each(function(){
|
||||||
|
$(this).css(e, aData[$(this).attr(`data-template-css-${e}`)]);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Text replacement
|
||||||
|
$('[data-template-text]', oElement).each(function(){
|
||||||
|
$(this).text(aData[$(this).attr('data-template-text')]);
|
||||||
|
})
|
||||||
|
|
||||||
|
// Condition
|
||||||
|
$('[data-template-condition]', oElement).each(function(){
|
||||||
|
$(this).toggle(aData[$(this).attr('data-template-condition')]);
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add classes
|
||||||
|
$('[data-template-add-class]', oElement).each(function(){
|
||||||
|
$(this).addClass(aData[$(this).attr('data-template-add-class')]);
|
||||||
|
})
|
||||||
|
|
||||||
|
return oElement;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExtractArrayItemsContainingThisKeyAndValue.
|
||||||
|
*
|
||||||
|
* This function extract item(s) of an array witch include the key value pair.
|
||||||
|
*
|
||||||
|
* @since 3.1.0
|
||||||
|
*
|
||||||
|
* @param aArrayToSearchIn Array to search in
|
||||||
|
* @param sKey Key to search
|
||||||
|
* @param sValue Value to search
|
||||||
|
* @returns {*|*[]|null}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
ExtractArrayItemsContainingThisKeyAndValue: function(aArrayToSearchIn, sKey, sValue)
|
||||||
|
{
|
||||||
|
let aResult = [];
|
||||||
|
|
||||||
|
// Iterate throw items...
|
||||||
|
for(let i = 0 ; i < aArrayToSearchIn.length ; i++){
|
||||||
|
if(aArrayToSearchIn[i][sKey] === sValue){
|
||||||
|
aResult.push(aArrayToSearchIn[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return result
|
||||||
|
switch(aResult.length){
|
||||||
|
case 0:
|
||||||
|
return null;
|
||||||
|
case 1:
|
||||||
|
return aResult[0];
|
||||||
|
default:
|
||||||
|
return aResult;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ class ClassLoader
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string[] Array of classname => path
|
* @return string[] Array of classname => path
|
||||||
* @psalm-return array<string, string>
|
* @psalm-var array<string, string>
|
||||||
*/
|
*/
|
||||||
public function getClassMap()
|
public function getClassMap()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,8 +24,21 @@ use Composer\Semver\VersionParser;
|
|||||||
*/
|
*/
|
||||||
class InstalledVersions
|
class InstalledVersions
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var mixed[]|null
|
||||||
|
* @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
|
||||||
|
*/
|
||||||
private static $installed;
|
private static $installed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool|null
|
||||||
|
*/
|
||||||
private static $canGetVendors;
|
private static $canGetVendors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array[]
|
||||||
|
* @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||||
|
*/
|
||||||
private static $installedByVendor = array();
|
private static $installedByVendor = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -254,6 +254,13 @@ return array(
|
|||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\Select' => $baseDir . '/sources/Application/UI/Base/Component/Input/Select/Select.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\Select' => $baseDir . '/sources/Application/UI/Base/Component/Input/Select/Select.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\SelectOption' => $baseDir . '/sources/Application/UI/Base/Component/Input/Select/SelectOption.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\SelectOption' => $baseDir . '/sources/Application/UI/Base/Component/Input/Select/SelectOption.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\SelectOptionUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/Input/Select/SelectOptionUIBlockFactory.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\SelectOptionUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/Input/Select/SelectOptionUIBlockFactory.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\DataProvider\\AbstractDataProvider' => $baseDir . '/sources/Application/UI/Base/Component/Input/Set/DataProvider/AbstractDataProvider.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\DataProvider\\AjaxDataProvider' => $baseDir . '/sources/Application/UI/Base/Component/Input/Set/DataProvider/AjaxDataProvider.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\DataProvider\\AjaxDataProviderForOQL' => $baseDir . '/sources/Application/UI/Base/Component/Input/Set/DataProvider/AjaxDataProviderForOql.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\DataProvider\\SimpleDataProvider' => $baseDir . '/sources/Application/UI/Base/Component/Input/Set/DataProvider/SimpleDataProvider.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\DataProvider\\iDataProvider' => $baseDir . '/sources/Application/UI/Base/Component/Input/Set/DataProvider/iDataProvider.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\Set' => $baseDir . '/sources/Application/UI/Base/Component/Input/Set/Set.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\SetUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Component/Input/Set/SetUIBlockFactory.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\TextArea' => $baseDir . '/sources/Application/UI/Base/Component/Input/TextArea.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\TextArea' => $baseDir . '/sources/Application/UI/Base/Component/Input/TextArea.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\tInputLabel' => $baseDir . '/sources/Application/UI/Base/Component/Input/tInputLabel.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\tInputLabel' => $baseDir . '/sources/Application/UI/Base/Component/Input/tInputLabel.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\MedallionIcon\\MedallionIcon' => $baseDir . '/sources/Application/UI/Base/Component/MedallionIcon/MedallionIcon.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\MedallionIcon\\MedallionIcon' => $baseDir . '/sources/Application/UI/Base/Component/MedallionIcon/MedallionIcon.php',
|
||||||
@@ -349,7 +356,9 @@ return array(
|
|||||||
'Combodo\\iTop\\Application\\UI\\Links\\Direct\\BlockDirectLinksViewTable' => $baseDir . '/sources/Application/UI/Links/Direct/BlockDirectLinksViewTable.php',
|
'Combodo\\iTop\\Application\\UI\\Links\\Direct\\BlockDirectLinksViewTable' => $baseDir . '/sources/Application/UI/Links/Direct/BlockDirectLinksViewTable.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockIndirectLinksEditTable' => $baseDir . '/sources/Application/UI/Links/Indirect/BlockIndirectLinksEditTable.php',
|
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockIndirectLinksEditTable' => $baseDir . '/sources/Application/UI/Links/Indirect/BlockIndirectLinksEditTable.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockIndirectLinksViewTable' => $baseDir . '/sources/Application/UI/Links/Indirect/BlockIndirectLinksViewTable.php',
|
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockIndirectLinksViewTable' => $baseDir . '/sources/Application/UI/Links/Indirect/BlockIndirectLinksViewTable.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockLinksSetDisplayAsProperty' => $baseDir . '/sources/Application/UI/Links/Set/BlockLinksSetDisplayAsProperty.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockObjectPickerDialog' => $baseDir . '/sources/Application/UI/Links/Indirect/BlockObjectPickerDialog.php',
|
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockObjectPickerDialog' => $baseDir . '/sources/Application/UI/Links/Indirect/BlockObjectPickerDialog.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Links\\Set\\LinksSetUIBlockFactory' => $baseDir . '/sources/Application/UI/Links/Set/LinksSetUIBlockFactory.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Preferences\\BlockShortcuts\\BlockShortcuts' => $baseDir . '/sources/Application/UI/Preferences/BlockShortcuts/BlockShortcuts.php',
|
'Combodo\\iTop\\Application\\UI\\Preferences\\BlockShortcuts\\BlockShortcuts' => $baseDir . '/sources/Application/UI/Preferences/BlockShortcuts/BlockShortcuts.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Printable\\BlockPrintHeader\\BlockPrintHeader' => $baseDir . '/sources/Application/UI/Printable/BlockPrintHeader/BlockPrintHeader.php',
|
'Combodo\\iTop\\Application\\UI\\Printable\\BlockPrintHeader\\BlockPrintHeader' => $baseDir . '/sources/Application/UI/Printable/BlockPrintHeader/BlockPrintHeader.php',
|
||||||
'Combodo\\iTop\\Composer\\iTopComposer' => $baseDir . '/sources/Composer/iTopComposer.php',
|
'Combodo\\iTop\\Composer\\iTopComposer' => $baseDir . '/sources/Composer/iTopComposer.php',
|
||||||
@@ -425,12 +434,18 @@ return array(
|
|||||||
'Combodo\\iTop\\Renderer\\FormRenderer' => $baseDir . '/sources/Renderer/FormRenderer.php',
|
'Combodo\\iTop\\Renderer\\FormRenderer' => $baseDir . '/sources/Renderer/FormRenderer.php',
|
||||||
'Combodo\\iTop\\Renderer\\RenderingOutput' => $baseDir . '/sources/Renderer/RenderingOutput.php',
|
'Combodo\\iTop\\Renderer\\RenderingOutput' => $baseDir . '/sources/Renderer/RenderingOutput.php',
|
||||||
'Combodo\\iTop\\Router\\Router' => $baseDir . '/sources/Router/Router.php',
|
'Combodo\\iTop\\Router\\Router' => $baseDir . '/sources/Router/Router.php',
|
||||||
|
'Combodo\\iTop\\Service\\Base\\ObjectRepository' => $baseDir . '/sources/Service/Base/ObjectRepository.php',
|
||||||
|
'Combodo\\iTop\\Service\\Base\\iDataPostProcessor' => $baseDir . '/sources/Service/Base/iDataPostProcessor.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\Description\\EventDataDescription' => $baseDir . '/sources/Application/Service/Events/Description/EventDataDescription.php',
|
'Combodo\\iTop\\Service\\Events\\Description\\EventDataDescription' => $baseDir . '/sources/Application/Service/Events/Description/EventDataDescription.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\Description\\EventDescription' => $baseDir . '/sources/Application/Service/Events/Description/EventDescription.php',
|
'Combodo\\iTop\\Service\\Events\\Description\\EventDescription' => $baseDir . '/sources/Application/Service/Events/Description/EventDescription.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\EventData' => $baseDir . '/sources/Application/Service/Events/EventData.php',
|
'Combodo\\iTop\\Service\\Events\\EventData' => $baseDir . '/sources/Application/Service/Events/EventData.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\EventHelper' => $baseDir . '/sources/Application/Service/Events/EventHelper.php',
|
'Combodo\\iTop\\Service\\Events\\EventHelper' => $baseDir . '/sources/Application/Service/Events/EventHelper.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\EventService' => $baseDir . '/sources/Application/Service/Events/EventService.php',
|
'Combodo\\iTop\\Service\\Events\\EventService' => $baseDir . '/sources/Application/Service/Events/EventService.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\iEventServiceSetup' => $baseDir . '/sources/Application/Service/Events/iEventServiceSetup.php',
|
'Combodo\\iTop\\Service\\Events\\iEventServiceSetup' => $baseDir . '/sources/Application/Service/Events/iEventServiceSetup.php',
|
||||||
|
'Combodo\\iTop\\Service\\Links\\LinkSetDataTransformer' => $baseDir . '/sources/Service/Links/LinkSetDataTransformer.php',
|
||||||
|
'Combodo\\iTop\\Service\\Links\\LinkSetModel' => $baseDir . '/sources/Service/Links/LinkSetModel.php',
|
||||||
|
'Combodo\\iTop\\Service\\Links\\LinkSetRepository' => $baseDir . '/sources/Service/Links/LinkSetRepository.php',
|
||||||
|
'Combodo\\iTop\\Service\\Links\\LinksBulkDataPostProcessor' => $baseDir . '/sources/Service/Links/LinksBulkDataPostProcessor.php',
|
||||||
'CompileCSSService' => $baseDir . '/application/compilecssservice.class.inc.php',
|
'CompileCSSService' => $baseDir . '/application/compilecssservice.class.inc.php',
|
||||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
'Config' => $baseDir . '/core/config.class.inc.php',
|
'Config' => $baseDir . '/core/config.class.inc.php',
|
||||||
|
|||||||
@@ -60,16 +60,11 @@ class ComposerAutoloaderInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $fileIdentifier
|
|
||||||
* @param string $file
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function composerRequire7f81b4a2a468a061c306af5e447a9a9f($fileIdentifier, $file)
|
function composerRequire7f81b4a2a468a061c306af5e447a9a9f($fileIdentifier, $file)
|
||||||
{
|
{
|
||||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
|
||||||
|
|
||||||
require $file;
|
require $file;
|
||||||
|
|
||||||
|
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -619,6 +619,13 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\Select' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Select/Select.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\Select' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Select/Select.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\SelectOption' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Select/SelectOption.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\SelectOption' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Select/SelectOption.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\SelectOptionUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Select/SelectOptionUIBlockFactory.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Select\\SelectOptionUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Select/SelectOptionUIBlockFactory.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\DataProvider\\AbstractDataProvider' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Set/DataProvider/AbstractDataProvider.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\DataProvider\\AjaxDataProvider' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Set/DataProvider/AjaxDataProvider.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\DataProvider\\AjaxDataProviderForOQL' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Set/DataProvider/AjaxDataProviderForOql.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\DataProvider\\SimpleDataProvider' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Set/DataProvider/SimpleDataProvider.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\DataProvider\\iDataProvider' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Set/DataProvider/iDataProvider.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\Set' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Set/Set.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\Set\\SetUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/Set/SetUIBlockFactory.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\TextArea' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/TextArea.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\TextArea' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/TextArea.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\tInputLabel' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/tInputLabel.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\tInputLabel' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Input/tInputLabel.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\MedallionIcon\\MedallionIcon' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/MedallionIcon/MedallionIcon.php',
|
'Combodo\\iTop\\Application\\UI\\Base\\Component\\MedallionIcon\\MedallionIcon' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/MedallionIcon/MedallionIcon.php',
|
||||||
@@ -714,7 +721,9 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Combodo\\iTop\\Application\\UI\\Links\\Direct\\BlockDirectLinksViewTable' => __DIR__ . '/../..' . '/sources/Application/UI/Links/Direct/BlockDirectLinksViewTable.php',
|
'Combodo\\iTop\\Application\\UI\\Links\\Direct\\BlockDirectLinksViewTable' => __DIR__ . '/../..' . '/sources/Application/UI/Links/Direct/BlockDirectLinksViewTable.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockIndirectLinksEditTable' => __DIR__ . '/../..' . '/sources/Application/UI/Links/Indirect/BlockIndirectLinksEditTable.php',
|
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockIndirectLinksEditTable' => __DIR__ . '/../..' . '/sources/Application/UI/Links/Indirect/BlockIndirectLinksEditTable.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockIndirectLinksViewTable' => __DIR__ . '/../..' . '/sources/Application/UI/Links/Indirect/BlockIndirectLinksViewTable.php',
|
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockIndirectLinksViewTable' => __DIR__ . '/../..' . '/sources/Application/UI/Links/Indirect/BlockIndirectLinksViewTable.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockLinksSetDisplayAsProperty' => __DIR__ . '/../..' . '/sources/Application/UI/Links/Set/BlockLinksSetDisplayAsProperty.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockObjectPickerDialog' => __DIR__ . '/../..' . '/sources/Application/UI/Links/Indirect/BlockObjectPickerDialog.php',
|
'Combodo\\iTop\\Application\\UI\\Links\\Indirect\\BlockObjectPickerDialog' => __DIR__ . '/../..' . '/sources/Application/UI/Links/Indirect/BlockObjectPickerDialog.php',
|
||||||
|
'Combodo\\iTop\\Application\\UI\\Links\\Set\\LinksSetUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Links/Set/LinksSetUIBlockFactory.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Preferences\\BlockShortcuts\\BlockShortcuts' => __DIR__ . '/../..' . '/sources/Application/UI/Preferences/BlockShortcuts/BlockShortcuts.php',
|
'Combodo\\iTop\\Application\\UI\\Preferences\\BlockShortcuts\\BlockShortcuts' => __DIR__ . '/../..' . '/sources/Application/UI/Preferences/BlockShortcuts/BlockShortcuts.php',
|
||||||
'Combodo\\iTop\\Application\\UI\\Printable\\BlockPrintHeader\\BlockPrintHeader' => __DIR__ . '/../..' . '/sources/Application/UI/Printable/BlockPrintHeader/BlockPrintHeader.php',
|
'Combodo\\iTop\\Application\\UI\\Printable\\BlockPrintHeader\\BlockPrintHeader' => __DIR__ . '/../..' . '/sources/Application/UI/Printable/BlockPrintHeader/BlockPrintHeader.php',
|
||||||
'Combodo\\iTop\\Composer\\iTopComposer' => __DIR__ . '/../..' . '/sources/Composer/iTopComposer.php',
|
'Combodo\\iTop\\Composer\\iTopComposer' => __DIR__ . '/../..' . '/sources/Composer/iTopComposer.php',
|
||||||
@@ -790,12 +799,18 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Combodo\\iTop\\Renderer\\FormRenderer' => __DIR__ . '/../..' . '/sources/Renderer/FormRenderer.php',
|
'Combodo\\iTop\\Renderer\\FormRenderer' => __DIR__ . '/../..' . '/sources/Renderer/FormRenderer.php',
|
||||||
'Combodo\\iTop\\Renderer\\RenderingOutput' => __DIR__ . '/../..' . '/sources/Renderer/RenderingOutput.php',
|
'Combodo\\iTop\\Renderer\\RenderingOutput' => __DIR__ . '/../..' . '/sources/Renderer/RenderingOutput.php',
|
||||||
'Combodo\\iTop\\Router\\Router' => __DIR__ . '/../..' . '/sources/Router/Router.php',
|
'Combodo\\iTop\\Router\\Router' => __DIR__ . '/../..' . '/sources/Router/Router.php',
|
||||||
|
'Combodo\\iTop\\Service\\Base\\ObjectRepository' => __DIR__ . '/../..' . '/sources/Service/Base/ObjectRepository.php',
|
||||||
|
'Combodo\\iTop\\Service\\Base\\iDataPostProcessor' => __DIR__ . '/../..' . '/sources/Service/Base/iDataPostProcessor.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\Description\\EventDataDescription' => __DIR__ . '/../..' . '/sources/Application/Service/Events/Description/EventDataDescription.php',
|
'Combodo\\iTop\\Service\\Events\\Description\\EventDataDescription' => __DIR__ . '/../..' . '/sources/Application/Service/Events/Description/EventDataDescription.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\Description\\EventDescription' => __DIR__ . '/../..' . '/sources/Application/Service/Events/Description/EventDescription.php',
|
'Combodo\\iTop\\Service\\Events\\Description\\EventDescription' => __DIR__ . '/../..' . '/sources/Application/Service/Events/Description/EventDescription.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\EventData' => __DIR__ . '/../..' . '/sources/Application/Service/Events/EventData.php',
|
'Combodo\\iTop\\Service\\Events\\EventData' => __DIR__ . '/../..' . '/sources/Application/Service/Events/EventData.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\EventHelper' => __DIR__ . '/../..' . '/sources/Application/Service/Events/EventHelper.php',
|
'Combodo\\iTop\\Service\\Events\\EventHelper' => __DIR__ . '/../..' . '/sources/Application/Service/Events/EventHelper.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\EventService' => __DIR__ . '/../..' . '/sources/Application/Service/Events/EventService.php',
|
'Combodo\\iTop\\Service\\Events\\EventService' => __DIR__ . '/../..' . '/sources/Application/Service/Events/EventService.php',
|
||||||
'Combodo\\iTop\\Service\\Events\\iEventServiceSetup' => __DIR__ . '/../..' . '/sources/Application/Service/Events/iEventServiceSetup.php',
|
'Combodo\\iTop\\Service\\Events\\iEventServiceSetup' => __DIR__ . '/../..' . '/sources/Application/Service/Events/iEventServiceSetup.php',
|
||||||
|
'Combodo\\iTop\\Service\\Links\\LinkSetDataTransformer' => __DIR__ . '/../..' . '/sources/Service/Links/LinkSetDataTransformer.php',
|
||||||
|
'Combodo\\iTop\\Service\\Links\\LinkSetModel' => __DIR__ . '/../..' . '/sources/Service/Links/LinkSetModel.php',
|
||||||
|
'Combodo\\iTop\\Service\\Links\\LinkSetRepository' => __DIR__ . '/../..' . '/sources/Service/Links/LinkSetRepository.php',
|
||||||
|
'Combodo\\iTop\\Service\\Links\\LinksBulkDataPostProcessor' => __DIR__ . '/../..' . '/sources/Service/Links/LinksBulkDataPostProcessor.php',
|
||||||
'CompileCSSService' => __DIR__ . '/../..' . '/application/compilecssservice.class.inc.php',
|
'CompileCSSService' => __DIR__ . '/../..' . '/application/compilecssservice.class.inc.php',
|
||||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
'Config' => __DIR__ . '/../..' . '/core/config.class.inc.php',
|
'Config' => __DIR__ . '/../..' . '/core/config.class.inc.php',
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
'type' => 'project',
|
'type' => 'project',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'reference' => '1cac1890774b4defa212a142f88348f2f8743f4c',
|
'reference' => '9482139b5aec9978f05b1cbb0542b24c18681819',
|
||||||
'name' => 'combodo/itop',
|
'name' => 'combodo/itop',
|
||||||
'dev' => true,
|
'dev' => true,
|
||||||
),
|
),
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
'type' => 'project',
|
'type' => 'project',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'reference' => '1cac1890774b4defa212a142f88348f2f8743f4c',
|
'reference' => '9482139b5aec9978f05b1cbb0542b24c18681819',
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'combodo/tcpdf' => array(
|
'combodo/tcpdf' => array(
|
||||||
|
|||||||
@@ -1499,6 +1499,14 @@ EOF;
|
|||||||
$aParameters['count_max'] = $this->GetPropNumber($oField, 'count_max', 0);
|
$aParameters['count_max'] = $this->GetPropNumber($oField, 'count_max', 0);
|
||||||
$aParameters['duplicates'] = $this->GetPropBoolean($oField, 'duplicates', false);
|
$aParameters['duplicates'] = $this->GetPropBoolean($oField, 'duplicates', false);
|
||||||
$aParameters['depends_on'] = $sDependencies;
|
$aParameters['depends_on'] = $sDependencies;
|
||||||
|
$aParameters['display_style'] = $this->GetPropString($oField, 'display_style');
|
||||||
|
if ($sOql = $oField->GetChildText('filter')) {
|
||||||
|
$sEscapedOql = self::QuoteForPHP($sOql);
|
||||||
|
$aParameters['allowed_values'] = "new ValueSetObjects($sEscapedOql)";
|
||||||
|
} else {
|
||||||
|
$aParameters['allowed_values'] = 'null';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
elseif ($sAttType == 'AttributeLinkedSet')
|
elseif ($sAttType == 'AttributeLinkedSet')
|
||||||
{
|
{
|
||||||
@@ -1506,6 +1514,7 @@ EOF;
|
|||||||
$aParameters['ext_key_to_me'] = $this->GetMandatoryPropString($oField, 'ext_key_to_me');
|
$aParameters['ext_key_to_me'] = $this->GetMandatoryPropString($oField, 'ext_key_to_me');
|
||||||
$aParameters['count_min'] = $this->GetPropNumber($oField, 'count_min', 0);
|
$aParameters['count_min'] = $this->GetPropNumber($oField, 'count_min', 0);
|
||||||
$aParameters['count_max'] = $this->GetPropNumber($oField, 'count_max', 0);
|
$aParameters['count_max'] = $this->GetPropNumber($oField, 'count_max', 0);
|
||||||
|
$aParameters['display_style'] = $this->GetPropString($oField, 'display_style');
|
||||||
$sEditMode = $oField->GetChildText('edit_mode');
|
$sEditMode = $oField->GetChildText('edit_mode');
|
||||||
if (!is_null($sEditMode))
|
if (!is_null($sEditMode))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -384,6 +384,7 @@
|
|||||||
<xsd:element name="ext_key_to_me" type="xsd:string"/>
|
<xsd:element name="ext_key_to_me" type="xsd:string"/>
|
||||||
<xsd:element name="count_min" type="xsd:string"/>
|
<xsd:element name="count_min" type="xsd:string"/>
|
||||||
<xsd:element name="count_max" type="xsd:string"/>
|
<xsd:element name="count_max" type="xsd:string"/>
|
||||||
|
<xsd:element name="display_style" type="xsd:string" minOccurs="0"/>
|
||||||
</xsd:sequence>
|
</xsd:sequence>
|
||||||
</xsd:extension>
|
</xsd:extension>
|
||||||
</xsd:complexContent>
|
</xsd:complexContent>
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
<?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\Base\Component\Input\Set\DataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AbstractDataProvider
|
||||||
|
*
|
||||||
|
* @package Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
abstract class AbstractDataProvider implements iDataProvider
|
||||||
|
{
|
||||||
|
/** @var string $sDataValueField Field used for input value */
|
||||||
|
private string $sDataValueField;
|
||||||
|
|
||||||
|
/** @var string $sDataLabelField Field used for label rendering */
|
||||||
|
private string $sDataLabelField;
|
||||||
|
|
||||||
|
/** @var array $aDataSearchFields Fields used for search engine */
|
||||||
|
private array $aDataSearchFields;
|
||||||
|
|
||||||
|
/** @var string|null $sGroupField Field used for grouping options */
|
||||||
|
private ?string $sGroupField;
|
||||||
|
|
||||||
|
/** @var string|null $sTooltipField Field used for item tooltip */
|
||||||
|
private ?string $sTooltipField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
$this->Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function Init()
|
||||||
|
{
|
||||||
|
$this->sDataLabelField = 'label';
|
||||||
|
$this->sDataValueField = 'value';
|
||||||
|
$this->aDataSearchFields = ['search'];
|
||||||
|
$this->sGroupField = null;
|
||||||
|
$this->sTooltipField = 'label';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function GetDataValueField(): string
|
||||||
|
{
|
||||||
|
return $this->sDataValueField;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function SetDataValueField(string $sField): AbstractDataProvider
|
||||||
|
{
|
||||||
|
$this->sDataValueField = $sField;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function GetDataLabelField(): string
|
||||||
|
{
|
||||||
|
return $this->sDataLabelField;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function SetDataLabelField(string $sField): AbstractDataProvider
|
||||||
|
{
|
||||||
|
$this->sDataLabelField = $sField;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function GetDataSearchFields(): array
|
||||||
|
{
|
||||||
|
return $this->aDataSearchFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function SetDataSearchFields(array $aFields): AbstractDataProvider
|
||||||
|
{
|
||||||
|
$this->aDataSearchFields = $aFields;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function GetGroupField(): ?string
|
||||||
|
{
|
||||||
|
return $this->sGroupField;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function SetGroupField(string $sField): iDataProvider
|
||||||
|
{
|
||||||
|
$this->sGroupField = $sField;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function GetTooltipField(): ?string
|
||||||
|
{
|
||||||
|
return $this->sTooltipField;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function SetTooltipField(string $sField): iDataProvider
|
||||||
|
{
|
||||||
|
$this->sTooltipField = $sField;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsAjaxProviderType.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function IsAjaxProviderType(): bool
|
||||||
|
{
|
||||||
|
return $this->GetType() === iDataProvider::TYPE_AJAX_PROVIDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsSimpleProviderType.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function IsSimpleProviderType(): bool
|
||||||
|
{
|
||||||
|
return $this->GetType() === iDataProvider::TYPE_SIMPLE_PROVIDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
<?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\Base\Component\Input\Set\DataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AjaxDataProvider
|
||||||
|
*
|
||||||
|
* @package Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
class AjaxDataProvider extends SimpleDataProvider
|
||||||
|
{
|
||||||
|
/** @var int DEFAULT_MAX_RESULTS maximum results fetched */
|
||||||
|
const DEFAULT_MAX_RESULTS = 25;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see \Combodo\iTop\Router\Router
|
||||||
|
* @var string $sAjaxRoute Router route name
|
||||||
|
*/
|
||||||
|
private string $sRoute;
|
||||||
|
|
||||||
|
/** @var array $aParams Query string params */
|
||||||
|
private array $aParams = [];
|
||||||
|
|
||||||
|
/** @var array $aPostParams Post params */
|
||||||
|
private array $aPostParams = [];
|
||||||
|
|
||||||
|
/** @var int $iMaxResults Maximum entries */
|
||||||
|
private int $iMaxResults = AjaxDataProvider::DEFAULT_MAX_RESULTS;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param string $sRoute Router route name
|
||||||
|
* @param array $aParams Query string params
|
||||||
|
* @param array $aPostParams Post params
|
||||||
|
*/
|
||||||
|
public function __construct(string $sRoute, array $aParams = [], array $aPostParams = [])
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
// Retrieve parameters
|
||||||
|
$this->sRoute = $sRoute;
|
||||||
|
$this->aParams = $aParams;
|
||||||
|
$this->aPostParams = $aPostParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function GetType(): string
|
||||||
|
{
|
||||||
|
return iDataProvider::TYPE_AJAX_PROVIDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetParam.
|
||||||
|
*
|
||||||
|
* @param string $sName
|
||||||
|
* @param string $sValue
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetParam(string $sName, string $sValue): AjaxDataProvider
|
||||||
|
{
|
||||||
|
$this->aParams[$sName] = $sValue;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetParam.
|
||||||
|
*
|
||||||
|
* @param string $sName
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetParam(string $sName): string
|
||||||
|
{
|
||||||
|
return $this->aParams[$sName];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetParams.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function GetParams(): array
|
||||||
|
{
|
||||||
|
return $this->aParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetParamsAsQueryString.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetParamsAsQueryString(): string
|
||||||
|
{
|
||||||
|
$aFlattened = $this->aParams;
|
||||||
|
array_walk($aFlattened, function (&$sValue, $key) {
|
||||||
|
$sValue = "{$key}={$sValue}";
|
||||||
|
});
|
||||||
|
|
||||||
|
return '&'.implode('&', $aFlattened);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetPostParamsAsJsonString.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetPostParamsAsJsonString(): string
|
||||||
|
{
|
||||||
|
return json_encode($this->aPostParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetPostParam.
|
||||||
|
*
|
||||||
|
* @param string $sName
|
||||||
|
* @param $oValue
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetPostParam(string $sName, $oValue): AjaxDataProvider
|
||||||
|
{
|
||||||
|
$this->aPostParams[$sName] = $oValue;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetRoute.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function GetRoute(): string
|
||||||
|
{
|
||||||
|
return $this->sRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return maximum results count.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function GetMaxResults(): int
|
||||||
|
{
|
||||||
|
return $this->iMaxResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<?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\Base\Component\Input\Set\DataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AjaxDataProviderForOQL
|
||||||
|
*
|
||||||
|
* @package Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
class AjaxDataProviderForOQL extends AjaxDataProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param string $sObjectClass Db Object class
|
||||||
|
* @param string $sOql Oql
|
||||||
|
* @param string|null $sWizardHelperJsVarName Wizard helper name
|
||||||
|
* @param array $aFieldsToLoad Array of fields to load
|
||||||
|
*/
|
||||||
|
public function __construct(string $sObjectClass, string $sOql, string $sWizardHelperJsVarName = null, array $aFieldsToLoad = [])
|
||||||
|
{
|
||||||
|
parent::__construct('object.search', [
|
||||||
|
'object_class' => $sObjectClass,
|
||||||
|
'oql' => $sOql,
|
||||||
|
'fields_to_load' => json_encode($aFieldsToLoad),
|
||||||
|
], [
|
||||||
|
'this_object_data' => $sWizardHelperJsVarName != null ? "EVAL_JAVASCRIPT{{$sWizardHelperJsVarName}.UpdateWizardToJSON();}" : "",
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
$this->Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function Init()
|
||||||
|
{
|
||||||
|
$this->SetDataLabelField('friendlyname')
|
||||||
|
->SetDataValueField('key')
|
||||||
|
->SetDataSearchFields(['friendlyname', 'additional_field']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<?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\Base\Component\Input\Set\DataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SimpleDataProvider
|
||||||
|
*
|
||||||
|
* @package Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
class SimpleDataProvider extends AbstractDataProvider
|
||||||
|
{
|
||||||
|
/** @var array $aOptions */
|
||||||
|
private array $aOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param array $aOptions
|
||||||
|
*/
|
||||||
|
public function __construct(array $aOptions = [])
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
// retrieve parameters
|
||||||
|
$this->SetOptions($aOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function GetType(): string
|
||||||
|
{
|
||||||
|
return iDataProvider::TYPE_SIMPLE_PROVIDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function SetOptions(array $aOptions): SimpleDataProvider
|
||||||
|
{
|
||||||
|
$this->aOptions = $aOptions;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function SetOption(string $sKey, string $sValue): SimpleDataProvider
|
||||||
|
{
|
||||||
|
$this->aOptions[$sKey] = $sValue;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
public function GetOptions(): array
|
||||||
|
{
|
||||||
|
return $this->aOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetOptionsGroups.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function GetOptionsGroups(): array
|
||||||
|
{
|
||||||
|
$aGroups = [];
|
||||||
|
if ($this->GetGroupField() != null) {
|
||||||
|
foreach ($this->GetOptions() as $aOption) {
|
||||||
|
if (array_key_exists($this->GetGroupField(), $aOption)) {
|
||||||
|
$aGroups[$aOption[$this->GetGroupField()]] = [
|
||||||
|
'label' => $aOption[$this->GetGroupField()],
|
||||||
|
'value' => $aOption[$this->GetGroupField()],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_values($aGroups);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
<?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\Base\Component\Input\Set\DataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface iDataProvider
|
||||||
|
*
|
||||||
|
* @package Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
interface iDataProvider
|
||||||
|
{
|
||||||
|
public const TYPE_AJAX_PROVIDER = "AJAX_PROVIDER";
|
||||||
|
public const TYPE_SIMPLE_PROVIDER = "SIMPLE_PROVIDER";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetType.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetType(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetOptions.
|
||||||
|
*
|
||||||
|
* @param array $aOptions
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetOptions(array $aOptions): iDataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetOption.
|
||||||
|
*
|
||||||
|
* @param string $sKey
|
||||||
|
* @param string $sValue
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetOption(string $sKey, string $sValue): iDataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetOptions.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function GetOptions(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetDataValueField.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetDataValueField(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetDataValueField.
|
||||||
|
*
|
||||||
|
* @param string $sField
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetDataValueField(string $sField): iDataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetDataLabelField.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetDataLabelField(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetDataLabelField.
|
||||||
|
*
|
||||||
|
* @param string $sField
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetDataLabelField(string $sField): iDataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetDataSearchFields.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function GetDataSearchFields(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetDataSearchFields.
|
||||||
|
*
|
||||||
|
* @param array $aFields
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetDataSearchFields(array $aFields): iDataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetGroupField.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function GetGroupField(): ?string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetGroupField.
|
||||||
|
*
|
||||||
|
* @param string $sField
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetGroupField(string $sField): iDataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetTooltipField.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function GetTooltipField(): ?string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetTooltipField.
|
||||||
|
*
|
||||||
|
* @param string $sField
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetTooltipField(string $sField): iDataProvider;
|
||||||
|
}
|
||||||
397
sources/Application/UI/Base/Component/Input/Set/Set.php
Normal file
397
sources/Application/UI/Base/Component/Input/Set/Set.php
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
<?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\Base\Component\Input\Set;
|
||||||
|
|
||||||
|
use Combodo\iTop\Application\UI\Base\Component\Input\AbstractInput;
|
||||||
|
use Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider\iDataProvider;
|
||||||
|
use Dict;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Set
|
||||||
|
*
|
||||||
|
* @package Combodo\iTop\Application\UI\Base\Component\Input\Set
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
class Set extends AbstractInput
|
||||||
|
{
|
||||||
|
// Overloaded constants
|
||||||
|
public const BLOCK_CODE = 'ibo-set';
|
||||||
|
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/components/input/set/layout';
|
||||||
|
public const DEFAULT_JS_ON_READY_TEMPLATE_REL_PATH = 'base/components/input/set/layout';
|
||||||
|
|
||||||
|
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||||
|
'js/selectize/plugin_combodo_add_button.js',
|
||||||
|
'js/selectize/plugin_combodo_auto_position.js',
|
||||||
|
'js/selectize/plugin_combodo_update_operations.js',
|
||||||
|
'js/selectize/plugin_combodo_multi_values_synthesis.js',
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @var int|null $iMaxItems Maximum number of items selectable */
|
||||||
|
private ?int $iMaxItems;
|
||||||
|
|
||||||
|
/** @var int|null $iMaxItem Maximum number of displayed options */
|
||||||
|
private ?int $iMaxOptions;
|
||||||
|
|
||||||
|
/** @var bool $bHasRemoveItemButton Enable remove item button */
|
||||||
|
private bool $bHasRemoveItemButton;
|
||||||
|
|
||||||
|
/** @var bool $bHasAddOptionButton Enable add option button */
|
||||||
|
private bool $bHasAddOptionButton;
|
||||||
|
|
||||||
|
/** @var string $sAddButtonTitle Add button title */
|
||||||
|
private string $sAddButtonTitle;
|
||||||
|
|
||||||
|
/** @var bool $bIsPreloadEnabled Load data at initialization (ajax data provider only) */
|
||||||
|
private bool $bIsPreloadEnabled;
|
||||||
|
|
||||||
|
/** @var string|null $sTemplateOptions Template for rendering options in dropdown (twig) */
|
||||||
|
private ?string $sTemplateOptions;
|
||||||
|
|
||||||
|
/** @var string|null $sTemplateItems Template for rendering items in input (twig) */
|
||||||
|
private ?string $sTemplateItems;
|
||||||
|
|
||||||
|
/** @var \Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider\iDataProvider $oDataProvider Set data provider */
|
||||||
|
private iDataProvider $oDataProvider;
|
||||||
|
|
||||||
|
/** @var bool $bIsMultiValuesSynthesis Used for bulk modify for example */
|
||||||
|
private bool $bIsMultiValuesSynthesis;
|
||||||
|
|
||||||
|
/** @var bool $bHasError Error flag */
|
||||||
|
private bool $bHasError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param string|null $sId Block identifier
|
||||||
|
*/
|
||||||
|
public function __construct(string $sId = null)
|
||||||
|
{
|
||||||
|
parent::__construct($sId);
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
$this->Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function Init()
|
||||||
|
{
|
||||||
|
$this->SetValue('[]');
|
||||||
|
// @todo BDA placeholder depending on autocomplete activation (search...., click to add...)
|
||||||
|
$this->SetPlaceholder(Dict::S('Core:AttributeSet:placeholder'));
|
||||||
|
$this->iMaxItems = null;
|
||||||
|
$this->iMaxOptions = null;
|
||||||
|
$this->bHasRemoveItemButton = true;
|
||||||
|
$this->bHasAddOptionButton = false;
|
||||||
|
$this->sAddButtonTitle = Dict::S('UI:Button:Create');
|
||||||
|
$this->bIsPreloadEnabled = false;
|
||||||
|
$this->sTemplateOptions = null;
|
||||||
|
$this->sTemplateItems = null;
|
||||||
|
$this->bIsMultiValuesSynthesis = false;
|
||||||
|
$this->bHasError = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetMaxItems.
|
||||||
|
*
|
||||||
|
* @param int|null $iMaxItems
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetMaxItems(?int $iMaxItems): Set
|
||||||
|
{
|
||||||
|
$this->iMaxItems = $iMaxItems;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetMaxItems.
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
public function GetMaxItems(): ?int
|
||||||
|
{
|
||||||
|
return $this->iMaxItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetMaxOptions.
|
||||||
|
*
|
||||||
|
* @param int|null $iMaxOptions
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetMaxOptions(?int $iMaxOptions): Set
|
||||||
|
{
|
||||||
|
$this->iMaxOptions = $iMaxOptions;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetMaxOptions.
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
public function GetMaxOptions(): ?int
|
||||||
|
{
|
||||||
|
return $this->iMaxOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetHasRemoveItemButton.
|
||||||
|
*
|
||||||
|
* @param bool $bHasRemoveItemButton
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetHasRemoveItemButton(bool $bHasRemoveItemButton): Set
|
||||||
|
{
|
||||||
|
$this->bHasRemoveItemButton = $bHasRemoveItemButton;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HasRemoveItemButton.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function HasRemoveItemButton(): bool
|
||||||
|
{
|
||||||
|
return $this->bHasRemoveItemButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetHasAddOptionButton.
|
||||||
|
*
|
||||||
|
* @param bool $bHasAddOptionButton
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetHasAddOptionButton(bool $bHasAddOptionButton): Set
|
||||||
|
{
|
||||||
|
$this->bHasAddOptionButton = $bHasAddOptionButton;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HasAddOptionButton.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function HasAddOptionButton(): bool
|
||||||
|
{
|
||||||
|
return $this->bHasAddOptionButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetAddButtonTitle.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetAddButtonTitle(): string
|
||||||
|
{
|
||||||
|
return $this->sAddButtonTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetAddButtonTitle.
|
||||||
|
*
|
||||||
|
* @param string $sTitle
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetAddButtonTitle(string $sTitle): Set
|
||||||
|
{
|
||||||
|
$this->sAddButtonTitle = $sTitle;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetPreloadEnabled.
|
||||||
|
*
|
||||||
|
* @param bool $bEnabled
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetPreloadEnabled(bool $bEnabled): Set
|
||||||
|
{
|
||||||
|
$this->bIsPreloadEnabled = $bEnabled;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsPreloadEnabled.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function IsPreloadEnabled(): bool
|
||||||
|
{
|
||||||
|
return $this->bIsPreloadEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetOptionsTemplate.
|
||||||
|
*
|
||||||
|
* @param string $sTemplate
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetOptionsTemplate(string $sTemplate): Set
|
||||||
|
{
|
||||||
|
$this->sTemplateOptions = $sTemplate;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return options template.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetOptionsTemplate(): ?string
|
||||||
|
{
|
||||||
|
return $this->sTemplateOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HasOptionsTemplate.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function HasOptionsTemplate(): bool
|
||||||
|
{
|
||||||
|
return $this->sTemplateOptions != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetItemsTemplate.
|
||||||
|
*
|
||||||
|
* @param string $sTemplate
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetItemsTemplate(string $sTemplate): Set
|
||||||
|
{
|
||||||
|
$this->sTemplateItems = $sTemplate;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return items template.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetItemsTemplate(): ?string
|
||||||
|
{
|
||||||
|
return $this->sTemplateItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HasItemsTemplate.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function HasItemsTemplate(): bool
|
||||||
|
{
|
||||||
|
return $this->sTemplateItems != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetDataProvider.
|
||||||
|
*
|
||||||
|
* @param \Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider\iDataProvider $oDataProvider
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetDataProvider(iDataProvider $oDataProvider): Set
|
||||||
|
{
|
||||||
|
$this->oDataProvider = $oDataProvider;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get data provider.
|
||||||
|
*
|
||||||
|
* @return iDataProvider
|
||||||
|
*/
|
||||||
|
public function GetDataProvider(): iDataProvider
|
||||||
|
{
|
||||||
|
return $this->oDataProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetIsMultiValuesSynthesis.
|
||||||
|
*
|
||||||
|
* @param bool $bIsMultiValuesSynthesis
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetIsMultiValuesSynthesis(bool $bIsMultiValuesSynthesis): Set
|
||||||
|
{
|
||||||
|
$this->bIsMultiValuesSynthesis = $bIsMultiValuesSynthesis;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsMultiValuesSynthesis.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function IsMultiValuesSynthesis(): bool
|
||||||
|
{
|
||||||
|
return $this->bIsMultiValuesSynthesis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetHasError.
|
||||||
|
*
|
||||||
|
* @param $bHasError
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function SetHasError($bHasError): Set
|
||||||
|
{
|
||||||
|
$this->bHasError = $bHasError;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HasError.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function HasError(): bool
|
||||||
|
{
|
||||||
|
return $this->bHasError;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
<?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\Base\Component\Input\Set;
|
||||||
|
|
||||||
|
use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory;
|
||||||
|
use Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider\AjaxDataProvider;
|
||||||
|
use Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider\AjaxDataProviderForOQL;
|
||||||
|
use Combodo\iTop\Application\UI\Base\Component\Input\Set\DataProvider\SimpleDataProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SetUIBlockFactory
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*
|
||||||
|
* @since 3.1.0
|
||||||
|
* @package Combodo\iTop\Application\UI\Base\Component\Input\Set
|
||||||
|
*/
|
||||||
|
class SetUIBlockFactory extends AbstractUIBlockFactory
|
||||||
|
{
|
||||||
|
/** @inheritDoc */
|
||||||
|
public const TWIG_TAG_NAME = 'UISet';
|
||||||
|
/** @inheritDoc */
|
||||||
|
public const UI_BLOCK_CLASS_NAME = Set::class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MakeForSimple.
|
||||||
|
*
|
||||||
|
* Create a simple set base on a static array of options.
|
||||||
|
* Options array must contain label, value and search string for each option.
|
||||||
|
* Keys for each entry must be provided but can be the same.
|
||||||
|
* If a group field is provided, options will be grouped according to this setting.
|
||||||
|
*
|
||||||
|
* @param string $sId Block identifier
|
||||||
|
* @param array $aOptions Array containing options
|
||||||
|
* @param string $sLabelFields Field used for label rendering
|
||||||
|
* @param string $sValueField Field used for option value
|
||||||
|
* @param array $aSearchFields Fields used for searching
|
||||||
|
* @param string|null $sGroupField Field used for grouping
|
||||||
|
*
|
||||||
|
* @return \Combodo\iTop\Application\UI\Base\Component\Input\Set\Set
|
||||||
|
*/
|
||||||
|
public static function MakeForSimple(string $sId, array $aOptions, string $sLabelFields, string $sValueField, array $aSearchFields, ?string $sGroupField = null): Set
|
||||||
|
{
|
||||||
|
// Create set ui block
|
||||||
|
$oSetUIBlock = new Set($sId);
|
||||||
|
|
||||||
|
// Simple data provider
|
||||||
|
$oDataProvider = new SimpleDataProvider($aOptions);
|
||||||
|
$oDataProvider
|
||||||
|
->SetDataLabelField($sLabelFields)
|
||||||
|
->SetDataValueField($sValueField)
|
||||||
|
->SetDataSearchFields($aSearchFields)
|
||||||
|
->SetTooltipField($sLabelFields);
|
||||||
|
if ($sGroupField != null) {
|
||||||
|
$oDataProvider->SetGroupField($sGroupField);
|
||||||
|
}
|
||||||
|
$oSetUIBlock->SetDataProvider($oDataProvider);
|
||||||
|
|
||||||
|
return $oSetUIBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MakeForAjax.
|
||||||
|
*
|
||||||
|
* Create a dynamic set base on options provided by ajax call.
|
||||||
|
* Options array must contain label, value and search string for each option.
|
||||||
|
* Keys for each entry must be provided but can be the same.
|
||||||
|
* If a group field is provided, options will be grouped according to this setting.
|
||||||
|
*
|
||||||
|
* @param string $sId Block identifier
|
||||||
|
* @param string $sAjaxRoute Ajax route @see \Combodo\iTop\Router\Router
|
||||||
|
* @param array $aAjaxRouteParams Url query parameters
|
||||||
|
* @param string $sLabelFields Field used for label
|
||||||
|
* @param string $sValueField Field used for value
|
||||||
|
* @param array $aSearchFields Fields used for search
|
||||||
|
* @param string|null $sGroupField Field used for grouping
|
||||||
|
*
|
||||||
|
* @return \Combodo\iTop\Application\UI\Base\Component\Input\Set\Set
|
||||||
|
*/
|
||||||
|
public static function MakeForAjax(string $sId, string $sAjaxRoute, array $aAjaxRouteParams, string $sLabelFields, string $sValueField, array $aSearchFields, ?string $sGroupField = null): Set
|
||||||
|
{
|
||||||
|
// Create set ui block
|
||||||
|
$oSetUIBlock = new Set($sId);
|
||||||
|
|
||||||
|
// Ajax data provider
|
||||||
|
$oDataProvider = new AjaxDataProvider($sAjaxRoute, $aAjaxRouteParams);
|
||||||
|
$oDataProvider
|
||||||
|
->SetDataLabelField($sLabelFields)
|
||||||
|
->SetDataValueField($sValueField)
|
||||||
|
->SetDataSearchFields($aSearchFields)
|
||||||
|
->SetTooltipField($sLabelFields);
|
||||||
|
if ($sGroupField != null) {
|
||||||
|
$oDataProvider->SetGroupField($sGroupField);
|
||||||
|
}
|
||||||
|
$oSetUIBlock->SetDataProvider($oDataProvider);
|
||||||
|
|
||||||
|
return $oSetUIBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MakeForOQL.
|
||||||
|
*
|
||||||
|
* Create a oql set base on options provided by OQL call.
|
||||||
|
* Options array must contain label, value and search string for each option.
|
||||||
|
* Keys for each entry must be provided but can be the same.
|
||||||
|
* If a group field is provided, options will be grouped according to this setting.
|
||||||
|
* Default fields are loaded but you can request more.
|
||||||
|
*
|
||||||
|
* @param string $sId Block identifier
|
||||||
|
* @param string $sObjectClass Object class
|
||||||
|
* @param string $sOql OQL to query objects
|
||||||
|
* @param string|null $sWizardHelperJsVarName Wizard helper name
|
||||||
|
* @param array $aFieldsToLoad Additional fields to load on objects
|
||||||
|
* @param string|null $sGroupField Field used for grouping
|
||||||
|
*
|
||||||
|
* @return \Combodo\iTop\Application\UI\Base\Component\Input\Set\Set
|
||||||
|
*/
|
||||||
|
public static function MakeForOQL(string $sId, string $sObjectClass, string $sOql, string $sWizardHelperJsVarName = null, array $aFieldsToLoad = [], ?string $sGroupField = null): Set
|
||||||
|
{
|
||||||
|
// Create set ui block
|
||||||
|
$oSetUIBlock = new Set($sId);
|
||||||
|
|
||||||
|
// Renderers
|
||||||
|
$oSetUIBlock->SetOptionsTemplate('application/object/set/option_renderer.html.twig');
|
||||||
|
$oSetUIBlock->SetItemsTemplate('application/object/set/item_renderer.html.twig');
|
||||||
|
|
||||||
|
// OQL data provider
|
||||||
|
$oDataProvider = new AjaxDataProviderForOQL($sObjectClass, $sOql, $sWizardHelperJsVarName, $aFieldsToLoad);
|
||||||
|
if ($sGroupField != null) {
|
||||||
|
$oDataProvider->SetGroupField($sGroupField);
|
||||||
|
}
|
||||||
|
$oDataProvider->SetTooltipField('full_description');
|
||||||
|
$oSetUIBlock->SetDataProvider($oDataProvider);
|
||||||
|
|
||||||
|
return $oSetUIBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,21 @@
|
|||||||
|
|
||||||
namespace Combodo\iTop\Application\UI\Links;
|
namespace Combodo\iTop\Application\UI\Links;
|
||||||
|
|
||||||
|
use ApplicationException;
|
||||||
|
use ArchivedObjectException;
|
||||||
|
use AttributeLinkedSet;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\MedallionIcon\MedallionIcon;
|
use Combodo\iTop\Application\UI\Base\Component\MedallionIcon\MedallionIcon;
|
||||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
|
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
|
||||||
|
use CoreException;
|
||||||
|
use CoreWarning;
|
||||||
|
use DBObject;
|
||||||
|
use DictExceptionMissingString;
|
||||||
|
use DisplayBlock;
|
||||||
|
use Exception;
|
||||||
use MetaModel;
|
use MetaModel;
|
||||||
|
use MySQLException;
|
||||||
|
use Utils;
|
||||||
|
use WebPage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AbstractBlockLinksViewTable
|
* Class AbstractBlockLinksViewTable
|
||||||
@@ -27,8 +39,8 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
|||||||
'js/wizardhelper.js',
|
'js/wizardhelper.js',
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var \DBObject $oDbObject db object witch link set belongs to */
|
/** @var DBObject $oDbObject db object witch link set belongs to */
|
||||||
protected \DBObject $oDbObject;
|
protected DBObject $oDbObject;
|
||||||
|
|
||||||
/** @var string $sObjectClass db object class name */
|
/** @var string $sObjectClass db object class name */
|
||||||
protected string $sObjectClass;
|
protected string $sObjectClass;
|
||||||
@@ -36,27 +48,27 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
|||||||
/** @var string $sAttCode db object link set attribute code */
|
/** @var string $sAttCode db object link set attribute code */
|
||||||
protected string $sAttCode;
|
protected string $sAttCode;
|
||||||
|
|
||||||
/** @var \AttributeLinkedSet $oAttDef attribute link set */
|
/** @var AttributeLinkedSet $oAttDef attribute link set */
|
||||||
protected \AttributeLinkedSet $oAttDef;
|
protected AttributeLinkedSet $oAttDef;
|
||||||
|
|
||||||
/** @var string $sTargetClass links target classname */
|
/** @var string $sTargetClass links target classname */
|
||||||
protected string $sTargetClass;
|
protected string $sTargetClass;
|
||||||
|
|
||||||
protected string $sTableId;
|
protected string $sTableId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param \WebPage $oPage
|
* @param WebPage $oPage
|
||||||
* @param \DBObject $oDbObject
|
* @param DBObject $oDbObject
|
||||||
* @param string $sObjectClass
|
* @param string $sObjectClass
|
||||||
* @param string $sAttCode
|
* @param string $sAttCode
|
||||||
* @param \AttributeLinkedSet $oAttDef
|
* @param AttributeLinkedSet $oAttDef
|
||||||
*
|
*
|
||||||
* @throws \CoreException
|
* @throws CoreException
|
||||||
* @throws \Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function __construct(\WebPage $oPage, \DBObject $oDbObject, string $sObjectClass, string $sAttCode, \AttributeLinkedSet $oAttDef)
|
public function __construct(WebPage $oPage, DBObject $oDbObject, string $sObjectClass, string $sAttCode, AttributeLinkedSet $oAttDef)
|
||||||
{
|
{
|
||||||
parent::__construct('', ["ibo-block-links-table"]);
|
parent::__construct('', ["ibo-block-links-table"]);
|
||||||
|
|
||||||
@@ -78,7 +90,7 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
|||||||
* Init.
|
* Init.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private function Init()
|
private function Init()
|
||||||
{
|
{
|
||||||
@@ -89,12 +101,12 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
|||||||
* Initialize UI.
|
* Initialize UI.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
private function InitUI(\WebPage $oPage)
|
private function InitUI(WebPage $oPage)
|
||||||
{
|
{
|
||||||
// header
|
// header
|
||||||
$this->InitHeader();;
|
$this->InitHeader();
|
||||||
|
|
||||||
// Table
|
// Table
|
||||||
$this->InitTable($oPage);
|
$this->InitTable($oPage);
|
||||||
@@ -104,7 +116,8 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
|||||||
* InitHeader.
|
* InitHeader.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \CoreException
|
* @throws CoreException
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private function InitHeader()
|
private function InitHeader()
|
||||||
{
|
{
|
||||||
@@ -117,21 +130,21 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
|||||||
/**
|
/**
|
||||||
* InitTable.
|
* InitTable.
|
||||||
*
|
*
|
||||||
* @param \WebPage $oPage
|
* @param WebPage $oPage
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \ApplicationException
|
* @throws ApplicationException
|
||||||
* @throws \ArchivedObjectException
|
* @throws ArchivedObjectException
|
||||||
* @throws \CoreException
|
* @throws CoreException
|
||||||
* @throws \CoreWarning
|
* @throws CoreWarning
|
||||||
* @throws \DictExceptionMissingString
|
* @throws DictExceptionMissingString
|
||||||
* @throws \MySQLException
|
* @throws MySQLException
|
||||||
*/
|
*/
|
||||||
private function InitTable(\WebPage $oPage)
|
private function InitTable(WebPage $oPage)
|
||||||
{
|
{
|
||||||
// retrieve db object set
|
// retrieve db object set
|
||||||
$oOrmLinkSet = $this->oDbObject->Get($this->sAttCode);
|
$oOrmLinkSet = $this->oDbObject->Get($this->sAttCode);
|
||||||
$oLinkSet = $oOrmLinkSet->ToDBObjectSet(\utils::ShowObsoleteData());
|
$oLinkSet = $oOrmLinkSet->ToDBObjectSet(utils::ShowObsoleteData());
|
||||||
|
|
||||||
// add list block
|
// add list block
|
||||||
$oBlock = new \DisplayBlock($oLinkSet->GetFilter(), 'list', false);
|
$oBlock = new \DisplayBlock($oLinkSet->GetFilter(), 'list', false);
|
||||||
@@ -163,11 +176,11 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
|||||||
*
|
*
|
||||||
* Provide parameters for display block as list.
|
* Provide parameters for display block as list.
|
||||||
*
|
*
|
||||||
* @see \DisplayBlock::RenderList
|
* @see DisplayBlock::RenderList
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \ArchivedObjectException
|
* @throws ArchivedObjectException
|
||||||
* @throws \CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
abstract function GetExtraParam(): array;
|
abstract function GetExtraParam(): array;
|
||||||
|
|
||||||
@@ -178,7 +191,7 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
|||||||
*
|
*
|
||||||
* @see \Combodo\iTop\Application\UI\Base\Component\DataTable\tTableRowActions
|
* @see \Combodo\iTop\Application\UI\Base\Component\DataTable\tTableRowActions
|
||||||
*
|
*
|
||||||
* @return \string[][]
|
* @return string[][]
|
||||||
*/
|
*/
|
||||||
abstract function GetRowActions(): array;
|
abstract function GetRowActions(): array;
|
||||||
|
|
||||||
@@ -188,12 +201,11 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
|||||||
* Return link set target class.
|
* Return link set target class.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
* @throws \Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
abstract function GetTargetClass(): string;
|
abstract function GetTargetClass(): string;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -201,5 +213,5 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
|||||||
{
|
{
|
||||||
return $this->sAttCode;
|
return $this->sAttCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function InitTable(\WebPage $oPage, \DBObjectSet $oValue, string $sFormPrefix)
|
public function InitTable(\WebPage $oPage, $oValue, string $sFormPrefix)
|
||||||
{
|
{
|
||||||
/** @todo fields initialization */
|
/** @todo fields initialization */
|
||||||
$this->sInputName = $sFormPrefix.'attr_'.$this->oUILinksDirectWidget->GetAttCode();
|
$this->sInputName = $sFormPrefix.'attr_'.$this->oUILinksDirectWidget->GetAttCode();
|
||||||
@@ -193,26 +193,6 @@ class BlockDirectLinksEditTable extends UIContentBlock
|
|||||||
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->oUILinksDirectWidget->GetInputId().'" onClick="oWidget'.$this->oUILinksDirectWidget->GetInputId().'.directlinks(\'instance\')._onSelectChange();" value="'.$oLinkObj->GetKey().'"/>';
|
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->oUILinksDirectWidget->GetInputId().'" onClick="oWidget'.$this->oUILinksDirectWidget->GetInputId().'.directlinks(\'instance\')._onSelectChange();" value="'.$oLinkObj->GetKey().'"/>';
|
||||||
foreach ($this->oUILinksDirectWidget->GetZList() as $sLinkedAttCode) {
|
foreach ($this->oUILinksDirectWidget->GetZList() as $sLinkedAttCode) {
|
||||||
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
|
||||||
|
|
||||||
// tentative d'ajout des attributs en édition
|
|
||||||
// $sValue = $oLinkObj->Get($sLinkedAttCode);
|
|
||||||
// $sDisplayValue = $oLinkObj->GetEditValue($sLinkedAttCode);
|
|
||||||
// $oAttDef = MetaModel::GetAttributeDef($this->oUILinksDirectWidget->GetLinkedClass(), $sLinkedAttCode);
|
|
||||||
//
|
|
||||||
// $aRow[$sLinkedAttCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'
|
|
||||||
// .\cmdbAbstractObject::GetFormElementForField(
|
|
||||||
// $oPage,
|
|
||||||
// $this->oUILinksDirectWidget->GetLinkedClass(),
|
|
||||||
// $sLinkedAttCode,
|
|
||||||
// $oAttDef,
|
|
||||||
// $sValue,
|
|
||||||
// $sDisplayValue,
|
|
||||||
// $this->GetFieldId($oValue, $sLinkedAttCode),
|
|
||||||
// ']',
|
|
||||||
// 0,
|
|
||||||
// []
|
|
||||||
// )
|
|
||||||
// .'</div></div></div>';
|
|
||||||
}
|
}
|
||||||
$aRows[] = $aRow;
|
$aRows[] = $aRow;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ use PHPUnit\Exception;
|
|||||||
*/
|
*/
|
||||||
class BlockIndirectLinksViewTable extends AbstractBlockLinksViewTable
|
class BlockIndirectLinksViewTable extends AbstractBlockLinksViewTable
|
||||||
{
|
{
|
||||||
public const BLOCK_CODE = 'ibo-block-indirect-links-view-table';
|
public const BLOCK_CODE = 'ibo-block-indirect-links-view-table';
|
||||||
|
public const REQUIRES_ANCESTORS_DEFAULT_JS_FILES = true;
|
||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
public function GetTargetClass(): string
|
public function GetTargetClass(): string
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
|||||||
use Combodo\iTop\Application\UI\Base\Component\QuickCreate\QuickCreateHelper;
|
use Combodo\iTop\Application\UI\Base\Component\QuickCreate\QuickCreateHelper;
|
||||||
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
|
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
|
||||||
use Combodo\iTop\Controller\AbstractController;
|
use Combodo\iTop\Controller\AbstractController;
|
||||||
|
use Combodo\iTop\Service\Base\ObjectRepository;
|
||||||
use CoreCannotSaveObjectException;
|
use CoreCannotSaveObjectException;
|
||||||
use DeleteException;
|
use DeleteException;
|
||||||
use Dict;
|
use Dict;
|
||||||
@@ -543,4 +544,44 @@ JS;
|
|||||||
'js/jquery.blockUI.js',
|
'js/jquery.blockUI.js',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OperationSearch.
|
||||||
|
*
|
||||||
|
* Search objects via an oql and a friendly name search string
|
||||||
|
*
|
||||||
|
* @return JsonPage
|
||||||
|
*/
|
||||||
|
public function OperationSearch(): JsonPage
|
||||||
|
{
|
||||||
|
$oPage = new JsonPage();
|
||||||
|
|
||||||
|
// Retrieve query params
|
||||||
|
$sObjectClass = utils::ReadParam('object_class', '', false, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||||
|
$sOql = utils::ReadParam('oql', '', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
|
||||||
|
$aFieldsToLoad = json_decode(utils::ReadParam('fields_to_load', '', false, utils::ENUM_SANITIZATION_FILTER_STRING));
|
||||||
|
$sSearch = utils::ReadParam('search', '', false, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||||
|
|
||||||
|
// Retrieve this reference object (for OQL)
|
||||||
|
$sThisObjectData = utils::ReadPostedParam('this_object_data', null, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
|
||||||
|
$oThisObj = ObjectRepository::GetObjectFromWizardHelperData($sThisObjectData);
|
||||||
|
|
||||||
|
// Retrieve data post processor
|
||||||
|
$aDataProcessor = utils::ReadParam('data_post_processor', null, false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
|
||||||
|
|
||||||
|
// Search objects
|
||||||
|
$aResult = ObjectRepository::SearchFromOql($sObjectClass, $aFieldsToLoad, $sOql, $sSearch, $oThisObj);
|
||||||
|
|
||||||
|
// Data post processor
|
||||||
|
// Note: Data post processor allow you to perform actions on search result (compute object result statistics, add others information...).
|
||||||
|
if ($aResult !== null && $aDataProcessor !== null) {
|
||||||
|
$aResult = call_user_func(array($aDataProcessor['class_name'], 'Execute'), $aResult, $aDataProcessor['settings']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $oPage->SetData([
|
||||||
|
'search_data' => $aResult,
|
||||||
|
'success' => $aResult !== null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -10,9 +10,10 @@ use AjaxPage;
|
|||||||
use cmdbAbstractObject;
|
use cmdbAbstractObject;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory;
|
||||||
use Combodo\iTop\Controller\AbstractController;
|
use Combodo\iTop\Controller\AbstractController;
|
||||||
|
use Exception;
|
||||||
|
use JsonPage;
|
||||||
use CoreException;
|
use CoreException;
|
||||||
use DBObject;
|
use DBObject;
|
||||||
use JsonPage;
|
|
||||||
use MetaModel;
|
use MetaModel;
|
||||||
use UserRights;
|
use UserRights;
|
||||||
use utils;
|
use utils;
|
||||||
@@ -58,7 +59,7 @@ class LinkSetController extends AbstractController
|
|||||||
$sErrorMessage = json_encode($oDeletionPlan->GetIssues());
|
$sErrorMessage = json_encode($oDeletionPlan->GetIssues());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (\Exception $e) {
|
catch (Exception $e) {
|
||||||
$sErrorMessage = $e->getMessage();
|
$sErrorMessage = $e->getMessage();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -102,7 +103,7 @@ class LinkSetController extends AbstractController
|
|||||||
$oLinkedObject->DBWrite();
|
$oLinkedObject->DBWrite();
|
||||||
$bOperationSuccess = true;
|
$bOperationSuccess = true;
|
||||||
}
|
}
|
||||||
catch (\Exception $e) {
|
catch (Exception $e) {
|
||||||
$sErrorMessage = $e->getMessage();
|
$sErrorMessage = $e->getMessage();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
263
sources/Service/Base/ObjectRepository.php
Normal file
263
sources/Service/Base/ObjectRepository.php
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Service\Base;
|
||||||
|
|
||||||
|
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
||||||
|
use DBObject;
|
||||||
|
use DBObjectSearch;
|
||||||
|
use DBObjectSet;
|
||||||
|
use DBSearch;
|
||||||
|
use Exception;
|
||||||
|
use ExceptionLog;
|
||||||
|
use iDBObjectSetIterator;
|
||||||
|
use MetaModel;
|
||||||
|
use utils;
|
||||||
|
use WizardHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ObjectRepository
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
* @since 3.1.0
|
||||||
|
* @package Combodo\iTop\Service\Base
|
||||||
|
*/
|
||||||
|
class ObjectRepository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Search.
|
||||||
|
*
|
||||||
|
* @param string $sObjectClass Object class to search
|
||||||
|
* @param array $aFieldsToLoad Additional fields to load
|
||||||
|
* @param string $sSearch Friendly name search string
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
static public function Search(string $sObjectClass, array $aFieldsToLoad, string $sSearch): ?array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Create db search
|
||||||
|
$oDbObjectSearch = new DBObjectSearch($sObjectClass);
|
||||||
|
$oDbObjectSearch->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
|
|
||||||
|
// Add a friendly name search condition
|
||||||
|
$oDbObjectSearch->AddCondition('friendlyname', $sSearch, 'Contains');
|
||||||
|
|
||||||
|
// Create db object set
|
||||||
|
$oSet = new DBObjectSet($oDbObjectSearch);
|
||||||
|
|
||||||
|
// Transform set to array
|
||||||
|
$aResult = ObjectRepository::DBSetToObjectArray($oSet, $sObjectClass, $aFieldsToLoad);
|
||||||
|
|
||||||
|
// Handle max results for autocomplete
|
||||||
|
if (Utils::IsNullOrEmptyString($sSearch)
|
||||||
|
&& count($aResult) > MetaModel::GetConfig()->Get('max_autocomplete_results')) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aResult;
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
|
||||||
|
ExceptionLog::LogException($e);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SearchFromOql.
|
||||||
|
*
|
||||||
|
* @param string $sObjectClass Object class to search
|
||||||
|
* @param array $aFieldsToLoad Additional fields to load
|
||||||
|
* @param string $sOql Oql expression
|
||||||
|
* @param string $sSearch Friendly name search string
|
||||||
|
* @param DBObject|null $oThisObject This object reference for oql
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
static public function SearchFromOql(string $sObjectClass, array $aFieldsToLoad, string $sOql, string $sSearch, DBObject $oThisObject = null): ?array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Create db search
|
||||||
|
$oDbObjectSearch = DBSearch::FromOQL($sOql);
|
||||||
|
$oDbObjectSearch->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||||
|
$oDbObjectSearch->AddCondition('friendlyname', $sSearch, 'Contains');
|
||||||
|
|
||||||
|
// Create db set from db search
|
||||||
|
$oDbObjectSet = new DBObjectSet($oDbObjectSearch, [], ['this' => $oThisObject]);
|
||||||
|
|
||||||
|
// return object array
|
||||||
|
return ObjectRepository::DBSetToObjectArray($oDbObjectSet, $sObjectClass, $aFieldsToLoad);
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
|
||||||
|
ExceptionLog::LogException($e);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DBSetToObjectArray.
|
||||||
|
*
|
||||||
|
* @param iDBObjectSetIterator $oDbObjectSet Db object set
|
||||||
|
* @param string $sObjectClass Object class
|
||||||
|
* @param array $aFieldsToLoad Additional fields to load
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws \ArchivedObjectException
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \DictExceptionMissingString
|
||||||
|
*/
|
||||||
|
static private function DBSetToObjectArray(iDBObjectSetIterator $oDbObjectSet, string $sObjectClass, array $aFieldsToLoad): array
|
||||||
|
{
|
||||||
|
// Retrieve friendly name complementary specification
|
||||||
|
$aComplementAttributeSpec = MetaModel::GetNameSpec($sObjectClass, FriendlyNameType::COMPLEMENTARY);
|
||||||
|
|
||||||
|
// Retrieve image attribute code
|
||||||
|
$sObjectImageAttCode = MetaModel::GetImageAttributeCode($sObjectClass);
|
||||||
|
|
||||||
|
// Prepare fields to load
|
||||||
|
$aDefaultFieldsToLoad = ObjectRepository::GetDefaultFieldsToLoad($aComplementAttributeSpec, $sObjectImageAttCode);
|
||||||
|
$aFieldsToLoad = array_merge($aDefaultFieldsToLoad, $aFieldsToLoad);
|
||||||
|
|
||||||
|
// Optimize columns load
|
||||||
|
$oDbObjectSet->OptimizeColumnLoad([
|
||||||
|
$sObjectClass => $aFieldsToLoad,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Prepare result
|
||||||
|
$aResult = [];
|
||||||
|
|
||||||
|
// Iterate throw objects...
|
||||||
|
$oDbObjectSet->Rewind();
|
||||||
|
while ($oObject = $oDbObjectSet->Fetch()) {
|
||||||
|
|
||||||
|
// Prepare objet data
|
||||||
|
$aObjectData = [];
|
||||||
|
|
||||||
|
// Object key
|
||||||
|
$aObjectData['key'] = $oObject->GetKey();
|
||||||
|
|
||||||
|
// Fill loaded columns...
|
||||||
|
foreach ($aFieldsToLoad as $sField) {
|
||||||
|
$aObjectData[$sField] = $oObject->Get($sField);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute others data
|
||||||
|
$aResult[] = ObjectRepository::ComputeOthersData($oObject, $sObjectClass, $aObjectData, $aComplementAttributeSpec, $sObjectImageAttCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetDefaultFieldsToLoad.
|
||||||
|
*
|
||||||
|
* Return attributes to load for any objects.
|
||||||
|
*
|
||||||
|
* @param array $aComplementAttributeSpec Friendly name complementary spec
|
||||||
|
* @param string $sObjectImageAttCode Image attribute code
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
static public function GetDefaultFieldsToLoad(array $aComplementAttributeSpec, string $sObjectImageAttCode)
|
||||||
|
{
|
||||||
|
// Friendly name complementary fields
|
||||||
|
$aFieldsToLoad = $aComplementAttributeSpec[1];
|
||||||
|
|
||||||
|
// Image attribute
|
||||||
|
if (!empty($sObjectImageAttCode)) {
|
||||||
|
$aFieldsToLoad[] = $sObjectImageAttCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add friendly name
|
||||||
|
$aFieldsToLoad[] = 'friendlyname';
|
||||||
|
|
||||||
|
return $aFieldsToLoad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ComputeOthersData.
|
||||||
|
*
|
||||||
|
* @param DBObject $oDbObject Db object
|
||||||
|
* @param string $sClass Object class
|
||||||
|
* @param array $aData Object data to fill
|
||||||
|
* @param array $aComplementAttributeSpec Friendly name complementary spec
|
||||||
|
* @param string $sObjectImageAttCode Image attribute code
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
static public function ComputeOthersData(DBObject $oDbObject, string $sClass, array $aData, array $aComplementAttributeSpec, string $sObjectImageAttCode): array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Obsolescence flag
|
||||||
|
$aData['obsolescence_flag'] = $oDbObject->IsObsolete();
|
||||||
|
|
||||||
|
// Additional fields
|
||||||
|
if (count($aComplementAttributeSpec[1]) > 0) {
|
||||||
|
$aArguments = [];
|
||||||
|
foreach ($aComplementAttributeSpec[1] as $sAdditionalField) {
|
||||||
|
$aArguments[] = $oDbObject->Get($sAdditionalField);
|
||||||
|
}
|
||||||
|
$aData['additional_field'] = utils::HtmlEntities(vsprintf($aComplementAttributeSpec[0], $aArguments));
|
||||||
|
$aData['full_description'] = "{$aData['friendlyname']}<br><i><small>{$aData['additional_field']}</small></i>";
|
||||||
|
} else {
|
||||||
|
$aData['full_description'] = $aData['friendlyname'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Image
|
||||||
|
if (!empty($sObjectImageAttCode)) {
|
||||||
|
$aData['has_image'] = true;
|
||||||
|
/** @var \ormDocument $oImage */
|
||||||
|
$oImage = $oDbObject->Get($sObjectImageAttCode);
|
||||||
|
if (!$oImage->IsEmpty()) {
|
||||||
|
$aData['picture_url'] = "url('{$oImage->GetDisplayURL($sClass, $oDbObject->GetKey(), $sObjectImageAttCode)}')";
|
||||||
|
$aData['initials'] = '';
|
||||||
|
} else {
|
||||||
|
$aData['initials'] = utils::FormatInitialsForMedallion(utils::ToAcronym($oDbObject->Get('friendlyname')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aData;
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
|
||||||
|
ExceptionLog::LogException($e);
|
||||||
|
|
||||||
|
return $aData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetObjectFromWizardHelperData
|
||||||
|
*
|
||||||
|
* @param string $sData
|
||||||
|
*
|
||||||
|
* @return DBObject|null
|
||||||
|
*/
|
||||||
|
public static function GetObjectFromWizardHelperData(string $sData): ?DBObject
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$oThisObj = null;
|
||||||
|
if ($sData != null) {
|
||||||
|
$oWizardHelper = WizardHelper::FromJSON($sData);
|
||||||
|
$oThisObj = $oWizardHelper->GetTargetObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $oThisObj;
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
40
sources/Service/Base/iDataPostProcessor.php
Normal file
40
sources/Service/Base/iDataPostProcessor.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?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\Service\Base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface iDataPostProcessor
|
||||||
|
*
|
||||||
|
* @package Combodo\iTop\Service\Base
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
interface iDataPostProcessor
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute.
|
||||||
|
*
|
||||||
|
* @param array $aData Array of elements
|
||||||
|
* @param array $aSettings Array of settings
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function Execute(array $aData, array $aSettings): array;
|
||||||
|
|
||||||
|
}
|
||||||
176
sources/Service/Links/LinkSetDataTransformer.php
Normal file
176
sources/Service/Links/LinkSetDataTransformer.php
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
<?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\Service\Links;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use ExceptionLog;
|
||||||
|
use iDBObjectSetIterator;
|
||||||
|
use MetaModel;
|
||||||
|
use ormLinkSet;
|
||||||
|
use utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class LinksSetDataTransformer
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*
|
||||||
|
* @since 3.1.0
|
||||||
|
* @package Combodo\iTop\Service\Links
|
||||||
|
*/
|
||||||
|
class LinkSetDataTransformer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Decode.
|
||||||
|
*
|
||||||
|
* Convert db object set to array.
|
||||||
|
* This array will be provided to set component view.
|
||||||
|
*
|
||||||
|
* @param \iDBObjectSetIterator $oDbObjectSet Db object set
|
||||||
|
* @param string $sTargetClass Target class name
|
||||||
|
* @param string|null $sTargetField Target field
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
static public function Decode(iDBObjectSetIterator $oDbObjectSet, string $sTargetClass, string $sTargetField = null): array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Prepare result
|
||||||
|
$aResult = [];
|
||||||
|
|
||||||
|
// Ensure start at set beginning
|
||||||
|
$oDbObjectSet->Rewind();
|
||||||
|
|
||||||
|
// Iterate throw objects...
|
||||||
|
while ($oObject = $oDbObjectSet->Fetch()) {
|
||||||
|
|
||||||
|
// In case ot indirect link
|
||||||
|
if ($sTargetField !== null) {
|
||||||
|
$oObject = MetaModel::GetObject($sTargetClass, $oObject->Get($sTargetField));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!utils::ShowObsoleteData() && $oObject->IsObsolete()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append object key
|
||||||
|
$aResult[] = $oObject->GetKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aResult;
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
|
||||||
|
ExceptionLog::LogException($e);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode.
|
||||||
|
*
|
||||||
|
* Convert array from view to arrays used by UI.php to apply link set modifications.
|
||||||
|
*
|
||||||
|
* @see cmdbAbstractObject::PrepareValueFromPostedForm
|
||||||
|
*
|
||||||
|
* @param array $aElements Link set elements
|
||||||
|
* @param string $sLinkClass Link class name
|
||||||
|
* @param string|null $sExtKeyToRemote External key to remote
|
||||||
|
*
|
||||||
|
* @return array{to_be_created: array, to_be_deleted: array, to_be_added: array, to_be_removed: array}
|
||||||
|
*/
|
||||||
|
static public function Encode(array $aElements, string $sLinkClass, string $sExtKeyToRemote = null): array
|
||||||
|
{
|
||||||
|
// Result arrays
|
||||||
|
$aToBeCreate = [];
|
||||||
|
$aToBeDelete = [];
|
||||||
|
$aToBeAdd = [];
|
||||||
|
$aToBeRemove = [];
|
||||||
|
|
||||||
|
// Iterate throw data...
|
||||||
|
foreach ($aElements as $aData) {
|
||||||
|
|
||||||
|
switch ($aData['operation']) {
|
||||||
|
|
||||||
|
// OPERATION ADD
|
||||||
|
case 'add':
|
||||||
|
if ($sExtKeyToRemote === null) {
|
||||||
|
// Direct link attach
|
||||||
|
$aToBeAdd[] = $aData['data']['key'];
|
||||||
|
} else {
|
||||||
|
// Indirect link creation
|
||||||
|
$aToBeCreate[] = [
|
||||||
|
'class' => $sLinkClass,
|
||||||
|
'data' => [
|
||||||
|
$sExtKeyToRemote => $aData['data']['key'],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// OPERATION REMOVE
|
||||||
|
case 'remove':
|
||||||
|
if ($sExtKeyToRemote === null) {
|
||||||
|
// Direct link detach
|
||||||
|
$aToBeRemove[] = $aData['data']['key'];
|
||||||
|
} else {
|
||||||
|
// Indirect link deletion
|
||||||
|
foreach ($aData['data']['link_keys'] as $sKey) {
|
||||||
|
$aToBeDelete[] = $sKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'to_be_created' => $aToBeCreate,
|
||||||
|
'to_be_deleted' => $aToBeDelete,
|
||||||
|
'to_be_added' => $aToBeAdd,
|
||||||
|
'to_be_removed' => $aToBeRemove,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert string representation of an orm linked set to object ormLinkSet.
|
||||||
|
*
|
||||||
|
* @param string $sValue
|
||||||
|
* @param \ormLinkSet $oOrmLinkSet
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static public function StringToOrmLinkSet(string $sValue, ormLinkSet $oOrmLinkSet)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$aItems = explode(" ", $sValue);
|
||||||
|
foreach ($aItems as $sItem) {
|
||||||
|
if (!empty($sItem)) {
|
||||||
|
$oItem = MetaModel::GetObject($oOrmLinkSet->GetClass(), intval($sItem));
|
||||||
|
if (!utils::ShowObsoleteData() && $oItem->IsObsolete()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$oOrmLinkSet->AddItem($oItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
ExceptionLog::LogException($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
sources/Service/Links/LinkSetModel.php
Normal file
75
sources/Service/Links/LinkSetModel.php
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Service\Links;
|
||||||
|
|
||||||
|
use AttributeExternalKey;
|
||||||
|
use AttributeLinkedSet;
|
||||||
|
use AttributeLinkedSetIndirect;
|
||||||
|
use Exception;
|
||||||
|
use MetaModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class LinkSetModel
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
* @since 3.1.0
|
||||||
|
* @package Combodo\iTop\Service\Links
|
||||||
|
*/
|
||||||
|
class LinkSetModel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* GetTargetClass.
|
||||||
|
*
|
||||||
|
* @param AttributeLinkedSet $oAttDef
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static public function GetTargetClass(AttributeLinkedSet $oAttDef): string
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if ($oAttDef instanceof AttributeLinkedSetIndirect) {
|
||||||
|
/** @var AttributeExternalKey $oLinkingAttDef */
|
||||||
|
$oLinkingAttDef = MetaModel::GetAttributeDef($oAttDef->GetLinkedClass(), $oAttDef->GetExtKeyToRemote());
|
||||||
|
|
||||||
|
return $oLinkingAttDef->GetTargetClass();
|
||||||
|
} else {
|
||||||
|
return $oAttDef->GetLinkedClass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetLinkedClass.
|
||||||
|
*
|
||||||
|
* @param AttributeLinkedSet $oAttDef
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static public function GetLinkedClass(AttributeLinkedSet $oAttDef): string
|
||||||
|
{
|
||||||
|
return $oAttDef->GetLinkedClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetTargetField.
|
||||||
|
*
|
||||||
|
* @param AttributeLinkedSet $oAttDef
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
static public function GetTargetField(AttributeLinkedSet $oAttDef): ?string
|
||||||
|
{
|
||||||
|
if ($oAttDef instanceof AttributeLinkedSetIndirect) {
|
||||||
|
return $oAttDef->GetExtKeyToRemote();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
100
sources/Service/Links/LinkSetRepository.php
Normal file
100
sources/Service/Links/LinkSetRepository.php
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Service\Links;
|
||||||
|
|
||||||
|
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
||||||
|
use Combodo\iTop\Service\Base\ObjectRepository;
|
||||||
|
use Exception;
|
||||||
|
use ExceptionLog;
|
||||||
|
use iDBObjectSetIterator;
|
||||||
|
use MetaModel;
|
||||||
|
use utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class LinkSetRepository
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
* @since 3.1.0
|
||||||
|
* @package Combodo\iTop\Service\Links
|
||||||
|
*/
|
||||||
|
class LinkSetRepository
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LinksDbSetToTargetObjectArray.
|
||||||
|
*
|
||||||
|
* @param iDBObjectSetIterator $oDbObjectSet Db object set
|
||||||
|
* @param string $sTargetClass Target class name
|
||||||
|
* @param string|null $sTargetField Target field
|
||||||
|
*
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
static public function LinksDbSetToTargetObjectArray(iDBObjectSetIterator $oDbObjectSet, string $sTargetClass, string $sTargetField = null): ?array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Retrieve friendly name complementary specification
|
||||||
|
$aComplementAttributeSpec = MetaModel::GetNameSpec($sTargetClass, FriendlyNameType::COMPLEMENTARY);
|
||||||
|
|
||||||
|
// Retrieve image attribute code
|
||||||
|
$sObjectImageAttCode = MetaModel::GetImageAttributeCode($sTargetClass);
|
||||||
|
|
||||||
|
// Prepare fields to load
|
||||||
|
$aFieldsToLoad = ObjectRepository::GetDefaultFieldsToLoad($aComplementAttributeSpec, $sObjectImageAttCode);
|
||||||
|
|
||||||
|
// Optimize columns load
|
||||||
|
$oDbObjectSet->OptimizeColumnLoad([
|
||||||
|
$sTargetClass => $aFieldsToLoad,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Prepare result
|
||||||
|
$aResult = [];
|
||||||
|
|
||||||
|
// Iterate throw objects...
|
||||||
|
$oDbObjectSet->Rewind();
|
||||||
|
while ($oObject = $oDbObjectSet->Fetch()) {
|
||||||
|
|
||||||
|
// Ignore obsolete data
|
||||||
|
if (!utils::ShowObsoleteData() && $oObject->IsObsolete()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare objet data
|
||||||
|
$aObjectData = [];
|
||||||
|
|
||||||
|
// Link keys
|
||||||
|
$aObjectData['link_keys'] = [$oObject->GetKey()];
|
||||||
|
|
||||||
|
// In case ot indirect link
|
||||||
|
if ($sTargetField != null) {
|
||||||
|
$oObject = MetaModel::GetObject($sTargetClass, $oObject->Get($sTargetField));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remote key
|
||||||
|
$aObjectData['key'] = $oObject->GetKey();
|
||||||
|
|
||||||
|
// Fill loaded columns...
|
||||||
|
foreach ($aFieldsToLoad as $sField) {
|
||||||
|
$aObjectData[$sField] = $oObject->Get($sField);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute others data
|
||||||
|
$aResult[] = ObjectRepository::ComputeOthersData($oObject, $sTargetClass, $aObjectData, $aComplementAttributeSpec, $sObjectImageAttCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aResult;
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
|
||||||
|
ExceptionLog::LogException($e);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
139
sources/Service/Links/LinksBulkDataPostProcessor.php
Normal file
139
sources/Service/Links/LinksBulkDataPostProcessor.php
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
<?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\Service\Links;
|
||||||
|
|
||||||
|
use CMDBSource;
|
||||||
|
use Combodo\iTop\Service\Base\iDataPostProcessor;
|
||||||
|
use DBObjectSet;
|
||||||
|
use DBSearch;
|
||||||
|
use Exception;
|
||||||
|
use ExceptionLog;
|
||||||
|
use FieldExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class LinksBulkDataPostProcessor
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*
|
||||||
|
* @since 3.1.0
|
||||||
|
* @package Combodo\iTop\Service\Links
|
||||||
|
*/
|
||||||
|
class LinksBulkDataPostProcessor implements iDataPostProcessor
|
||||||
|
{
|
||||||
|
/** @inheritDoc */
|
||||||
|
public static function Execute(array $aData, array $aSettings): array
|
||||||
|
{
|
||||||
|
return self::ComputeScopeData($aData, $aSettings['bulk_oql'], $aSettings['link_class'], $aSettings['origin_field'], $aSettings['target_field']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ComputeScopeData.
|
||||||
|
*
|
||||||
|
* @param array $aResult
|
||||||
|
* @param string $sScope
|
||||||
|
* @param string $sLinkClass
|
||||||
|
* @param string $sOriginField
|
||||||
|
* @param string $sTargetField
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function ComputeScopeData(array $aResult, string $sScope, string $sLinkClass, string $sOriginField, string $sTargetField): array
|
||||||
|
{
|
||||||
|
if (!empty($sScope)) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
// OQL to select bulk object selection
|
||||||
|
$oDbObjectSearchBulkObjects = DBSearch::FromOQL($sScope);
|
||||||
|
$oDbObjectSetBulkObjects = new DBObjectSet($oDbObjectSearchBulkObjects);
|
||||||
|
$aBulksObjects = $oDbObjectSetBulkObjects->GetColumnAsArray('id', false);
|
||||||
|
$sBulkList = implode(',', $aBulksObjects);
|
||||||
|
|
||||||
|
// Get all links attached to object selection
|
||||||
|
$sOqlGroupBy = "SELECT $sLinkClass AS lnk WHERE lnk.$sOriginField IN ($sBulkList)";
|
||||||
|
$oDbObjectSearch = DBSearch::FromOQL($sOqlGroupBy);
|
||||||
|
|
||||||
|
// Group by links attached to object selection
|
||||||
|
$oFieldExp = new FieldExpression($sTargetField, 'lnk');
|
||||||
|
$sQuery = $oDbObjectSearch->MakeGroupByQuery([$sTargetField], array('grouped_by_1' => $oFieldExp), true);
|
||||||
|
$aGroupResult = CMDBSource::QueryToArray($sQuery, MYSQLI_ASSOC);
|
||||||
|
|
||||||
|
// Iterate throw result...
|
||||||
|
foreach ($aResult as &$aItem) {
|
||||||
|
|
||||||
|
// Find group by object to extract link count
|
||||||
|
$aFound = null;
|
||||||
|
foreach ($aGroupResult as $aItemGroup) {
|
||||||
|
if ($aItem['key'] === $aItemGroup['grouped_by_1']) {
|
||||||
|
$aFound = $aItemGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If found, get information
|
||||||
|
if ($aFound !== null) {
|
||||||
|
$aItem['group'] = 'Objects already linked';
|
||||||
|
$aItem['occurrence'] = $aFound['_itop_count_'];
|
||||||
|
$aItem['occurrence_label'] = "Link on {$aFound['_itop_count_']} Objects(s)";
|
||||||
|
$aItem['occurrence_info'] = "({$aFound['_itop_count_']})";
|
||||||
|
$aItem['full'] = ($aFound['_itop_count_'] == $oDbObjectSetBulkObjects->Count());
|
||||||
|
|
||||||
|
// Retrieve linked objects keys
|
||||||
|
$sOqlLinkKeys = "SELECT $sLinkClass AS lnk WHERE lnk.$sOriginField IN ($sBulkList) AND lnk.$sTargetField = {$aItem['key']}";
|
||||||
|
$oDbSearchLinkKeys = DBSearch::FromOQL($sOqlLinkKeys);
|
||||||
|
$aLinkedObjects = new DBObjectSet($oDbSearchLinkKeys);
|
||||||
|
$aItem['link_keys'] = $aLinkedObjects->GetColumnAsArray('id', false);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$aItem['group'] = 'Others';
|
||||||
|
$aItem['occurrence'] = '';
|
||||||
|
$aItem['empty'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Order items
|
||||||
|
usort($aResult, [self::class, "CompareItems"]);
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
|
||||||
|
ExceptionLog::LogException($e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CompareItems.
|
||||||
|
*
|
||||||
|
* @param $aItemA
|
||||||
|
* @param $aItemB
|
||||||
|
*
|
||||||
|
* @return array|int
|
||||||
|
*/
|
||||||
|
static private function CompareItems($aItemA, $aItemB): int
|
||||||
|
{
|
||||||
|
if ($aItemA['occurrence'] === $aItemB['occurrence']) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($aItemA['occurrence'] > $aItemB['occurrence']) ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
15
templates/application/object/set/item_renderer.html.twig
Normal file
15
templates/application/object/set/item_renderer.html.twig
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<div class="friendlyname">
|
||||||
|
|
||||||
|
{# Obsolescence #}
|
||||||
|
<span class="object-ref-icon text_decoration" data-template-condition="obsolescence_flag">
|
||||||
|
<span class="fas fa-eye-slash object-obsolete fa-1x fa-fw"></span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{# Friendly name #}
|
||||||
|
<span data-template-text="friendlyname"></span>
|
||||||
|
|
||||||
|
{# Additional content #}
|
||||||
|
{% block additional_content %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
</div>
|
||||||
29
templates/application/object/set/option_renderer.html.twig
Normal file
29
templates/application/object/set/option_renderer.html.twig
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<div class="option ibo-input-select--autocomplete-item" role="option" >
|
||||||
|
|
||||||
|
{# Image #}
|
||||||
|
<span class="ibo-input-select--autocomplete-item-image" data-template-condition="has_image" data-template-css-background-image="picture_url" data-template-text="initials"></span>
|
||||||
|
|
||||||
|
{# Desc #}
|
||||||
|
<span class="ibo-input-select--autocomplete-item-txt">
|
||||||
|
|
||||||
|
{# Obsolescnce #}
|
||||||
|
<span class="object-ref-icon text_decoration" data-template-condition="obsolescence_flag">
|
||||||
|
<span class="fas fa-eye-slash object-obsolete fa-1x fa-fw"></span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{# Friendly name #}
|
||||||
|
<span data-template-text="friendlyname"></span>
|
||||||
|
|
||||||
|
{# Additional content #}
|
||||||
|
{% block additional_content %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{# Additional field #}
|
||||||
|
<div>
|
||||||
|
<i data-template-text="additional_field"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
13
templates/application/object/set/set_renderer.html.twig
Normal file
13
templates/application/object/set/set_renderer.html.twig
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<div data-template-attr-title="friendlyname">
|
||||||
|
|
||||||
|
{# obsolescence #}
|
||||||
|
{% if obsolescence_flag %}
|
||||||
|
<span class="object-ref-icon text_decoration">
|
||||||
|
<span class="fas fa-eye-slash object-obsolete fa-1x fa-fw"></span>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# friendly name #}
|
||||||
|
<span data-template-text="friendlyname">{{ friendlyname }}</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
{% block iboInputLabel %}
|
{% block iboInputLabel %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block iboInput %}
|
{% block iboInput %}
|
||||||
<input type="{{ oUIBlock.GetType() }}" id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}" value="{{ oUIBlock.GetValue()|raw }}"
|
|
||||||
|
<input type="{{ oUIBlock.GetType() }}" id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}" value="{{ oUIBlock.GetValue() }}"
|
||||||
class="{{ oUIBlock.GetBlocksInheritanceCSSClassesAsString() }} {{ oUIBlock.GetAdditionalCSSClassesAsString() }} {% if oUIBlock.IsHidden() %}ibo-is-hidden{% endif %}"
|
class="{{ oUIBlock.GetBlocksInheritanceCSSClassesAsString() }} {{ oUIBlock.GetAdditionalCSSClassesAsString() }} {% if oUIBlock.IsHidden() %}ibo-is-hidden{% endif %}"
|
||||||
data-role="ibo-input"
|
data-role="ibo-input"
|
||||||
{% if oUIBlock.IsChecked() %} checked="checked"{% endif %}
|
{% if oUIBlock.IsChecked() %} checked="checked"{% endif %}
|
||||||
|
|||||||
26
templates/base/components/input/set/layout.html.twig
Normal file
26
templates/base/components/input/set/layout.html.twig
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{# @copyright Copyright (C) 2010-2021 Combodo SARL #}
|
||||||
|
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||||
|
|
||||||
|
{# Set ui block #}
|
||||||
|
<select
|
||||||
|
id="{{ oUIBlock.GetId() }}"
|
||||||
|
name="{{ oUIBlock.GetName() }}"
|
||||||
|
multiple
|
||||||
|
style="display: none;"
|
||||||
|
>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
{# Options template #}
|
||||||
|
{% if oUIBlock.HasOptionsTemplate() %}
|
||||||
|
<template id="{{ oUIBlock.GetId() }}_options_template">
|
||||||
|
{% include oUIBlock.GetOptionsTemplate() %}
|
||||||
|
</template>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Items template #}
|
||||||
|
{% if oUIBlock.HasItemsTemplate() %}
|
||||||
|
<template id="{{ oUIBlock.GetId() }}_items_template">
|
||||||
|
{% include oUIBlock.GetItemsTemplate() %}
|
||||||
|
</template>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
206
templates/base/components/input/set/layout.ready.js.twig
Normal file
206
templates/base/components/input/set/layout.ready.js.twig
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
|
||||||
|
{# @copyright Copyright (C) 2010-2021 Combodo SARL #}
|
||||||
|
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||||
|
|
||||||
|
{# SET WIDGET #}
|
||||||
|
{% set oDataProvider = oUIBlock.GetDataProvider() %}
|
||||||
|
let oWidget{{ oUIBlock.GetId() }} = $('#{{ oUIBlock.GetId() }}').selectize({
|
||||||
|
|
||||||
|
{# Global options #}
|
||||||
|
{% if oDataProvider.IsAjaxProviderType %}
|
||||||
|
preload: true, {# call ajax directly #}
|
||||||
|
loadingClass: '',
|
||||||
|
{% endif %}
|
||||||
|
itemClass: 'item attribute-set-item',
|
||||||
|
hasError: {{ oUIBlock.HasError()|var_export() }},
|
||||||
|
placeholder: '{{ oUIBlock.GetPlaceholder() }}',
|
||||||
|
|
||||||
|
{# Remove button plugin #}
|
||||||
|
plugins: {
|
||||||
|
{# PLUGIN update operations #}
|
||||||
|
'combodo_update_operations' : {},
|
||||||
|
{# PLUGIN combodo auto position #}
|
||||||
|
'combodo_auto_position' : {
|
||||||
|
maxDropDownHeight: 300, {# in px #}
|
||||||
|
},
|
||||||
|
{# PLUGIN combodo add button #}
|
||||||
|
{% if oUIBlock.HasAddOptionButton() %}
|
||||||
|
'combodo_add_button' : {
|
||||||
|
title: '{{ oUIBlock.GetAddButtonTitle() }}'
|
||||||
|
},
|
||||||
|
{% endif %}
|
||||||
|
{% if oUIBlock.IsMultiValuesSynthesis() %}
|
||||||
|
'combodo_multi_values_synthesis' : {
|
||||||
|
|
||||||
|
tooltip_links_will_be_created_for_all_objects: '{{ 'UI:Links:Bulk:LinkWillBeCreatedForAllObjects'|dict_s }}',
|
||||||
|
tooltip_links_will_be_deleted_from_all_objects: '{{ 'UI:Links:Bulk:LinkWillBeDeletedFromAllObjects'|dict_s }}',
|
||||||
|
tooltip_links_will_be_created_for_one_object: '{{ 'UI:Links:Bulk:LinkWillBeCreatedFor1Object'|dict_s }}',
|
||||||
|
tooltip_links_will_be_deleted_from_one_object: '{{ 'UI:Links:Bulk:LinkWillBeDeletedFrom1Object'|dict_s }}',
|
||||||
|
tooltip_links_will_be_created_for_x_objects: '{{ 'UI:Links:Bulk:LinkWillBeCreatedForXObjects'|dict_s }}',
|
||||||
|
tooltip_links_will_be_deleted_from_x_objects: '{{ 'UI:Links:Bulk:LinkWillBeDeletedFromXObjects'|dict_s }}',
|
||||||
|
tooltip_links_exist_for_all_objects: '{{ 'UI:Links:Bulk:LinkExistForAllObjects'|dict_s }}',
|
||||||
|
tooltip_links_exist_for_one_object: '{{ 'UI:Links:Bulk:LinkExistForOneObject'|dict_s }}',
|
||||||
|
tooltip_links_exist_for_x_objects: '{{ 'UI:Links:Bulk:LinkExistForXObjects'|dict_s }}',
|
||||||
|
},
|
||||||
|
{% endif %}
|
||||||
|
{# PLUGIN remove button #}
|
||||||
|
{% if oUIBlock.HasRemoveItemButton() %}
|
||||||
|
'remove_button' : {},
|
||||||
|
{% endif %}
|
||||||
|
},
|
||||||
|
|
||||||
|
{# Max items you can select #}
|
||||||
|
{% if oUIBlock.GetMaxItems() is not empty %}
|
||||||
|
maxItems: {{ oUIBlock.GetMaxItems() }},
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Max options available #}
|
||||||
|
{% if oUIBlock.GetMaxOptions() is not empty %}
|
||||||
|
maxOptions: {{ oUIBlock.GetMaxOptions() }},
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Data fields #}
|
||||||
|
valueField: '{{ oDataProvider.GetDataValueField() }}',
|
||||||
|
labelField: '{{ oDataProvider.GetDataLabelField() }}',
|
||||||
|
searchField: {{ oDataProvider.GetDataSearchFields()|json_encode()|raw }},
|
||||||
|
optgroupField: '{{ oDataProvider.GetGroupField() }}',
|
||||||
|
tooltipField: '{{ oDataProvider.GetTooltipField() }}',
|
||||||
|
|
||||||
|
{# Initial options data, may be oveeride by ajax load method #}
|
||||||
|
options: {{ oDataProvider.GetOptions()|json_encode()|raw }},
|
||||||
|
|
||||||
|
{# Groups data #}
|
||||||
|
optgroups: {{ oDataProvider.GetOptionsGroups()|json_encode()|raw }},
|
||||||
|
|
||||||
|
{# Items data #}
|
||||||
|
initial: {{ oUIBlock.GetValue()|raw }},
|
||||||
|
items: {{ oUIBlock.GetValue()|raw }},
|
||||||
|
|
||||||
|
inputClass: 'ibo-input ibo-input-selectize ibo-input-set attribute-set selectize-input',
|
||||||
|
|
||||||
|
{# Ajax data load #}
|
||||||
|
{% if oDataProvider.IsAjaxProviderType %}
|
||||||
|
load: function (query, callback) {
|
||||||
|
let me = this;
|
||||||
|
$.ajax({
|
||||||
|
url: '{{ get_absolute_url_app_root() }}pages/ajax.render.php?route={{ oDataProvider.GetRoute() }}&search=' + query + '{{ oDataProvider.GetParamsAsQueryString|raw }}',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: me.convertParamArray('{{ oDataProvider.GetPostParamsAsJsonString()|raw }}'),
|
||||||
|
error: function (e) {
|
||||||
|
callback();
|
||||||
|
console.error(e);
|
||||||
|
if(!me.settings.hasError) {
|
||||||
|
me.toggleErrorClass(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
success: function (res) {
|
||||||
|
|
||||||
|
// Handle errors
|
||||||
|
if(!me.settings.hasError){
|
||||||
|
me.toggleErrorClass(!res.data.success);
|
||||||
|
if(!res.data.success) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve current input value
|
||||||
|
let aSelectedItems = me.getValue();
|
||||||
|
// Filter old options data to keep selected values
|
||||||
|
let options = Object.values(me.options);
|
||||||
|
options = options.filter(item => aSelectedItems.includes(item['{{ oDataProvider.GetDataValueField() }}']));
|
||||||
|
// Merge kept and new values
|
||||||
|
options = $.merge(options, res.data.search_data);
|
||||||
|
// Compute groups
|
||||||
|
$.each(options, function(index, value) {
|
||||||
|
me.addOptionGroup(value['{{ oDataProvider.GetGroupField() }}'], {
|
||||||
|
label: value['{{ oDataProvider.GetGroupField() }}'],
|
||||||
|
value: value['{{ oDataProvider.GetGroupField() }}']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// Clear all options
|
||||||
|
me.clearOptions();
|
||||||
|
// Add merged values
|
||||||
|
callback(options);
|
||||||
|
// Restore input value
|
||||||
|
me.addItems(aSelectedItems, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Renderers #}
|
||||||
|
render: {
|
||||||
|
|
||||||
|
{# Options #}
|
||||||
|
{% if oUIBlock.HasOptionsTemplate() %}
|
||||||
|
option: function(option) {
|
||||||
|
return CombodoGlobalToolbox.RenderTemplate('#{{ oUIBlock.GetId() }}_options_template', option, this.settings.optionClass)[0].outerHTML;
|
||||||
|
},
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Items #}
|
||||||
|
{% if oUIBlock.HasItemsTemplate() %}
|
||||||
|
item: function (item) {
|
||||||
|
return CombodoGlobalToolbox.RenderTemplate('#{{ oUIBlock.GetId() }}_items_template', item, this.settings.itemClass)[0].outerHTML;
|
||||||
|
},
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
onInitialize: function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to convert param array.
|
||||||
|
*
|
||||||
|
* EVAL_JAVASCRIPT{code_to_eval}
|
||||||
|
*/
|
||||||
|
this.convertParamArray = function(paramArray){
|
||||||
|
let postParam = JSON.parse(paramArray);
|
||||||
|
let data = {};
|
||||||
|
Object.entries(postParam).forEach(([key, value]) => {
|
||||||
|
let matches = null;
|
||||||
|
if(typeof(value) === 'string'){
|
||||||
|
matches = value.match(/^EVAL_JAVASCRIPT{(.*)}$/);
|
||||||
|
}
|
||||||
|
if(matches != null){
|
||||||
|
data[key] = eval(matches[1]);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
data[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to show error.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
this.toggleErrorClass = function(bValue){
|
||||||
|
this.$control.toggleClass('selectize-input-error', bValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
{# Error #}
|
||||||
|
this.toggleErrorClass(this.settings.hasError);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
{# On item add #}
|
||||||
|
onItemAdd: function(value, $item){
|
||||||
|
$item.addClass(this.settings.itemClass);
|
||||||
|
$item.attr({
|
||||||
|
'data-tooltip-content': this.options[value][this.settings.tooltipField],
|
||||||
|
'data-tooltip-html-enabled': true
|
||||||
|
});
|
||||||
|
CombodoTooltip.InitTooltipFromMarkup($item);
|
||||||
|
},
|
||||||
|
|
||||||
|
{# plugin combodo_add_button #}
|
||||||
|
{% if oUIBlock.HasAddOptionButton() %}
|
||||||
|
onAdd: function(){
|
||||||
|
alert('todo on add option');
|
||||||
|
},
|
||||||
|
{% endif %}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{# @copyright Copyright (C) 2010-2021 Combodo SARL #}
|
||||||
|
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||||
|
|
||||||
|
<div class="option simple-option-renderer" role="option">
|
||||||
|
|
||||||
|
<div class="simple-option-renderer--container" data-template-add-class="class">
|
||||||
|
|
||||||
|
<i class="simple-option-renderer--container--icon" data-template-add-class="icon"></i>
|
||||||
|
|
||||||
|
<span class="simple-option-renderer--container--label" data-template-text="label">
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -28,13 +28,12 @@ use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
|||||||
use Combodo\iTop\Application\UI\Base\Component\ButtonGroup\ButtonGroup;
|
use Combodo\iTop\Application\UI\Base\Component\ButtonGroup\ButtonGroup;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\ButtonGroup\ButtonGroupUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\ButtonGroup\ButtonGroupUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\CollapsibleSection\CollapsibleSection;
|
use Combodo\iTop\Application\UI\Base\Component\CollapsibleSection\CollapsibleSection;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Dashlet\DashletBadge;
|
|
||||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTable;
|
|
||||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Field\FieldUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Field\FieldUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSet;
|
use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSet;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
|
||||||
|
use Combodo\iTop\Application\UI\Base\Component\Input\Set\SetUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Panel\Panel;
|
use Combodo\iTop\Application\UI\Base\Component\Panel\Panel;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Pill\PillFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Pill\PillFactory;
|
||||||
@@ -407,24 +406,163 @@ $oPage->AddUiBlock(DataTableUIBlockFactory::MakeForStaticData('Static datatable'
|
|||||||
), array(
|
), array(
|
||||||
'a' => 'A3', 'b' => 'B3', 'c' => 'C3', 'd' => 'D3'
|
'a' => 'A3', 'b' => 'B3', 'c' => 'C3', 'd' => 'D3'
|
||||||
), array(
|
), array(
|
||||||
'a' => 'A4', 'b' => 'B4', 'c' => 'C4', 'd' => 'D4'
|
'a' => 'A4',
|
||||||
),array(
|
'b' => 'B4',
|
||||||
'@class' => 'ibo-is-red','a' => 'A5 (Red highlighting)', 'b' => 'B5', 'c' => 'C5', 'd' => 'D5'
|
'c' => 'C4',
|
||||||
),array(
|
'd' => 'D4',
|
||||||
'@class' => 'ibo-is-danger','a' => 'A6 (Danger highlighting)', 'b' => 'B6', 'c' => 'C6', 'd' => 'D6'
|
),
|
||||||
),array(
|
array(
|
||||||
'@class' => 'ibo-is-orange','a' => 'A7 (Orange highlighting)', 'b' => 'B7', 'c' => 'C7', 'd' => 'D7'
|
'@class' => 'ibo-is-red',
|
||||||
),array(
|
'a' => 'A5 (Red highlighting)',
|
||||||
'@class' => 'ibo-is-warning','a' => 'A8 (Warning highlighting)', 'b' => 'B8', 'c' => 'C8', 'd' => 'D8'
|
'b' => 'B5',
|
||||||
),array(
|
'c' => 'C5',
|
||||||
'@class' => 'ibo-is-blue','a' => 'A9 (Blue highlighting)', 'b' => 'B9', 'c' => 'C9', 'd' => 'D9'
|
'd' => 'D5',
|
||||||
),array(
|
),
|
||||||
'@class' => 'ibo-is-info','a' => 'A10 (Info highlighting)', 'b' => 'B10', 'c' => 'C10', 'd' => 'D10'
|
array(
|
||||||
),array(
|
'@class' => 'ibo-is-danger',
|
||||||
'@class' => 'ibo-is-green','a' => 'A11 (Green highlighting)', 'b' => 'B11', 'c' => 'C11', 'd' => 'D11'
|
'a' => 'A6 (Danger highlighting)',
|
||||||
),array(
|
'b' => 'B6',
|
||||||
'@class' => 'ibo-is-success','a' => 'A12 (Success highlighting)', 'b' => 'B12', 'c' => 'C12', 'd' => 'D12'
|
'c' => 'C6',
|
||||||
),
|
'd' => 'D6',
|
||||||
)));
|
),
|
||||||
|
array(
|
||||||
|
'@class' => 'ibo-is-orange',
|
||||||
|
'a' => 'A7 (Orange highlighting)',
|
||||||
|
'b' => 'B7',
|
||||||
|
'c' => 'C7',
|
||||||
|
'd' => 'D7',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'@class' => 'ibo-is-warning',
|
||||||
|
'a' => 'A8 (Warning highlighting)',
|
||||||
|
'b' => 'B8',
|
||||||
|
'c' => 'C8',
|
||||||
|
'd' => 'D8',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'@class' => 'ibo-is-blue',
|
||||||
|
'a' => 'A9 (Blue highlighting)',
|
||||||
|
'b' => 'B9',
|
||||||
|
'c' => 'C9',
|
||||||
|
'd' => 'D9',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'@class' => 'ibo-is-info',
|
||||||
|
'a' => 'A10 (Info highlighting)',
|
||||||
|
'b' => 'B10',
|
||||||
|
'c' => 'C10',
|
||||||
|
'd' => 'D10',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'@class' => 'ibo-is-green',
|
||||||
|
'a' => 'A11 (Green highlighting)',
|
||||||
|
'b' => 'B11',
|
||||||
|
'c' => 'C11',
|
||||||
|
'd' => 'D11',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'@class' => 'ibo-is-success',
|
||||||
|
'a' => 'A12 (Success highlighting)',
|
||||||
|
'b' => 'B12',
|
||||||
|
'c' => 'C12',
|
||||||
|
'd' => 'D12',
|
||||||
|
),
|
||||||
|
)));
|
||||||
|
|
||||||
|
/////////
|
||||||
|
// Set
|
||||||
|
/////////
|
||||||
|
|
||||||
|
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Set examples', 2));
|
||||||
|
|
||||||
|
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Simple', 4));
|
||||||
|
|
||||||
|
$aOptions = [
|
||||||
|
[
|
||||||
|
'label' => 'Chien',
|
||||||
|
'value' => 'dog',
|
||||||
|
'icon' => 'fas fa-dog',
|
||||||
|
'group' => 'Domestique',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => 'Chat',
|
||||||
|
'value' => 'cat',
|
||||||
|
'icon' => 'fas fa-cat',
|
||||||
|
'group' => 'Domestique',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => 'Cheval',
|
||||||
|
'value' => 'horse',
|
||||||
|
'icon' => 'fas fa-horse',
|
||||||
|
'group' => 'Domestique',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => 'Araignée',
|
||||||
|
'value' => 'spider',
|
||||||
|
'icon' => 'fas fa-spider',
|
||||||
|
'class' => 'demo_set',
|
||||||
|
'group' => 'Sauvage',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => 'Otarie',
|
||||||
|
'value' => 'otter',
|
||||||
|
'icon' => 'fas fa-otter',
|
||||||
|
'group' => 'Sauvage',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => 'Poisson',
|
||||||
|
'value' => 'fish',
|
||||||
|
'icon' => 'fas fa-fish',
|
||||||
|
'group' => 'Domestique',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => 'Grenouille',
|
||||||
|
'value' => 'frog',
|
||||||
|
'icon' => 'fas fa-frog',
|
||||||
|
'group' => 'Sauvage',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => 'Hippopotame',
|
||||||
|
'value' => 'hippo',
|
||||||
|
'icon' => 'fas fa-hippo',
|
||||||
|
'group' => 'Sauvage',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$oPage->add_style('.demo_set{color:red;}');
|
||||||
|
|
||||||
|
$oSimpleSetBlock = SetUIBlockFactory::MakeForSimple('SetSimple', $aOptions, 'label', 'value', ['label']);
|
||||||
|
$oSimpleSetBlock->SetName('SimpleSetBlock');
|
||||||
|
$oPage->AddUiBlock($oSimpleSetBlock);
|
||||||
|
|
||||||
|
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Add Option Button', 3));
|
||||||
|
|
||||||
|
$oSimpleAddSetBlock = SetUIBlockFactory::MakeForSimple('SetWithAddOption', $aOptions, 'label', 'value', ['label']);
|
||||||
|
$oSimpleAddSetBlock->SetName('SetWithAddOption');
|
||||||
|
$oSimpleAddSetBlock->SetHasAddOptionButton(true);
|
||||||
|
$oPage->AddUiBlock($oSimpleAddSetBlock);
|
||||||
|
|
||||||
|
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Renderer', 3));
|
||||||
|
|
||||||
|
$oSimpleSetBlockRenderer = SetUIBlockFactory::MakeForSimple('SetRenderer', $aOptions, 'label', 'value', ['label']);
|
||||||
|
$oSimpleSetBlockRenderer->SetName('SimpleSetBlockWithRenderer');
|
||||||
|
$oSimpleSetBlockRenderer->SetOptionsTemplate('base/components/input/set/simple_option_renderer.html.twig');
|
||||||
|
$oSimpleSetBlockRenderer->SetItemsTemplate('base/components/input/set/simple_option_renderer.html.twig');
|
||||||
|
$oPage->AddUiBlock($oSimpleSetBlockRenderer);
|
||||||
|
|
||||||
|
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('Grouping', 3));
|
||||||
|
|
||||||
|
$oSimpleSetBlockGroup = SetUIBlockFactory::MakeForSimple('SetGroup', $aOptions, 'label', 'value', ['label'], 'group');
|
||||||
|
$oSimpleSetBlockGroup->SetName('SimpleSetBlockWithGroup');
|
||||||
|
$oPage->AddUiBlock($oSimpleSetBlockGroup);
|
||||||
|
|
||||||
|
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral('OQL', 3));
|
||||||
|
|
||||||
|
$oSimpleSetBlockOql = SetUIBlockFactory::MakeForOQL('SetOql', 'Person', 'SELECT Person');
|
||||||
|
$oSimpleSetBlockOql->SetName('OqlSet');
|
||||||
|
$oPage->AddUiBlock($oSimpleSetBlockOql);
|
||||||
|
|
||||||
|
$oSimpleSetBlockOql2 = SetUIBlockFactory::MakeForOQL('SetOql2', 'Location', 'SELECT Location');
|
||||||
|
$oSimpleSetBlockOql2->SetName('OqlSet2');
|
||||||
|
$oPage->AddUiBlock($oSimpleSetBlockOql2);
|
||||||
|
|
||||||
$oPage->output();
|
$oPage->output();
|
||||||
|
|||||||
Reference in New Issue
Block a user