Compare commits

..

12 Commits

Author SHA1 Message Date
Timothee
04ac112628 N°6759 - Fixing attributes visibility 2025-08-28 10:27:20 +02:00
Timothee
646aa743dc N°6759 - Small fixes 2025-08-26 15:26:37 +02:00
Timothee
67f60ddd00 N°6759 - Migrate from jquery to js 2025-08-26 15:07:44 +02:00
Timothee
85ed39caa6 N°6759 - Small fixes 2025-08-22 16:03:02 +02:00
Timothee
f0ebf02f77 N°6759 - Fix alerts html 2025-08-22 15:03:13 +02:00
Timothee
338b47d8f6 N°6759 - Migrating to twig templating 2025-08-22 14:42:42 +02:00
Timothee
9c31a450dd N°6759 - Migrate Validate to its own Validator 2025-08-21 14:22:10 +02:00
Timothee
8368afd20e N°6759 - Fix preg_match test 2025-08-20 16:07:23 +02:00
Timothee
3d7b1d60aa N°6759 - Dump autoload 2025-08-20 16:07:23 +02:00
Timothee
d50758caae N°6759 - Remove unused use and comments 2025-08-20 16:07:23 +02:00
Timothee
9097c8cef1 N°6759 - Factorize code in config 2025-08-20 16:07:23 +02:00
Timothee
f8e56eda45 N°6759 - Factorize code in config 2025-08-20 16:07:23 +02:00
185 changed files with 4610 additions and 8203 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,72 +0,0 @@
<?php
/**
* Extend this class instead of implementing iApplicationUIExtension if you don't need to overload
*
* @api
* @package UIExtensibilityAPI
* @since 2.7.0
*/
abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
{
/**
* @inheritDoc
*/
public function OnDisplayProperties($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false)
{
}
/**
* @inheritDoc
*/
public function OnDisplayRelations($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false)
{
}
/**
* @inheritDoc
*/
public function OnFormSubmit($oObject, $sFormPrefix = '')
{
}
/**
* @inheritDoc
*/
public function OnFormCancel($sTempId)
{
}
/**
* @inheritDoc
*/
public function EnumUsedAttributes($oObject)
{
return array();
}
/**
* @inheritDoc
*/
public function GetIcon($oObject)
{
return '';
}
/**
* @inheritDoc
*/
public function GetHilightClass($oObject)
{
return HILIGHT_CLASS_NONE;
}
/**
* @inheritDoc
*/
public function EnumAllowedActions(DBObjectSet $oSet)
{
return array();
}
}

View File

@@ -1,35 +0,0 @@
<?php
/**
* Extend this class instead of iPageUIBlockExtension if you don't need to overload all methods
*
* @api
* @package UIBlockExtensibilityAPI
* @since 3.0.0
*/
abstract class AbstractPageUIBlockExtension implements iPageUIBlockExtension
{
/**
* @inheritDoc
*/
public function GetBannerBlock()
{
return null;
}
/**
* @inheritDoc
*/
public function GetHeaderBlock()
{
return null;
}
/**
* @inheritDoc
*/
public function GetFooterBlock()
{
return null;
}
}

View File

@@ -1,28 +0,0 @@
<?php
/**
* Extend this class instead of implementing iPreferencesExtension if you don't need to overload all methods
*
* @api
* @package PreferencesExtensibilityAPI
* @since 2.7.0
*/
abstract class AbstractPreferencesExtension implements iPreferencesExtension
{
/**
* @inheritDoc
*/
public function DisplayPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage)
{
// Do nothing
}
/**
* @inheritDoc
*/
public function ApplyPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage, $sOperation)
{
// Do nothing
}
}

View File

@@ -1,35 +0,0 @@
<?php
/**
* Inherit from this class to provide messages to be displayed in the "Welcome Popup"
*
* @api
* @since 3.2.0
*/
abstract class AbstractWelcomePopupExtension implements iWelcomePopupExtension
{
/**
* @inheritDoc
*/
public function GetIconRelPath(): string
{
return \Combodo\iTop\Application\Branding::$aLogoPaths[\Combodo\iTop\Application\Branding::ENUM_LOGO_TYPE_MAIN_LOGO_COMPACT]['default'];
}
/**
* @inheritDoc
*/
public function GetMessages(): array
{
return [];
}
/**
* @inheritDoc
*/
public function AcknowledgeMessage(string $sMessageId): void
{
// No need to process the acknowledgment notice by default
return;
}
}

View File

@@ -1,150 +0,0 @@
<?php
/**
* Base class for the various types of custom menus
*
* @api
* @package UIExtensibilityAPI
* @since 2.0
*/
abstract class ApplicationPopupMenuItem
{
/** @ignore */
protected $sUID;
/** @ignore */
protected $sLabel;
/** @ignore */
protected $sTooltip;
/** @ignore */
protected $sIconClass;
/** @ignore */
protected $aCssClasses;
/**
* Constructor
*
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
* @param string $sLabel The display label of the menu (must be localized)
* @api
*/
public function __construct($sUID, $sLabel)
{
$this->sUID = $sUID;
$this->sLabel = $sLabel;
$this->sTooltip = '';
$this->sIconClass = '';
$this->aCssClasses = array();
}
/**
* Get the UID
*
* @return string The unique identifier
* @ignore
*/
public function GetUID()
{
return $this->sUID;
}
/**
* Get the label
*
* @return string The label
* @ignore
*/
public function GetLabel()
{
return $this->sLabel;
}
/**
* Get the CSS classes
*
* @return array
* @ignore
*/
public function GetCssClasses()
{
return $this->aCssClasses;
}
/**
* @param $aCssClasses
* @api
*/
public function SetCssClasses($aCssClasses)
{
$this->aCssClasses = $aCssClasses;
}
/**
* Adds a CSS class to the CSS classes that will be put on the menu item
*
* @param $sCssClass
* @api
*/
public function AddCssClass($sCssClass)
{
$this->aCssClasses[] = $sCssClass;
}
/**
* @param $sTooltip
*
* @api
* @since 3.0.0
*/
public function SetTooltip($sTooltip)
{
$this->sTooltip = $sTooltip;
}
/**
* @return string
*
* @api
* @since 3.0.0
*/
public function GetTooltip()
{
return $this->sTooltip;
}
/**
* @param $sIconClass
*
* @api
* @since 3.0.0
*/
public function SetIconClass($sIconClass)
{
$this->sIconClass = $sIconClass;
}
/**
* @return string
*
* @api
* @since 3.0.0
*/
public function GetIconClass()
{
return $this->sIconClass;
}
/**
* Returns the components to create a popup menu item in HTML
*
* @return array A hash array: array('label' => , 'url' => , 'target' => , 'onclick' => )
* @ignore
*/
abstract public function GetMenuItem();
/** @ignore */
public function GetLinkedScripts()
{
return array();
}
}

View File

@@ -1,13 +0,0 @@
<?php
/**
* Class for adding an item as a button that runs some JS code
*
* @api
* @package UIExtensibilityAPI
* @since 2.0
*/
class JSButtonItem extends JSPopupMenuItem
{
}

View File

@@ -1,70 +0,0 @@
<?php
/**
* Class for adding an item into a popup menu that triggers some Javascript code
*
* Note: This works only in the backoffice, {@see \JSButtonItem} for the end-user portal
*
* @api
* @package UIExtensibilityAPI
* @since 2.0
*/
class JSPopupMenuItem extends ApplicationPopupMenuItem
{
/** @ignore */
protected $sJsCode;
/** @ignore */
protected $sUrl;
/** @ignore */
protected $aIncludeJSFiles;
/**
* Class for adding an item that triggers some Javascript code
*
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
* @param string $sLabel The display label of the menu (must be localized)
* @param string $sJSCode In case the menu consists in executing some havascript code inside the page, pass it here. If supplied $sURL
* ans $sTarget will be ignored
* @param array $aIncludeJSFiles An array of file URLs to be included (once) to provide some JS libraries for the page.
* @api
*/
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = array())
{
parent::__construct($sUID, $sLabel);
$this->sJsCode = $sJSCode;
$this->sUrl = '#';
$this->aIncludeJSFiles = $aIncludeJSFiles;
}
/** @ignore */
public function GetMenuItem()
{
// Note: the semicolumn is a must here!
return array(
'label' => $this->GetLabel(),
'onclick' => $this->GetJsCode() . '; return false;',
'url' => $this->GetUrl(),
'css_classes' => $this->GetCssClasses(),
'icon_class' => $this->sIconClass,
'tooltip' => $this->sTooltip
);
}
/** @ignore */
public function GetLinkedScripts()
{
return $this->aIncludeJSFiles;
}
/** @ignore */
public function GetJsCode()
{
return $this->sJsCode;
}
/** @ignore */
public function GetUrl()
{
return $this->sUrl;
}
}

View File

@@ -1,29 +0,0 @@
<?php
/**
* Class for adding a separator (horizontal line, not selectable) the output
* will automatically reduce several consecutive separators to just one
*
* @api
* @package UIExtensibilityAPI
* @since 2.0
*/
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
{
static $idx = 0;
/**
* Constructor
* @api
*/
public function __construct()
{
parent::__construct('_separator_' . (self::$idx++), '');
}
/** @ignore */
public function GetMenuItem()
{
return array('label' => '<hr class="menu-separator">', 'url' => '', 'css_classes' => $this->aCssClasses);
}
}

View File

@@ -1,13 +0,0 @@
<?php
/**
* Class for adding an item as a button that browses to the given URL
*
* @api
* @package UIExtensibilityAPI
* @since 2.0
*/
class URLButtonItem extends URLPopupMenuItem
{
}

View File

@@ -1,58 +0,0 @@
<?php
/**
* Class for adding an item into a popup menu that browses to the given URL
*
* Note: This works only in the backoffice, {@see \URLButtonItem} for the end-user portal
*
* @api
* @package UIExtensibilityAPI
* @since 2.0
*/
class URLPopupMenuItem extends ApplicationPopupMenuItem
{
/** @ignore */
protected $sUrl;
/** @ignore */
protected $sTarget;
/**
* Constructor
*
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
* @param string $sLabel The display label of the menu (must be localized)
* @param string $sUrl If the menu is an hyperlink, provide the absolute hyperlink here
* @param string $sTarget In case the menu is an hyperlink and a specific target is needed (_blank for example), pass it here
* @api
*/
public function __construct($sUID, $sLabel, $sUrl, $sTarget = '_top')
{
parent::__construct($sUID, $sLabel);
$this->sUrl = $sUrl;
$this->sTarget = $sTarget;
}
/** @ignore */
public function GetMenuItem()
{
return array('label' => $this->GetLabel(),
'url' => $this->GetUrl(),
'target' => $this->GetTarget(),
'css_classes' => $this->aCssClasses,
'icon_class' => $this->sIconClass,
'tooltip' => $this->sTooltip
);
}
/** @ignore */
public function GetUrl()
{
return $this->sUrl;
}
/** @ignore */
public function GetTarget()
{
return $this->sTarget;
}
}

View File

@@ -1,173 +0,0 @@
<?php
/**
* Implement this interface to change the behavior of the GUI for some objects.
*
* All methods are invoked by iTop for a given object. There are basically two usages:
*
* 1) To tweak the form of an object, you will have to implement a specific behavior within:
*
* * OnDisplayProperties (bEditMode = true)
* * OnFormSubmit
* * OnFormCancel
*
* 2) To tune the display of the object details, you can use:
*
* * OnDisplayProperties
* * OnDisplayRelations
* * GetIcon
* * GetHilightClass
*
* Please note that some of the APIs can be called several times for a single page displayed.
* Therefore it is not recommended to perform too many operations, such as querying the database.
* A recommended pattern is to cache data by the mean of static members.
*
* @api
* @package UIExtensibilityAPI
*/
interface iApplicationUIExtension
{
/**
* Invoked when an object is being displayed (wiew or edit)
*
* The method is called right after the main tab has been displayed.
* You can add output to the page, either to change the display, or to add a form input
*
* Example:
* <code>
* if ($bEditMode)
* {
* $oPage->p('Age of the captain: &lt;input type="text" name="captain_age"/&gt;');
* }
* else
* {
* $oPage->p('Age of the captain: '.$iCaptainAge);
* }
* </code>
*
* @api
*
*@param \Combodo\iTop\Application\WebPage\WebPage $oPage The output context
* @param boolean $bEditMode True if the edition form is being displayed
*
* @param DBObject $oObject The object being displayed
*
* @return void
*/
public function OnDisplayProperties($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false);
/**
* Invoked when an object is being displayed (wiew or edit)
*
* The method is called rigth after all the tabs have been displayed
*
* @api
*
*@param \Combodo\iTop\Application\WebPage\WebPage $oPage The output context
* @param boolean $bEditMode True if the edition form is being displayed
*
* @param DBObject $oObject The object being displayed
*
* @return void
*/
public function OnDisplayRelations($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false);
/**
* Invoked when the end-user clicks on Modify from the object edition form
*
* The method is called after the changes from the standard form have been
* taken into account, and before saving the changes into the database.
*
* @param DBObject $oObject The object being edited
* @param string $sFormPrefix Prefix given to the HTML form inputs
*
* @return void
* @api
*/
public function OnFormSubmit($oObject, $sFormPrefix = '');
/**
* Invoked when the end-user clicks on Cancel from the object edition form
*
* Implement here any cleanup. This is necessary when you have injected some
* javascript into the edition form, and if that code requires to store temporary data
* (this is the case when a file must be uploaded).
*
* @param string $sTempId Unique temporary identifier made of session_id and transaction_id. It identifies the object in a unique way.
*
* @return void
* @api
*/
public function OnFormCancel($sTempId);
/**
* Not yet called by the framework!
*
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
*
* @param DBObject $oObject The object being displayed
*
* @return string[] desc
* @api
*/
public function EnumUsedAttributes($oObject); // Not yet implemented
/**
* Not yet called by the framework!
*
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
*
* @param DBObject $oObject The object being displayed
*
* @return string Path of the icon, relative to the modules directory.
* @api
*/
public function GetIcon($oObject); // Not yet implemented
/**
* Invoked when the object is displayed alone or within a list
*
* Returns a value influencing the appearance of the object depending on its
* state.
*
* Possible values are:
*
* * HILIGHT_CLASS_CRITICAL
* * HILIGHT_CLASS_WARNING
* * HILIGHT_CLASS_OK
* * HILIGHT_CLASS_NONE
*
* @param DBObject $oObject The object being displayed
*
* @return integer The value representing the mood of the object
* @api
*/
public function GetHilightClass($oObject);
/**
* Called when building the Actions menu for a single object or a list of objects
*
* Use this to add items to the Actions menu. You will have to specify a label and an URL.
*
* Example:
* <code>
* $oObject = $oSet->fetch();
* if ($oObject instanceof Sheep)
* {
* return array('View in my app' => 'http://myserver/view_sheeps?id='.$oObject->Get('name'));
* }
* else
* {
* return array();
* }
* </code>
*
* See also iPopupMenuExtension for greater flexibility
*
* @param DBObjectSet $oSet A set of persistent objects (DBObject)
*
* @return array
* @api
*/
public function EnumAllowedActions(DBObjectSet $oSet);
}

View File

@@ -1,19 +0,0 @@
<?php
/**
* Implement this interface to add Dict entries
*
* @see \iTopWebPage::$a_dict_entries
* @api
* @package BackofficeUIExtensibilityAPI
* @since 3.0.0
*/
interface iBackofficeDictEntriesExtension
{
/**
* @return array
* @see \iTopWebPage::a_dict_entries
* @api
*/
public function GetDictEntries(): array;
}

View File

