mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-22 10:08:45 +02:00
N°2847 - Action buttons
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
@@ -157,17 +160,17 @@ class DataTable
|
||||
$sPager = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex);
|
||||
$sActionsMenu = '';
|
||||
$sToolkitMenu = '';
|
||||
if ($bActionsMenu)
|
||||
{
|
||||
if ($bActionsMenu) {
|
||||
$sActionsMenu = $this->GetActionsMenu($oPage, $aExtraParams);
|
||||
}
|
||||
if ($bToolkitMenu)
|
||||
{
|
||||
$sToolkitMenu = $this->GetToolkitMenu($oPage, $aExtraParams);
|
||||
}
|
||||
// if ($bToolkitMenu)
|
||||
// {
|
||||
// $sToolkitMenu = $this->GetToolkitMenu($oPage, $aExtraParams);
|
||||
// }
|
||||
|
||||
$sDataTable = $this->GetHTMLTable($oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||
$sConfigDlg = $this->GetTableConfigDlg($oPage, $aColumns, $bViewLink, $iDefaultPageSize);
|
||||
|
||||
|
||||
$sHtml = "<table id=\"{$this->sDatatableContainerId}\" class=\"datatable\">";
|
||||
$sHtml .= "<tr><td>";
|
||||
$sHtml .= "<table style=\"width:100%;\">";
|
||||
@@ -355,9 +358,18 @@ EOF;
|
||||
protected function GetActionsMenu(WebPage $oPage, $aExtraParams)
|
||||
{
|
||||
$oMenuBlock = new MenuBlock($this->oSet->GetFilter(), 'list');
|
||||
|
||||
$sHtml = $oMenuBlock->GetRenderContent($oPage, $aExtraParams, $this->iListId);
|
||||
return $sHtml;
|
||||
|
||||
$oBlock = $oMenuBlock->GetRenderContent($oPage, $aExtraParams, $this->iListId);
|
||||
foreach ($oBlock->GetCssFilesUrlRecursively(true) as $sFileAbsUrl) {
|
||||
$oPage->add_linked_stylesheet($sFileAbsUrl);
|
||||
}
|
||||
// JS files
|
||||
foreach ($oBlock->GetJsFilesUrlRecursively(true) as $sFileAbsUrl) {
|
||||
$oPage->add_linked_script($sFileAbsUrl);
|
||||
}
|
||||
|
||||
$oPage->RenderInlineTemplatesRecursively($oBlock);
|
||||
return BlockRenderer::RenderBlockTemplates($oBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -236,14 +236,14 @@ EOF
|
||||
$sHTMLValue .= "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\"></select>";
|
||||
$sJsonOptions=json_encode($aOptions);
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
<<<EOF
|
||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', true, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||
oACWidget_{$this->iId}.AddSelectize('$sJsonOptions','$sDisplayValue');
|
||||
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
|
||||
$('#$this->iId').bind('change', function() { $(this).trigger('extkeychange') } );
|
||||
|
||||
JS
|
||||
EOF
|
||||
);
|
||||
}
|
||||
else
|
||||
@@ -278,7 +278,7 @@ JS
|
||||
$JSSearchMode = $this->bSearchMode ? 'true' : 'false';
|
||||
// Scripts to start the autocomplete and bind some events to it
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
<<<EOF
|
||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', false, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||
oACWidget_{$this->iId}.AddAutocomplete($iMinChars, $sWizHelperJSON);
|
||||
@@ -286,7 +286,7 @@ JS
|
||||
{
|
||||
$('body').append('<div id="ac_dlg_{$this->iId}"></div>');
|
||||
}
|
||||
JS
|
||||
EOF
|
||||
);
|
||||
}
|
||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||
@@ -544,13 +544,13 @@ EOF
|
||||
$oPage->add_ready_script("$('.multiselect').multiselect($sJSOptions);");
|
||||
}
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
<<<EOF
|
||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', true, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
|
||||
$('#$this->iId').bind('change', function() { $(this).trigger('extkeychange') } );
|
||||
|
||||
JS
|
||||
EOF
|
||||
);
|
||||
} // Switch
|
||||
}
|
||||
@@ -586,7 +586,7 @@ JS
|
||||
$JSSearchMode = $this->bSearchMode ? 'true' : 'false';
|
||||
// Scripts to start the autocomplete and bind some events to it
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
<<<EOF
|
||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', false, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||
oACWidget_{$this->iId}.AddAutocomplete($iMinChars, $sWizHelperJSON);
|
||||
@@ -594,8 +594,8 @@ JS
|
||||
{
|
||||
$('body').append('<div id="ac_dlg_{$this->iId}"></div>');
|
||||
}
|
||||
JS
|
||||
);
|
||||
EOF
|
||||
);
|
||||
}
|
||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||
{
|
||||
@@ -631,53 +631,55 @@ JS
|
||||
|
||||
public function GetSearchDialog(WebPage $oPage, $sTitle, $oCurrObject = null)
|
||||
{
|
||||
$sHTML = '<div class="wizContainer" style="vertical-align:top;"><div id="dc_'.$this->iId.'">';
|
||||
$oPage->add('<div class="wizContainer" style="vertical-align:top;"><div id="dc_'.$this->iId.'">');
|
||||
|
||||
if ( ($oCurrObject != null) && ($this->sAttCode != ''))
|
||||
{
|
||||
if (($oCurrObject != null) && ($this->sAttCode != '')) {
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($oCurrObject), $this->sAttCode);
|
||||
/** @var \DBObject $oCurrObject */
|
||||
$aArgs = $oCurrObject->ToArgsForQuery();
|
||||
$aParams = array('query_params' => $aArgs);
|
||||
$oSet = $oAttDef->GetAllowedValuesAsObjectSet($aArgs);
|
||||
$oFilter = $oSet->GetFilter();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aParams = array();
|
||||
$oFilter = new DBObjectSearch($this->sTargetClass);
|
||||
}
|
||||
$oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false, $aParams);
|
||||
$sHTML .= $oBlock->GetDisplay($oPage, $this->iId,
|
||||
array(
|
||||
'menu' => false,
|
||||
'currentId' => $this->iId,
|
||||
'table_id' => "dr_{$this->iId}",
|
||||
'table_inner_id' => "{$this->iId}_results",
|
||||
'selection_mode' => true,
|
||||
'selection_type' => 'single',
|
||||
'cssCount' => '#count_'.$this->iId)
|
||||
);
|
||||
$sHTML .= "<form id=\"fr_{$this->iId}\" OnSubmit=\"return oACWidget_{$this->iId}.DoOk();\">\n";
|
||||
$sHTML .= "<div id=\"dr_{$this->iId}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n";
|
||||
$sHTML .= "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
|
||||
$sHTML .= "</div>\n";
|
||||
$sHTML .= "<input type=\"button\" id=\"btn_cancel_{$this->iId}\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#ac_dlg_{$this->iId}').dialog('close');\"> ";
|
||||
$sHTML .= "<input type=\"button\" id=\"btn_ok_{$this->iId}\" value=\"".Dict::S('UI:Button:Ok')."\" onClick=\"oACWidget_{$this->iId}.DoOk();\">";
|
||||
$sHTML .= "<input type=\"hidden\" id=\"count_{$this->iId}\" value=\"0\">";
|
||||
$sHTML .= "</form>\n";
|
||||
$sHTML .= '</div></div>';
|
||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, $this->iId,
|
||||
array(
|
||||
'menu' => false,
|
||||
'currentId' => $this->iId,
|
||||
'table_id' => "dr_{$this->iId}",
|
||||
'table_inner_id' => "{$this->iId}_results",
|
||||
'selection_mode' => true,
|
||||
'selection_type' => 'single',
|
||||
'cssCount' => '#count_'.$this->iId
|
||||
)
|
||||
));
|
||||
$sCancel = Dict::S('UI:Button:Cancel');
|
||||
$sOK = Dict::S('UI:Button:Ok');
|
||||
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||
$oPage->add(<<<HTML
|
||||
<form id="fr_{$this->iId}" OnSubmit="return oACWidget_{$this->iId}.DoOk();">
|
||||
<div id="dr_{$this->iId}" style="vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;">
|
||||
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
||||
</div>
|
||||
<input type="button" id="btn_cancel_{$this->iId}" value="{$sCancel}" onClick="$('#ac_dlg_{$this->iId}').dialog('close');">
|
||||
<input type="button" id="btn_ok_{$this->iId}" value="{$sOK}" onClick="oACWidget_{$this->iId}.DoOk();">
|
||||
<input type="hidden" id="count_{$this->iId}" value="0">
|
||||
</form>
|
||||
</div></div>
|
||||
HTML
|
||||
);
|
||||
|
||||
$sDialogTitle = addslashes($sTitle);
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$oPage->add_ready_script(<<<JS
|
||||
$('#ac_dlg_{$this->iId}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, autoOpen: false, modal: true, title: '$sDialogTitle', resizeStop: oACWidget_{$this->iId}.UpdateSizes, close: oACWidget_{$this->iId}.OnClose });
|
||||
$('#fs_{$this->iId}').bind('submit.uiAutocomplete', oACWidget_{$this->iId}.DoSearchObjects);
|
||||
$('#dc_{$this->iId}').resize(oACWidget_{$this->iId}.UpdateSizes);
|
||||
EOF
|
||||
);
|
||||
$oPage->add($sHTML);
|
||||
JS
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -294,20 +294,17 @@ class UILinksWidgetDirect
|
||||
*/
|
||||
public function GetObjectsSelectionDlg($oPage, $oCurrentObj, $aAlreadyLinked, $aPrefillFormParam = array())
|
||||
{
|
||||
$sHtml = "<div class=\"wizContainer\" style=\"vertical-align:top;\">\n";
|
||||
$oPage->add("<div class=\"wizContainer\" style=\"vertical-align:top;\">\n");
|
||||
|
||||
$oHiddenFilter = new DBObjectSearch($this->sLinkedClass);
|
||||
if (($oCurrentObj != null) && MetaModel::IsSameFamilyBranch($this->sLinkedClass, $this->sClass))
|
||||
{
|
||||
if (($oCurrentObj != null) && MetaModel::IsSameFamilyBranch($this->sLinkedClass, $this->sClass)) {
|
||||
// Prevent linking to self if the linked object is of the same family
|
||||
// and already present in the database
|
||||
if (!$oCurrentObj->IsNew())
|
||||
{
|
||||
if (!$oCurrentObj->IsNew()) {
|
||||
$oHiddenFilter->AddCondition('id', $oCurrentObj->GetKey(), '!=');
|
||||
}
|
||||
}
|
||||
if (count($aAlreadyLinked) > 0)
|
||||
{
|
||||
if (count($aAlreadyLinked) > 0) {
|
||||
$oHiddenFilter->AddCondition('id', $aAlreadyLinked, 'NOTIN');
|
||||
}
|
||||
$oHiddenCriteria = $oHiddenFilter->GetCriteria();
|
||||
@@ -319,18 +316,14 @@ class UILinksWidgetDirect
|
||||
if ($valuesDef === null)
|
||||
{
|
||||
$oFilter = new DBObjectSearch($this->sLinkedClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!$valuesDef instanceof ValueSetObjects)
|
||||
{
|
||||
} else {
|
||||
if (!$valuesDef instanceof ValueSetObjects) {
|
||||
throw new Exception('Error: only ValueSetObjects are supported for "allowed_values" in AttributeLinkedSet ('.$this->sClass.'/'.$this->sAttCode.').');
|
||||
}
|
||||
$oFilter = DBObjectSearch::FromOQL($valuesDef->GetFilterExpression());
|
||||
}
|
||||
|
||||
if ($oCurrentObj != null)
|
||||
{
|
||||
if ($oCurrentObj != null) {
|
||||
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
||||
|
||||
$aArgs = array_merge($oCurrentObj->ToArgs('this'), $oFilter->GetInternalParams());
|
||||
@@ -339,7 +332,7 @@ class UILinksWidgetDirect
|
||||
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
||||
}
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||
$sHtml .= $oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->sInputid}",
|
||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->sInputid}",
|
||||
array(
|
||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->sInputid}",
|
||||
'table_id' => "add_{$this->sInputid}",
|
||||
@@ -349,16 +342,22 @@ class UILinksWidgetDirect
|
||||
'query_params' => $oFilter->GetInternalParams(),
|
||||
'hidden_criteria' => $sHiddenCriteria,
|
||||
)
|
||||
);
|
||||
$sHtml .= "<form id=\"ObjectsAddForm_{$this->sInputid}\">\n";
|
||||
$sHtml .= "<div id=\"SearchResultsToAdd_{$this->sInputid}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n";
|
||||
$sHtml .= "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= "<input type=\"hidden\" id=\"count_{$this->sInputid}\" value=\"0\"/>";
|
||||
$sHtml .= "<button type=\"button\" class=\"cancel\">".Dict::S('UI:Button:Cancel')."</button> <button type=\"button\" class=\"ok\" disabled=\"disabled\">".Dict::S('UI:Button:Add')."</button>";
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= "</form>\n";
|
||||
$oPage->add($sHtml);
|
||||
));
|
||||
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||
$sCancel = Dict::S('UI:Button:Cancel');
|
||||
$sAdd = Dict::S('UI:Button:Add');
|
||||
|
||||
$oPage->add(<<<HTML
|
||||
<form id="ObjectsAddForm_{$this->sInputid}">
|
||||
<div id="SearchResultsToAdd_{$this->sInputid}" style="vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;">
|
||||
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
||||
</div>
|
||||
<input type="hidden" id="count_{$this->sInputid}" value="0"/>
|
||||
<button type="button" class="cancel">{$sCancel}</button> <button type="button" class="ok" disabled="disabled">{$sAdd}</button>
|
||||
</form>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -513,31 +513,27 @@ JS
|
||||
*/
|
||||
public function GetObjectPickerDialog($oPage, $oCurrentObj, $sJson, $aAlreadyLinkedIds = array(), $aPrefillFormParam = array())
|
||||
{
|
||||
$sHtml = "<div class=\"wizContainer\" style=\"vertical-align:top;\">\n";
|
||||
$oPage->add("<div class=\"wizContainer\" style=\"vertical-align:top;\">\n");
|
||||
|
||||
$oAlreadyLinkedFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0)
|
||||
{
|
||||
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0) {
|
||||
$oAlreadyLinkedFilter->AddCondition('id', $aAlreadyLinkedIds, 'NOTIN');
|
||||
$oAlreadyLinkedExpression = $oAlreadyLinkedFilter->GetCriteria();
|
||||
$sAlreadyLinkedExpression = $oAlreadyLinkedExpression->Render();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sAlreadyLinkedExpression = '';
|
||||
}
|
||||
|
||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||
|
||||
if(!empty($oCurrentObj))
|
||||
{
|
||||
if (!empty($oCurrentObj)) {
|
||||
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
||||
$aPrefillFormParam['filter'] = $oFilter;
|
||||
$aPrefillFormParam['dest_class'] = $this->m_sRemoteClass;
|
||||
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
||||
}
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||
$sHtml .= $oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
||||
array(
|
||||
'menu' => false,
|
||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
|
||||
@@ -548,16 +544,23 @@ JS
|
||||
'cssCount' => '#count_'.$this->m_sAttCode.$this->m_sNameSuffix,
|
||||
'query_params' => $oFilter->GetInternalParams(),
|
||||
'hidden_criteria' => $sAlreadyLinkedExpression,
|
||||
));
|
||||
$sHtml .= "<form id=\"ObjectsAddForm_{$this->m_sAttCode}{$this->m_sNameSuffix}\">\n";
|
||||
$sHtml .= "<div id=\"SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n";
|
||||
$sHtml .= "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= "<input type=\"hidden\" id=\"count_{$this->m_sAttCode}{$this->m_sNameSuffix}\" value=\"0\"/>";
|
||||
$sHtml .= "<input type=\"button\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('close');\"> <input id=\"btn_ok_{$this->m_sAttCode}{$this->m_sNameSuffix}\" disabled=\"disabled\" type=\"button\" onclick=\"return oWidget{$this->m_iInputId}.DoAddObjects(this.id);\" value=\"".Dict::S('UI:Button:Add')."\">";
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= "</form>\n";
|
||||
$oPage->add($sHtml);
|
||||
)));
|
||||
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||
$sCancel = Dict::S('UI:Button:Cancel');
|
||||
$sAdd = Dict::S('UI:Button:Add');
|
||||
|
||||
$oPage->add(<<<HTML
|
||||
<form id="ObjectsAddForm_{$this->m_sAttCode}{$this->m_sNameSuffix}">
|
||||
<div id="SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}" style="vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;">
|
||||
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
||||
</div>
|
||||
<input type="hidden" id="count_{$this->m_sAttCode}{$this->m_sNameSuffix}" value="0"/>
|
||||
<input type="button" value="{$sCancel}" onClick="$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('close');"> <input id="btn_ok_{$this->m_sAttCode}{$this->m_sNameSuffix}" disabled="disabled" type="button" onclick="return oWidget{$this->m_iInputId}.DoAddObjects(this.id);" value="{$sAdd}">
|
||||
</form>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
|
||||
$oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, autoOpen: false, modal: true, resizeStop: oWidget{$this->m_iInputId}.UpdateSizes });");
|
||||
$oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('option', {title:'".addslashes(Dict::Format('UI:AddObjectsOf_Class_LinkedWith_Class', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName($this->m_sClass)))."'});");
|
||||
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix} form').bind('submit.uilinksWizard', oWidget{$this->m_iInputId}.SearchObjectsToAdd);");
|
||||
|
||||
@@ -40,12 +40,12 @@ class UISearchFormForeignKeys
|
||||
*/
|
||||
public function ShowModalSearchForeignKeys($oPage, $sTitle)
|
||||
{
|
||||
$sHtml = "<div class=\"wizContainer\" style=\"vertical-align:top;\">\n";
|
||||
$oPage->add("<div class=\"wizContainer\" style=\"vertical-align:top;\">\n");
|
||||
|
||||
$oFilter = new DBObjectSearch($this->m_sRemoteClass);
|
||||
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||
$sHtml .= $oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_iInputId}",
|
||||
$oPage->AddUiBlock($oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_iInputId}",
|
||||
array(
|
||||
'menu' => false,
|
||||
'result_list_outer_selector' => "SearchResultsToAdd_{$this->m_iInputId}",
|
||||
@@ -54,16 +54,23 @@ class UISearchFormForeignKeys
|
||||
'selection_mode' => true,
|
||||
'cssCount' => "#count_{$this->m_iInputId}",
|
||||
'query_params' => $oFilter->GetInternalParams(),
|
||||
));
|
||||
$sHtml .= "<form id=\"ObjectsAddForm_{$this->m_iInputId}\">\n";
|
||||
$sHtml .= "<div id=\"SearchResultsToAdd_{$this->m_iInputId}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n";
|
||||
$sHtml .= "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= "<input type=\"hidden\" id=\"count_{$this->m_iInputId}\" value=\"0\"/>";
|
||||
$sHtml .= "<input type=\"button\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#dlg_{$this->m_iInputId}').dialog('close');\"> <input id=\"btn_ok_{$this->m_iInputId}\" disabled=\"disabled\" type=\"button\" onclick=\"return oForeignKeysWidget{$this->m_iInputId}.DoAddObjects(this.id);\" value=\"".Dict::S('UI:Button:Add')."\">";
|
||||
$sHtml .= "</div>\n";
|
||||
$sHtml .= "</form>\n";
|
||||
$oPage->add($sHtml);
|
||||
)));
|
||||
$sEmptyList = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||
$sCancel = Dict::S('UI:Button:Cancel');
|
||||
$sAdd = Dict::S('UI:Button:Add');
|
||||
|
||||
$oPage->add(<<<HTML
|
||||
<form id="ObjectsAddForm_{$this->m_iInputId}">
|
||||
<div id="SearchResultsToAdd_{$this->m_iInputId}" style="vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;">
|
||||
<div style="background: #fff; border:0; text-align:center; vertical-align:middle;"><p>{$sEmptyList}</p></div>
|
||||
</div>
|
||||
<input type="hidden" id="count_{$this->m_iInputId}" value="0"/>
|
||||
<input type="button" value="{$sCancel}" onClick="$('#dlg_{$this->m_iInputId}').dialog('close');"> <input id="btn_ok_{$this->m_iInputId}" disabled="disabled" type="button" onclick="return oForeignKeysWidget{$this->m_iInputId}.DoAddObjects(this.id);" value="{$sAdd}">
|
||||
</form>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
|
||||
$oPage->add_ready_script("$('#dlg_{$this->m_iInputId}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, autoOpen: false, modal: true, resizeStop: oForeignKeysWidget{$this->m_iInputId}.UpdateSizes });");
|
||||
$oPage->add_ready_script("$('#dlg_{$this->m_iInputId}').dialog('option', {title:'$sTitle'});");
|
||||
$oPage->add_ready_script("$('#SearchFormToAdd_{$this->m_iInputId} form').bind('submit.uilinksWizard', oForeignKeysWidget{$this->m_iInputId}.SearchObjectsToAdd);");
|
||||
|
||||
@@ -20,4 +20,5 @@
|
||||
@import "form";
|
||||
@import "input";
|
||||
@import "fieldset";
|
||||
@import "field";
|
||||
@import "field";
|
||||
@import "toolbar";
|
||||
@@ -303,8 +303,13 @@ $ibo-button-icon--padding-right: 4px !default;
|
||||
& ~ .ibo-button {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
&.ibo-action-button {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-button-icon {
|
||||
padding-right: $ibo-button-icon--padding-right;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
8
css/backoffice/components/_toolbar.scss
Normal file
8
css/backoffice/components/_toolbar.scss
Normal file
@@ -0,0 +1,8 @@
|
||||
/*!
|
||||
* copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
.ibo-action-toolbar {
|
||||
position: relative;
|
||||
}
|
||||
@@ -184,6 +184,7 @@ return array(
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\Title\\Title' => $baseDir . '/sources/application/UI/Component/Title/Title.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\Title\\TitleFactory' => $baseDir . '/sources/application/UI/Component/Title/TitleFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\Title\\TitleForObjectDetails' => $baseDir . '/sources/application/UI/Component/Title/TitleForObjectDetails.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\Toolbar\\Toolbar' => $baseDir . '/sources/application/UI/Component/Toolbar/Toolbar.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntry' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/ActivityEntry.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntryFactory' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/ActivityEntryFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\CMDBChangeOp\\CMDBChangeOpAttachmentAddedFactory' => $baseDir . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/CMDBChangeOp/CMDBChangeOpAttachmentAddedFactory.php',
|
||||
|
||||
@@ -414,6 +414,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\Title\\Title' => __DIR__ . '/../..' . '/sources/application/UI/Component/Title/Title.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\Title\\TitleFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/Title/TitleFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\Title\\TitleForObjectDetails' => __DIR__ . '/../..' . '/sources/application/UI/Component/Title/TitleForObjectDetails.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\Toolbar\\Toolbar' => __DIR__ . '/../..' . '/sources/application/UI/Component/Toolbar/Toolbar.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntry' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/ActivityEntry.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\ActivityEntryFactory' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/ActivityEntryFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\ActivityPanel\\ActivityEntry\\CMDBChangeOp\\CMDBChangeOpAttachmentAddedFactory' => __DIR__ . '/../..' . '/sources/application/UI/Layout/ActivityPanel/ActivityEntry/CMDBChangeOp/CMDBChangeOpAttachmentAddedFactory.php',
|
||||
|
||||
@@ -123,21 +123,20 @@ EOF
|
||||
|
||||
$oFavoriteOrganizationsBlock = new Panel(Dict::S('UI:FavoriteOrganizations'), array(), 'grey', 'ibo-favorite-organizations');
|
||||
|
||||
$sFavoriteOrganizationsHtml = '';
|
||||
$sFavoriteOrganizationsHtml .= Dict::S('UI:FavoriteOrganizations+');
|
||||
$sFavoriteOrganizationsHtml .= '<form method="post">';
|
||||
$oFavoriteOrganizationsBlock->AddHtml(Dict::S('UI:FavoriteOrganizations+'));
|
||||
$oFavoriteOrganizationsBlock->AddHtml('<form method="post">');
|
||||
// Favorite organizations: the organizations listed in the drop-down menu
|
||||
$sOQL = ApplicationMenu::GetFavoriteSiloQuery();
|
||||
$oFilter = DBObjectSearch::FromOQL($sOQL);
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$sFavoriteOrganizationsHtml .= $oBlock->GetDisplay($oP, 1, array(
|
||||
$oFavoriteOrganizationsBlock->AddSubBlock($oBlock->GetDisplay($oP, 1, array(
|
||||
'menu' => false,
|
||||
'selection_mode' => true,
|
||||
'selection_type' => 'multiple',
|
||||
'cssCount' => '.selectedCount',
|
||||
'table_id' => 'user_prefs',
|
||||
));
|
||||
$sFavoriteOrganizationsHtml .= $oAppContext->GetForForm();
|
||||
)));
|
||||
$oFavoriteOrganizationsBlock->AddSubBlock($oAppContext->GetForFormBlock());
|
||||
|
||||
// - Cancel button
|
||||
$oFavoriteOrganizationsCancelButton = ButtonFactory::MakeForSecondaryAction(Dict::S('UI:Button:Cancel'));
|
||||
@@ -202,8 +201,6 @@ EOF
|
||||
);
|
||||
}
|
||||
|
||||
$oFavoriteOrganizationsHtmlBlock = new Html($sFavoriteOrganizationsHtml);
|
||||
$oFavoriteOrganizationsBlock->AddSubBlock($oFavoriteOrganizationsHtmlBlock);
|
||||
$oFavoriteOrganizationsBlock->AddSubBlock($oFavoriteOrganizationsCancelButton);
|
||||
$oFavoriteOrganizationsBlock->AddSubBlock($oFavoriteOrganizationsSubmitButton);
|
||||
$oFavoriteOrganizationsBlock->AddSubBlock($oFavoriteOrganizationsEndHtmlBlock);
|
||||
@@ -217,18 +214,16 @@ EOF
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$oShortcutsBlock = new Panel(Dict::S('Menu:MyShortcuts'), array(), 'grey', 'ibo-shortcuts');
|
||||
$sShortcutsHtml = '';
|
||||
$oBMSearch = new DBObjectSearch('Shortcut');
|
||||
$oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||
|
||||
$aExtraParams = array();
|
||||
$oBlock = new DisplayBlock($oBMSearch, 'list', false, $aExtraParams);
|
||||
$sShortcutsHtml .= $oBlock->GetDisplay($oP, 'shortcut_list', array('view_link' => false, 'menu' => false, 'toolkit_menu' => false, 'selection_mode' => true, 'selection_type' => 'multiple', 'cssCount'=> '#shortcut_selection_count', 'table_id' => 'user_prefs_shortcuts'));
|
||||
$sShortcutsHtml .='<p>';
|
||||
$oShortcutsBlock->AddSubBlock($oBlock->GetDisplay($oP, 'shortcut_list', array('view_link' => false, 'menu' => false, 'toolkit_menu' => false, 'selection_mode' => true, 'selection_type' => 'multiple', 'cssCount' => '#shortcut_selection_count', 'table_id' => 'user_prefs_shortcuts')));
|
||||
$sShortcutsHtml = '<p>';
|
||||
|
||||
$oSet = new DBObjectSet($oBMSearch);
|
||||
if ($oSet->Count() > 0)
|
||||
{
|
||||
if ($oSet->Count() > 0) {
|
||||
$sButtons = '<img src="../images/tv-item-last.gif">';
|
||||
$sButtons .= '<button id="shortcut_btn_rename">'.Dict::S('UI:Button:Rename').'</button>';
|
||||
$sButtons .= '<button id="shortcut_btn_delete">'.Dict::S('UI:Button:Delete').'</button>';
|
||||
|
||||
@@ -94,6 +94,8 @@ class Button extends UIBlock
|
||||
protected $sJsCode;
|
||||
/** @var string $sOnClickJsCode */
|
||||
protected $sOnClickJsCode;
|
||||
/** @var array */
|
||||
protected $aAdditionalCSSClasses;
|
||||
|
||||
/**
|
||||
* Button constructor.
|
||||
@@ -127,6 +129,7 @@ class Button extends UIBlock
|
||||
$this->sJsCode = $sJsCode;
|
||||
$this->sOnClickJsCode = $sOnClickJsCode;
|
||||
$this->bIsDisabled = false;
|
||||
$this->aAdditionalCSSClasses = [];
|
||||
|
||||
parent::__construct($sId);
|
||||
}
|
||||
@@ -160,7 +163,7 @@ class Button extends UIBlock
|
||||
|
||||
/**
|
||||
* @param string $sType
|
||||
*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetType(string $sType)
|
||||
@@ -179,7 +182,7 @@ class Button extends UIBlock
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetName(string $sName)
|
||||
@@ -198,7 +201,7 @@ class Button extends UIBlock
|
||||
|
||||
/**
|
||||
* @param string $sValue
|
||||
*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetValue(string $sValue)
|
||||
@@ -217,7 +220,7 @@ class Button extends UIBlock
|
||||
|
||||
/**
|
||||
* @param string $sTooltip
|
||||
*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetTooltip(string $sTooltip)
|
||||
@@ -236,7 +239,7 @@ class Button extends UIBlock
|
||||
|
||||
/**
|
||||
* @param string $sIconClass
|
||||
*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetIconClass(string $sIconClass)
|
||||
@@ -255,7 +258,7 @@ class Button extends UIBlock
|
||||
|
||||
/**
|
||||
* @param string $sActionType
|
||||
*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetActionType(string $sActionType)
|
||||
@@ -275,7 +278,7 @@ class Button extends UIBlock
|
||||
|
||||
/**
|
||||
* @param string $sColor
|
||||
*
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetColor(string $sColor)
|
||||
@@ -302,6 +305,7 @@ class Button extends UIBlock
|
||||
$this->bIsDisabled = $bIsDisabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@@ -341,4 +345,24 @@ class Button extends UIBlock
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetAdditionalCSSClass(): string
|
||||
{
|
||||
return implode(' ', $this->aAdditionalCSSClasses);
|
||||
}
|
||||
|
||||
public function AddCSSClasses(string $sCSSClasses): self
|
||||
{
|
||||
foreach (explode(' ', $sCSSClasses) as $sCSSClass) {
|
||||
if (!empty($sCSSClass)) {
|
||||
$this->aAdditionalCSSClasses[$sCSSClass] = $sCSSClass;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -285,4 +285,40 @@ class ButtonFactory
|
||||
|
||||
return $oButton;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a basis Button component for any purpose
|
||||
*
|
||||
* @param string $sLabel
|
||||
* @param string $sName See Button::$sName
|
||||
* @param string $sIconClass
|
||||
* @param string $sURL
|
||||
* @param string $sTarget
|
||||
* @param string|null $sId
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\Button\Button
|
||||
*/
|
||||
public static function MakeAlternativeNeutralActionButton(string $sLabel, string $sName, string $sIconClass = '', string $sURL = '', string $sTarget = '', ?string $sId = null): Button
|
||||
{
|
||||
$oButton = new Button($sLabel, $sId);
|
||||
$oButton->SetActionType(Button::ENUM_ACTION_TYPE_ALTERNATIVE)
|
||||
->SetColor(Button::ENUM_COLOR_NEUTRAL)
|
||||
->SetName($sName);
|
||||
|
||||
if (!empty($sIconClass)) {
|
||||
$oButton->SetIconClass($sIconClass);
|
||||
}
|
||||
|
||||
if (!empty($sURL)) {
|
||||
if (empty($sTarget)) {
|
||||
$sJS = "window.location='{$sURL}';";
|
||||
} else {
|
||||
$sJS = "window.open('{$sURL}', '{$sTarget}');";
|
||||
}
|
||||
$oButton->SetOnClickJsCode($sJS);
|
||||
}
|
||||
|
||||
return $oButton;
|
||||
}
|
||||
}
|
||||
@@ -21,10 +21,8 @@ namespace Combodo\iTop\Application\UI\Component\PopoverMenu;
|
||||
|
||||
|
||||
|
||||
use appUserPreferences;
|
||||
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItemFactory;
|
||||
use Dict;
|
||||
use iNewsroomProvider;
|
||||
use JSPopupMenuItem;
|
||||
use MetaModel;
|
||||
use URLPopupMenuItem;
|
||||
@@ -198,4 +196,51 @@ class PopoverMenuFactory
|
||||
|
||||
return $aItems;
|
||||
}
|
||||
|
||||
public static function MakeMenuForActions(string $sId, array $aMenuItems): PopoverMenu
|
||||
{
|
||||
$oMenu = new PopoverMenu($sId);
|
||||
|
||||
$bFirst = true;
|
||||
foreach ($aMenuItems as $sSection => $aActions) {
|
||||
$aItems = [];
|
||||
|
||||
if (!$bFirst) {
|
||||
$aItems[] = PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem(
|
||||
new \SeparatorPopupMenuItem()
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($aActions as $aAction) {
|
||||
if (!empty($aAction['on_click'])) {
|
||||
// JS
|
||||
$oPopoverMenuItem = PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem(
|
||||
new JSPopupMenuItem(
|
||||
$aAction['uid'],
|
||||
$aAction['label'],
|
||||
$aAction['on_click'])
|
||||
);
|
||||
} else {
|
||||
// URL
|
||||
$oPopoverMenuItem = PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem(
|
||||
new URLPopupMenuItem(
|
||||
$aAction['uid'],
|
||||
$aAction['label'],
|
||||
$aAction['url'],
|
||||
$aAction['target'])
|
||||
);
|
||||
}
|
||||
if (!empty($aAction['css_classes'])) {
|
||||
$oPopoverMenuItem->SetCssClasses($aAction['css_classes']);
|
||||
}
|
||||
$aItems[] = $oPopoverMenuItem;
|
||||
}
|
||||
|
||||
$oMenu->AddSection($sSection)
|
||||
->SetItems($sSection, $aItems);
|
||||
$bFirst = false;
|
||||
}
|
||||
|
||||
return $oMenu;
|
||||
}
|
||||
}
|
||||
22
sources/application/UI/Component/Toolbar/Toolbar.php
Normal file
22
sources/application/UI/Component/Toolbar/Toolbar.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\Toolbar;
|
||||
|
||||
|
||||
use Combodo\iTop\Application\UI\Layout\UIContentBlock;
|
||||
|
||||
/**
|
||||
* Class Toolbar
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI\Component\Toolbar
|
||||
*/
|
||||
class Toolbar extends UIContentBlock
|
||||
{
|
||||
// Overloaded constants
|
||||
public const BLOCK_CODE = 'ibo-toolbar';
|
||||
public const HTML_TEMPLATE_REL_PATH = 'components/toolbar/layout';
|
||||
}
|
||||
@@ -18,19 +18,23 @@ class UIContentBlock extends UIBlock implements iUIContentBlock
|
||||
public const BLOCK_CODE = 'ibo-contentblock';
|
||||
public const HTML_TEMPLATE_REL_PATH = 'layouts/contentblock/layout';
|
||||
public const JS_TEMPLATE_REL_PATH = 'layouts/contentblock/layout';
|
||||
|
||||
/** @var array */
|
||||
protected $aCSSClasses;
|
||||
/** @var array */
|
||||
protected $aSubBlocks;
|
||||
|
||||
/**
|
||||
* UIContentBlock constructor.
|
||||
*
|
||||
* @param string|null $sName
|
||||
* @param string $sContainerClass
|
||||
*/
|
||||
public function __construct(string $sName = null)
|
||||
public function __construct(string $sName = null, string $sContainerClass = '')
|
||||
{
|
||||
parent::__construct($sName);
|
||||
|
||||
$this->aSubBlocks = [];
|
||||
$this->SetCSSClasses($sContainerClass);
|
||||
}
|
||||
|
||||
public function AddHtml(string $sHtml): iUIBlock
|
||||
@@ -110,4 +114,40 @@ class UIContentBlock extends UIBlock implements iUIContentBlock
|
||||
{
|
||||
return array_key_exists($sId, $this->aSubBlocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetCSSClasses(): string
|
||||
{
|
||||
return implode(' ', $this->aCSSClasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sCSSClasses
|
||||
*
|
||||
* @return UIContentBlock
|
||||
*/
|
||||
public function SetCSSClasses(string $sCSSClasses): UIContentBlock
|
||||
{
|
||||
$this->aCSSClasses = [];
|
||||
$this->AddCSSClasses($sCSSClasses);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sCSSClasses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddCSSClasses(string $sCSSClasses): UIContentBlock
|
||||
{
|
||||
foreach (explode(' ', $sCSSClasses) as $sCSSClass) {
|
||||
if (!empty($sCSSClass)) {
|
||||
$this->aCSSClasses[$sCSSClass] = $sCSSClass;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
||||
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu;
|
||||
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuFactory;
|
||||
use Combodo\iTop\Application\UI\iUIBlock;
|
||||
use Combodo\iTop\Application\UI\Layout\UIContentBlock;
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
@@ -313,8 +315,11 @@ class WebPage implements Page
|
||||
* @return \Combodo\iTop\Application\UI\iUIBlock block added
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function AddUiBlock(iUIBlock $oBlock): iUIBlock
|
||||
public function AddUiBlock(?iUIBlock $oBlock): ?iUIBlock
|
||||
{
|
||||
if (is_null($oBlock)) {
|
||||
return null;
|
||||
}
|
||||
$this->oContentLayout->AddSubBlock($oBlock);
|
||||
return $oBlock;
|
||||
}
|
||||
@@ -703,7 +708,7 @@ class WebPage implements Page
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
protected function RenderInlineTemplatesRecursively(iUIBlock $oBlock): void
|
||||
public function RenderInlineTemplatesRecursively(iUIBlock $oBlock): void
|
||||
{
|
||||
$oBlockRenderer = new BlockRenderer($oBlock);
|
||||
$sInlineScript = trim($oBlockRenderer->RenderJsInline());
|
||||
@@ -978,32 +983,26 @@ class WebPage implements Page
|
||||
{
|
||||
$sPrevUrl = '';
|
||||
$sHtml = '';
|
||||
if (!$this->IsPrintableVersion())
|
||||
{
|
||||
foreach ($aActions as $sActionId => $aAction)
|
||||
{
|
||||
if (!$this->IsPrintableVersion()) {
|
||||
foreach ($aActions as $sActionId => $aAction) {
|
||||
$sDataActionId = 'data-action-id="'.$sActionId.'"';
|
||||
$sClass = isset($aAction['css_classes']) ? 'class="'.implode(' ', $aAction['css_classes']).'"' : '';
|
||||
$sOnClick = isset($aAction['onclick']) ? 'onclick="'.htmlspecialchars($aAction['onclick'], ENT_QUOTES,
|
||||
"UTF-8").'"' : '';
|
||||
$sTarget = isset($aAction['target']) ? "target=\"{$aAction['target']}\"" : "";
|
||||
if (empty($aAction['url']))
|
||||
{
|
||||
if (empty($aAction['url'])) {
|
||||
if ($sPrevUrl != '') // Don't output consecutively two separators...
|
||||
{
|
||||
$sHtml .= "<li $sDataActionId>{$aAction['label']}</li>";
|
||||
}
|
||||
$sPrevUrl = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sHtml .= "<li $sDataActionId><a $sTarget href=\"{$aAction['url']}\" $sClass $sOnClick>{$aAction['label']}</a></li>";
|
||||
$sPrevUrl = $aAction['url'];
|
||||
}
|
||||
}
|
||||
$sHtml .= "</ul></li></ul></div>";
|
||||
foreach (array_reverse($aFavoriteActions) as $sActionId => $aAction)
|
||||
{
|
||||
foreach (array_reverse($aFavoriteActions) as $sActionId => $aAction) {
|
||||
$sTarget = isset($aAction['target']) ? " target=\"{$aAction['target']}\"" : "";
|
||||
$sHtml .= "<div class=\"actions_button\" data-action-id=\"$sActionId\"><a $sTarget href='{$aAction['url']}'>{$aAction['label']}</a></div>";
|
||||
}
|
||||
@@ -1012,6 +1011,39 @@ class WebPage implements Page
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sId
|
||||
* @param array $aActions
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu|null
|
||||
*/
|
||||
public function GetPopoverMenu(string $sId, array $aActions): ?PopoverMenu
|
||||
{
|
||||
if ($this->IsPrintableVersion()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$iSectionIndex = 0;
|
||||
$aMenuItems = [];
|
||||
foreach ($aActions as $sActionId => $aAction) {
|
||||
if (empty($aAction['url'])) {
|
||||
$iSectionIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$aMenuItems["{$sId}_section_{$iSectionIndex}"][] = [
|
||||
'uid' => $sActionId,
|
||||
'css_classes' => isset($aAction['css_classes']) ? $aAction['css_classes'] : [],
|
||||
'on_click' => isset($aAction['onclick']) ? $aAction['onclick'] : '',
|
||||
'target' => isset($aAction['target']) ? $aAction['target'] : '',
|
||||
'url' => $aAction['url'],
|
||||
'label' => $aAction['label'],
|
||||
];
|
||||
}
|
||||
|
||||
return PopoverMenuFactory::MakeMenuForActions($sId, $aMenuItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bReturnOutput
|
||||
*
|
||||
@@ -1019,16 +1051,13 @@ class WebPage implements Page
|
||||
*/
|
||||
protected function output_dict_entries($bReturnOutput = false)
|
||||
{
|
||||
if ((count($this->a_dict_entries) > 0) || (count($this->a_dict_entries_prefixes) > 0))
|
||||
{
|
||||
if (class_exists('Dict'))
|
||||
{
|
||||
if ((count($this->a_dict_entries) > 0) || (count($this->a_dict_entries_prefixes) > 0)) {
|
||||
if (class_exists('Dict')) {
|
||||
// The dictionary may not be available for example during the setup...
|
||||
// Create a specific dictionary file and load it as a JS script
|
||||
$sSignature = $this->get_dict_signature();
|
||||
$sJSFileName = utils::GetCachePath().$sSignature.'.js';
|
||||
if (!file_exists($sJSFileName) && is_writable(utils::GetCachePath()))
|
||||
{
|
||||
if (!file_exists($sJSFileName) && is_writable(utils::GetCachePath())) {
|
||||
file_put_contents($sJSFileName, $this->get_dict_file_content());
|
||||
}
|
||||
// Load the dictionary as the first javascript file, so that other JS file benefit from the translations
|
||||
|
||||
@@ -893,7 +893,7 @@ EOF;
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
protected function RenderInlineTemplatesRecursively(iUIBlock $oBlock): void
|
||||
public function RenderInlineTemplatesRecursively(iUIBlock $oBlock): void
|
||||
{
|
||||
$oBlockRenderer = new BlockRenderer($oBlock);
|
||||
$this->add_init_script($oBlockRenderer->RenderJsInline());
|
||||
@@ -1326,8 +1326,11 @@ EOF;
|
||||
return null;
|
||||
}
|
||||
|
||||
public function AddUiBlock(iUIBlock $oBlock): iUIBlock
|
||||
public function AddUiBlock(?iUIBlock $oBlock): ?iUIBlock
|
||||
{
|
||||
if (is_null($oBlock)) {
|
||||
return null;
|
||||
}
|
||||
if (($this->m_oTabs->GetCurrentTabContainer() != '') && ($this->m_oTabs->GetCurrentTab() != '')) {
|
||||
return $this->m_oTabs->AddUIBlockToCurrentTab($oBlock);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<button id="{{ oUIBlock.GetId() }}"
|
||||
class="ibo-button ibo-is-{{ oUIBlock.GetActionType() }} ibo-is-{{ oUIBlock.GetColor() }}"
|
||||
class="ibo-button ibo-is-{{ oUIBlock.GetActionType() }} ibo-is-{{ oUIBlock.GetColor() }} {{ oUIBlock.GetAdditionalCSSClass() }}"
|
||||
type="{{ oUIBlock.GetType() }}"
|
||||
name="{{ oUIBlock.GetName() }}"
|
||||
value="{{ oUIBlock.GetValue() }}"
|
||||
|
||||
1
templates/components/toolbar/layout.html.twig
Normal file
1
templates/components/toolbar/layout.html.twig
Normal file
@@ -0,0 +1 @@
|
||||
{% extends 'layouts/contentblock/layout.html.twig' %}
|
||||
@@ -1,7 +1,17 @@
|
||||
{% apply spaceless %}
|
||||
{% block iboContentBlockContainer %}
|
||||
|
||||
{% if oUIBlock.GetCSSClasses() %}
|
||||
<div id="{{ oUIBlock.GetId() }}" class="{{ oUIBlock.GetCSSClasses() }}">
|
||||
{% endif %}
|
||||
|
||||
{% for oSubBlock in oUIBlock.GetSubBlocks() %}
|
||||
{{ render_block(oSubBlock, {aPage: aPage}) }}
|
||||
{% endfor %}
|
||||
|
||||
{% if oUIBlock.GetCSSClasses() %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
{% endapply %}
|
||||
Reference in New Issue
Block a user