diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index eb28a7e66..d9cfa460d 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -30,6 +30,7 @@ use Combodo\iTop\Application\UI\Layout\MultiColumn\Column\Column; use Combodo\iTop\Application\UI\Layout\MultiColumn\MultiColumn; use Combodo\iTop\Application\UI\Layout\UIContentBlock; use Combodo\iTop\Application\UI\Layout\Object\ObjectFactory; +use Combodo\iTop\Application\UI\Component\Panel\Panel; define('OBJECT_PROPERTIES_TAB', 'ObjectProperties'); @@ -388,9 +389,6 @@ EOF $aIcons[] = "
  $sLabel
"; } - $sObjectIcon = $this->GetIcon(); - $sClassName = MetaModel::GetName(get_class($this)); - $sObjectName = $this->GetName(); if (count($aIcons) > 0) { $sTags = '
'.implode(' ', $aIcons).'
'; } else { @@ -450,7 +448,7 @@ EOF // Special case to display the case log, if any... // WARNING: if you modify the loop below, also check the corresponding code in UpdateObject and DisplayModifyForm - // TODO 2.8.0: Remove when sure everything has been migrated + // TODO 3.0.0: Remove when sure everything has been migrated (CHECK THE WARNING ABOVE!) // foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode => $oAttDef) // { // if ($oAttDef instanceof AttributeCaseLog) @@ -978,86 +976,26 @@ EOF $iKey = $this->GetKey(); $sMode = static::ENUM_OBJECT_MODE_VIEW; - // Object's details - // TODO 3.0.0: Complete the factory - $oObjectDetails = ObjectFactory::MakeDetails($this); -// $oPage->AddUiBlock($oObjectDetails); - - - // TODO 2.8.0: Remove this when object details block completed, this is hardcoded for the demo - $oPage->add_style(<< .ibo-panel--body { - padding: 8px 16px 0px; -} -.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container > .ibo-tab-container--tabs-list{ - margin-left: -16px; - margin-right: -16px; - padding-left: calc(32px + 90px + 32px - 24px); -} -.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container > .ibo-tab-container--tab-container{ - margin-left: -16px; - margin-right: -16px; -} -.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container.ibo-is-vertical{ - display: flex; - flex-direction: row; -} -.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container.ibo-is-vertical > .ibo-tab-container--tabs-list{ - padding-top: 50px; - flex-direction: column; - height: auto; - padding-left: unset; - margin-right: unset; - min-width: calc(32px + 90px + 32px); -} -.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container.ibo-is-vertical > .ibo-tab-container--tabs-list > .ibo-tab-container--tab-header{ - height: 50px; - width: 100%; - justify-content: left; -} -.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container.ibo-is-vertical > .ibo-tab-container--tabs-list > .ibo-tab-container--tab-header > .ibo-tab-container--tab-toggler{ - width: 100%; - justify-content: left; -} -.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container.ibo-is-vertical > .ibo-tab-container--tab-container { - flex-grow: 1; - margin-left: unset; -} -CSS - ); - $oPage->add(<<
HTML ); - $this->DisplayBareHeader($oPage, $bEditMode); + /** @var \iTopWebPage $oPage */ - $oPage->AddTabContainer(OBJECT_PROPERTIES_TAB); + $this->DisplayBareHeader($oPage, $bEditMode); + // Object's details + // TODO 3.0.0: Complete the factory + $oObjectDetails = ObjectFactory::MakeDetails($this); + $oPage->AddUiBlock($oObjectDetails); + + $oPage->AddTabContainer(OBJECT_PROPERTIES_TAB, '', $oObjectDetails); $oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB); $oPage->SetCurrentTab('UI:PropertiesTab'); $this->DisplayBareProperties($oPage, $bEditMode); $this->DisplayBareRelations($oPage, $bEditMode); - //$oPage->SetCurrentTab('UI:HistoryTab'); - //$this->DisplayBareHistory($oPage, $bEditMode); // TODO 3.0.0: What to do with this? - //$oPage->AddAjaxTab('UI:HistoryTab', utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=history&class='.$sClass.'&id='.$iKey); + //$this->DisplayBareHistory($oPage, $bEditMode); $oPage->add(<< HTML @@ -2645,13 +2583,26 @@ JS ->SetOnSubmitJsCode("return OnSubmit('form_{$this->m_iFormId}');"); $oContentBlock->AddSubBlock($oForm); + // TODO 3.0.0: Dehardcode this after object details are refactored + $oPage->add_style(<<SetCSSClasses('ibo-toolbar ibo-toolbar-top'); + if ($sMode === static::ENUM_OBJECT_MODE_EDIT) { // The object already exists in the database, it's a modification $oForm->AddSubBlock(InputFactory::MakeForHidden('id', $iKey, "{$sPrefix}_id")); } $oForm->AddSubBlock(InputFactory::MakeForHidden('operation', $sOperation)); + $oCancelButton = ButtonFactory::MakeForSecondaryAction(Dict::S('UI:Button:Cancel')); $oCancelButton->AddCSSClasses('action cancel'); $oToolbarTop->AddSubBlock($oCancelButton); @@ -2739,7 +2690,11 @@ EOF $oForm->AddSubBlock($oToolbarTop); } - $oPage->AddTabContainer(OBJECT_PROPERTIES_TAB, $sPrefix, $oForm); + + // TODO 3.0.0: Use ObjectDetails block when ready. + $oPanel = new Panel; + $oForm->AddSubBlock($oPanel); + $oPage->AddTabContainer(OBJECT_PROPERTIES_TAB, $sPrefix, $oPanel); $oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB); $oPage->SetCurrentTab('UI:PropertiesTab'); @@ -2772,6 +2727,7 @@ EOF // bottom or both: display the buttons here $oPage->p($sStatesSelection); $oToolbarBottom = new Toolbar(); + $oToolbarBottom->SetCSSClasses('ibo-toolbar'); foreach ($oToolbarTop->GetSubBlocks() as $oButton) { $oToolbarBottom->AddSubBlock($oButton); } diff --git a/css/backoffice/layout/_all.scss b/css/backoffice/layout/_all.scss index d399e4419..2d2fe150e 100644 --- a/css/backoffice/layout/_all.scss +++ b/css/backoffice/layout/_all.scss @@ -30,4 +30,5 @@ @import "activity-panel/caselog-entry"; @import "activity-panel/edits-entry"; @import "activity-panel/transition-entry"; -@import "activity-panel/activity-new-entry-form"; \ No newline at end of file +@import "activity-panel/activity-new-entry-form"; +@import "blocks-integrations/panel-with-tab-container"; diff --git a/css/backoffice/layout/_object-details.scss b/css/backoffice/layout/_object-details.scss index 4ad61d2c7..8d362c72d 100644 --- a/css/backoffice/layout/_object-details.scss +++ b/css/backoffice/layout/_object-details.scss @@ -3,24 +3,50 @@ * @license http://opensource.org/licenses/AGPL-3.0 */ -$ibo-object-details--body--padding-top: $ibo-panel--highlight--height !default; -$ibo-object-details--tabs-list--margin-x: -1 * $ibo-panel--body--padding-x !default; +// TODO 3.0.0: This is temporary to make object forms work while it is being migrated to the blocks syste. +// When there is a real ObjectDetails block, rework this to match the block conventions. -$ibo-object-details--tab-container--margin-x: -1 * $ibo-panel--body--padding-x !default; - -.ibo-object-details.ibo-panel { - > .ibo-panel--body { - padding-top: $ibo-object-details--body--padding-top; - - > .ibo-tab-container { - > .ibo-tab-container--tabs-list{ - margin-left: $ibo-object-details--tabs-list--margin-x; - margin-right: $ibo-object-details--tabs-list--margin-x; - } - > .ibo-tab-container--tab-container{ - margin-left: $ibo-object-details--tab-container--margin-x; - margin-right: $ibo-object-details--tab-container--margin-x; - } - } - } +.object-details .ibo-title { + z-index: 1; + align-items: start; + position: relative; + padding-left: 32px; +} +.object-details .ibo-title .ibo-title--medallion { + position: absolute; + margin-top: 16px; +} +.object-details .ibo-title .ibo-title--content { + margin-left: calc(90px + 32px); +} +.object-details .ibo-panel { + z-index: 0; +} +.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container > .ibo-tab-container--tabs-list{ + padding-left: calc(32px + 90px + 32px - 24px); +} +.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container.ibo-is-vertical{ + display: flex; + flex-direction: row; +} +.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container.ibo-is-vertical > .ibo-tab-container--tabs-list{ + padding-top: 50px; + flex-direction: column; + height: auto; + padding-left: unset; + margin-right: unset; + min-width: calc(32px + 90px + 32px); +} +.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container.ibo-is-vertical > .ibo-tab-container--tabs-list > .ibo-tab-container--tab-header{ + height: 50px; + width: 100%; + justify-content: left; +} +.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container.ibo-is-vertical > .ibo-tab-container--tabs-list > .ibo-tab-container--tab-header > .ibo-tab-container--tab-toggler{ + width: 100%; + justify-content: left; +} +.object-details .ibo-panel > .ibo-panel--body > .ibo-tab-container.ibo-is-vertical > .ibo-tab-container--tab-container { + flex-grow: 1; + margin-left: unset; } \ No newline at end of file diff --git a/css/backoffice/layout/blocks-integrations/_panel-with-tab-container.scss b/css/backoffice/layout/blocks-integrations/_panel-with-tab-container.scss new file mode 100644 index 000000000..358d02ab9 --- /dev/null +++ b/css/backoffice/layout/blocks-integrations/_panel-with-tab-container.scss @@ -0,0 +1,26 @@ +/*! + * @copyright Copyright (C) 2010-2020 Combodo SARL + * @license http://opensource.org/licenses/AGPL-3.0 + */ + +$ibo-panel-with-tab-container--body--padding-top: $ibo-panel--highlight--height !default; +$ibo-panel-with-tab-container--tabs-list--margin-x: -1 * $ibo-panel--body--padding-x !default; + +$ibo-panel-with-tab-container--tab-container--margin-x: -1 * $ibo-panel--body--padding-x !default; + +.ibo-panel { + > .ibo-panel--body { + padding-top: $ibo-panel-with-tab-container--body--padding-top; + + > .ibo-tab-container { + > .ibo-tab-container--tabs-list{ + margin-left: $ibo-panel-with-tab-container--tabs-list--margin-x; + margin-right: $ibo-panel-with-tab-container--tabs-list--margin-x; + } + > .ibo-tab-container--tab-container{ + margin-left: $ibo-panel-with-tab-container--tab-container--margin-x; + margin-right: $ibo-panel-with-tab-container--tab-container--margin-x; + } + } + } +} \ No newline at end of file diff --git a/sources/application/UI/Layout/Object/ObjectDetails.php b/sources/application/UI/Layout/Object/ObjectDetails.php index a1c00ac5d..90fef17c5 100644 --- a/sources/application/UI/Layout/Object/ObjectDetails.php +++ b/sources/application/UI/Layout/Object/ObjectDetails.php @@ -8,10 +8,126 @@ namespace Combodo\iTop\Application\UI\Layout\Object; use Combodo\iTop\Application\UI\Component\Panel\Panel; +use DBObject; +use MetaModel; class ObjectDetails extends Panel { // Overloaded constants public const BLOCK_CODE = 'ibo-object-details'; public const HTML_TEMPLATE_REL_PATH = 'layouts/object/object-details/layout'; + + /** @var string */ + protected $sClassName; + /** @var string */ + protected $sClassLabel; + /** @var string */ + protected $sName; + /** @var string */ + protected $sIconUrl; + /** @var string */ + protected $sStatusCode; + /** @var string */ + protected $sStatusLabel; + /** @var string */ + protected $sStatusColor; + + /** + * ObjectDetails constructor. + * + * @param \DBObject $oObject + * @param string|null $sId + * + * @throws \CoreException + */ + public function __construct(DBObject $oObject, ?string $sId = null) { + $this->sClassName = get_class($oObject); + $this->sClassLabel = MetaModel::GetName($this->GetClassName()); + // Note: We get the raw name as only the front-end consumer knows when and how to encode it. + $this->sName = $oObject->GetRawName(); + $this->sIconUrl = $oObject->GetIcon(false); + + $sStatusAttCode = MetaModel::GetStateAttributeCode($this->sClassName); + if(!empty($sStatusAttCode)) { + $this->sStatusCode = $oObject->GetState(); + $this->sStatusLabel = $oObject->GetStateLabel(); + // TODO 3.0.0 : Dehardcode this + switch ($this->sStatusCode) { + case 'new': + $this->sStatusColor = 'new'; + break; + + case 'waiting_for_approval': + case 'pending': + $this->sStatusColor = 'waiting'; + break; + + case 'escalated_tto': + case 'escalated_ttr': + case 'rejected': + $this->sStatusColor = 'failure'; + break; + + case 'resolved': + $this->sStatusColor = 'success'; + break; + + case 'closed': + $this->sStatusColor = 'frozen'; + break; + + case 'approved': + case 'assigned': + case 'dispatched': + case 'redispatched': + default: + $this->sStatusColor = 'neutral'; + break; + } + } + + parent::__construct('', [], static::DEFAULT_COLOR, $sId); + + } + + + /** + * @return string + */ + public function GetClassName(): string + { + return $this->sClassName; + } + + /** + * @return string + */ + public function GetObjectName(): string + { + return $this->sName; + } + + public function SetStatus($sCode, $sLabel, $sColor) + { + $this->sStatusCode = $sColor; + $this->sStatusLabel = $sLabel; + $this->sStatusColor = $sColor; + + return $this; + } + + public function GetStatusCode(): string + { + return $this->sStatusCode; + } + + public function GetStatusLabel(): string + { + return $this->sStatusLabel; + } + + public function GetStatusColor(): string + { + return $this->sStatusColor; + } } \ No newline at end of file diff --git a/sources/application/UI/Layout/Object/ObjectFactory.php b/sources/application/UI/Layout/Object/ObjectFactory.php index 5d28818ad..e753ba08a 100644 --- a/sources/application/UI/Layout/Object/ObjectFactory.php +++ b/sources/application/UI/Layout/Object/ObjectFactory.php @@ -25,6 +25,6 @@ class ObjectFactory { * @return \Combodo\iTop\Application\UI\Layout\Object\ObjectDetails */ public static function MakeDetails(DBObject $oObject) { - return new ObjectDetails(); + return new ObjectDetails($oObject); } } \ No newline at end of file diff --git a/sources/application/WebPage/WebPage.php b/sources/application/WebPage/WebPage.php index 5770724ef..1d0016463 100644 --- a/sources/application/WebPage/WebPage.php +++ b/sources/application/WebPage/WebPage.php @@ -317,6 +317,7 @@ class WebPage implements Page */ public function AddUiBlock(?iUIBlock $oBlock): ?iUIBlock { + // TODO 3.0.0: Why make this parameter nullable?! if (is_null($oBlock)) { return null; }