@@ -1,19 +0,0 @@
<?php
/**
* Implement this interface to add Dict entries prefixes
*
* @see \iTopWebPage::$a_dict_entries_prefixes
* @api
* @package BackofficeUIExtensibilityAPI
* @since 3.0.0
*/
interface iBackofficeDictEntriesPrefixesExtension
{
/**
* @return array
* @see \iTopWebPage::a_dict_entries_prefixes
* @api
*/
public function GetDictEntriesPrefixes(): array;
}

View File

@@ -1,20 +0,0 @@
<?php
/**
* Implement this interface to add inline script (JS) to the backoffice pages' head.
* Will be executed first, BEFORE the DOM interpretation.
*
* @see \iTopWebPage::$a_early_scripts
* @api
* @package BackofficeUIExtensibilityAPI
* @since 3.0.0
*/
interface iBackofficeEarlyScriptExtension
{
/**
* @return string
* @see \iTopWebPage::$a_early_scripts
* @api
*/
public function GetEarlyScript(): string;
}

View File

@@ -1,19 +0,0 @@
<?php
/**
* Implement this interface to add inline script (JS) to the backoffice pages that will be executed right when the DOM is ready.
*
* @see \iTopWebPage::$a_init_scripts
* @api
* @package BackofficeUIExtensibilityAPI
* @since 3.0.0
*/
interface iBackofficeInitScriptExtension
{
/**
* @return string
* @see \iTopWebPage::$a_init_scripts
* @api
*/
public function GetInitScript(): string;
}

View File

@@ -1,20 +0,0 @@
<?php
/**
* Implement this interface to add script (JS) files to the backoffice pages
*
* @see \iTopWebPage::$a_linked_scripts
* @api
* @package BackofficeUIExtensibilityAPI
* @since 3.0.0
*/
interface iBackofficeLinkedScriptsExtension
{
/**
* Each script will be included using this property
* @return array An array of absolute URLs to the files to include
* @see \iTopWebPage::$a_linked_scripts
* @api
*/
public function GetLinkedScriptsAbsUrls(): array;
}

View File

@@ -1,19 +0,0 @@
<?php
/**
* Implement this interface to add stylesheets (CSS) to the backoffice pages
*
* @see \iTopWebPage::$a_linked_stylesheets
* @api
* @package BackofficeUIExtensibilityAPI
* @since 3.0.0
*/
interface iBackofficeLinkedStylesheetsExtension
{
/**
* @return array An array of absolute URLs to the files to include
* @see \iTopWebPage::$a_linked_stylesheets
* @api
*/
public function GetLinkedStylesheetsAbsUrls(): array;
}

View File

@@ -1,19 +0,0 @@
<?php
/**
* Implement this interface to add inline script (JS) to the backoffice pages that will be executed slightly AFTER the DOM is ready (just after the init. scripts).
*
* @see \iTopWebPage::$a_ready_scripts
* @api
* @package BackofficeUIExtensibilityAPI
* @since 3.0.0
*/
interface iBackofficeReadyScriptExtension
{
/**
* @return string
* @see \iTopWebPage::$a_ready_scripts
* @api
*/
public function GetReadyScript(): string;
}

View File

@@ -1,19 +0,0 @@
<?php
/**
* Implement this interface to add sass file (SCSS) to the backoffice pages.
* example: return "css/setup.scss"
*
* @api
* @package BackofficeUIExtensibilityAPI
* @since 3.3.0
*/
interface iBackofficeSassExtension
{
/**
* @return string
* @see \iTopWebPage::$a_styles
* @api
*/
public function GetSass(): string;
}

View File

@@ -1,19 +0,0 @@
<?php
/**
* Implement this interface to add inline script (JS) to the backoffice pages that will be executed immediately, without waiting for the DOM to be ready.
*
* @see \iTopWebPage::$a_scripts
* @api
* @package BackofficeUIExtensibilityAPI
* @since 3.0.0
*/
interface iBackofficeScriptExtension
{
/**
* @return string
* @see \iTopWebPage::$a_scripts
* @api
*/
public function GetScript(): string;
}

View File

@@ -1,19 +0,0 @@
<?php
/**
* Implement this interface to add inline style (CSS) to the backoffice pages' head.
*
* @see \iTopWebPage::$a_styles
* @api
* @package BackofficeUIExtensibilityAPI
* @since 3.0.0
*/
interface iBackofficeStyleExtension
{
/**
* @return string
* @see \iTopWebPage::$a_styles
* @api
*/
public function GetStyle(): string;
}

View File

@@ -1,35 +0,0 @@
<?php
/**
* Implement this interface to register a new field renderer mapping to either:
* - Add the rendering of a new attribute type
* - Overload the default rendering of an attribute type
*
* @since 3.1.0 N°6041
*
* @experimental Form / Field / Renderer should be used in more places in next iTop releases, which may introduce major API changes
*/
interface iFieldRendererMappingsExtension
{
/**
* @return array {
* array: {
* field: string,
* form_renderer: string,
* field_renderer: string
* }
* } List of field renderer mapping: FQCN field class, FQCN Form Renderer class, FQCN Field Renderer class
*
* Example:
*
* ```php
* [
* ['field' => 'FQCN\FieldA', 'form_renderer' => 'Combodo\iTop\Renderer\Console\ConsoleFormRenderer', 'field_renderer' => 'FQCN\FieldRendererA'],
* ['field' => 'FQCN\FieldB', 'form_renderer' => 'Combodo\iTop\Renderer\Console\ConsoleFormRenderer', 'field_renderer' => 'FQCN\FieldRendererB'],
* ['field' => 'FQCN\FieldA', 'form_renderer' => 'Combodo\iTop\Renderer\Bootstrap\BsFormRenderer', 'field_renderer' => 'FQCN\FieldRendererA'],
* ['field' => 'FQCN\FieldB', 'form_renderer' => 'Combodo\iTop\Renderer\Bootstrap\BsFormRenderer', 'field_renderer' => 'FQCN\FieldRendererB'],
* ]
* ```
*/
public static function RegisterSupportedFields(): array;
}

View File

@@ -1,47 +0,0 @@
<?php
/**
* Implement this interface to add content to any iTopWebPage
*
* There are 3 places where content can be added:
*
* * The north pane: (normaly empty/hidden) at the top of the page, spanning the whole
* width of the page
* * The south pane: (normaly empty/hidden) at the bottom of the page, spanning the whole
* width of the page
* * The admin banner (two tones gray background) at the left of the global search.
* Limited space, use it for short messages
*
* Each of the methods of this interface is supposed to return the HTML to be inserted at
* the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions
*
* @api
* @package BackofficeUIExtensibilityAPI
* @since 3.0.0
*/
interface iPageUIBlockExtension
{
/**
* Add content to the "admin banner"
*
* @api
* @return \Combodo\iTop\Application\UI\Base\iUIBlock|null The Block to add into the page
*/
public function GetBannerBlock();
/**
* Add content to the header of the page
*
* @api
* @return \Combodo\iTop\Application\UI\Base\iUIBlock|null The Block to add into the page
*/
public function GetHeaderBlock();
/**
* Add content to the footer of the page
*
* @api
* @return \Combodo\iTop\Application\UI\Base\iUIBlock|null The Block to add into the page
*/
public function GetFooterBlock();
}

View File

@@ -1,112 +0,0 @@
<?php
/**
* New extension to add menu items in the "popup" menus inside iTop. Provides a greater flexibility than
* iApplicationUIExtension::EnumAllowedActions.
*
* To add some menus into iTop, declare a class that implements this interface, it will be called automatically
* by the application, as long as the class definition is included somewhere in the code
*
* @api
* @package UIExtensibilityAPI
* @since 2.0
*/
interface iPopupMenuExtension
{
/**
* Insert an item into the Actions menu of a list
*
* $param is a DBObjectSet containing the list of objects
* @api
*/
const MENU_OBJLIST_ACTIONS = 1;
/**
* Insert an item into the Toolkit menu of a list
*
* $param is a DBObjectSet containing the list of objects
* @api
*/
const MENU_OBJLIST_TOOLKIT = 2;
/**
* Insert an item into the Actions menu on an object details page
*
* $param is a DBObject instance: the object currently displayed
* @api
*/
const MENU_OBJDETAILS_ACTIONS = 3;
/**
* Insert an item into the Dashboard menu
*
* The dashboad menu is shown on the top right corner when a dashboard
* is being displayed.
*
* $param is a Dashboard instance: the dashboard currently displayed
* @api
*/
const MENU_DASHBOARD_ACTIONS = 4;
/**
* Insert an item into the User menu (upper right corner)
*
* $param is null
* @api
*/
const MENU_USER_ACTIONS = 5;
/**
* Insert an item into the Action menu on an object item in an objects list in the portal
*
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object on
* the current line)
* @api
*/
const PORTAL_OBJLISTITEM_ACTIONS = 7;
/**
* Insert an item into the Action menu on an object details page in the portal
*
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object
* currently displayed)
* @api
*/
const PORTAL_OBJDETAILS_ACTIONS = 8;
/**
* Insert an item into the Actions menu of a list in the portal
* Note: This is not implemented yet !
*
* $param is an array('portal_id' => $sPortalId, 'object_set' => $oSet) containing DBObjectSet containing the list of objects
*
* @todo
*/
const PORTAL_OBJLIST_ACTIONS = 6;
/**
* Insert an item into the user menu of the portal
* Note: This is not implemented yet !
*
* $param is the portal id
*
* @todo
*/
const PORTAL_USER_ACTIONS = 9;
/**
* Insert an item into the navigation menu of the portal
* Note: This is not implemented yet !
*
* $param is the portal id
*
* @todo
*/
const PORTAL_MENU_ACTIONS = 10;
/**
* Get the list of items to be added to a menu.
*
* This method is called by the framework for each menu.
* The items will be inserted in the menu in the order of the returned array.
*
* @param int $iMenuId The identifier of the type of menu, as listed by the constants MENU_xxx
* @param mixed $param Depends on $iMenuId, see the constants defined above
*
* @return object[] An array of ApplicationPopupMenuItem or an empty array if no action is to be added to the menu
* @api
*/
public static function EnumItems($iMenuId, $param);
}

View File

@@ -1,28 +0,0 @@
<?php
/**
* @api
* @package PreferencesExtensibilityAPI
* @since 2.7.0
*/
interface iPreferencesExtension
{
/**
* @api
*
* @param \Combodo\iTop\Application\WebPage\WebPage $oPage
*
*/
public function DisplayPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage);
/**
* @api
*
* @param string $sOperation
*
* @param \Combodo\iTop\Application\WebPage\WebPage $oPage
*
* @return bool true if the operation has been used
*/
public function ApplyPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage, $sOperation);
}

View File

@@ -1,38 +0,0 @@
<?php
/**
* Interface to provide messages to be displayed in the "Welcome Popup"
*
* @api
* @since 3.2.0
*/
interface iWelcomePopupExtension
{
// Importance for ordering messages
// Just two levels since less important messages have nothing to do in the welcome popup
public const ENUM_IMPORTANCE_CRITICAL = 0;
public const ENUM_IMPORTANCE_HIGH = 1;
public const DEFAULT_IMPORTANCE = self::ENUM_IMPORTANCE_HIGH;
/**
* Overload this method if you need to display an icon representing the provider (eg. your own company logo, module icon, ...)
*
* @return string Relative path (from app. root) of the icon representing the provider
* @api
*/
public function GetIconRelPath(): string;
/**
* @return \Combodo\iTop\Application\WelcomePopup\Message[]
* @api
*/
public function GetMessages(): array;
/**
* Overload this method if the provider needs to do some additional processing after the message ($sMessageId) has been acknowledged by the current user
*
* @param string $sMessageId
* @api
*/
public function AcknowledgeMessage(string $sMessageId): void;
}

View File

@@ -1,16 +0,0 @@
<?php
/**
* Implement this interface to add files to the backup
*
* @api
* @since 3.2.0
*/
interface iBackupExtraFilesExtension
{
/**
* @return string[] Array of relative paths (from app root) for files and directories to be included in the backup
* @api
*/
public function GetExtraFilesRelPaths(): array;
}

View File

@@ -1,25 +0,0 @@
<?php
/**
* KPI logging extensibility point
*
* KPI Logger extension
*/
interface iKPILoggerExtension
{
/**
* Init the statistics collected
*
* @return void
*/
public function InitStats();
/**
* Add a new KPI to the stats
*
* @param \Combodo\iTop\Core\Kpi\KpiLogData $oKpiLogData
*
* @return mixed
*/
public function LogOperation($oKpiLogData);
}

View File

@@ -1,16 +0,0 @@
<?php
/**
* Helpers for modules extensibility, with discover performed by the MetaModel.
*
*
* @api
* @package Extensibility
*/
interface iModuleExtension
{
/**
* @api
*/
public function __construct();
}

View File

