mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-21 00:02:17 +02:00
N°9167 Use ExtensionDetails UIBlocks instead of table
This commit is contained in:
@@ -63,3 +63,14 @@ $ibo-extension-details--actions--button--padding-x: $ibo-button--padding-x !defa
|
|||||||
.ibo-extension-details--actions:has(.toggler-install:not(:disabled)) .ibo-popover-menu--section a[data-resource-id="force_uninstall"] {
|
.ibo-extension-details--actions:has(.toggler-install:not(:disabled)) .ibo-popover-menu--section a[data-resource-id="force_uninstall"] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ibo-extension-details .ibo-popover-menu ~ .ibo-button{
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.ibo-extension-details .ibo-popover-menu:has(.ibo-popover-menu--item) ~ .ibo-button{
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ibo-extension-details .ibo-toggler--wrapper:has(.ibo-toggler.ibo-is-hidden){
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,10 +4,21 @@
|
|||||||
|
|
||||||
|
|
||||||
{% UIPanel ForInformation { sTitle:'DataFeatureRemoval:Analysis:Title'|dict_s} %}
|
{% UIPanel ForInformation { sTitle:'DataFeatureRemoval:Analysis:Title'|dict_s} %}
|
||||||
|
{% UIPanel Neutral { sTitle:'DataFeatureRemoval:Features:Title'|dict_s, sSubTitle: '' } %}
|
||||||
{% UIFieldSet Standard {sLegend:'DataFeatureRemoval:Features:Title'|dict_s} %}
|
{% UIMultiColumn Standard {} %}
|
||||||
{% UIDataTable ForForm { sRef:'aExtensions', aColumns:aExtensions.Columns, aData:aExtensions.Data} %}{% EndUIDataTable %}
|
{% for iColumnIndex in 0..iColumnCount-1 %}
|
||||||
{% EndUIFieldSet %}
|
{% UIColumn Standard {} %}
|
||||||
|
{% for aExtension in aAvailableExtensions[iColumnIndex] %}
|
||||||
|
{% if aExtension['installed'] %}
|
||||||
|
{% UIExtensionDetails Installed { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||||
|
{% else %}
|
||||||
|
{% UIExtensionDetails NotInstalled { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% EndUIColumn %}
|
||||||
|
{% endfor %}
|
||||||
|
{% EndUIMultiColumn %}
|
||||||
|
{% EndUIPanel %}
|
||||||
|
|
||||||
{% if bDeletionNeeded %}
|
{% if bDeletionNeeded %}
|
||||||
{% UIFieldSet Standard {sLegend:'DataFeatureRemoval:DeletionPlan:Title'|dict_s} %}
|
{% UIFieldSet Standard {sLegend:'DataFeatureRemoval:DeletionPlan:Title'|dict_s} %}
|
||||||
|
|||||||
@@ -6,9 +6,21 @@
|
|||||||
{% UIInput ForHidden {sName:'operation', sValue:'Analyze'} %}
|
{% UIInput ForHidden {sName:'operation', sValue:'Analyze'} %}
|
||||||
{% UIInput ForHidden {sName:'transaction_id', sValue:sTransactionId} %}
|
{% UIInput ForHidden {sName:'transaction_id', sValue:sTransactionId} %}
|
||||||
|
|
||||||
{% UIFieldSet Standard {sLegend:'DataFeatureRemoval:Features:Title'|dict_s} %}
|
{% UIPanel Neutral { sTitle:'DataFeatureRemoval:Features:Title'|dict_s, sSubTitle: '' } %}
|
||||||
{% UIDataTable ForForm { sRef:'aExtensions', aColumns:aExtensions.Columns, aData:aExtensions.Data} %}{% EndUIDataTable %}
|
{% UIMultiColumn Standard {} %}
|
||||||
{% EndUIFieldSet %}
|
{% for iColumnIndex in 0..iColumnCount-1 %}
|
||||||
|
{% UIColumn Standard {} %}
|
||||||
|
{% for aExtension in aAvailableExtensions[iColumnIndex] %}
|
||||||
|
{% if aExtension['installed'] %}
|
||||||
|
{% UIExtensionDetails Installed { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||||
|
{% else %}
|
||||||
|
{% UIExtensionDetails NotInstalled { sCode : aExtension['code'], sLabel : aExtension['label'], sDescription : aExtension['description'], aMetaData : [aExtension['version'], aExtension['source']], aExtraFlags : aExtension['extra_flags']} %}{% EndUIExtensionDetails %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% EndUIColumn %}
|
||||||
|
{% endfor %}
|
||||||
|
{% EndUIMultiColumn %}
|
||||||
|
{% EndUIPanel %}
|
||||||
|
|
||||||
{% UIToolbar ForButton {} %}
|
{% UIToolbar ForButton {} %}
|
||||||
{% UIButton ForPrimaryAction {sLabel:'UI:Button:Analyze'|dict_s, sName:'btn_apply', sId:'btn_apply', bIsSubmit:true} %}
|
{% UIButton ForPrimaryAction {sLabel:'UI:Button:Analyze'|dict_s, sName:'btn_apply', sId:'btn_apply', bIsSubmit:true} %}
|
||||||
|
|||||||
@@ -486,7 +486,7 @@ class iTopExtensionsMap
|
|||||||
'default' => true, // by default offer to install all modules
|
'default' => true, // by default offer to install all modules
|
||||||
'modules' => $oExtension->aModules,
|
'modules' => $oExtension->aModules,
|
||||||
'mandatory' => $oExtension->bMandatory,
|
'mandatory' => $oExtension->bMandatory,
|
||||||
'source_label' => $this->GetExtensionSourceLabel($oExtension->sSource),
|
'source_label' => $oExtension->GetExtensionSourceLabel(),
|
||||||
'uninstallable' => $oExtension->CanBeUninstalled(),
|
'uninstallable' => $oExtension->CanBeUninstalled(),
|
||||||
'missing' => $oExtension->bRemovedFromDisk,
|
'missing' => $oExtension->bRemovedFromDisk,
|
||||||
'version' => $oExtension->sVersion,
|
'version' => $oExtension->sVersion,
|
||||||
@@ -496,22 +496,6 @@ class iTopExtensionsMap
|
|||||||
return $aRes;
|
return $aRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetExtensionSourceLabel($sSource)
|
|
||||||
{
|
|
||||||
$sResult = '';
|
|
||||||
switch ($sSource) {
|
|
||||||
case iTopExtension::SOURCE_MANUAL:
|
|
||||||
$sResult = 'Local extensions folder';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case iTopExtension::SOURCE_REMOTE:
|
|
||||||
$sResult = (ITOP_APPLICATION == 'iTop') ? 'iTop Hub' : 'ITSM Designer';
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
return $sResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the given extension as chosen
|
* Mark the given extension as chosen
|
||||||
* @param string $sExtensionCode The code of the extension (code without version number)
|
* @param string $sExtensionCode The code of the extension (code without version number)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use SetupUtils;
|
|||||||
|
|
||||||
class DryRemovalRuntimeEnvironment extends RunTimeEnvironment
|
class DryRemovalRuntimeEnvironment extends RunTimeEnvironment
|
||||||
{
|
{
|
||||||
protected array $aExtensionsByCode;
|
protected array $aExtensionsToRemoveByCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toolset for building a run-time environment
|
* Toolset for building a run-time environment
|
||||||
@@ -18,7 +18,7 @@ class DryRemovalRuntimeEnvironment extends RunTimeEnvironment
|
|||||||
public function __construct($sSourceEnv = 'production', array $aExtensionCodesToRemove = [])
|
public function __construct($sSourceEnv = 'production', array $aExtensionCodesToRemove = [])
|
||||||
{
|
{
|
||||||
parent::__construct($sSourceEnv, false);
|
parent::__construct($sSourceEnv, false);
|
||||||
$this->aExtensionsByCode = $aExtensionCodesToRemove;
|
$this->aExtensionsToRemoveByCode = $aExtensionCodesToRemove;
|
||||||
$this->Prepare($sSourceEnv, $this->sBuildEnv);
|
$this->Prepare($sSourceEnv, $this->sBuildEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ class DryRemovalRuntimeEnvironment extends RunTimeEnvironment
|
|||||||
SetupUtils::copydir(APPROOT."/data/$sSourceEnv-modules", APPROOT."/data/$sBuildEnv-modules");
|
SetupUtils::copydir(APPROOT."/data/$sSourceEnv-modules", APPROOT."/data/$sBuildEnv-modules");
|
||||||
SetupUtils::copydir(APPROOT."/conf/$sSourceEnv", APPROOT."/conf/$sBuildEnv");
|
SetupUtils::copydir(APPROOT."/conf/$sSourceEnv", APPROOT."/conf/$sBuildEnv");
|
||||||
|
|
||||||
$this->DeclareExtensionAsRemoved($this->aExtensionsByCode);
|
$this->DeclareExtensionAsRemoved($this->aExtensionsToRemoveByCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function DeclareExtensionAsRemoved(array $aExtensionCodes): void
|
private function DeclareExtensionAsRemoved(array $aExtensionCodes): void
|
||||||
|
|||||||
@@ -169,4 +169,17 @@ class iTopExtension
|
|||||||
return json_encode($this->__serialize(), JSON_PRETTY_PRINT);
|
return json_encode($this->__serialize(), JSON_PRETTY_PRINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetExtensionSourceLabel(): string
|
||||||
|
{
|
||||||
|
return match ($this->sSource) {
|
||||||
|
self::SOURCE_MANUAL => 'Local extensions folder',
|
||||||
|
self::SOURCE_REMOTE => (ITOP_APPLICATION == 'iTop') ? 'iTop Hub' : 'ITSM Designer',
|
||||||
|
default => '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public function IsRemote(): string
|
||||||
|
{
|
||||||
|
return $this->sSource === self::SOURCE_REMOTE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,32 +179,37 @@ class ExtensionDetails extends UIContentBlock
|
|||||||
|
|
||||||
protected function InitializeToggler()
|
protected function InitializeToggler()
|
||||||
{
|
{
|
||||||
|
$sName = 'aSelectedExtensions['.$this->GetCode().']';
|
||||||
$this->oToggler = new Toggler();
|
$this->oToggler = new Toggler();
|
||||||
$this->oToggler->SetName('ExtensionToggler');
|
$this->oToggler->SetName($sName);
|
||||||
$this->oToggler->AddCSSClass('toggler-install');
|
$this->oToggler->AddCSSClass('toggler-install');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function InitializePopoverMenu()
|
protected function InitializePopoverMenu()
|
||||||
{
|
{
|
||||||
$sModalLabel = Dict::Format('UI:Layout:ExtensionsDetails:MenuAboutTitle', $this->sLabel);
|
|
||||||
$sModalText = $this->sAbout;
|
|
||||||
$oModifyButton = new JSButtonItem(
|
|
||||||
'extension_details',
|
|
||||||
Dict::S('UI:Layout:ExtensionsDetails:MenuAbout'),
|
|
||||||
<<<JS
|
|
||||||
CombodoModal.OpenModal({
|
|
||||||
title: '$sModalLabel',
|
|
||||||
content: '$sModalText',
|
|
||||||
});
|
|
||||||
JS,
|
|
||||||
);
|
|
||||||
$this->oPopoverMenu = new PopoverMenu();
|
$this->oPopoverMenu = new PopoverMenu();
|
||||||
$this->oPopoverMenu->AddItem('more-actions', PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem($oModifyButton));
|
|
||||||
$oPopoverOpenButton = ButtonUIBlockFactory::MakeIconAction('fas fa-ellipsis-v', 'Show more actions');
|
$oPopoverOpenButton = ButtonUIBlockFactory::MakeIconAction('fas fa-ellipsis-v', 'Show more actions');
|
||||||
$this->oPopoverMenu->SetTogglerFromBlock($oPopoverOpenButton);
|
$this->oPopoverMenu->SetTogglerFromBlock($oPopoverOpenButton);
|
||||||
$this->oMoreActions = new UIContentBlock();
|
$this->oMoreActions = new UIContentBlock();
|
||||||
$this->oMoreActions->AddSubBlock($this->oPopoverMenu);
|
$this->oMoreActions->AddSubBlock($this->oPopoverMenu);
|
||||||
$this->oMoreActions->AddSubBlock($oPopoverOpenButton);
|
$this->oMoreActions->AddSubBlock($oPopoverOpenButton);
|
||||||
|
|
||||||
|
if (mb_strlen($this->sAbout) > 0) {
|
||||||
|
$sModalLabel = Dict::Format('UI:Layout:ExtensionsDetails:MenuAboutTitle', $this->sLabel);
|
||||||
|
$sModalText = $this->sAbout;
|
||||||
|
$oModifyButton = new JSButtonItem(
|
||||||
|
'extension_details',
|
||||||
|
Dict::S('UI:Layout:ExtensionsDetails:MenuAbout'),
|
||||||
|
<<<JS
|
||||||
|
CombodoModal.OpenModal({
|
||||||
|
title: '$sModalLabel',
|
||||||
|
content: '$sModalText',
|
||||||
|
});
|
||||||
|
JS,
|
||||||
|
);
|
||||||
|
$this->oPopoverMenu->AddItem('more-actions', PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem($oModifyButton));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AllowForceUninstall()
|
public function AllowForceUninstall()
|
||||||
@@ -213,7 +218,8 @@ JS,
|
|||||||
'force_uninstall',
|
'force_uninstall',
|
||||||
Dict::S('UI:Layout:ExtensionsDetails:MenuForce'),
|
Dict::S('UI:Layout:ExtensionsDetails:MenuForce'),
|
||||||
<<<JS
|
<<<JS
|
||||||
this.closest('.ibo-extension-details').querySelector('input[type=checkbox]').disabled = false
|
this.closest('.ibo-extension-details').querySelector('input[type=checkbox]').disabled = false;
|
||||||
|
this.remove();
|
||||||
JS,
|
JS,
|
||||||
);
|
);
|
||||||
$this->oPopoverMenu->AddItem('more-actions', PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem($oForceUninstallButton));
|
$this->oPopoverMenu->AddItem('more-actions', PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem($oForceUninstallButton));
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ class ExtensionDetailsUIBlockFactory extends AbstractUIBlockFactory
|
|||||||
$aBadges = [];
|
$aBadges = [];
|
||||||
$bUninstallable = $aExtraFlags['uninstallable'] ?? true;
|
$bUninstallable = $aExtraFlags['uninstallable'] ?? true;
|
||||||
$bMissingFromDisk = $aExtraFlags['missing'] ?? false;
|
$bMissingFromDisk = $aExtraFlags['missing'] ?? false;
|
||||||
|
$bSelected = $aExtraFlags['selected'] ?? true;
|
||||||
|
$bDisabled = $aExtraFlags['disabled'] ?? false;
|
||||||
|
$bRemote = $aExtraFlags['remote'] ?? false;
|
||||||
self::AddExtraBadges($aBadges, $bUninstallable, $bMissingFromDisk);
|
self::AddExtraBadges($aBadges, $bUninstallable, $bMissingFromDisk);
|
||||||
$oBadgeInstalled = BadgeUIBlockFactory::MakeGreen(Dict::S('UI:Layout:ExtensionsDetails:BadgeInstalled'));
|
$oBadgeInstalled = BadgeUIBlockFactory::MakeGreen(Dict::S('UI:Layout:ExtensionsDetails:BadgeInstalled'));
|
||||||
$oBadgeInstalled->AddCSSClass('checked');
|
$oBadgeInstalled->AddCSSClass('checked');
|
||||||
@@ -28,10 +31,22 @@ class ExtensionDetailsUIBlockFactory extends AbstractUIBlockFactory
|
|||||||
|
|
||||||
$oExtensionDetails = new ExtensionDetails($sCode, $sLabel, $sDescription, $aMetaData, $aBadges, $sAbout);
|
$oExtensionDetails = new ExtensionDetails($sCode, $sLabel, $sDescription, $aMetaData, $aBadges, $sAbout);
|
||||||
$oExtensionDetails->GetToggler()->SetIsToggled(true);
|
$oExtensionDetails->GetToggler()->SetIsToggled(true);
|
||||||
if (!$bUninstallable) {
|
if ($bMissingFromDisk) {
|
||||||
|
$oExtensionDetails->GetToggler()->SetIsToggled(false);
|
||||||
|
$oExtensionDetails->GetToggler()->SetIsDisabled(true);
|
||||||
|
} elseif (!$bUninstallable || $bRemote) {
|
||||||
$oExtensionDetails->AllowForceUninstall();
|
$oExtensionDetails->AllowForceUninstall();
|
||||||
$oExtensionDetails->GetToggler()->SetIsDisabled(true);
|
$oExtensionDetails->GetToggler()->SetIsDisabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$bSelected) {
|
||||||
|
$oExtensionDetails->GetToggler()->SetIsToggled(false);
|
||||||
|
}
|
||||||
|
if ($bDisabled) {
|
||||||
|
$oExtensionDetails->GetToggler()->SetIsDisabled(true);
|
||||||
|
$oExtensionDetails->GetToggler()->AddCSSClass('ibo-is-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
return $oExtensionDetails;
|
return $oExtensionDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +54,8 @@ class ExtensionDetailsUIBlockFactory extends AbstractUIBlockFactory
|
|||||||
{
|
{
|
||||||
$aBadges = [];
|
$aBadges = [];
|
||||||
$bUninstallable = $aExtraFlags['uninstallable'] ?? true;
|
$bUninstallable = $aExtraFlags['uninstallable'] ?? true;
|
||||||
|
$bSelected = $aExtraFlags['selected'] ?? false;
|
||||||
|
$bDisabled = $aExtraFlags['disabled'] ?? false;
|
||||||
self::AddExtraBadges($aBadges, $bUninstallable, false);
|
self::AddExtraBadges($aBadges, $bUninstallable, false);
|
||||||
$oBadgeInstalled = BadgeUIBlockFactory::MakeGrey(Dict::S('UI:Layout:ExtensionsDetails:BadgeNotInstalled'));
|
$oBadgeInstalled = BadgeUIBlockFactory::MakeGrey(Dict::S('UI:Layout:ExtensionsDetails:BadgeNotInstalled'));
|
||||||
$oBadgeInstalled->AddCSSClass('unchecked');
|
$oBadgeInstalled->AddCSSClass('unchecked');
|
||||||
@@ -46,8 +63,17 @@ class ExtensionDetailsUIBlockFactory extends AbstractUIBlockFactory
|
|||||||
$oBadgeToBeUninstalled = BadgeUIBlockFactory::MakeCyan(Dict::S('UI:Layout:ExtensionsDetails:BadgeToBeInstalled'));
|
$oBadgeToBeUninstalled = BadgeUIBlockFactory::MakeCyan(Dict::S('UI:Layout:ExtensionsDetails:BadgeToBeInstalled'));
|
||||||
$oBadgeToBeUninstalled->AddCSSClass('checked');
|
$oBadgeToBeUninstalled->AddCSSClass('checked');
|
||||||
$aBadges[] = $oBadgeToBeUninstalled;
|
$aBadges[] = $oBadgeToBeUninstalled;
|
||||||
|
$oExtensionDetails = new ExtensionDetails($sCode, $sLabel, $sDescription, $aMetaData, $aBadges, $sAbout);
|
||||||
|
|
||||||
return new ExtensionDetails($sCode, $sLabel, $sDescription, $aMetaData, $aBadges, $sAbout);
|
if ($bSelected) {
|
||||||
|
$oExtensionDetails->GetToggler()->SetIsToggled(true);
|
||||||
|
}
|
||||||
|
if ($bDisabled) {
|
||||||
|
$oExtensionDetails->GetToggler()->SetIsDisabled(true);
|
||||||
|
$oExtensionDetails->GetToggler()->AddCSSClass('ibo-is-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $oExtensionDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function AddExtraBadges(array &$aBadges, bool $bUninstallable, bool $bMissingFromDisk)
|
private static function AddExtraBadges(array &$aBadges, bool $bUninstallable, bool $bMissingFromDisk)
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
{% extends "base/components/input/layout.html.twig" %}
|
{% extends "base/components/input/layout.html.twig" %}
|
||||||
{% block iboInput %}
|
{% block iboInput %}
|
||||||
<span class="ibo-toggler--wrapper">
|
<span class="ibo-toggler--wrapper">
|
||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
<span class="ibo-toggler--slider"></span>
|
<span class="ibo-toggler--slider"></span>
|
||||||
|
<input class="ibo-toggler--hidden" type="hidden" name="{{ oUIBlock.GetName() }}" value="{% if oUIBlock.IsChecked() %}on{% else %}off{% endif %}"/>
|
||||||
</span>
|
</span>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
|
||||||
$('#{{ oUIBlock.GetId() }}').parent().on('click', function() {
|
$('#{{ oUIBlock.GetId() }}').parent().on('click', function() {
|
||||||
let oInput = $(this).find('.ibo-toggler');
|
let oInput = $(this).find('.ibo-toggler');
|
||||||
|
let oHiddenInput = $(this).find('.ibo-toggler--hidden');
|
||||||
if (!oInput.prop('disabled')) {
|
if (!oInput.prop('disabled')) {
|
||||||
oInput.prop('checked', !oInput.prop('checked'));
|
oInput.prop('checked', !oInput.prop('checked'));
|
||||||
|
oHiddenInput.val(oInput.prop('checked') ? 'on' : 'off');
|
||||||
oInput.trigger('change');
|
oInput.trigger('change');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -639,6 +639,9 @@ $oPage->AddUiBlock($oMultiCol);
|
|||||||
$oExtensionDetailInstalledFromFactory = ExtensionDetailsUIBlockFactory::MakeInstalled('itop-sample', 'My extension v2', 'This is for test only', ['v1.1.1', 'Designer', '12/12/2012'], ['uninstallable' => false,'missing' => true]);
|
$oExtensionDetailInstalledFromFactory = ExtensionDetailsUIBlockFactory::MakeInstalled('itop-sample', 'My extension v2', 'This is for test only', ['v1.1.1', 'Designer', '12/12/2012'], ['uninstallable' => false,'missing' => true]);
|
||||||
$oColumnLeft->AddSubBlock($oExtensionDetailInstalledFromFactory);
|
$oColumnLeft->AddSubBlock($oExtensionDetailInstalledFromFactory);
|
||||||
|
|
||||||
|
$oExtensionDetailInstalledFromFactory = ExtensionDetailsUIBlockFactory::MakeInstalled('itop-not-uninstallable', 'You cannot uninstall me', 'Click force uninstall to uninstall me', ['v9.9.9', 'Void', '12/12/2012'], ['uninstallable' => false,'missing' => false]);
|
||||||
|
$oColumnLeft->AddSubBlock($oExtensionDetailInstalledFromFactory);
|
||||||
|
|
||||||
$oExtensionDetailInstalledWithLongTitle = ExtensionDetailsUIBlockFactory::MakeNotInstalled('itop-sample', 'My extension with a very long title', 'This is for test only', ['v1.1.1', 'Designer', '12/12/2012'], ['uninstallable' => false]);
|
$oExtensionDetailInstalledWithLongTitle = ExtensionDetailsUIBlockFactory::MakeNotInstalled('itop-sample', 'My extension with a very long title', 'This is for test only', ['v1.1.1', 'Designer', '12/12/2012'], ['uninstallable' => false]);
|
||||||
$oColumnRight->AddSubBlock($oExtensionDetailInstalledWithLongTitle);
|
$oColumnRight->AddSubBlock($oExtensionDetailInstalledWithLongTitle);
|
||||||
$oPage->add('<hr id="page_bottom"/>');
|
$oPage->add('<hr id="page_bottom"/>');
|
||||||
|
|||||||
Reference in New Issue
Block a user