@@ -1,159 +0,0 @@
<?php
/**
* Login finite state machine
*
* Execute the action corresponding to the current login state.
*
* * If a page is displayed, the action must exit at this point
* * if LoginWebPage::LOGIN_FSM_RETURN_ERROR is returned $iErrorCode must be set
* * if LoginWebPage::LOGIN_FSM_RETURN_OK is returned then the login is OK and terminated
* * if LoginWebPage::LOGIN_FSM_CONTINUE is returned then the FSM will proceed to next plugin or to next state
*
* @api
* @package LoginExtensibilityAPI
* @since 2.7.0
*/
abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
{
/**
* @inheritDoc
*/
abstract public function ListSupportedLoginModes();
/**
* @inheritDoc
*/
public function LoginAction($sLoginState, &$iErrorCode)
{
switch ($sLoginState) {
case LoginWebPage::LOGIN_STATE_START:
return $this->OnStart($iErrorCode);
case LoginWebPage::LOGIN_STATE_MODE_DETECTION:
return $this->OnModeDetection($iErrorCode);
case LoginWebPage::LOGIN_STATE_READ_CREDENTIALS:
return $this->OnReadCredentials($iErrorCode);
case LoginWebPage::LOGIN_STATE_CHECK_CREDENTIALS:
return $this->OnCheckCredentials($iErrorCode);
case LoginWebPage::LOGIN_STATE_CREDENTIALS_OK:
return $this->OnCredentialsOK($iErrorCode);
case LoginWebPage::LOGIN_STATE_USER_OK:
return $this->OnUsersOK($iErrorCode);
case LoginWebPage::LOGIN_STATE_CONNECTED:
return $this->OnConnected($iErrorCode);
case LoginWebPage::LOGIN_STATE_ERROR:
return $this->OnError($iErrorCode);
}
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* Initialization
*
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
* @api
*/
protected function OnStart(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* Detect login mode explicitly without respecting configured order (legacy mode)
* In most case do nothing here
*
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
* @api
*/
protected function OnModeDetection(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* Obtain the credentials either if login mode is empty or set to yours.
* This step can be called multiple times by the FSM:
* for example:
* 1 - display login form
* 2 - read the values posted by the user (store that in session)
*
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
* @api
*/
protected function OnReadCredentials(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* Control the validity of the data from the session
* Automatic user provisioning can be done here
*
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
* @api
*/
protected function OnCheckCredentials(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
* @api
*/
protected function OnCredentialsOK(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
* @api
*/
protected function OnUsersOK(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
* @api
*/
protected function OnConnected(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
* @api
*/
protected function OnError(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
}

View File

@@ -1,17 +0,0 @@
<?php
/**
* @api
* @package LoginExtensibilityAPI
* @since 2.7.0
*/
interface iLoginExtension
{
/**
* Return the list of supported login modes for this plugin
*
* @return array of supported login modes
* @api
*/
public function ListSupportedLoginModes();
}

View File

@@ -1,24 +0,0 @@
<?php
/**
* @api
* @package LoginExtensibilityAPI
* @since 2.7.0
*/
interface iLoginFSMExtension extends iLoginExtension
{
/**
* Execute action for this login state
* If a page is displayed, the action must exit at this point
* if LoginWebPage::LOGIN_FSM_RETURN_ERROR is returned $iErrorCode must be set
* if LoginWebPage::LOGIN_FSM_RETURN_OK is returned then the login is OK and terminated
* if LoginWebPage::LOGIN_FSM_CONTINUE is returned then the FSM will proceed to next plugin or state
*
* @param string $sLoginState (see LoginWebPage::LOGIN_STATE_...)
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
* @api
*/
public function LoginAction($sLoginState, &$iErrorCode);
}

View File

@@ -1,17 +0,0 @@
<?php
/**
* Login page extensibility
*
* @api
* @package UIExtensibilityAPI
* @since 2.7.0
*/
interface iLoginUIExtension extends iLoginExtension
{
/**
* @return LoginTwigContext
* @api
*/
public function GetTwigContext();
}

View File

@@ -1,15 +0,0 @@
<?php
/**
* @api
* @package LoginExtensibilityAPI
* @since 2.7.0
*/
interface iLogoutExtension extends iLoginExtension
{
/**
* Execute all actions to log out properly
* @api
*/
public function LogoutAction();
}

View File

@@ -1,67 +0,0 @@
<?php
/**
* Extend this class instead of iPortalUIExtension if you don't need to overload all methods
*
* @api
* @package PortalExtensibilityAPI
* @since 2.4.0
*/
abstract class AbstractPortalUIExtension implements iPortalUIExtension
{
/**
* @inheritDoc
*/
public function GetCSSFiles(\Symfony\Component\DependencyInjection\Container $oContainer)
{
return array();
}
/**
* @inheritDoc
*/
public function GetCSSInline(\Symfony\Component\DependencyInjection\Container $oContainer)
{
return null;
}
/**
* @inheritDoc
*/
public function GetJSFiles(\Symfony\Component\DependencyInjection\Container $oContainer)
{
return array();
}
/**
* @inheritDoc
*/
public function GetJSInline(\Symfony\Component\DependencyInjection\Container $oContainer)
{
return null;
}
/**
* @inheritDoc
*/
public function GetBodyHTML(\Symfony\Component\DependencyInjection\Container $oContainer)
{
return null;
}
/**
* @inheritDoc
*/
public function GetMainContentHTML(\Symfony\Component\DependencyInjection\Container $oContainer)
{
return null;
}
/**
* @inheritDoc
*/
public function GetNavigationMenuHTML(\Symfony\Component\DependencyInjection\Container $oContainer)
{
return null;
}
}

View File

@@ -1,87 +0,0 @@
<?php
/**
* Implement this interface to add content to any enhanced portal page
*
* @api
* @package PortalExtensibilityAPI
*
* @since 2.4.0 interface creation
* @since 2.7.0 change method signatures due to Silex to Symfony migration
*/
interface iPortalUIExtension
{
const ENUM_PORTAL_EXT_UI_BODY = 'Body';
const ENUM_PORTAL_EXT_UI_NAVIGATION_MENU = 'NavigationMenu';
const ENUM_PORTAL_EXT_UI_MAIN_CONTENT = 'MainContent';
/**
* Returns an array of CSS file urls
*
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return array
* @api
*/
public function GetCSSFiles(\Symfony\Component\DependencyInjection\Container $oContainer);
/**
* Returns inline (raw) CSS
*
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return string
* @api
*/
public function GetCSSInline(\Symfony\Component\DependencyInjection\Container $oContainer);
/**
* Returns an array of JS file urls
*
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return array
* @api
*/
public function GetJSFiles(\Symfony\Component\DependencyInjection\Container $oContainer);
/**
* Returns raw JS code
*
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return string
* @api
*/
public function GetJSInline(\Symfony\Component\DependencyInjection\Container $oContainer);
/**
* Returns raw HTML code to put at the end of the <body> tag
*
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return string
* @api
*/
public function GetBodyHTML(\Symfony\Component\DependencyInjection\Container $oContainer);
/**
* Returns raw HTML code to put at the end of the #main-wrapper element
*
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return string
* @api
*/
public function GetMainContentHTML(\Symfony\Component\DependencyInjection\Container $oContainer);
/**
* Returns raw HTML code to put at the end of the #topbar and #sidebar elements
*
* @param \Symfony\Component\DependencyInjection\Container $oContainer
*
* @return string
* @api
*/
public function GetNavigationMenuHTML(\Symfony\Component\DependencyInjection\Container $oContainer);
}

View File

@@ -1,102 +0,0 @@
<?php
/**
* Minimal REST response structure. Derive this structure to add response data and error codes.
*
* @api
* @package RESTAPI
* @since 2.0.1
*/
class RestResult
{
/**
* Result: no issue has been encountered
* @api
*/
const OK = 0;
/**
* Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation
* @api
*/
const UNAUTHORIZED = 1;
/**
* Result: the parameter 'version' is missing
* @api
*/
const MISSING_VERSION = 2;
/**
* Result: the parameter 'json_data' is missing
* @api
*/
const MISSING_JSON = 3;
/**
* Result: the input structure is not a valid JSON string
* @api
*/
const INVALID_JSON = 4;
/**
* Result: the parameter 'auth_user' is missing, authentication aborted
* @api
*/
const MISSING_AUTH_USER = 5;
/**
* Result: the parameter 'auth_pwd' is missing, authentication aborted
* @api
*/
const MISSING_AUTH_PWD = 6;
/**
* Result: no operation is available for the specified version
* @api
*/
const UNSUPPORTED_VERSION = 10;
/**
* Result: the requested operation is not valid for the specified version
* @api
*/
const UNKNOWN_OPERATION = 11;
/**
* Result: the requested operation cannot be performed because it can cause data (integrity) loss
* @api
*/
const UNSAFE = 12;
/**
* Result: the request page number is not valid. It must be an integer greater than 0
* @api
*/
const INVALID_PAGE = 13;
/**
* Result: the operation could not be performed, see the message for troubleshooting
* @api
*/
const INTERNAL_ERROR = 100;
/**
* Default constructor - ok!
* @api
*/
public function __construct()
{
$this->code = RestResult::OK;
}
/**
* Result code
* @var int
* @api
*/
public $code;
/**
* Result message
* @var string
* @api
*/
public $message;
/**
* Sanitize the content of this result to hide sensitive information
*/
public function SanitizeContent()
{
// The default implementation does nothing
}
}

View File

@@ -1,368 +0,0 @@
<?php
/**
* Helpers for implementing REST services
*
* @api
* @package RESTAPI
*/
class RestUtils
{
/**
* Registering tracking information. Any further object modification be associated with the given comment, when the modification gets
* recorded into the DB
*
* @param StdClass $oData Structured input data. Must contain 'comment'.
*
* @return void
* @throws Exception
* @api
*
*/
public static function InitTrackingComment($oData)
{
$sComment = self::GetMandatoryParam($oData, 'comment');
CMDBObject::SetTrackInfo($sComment);
}
/**
* Read a mandatory parameter from from a Rest/Json structure.
*
* @param string $sParamName Name of the parameter to fetch from the input data
* @param StdClass $oData Structured input data. Must contain the entry defined by sParamName.
*
* @return mixed parameter value if present
* @throws Exception If the parameter is missing
* @api
*/
public static function GetMandatoryParam($oData, $sParamName)
{
if (isset($oData->$sParamName)) {
return $oData->$sParamName;
} else {
throw new Exception("Missing parameter '$sParamName'");
}
}
/**
* Read an optional parameter from a Rest/Json structure.
*
* @param string $sParamName Name of the parameter to fetch from the input data
* @param mixed $default Default value if the parameter is not found in the input data
*
* @param StdClass $oData Structured input data.
*
* @return mixed
* @throws Exception
* @api
*/
public static function GetOptionalParam($oData, $sParamName, $default)
{
if (isset($oData->$sParamName)) {
return $oData->$sParamName;
} else {
return $default;
}
}
/**
* Read a class from a Rest/Json structure.
*
* @param string $sParamName Name of the parameter to fetch from the input data
* @param StdClass $oData Structured input data. Must contain the entry defined by sParamName.
*
* @return string
* @throws Exception If the parameter is missing or the class is unknown
* @api
*/
public static function GetClass($oData, $sParamName)
{
$sClass = self::GetMandatoryParam($oData, $sParamName);
if (!MetaModel::IsValidClass($sClass)) {
throw new Exception("$sParamName: '$sClass' is not a valid class'");
}
return $sClass;
}
/**
* Read a list of attribute codes from a Rest/Json structure.
*
* @param StdClass $oData Structured input data.
* @param string $sParamName Name of the parameter to fetch from the input data
*
* @param string $sClass Name of the class
*
* @return array of class => list of attributes (see RestResultWithObjects::AddObject that uses it)
* @throws Exception
* @api
*/
public static function GetFieldList($sClass, $oData, $sParamName)
{
$sFields = self::GetOptionalParam($oData, $sParamName, '*');
$aShowFields = array();
if ($sFields == '*') {
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
$aShowFields[$sClass][] = $sAttCode;
}
} elseif ($sFields == '*+') {
foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sRefClass) {
foreach (MetaModel::ListAttributeDefs($sRefClass) as $sAttCode => $oAttDef) {
$aShowFields[$sRefClass][] = $sAttCode;
}
}
} else {
foreach (explode(',', $sFields) as $sAttCode) {
$sAttCode = trim($sAttCode);
if (($sAttCode != 'id') && (!MetaModel::IsValidAttCode($sClass, $sAttCode))) {
throw new Exception("$sParamName: invalid attribute code '$sAttCode'");
}
$aShowFields[$sClass][] = $sAttCode;
}
}
return $aShowFields;
}
/**
* Read and interpret object search criteria from a Rest/Json structure
*
* @param string $sClass Name of the class
* @param StdClass $oCriteria Hash of attribute code => value (can be a substructure or a scalar, depending on the nature of the
* attriute)
*
* @return object The object found
* @throws Exception If the input structure is not valid or it could not find exactly one object
* @api
*/
protected static function FindObjectFromCriteria($sClass, $oCriteria)
{
$aCriteriaReport = array();
if (isset($oCriteria->finalclass)) {
if (!MetaModel::IsValidClass($oCriteria->finalclass)) {
throw new Exception("finalclass: Unknown class '" . $oCriteria->finalclass . "'");
}
if (!MetaModel::IsParentClass($sClass, $oCriteria->finalclass)) {
throw new Exception("finalclass: '" . $oCriteria->finalclass . "' is not a child class of '$sClass'");
}
$sClass = $oCriteria->finalclass;
}
$oSearch = new DBObjectSearch($sClass);
foreach ($oCriteria as $sAttCode => $value) {
$realValue = static::MakeValue($sClass, $sAttCode, $value);
$oSearch->AddCondition($sAttCode, $realValue, '=');
if (is_object($value) || is_array($value)) {
$value = json_encode($value);
}
$aCriteriaReport[] = "$sAttCode: $value ($realValue)";
}
$oSet = new DBObjectSet($oSearch);
$iCount = $oSet->Count();
if ($iCount == 0) {
throw new Exception("No item found with criteria: " . implode(', ', $aCriteriaReport));
} elseif ($iCount > 1) {
throw new Exception("Several items found ($iCount) with criteria: " . implode(', ', $aCriteriaReport));
}
$res = $oSet->Fetch();
return $res;
}
/**
* Find an object from a polymorph search specification (Rest/Json)
*
* @param mixed $key Either search criteria (substructure), or an object or an OQL string.
* @param bool $bAllowNullValue Allow the cases such as key = 0 or key = {null} and return null then
* @param string $sClass Name of the class
*
* @return DBObject The object found
* @throws Exception If the input structure is not valid or it could not find exactly one object
*
* @api
* @see DBObject::CheckChangedExtKeysValues() generic method to check that we can access the linked object isn't used in that use case because values can be literal, OQL, friendlyname
*/
public static function FindObjectFromKey($sClass, $key, $bAllowNullValue = false)
{
if (is_object($key)) {
$res = static::FindObjectFromCriteria($sClass, $key);
} elseif (is_numeric($key)) {
if ($bAllowNullValue && ($key == 0)) {
$res = null;
} else {
$res = MetaModel::GetObject($sClass, $key, false);
if (is_null($res)) {
throw new Exception("Invalid object $sClass::$key");
}
}
} elseif (is_string($key)) {
// OQL
$oSearch = DBObjectSearch::FromOQL($key);
$oSet = new DBObjectSet($oSearch);
$iCount = $oSet->Count();
if ($iCount == 0) {
throw new Exception("No item found for query: $key");
} elseif ($iCount > 1) {
throw new Exception("Several items found ($iCount) for query: $key");
}
$res = $oSet->Fetch();
} else {
throw new Exception("Wrong format for key");
}
return $res;
}
/**
* Search objects from a polymorph search specification (Rest/Json)
*
* @param string $sClass Name of the class
* @param mixed $key Either search criteria (substructure), or an object or an OQL string.
* @param int $iLimit The limit of results to return
* @param int $iOffset The offset of results to return
*
* @return DBObjectSet The search result set
* @throws Exception If the input structure is not valid
* @api
*/
public static function GetObjectSetFromKey($sClass, $key, $iLimit = 0, $iOffset = 0)
{
if (is_object($key)) {
if (isset($key->finalclass)) {
$sClass = $key->finalclass;
if (!MetaModel::IsValidClass($sClass)) {
throw new Exception("finalclass: Unknown class '$sClass'");
}
}
$oSearch = new DBObjectSearch($sClass);
foreach ($key as $sAttCode => $value) {
$realValue = static::MakeValue($sClass, $sAttCode, $value);
$oSearch->AddCondition($sAttCode, $realValue, '=');
}
} elseif (is_numeric($key)) {
$oSearch = new DBObjectSearch($sClass);
$oSearch->AddCondition('id', $key);
} elseif (is_string($key)) {
// OQL
try {
$oSearch = DBObjectSearch::FromOQL($key);
} catch (Exception $e) {
throw new CoreOqlException('Query failed to execute', [
'query' => $key,
'exception_class' => get_class($e),
'exception_message' => $e->getMessage(),
]);
}
} else {
throw new Exception("Wrong format for key");
}
$oObjectSet = new DBObjectSet($oSearch, array(), array(), null, $iLimit, $iOffset);
return $oObjectSet;
}
/**
* Interpret the Rest/Json value and get a valid attribute value
*
* @param string $sAttCode Attribute code
* @param mixed $value Depending on the type of attribute (a scalar, or search criteria, or list of related objects...)
* @param string $sClass Name of the class
*
* @return mixed The value that can be used with DBObject::Set()
* @throws Exception If the specification of the value is not valid.
* @api
*/
public static function MakeValue($sClass, $sAttCode, $value)
{
try {
if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) {
throw new Exception("Unknown attribute");
}
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
if ($oAttDef instanceof AttributeExternalKey) {
$oExtKeyObject = static::FindObjectFromKey($oAttDef->GetTargetClass(), $value, true /* allow null */);
$value = ($oExtKeyObject != null) ? $oExtKeyObject->GetKey() : 0;
} elseif ($oAttDef instanceof AttributeLinkedSet) {
if (!is_array($value)) {
throw new Exception("A link set must be defined by an array of objects");
}
$sLnkClass = $oAttDef->GetLinkedClass();
$aLinks = array();
foreach ($value as $oValues) {
$oLnk = static::MakeObjectFromFields($sLnkClass, $oValues);
// Fix for N°1939
if (($oAttDef instanceof AttributeLinkedSetIndirect) && ($oLnk->Get($oAttDef->GetExtKeyToRemote()) == 0)) {
continue;
}
$aLinks[] = $oLnk;
}
$value = DBObjectSet::FromArray($sLnkClass, $aLinks);
} elseif ($oAttDef instanceof AttributeTagSet) {
if (!is_array($value)) {
throw new Exception("A tag set must be defined by an array of tag codes");
}
$value = $oAttDef->FromJSONToValue($value);
} else {
$value = $oAttDef->FromJSONToValue($value);
}
} catch (Exception $e) {
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
}
return $value;
}
/**
* Interpret a Rest/Json structure that defines attribute values, and build an object
*
* @param array $aFields A hash of attribute code => value specification.
* @param string $sClass Name of the class
*
* @return DBObject The newly created object
* @throws Exception If the specification of the values is not valid
* @api
*/
public static function MakeObjectFromFields($sClass, $aFields)
{
$oObject = MetaModel::NewObject($sClass);
foreach ($aFields as $sAttCode => $value) {
$realValue = static::MakeValue($sClass, $sAttCode, $value);
try {
$oObject->Set($sAttCode, $realValue);
} catch (Exception $e) {
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
}
}
return $oObject;
}
/**
* Interpret a Rest/Json structure that defines attribute values, and update the given object
*
* @param array $aFields A hash of attribute code => value specification.
* @param DBObject $oObject The object being modified
*
* @return DBObject The object modified
* @throws Exception If the specification of the values is not valid
* @api
*/
public static function UpdateObjectFromFields($oObject, $aFields)
{
$sClass = get_class($oObject);
foreach ($aFields as $sAttCode => $value) {
$realValue = static::MakeValue($sClass, $sAttCode, $value);
try {
$oObject->Set($sAttCode, $realValue);
} catch (Exception $e) {
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
}
}
return $oObject;
}
}

View File

@@ -1,12 +0,0 @@
<?php
/**
* A REST service provider implementing this interface will have its input JSON data sanitized for logging purposes
*
* @see \iRestServiceProvider
* @since 2.7.13, 3.2.1-1
*/
interface iRestInputSanitizer
{
public function SanitizeJsonInput(string $sJsonInput): string;
}

View File

@@ -1,33 +0,0 @@
<?php
/**
* Implement this interface to add new operations to the REST/JSON web service
*
* @api
* @package RESTExtensibilityAPI
* @since 2.0.1
*/
interface iRestServiceProvider
{
/**
* Enumerate services delivered by this class
*
* @param string $sVersion The version (e.g. 1.0) supported by the services
*
* @return array An array of hash 'verb' => verb, 'description' => description
* @api
*/
public function ListOperations($sVersion);
/**
* Enumerate services delivered by this class
*
* @param string $sVersion The version (e.g. 1.0) supported by the services
* @param string $sVerb
* @param array $aParams
*
* @return RestResult The standardized result structure (at least a message)
* @api
*/
public function ExecOperation($sVersion, $sVerb, $aParams);
}

View File

@@ -214,15 +214,6 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
*/
protected static bool $bBlockEventDBLinksChanged = false;
/**
* If set to true, the object is considered as modified, whatever the actual state is.
* This is used when an object is modified indirectly (eg. through a linked set)
*
* @var bool
*
* @since 3.3.0 N°8210 - Remove iApplicationObjectExtension
*/
private bool $bIsMarkedAsModified = false;
/**
* Constructor from a row of data (as a hash 'attcode' => value)
@@ -4551,6 +4542,21 @@ HTML;
return $res;
}
protected function PostInsertActions(): void
{
parent::PostInsertActions();
// Invoke extensions after insertion (the object must exist, have an id, etc.)
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins(iApplicationObjectExtension::class) as $oExtensionInstance) {
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBInsert()");
$oKPI = new ExecutionKPI();
$oExtensionInstance->OnDBInsert($this, self::GetCurrentChange());
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBInsert');
}
}
/**
* @inheritdoc
* Attaches InlineImages to the current object
@@ -4583,6 +4589,21 @@ HTML;
return $res;
}
protected function PostUpdateActions(array $aChanges): void
{
parent::PostUpdateActions($aChanges);
// Invoke extensions after the update (could be before)
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins(iApplicationObjectExtension::class) as $oExtensionInstance) {
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBUpdate()");
$oKPI = new ExecutionKPI();
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBUpdate');
}
}
/**
* @param string $sMessageIdPrefix
*
@@ -4618,6 +4639,21 @@ HTML;
return $oDeletionPlan;
}
final protected function PreDeleteActions(): void
{
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBDelete()");
$oKPI = new ExecutionKPI();
$oExtensionInstance->OnDBDelete($this, self::GetCurrentChange());
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBDelete');
}
parent::PreDeleteActions();
}
final protected function PostDeleteActions(): void
{
parent::PostDeleteActions();
@@ -4630,20 +4666,25 @@ HTML;
return true;
}
return $this->bIsMarkedAsModified;
}
// Plugins
//
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified()");
$oKPI = new ExecutionKPI();
$bIsModified = $oExtensionInstance->OnIsModified($this);
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnIsModified');
if ($bIsModified) {
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified() -> true");
return true;
} else {
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified() -> false");
}
}
/**
* Override the default modification state of the object.
*
* The object is considered as modified, whatever the actual state is.
* This is used when an object is modified indirectly (eg. through a linked set)
*
* @return void
*/
public function MarkObjectAsModified(): void
{
$this->bIsMarkedAsModified = true;
return false;
}
/**
@@ -4657,7 +4698,7 @@ HTML;
}
/**
* Whether to bypass the checks of user rights when writing this object
* Whether to bypass the checks of user rights when writing this object, could be used in {@link \iApplicationObjectExtension::OnCheckToWrite()}
*
* @return bool
*/
@@ -4686,6 +4727,22 @@ HTML;
{
parent::DoCheckToWrite();
// Plugins
//
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnCheckToWrite()");
$oKPI = new ExecutionKPI();
$aNewIssues = $oExtensionInstance->OnCheckToWrite($this);
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToWrite');
if (is_array($aNewIssues) && (count($aNewIssues) > 0)) // Some extensions return null instead of an empty array
{
$this->m_aCheckIssues = array_merge($this->m_aCheckIssues, $aNewIssues);
}
}
// User rights
//
if (!$this->bAllowWrite)
@@ -4722,6 +4779,22 @@ HTML;
{
parent::DoCheckToDelete($oDeletionPlan);
// Plugins
//
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnCheckToDelete()");
$oKPI = new ExecutionKPI();
$aNewIssues = $oExtensionInstance->OnCheckToDelete($this);
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToDelete');
if (is_array($aNewIssues) && count($aNewIssues) > 0)
{
$this->m_aDeleteIssues = array_merge($this->m_aDeleteIssues, $aNewIssues);
}
}
// User rights
//
if (! $this->bAllowDelete)
@@ -5736,7 +5809,7 @@ JS
{
$this->NotifyAttachedObjectsOnLinkClassModification();
$this->RemoveObjectAwaitingEventDbLinksChanged(get_class($this), $this->GetKey());
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges, 'stimulus_applied' => $sStimulusBeingApplied, 'cmdb_change' => self::GetCurrentChange()]);
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges, 'stimulus_applied' => $sStimulusBeingApplied]);
}
//////////////
@@ -5774,7 +5847,7 @@ JS
final protected function FireEventAfterDelete(): void
{
$this->NotifyAttachedObjectsOnLinkClassModification();
$this->FireEvent(EVENT_DB_AFTER_DELETE, ['cmdb_change' => self::GetCurrentChange()]);
$this->FireEvent(EVENT_DB_AFTER_DELETE);
}
/**

View File

@@ -18,7 +18,7 @@
"laminas/laminas-mail": "^2.11",
"laminas/laminas-servicemanager": "^3.5",
"league/oauth2-google": "^4.0.1",
"nikic/php-parser": "dev-master",
"nikic/php-parser": "~5.6.0",
"pear/archive_tar": "~1.4.14",
"pelago/emogrifier": "^7.2.0",
"psr/log": "^3.0.0",
@@ -41,10 +41,6 @@
"symfony/stopwatch": "~6.4.0",
"symfony/web-profiler-bundle": "~6.4.0"
},
"repositories": [{
"type": "vcs",
"url": "https://github.com/Combodo/PHP-Parser"
}],
"suggest": {
"ext-libsodium": "Required to use the AttributeEncryptedString.",
"ext-openssl": "Can be used as a polyfill if libsodium is not installed",

30
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "be4951ced82be6e0ac8c18fa6ddaafc9",
"content-hash": "a0021a80fcc9bccc3f577530893e2974",
"packages": [
{
"name": "apereo/phpcas",
@@ -1020,16 +1020,16 @@
},
{
"name": "nikic/php-parser",
"version": "dev-master",
"version": "v5.6.0",
"source": {
"type": "git",
"url": "https://github.com/Combodo/PHP-Parser.git",
"reference": "8ffc1239ff48ed2476b2672dbcc939fcdc5b0f7a"
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Combodo/PHP-Parser/zipball/8ffc1239ff48ed2476b2672dbcc939fcdc5b0f7a",
"reference": "8ffc1239ff48ed2476b2672dbcc939fcdc5b0f7a",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/221b0d0fdf1369c71047ad1d18bb5880017bbc56",
"reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56",
"shasum": ""
},
"require": {
@@ -1042,14 +1042,13 @@
"ircmaxell/php-yacc": "^0.0.7",
"phpunit/phpunit": "^9.0"
},
"default-branch": true,
"bin": [
"bin/php-parse"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.x-dev"
"dev-master": "5.0-dev"
}
},
"autoload": {
@@ -1057,11 +1056,7 @@
"PhpParser\\": "lib/PhpParser"
}
},
"autoload-dev": {
"psr-4": {
"PhpParser\\": "test/PhpParser/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
@@ -1076,9 +1071,10 @@
"php"
],
"support": {
"source": "https://github.com/Combodo/PHP-Parser/tree/master"
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.6.0"
},
"time": "2025-09-09T09:14:16+00:00"
"time": "2025-07-27T20:03:57+00:00"
},
{
"name": "paragonie/random_compat",
@@ -5247,9 +5243,7 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"nikic/php-parser": 20
},
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {

View File

@@ -8161,7 +8161,7 @@ class AttributeURL extends AttributeString
* @since 3.0.3 moved from Config to AttributeURL constant
*/
public const DEFAULT_VALIDATION_PATTERN = /** @lang RegExp */
'(https?|ftp)\://([a-zA-Z0-9+!*(),;?&=\$_.-]+(\:[a-zA-Z0-9+!*(),;?&=\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\:[0-9]{2,5})?(/([a-zA-Z0-9:%@+\$_-]\.?)+)*/?(\?[a-zA-Z+&\$_.-][a-zA-Z0-9;:[\]@&%=+/\$_.,-]*)?(#[a-zA-Z0-9_.-][a-zA-Z0-9+\$_.-]*)?';
'(https?|ftp)\://([a-zA-Z0-9+!*(),;?&=\$_.-]+(\:[a-zA-Z0-9+!*(),;?&=\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\:[0-9]{2,5})?(/([a-zA-Z0-9:%+\$_-]\.?)+)*/?(\?[a-zA-Z+&\$_.-][a-zA-Z0-9;:[\]@&%=+/\$_.,-]*)?(#[a-zA-Z0-9_.-][a-zA-Z0-9+\$_.-]*)?';
/**
* Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329)

View File

@@ -226,23 +226,27 @@ class CMDBSource
*/
public static function InitServerAndPort($sDbHost, &$sServer, &$iPort)
{
if ($sDbHost != null) {
$aConnectInfo = explode(':', $sDbHost);
$aConnectInfo = explode(':', $sDbHost);
$bUsePersistentConnection = false;
if (strcasecmp($aConnectInfo[0], 'p') === 0) {
$bUsePersistentConnection = true;
$sServer = $aConnectInfo[0].':'.$aConnectInfo[1];
} else {
$sServer = $aConnectInfo[0];
}
$bUsePersistentConnection = false;
if (strcasecmp($aConnectInfo[0], 'p') === 0)
{
$bUsePersistentConnection = true;
$sServer = $aConnectInfo[0].':'.$aConnectInfo[1];
}
else
{
$sServer = $aConnectInfo[0];
}
$iConnectInfoCount = count($aConnectInfo);
if ($bUsePersistentConnection && ($iConnectInfoCount == 3)) {
$iPort = (int)($aConnectInfo[2]);
} else if (!$bUsePersistentConnection && ($iConnectInfoCount == 2)) {
$iPort = (int)($aConnectInfo[1]);
}
$iConnectInfoCount = count($aConnectInfo);
if ($bUsePersistentConnection && ($iConnectInfoCount == 3))
{
$iPort = (int)($aConnectInfo[2]);
}
else if (!$bUsePersistentConnection && ($iConnectInfoCount == 2))
{
$iPort = (int)($aConnectInfo[1]);
}
}

View File

@@ -2021,7 +2021,10 @@ class Config
$bLoadConfig = false;
}
$this->m_aAddons = [];
$this->m_aAddons = array(
// Default AddOn, always present can be moved to an official iTop Module later if needed
'user rights' => 'addons/userrights/userrightsprofile.class.inc.php',
);
foreach ($this->m_aSettings as $sPropCode => $aSettingInfo)
{
@@ -2149,13 +2152,19 @@ class Config
array('file' => $sConfigFile, 'expected' => '$MySettings'));
}
if (!array_key_exists('addons', $MyModules) || !array_key_exists('user rights', $MyModules['addons']))
if (!array_key_exists('addons', $MyModules))
{
throw new ConfigException('Missing item in configuration file',
array('file' => $sConfigFile, 'expected' => '$MyModules[\'addons\']'));
}
if (!array_key_exists('user rights', $MyModules['addons']))
{
// Add one, by default
$MyModules['addons']['user rights'] = 'addons/userrights/userrightsprofile.class.inc.php';
$this->m_aAddons = $MyModules['addons'];
$MyModules['addons']['user rights'] = '/addons/userrights/userrightsnull.class.inc.php';
}
$this->m_aAddons = $MyModules['addons'];
foreach ($MySettings as $sPropCode => $rawvalue)
{
if ($this->IsProperty($sPropCode))
@@ -2259,21 +2268,11 @@ class Config
$this->m_aModuleSettings[$sModule][$sProperty] = $value;
}
/**
* @deprecated 3.3.0 N°8190
*/
public function GetAddons()
{
if (array_key_exists("user rights", $this->m_aAddons)) {
return $this->m_aAddons;
} else {
return array_merge($this->m_aAddons,['user rights' => 'addons/userrights/userrightsprofile.class.inc.php']);
}
return $this->m_aAddons;
}
/**
* @deprecated 3.3.0 N°8190
*/
public function SetAddons($aAddons)
{
$this->m_aAddons = $aAddons;
@@ -2707,6 +2706,15 @@ class Config
{
fwrite($hFile, "\t'addons' => {$aParserValue['value']},\n");
}
else
{
fwrite($hFile, "\t'addons' => array (\n");
foreach ($this->m_aAddons as $sKey => $sFile)
{
fwrite($hFile, "\t\t'$sKey' => '$sFile',\n");
}
fwrite($hFile, "\t),\n");
}
fwrite($hFile, ");\n");
fwrite($hFile, '?'.'>'); // Avoid perturbing the syntax highlighting !
@@ -2852,8 +2860,20 @@ class Config
}
}
}
RunTimeEnvironment::CallInstallerHandler($aModuleInfo, "BeforeWritingConfig", [$this]);
if (isset($aModuleInfo['installer']))
{
$sModuleInstallerClass = $aModuleInfo['installer'];
if (!class_exists($sModuleInstallerClass))
{
throw new Exception("Wrong installer class: '$sModuleInstallerClass' is not a PHP class - Module: ".$aModuleInfo['label']);
}
if (!is_subclass_of($sModuleInstallerClass, 'ModuleInstallerAPI'))
{
throw new Exception("Wrong installer class: '$sModuleInstallerClass' is not derived from 'ModuleInstallerAPI' - Module: ".$aModuleInfo['label']);
}
$aCallSpec = array($sModuleInstallerClass, 'BeforeWritingConfig');
call_user_func_array($aCallSpec, array($this));
}
}
}
$this->SetAddOns($aAddOns);

View File

@@ -1748,9 +1748,9 @@ abstract class DBObject implements iDisplay
* @throws \CoreException
* @since 3.0.0 N°4106 Method should not be overloaded anymore for performances reasons. It will be set final in 3.1.0 (N°4107)
* @since 3.0.0 N°580 New $sType parameter
* @since 3.3.0 N°4107 Should never be overriden
*
*/
public final function GetName($sType = FriendlyNameType::SHORT)
public function GetName($sType = FriendlyNameType::SHORT)
{
return utils::EscapeHtml($this->GetRawName($sType));
}

View File

@@ -7027,7 +7027,7 @@ abstract class MetaModel
* @param array $aParams
* @param bool $bAllowAllData
*
* @return \DBObject|null
* @return \DBObject
* @throws \OQLException
*/
public static function GetObjectFromOQL($sQuery, $aParams = null, $bAllowAllData = false)
@@ -7709,6 +7709,7 @@ abstract class MetaModel
'iLoginUIExtension',
'iPreferencesExtension',
'iApplicationUIExtension',
'iApplicationObjectExtension',
'iPopupMenuExtension',
'iPageUIBlockExtension',
'iBackofficeLinkedScriptsExtension',

View File

@@ -39,23 +39,6 @@
//
// .site-nav a { color:#BADA55!important; }
$ibo-shame--switch--width: 36px !default;
$ibo-shame--switch--height: 20px !default;
$ibo-shame--slider--background-color: $ibo-color-secondary-600 !default;
$ibo-shame--slider--before--height: 15px !default;
$ibo-shame--slider--before--width: 15px !default;
$ibo-shame--slider--before--background-color: $ibo-color-secondary-300 !default;
$ibo-shame--slider--is-checked--background-color: $ibo-color-primary-600 !default;
$ibo-shame--slider--is-focus--box-shadow: 0 0 1px $ibo-color-primary-600 !default;
$ibo-shame--slider--is-round--border-radius: 20px !default;
$ibo-shame--slider--is-round--before--border-radius: 7px !default;
// N°2847 - Recolor svg illustrations with iTop's primary color
.ibo-svg-illustration--container > svg *[fill="#6c63ff"]{
fill: $ibo-svg-illustration--fill;
@@ -73,8 +56,8 @@ $ibo-shame--slider--is-round--before--border-radius: 7px !default;
.switch {
position: relative;
display: inline-block;
width: $ibo-shame--switch--width;
height: $ibo-shame--switch--height;
width: 36px;
height: 20px;
vertical-align: baseline;
}
@@ -91,27 +74,27 @@ $ibo-shame--slider--is-round--before--border-radius: 7px !default;
left: 0;
right: 0;
bottom: 0;
background-color: $ibo-shame--slider--background-color;
background-color: $ibo-color-secondary-600;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: $ibo-shame--slider--before--height;
width: $ibo-shame--slider--before--width;
height: 15px;
width: 15px;
left: 3px;
bottom: 3px;
background-color: $ibo-shame--slider--before--background-color;
background-color: $ibo-color-secondary-300;
transition: .4s;
}
input:checked + .slider {
background-color: $ibo-shame--slider--is-checked--background-color;
background-color: $ibo-color-primary-600;
}
input:focus + .slider {
box-shadow: $ibo-shame--slider--is-focus--box-shadow;
box-shadow: 0 0 1px $ibo-color-primary-600;
}
input:checked + .slider:before {
@@ -120,9 +103,9 @@ input:checked + .slider:before {
/* Rounded sliders */
.slider.round {
border-radius: $ibo-shame--slider--is-round--border-radius;
border-radius: 20px;
}
.slider.round:before {
border-radius: $ibo-shame--slider--is-round--before--border-radius;
border-radius: 7px;
}

View File

@@ -3,14 +3,12 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-bulk--bulk-modify--incompatible-attribute--color--margin-right: $ibo-vendors-selectize--item--icon--margin-right !default;
$ibo-bulk--bulk-modify--incompatible-attribute--color: $ibo-color-information-500 !default;
.ibo-bulk--bulk-modify--incompatible-attribute {
&:before{
margin-right: $ibo-bulk--bulk-modify--incompatible-attribute--color--margin-right;
margin-right: $ibo-vendors-selectize--item--icon--margin-right;
@extend %fa-solid-base;
content: '\f05a';
color: $ibo-bulk--bulk-modify--incompatible-attribute--color;
color: $ibo-color-information-500;
}
}

View File

@@ -3,16 +3,12 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-linked-set--bulk-tooltip-info--content: '\f05a' !default;
$ibo-linked-set--bulk-tooltip-info--color: $ibo-color-information-500 !default;
$ibo-linked-set--bulk-tooltip-info--margin-right: $ibo-vendors-selectize--item--icon--margin-right !default;
.ibo-linked-set--bulk-tooltip-info {
@extend %ibo-font-ral-nor-100;
font-size: $ibo-font-size-100;
&:before{
margin-right: $ibo-linked-set--bulk-tooltip-info--margin-right;
margin-right: $ibo-vendors-selectize--item--icon--margin-right;
@extend %fa-solid-base;
content: $ibo-linked-set--bulk-tooltip-info--content;
color: $ibo-linked-set--bulk-tooltip-info--color;
content: '\f05a';
color: $ibo-color-information-500;
}
}

View File

@@ -9,4 +9,8 @@
.ibo-details .ibo-prop--apply {
display: table-column;
}
.ibo-details {
margin-top: 5px;
}

View File

@@ -16,7 +16,7 @@
@import "panel/all";
@import "pill/all";
@import "dashlet/all";
@import "prop-within-details";
@import "add-to-dashboard";
@import "caselog-entry-form-within-activity-panel";
@import "tab-container-within-panel";
@import "medallion-with-blocklist";

View File

@@ -3,17 +3,13 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-medallion-with-blocklist--icon--image--margin-x: auto !default;
$ibo-medallion-with-blocklist--icon--image--margin-y: 0 !default;
$ibo-medallion-with-blocklist--icon--description--margin-top: $ibo-spacing-400 !default;
.ibo-block-list--medallion{
flex-direction: column;
align-items: center;
> .ibo-medallion-icon--image{
margin: $ibo-medallion-with-blocklist--icon--image--margin-y $ibo-medallion-with-blocklist--icon--image--margin-x;
margin: 0 auto;
~ .ibo-medallion-icon--description{
margin-top: $ibo-medallion-with-blocklist--icon--description--margin-top;
margin-top: 12px;
}
}
> .ibo-medallion-icon--description{

View File

@@ -15,13 +15,6 @@ $ibo-panel-with-tab-container--margin-bottom: -1 * $ibo-panel--body--padding-bot
$ibo-panel-with-tab-container--tab-toggler--font-size--is-sticking: $ibo-font-size-100 !default;
$ibo-tab-container-within-panel--tabs-list--padding-top: $ibo-spacing-800 !default;
// I'm not sure where these values come from, might need to be replaced by variables
$ibo-tab-container-within-panel--tabs-list--min-width: calc(32px + 90px + 32px) !default;
$ibo-tab-container-within-panel--tabs-header--height: $ibo-spacing-800 !default;
$ibo-tab-container-within-panel--tabs--list--is-sticking--z-index: 10 !default;
$ibo-tab-container-within-panel--tabs--list--is-sticking--is-not-vertical--padding-left: $ibo-spacing-0 !default;
// Note: We use the child ">" selector to ensure this applies only to the child tab container, not another one that would be nested
.ibo-panel {
> .ibo-panel--body {
@@ -42,15 +35,15 @@ $ibo-tab-container-within-panel--tabs--list--is-sticking--is-not-vertical--paddi
flex-direction: row;
> .ibo-tab-container--tabs-list {
padding-top: $ibo-tab-container-within-panel--tabs-list--padding-top;
padding-top: 50px;
flex-direction: column;
height: auto;
padding-left: unset;
margin-right: unset;
min-width: $ibo-tab-container-within-panel--tabs-list--min-width;
min-width: calc(32px + 90px + 32px);
> .ibo-tab-container--tab-header {
height: $ibo-tab-container-within-panel--tabs-header--height;
height: 50px;
width: 100%;
justify-content: left;
@@ -75,12 +68,12 @@ $ibo-tab-container-within-panel--tabs--list--is-sticking--is-not-vertical--paddi
> .ibo-tab-container {
> .ibo-tab-container--tabs-list.ibo-is-sticking {
position: fixed;
z-index: $ibo-tab-container-within-panel--tabs--list--is-sticking--z-index;
z-index: 10;
}
&:not(.ibo-is-vertical){
> .ibo-tab-container--tabs-list.ibo-is-sticking {
padding-left: $ibo-tab-container-within-panel--tabs--list--is-sticking--is-not-vertical--padding-left;
padding-left: 0;
.ibo-tab-container--tab-toggler,
.ibo-tab-container--extra-tabs-list-toggler {

View File

@@ -3,11 +3,8 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-datatable-within-panel--panel-body--width: 100% !default;
.ibo-panel .ibo-panel--body{
.ibo-datatable{
width: $ibo-datatable-within-panel--panel-body--width;
width: 100%
}
}

View File

@@ -3,8 +3,6 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-object-details-with-tab-container--tab-list--padding-left: calc(#{$ibo-object-details--icon--spacing--as-medallion} + #{$ibo-object-details--icon--size} + #{$ibo-object-details--icon--spacing--as-medallion} - #{$ibo-tab-container--tab-toggler--padding-x}) !default;
// Note: We use the child ">" selector to ensure this applies only the child tab container, not another one that would be nested
.ibo-object-details.ibo-has-medallion-icon {
> .ibo-panel--body {
@@ -12,7 +10,7 @@ $ibo-object-details-with-tab-container--tab-list--padding-left: calc(#{$ibo-obje
> .ibo-tab-container:not(.ibo-is-vertical) {
> .ibo-tab-container--tabs-list {
// Align tab toggler's title with the panel's title
padding-left: $ibo-object-details-with-tab-container--tab-list--padding-left;
padding-left: calc(#{$ibo-object-details--icon--spacing--as-medallion} + #{$ibo-object-details--icon--size} + #{$ibo-object-details--icon--spacing--as-medallion} - #{$ibo-tab-container--tab-toggler--padding-x});
}
}
}

View File

@@ -9,12 +9,6 @@ $ibo-dashlet--width--is-inline: auto !default;
$ibo-dashlet--elements-spacing-x: $ibo-spacing-600 !default;
$ibo-dashlet--elements-spacing-y: $ibo-spacing-600 !default;
$ibo-dashlet-blocker--z-index: 9 !default; /* To be above calendar links & all, but below .close-box (9) */
$ibo-dashlet-blocker--top: 0 !default;
$ibo-dashlet-blocker--left: 0 !default;
$ibo-dashlet-blocker--width: 100% !default;
$ibo-dashlet-blocker--height: 100% !default;
/* Rules */
.ibo-dashlet {
position: relative;
@@ -29,13 +23,18 @@ $ibo-dashlet-blocker--height: 100% !default;
.ibo-dashlet--is-inline {
width: $ibo-dashlet--width--is-inline;
}
.ibo-details > .ibo-prop--apply {
display: table-column;
}
.ibo-details{
margin-top: 5px;
}
.ibo-dashlet-blocker{
position: absolute;
z-index: $ibo-dashlet-blocker--z-index;
top: $ibo-dashlet-blocker--top;
left: $ibo-dashlet-blocker--left;
width: $ibo-dashlet-blocker--width;
height: $ibo-dashlet-blocker--height;
z-index: 9; /* To be above calendar links & all, but below .close-box (9) */
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: not-allowed;
}

View File

@@ -24,8 +24,6 @@ $ibo-datatable--sort-order--color: $ibo-color-primary-600 !default;
$ibo-fieldsorter--selected--background-color: $ibo-color-blue-200 !default;
$ibo-datatable--selected-result-count--padding-right: 0.2em !default;
$ibo-datatable--selected-result-count--padding-left: 0.1em !default;
/* CSS variables (can be changed directly from the browser) */
:root {
@@ -136,8 +134,8 @@ $ibo-datatable--selected-result-count--padding-left: 0.1em !default;
}
.ibo-datatable--selected-count, .ibo-datatable--result-count{
padding-right: $ibo-datatable--selected-result-count--padding-right;
padding-left: $ibo-datatable--selected-result-count--padding-left;
padding-right: 0.2em;
padding-left: 0.1em;
}
//

View File

@@ -3,7 +3,7 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-input-image--image-view--min-height: $ibo-size-500 !default;
$ibo-input-image--image-view--min-height: 96px !default;
$ibo-input-image--image-view--background-color: $ibo-color-grey-200 !default;
$ibo-input-image--image-view--border-radius: $ibo-border-radius-500 !default;

View File

@@ -1,14 +1,5 @@
/*
* @copyright Copyright (C) 2010-2025 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-input-richtext-placeholder--height: $ibo-size-600 !default;
$ibo-input-richtext-placeholder--width: 100% !default;
.ibo-input-richtext-placeholder{
height: $ibo-input-richtext-placeholder--height;
width: $ibo-input-richtext-placeholder--width;
height: 200px;
width: 100%;
visibility: hidden;
}

View File

@@ -3,8 +3,6 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-input-select-icon--menu--icon--max-height: 100% !default;
$ibo-input-select-icon--menu--icon--max-width: 100% !default;
$ibo-input-select-icon--icon--padding-right: $ibo-spacing-200 !default;
$ibo-input-select-icon--menu--z-index: 21 !default;
@@ -18,8 +16,8 @@ $ibo-input-select-icon--menu--icon--margin-right: 10px !default;
display: inline-flex;
text-align: left;
>img{
max-height: $ibo-input-select-icon--menu--icon--max-height;
max-width: $ibo-input-select-icon--menu--icon--max-width;
max-height: 100%;
max-width: 100%;
padding-right: $ibo-input-select-icon--icon--padding-right;
}
>span{

View File

@@ -20,7 +20,6 @@ $ibo-input-select-selectize--item--active--background-color: $ibo-color-blue-100
$ibo-input-select-wrapper--width: 100% !default;
$ibo-input-select-wrapper--after--content: "\f0d7" !default;
$ibo-input-select-wrapper--after--right: 8px !default;
$ibo-input-select-wrapper--after--height: 28px !default;
$ibo-input-select-wrapper--after--margin-left: -16px !default;
@@ -33,7 +32,6 @@ $ibo-input-select--action-button--height: 28px !default;
$ibo-input-select--action-button--width: 23px !default;
$ibo-input-select--action-button--margin-top: $ibo-spacing-0 !default;
$ibo-input-select--action-button--margin-right: 3px !default;
$ibo-input-select--action-button--font-size: $ibo-font-size-100 !default;
$ibo-input-select--action-button--background-color: inherit !default;
$ibo-input-select--action-button--color: $ibo-color-grey-800 !default;
$ibo-input-select--action-button--padding-x: $ibo-spacing-100 !default;
@@ -59,7 +57,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
min-width: $ibo-input-select-selectize--value--min-midth !important;
input {
border-width: 0;
border-width: 0px;
color: inherit;
border-color: $ibo-color-white-100;
padding-left: $ibo-input-select--padding-x;
@@ -123,7 +121,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
.ibo-input-select-wrapper::after{
position: absolute;
z-index: 1;
content: $ibo-input-select-wrapper--after--content;
content: "\f0d7";
font-family: "Font Awesome 5 Free";
font-weight: 600;
@@ -147,7 +145,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
.ibo-input-select-wrapper--with-buttons:not(.ibo-input-select-autocomplete-wrapper)::after {
position: absolute;
z-index: 1;
content: $ibo-input-select-wrapper--after--content;
content: "\f0d7";
font-family: "Font Awesome 5 Free";
font-weight: 600;
cursor: pointer;
@@ -170,7 +168,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
margin-top: $ibo-input-select--action-button--margin-top;
margin-right: $ibo-input-select--action-button--margin-right;
font-size: $ibo-input-select--action-button--font-size;
font-size: $ibo-font-size-100;
background-color: $ibo-input-select--action-button--background-color;
color: $ibo-input-select--action-button--color;
padding: $ibo-input-select--action-button--padding-y $ibo-input-select--action-button--padding-x;

View File

@@ -8,9 +8,6 @@ $ibo-input-text--min-height: 12rem !default;
$ibo-input-text--padding-x: $ibo-spacing-400 !default;
$ibo-input-text--padding-y: 10px !default;
$ibo-input-text--export--width: 100% !default;
$ibo-input-text--export--min-height: 15em !default;
.ibo-input-text {
width: $ibo-input-text--width;
min-height: $ibo-input-text--min-height;
@@ -26,6 +23,6 @@ $ibo-input-text--export--min-height: 15em !default;
}
.ibo-input-text--export {
width: $ibo-input-text--export--width;
min-height: $ibo-input-text--export--min-height;
width: 100%;
min-height: 15em;
}

View File

@@ -9,8 +9,6 @@ $ibo-toggler--wrapper--height: 20px !default;
$ibo-toggler--slider--border-radius: $ibo-border-radius-900 !default;
$ibo-toggler--slider--background-color: $ibo-color-secondary-600 !default;
$ibo-toggler--slider--before--left: 3px !default;
$ibo-toggler--slider--before--bottom: 3px !default;
$ibo-toggler--slider--before--height: 15px !default;
$ibo-toggler--slider--before--width: 15px !default;
$ibo-toggler--slider--before--border-radius: $ibo-border-radius-full !default;
@@ -48,8 +46,8 @@ $ibo-toggler--label--margin-left: 4px !default;
.ibo-toggler--slider:before {
content: "";
position: absolute;
left: $ibo-toggler--slider--before--left;
bottom: $ibo-toggler--slider--before--bottom;
left: 3px;
bottom: 3px;
height: $ibo-toggler--slider--before--height;
width: $ibo-toggler--slider--before--width;
border-radius: $ibo-toggler--slider--before--border-radius;

View File

@@ -27,9 +27,6 @@ $ibo-input--disabled--background-color: $ibo-color-grey-300 !default;
$ibo-input--placeholder--color: $ibo-color-grey-700 !default;
$ibo-input-wrapper--is-error--border-color: $ibo-color-red-600 !default;
$ibo-input-wrapper--vanilla--is-error--border: 0 !default;
$ibo-input-wrapper--vanilla--is-error--background-color: $ibo-color-transparent !default;
$ibo-field-validation: $ibo-color-red-700 !default;
$ibo-input--margin-x: $ibo-spacing-200 !default;
@@ -65,8 +62,8 @@ textarea.ibo-input{
border-color: $ibo-input-wrapper--is-error--border-color;
}
.ibo-input-vanilla input{
border: $ibo-input-wrapper--vanilla--is-error--border;
background-color: $ibo-input-wrapper--vanilla--is-error--background-color;
border: 0;
background-color: #11ffee00;
}
}
input.ibo-input-vanilla{

View File

@@ -10,10 +10,6 @@ $ibo-popover-menu--padding: $ibo-spacing-0 !default;
$ibo-popover-menu--toggler-visual-hint--margin-left: 0.5rem !default;
$ibo-popover-menu--section--height: 100% !default;
$ibo-popover-menu--section--margin-x: $ibo-spacing-0 !default;
$ibo-popover-menu--section--margin-y: $ibo-spacing-0 !default;
$ibo-popover-menu--section-border-radius: $ibo-popover-menu--border-radius !default;
.ibo-popover-menu {
@@ -39,8 +35,8 @@ $ibo-popover-menu--section-border-radius: $ibo-popover-menu--border-radius !defa
display: flex;
flex-direction: column;
align-self: flex-start;
margin: $ibo-popover-menu--section--margin-y $ibo-popover-menu--section--margin-x;
width: $ibo-popover-menu--section--height;
margin: $ibo-spacing-0 $ibo-spacing-0;
width: 100%;
white-space: nowrap;
overflow: hidden; /* To avoid first/last entries of the menu to have no border-radius on hover */

View File

@@ -6,7 +6,6 @@
@import "navigation-menu";
@import "top-bar";
@import "content";
@import "details";
@import "tab-container/tab-container";
@import "tab-container/tab";
@import "multi-column/multi-column";

View File

@@ -2,9 +2,6 @@
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-v-spacer--padding-top: 1em !default;
$ibo-side-content--background-color: $ibo-content-block--background-color !default;
$ibo-side-content--border-left: $ibo-content-block--border !default;
/* Note: We have to wrap it in the ID in order to overload its rules, otherwise, the ID takes over the simple CSS class... */
#ibo-center-container {
@@ -19,10 +16,10 @@ $ibo-side-content--border-left: $ibo-content-block--border !default;
}
.ibo-v-spacer {
padding-top: $ibo-v-spacer--padding-top;
padding-top: 1em;
}
#ibo-side-content {
background-color: $ibo-side-content--background-color;
border-left: $ibo-side-content--border-left;
background-color: $ibo-content-block--background-color;
border-left: $ibo-content-block--border;
}

View File

@@ -1,9 +0,0 @@
/*
* @copyright Copyright (C) 2010-2025 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-details--margin-top: 5px !default;
.ibo-details {
margin-top: $ibo-details--margin-top;
}

View File

@@ -218,8 +218,7 @@ $ibo-navigation-menu--user-info--height--is-expanded: 100% !default;
.ibo-navigation-menu--body{
width: $ibo-navigation-menu--body--width-expanded;
/* Values are hardcoded to ease the animation and there's no point in overloading them */
.ibo-navigation-menu--toggler-bar{
.ibo-navigation-menu--toggler-bar{
&:nth-child(1){
top: 4px;
left: 7px;
@@ -413,7 +412,6 @@ $ibo-navigation-menu--user-info--height--is-expanded: 100% !default;
transition: all 0.2s linear;
background-color: $ibo-navigation-menu--body--text-color;
/* Values are hardcoded to ease the animation and there's no point in overloading them */
&:nth-child(1){
top: 0;
}

View File

@@ -18,7 +18,6 @@ $ibo-activity-entry--medallion--has-no-image--background-color: $ibo-color-blue-
$ibo-activity-entry--medallion--has-no-image--text-color: $ibo-color-white-100 !default;
$ibo-activity-entry--medallion--has-no-image--border: 1px solid $ibo-color-grey-200 !default;
$ibo-activity-entry--information--margin-to-side: $ibo-spacing-0 !default;
$ibo-activity-entry--information--margin-to-other-side: $ibo-activity-entry--medallion--diameter + $ibo-activity-entry--medallion--margin-with-information !default;
$ibo-activity-entry--main-information--padding-x: $ibo-spacing-500 !default;
@@ -89,7 +88,7 @@ $ibo-activity-panel--load-all-entries--is-hover--margin-left: ($ibo-activity-pan
margin-left: $ibo-activity-entry--medallion--margin-with-information;
}
.ibo-activity-entry--information{
margin-right: $ibo-activity-entry--information--margin-to-side;
margin-right: 0;
margin-left: $ibo-activity-entry--information--margin-to-other-side;
}
.ibo-activity-entry--main-information{
@@ -110,7 +109,7 @@ $ibo-activity-panel--load-all-entries--is-hover--margin-left: ($ibo-activity-pan
&:not(.ibo-is-current-user){
.ibo-activity-entry--information{
margin-right: $ibo-activity-entry--information--margin-to-other-side;
margin-left: $ibo-activity-entry--information--margin-to-side;
margin-left: 0;
}
/* Bubble tip on the left for last entry of the group */
&:last-child{

View File

@@ -104,7 +104,6 @@ $ibo-activity-panel--add-caselog-entry-button--icon--line-height: 33px !default;
$ibo-activity-panel--entry-forms-confirmation-explanation--spacing: $ibo-spacing-500 !default;
$ibo-activity-panel--entry-forms-confirmation-preference-input--spacing: 0.5rem !default;
$ibo-activity-panel--closed-cover--z-index: 2 !default;
$ibo-activity-panel--closed-cover--background-color: $ibo-activity-panel--header--background-color !default;
$ibo-activity-panel--open-icon--margin-left: 0.75rem !default;
@@ -434,12 +433,14 @@ $ibo-activity-panel--open-icon--margin-left: 0.75rem !default;
.ibo-activity-panel--closed-cover {
display: none;
position: absolute;
z-index: $ibo-activity-panel--closed-cover--z-index; // Above the compose button and all
z-index: 2; // Above the compose button and all
// padding-top: 64px;
top: 0;
bottom: 0;
left: 0;
right: 0;
@extend %ibo-fully-centered-content;
// align-items: flex-start;
background-color: $ibo-activity-panel--closed-cover--background-color;
cursor: pointer;
}

View File

@@ -11,7 +11,7 @@ $ibo-caselog-entry-form--actions--margin-top: $ibo-spacing-300 !default;
$ibo-caselog-entry-form--actions--margin-bottom: $ibo-caselog-entry-form--actions--margin-top !default;
$ibo-caselog-entry-form--lock-indicator--margin-top: $ibo-caselog-entry-form--padding-bottom !default;
$ibo-caselog-entry-form--lock-icon--size: $ibo-size-350 !default;
$ibo-caselog-entry-form--lock-icon--size: 32px !default;
$ibo-caselog-entry-form--lock-icon--text-color: $ibo-color-grey-50 !default;
$ibo-caselog-entry-form--lock-icon--background-color: $ibo-color-grey-800 !default;
$ibo-caselog-entry-form--lock-icon--border-radius: $ibo-border-radius-full !default;

View File

@@ -25,10 +25,6 @@ $ibo-dashboard-editor--delete-dashlet-icon--right: 9px !default;
$ibo-dashboard-editor--delete-dashlet-icon--padding: $ibo-spacing-100 6px !default;
$ibo-dashboard-editor--delete-dashlet-icon--z-index: 21 !default;
$ibo-dashlet--properties--padding-bottom: 20px !default;
$ibo-dashlet--properties--table--width: 100% !default;
$ibo-dashlet--properties--table--cell--margin-bottom: 14px !default;
.ibo-dashboard-editor--pane{
flex-grow: 1;
@@ -51,13 +47,13 @@ $ibo-dashlet--properties--table--cell--margin-bottom: 14px !default;
.ibo-dashlet--properties{
display: flex;
flex-direction: column;
padding-bottom: $ibo-dashlet--properties--padding-bottom;
padding-bottom: 20px;
table{
width: $ibo-dashlet--properties--table--width;
width: 100%;
text-align: left;
td, th {
margin-bottom: $ibo-dashlet--properties--table--cell--margin-bottom;
margin-bottom: 14px;
.ibo-field {
@extend %ibo-font-size-100;

View File

@@ -7,38 +7,8 @@
$ibo-dashboard--grid--width: 100% !default;
$ibo-dashboard--grid--elements-spacing-x: $ibo-dashlet--elements-spacing-x !default;
$ibo-dashboard--grid--elements-spacing-y: $ibo-dashlet--elements-spacing-y !default;
$ibo-dashboard--grid--edit-mode--margin: 1px !default;
$ibo-dashboard--grid--edit-mode--border-color: $ibo-color-grey-400 !default;
$ibo-dashboard--grid--edit-mode--border: 2px $ibo-dashboard--grid--edit-mode--border-color dashed !default;
$ibo-dashboard--grid--edit-mode--width: 100% !default;
$ibo-dashboard--grid--edit-mode--min-height: 40px !default;
$ibo-dashboard--top-bar-padding-bottom: 20px !default;
$ibo-dashboard--selector--margin-left: $ibo-spacing-400 !default;
$ibo-dashboard--selector--margin-right: 1 !default;
$ibo-dashboard--selector--hover--background-color: $ibo-color-secondary-100 !default;
$ibo-dashboard--selector--hover--border-radius: $ibo-button--border-radius !default;
$ibo-dashboard--selector--selector-label--margin-x: 10px !default;
$ibo-dashboard--switch--width: 30px !default;
$ibo-dashboard--switch--height: $ibo-size-300 !default;
$ibo-dashboard--slider--before--content: "\f007" !default;
$ibo-dashboard--slider--before--font-size: $ibo-font-size-50 !default;
$ibo-dashboard--slider--before--color: $ibo-color-secondary-800 !default;
$ibo-dashboard--slider--before--right: 5px !default;
$ibo-dashboard--slider--before--bottom: 3px !default;
$ibo-dashboard--slider--after--content: "\f1ad" !default;
$ibo-dashboard--slider--after--font-size: $ibo-font-size-150 !default;
$ibo-dashboard--slider--after--color: $ibo-color-primary-600 !default;
$ibo-dashboard--slider--after--left: 6px !default;
$ibo-dashboard--slider--after--bottom: 1px !default;
/* Rules */
.ibo-dashboard--top-bar {
@extend %ibo-full-height-content;
@@ -60,18 +30,18 @@ $ibo-dashboard--slider--after--bottom: 1px !default;
.ibo-dashboard--selector {
display: flex;
align-items: center;
margin-left: $ibo-dashboard--selector--margin-left;
margin-right: $ibo-dashboard--selector--margin-right;
margin-left: 12px;
margin-right: 1px;
&:hover {
background-color: $ibo-dashboard--selector--hover--background-color;
border-radius: $ibo-dashboard--selector--hover--border-radius;
background-color: $ibo-color-secondary-100;
border-radius: $ibo-button--border-radius;
}
.selector-label {
display: inline-block;
margin-left: $ibo-dashboard--selector--selector-label--margin-x;
margin-right: $ibo-dashboard--selector--selector-label--margin-x;
margin-left: 10px;
margin-right: 10px;
vertical-align: super;
}
}
@@ -105,7 +75,7 @@ $ibo-dashboard--slider--after--bottom: 1px !default;
margin: calc(-1 * #{$ibo-dashboard--grid--elements-spacing-y} / 2) calc(-1 * #{$ibo-dashboard--grid--elements-spacing-x} / 2); /* Because of the margin all around the dashlets, we need to compensate it */
min-width: 0;
/* Compensate negative margin on inner borders to simulate equal dashlets spacing between columns */
/* Compensate negative margin on inner borders to simulate egal dashlets spacing between columns */
&:not(:last-child) {
margin-right: 0;
}
@@ -115,10 +85,10 @@ $ibo-dashboard--slider--after--bottom: 1px !default;
}
&.edit_mode {
margin: $ibo-dashboard--grid--edit-mode--margin;
border: $ibo-dashboard--grid--edit-mode--border;
width: $ibo-dashboard--grid--edit-mode--width;
min-height: $ibo-dashboard--grid--edit-mode--min-height;
margin: 1px;
border: 2px #ccc dashed;
width: 100%;
min-height: 40px;
}
}
@@ -128,8 +98,8 @@ $ibo-dashboard--slider--after--bottom: 1px !default;
.ibo-dashboard--switch {
position: relative;
display: inline-block;
width: $ibo-dashboard--switch--width;
height: $ibo-dashboard--switch--height;
width: 30px;
height: 24px;
vertical-align: baseline;
}
@@ -149,29 +119,31 @@ $ibo-dashboard--slider--after--bottom: 1px !default;
}
.ibo-dashboard--slider:before {
@extend %fa-solid-base;
content: $ibo-dashboard--slider--before--content;
font-size: $ibo-dashboard--slider--before--font-size;
color: $ibo-dashboard--slider--before--color;
position: absolute;
right: $ibo-dashboard--slider--before--right;
bottom: $ibo-dashboard--slider--before--bottom;
right: 5px;
bottom: 3px;
color: $ibo-color-secondary-800;
content: "\f007";
font-family: "Font Awesome 5 Free", serif;
font-size: $ibo-font-size-50;
font-weight: 900;
}
.ibo-dashboard--slider:after {
@extend %fa-solid-base;
content: $ibo-dashboard--slider--after--content;
font-size: $ibo-dashboard--slider--after--font-size;
color: $ibo-dashboard--slider--after--color;
position: absolute;
left: $ibo-dashboard--slider--after--left;
bottom: $ibo-dashboard--slider--after--bottom;
left: 6px;
bottom: 1px;
color: $ibo-color-primary-600;
content: "\f1ad";
font-family: "Font Awesome 5 Free", serif;
font-size: $ibo-font-size-150;
font-weight: 900;
}
input:checked + .ibo-dashboard--slider:before {
content: $ibo-dashboard--slider--after--content;
content: "\f1ad";
}
input:checked + .ibo-dashboard--slider:after {
content: $ibo-dashboard--slider--before--content;
content: "\f007";
}

View File

@@ -4,15 +4,10 @@
*/
$ibo-column--min-width: 300px !default;
$ibo-mini-column--min-width: 30px !default;
$ibo-column--padding-x: abs($ibo-multi-column--margin-x) !default;
$ibo-column--padding-y: $ibo-spacing-0 !default;
$ibo-mini-column--min-width: 30px !default;
$ibo-mini-column--padding-x: $ibo-column--padding-x !default;
$ibo-mini-column--padding-y: $ibo-column--padding-y !default;
$ibo-mini-column--button-margin-left: $ibo-spacing-0 !default;
$ibo-mini-column--button-margin-right: $ibo-spacing-0 !default;
$ibo-column--margin-bottom--is-last-element: $ibo-spacing-800 !default;
.ibo-column {
@@ -31,14 +26,14 @@ $ibo-column--margin-bottom--is-last-element: $ibo-spacing-800 !default;
min-width: $ibo-mini-column--min-width;
flex-grow: 1;
flex-shrink: 1;
padding: $ibo-mini-column--padding-y $ibo-mini-column--padding-x;
padding: $ibo-column--padding-y $ibo-column--padding-x;
flex-basis: 10%;
display: flex;
flex-direction: column;
>.ibo-button{
margin-left: $ibo-mini-column--button-margin-left;
margin-right: $ibo-mini-column--button-margin-right;
margin-left: 0;
margin-right: 0;
}
&:not(:last-child) {
margin-bottom: $ibo-column--margin-bottom--is-last-element;

View File

@@ -3,7 +3,7 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-multi-column--margin-x: -$ibo-spacing-500 !default; /* This is to compensate columns padding and make the whole multicolumn align with the parent borders (cf. Bootstrap rows / cols) */
$ibo-multi-column--margin-x: -16px !default; /* This is to compensate columns padding and make the whole multicolumn align with the parent borders (cf. Bootstrap rows / cols) */
$ibo-multi-column--margin-y: $ibo-spacing-0 !default;
.ibo-multi-column {

View File

@@ -16,8 +16,6 @@ $ibo-object-details--icon--spacing--as-medallion--is-sticking: $ibo-object-detai
$ibo-object-details--status-dot--size: 10px !default;
$ibo-object-details--status-dot--spacing: $ibo-spacing-300 !default;
$ibo-object-details--status-dot--border-radius: $ibo-border-radius-full !default;
$ibo-object-details--status--class--before--content: "(" !default;
$ibo-object-details--status--class--after--content: ")" !default;
$ibo-object-details--tag--sibling-spacing: $ibo-spacing-400 !default;
$ibo-object-details--tag--color: $ibo-panel--subtitle--color !default;
@@ -88,11 +86,11 @@ $ibo-object-details--header-right--padding-right--is-sticking: $ibo-spacing-300
display: inline-flex; /* To avoid having spaces around the class name due to the indentation */
&::before {
content: $ibo-object-details--status--class--before--content;
content: "(";
}
&::after {
content: $ibo-object-details--status--class--after--content;
content: ")";
}
}

View File

@@ -5,13 +5,12 @@
$ibo-wizard-container--padding: 10px $ibo-spacing-500 !default;
$ibo-wizard-container--background-color: $ibo-color-blue-200 !default;
$ibo-wizard-container--border-radius: $ibo-border-radius-300 !default;
$ibo-wizard-container--border-color: $ibo-color-blue-600 !default;
$ibo-wizard-container--border-width: 3px !default;
.ibo-wizard-container {
padding: $ibo-wizard-container--padding;
background: $ibo-wizard-container--background-color;
border-radius: $ibo-wizard-container--border-radius;
border-radius: $ibo-border-radius-300;
border-left: $ibo-wizard-container--border-width solid $ibo-wizard-container--border-color;
}

View File

@@ -63,10 +63,11 @@ $ibo-attachment--tab-header--drop-in--icon--color: $ibo-color-blue-600 !default;
background-color: $ibo-attachment--tab-header--drop-in--background-color;
color: $ibo-attachment--tab-header--drop-in--color;
> a::after{
content: $ibo-attachment--tab-header--drop-in--icon--content;
@extend %fa-solid-base;
padding-left: $ibo-attachment--tab-header--drop-in--icon--padding-left;
color: $ibo-attachment--tab-header--drop-in--icon--color;
font-family: "Font Awesome 5 Free";
content: $ibo-attachment--tab-header--drop-in--icon--content;
font-weight: 900;
color: $ibo-color-blue-600;
}
}
}

View File

@@ -19,19 +19,18 @@ $ibo-audit--audit-line--csv-download--height: 2.5em !default;
$ibo-audit--audit-line--status-indicator--diameter: 12px !default;
$ibo-audit--audit-line--status-indicator--margin-right: 5px !default;
/* Use semantic colors to ease accessibility */
$ibo-audit--status--color: (
'red': (
$ibo-color-danger-700,
$ibo-color-red-700,
),
'orange': (
$ibo-color-warning-700,
$ibo-color-orange-700,
),
'green': (
$ibo-color-success-800,
$ibo-color-green-800,
),
);
@each $sColor, $aAttributes in $ibo-audit--status--color {
$bg-color: nth($aAttributes, 1);
.ibo-audit--audit-category--panel .ibo-panel--body {

View File

@@ -7,7 +7,6 @@ $ibo-csv-import--cell-message--padding-top: 3px !default;
$ibo-csv-import--cell-modified--color: $ibo-color-blue-700 !default;
$ibo-csv-import--cell-error--color: $ibo-color-red-700 !default;
$ibo-csv-import--row--border-color: $ibo-color-grey-400 !default;
$ibo-csv-import--row--border: 1px $ibo-csv-import--row--border-color solid !default;
$ibo-csv-import--row-error--background-color: $ibo-color-red-200 !default;
$ibo-csv-import--download-file--color: $ibo-color-primary-400 !default;
$ibo-csv-import--download-file--font-size: 4em !default;
@@ -32,20 +31,20 @@ div.ibo-csv-import--cell-message {
}
tr.ibo-csv-import--row-unchanged td {
border-bottom: $ibo-csv-import--row--border;
border-bottom: 1px $ibo-csv-import--row--border-color solid;
}
.wizContainer table tr.ibo-csv-import--row-error td {
border-bottom: $ibo-csv-import--row--border;
border-bottom: 1px $ibo-csv-import--row--border-color solid;
background-color: $ibo-csv-import--row-error--background-color;
}
tr.ibo-csv-import--row-modified td {
border-bottom: $ibo-csv-import--row--border;
border-bottom: 1px $ibo-csv-import--row--border-color solid;
}
tr.ibo-csv-import--row-added td {
border-bottom: $ibo-csv-import--row--border;
border-bottom: 1px $ibo-csv-import--row--border-color solid;
}
.ibo-csv-import--download-file {

View File

@@ -11,9 +11,6 @@ $ibo-data-synchro-source--replicas-table--cell--arrow--min-width: 100px !default
$ibo-data-synchro-source--replicas-status--warning--margin: $ibo-spacing-0 5px $ibo-spacing-0 $ibo-spacing-300 !default;
$ibo-data-synchro-source--replicas-status-separator--border-color: $ibo-color-white-100 !default;
$ibo-data-synchro-source--replicas-status-separator--border: 2px solid $ibo-data-synchro-source--replicas-status-separator--border-color !default;
$ibo-data-synchro-source--replicas-status--color: (
'grey': (
$ibo-color-grey-400,
@@ -45,10 +42,6 @@ $ibo-data-synchro-source--replicas-status--color: (
),
) !default;
$ibo-data-synchro-source--synoptics--cell--arrow--border-color: $ibo-color-grey-50 !default;
$ibo-data-synchro-source--synoptics--cell--arrow--border: 2px solid $ibo-data-synchro-source--synoptics--cell--arrow--border-color !default;
@each $sColor, $aAttributes in $ibo-data-synchro-source--replicas-status--color {
$bg-color: nth($aAttributes, 1);
$color: nth($aAttributes, 2);
@@ -57,9 +50,8 @@ $ibo-data-synchro-source--synoptics--cell--arrow--border: 2px solid $ibo-data-sy
background-color: $bg-color;
}
}
.ibo-data-synchro-source--replicas-status-separator {
border-top: $ibo-data-synchro-source--replicas-status-separator--border-color;
border-top: 2px solid $ibo-color-white-100;
}
.ibo-data-synchro-source--replicas-status.ibo-is-light{
@@ -75,7 +67,7 @@ $ibo-data-synchro-source--synoptics--cell--arrow--border: 2px solid $ibo-data-sy
text-align: center;
&.arrow {
min-width: $ibo-data-synchro-source--replicas-table--cell--arrow--min-width;
border-top: $ibo-data-synchro-source--synoptics--cell--arrow--border;
border-top: 2px solid $ibo-color-grey-50;
}
}
.ibo-data-synchro-source--replicas-status--warning{

View File

@@ -29,14 +29,12 @@ $ibo-datamodel-viewer--schema--self-referencing--hover--fill: $ibo-datamodel-vie
$ibo-datamodel-viewer--schema--tooltip--fill: $ibo-color-white-100 !default;
$ibo-datamodel-viewer--schema--tooltip--background-color: $ibo-color-grey-900 !default;
$ibo-datamodel-viewer--schema--tooltip--border-color: $ibo-color-grey-700 !default;
$ibo-datamodel-viewer--schema--tooltip--border: 1px solid $ibo-datamodel-viewer--schema--tooltip--border-color !default;
$ibo-datamodel-viewer--schema--tooltip--border-radius: $ibo-border-radius-300 !default;
$ibo-datamodel-viewer--schema--tooltip--icon--font-size: $ibo-font-size-100 !default;
$ibo-datamodel-viewer--schema--tooltip--span--margin: 3px !default;
$ibo-datamodel-viewer--schema--tooltip-top--border-color: $ibo-color-grey-700 !default;
$ibo-datamodel-viewer--schema--tooltip-top--border: 1px solid $ibo-datamodel-viewer--schema--tooltip-top--border-color !default;
$ibo-datamodel-viewer--schema--tooltip-top--padding: 3px !default;
$ibo-datamodel-viewer--lifecycle-image--margin-bottom: $ibo-spacing-500 !default;
@@ -118,7 +116,7 @@ $ibo-datamodel-viewer--lifecycle-image--margin-bottom: $ibo-spacing-500 !default
position: fixed;
text-align: center;
background: $ibo-datamodel-viewer--schema--tooltip--fill;
border: $ibo-datamodel-viewer--schema--tooltip--border;
border: 1px solid $ibo-datamodel-viewer--schema--tooltip--border-color;
border-radius: $ibo-datamodel-viewer--schema--tooltip--border-radius;
pointer-events: none;
fill: $ibo-datamodel-viewer--schema--tooltip--background-color;
@@ -134,7 +132,7 @@ $ibo-datamodel-viewer--lifecycle-image--margin-bottom: $ibo-spacing-500 !default
#tooltipD3_top {
@extend %ibo-font-ral-bol-100;
border-bottom: $ibo-datamodel-viewer--schema--tooltip-top--border;
border-bottom: 1px solid $ibo-datamodel-viewer--schema--tooltip-top--border-color;
padding: $ibo-datamodel-viewer--schema--tooltip-top--padding;
}

View File

@@ -22,10 +22,6 @@ $ibo-display-graph--search-box--criterion--content--padding-x: 15px !default;
$ibo-display-graph--search-box--criterion--content--checkbox--margin-right: 10px !default;
$ibo-display-graph--graph-grouping-threshold--padding-right: $ibo-spacing-0 !default;
$ibo-display-graph--impacted-placeholder-height: $ibo-size-650 !default;
.itop-simple-graph {
margin-top: $ibo-simple-graph--margin-top;
border: 1px dotted transparent;
@@ -87,7 +83,7 @@ $ibo-display-graph--impacted-placeholder-height: $ibo-size-650 !default;
}
#graph_grouping_threshold{
width: auto;
padding-right: $ibo-display-graph--graph-grouping-threshold--padding-right;
padding-right: 0;
}
.ibo-display-graph--search-box {
.sf_criterion_area{
@@ -125,5 +121,5 @@ $ibo-display-graph--impacted-placeholder-height: $ibo-size-650 !default;
}
}
#impacted_objects_lists_placeholder, #impacted_groups_placeholder{
height: $ibo-display-graph--impacted-placeholder-height;
height: 250px;
}

View File

@@ -2,7 +2,6 @@
* @copyright Copyright (C) 2010-2024 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-input-select--notification-item--mixed-value--font-size: $ibo-font-size-100 !default;
$ibo-input-select--notification-item--mixed-value--color: $ibo-color-primary-800 !default;
$ibo-input-select--notification-item--mixed-value--margin-left: 4px !default;
@@ -13,7 +12,7 @@ $ibo-input-select--notification-item--mixed-value--margin-left: 4px !default;
}
.ibo-input-select--notification-item--mixed-value{
font-size: $ibo-input-select--notification-item--mixed-value--font-size;
font-size: $ibo-font-size-100;
color: $ibo-input-select--notification-item--mixed-value--color;
margin-left: $ibo-input-select--notification-item--mixed-value--margin-left;
}

View File

@@ -4,15 +4,11 @@
*/
$ibo-notifications--view-all--container--grid-gap: $ibo-spacing-600 !default;
$ibo-notifications--view-all--container--object-summary--title--font-size: $ibo-font-size-250 !default;
$ibo-notifications--view-all--container--object-summary--toolbar--min-width: $ibo-size-500 !default;
$ibo-notifications--view-all--container--object-summary--panel--body--max-height: 400px !default;
$ibo-notifications--view-all--item--unread--highlight--background-color: $ibo-color-red-600 !default;
$ibo-notifications--view-all--item--read--highlight--background-color: $ibo-color-grey-200 !default;
$ibo-notifications--view-all--container--read-unread--action--margin-left: $ibo-spacing-0 !default;
$ibo-notifications--view-all--container--large--grid-template-columns: repeat(3, 1fr) !default;
$ibo-notifications--view-all--container--medium--grid-template-columns: repeat(2, 1fr) !default;
$ibo-notifications--view-all--container--small--grid-template-columns: repeat(1, 1fr) !default;
@@ -24,10 +20,10 @@ $ibo-notifications--view-all--empty--svg--max-width: 30% !default;
display: grid;
grid-gap: $ibo-notifications--view-all--container--grid-gap;
.ibo-object-summary .ibo-panel--title{
font-size: $ibo-notifications--view-all--container--object-summary--title--font-size;
font-size: $ibo-font-size-250;
}
.ibo-object-summary .ibo-panel--toolbar{
min-width: $ibo-notifications--view-all--container--object-summary--toolbar--min-width;
min-width: 102px;
}
.ibo-object-summary > .ibo-panel--body{
box-shadow: none;
@@ -63,7 +59,7 @@ $ibo-notifications--view-all--empty--svg--max-width: 30% !default;
.ibo-notifications--view-all--container {
.ibo-notifications--view-all--read-action, .ibo-notifications--view-all--unread-action {
margin-left: $ibo-notifications--view-all--container--read-unread--action--margin-left !important;
margin-left: 0 !important;
}
}

View File

@@ -1,9 +1,3 @@
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-oauth-wizard--illustration--svg--max-height: $ibo-size-700 !default;
.ibo-oauth-wizard .ibo-panel--body{
.ibo-oauth-wizard--form--container{
display: flex;
@@ -14,7 +8,7 @@ $ibo-oauth-wizard--illustration--svg--max-height: $ibo-size-700 !default;
}
.ibo-oauth-wizard--illustration svg{
max-height: $ibo-oauth-wizard--illustration--svg--max-height;
max-height: 400px;
}
}
#ibo-oauth-wizard--conf--result{

View File

@@ -9,8 +9,6 @@ $ibo-preferences--user-preferences--picture-placeholder--image--diameter: 54px !
$ibo-preferences--user-preferences--picture-placeholder--image--border-radius: $ibo-border-radius-full !default;
$ibo-preferences--user-preferences--picture-placeholder--image--margin: $ibo-spacing-400 !default;
$ibo-preferences--user-preferences--picture-placeholder--image--background-color: $ibo-color-grey-300 !default;
$ibo-preferences--user-preferences--picture-placeholder--image--border-color: $ibo-preferences--user-preferences--picture-placeholder--image--background-color !default;
$ibo-preferences--user-preferences--picture-placeholder--image--border: solid 3px $ibo-preferences--user-preferences--picture-placeholder--image--border-color !default;
$ibo-preferences--user-preferences--picture-placeholder--image--active--border-color: $ibo-color-blue-800;
$ibo-preferences--user-preferences--picture-placeholder--image--hover--border-color: $ibo-color-blue-600;
@@ -20,8 +18,6 @@ $ibo-keyboard-shortcut--shortcut--width: 30% !default;
$ibo-keyboard-shortcut--input--color: $ibo-color-grey-800 !default;
$ibo-keyboard-shortcut--input--background-color: transparent !default;
$ibo-keyboard-shortcut--input--border-color: $ibo-color-grey-500 !default;
$ibo-keyboard-shortcut--input--border: 1px solid $ibo-keyboard-shortcut--input--border-color !default;
$ibo-keyboard-shortcut--input--border-bottom: 2px solid $ibo-keyboard-shortcut--input--border-color !default;
$ibo-keyboard-shortcut--input--border-radius: $ibo-border-radius-300 !default;
$ibo-keyboard-shortcut--input--padding-y: $ibo-spacing-100 !default;
$ibo-keyboard-shortcut--input--padding-x: $ibo-spacing-200 !default;
@@ -30,8 +26,6 @@ $ibo-keyboard-shortcut--input--margin-bottom: 5px !default;
$ibo-keyboard-shortcut--input--is-focus--color: $ibo-color-primary-800 !default;
$ibo-keyboard-shortcut--input--is-focus--border-color: $ibo-color-primary-600 !default;
$ibo-favorite-organizations--toolbar--padding-top: $ibo-button--padding-y/2 !default;
#ibo-main-content >.ibo-panel{
margin-left: $ibo-preferences--panel--margin-x;
margin-right: $ibo-preferences--panel--margin-x;
@@ -47,7 +41,7 @@ $ibo-favorite-organizations--toolbar--padding-top: $ibo-button--padding-y/2 !def
width: $ibo-preferences--user-preferences--picture-placeholder--image--diameter;
border-radius: $ibo-preferences--user-preferences--picture-placeholder--image--border-radius;
margin: $ibo-preferences--user-preferences--picture-placeholder--image--margin;
border: $ibo-preferences--user-preferences--picture-placeholder--image--border;
border: solid 3px $ibo-preferences--user-preferences--picture-placeholder--image--background-color;
> img{
border-radius: $ibo-preferences--user-preferences--picture-placeholder--image--border-radius;
@@ -78,8 +72,8 @@ $ibo-favorite-organizations--toolbar--padding-top: $ibo-button--padding-y/2 !def
color: $ibo-keyboard-shortcut--input--color;
background-color: $ibo-keyboard-shortcut--input--background-color;
border: $ibo-keyboard-shortcut--input--border;
border-bottom: $ibo-keyboard-shortcut--input--border-bottom;
border: 1px solid $ibo-keyboard-shortcut--input--border-color;
border-bottom: 2px solid $ibo-keyboard-shortcut--input--border-color;
border-radius: $ibo-keyboard-shortcut--input--border-radius;
padding: $ibo-keyboard-shortcut--input--padding-y $ibo-keyboard-shortcut--input--padding-x;
@@ -98,5 +92,5 @@ $ibo-favorite-organizations--toolbar--padding-top: $ibo-button--padding-y/2 !def
}
#ibo-favorite-organizations .ibo-datatable--toolbar {
padding-top: $ibo-favorite-organizations--toolbar--padding-top;
padding-top: $ibo-button--padding-y/2;
}

View File

@@ -6,15 +6,14 @@
$ibo-page-banner--background-color: $ibo-color-red-600 !default;
$ibo-page-banner--text-color: $ibo-color-red-100 !default;
$ibo-page-banner--text-content: "THIS IS NOT PRODUCTION INSTANCE" !default;
$ibo-page-banner--padding: 0.2 !default;
$ibo-page-banner--font-size: 1rem !default;
#ibo-page-banner::before {
display: block;
width: 100%;
padding: $ibo-page-banner--padding;
padding: 0.2rem;
text-align: center;
font-size: $ibo-page-banner--font-size;
font-size: 1rem;
background: $ibo-page-banner--background-color;
color: $ibo-page-banner--text-color;
content: $ibo-page-banner--text-content;

View File

@@ -19,9 +19,6 @@ $ibo-hyperlink-text-decoration--on-hover: $common-hyperlink-text-decoration--on-
$ibo-hyperlink-color--on-active: $common-hyperlink-color--on-active !default;
$ibo-hyperlink-text-decoration--on-active: $common-hyperlink-text-decoration--on-active !default;
$ibo-paragraph--spacing-top: 0.25em !default;
$ibo-paragraph--spacing-bottom: 0.25em !default;
$ibo-figure--spacing-x: $common-figure--spacing-x !default; /* Mind that this matches Bulma rule for figure */
$ibo-figure--spacing-y: $common-figure--spacing-y !default;
@@ -125,8 +122,8 @@ $ibo-figure--spacing-y: $common-figure--spacing-y !default;
}
p {
margin-top: $ibo-paragraph--spacing-top;
margin-bottom: $ibo-paragraph--spacing-bottom;
margin-top: 0.25em;
margin-bottom: 0.25em;
}
figure {

View File

@@ -3,15 +3,12 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-selectable--content: ' ' !default;
$ibo-selectable--background-color: $common-selectable--background-color !default;
$ibo-selectable--hover--content: '\f058' !default;
$ibo-selectable--hover--color: $common-selectable--hover--color !default;
$ibo-selectable--hover--background-color: $common-selectable--hover--background-color !default;
$ibo-selectable--hover--background-opacity: $common-selectable--hover--background-opacity !default;
$ibo-selected--content: '\f058' !default;
$ibo-selected--color: $common-selected--color !default;
$ibo-selected--background-color: $common-selected--background-color !default;
$ibo-selected--background-opacity: $common-selected--background-opacity !default;
@@ -20,21 +17,21 @@ $ibo-selected--hover--background-color: $common-selected--hover--background-colo
$ibo-selected--hover--background-opacity: $common-selected--hover--background-opacity !default;
@mixin ibo-selectable {
content: $ibo-selectable--content;
content: ' ';
@extend %fa-solid-base;
background-color: $ibo-selectable--background-color;
cursor: pointer;
}
@mixin ibo-selectable-hover {
@extend %fa-regular-base;
content: $ibo-selectable--hover--content;
content: '\f058';
color: $ibo-selectable--hover--color;
background-color: transparentize($ibo-selectable--hover--background-color, $ibo-selectable--hover--background-opacity);
}
@mixin ibo-selected {
@extend %fa-solid-base;
content: $ibo-selected--content;
content: '\f058';
color: $ibo-selected--color;
background-color: transparentize($ibo-selected--background-color, $ibo-selected--background-opacity);
}

View File

@@ -5,16 +5,15 @@
*/
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Service\Events\EventData;
use Combodo\iTop\Service\Events\EventService;
use Combodo\iTop\Service\Events\iEventServiceSetup;
class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExtension
{
const ENUM_GUI_ALL = 'all';
const ENUM_GUI_BACKOFFICE = 'backoffice';
const ENUM_GUI_PORTALS = 'portals';
protected static $m_bIsModified = false;
public function OnDisplayProperties($oObject, WebPage $oPage, $bEditMode = false)
{
if ($this->GetAttachmentsPosition() == 'properties')
@@ -159,39 +158,45 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
return array();
}
public function RegisterEventsAndListeners() : void
public function OnIsModified($oObject)
{
EventService::RegisterListener(EVENT_DB_AFTER_WRITE, [$this, 'OnDBAfterWrite']);
EventService::RegisterListener(EVENT_DB_AFTER_DELETE, [$this, 'OnDBAfterDelete']);
return self::$m_bIsModified;
}
public function OnDBAfterWrite(EventData $oEventData)
public function OnCheckToWrite($oObject)
{
$oObject = $oEventData->Get('object');
$oCMDBChange = $oEventData->Get('cmdb_change');
$bIsNew = $oEventData->Get('is_new');
return array();
}
public function OnCheckToDelete($oObject)
{
return array();
}
public function OnDBUpdate($oObject, $oChange = null)
{
if ($this->IsTargetObject($oObject))
{
if($bIsNew){
self::UpdateAttachments($oObject, $oCMDBChange);
}
else{
// Get all current attachments
$oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
$oSet = new DBObjectSet($oSearch, array(), array('class' => get_class($oObject), 'item_id' => $oObject->GetKey()));
while ($oAttachment = $oSet->Fetch())
{
$oAttachment->SetItem($oObject, true /*updateonchange*/);
}
// Get all current attachments
$oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
$oSet = new DBObjectSet($oSearch, array(), array('class' => get_class($oObject), 'item_id' => $oObject->GetKey()));
while ($oAttachment = $oSet->Fetch())
{
$oAttachment->SetItem($oObject, true /*updateonchange*/);
}
}
}
public function OnDBAfterDelete(EventData $oEventData)
public function OnDBInsert($oObject, $oChange = null)
{
$oObject = $oEventData->Get('object');
if ($this->IsTargetObject($oObject))
{
self::UpdateAttachments($oObject, $oChange);
}
}
public function OnDBDelete($oObject, $oChange = null)
{
if ($this->IsTargetObject($oObject))
{
$oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
@@ -286,7 +291,7 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
* @see ObjectFormManager::FinalizeAttachments() for the portal version
*
* @param $oObject
* @param $oCMDBChange
* @param $oChange
*
* @return void
* @throws \ArchivedObjectException
@@ -298,8 +303,10 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
*/
protected static function UpdateAttachments($oObject, $oCMDBChange = null)
protected static function UpdateAttachments($oObject, $oChange = null)
{
self::$m_bIsModified = false;
if (utils::ReadParam('attachment_plugin', 'not-in-form') == 'not-in-form')
{
// Workaround to an issue in iTop < 2.0
@@ -356,10 +363,9 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
{
foreach ($aActions as $oChangeOp)
{
self::RecordHistory($oCMDBChange, $oObject, $oChangeOp);
self::RecordHistory($oChange, $oObject, $oChangeOp);
}
$oObject->MarkObjectAsModified();
self::$m_bIsModified = true;
}
}
}
@@ -550,11 +556,11 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
}
/////////////////////////////////////////////////////////////////////////
private static function RecordHistory($oCMDBChange, $oTargetObject, $oMyChangeOp)
private static function RecordHistory($oChange, $oTargetObject, $oMyChangeOp)
{
if (!is_null($oCMDBChange))
if (!is_null($oChange))
{
$oMyChangeOp->Set("change", $oCMDBChange->GetKey());
$oMyChangeOp->Set("change", $oChange->GetKey());
}
$oMyChangeOp->Set("objclass", get_class($oTargetObject));
$oMyChangeOp->Set("objkey", $oTargetObject->GetKey());
@@ -642,8 +648,6 @@ class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
return $bReadonly;
}
}
/**

View File

@@ -16,7 +16,6 @@ SetupWebPage::AddModule(
//
'dependencies' => array(
'itop-welcome-itil/3.1.0,',
'itop-profiles-itil/3.1.0', //SuperUser id 117
),
'mandatory' => false,
'visible' => true,
@@ -29,7 +28,7 @@ SetupWebPage::AddModule(
'src/Service/ApplicationUIExtension.php',
),
'webservice' => array(
),
'data.struct' => array(
// add your 'structure' definition XML files here,
@@ -37,11 +36,11 @@ SetupWebPage::AddModule(
'data.sample' => array(
// add your sample data XML files here,
),
// Documentation
//
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
'doc.more_information' => '', // hyperlink to more information, if any
'doc.more_information' => '', // hyperlink to more information, if any
// Default settings
//

View File

@@ -26,7 +26,6 @@ SetupWebPage::AddModule(
'category' => 'Portal',
// Setup
'dependencies' => array(
'itop-attachments/3.2.1', //CMDBChangeOpAttachmentRemoved
),
'mandatory' => true,
'visible' => false,

View File

@@ -14,7 +14,6 @@ SetupWebPage::AddModule(
//
'dependencies' => array(
'itop-structure/2.7.1',
'itop-portal/3.0.0' // module_design_itop_design->module_designs->itop-portal
),
'mandatory' => false,
'visible' => true,
@@ -30,7 +29,7 @@ SetupWebPage::AddModule(
),
'data.sample' => array(
),
// Documentation
//
'doc.manual_setup' => '',

View File

@@ -327,8 +327,7 @@ $(function()
oElem.popover_menu({
'toggler': '[data-role="ibo-navigation-menu--notifications-show-all-multiple"]',
'position': {
'horizontal': "(oTargetPos.left+parseInt(oTargetElem.css('marginLeft'), 10)+(oTargetElem.outerWidth() / 1.5)-(oElem.outerWidth() / 2))+'px'",
'vertical': 'above'
'horizontal': "(oTargetPos.left+parseInt(oTargetElem.css('marginLeft'), 10)+(oTargetElem.outerWidth() / 2)-(oElem.outerWidth() / 2))+'px'",
},
});

Some files were not shown because too many files have changed in this diff Show More