Compare commits

..

57 Commits

Author SHA1 Message Date
Eric Espie
9f668079cf N°7423 - Forbid UserTokens to be able to connect to the backoffice (or any portal) - add context to users 2024-04-30 14:54:57 +02:00
Eric Espie
23e0988838 N°7423 - Forbid UserTokens to be able to connect to the backoffice (or any portal) - add context to users 2024-04-30 11:14:32 +02:00
jf-cbd
24cf28f09a Merge remote-tracking branch 'refs/remotes/origin/support/3.1' into support/3.2 2024-04-30 08:15:15 +02:00
jf-cbd
9ff54cead8 Merge remote-tracking branch 'refs/remotes/origin/support/3.0' into support/3.1 2024-04-30 08:14:11 +02:00
jf-cbd
dbcbb187b2 N°7445 - Invalid Unicode escape sequence on dashlet Header with statistics 2024-04-30 08:13:37 +02:00
jf-cbd
71b4d672d4 Merge remote-tracking branch 'refs/remotes/origin/support/3.0' into support/3.1
# Conflicts:
#	pages/ajax.render.php
2024-04-30 08:04:45 +02:00
jf-cbd
93bba66323 N°7445 - Invalid Unicode escape sequence on dashlet Header with statistics 2024-04-30 08:03:14 +02:00
Molkobain
0a95aa385a Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	tests/php-unit-tests/unitary-tests/application/applicationextension/Delta/application-extension-usages-in-snippets.xml
2024-04-29 14:03:16 +02:00
Molkobain
cab6394cba Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-04-29 13:58:13 +02:00
Molkobain
32140b360f Cherry pick fixes from 59a955f4 2024-04-29 11:45:09 +02:00
Stephen Abello
b1290072b5 N°6167 - Fix high contrast theme for new welcome popup 2024-04-29 11:09:41 +02:00
Stephen Abello
c82f169248 N°6167 - Fix darkmoon theme for new welcome popup 2024-04-29 10:51:59 +02:00
Benjamin Dalsass
06a8481511 N°7279 - AttributeClass defined in XML datamodel compilation issue 2024-04-25 11:39:54 +02:00
Benjamin Dalsass
a481992c8e N°7279 - AttributeClass defined in XML datamodel compilation issue 2024-04-25 09:16:30 +02:00
jf-cbd
0434579ef5 Merge remote-tracking branch 'refs/remotes/origin/support/3.1' into support/3.2 2024-04-24 17:11:19 +02:00
jf-cbd
59a955f491 🐛 N°7313 - Bad display of single quotes in charts (#627)
* 🐛 N°7313 - Bad display of single quotes in charts
* Fix and improve ItopCustomDatamodelTestCase
2024-04-24 17:03:47 +02:00
Molkobain
d1ff87c0e6 N°2039 - Add default search criteria for EventiTopNotification 2024-04-24 15:38:31 +02:00
vdumas
47248bf0b7 N°7474 - Setup crash when a profile is removed 2024-04-24 15:35:45 +02:00
Molkobain
0f49154b5d N°2039 - Fix unit test about dictionaries 2024-04-24 15:33:41 +02:00
Molkobain
0507f95971 N°2039 - Add line about newsroom action in the notifications configuration hint 2024-04-24 14:21:47 +02:00
jf-cbd
82220c801b Merge remote-tracking branch 'refs/remotes/origin/support/3.1' into support/3.2 2024-04-24 12:01:40 +02:00
jf-cbd
2ffcfd2f57 Merge remote-tracking branch 'refs/remotes/origin/support/3.0' into support/3.1 2024-04-24 12:00:47 +02:00
jf-cbd
e657052d17 Merge remote-tracking branch 'refs/remotes/origin/support/2.7' into support/3.0 2024-04-24 11:58:13 +02:00
jf-cbd
d85767a838 Update test to run only on commmunity builds 2024-04-24 11:14:40 +02:00
Eric Espie
e409ee8337 N°6438 - Reloading all displayed tickets when display the ticket list 2024-04-24 10:34:44 +02:00
Molkobain
973a716481 N°2039 - Add "list" zlist for EventiTopNotification class 2024-04-23 19:30:27 +02:00
Molkobain
cfbc75b564 N°2039 - Add descending order on date for EventiTopNotification 2024-04-23 19:23:26 +02:00
Molkobain
78215439ee N°2039 - Add complementary name on child classes to avoid empty summary cards in iTop 3.1+ 2024-04-23 19:14:44 +02:00
jf-cbd
028c7f0604 Merge remote-tracking branch 'refs/remotes/origin/support/3.1' into support/3.2 2024-04-23 14:45:23 +02:00
jf-cbd
e56d5ed3aa Merge remote-tracking branch 'refs/remotes/origin/support/3.0' into support/3.1
# Conflicts:
#	datamodels/2.x/itop-hub-connector/launch.php
#	setup/wizardsteps.class.inc.php
2024-04-23 14:13:40 +02:00
jf-cbd
e5a8bd61b0 Merge remote-tracking branch 'refs/remotes/origin/support/2.7' into support/3.0
# Conflicts:
#	datamodels/2.x/itop-hub-connector/launch.php
2024-04-23 14:03:15 +02:00
jf-cbd
eeec57536b Security hardening 2024-04-23 11:55:39 +02:00
jf-cbd
e3173810fd Merge branch 'refs/heads/support/3.1' into support/3.2
# Conflicts:
#	pages/ajax.render.php
2024-04-19 15:30:48 +02:00
jf-cbd
3b7f26d794 Revert "Merge branch 'refs/heads/support/3.1' into support/3.2"
This reverts commit 6ff60080a1, reversing
changes made to 9d195d6fa0.
2024-04-19 15:26:15 +02:00
jf-cbd
7fba61ff35 N°7445 - Invalid Unicode escape sequence on dashlet Header with statistics 2024-04-19 15:21:48 +02:00
jf-cbd
1bf156bdda Revert "Merge branch 'refs/heads/support/3.0' into support/3.1"
This reverts commit 1164e757de, reversing
changes made to 1235452a1b.
2024-04-19 15:16:57 +02:00
jf-cbd
6ff60080a1 Merge branch 'refs/heads/support/3.1' into support/3.2
# Conflicts:
#	pages/ajax.render.php
2024-04-19 11:27:32 +02:00
jf-cbd
1164e757de Merge branch 'refs/heads/support/3.0' into support/3.1
# Conflicts:
#	pages/ajax.render.php
2024-04-19 11:24:56 +02:00
jf-cbd
514e0b80a5 N°7445 - Invalid Unicode escape sequence on dashlet Header with statistics 2024-04-19 11:17:09 +02:00
Molkobain
9d195d6fa0 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-04-19 09:25:42 +02:00
Molkobain
1235452a1b Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-04-19 09:24:21 +02:00
Molkobain
35f4ab4941 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-04-19 09:22:32 +02:00
Molkobain
16ff6341d0 N°7455 - Fix regression from 4c784886, wrong class tested 2024-04-19 09:14:53 +02:00
Molkobain
e669f0e6b9 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-04-18 18:50:29 +02:00
Molkobain
12ad3c2732 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-04-18 18:49:08 +02:00
Molkobain
ac826cb9f1 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-04-18 18:48:24 +02:00
Molkobain
9dab8679d6 N°7448 - Update dictionary entry 2024-04-18 18:44:20 +02:00
Molkobain
d9c0c3cdbe Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-04-18 18:18:44 +02:00
Molkobain
4f3b25aa46 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2024-04-18 18:17:41 +02:00
Molkobain
f737bcb9a0 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2024-04-18 18:16:24 +02:00
Molkobain
4c78488644 N°7455 - Ensure form renderer class extends FormRenderer 2024-04-18 18:15:02 +02:00
Denis
3a8ad59e6c N°6167 - Introduce API for the content of the Welcome Popup (#505)
* API for the content of the Welcome Popup

* Apply suggestions from code review

* N°7410 - Refactor code to match conventions

* N°7410 - Refactor to new design

* N°7410 - Review adjustments

* N°7410 - Review adjustments

* N°7410 - Update translations

* N°7410 - Update setup complied file

* Update sources/Application/WelcomePopup/Provider/DefaultProvider.php

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-04-18 16:57:07 +02:00
Stephen Abello
62f5f2c942 N°5298 -When opening CKEditor4 data with CKEditor5, if no change has been made return initial data instead of transformed data 2024-04-18 14:51:44 +02:00
Benjamin Dalsass
c56aeb08f5 N°2443 - Boolean don't accept yes/no value (#645)
AttributeBoolean form field edition is now handled by list or radio
2024-04-17 16:04:07 +02:00
Anne-Cath
ddc004a147 N°7461 - Portal: import user photo don't like some pictures with PHP>=8.1 2024-04-17 15:44:52 +02:00
Anne-Catherine
e4a3a7d0ca N°6962 - Impact analysis does not fully take into account the user rights with sharing base (#572) 2024-04-17 14:38:33 +02:00
vdumas
6ae813221e N°2572 - Improve error message "Nowhere to go??" with root cause 2024-04-15 13:52:46 +02:00
106 changed files with 2629 additions and 772 deletions

View File

@@ -2297,3 +2297,75 @@ interface iBackupExtraFilesExtension
*/
public function GetExtraFilesRelPaths(): array;
}
/**
* 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, ...)
*
* @api
* @return string Relative path (from app. root) of the icon representing the provider
*/
public function GetIconRelPath(): string;
/**
* @api
* @return \Combodo\iTop\Application\WelcomePopup\Message[]
*/
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;
}
/**
* 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

@@ -2326,6 +2326,7 @@ JS
// b) or override some of the configuration settings, using the second parameter of ckeditor()
$aConfig = CKEditorHelper::GetCkeditorPref();
$aConfig['placeholder'] = Dict::S('UI:CaseLogTypeYourTextHere');
$aConfig['detectChanges'] = ['initialValue' => $sOriginalValue];
// - Final config
$sConfigJS = json_encode($aConfig);
@@ -2609,6 +2610,13 @@ JS
$iFieldSize = $oAttDef->GetMaxSize();
if ($aAllowedValues !== null)
{
// convert AttributeBoolean value due to issue with radio style when value is false
// @see N°2443 - Boolean don't accept yes/no value
if($oAttDef instanceof AttributeBoolean){
$value = $value === false ? 0 : 1;
}
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
$sDisplayStyle = $oAttDef->GetDisplayStyle();
switch ($sDisplayStyle)

View File

@@ -40,6 +40,36 @@
<presentation/>
<methods/>
</class>
<class id="WelcomePopupAcknowledge" _delta="define">
<parent>DBObject</parent>
<properties>
<comment>/** Acknowledge welcome popup messages */</comment>
<abstract>false</abstract>
<category></category>
<key_type>autoincrement</key_type>
<db_table>priv_welcome_popup_acknowledge</db_table>
</properties>
<fields>
<field id="message_uuid" xsi:type="AttributeString">
<sql>message_uuid</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="user_id" xsi:type="AttributeExternalKey">
<sql>user_id</sql>
<target_class>User</target_class>
<is_null_allowed>false</is_null_allowed>
<on_target_delete>DEL_SILENT</on_target_delete>
</field>
<field id="acknowledge_date" xsi:type="AttributeDateTime">
<sql>acknowledge_date</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
</fields>
<presentation/>
<methods/>
</class>
</classes>
<portals>
<portal id="backoffice" _delta="define">

View File

@@ -566,7 +566,7 @@ EOF;
{
if (is_object($aObjects[$sAlias]))
{
$sHilightClass = $aObjects[$sAlias]->GetHilightClass();
$sHilightClass = MetaModel::GetHilightClass($sClassName, $aObjects[$sAlias]);
if ($sHilightClass != '')
{
$aRow['@class'] = $sHilightClass;

View File

@@ -1695,7 +1695,7 @@ JS
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
$iTotalCount += $aRow['_itop_count_'];
$aValues[] = array(
'label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'),
'label' => $sValue,
'label_html' => $sHtmlValue,
'value' => (float)$aRow[$sFctVar],
);

View File

@@ -971,7 +971,7 @@ class LoginWebPage extends NiceWebPage
}
else if($ret === false)
{
throw new Exception('Nowhere to go??');
throw new Exception('Nowhere to go: Your combination of user Profiles denies you access to any '.ITOP_APPLICATION_SHORT.' portal. Please contact your administrator');
}
else
{
@@ -1044,6 +1044,33 @@ class LoginWebPage extends NiceWebPage
exit;
}
}
// Check allowed context for the selected user
// If the user has no context -> allow to connect
// If the entry point has no context -> allow only users with no context specified
// If the entry point has one or more contexts -> allow only users with one of the entry point context specified
$oUser = UserRights::GetUserObject();
$aContexts = $oUser->Get('allowed_contexts')->GetValues();
if (count($aContexts) > 0) {
if (ContextTag::Check($aContexts) === false) {
IssueLog::Error(sprintf(
'User "%s" cannot connect: the current context (%s) does not match current allowed contexts: %s',
UserRights::GetUser(),
implode(',', \ContextTag::GetStack()),
implode(',', $aContexts)));
if ($iOnExit == self::EXIT_RETURN) {
return self::EXIT_CODE_NOTAUTHORIZED;
} else {
require_once(APPROOT.'/setup/setuppage.class.inc.php');
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
$oP->add('<h1>'.Dict::S('UI:Login:Error:AccessRestricted')."</h1>\n");
$oP->p("<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/logoff.php\">".Dict::S('UI:LogOffMenu').'</a>');
$oP->output();
exit;
}
}
}
$iRet = call_user_func(array(self::$sHandlerClass, 'ChangeLocation'), $sRequestedPortalId, $iOnExit);
}
if ($iOnExit == self::EXIT_RETURN)

View File

@@ -1,29 +0,0 @@
<div style="width:100%;background: #fff url(../images/welcome.jpg) top left no-repeat;">
<style>
.welcome_popup_cell {
vertical-align:top;
width:50%;
border:0px solid #000;
-moz-border-radius:10px;
padding:5px;
text-align:left;
}
tr td.welcome_popup_cell, tr td.welcome_popup_cell ul {
font-size:10pt;
}
</style>
<p></p>
<p></p>
<p style="text-align:left; font-size:32px;padding-left:400px;padding-top:40px;margin-bottom:30px;margin-top:0;color:#FFFFFF;"><itopstring>UI:WelcomeMenu:Title</itopstring></p>
<p></p>
<table border="0" style="padding:10px;border-spacing: 10px;width:100%">
<tr>
<td class="welcome_popup_cell">
<itopstring>UI:WelcomeMenu:LeftBlock</itopstring>
</td>
<td class="welcome_popup_cell">
<itopstring>UI:WelcomeMenu:RightBlock</itopstring>
</td>
</tr>
</table>
</div>

View File

@@ -87,7 +87,7 @@ class UIHTMLEditorWidget
if ($sHeightSpec != '') {
$aConfig['height'] = $sHeightSpec;
}
// TODO 3.2.0 Add the configuration for the editor
$aConfig['detectChanges'] = ['initialValue' => $sValue];
$sConfigJS = json_encode($aConfig);
WebResourcesHelper::EnableCKEditorToWebPage($oPage);

View File

@@ -2226,8 +2226,8 @@ SQL;
$fScale = min($iMaxImageWidth / $iWidth, $iMaxImageHeight / $iHeight);
$iNewWidth = $iWidth * $fScale;
$iNewHeight = $iHeight * $fScale;
$iNewWidth = floor($iWidth * $fScale);
$iNewHeight = floor($iHeight * $fScale);
$new = imagecreatetruecolor($iNewWidth, $iNewHeight);

View File

@@ -52,9 +52,9 @@ abstract class Action extends cmdbAbstractObject
"category" => "grant_by_profile,core/cmdb",
"key_type" => "autoincrement",
"name_attcode" => "name",
"complementary_name_attcode" => array('finalclass', 'description'),
"complementary_name_attcode" => ['finalclass', 'description'],
"state_attcode" => "status",
"reconc_keys" => array('name'),
"reconc_keys" => ['name'],
"db_table" => "priv_action",
"db_key_field" => "id",
"db_finalclass_field" => "realclass",
@@ -287,8 +287,9 @@ abstract class ActionNotification extends Action
"category" => "grant_by_profile,core/cmdb",
"key_type" => "autoincrement",
"name_attcode" => "name",
"complementary_name_attcode" => ['finalclass', 'description'],
"state_attcode" => "",
"reconc_keys" => array('name'),
"reconc_keys" => ['name'],
"db_table" => "priv_action_notification",
"db_key_field" => "id",
"db_finalclass_field" => "",

View File

@@ -3572,6 +3572,19 @@ class AttributeBoolean extends AttributeInteger
{
return CMDBChangeOpSetAttributeScalar::class;
}
public function GetAllowedValues($aArgs = array(), $sContains = '') : array
{
return [
0 => $this->GetValueLabel(false),
1 => $this->GetValueLabel(true)
];
}
public function GetDisplayStyle()
{
return $this->GetOptional('display_style', 'select');
}
}
/**
@@ -11071,7 +11084,7 @@ class AttributeEnumSet extends AttributeSet
return max(255, $iMaxSize);
}
private function GetRawPossibleValues($aArgs = array(), $sContains = '')
protected function GetRawPossibleValues($aArgs = array(), $sContains = '')
{
/** @var ValueSetEnumPadded $oValSetDef */
$oValSetDef = $this->Get('possible_values');
@@ -11304,6 +11317,65 @@ class AttributeEnumSet extends AttributeSet
}
}
/**
* @since 3.2.0 N°7423
*/
class AttributeContextTagSet extends AttributeEnumSet
{
public static function ListExpectedParams()
{
// allowed_values and possible_values are replaced by context_type and excluded_contexts
return array_diff(
array_merge(parent::ListExpectedParams(), ['is_null_allowed', 'max_items', 'context_type', 'denied_contexts']),
['allowed_values', 'possible_values']);
}
protected function GetRawPossibleValues($aArgs = array(), $sContains = ''): array
{
$sType = $this->Get('context_type');
$aExcludedContexts = $this->Get('denied_contexts');
$aContexts = [];
switch ($sType) {
case 'authentication':
$aContexts = ContextTag::GetTagsForConnection();
break;
case 'all':
$aContexts = ContextTag::GetTags();
break;
}
$aContexts = array_diff($aContexts, $aExcludedContexts);
$oValSetDef = new ValueSetEnumPadded($aContexts);
return $oValSetDef->GetValues([], $sContains);
}
public function GetPossibleValues($aArgs = array(), $sContains = '')
{
return $this->GetRawPossibleValues($aArgs, $sContains);
}
public function GetValueLabel($sValue)
{
if ($sValue instanceof ormSet) {
$sValue = implode(', ', $sValue->GetValues());
}
$aValues = $this->GetRawPossibleValues();
$sLabel = Dict::S('Enum:Undefined');
if (is_string($sValue) && isset($aValues[$sValue])) {
$sLabel = $aValues[$sValue];
}
return $sLabel;
}
public function GetValueDescription($sValue)
{
return '';
}
}
class AttributeClassAttCodeSet extends AttributeSet
{
@@ -11547,6 +11619,11 @@ class AttributeClassAttCodeSet extends AttributeSet
}
return '<span class="'.implode(' ', $this->aCSSClasses).'">'.$value.'</span>';
}
public function IsNull($proposedValue)
{
return (empty($proposedValue));
}
}
class AttributeQueryAttCodeSet extends AttributeSet

View File

@@ -560,6 +560,14 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => true,
],
'list.highlight_abstract_class' => [
'type' => 'bool',
'description' => 'Compute highlight row colors for lists of abstract objects. Mind that setting this to true has a negative impact on performances.',
'default' => false,
'value' => false,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'tag_set_item_separator' => [
'type' => 'string',
'description' => 'Tag set from string: tag label separator',
@@ -1209,6 +1217,14 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'relations.complete_analysis' => [
'type' => 'bool',
'description' => 'Continue the impact/depends analysis even if a step is not visible to the user',
'default' => false,
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'sessions_tracking.enabled' => [
'type' => 'bool',
'description' => 'Whether or not the whole mechanism to track active sessions is enabled. See PHP session.gc_maxlifetime setting to configure session expiration.',

View File

@@ -58,12 +58,15 @@ class ContextTag
public const TAG_SETUP = 'Setup';
public const TAG_SYNCHRO = 'Synchro';
public const TAG_REST = 'REST/JSON';
/**
* @since 3.2.0 N°7423
*/
public const TAG_GUI = 'GUI';
/**
* @since 3.1.0 N°6047
*/
public const TAG_IMPORT = 'Import';
/**
/**
* @since 3.1.0 N°6047
*/
public const TAG_EXPORT = 'Export';
@@ -101,11 +104,18 @@ class ContextTag
/**
* Check if a given tag is present in the stack
* @param string $sTag
* or check if one of the tags in the array is present
*
* @param array|string $sTag
*
* @return bool
*/
public static function Check($sTag)
public static function Check(array|string $sTag): bool
{
if (is_array($sTag)) {
return (count(array_intersect($sTag, static::$aStack)) > 0);
}
return in_array($sTag, static::$aStack);
}
@@ -118,6 +128,25 @@ class ContextTag
return static::$aStack;
}
public static function GetTagsForConnection(): array
{
$aRawTags = array(
ContextTag::TAG_GUI,
ContextTag::TAG_REST,
ContextTag::TAG_SYNCHRO,
ContextTag::TAG_IMPORT,
ContextTag::TAG_EXPORT);
$aTags = array();
foreach ($aRawTags as $sRawTag)
{
$aTags[$sRawTag] = Dict::S("Core:Context={$sRawTag}");
}
return $aTags;
}
/**
* Get all the predefined context tags
* @return array
@@ -125,11 +154,14 @@ class ContextTag
public static function GetTags()
{
$aRawTags = array(
ContextTag::TAG_GUI,
ContextTag::TAG_REST,
ContextTag::TAG_SYNCHRO,
ContextTag::TAG_SETUP,
ContextTag::TAG_CONSOLE,
ContextTag::TAG_CRON,
ContextTag::TAG_IMPORT,
ContextTag::TAG_EXPORT,
ContextTag::TAG_PORTAL);
$aTags = array();

View File

@@ -108,6 +108,10 @@
<attributes>
<attribute id="name"/>
</attributes>
<complementary_attributes>
<attribute id="finalclass"/>
<attribute id="description"/>
</complementary_attributes>
</naming>
<style>
<icon>../../images/icons/icons8-notification.svg</icon>
@@ -333,6 +337,11 @@
<attribute id="title"/>
</attributes>
</naming>
<order>
<columns>
<column id="date" ascending="false" />
</columns>
</order>
</properties>
<fields>
<field id="title" xsi:type="AttributeString">
@@ -435,6 +444,41 @@
</item>
</items>
</summary>
<list>
<items>
<item id="date">
<rank>10</rank>
</item>
<item id="contact_id">
<rank>20</rank>
</item>
<item id="message">
<rank>30</rank>
</item>
<item id="read">
<rank>40</rank>
</item>
<item id="read_date">
<rank>50</rank>
</item>
</items>
</list>
<default_search>
<items>
<item id="action_id">
<rank>10</rank>
</item>
<item id="trigger_id">
<rank>20</rank>
</item>
<item id="date">
<rank>30</rank>
</item>
<item id="contact_id">
<rank>40</rank>
</item>
</items>
</default_search>
</presentation>
<methods/>
</class>
@@ -764,6 +808,29 @@
</fields>
</class>
</classes>
<attribute_definitions _delta="define">
<attribute_definition id="AttributeContextTagSet">
<properties>
<property id="sql"/>
<property id="is_null_allowed"/>
<property id="max_items"/>
<property id="default_value"/>
<property id="context_type">
<php_param>context_type</php_param>
<mandatory>true</mandatory>
<type>string</type>
</property>
<property id="denied_contexts">
<php_param>denied_contexts</php_param>
<mandatory>false</mandatory>
<type>collection</type>
<collection_element_name>denied_context</collection_element_name>
<collection_type>id</collection_type>
<default/>
</property>
</properties>
</attribute_definition>
</attribute_definitions>
<attribute_properties_definition _delta="define">
<properties>
<property id="sql">
@@ -786,11 +853,6 @@
<mandatory>true</mandatory>
<type>string</type>
</property>
<property id="sql">
<php_param>sql</php_param>
<mandatory>true</mandatory>
<type>string</type>
</property>
<property id="class_attcode">
<php_param>class_attcode</php_param>
<mandatory>true</mandatory>

View File

@@ -129,6 +129,7 @@ class HTMLBulkExport extends TabularBulkExport
$this->OptimizeColumnLoad($oSet);
$sFirstAlias = $this->oSearch->GetClassAlias();
$sClass = $this->oSearch->GetClass();
$iCount = 0;
$sData = '';
@@ -141,7 +142,7 @@ class HTMLBulkExport extends TabularBulkExport
$sHilightClass = '';
if ($oMainObj)
{
$sHilightClass = $aRow[$sFirstAlias]->GetHilightClass();
$sHilightClass = MetaModel::GetHilightClass($sClass, $aRow[$sFirstAlias]);
}
if ($sHilightClass != '')
{

View File

@@ -3697,6 +3697,27 @@ abstract class MetaModel
self::$m_aHighlightScales[$sTargetClass] = $aHighlightScale;
}
/**
* Get the HTML class to apply to the object in the datatables
*
* @param string $sClass requested for the list (can be abstract)
* @param \DBObject $oObject the object to display
*
* @return string the class to apply to the object
* @throws \ArchivedObjectException
* @throws \CoreException
*
* @since 3.2.0
*/
final public static function GetHilightClass(string $sClass, DBObject $oObject): string
{
if (self::IsAbstract($sClass) && self::GetConfig()->Get('list.highlight_abstract_class') === false) {
return '';
}
return $oObject->GetHilightClass();
}
/**
* @param string $sTargetClass
*

View File

@@ -20,7 +20,7 @@
/**
* Data structures (i.e. PHP classes) to build and use relation graphs
*
* @copyright Copyright (C) 2015-2023 Combodo SARL
* @copyright Copyright (C) 2015-2024 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*
*/
@@ -367,6 +367,9 @@ class RelationGraph extends SimpleGraph
$oNode->ReachDown('is_reached', true);
}
}
if ( MetaModel::GetConfig()->Get('relations.complete_analysis')) {
$this->ApplyUserRightsOnGraph();
}
}
/**
@@ -401,6 +404,9 @@ class RelationGraph extends SimpleGraph
$oNode->ReachDown('is_reached', true);
}
}
if ( MetaModel::GetConfig()->Get('relations.complete_analysis')) {
$this->ApplyUserRightsOnGraph();
}
}
@@ -460,6 +466,10 @@ class RelationGraph extends SimpleGraph
try
{
$oFlt = static::MakeSearch($sQuery);
if ( MetaModel::GetConfig()->Get('relations.complete_analysis')) {
//no filter to find all impacts
$oFlt->AllowAllData(true);
}
$oObjSet = new DBObjectSet($oFlt, array(), $oObject->ToArgsForQuery());
$oRelatedObj = $oObjSet->Fetch();
}
@@ -474,27 +484,24 @@ class RelationGraph extends SimpleGraph
{
set_time_limit(intval($iLoopTimeLimit));
$sObjectRef = RelationObjectNode::MakeId($oRelatedObj);
$oRelatedNode = $this->GetNode($sObjectRef);
if (is_null($oRelatedNode))
{
$oRelatedNode = new RelationObjectNode($this, $oRelatedObj);
}
$oSourceNode = $bDown ? $oObjectNode : $oRelatedNode;
$oSinkNode = $bDown ? $oRelatedNode : $oObjectNode;
$sObjectRef = RelationObjectNode::MakeId($oRelatedObj);
$oRelatedNode = $this->GetNode($sObjectRef);
if (is_null($oRelatedNode)) {
$oRelatedNode = new RelationObjectNode($this, $oRelatedObj);
}
$oSourceNode = $bDown ? $oObjectNode : $oRelatedNode;
$oSinkNode = $bDown ? $oRelatedNode : $oObjectNode;
if ($bEnableRedundancy)
{
$oRedundancyNode = $this->ComputeRedundancy($sRelCode, $aQueryInfo, $oSourceNode, $oSinkNode);
}
else
{
$oRedundancyNode = null;
}
if (!$oRedundancyNode)
{
// Direct link (otherwise handled by ComputeRedundancy)
new RelationEdge($this, $oSourceNode, $oSinkNode);
}
$oRedundancyNode = $this->ComputeRedundancy($sRelCode, $aQueryInfo, $oSourceNode, $oSinkNode);
} else {
$oRedundancyNode = null;
}
if (!$oRedundancyNode) {
// Direct link (otherwise handled by ComputeRedundancy)
new RelationEdge($this, $oSourceNode, $oSinkNode);
}
// Recurse
$this->AddRelatedObjects($sRelCode, $bDown, $oRelatedNode, $iMaxDepth - 1, $bEnableRedundancy);
}
@@ -538,6 +545,10 @@ class RelationGraph extends SimpleGraph
try
{
$oFlt = static::MakeSearch($sQuery);
if ( MetaModel::GetConfig()->Get('relations.complete_analysis')) {
//no filter to find all impacts
$oFlt->AllowAllData(true);
}
$oObjSet = new DBObjectSet($oFlt, array(), $oObject->ToArgsForQuery());
$iCount = $oObjSet->Count();
}
@@ -553,13 +564,12 @@ class RelationGraph extends SimpleGraph
while ($oUpperObj = $oObjSet->Fetch())
{
$sObjectRef = RelationObjectNode::MakeId($oUpperObj);
$oUpperNode = $this->GetNode($sObjectRef);
if (is_null($oUpperNode))
{
$oUpperNode = new RelationObjectNode($this, $oUpperObj);
}
new RelationEdge($this, $oUpperNode, $oRedundancyNode);
$sObjectRef = RelationObjectNode::MakeId($oUpperObj);
$oUpperNode = $this->GetNode($sObjectRef);
if (is_null($oUpperNode)) {
$oUpperNode = new RelationObjectNode($this, $oUpperObj);
}
new RelationEdge($this, $oUpperNode, $oRedundancyNode);
}
}
}
@@ -694,4 +704,47 @@ class RelationGraph extends SimpleGraph
$oSearch->SetArchiveMode(false);
return $oSearch;
}
/**
* @return void
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \MySQLException
* @throws \OQLException
* @throws \SimpleGraphException
*/
private function ApplyUserRightsOnGraph()
{
//The chart is complete. Now we need to control which objects are allowed to the current user.
if (!UserRights::IsAdministrator()) {
//First we get all the objects presents in chart in $aArrayTest
$oIterator = new RelationTypeIterator($this, 'Node');
$aArrayTest = [];
foreach ($oIterator as $oNode) {
$oObj = $oNode->GetProperty('object');
if ($oObj) {
$aArrayTest[get_class($oObj)][$oObj->GetKey()] = $oObj->GetKey();
}
}
//Then for each class, we made a request to control access rights
// visible objects are removed from $aArrayTest
foreach ($aArrayTest as $sClass => $aKeys) {
$sOQL = "SELECT ".$sClass.' WHERE id IN ('.implode(',', $aKeys).')';
$oSearch = DBObjectSearch::FromOQL($sOQL);
$aListId = $oSearch->SelectAttributeToArray('id');
foreach($aListId as$aItem ) {
unset($aArrayTest[$sClass][$aItem['id']]);
}
}
//then removes from the graph all objects still present in $aArrayTest
foreach ($oIterator as $oNode) {
$oObj = $oNode->GetProperty('object');
if ($oObj && isset($aArrayTest[get_class($oObj)]) && in_array($oObj->GetKey(), $aArrayTest[get_class($oObj)])) {
$this->FilterNode($oNode);
}
}
}
}
}

View File

@@ -36,9 +36,9 @@ abstract class Trigger extends cmdbAbstractObject
"category" => "grant_by_profile,core/cmdb",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => array('finalclass', 'complement'),
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger",
"db_key_field" => "id",
"db_finalclass_field" => "realclass",
@@ -173,8 +173,9 @@ abstract class TriggerOnObject extends Trigger
"category" => "grant_by_profile,core/cmdb",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onobject",
"db_key_field" => "id",
"db_finalclass_field" => "",
@@ -375,8 +376,9 @@ class TriggerOnPortalUpdate extends TriggerOnObject
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onportalupdate",
"db_key_field" => "id",
"db_finalclass_field" => "",
@@ -407,8 +409,9 @@ abstract class TriggerOnStateChange extends TriggerOnObject
"category" => "grant_by_profile,core/cmdb",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onstatechange",
"db_key_field" => "id",
"db_finalclass_field" => "",
@@ -441,8 +444,9 @@ class TriggerOnStateEnter extends TriggerOnStateChange
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onstateenter",
"db_key_field" => "id",
"db_finalclass_field" => "",
@@ -474,8 +478,9 @@ class TriggerOnStateLeave extends TriggerOnStateChange
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onstateleave",
"db_key_field" => "id",
"db_finalclass_field" => "",
@@ -507,8 +512,9 @@ class TriggerOnObjectCreate extends TriggerOnObject
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onobjcreate",
"db_key_field" => "id",
"db_finalclass_field" => "",
@@ -540,8 +546,9 @@ class TriggerOnObjectDelete extends TriggerOnObject
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onobjdelete",
"db_key_field" => "id",
"db_finalclass_field" => "",
@@ -574,8 +581,9 @@ class TriggerOnObjectUpdate extends TriggerOnObject
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onobjupdate",
"db_key_field" => "id",
"db_finalclass_field" => "",
@@ -669,8 +677,9 @@ class TriggerOnObjectMention extends TriggerOnObject
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onobjmention",
"db_key_field" => "id",
"db_finalclass_field" => "",
@@ -749,8 +758,9 @@ class TriggerOnAttributeBlobDownload extends TriggerOnObject
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onattblobdownload",
"db_key_field" => "id",
"db_finalclass_field" => "",
@@ -827,8 +837,9 @@ class TriggerOnThresholdReached extends TriggerOnObject
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_threshold",
"db_key_field" => "id",
"db_finalclass_field" => "",

View File

@@ -252,6 +252,8 @@ abstract class User extends cmdbAbstractObject
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("profile_list",array("linked_class" => "URP_UserProfile", "ext_key_to_me" => "userid", "ext_key_to_remote" => "profileid", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array(), "display_style" => 'property', "with_php_constraint" => true, "with_php_computation" => true)));
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("allowed_org_list", array("linked_class" => "URP_UserOrg", "ext_key_to_me" => "userid", "ext_key_to_remote" => "allowed_org_id", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array(), 'with_php_constraint' => true)));
MetaModel::Init_AddAttribute(new AttributeCaseLog("log", array("sql" => 'log', "is_null_allowed" => true, "default_value" => '', "allowed_values" => null, "depends_on" => array(), "always_load_in_tables" => false)));
$aTags = ContextTag::GetTagsForConnection();
MetaModel::Init_AddAttribute(new AttributeEnumSet('allowed_contexts', array('allowed_values' => null, 'possible_values' => new ValueSetEnumPadded($aTags, true), 'sql' => 'allowed_contexts', 'depends_on' => array(), 'is_null_allowed' => true, 'max_items' => 12)));
// Display lists
MetaModel::Init_SetZListItems('details', array('contactid', 'org_id', 'email', 'login', 'language', 'status', 'profile_list', 'allowed_org_list', 'log')); // Unused as it's an abstract class !
@@ -385,6 +387,12 @@ abstract class User extends cmdbAbstractObject
/** @var \DBObjectSet $oSet */
$oSet = $this->Get('profile_list');
if ($oSet->Count() == 0) {
if (ContextTag::Check(ContextTag::TAG_SETUP)) {
// During setup, if a profile is no more part of iTop, it will be deleted
// But if it is the only profile assigned to a user, we don't want this to stop the setup
SetupLog::Warning("The user with id: ".$this->GetKey()." is no more usable as its last profile was removed during setup");
return;
}
$this->m_aCheckIssues[] = Dict::S('Class:User/Error:AtLeastOneProfileIsNeeded');
}

View File

@@ -580,6 +580,7 @@ class ValueSetEnumPadded extends ValueSetEnum
$aPaddedValues[$sKey] = $sVal;
}
$this->m_values = $aPaddedValues;
$this->m_bIsLoaded = true;
}
}

View File

@@ -6,4 +6,5 @@
@import "bulk/all";
@import "display-block/all";
@import "linked-set/all";
@import "tabular-fields/all";
@import "tabular-fields/all";
@import "welcome-popup/all";

View File

@@ -0,0 +1,6 @@
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
@import "welcome-popup";

View File

@@ -0,0 +1,136 @@
/*!
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-welcome-popup--dialog--padding-x: $ibo-spacing-0 !default;
$ibo-welcome-popup--dialog--padding-y: $ibo-spacing-0 !default;
$ibo-welcome-popup--messages-stack--width: 300px !default;
$ibo-welcome-popup--messages-stack--padding-x: $ibo-spacing-500 !default;
$ibo-welcome-popup--messages-stack--padding-y: $ibo-spacing-600 !default;
$ibo-welcome-popup--messages-stack--background-color: $ibo-color-grey-100 !default;
$ibo-welcome-popup--stack-item--padding-x: $ibo-spacing-400 !default;
$ibo-welcome-popup--stack-item--padding-y: $ibo-spacing-400 !default;
$ibo-welcome-popup--stack-item--background-color: $ibo-color-white-100 !default;
$ibo-welcome-popup--stack-item--border-width: 1px !default;
$ibo-welcome-popup--stack-item--border-style: solid !default;
$ibo-welcome-popup--stack-item--border-color: $ibo-color-grey-300 !default;
$ibo-welcome-popup--stack-item--is-active--border-color: $ibo-color-grey-600 !default;
$ibo-welcome-popup--stack-item--opacity: 1 !default;
$ibo-welcome-popup--stack-item--is-acknowledged--opacity: 0.6 !default;
$ibo-welcome-popup--stack-item--sibling-spacing: $ibo-spacing-400 !default;
$ibo-welcome-popup--stack-item-icon--size: $ibo-size-350 !default;
$ibo-welcome-popup--stack-item-icon--margin-right: $ibo-spacing-400 !default;
$ibo-welcome-popup--stack-item-icon--border-size: 1px !default;
$ibo-welcome-popup--message-content--padding-x: $ibo-spacing-800 !default;
$ibo-welcome-popup--message-content--padding-y: $ibo-spacing-700 !default;
$ibo-welcome-popup--message-illustration--min-width: $ibo-size-650 !default;
$ibo-welcome-popup--message-illustration--background-size: contain !default;
$ibo-welcome-popup--message-illustration--spacing: $ibo-spacing-800 !default;
$ibo-welcome-popup--message-title--margin-bottom: $ibo-spacing-700 !default;
.ibo-welcome-popup--dialog {
@extend %ibo-full-height-content;
&.ui-dialog-content {
padding: $ibo-welcome-popup--dialog--padding-y $ibo-welcome-popup--dialog--padding-x; /* Overload default modal style */
height: auto !important; /* Overload default modal inline style to avoid "content" overflowing while "stack" size remains smaller */
}
}
.ibo-welcome-popup--messages-stack {
min-width: $ibo-welcome-popup--messages-stack--width;
max-width: $ibo-welcome-popup--messages-stack--width;
padding: $ibo-welcome-popup--messages-stack--padding-y $ibo-welcome-popup--messages-stack--padding-x;
overflow-y: auto;
background-color: $ibo-welcome-popup--messages-stack--background-color;
/* Here instead of in .ibo-welcome-popup--stack-item as there is an intermediate DOM level */
> *:not(:first-child) {
margin-top: $ibo-welcome-popup--stack-item--sibling-spacing;
}
}
.ibo-welcome-popup--stack-item {
@extend %ibo-vertically-centered-content;
padding: $ibo-welcome-popup--stack-item--padding-y $ibo-welcome-popup--messages-stack--padding-x;
background-color: $ibo-welcome-popup--stack-item--background-color;
border: $ibo-welcome-popup--stack-item--border-width $ibo-welcome-popup--stack-item--border-style $ibo-welcome-popup--stack-item--border-color;
@extend %ibo-border-radius-400;
&.ibo-is-active {
border-color: $ibo-welcome-popup--stack-item--is-active--border-color;
}
&.ibo-is-acknowledged {
opacity: $ibo-welcome-popup--stack-item--is-acknowledged--opacity;
&.ibo-is-active {
opacity: $ibo-welcome-popup--stack-item--opacity;
}
}
}
.ibo-welcome-popup--stack-item-icon {
width: $ibo-welcome-popup--stack-item-icon--size;
height: $ibo-welcome-popup--stack-item-icon--size;
min-width: $ibo-welcome-popup--stack-item-icon--size;
min-height: $ibo-welcome-popup--stack-item-icon--size;
margin-right: $ibo-welcome-popup--stack-item-icon--margin-right; /* Space from title which is always present */
@extend %ibo-medallion;
border-width: $ibo-welcome-popup--stack-item-icon--border-size;
}
.ibo-welcome-popup--stack-item-title {
@extend %ibo-text-truncated-with-ellipsis;
@extend %ibo-font-ral-med-150;
@extend %ibo-hyperlink-inherited-colors;
}
.ibo-welcome-popup--message-content-wrapper {
overflow: auto;
}
.ibo-welcome-popup--message-content {
display: flex;
justify-content: space-between;
align-items: center;
padding: $ibo-welcome-popup--message-content--padding-y $ibo-welcome-popup--message-content--padding-x;
.ibo-welcome-popup--message-illustration {
margin-left: $ibo-welcome-popup--message-illustration--spacing;
}
&:not(.ibo-is-active) {
display: none;
}
&.ibo-is-illustration-on-left-side {
flex-direction: row-reverse;
.ibo-welcome-popup--message-illustration {
margin-left: unset;
margin-right: $ibo-welcome-popup--message-illustration--spacing;
}
}
}
.ibo-welcome-popup--message-title {
@extend %ibo-font-ral-bol-150;
margin-bottom: $ibo-welcome-popup--message-title--margin-bottom;
}
.ibo-welcome-popup--message-description {
@extend %ibo-font-ral-med-150;
}
.ibo-welcome-popup--message-illustration {
min-width: $ibo-welcome-popup--message-illustration--min-width;
aspect-ratio: 1;
background-size: $ibo-welcome-popup--message-illustration--background-size;
}

View File

@@ -50,6 +50,7 @@ $ibo-field--enable-bulk--checkbox--margin-left: $ibo-spacing-300 !default;
[data-attribute-type="AttributeCustomFields"],
[data-attribute-type="AttributeTagSet"],
[data-attribute-type="AttributeEnumSet"],
[data-attribute-type="AttributeContextTagSet"],
[data-attribute-type="AttributeLinkedSet"],
[data-attribute-type="AttributeLinkedSetIndirect"],
[data-attribute-type="AttributeClassAttCodeSet"],

View File

@@ -14,7 +14,6 @@
@import "csv-import";
@import "global-search";
@import "run-query";
@import "welcome-popup";
@import "oauth.wizard";
@import "notifications";
@import "notifications-center";

View File

@@ -1,50 +0,0 @@
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
$ibo-welcome-popup--image--width: 30% !default;
$ibo-welcome-popup--image--svg--height: 100% !default;
$ibo-welcome-popup--image--svg--padding: 20px !default;
$ibo-welcome-popup--text--padding: 15px !default;
$ibo-welcome-popup--text--subdiv--padding-bottom: 20px !default;
$ibo-welcome-popup--text--first-subdiv--padding-bottom: 25px !default;
$ibo-welcome-popup--text--options--bottom: 10px !default;
#welcome_popup{
display: flex;
}
.ibo-welcome-popup--image{
display: flex;
justify-content: center;
align-self: center;
width: $ibo-welcome-popup--image--width;
>svg{
height: $ibo-welcome-popup--image--svg--height;
padding: $ibo-welcome-popup--image--svg--padding;
}
}
.ibo-welcome-popup--text{
flex-grow:1;
align-self: center;
padding: $ibo-welcome-popup--text--padding;
@extend %ibo-font-ral-nor-250;
>div>div{
padding-bottom: $ibo-welcome-popup--text--subdiv--padding-bottom;
&:first-child{
@extend %ibo-font-ral-sembol-300;
padding-bottom: $ibo-welcome-popup--text--first-subdiv--padding-bottom;
}
}
}
.ibo-welcome-popup--text--options{
position: absolute;
bottom: $ibo-welcome-popup--text--options--bottom;
}

File diff suppressed because one or more lines are too long

View File

@@ -276,4 +276,9 @@ $ibo-datamodel-viewer--schema--tooltip--fill: $ibo-color-grey-600;
$ibo-csv-import--row-error--background-color: $ibo-color-red-950;
$ibo-csv-import--cell-error--color: $ibo-color-red-500;
$ibo-csv-import--cell-modified--color: $ibo-color-blue-500;
$ibo-csv-import--cell-modified--color: $ibo-color-blue-500;
$ibo-welcome-popup--messages-stack--background-color: $ibo-color-grey-700;
$ibo-welcome-popup--stack-item--background-color: $ibo-color-grey-600;
$ibo-welcome-popup--stack-item--border-color: $ibo-color-grey-800;
$ibo-welcome-popup--stack-item--is-active--border-color: $ibo-color-grey-900;

File diff suppressed because one or more lines are too long

View File

@@ -142,4 +142,8 @@ $ibo-toast--icon--left: $ibo-spacing-400 !default;
.ibo-popover-menu--item:not(:last-child){
border-bottom: $ibo-high-contrast--thin-border;
}
.ibo-welcome-popup--stack-item.ibo-is-active {
border-width: 2px;
}

View File

@@ -771,8 +771,9 @@ class TriggerOnAttachmentDownload extends TriggerOnAttributeBlobDownload
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "",
"reconc_keys" => array('description'),
"reconc_keys" => ['description'],
"db_table" => "priv_trigger_onattdownload",
"db_key_field" => "id",
"db_finalclass_field" => "",

View File

@@ -0,0 +1,19 @@
<?php
class TokenValidation
{
// construct function
public function __construct()
{
}
public function isSetupTokenValid($sParamToken) : bool
{
if (!file_exists(APPROOT.'data/.setup')) {
return false;
}
$sSetupToken = trim(file_get_contents(APPROOT.'data/.setup'));
unlink(APPROOT.'data/.setup');
return $sParamToken === $sSetupToken;
}
}

View File

@@ -266,6 +266,7 @@ try {
require_once('hubconnectorpage.class.inc.php');
require_once(APPROOT.'/application/startup.inc.php');
require_once('TokenValidation.php');
$sTargetRoute = utils::ReadParam('target', ''); // ||browse_extensions|deploy_extensions|
@@ -281,13 +282,23 @@ try {
switch ($sTargetRoute) {
case 'inform_after_setup':
// Hidden IFRAME at the end of the setup
$oPage = new NiceWebPage('');
$aDataToPost = MakeDataToPost($sTargetRoute);
$oPage->add('<form id="hub_launch_form" action="'.$sHubUrlStateless.'" method="post">');
$oPage->add('<input type="hidden" name="json" value="'.utils::EscapeHtml(json_encode($aDataToPost)).'">');
$oPage->add_ready_script('$("#hub_launch_form").submit();');
break;
// Hidden IFRAME at the end of the setup
require_once (APPROOT.'/application/ajaxwebpage.class.inc.php');
$sParamToken = utils::ReadParam('setup_token');
$oTokenValidation = new TokenValidation();
$bIsTokenValid = $oTokenValidation->isSetupTokenValid($sParamToken);
if (UserRights::IsAdministrator() || $bIsTokenValid) {
$oPage = new NiceWebPage('');
$aDataToPost = MakeDataToPost($sTargetRoute);
$oPage->add('<form id="hub_launch_form" action="'.$sHubUrlStateless.'" method="post">');
$oPage->add('<input type="hidden" name="json" value="'.utils::EscapeHtml(json_encode($aDataToPost)).'">');
$oPage->add_ready_script('$("#hub_launch_form").submit();');
} else {
IssueLog::Error('TokenValidation failed on inform_after_setup page');
throw new Exception("Not allowed");
}
break;
default:
// All other cases, special "Hub like" web page

View File

@@ -400,39 +400,6 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
'BooleanLabel:no' => 'ne',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.' login~~',
'UI:WelcomeMenu:Title' => 'Vítejte v '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' je komplexní „opensource” provozní IT portál.</p>
<ul>Obsahuje:
<li>Kompletní CMDB (databázi pro správu konfigurací) sloužící pro dokumentování a správu evidovaného IT.</li>
<li>Modul pro řízení rizik umožňující sledovat veškeré problémy, které se vyskytly v souvislosti s provozem IT.</li>
<li>Modul pro řízení změn, který slouží k plánování a sledování změn v IT prostředí.</li>
<li>Databázi známých chyb, díky které lze urychlit řešení incidentů.</li>
<li>Modul pro správu výpadků umožňující nejen dokumentovat plánované výpadky, ale také informovat příslušné adresáty.</li>
<li>Úvodní obrazovku poskytující rychlý a aktuální přehled o Vašem IT.</li>
</ul>
<p>Každý modul může být nastaven "krok za krokem" nezávisle na ostatních modulech.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' je servisně orientovaný produkt, který umožňuje správcům IT velmi jednoduše spravovat více zákazníků nebo organizací.
<ul>iTop přináší mnoho dalších výhod umožňujících "optimální" nastavení podnikových procesů které:
<li>Zvyšují účinnost řízení IT.</li>
<li>Efektivně řídí operace prováděné nad IT infrastrukturou.</li>
<li>Zvyšují spokojenost zákazníků a poskytují vedoucím pracovníkům ucelený pohled na výkonnost organizace.</li>
</ul>
</p>
<p>iTop je zcela otevřený a umožňuje bezproblémovou integraci s Vaším současným IT systémem pro správu infrastruktury.</p>
<p>
<ul>Zavedení nové generace provozního IT portálu Vám pomůže:
<li>Lépe řídit stále více a více komplexní IT prostředí.</li>
<li>Implementovat ITIL procesy svým vlastním tempem.</li>
<li>Spravovat Vaše nejdůležitější IT aktivum - Dokumentaci.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>This version features a brand new modern and accessible backoffice design.</div>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>~~',
'UI:WelcomeMenu:AllOpenRequests' => 'Otevřené požadavky: %1$d',
'UI:WelcomeMenu:MyCalls' => 'Mé požadavky',
'UI:WelcomeMenu:OpenIncidents' => 'Otevřené incidenty: %1$d',
@@ -1054,6 +1021,7 @@ We hope youll enjoy this version as much as we enjoyed imagining and creating
<ol>
<li>Sending an email message: Such actions also define the template to be used for sending the email as well as the other parameters of the message like the recipients, importance, etc.<br />
Speciální stránka <a href="../setup/email.test.php" target="_blank">email.test.php</a> je dostupná pro testování a řešení problémů s configurací PHP mailu.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Outgoing webhooks: Allow integration with a third-party application by sending structured data to a defined URL.</li>
</ol>
</p>

View File

@@ -389,39 +389,6 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
'BooleanLabel:no' => 'no~~',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.' login~~',
'UI:WelcomeMenu:Title' => 'Velkommen til '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' er en komplet, OpenSource, webbaseret IT-Service-Management-Værktøj.</p>
<ul>Den inkluderer:
<li>En komplet CMDB (Configuration management database) til at dokumentere og styre IT-portfolioen.</li>
<li>Et Incident management modul til brug for sporing og kommunikation omkring alle spørgsmål vedrørende IT.</li>
<li>Et change management modul til planlægning og sporing af ændringer i IT miljøet.</li>
<li>En "known error database" til brug for at mindske tiden for løsning af hændelser.</li>
<li>Et outage modul til dokumentation for planlagt nedetid og advisering af relevante kontakter.</li>
<li>Dashboards for hurtigt overblik over IT.</li>
</ul>
<p>Alle moduler kan installeres, step by step, uafhængigt af hinanden.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' er service udbyder orienteret, det tillader let IT teknikere at administrere flere kunder eller organisationer.
<ul>iTop, leverer et feature-rich sæt af forretnings processer som:
<li>Forøger IT administrationens effektivitet</li>
<li>Drives IT operations performance</li>
<li>Improves customer satisfaction and provides executives with insights into business performance.</li>
</ul>
</p>
<p>'.ITOP_APPLICATION_SHORT.' is completely open to be integrated within your current IT Management infrastructure.</p>
<p>
<ul>Adopting this new generation of IT Operational portal will help you to:
<li>Better manage a more and more complex IT environment.</li>
<li>Implement ITIL processes at your own pace.</li>
<li>Manage the most important asset of your IT: Documentation.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>This version features a brand new modern and accessible backoffice design.</div>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>~~',
'UI:WelcomeMenu:AllOpenRequests' => 'Åbne anmodninger: %1$d',
'UI:WelcomeMenu:MyCalls' => 'Mine brugerhenvendelser',
'UI:WelcomeMenu:OpenIncidents' => 'Åbne Incidents: %1$d',
@@ -1044,6 +1011,7 @@ We hope youll enjoy this version as much as we enjoyed imagining and creating
<ol>
<li>Sending an email message: Such actions also define the template to be used for sending the email as well as the other parameters of the message like the recipients, importance, etc.<br />
En speciel side: <a href="../setup/email.test.php" target="_blank">email.test.php</a> er til rådighed for test og problemløsning af PHP mail konfigurationen.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Outgoing webhooks: Allow integration with a third-party application by sending structured data to a defined URL.</li>
</ol>
</p>

View File

@@ -388,39 +388,6 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'BooleanLabel:no' => 'Nein',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.' Login',
'UI:WelcomeMenu:Title' => 'Willkommen bei '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' ist ein ein vollständiges, ITIL- und webbasiertes IT-Service-Management-Tool (ITSM)</p>
<ul>Es umfasst...
<li>eine vollständige CMDB (Configuration Management Database), um das IT-Portfolio zu dokumentieren und zu managen,</li>
<li>ein Incident Management-Modul, um alle Störfälle in der IT-Landschaft zu beobachten und diese zu kommunizieren,</li>
<li>ein Change Management-Modul, um Änderungen der IT-Landschaft zu planen und zu beobachten,</li>
<li>eine Datenbank mit bekannten Fehlern, um Zwischenfälle schneller anhand bekannter Problemlösungen zu beseitigen,</li>
<li>ein Ausfall-Modul, um geplante Ausfälle zu dokumentieren und die betreffenden Kontakte zu informieren,</li>
<li>unterschiedliche Dashboards, um sich einen schnellen Überblick über Ihre IT zu verschaffen.</li>
</ul>
<p>Alle Module können nacheinander und vollständig unabhängig voneinander eingerichtet werden.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' ist mandantenfähig, es erlaubt IT-Technikern, auf einfache Art eine Vielzahl an Kunden und Firmen zu verwalten.
<ul>'.ITOP_APPLICATION_SHORT.' bietet ein umfangreiches Set an Business-Prozessen, die
<li>die Effizienz des IT-Managements steigern,</li>
<li>die die Performance des IT-Betriebs steuern,</li>
<li>die Kundenzufriedenheit verbessern und Führungskräften Einsicht in die Business Performance ermöglichen.</li>
</ul>
</p>
<p>'.ITOP_APPLICATION_SHORT.' ist komplett offen, damit es sich bestmöglich in Ihre derzeitige IT-Management-Infrastruktur integriert.</p>
<p>
<ul>Die neue Generation des IT Operational Portals ermöglicht Ihnen
<li>ein besseres Management in einer immer komplexeren IT-Landschaft,</li>
<li>die ITIL-Prozesse gemäß dem Rhythmus Ihres Unternehmens einzuführen,</li>
<li>und ein besseres Verwalten des wichtigsten Bestandteiles Ihrer IT: der Dokumentation.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Willkommen bei '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>Diese Version bietet ein brandneues, modernes und zugängliches Backoffice-Design.</div>
<div>Wir haben die Kernfunktionen von '.ITOP_APPLICATION.' beibehalten, die Sie mögen, und sie modernisiert, damit Sie sie lieben.
Wir hoffen, dass Ihnen diese Version genauso viel Spaß macht, wie uns die Vorstellung und die Erstellung dieser Version.</div>
<div>Passen Sie Ihre '.ITOP_APPLICATION.'-Einstellungen für ein personalisiertes Benutzererlebnis an.</div>',
'UI:WelcomeMenu:AllOpenRequests' => 'Offene Requests: %1$d',
'UI:WelcomeMenu:MyCalls' => 'An mich gestellte Benutzeranfragen',
'UI:WelcomeMenu:OpenIncidents' => 'Offene Incidents: %1$d',
@@ -1042,6 +1009,7 @@ Wir hoffen, dass Ihnen diese Version genauso viel Spaß macht, wie uns die Vorst
<ol>
<li>Senden einer E-Mail: Solche Aktionen definieren die verwendete Vorlage sowie andere Parameter der Nachricht wie Empfänger, Wichtigkeit, usw.<br />
Eine spezielle Seite: <a href="../setup/email.test.php" target="_blank">email.test.php</a> steht zum Testen und zur Fehlerbehebung Ihrer PHP-Mailkonfiguration bereit.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Ausgehende webhooks: Erlaubt die Integration mit einer externen Anwendung indem strukturierte Daten an eine definierte URL gesendet werden.</li>
</ol>
</p>

View File

@@ -209,12 +209,15 @@ Operators:<br/>
'Core:AttributeTag' => 'Tags',
'Core:AttributeTag+' => '',
'Core:Context=REST/JSON' => 'REST',
'Core:Context=REST/JSON' => 'Webservice',
'Core:Context=Synchro' => 'Synchro',
'Core:Context=Setup' => 'Setup',
'Core:Context=GUI:Console' => 'Console',
'Core:Context=CRON' => 'cron',
'Core:Context=CRON' => 'Background tasks',
'Core:Context=GUI:Portal' => 'Portal',
'Core:Context=GUI' => 'GUI',
'Core:Context=Import' => 'Import',
'Core:Context=Export' => 'Export',
));

View File

@@ -175,6 +175,8 @@ Dict::Add('EN US', 'English', 'English', array(
'Class:User/Attribute:status+' => 'Whether the user account is enabled or disabled.',
'Class:User/Attribute:status/Value:enabled' => 'Enabled',
'Class:User/Attribute:status/Value:disabled' => 'Disabled',
'Class:User/Attribute:allowed_contexts' => 'Allowed authentication contexts',
'Class:User/Attribute:allowed_contexts+' => 'List of authentication contexts that the user is allowed to access',
'Class:User/Error:LoginMustBeUnique' => 'Login must be unique - "%1$s" is already being used.',
'Class:User/Error:AtLeastOneProfileIsNeeded' => 'At least one profile must be assigned to this user.',
@@ -408,41 +410,6 @@ Dict::Add('EN US', 'English', 'English', array(
'BooleanLabel:no' => 'no',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.' login',
'UI:WelcomeMenu:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' is a complete, OpenSource, IT Operational Portal.</p>
<ul>It includes:
<li>A complete CMDB (Configuration management database) to document and manage the IT inventory.</li>
<li>An Incident management module to track and communicate about all issues occurring in the IT.</li>
<li>A change management module to plan and track the changes to the IT environment.</li>
<li>A known error database to speed up the resolution of incidents.</li>
<li>An outage module to document all planned outages and notify the appropriate contacts.</li>
<li>Dashboards to quickly get an overview of your IT.</li>
</ul>
<p>All the modules can be setup, step by step, indepently of each other.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' is service provider oriented, it allows IT engineers to manage easily multiple customers or organizations.
<ul>'.ITOP_APPLICATION_SHORT.', delivers a feature-rich set of business processes that:
<li>Enhances IT management effectiveness</li>
<li>Drives IT operations performance</li>
<li>Improves customer satisfaction and provides executives with insights into business performance.</li>
</ul>
</p>
<p>'.ITOP_APPLICATION_SHORT.' is completely open to be integrated within your current IT Management infrastructure.</p>
<p>
<ul>Adopting this new generation of IT Operational portal will help you to:
<li>Better manage a more and more complex IT environment.</li>
<li>Implement ITIL processes at your own pace.</li>
<li>Manage the most important asset of your IT: Documentation.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>This version features a brand new modern and accessible backoffice design.</div>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>',
'UI:WelcomeMenu:AllOpenRequests' => 'Open requests: %1$d',
'UI:WelcomeMenu:MyCalls' => 'My requests',
'UI:WelcomeMenu:OpenIncidents' => 'Open incidents: %1$d',
@@ -1096,6 +1063,7 @@ We hope youll enjoy this version as much as we enjoyed imagining and creating
<ol>
<li>Sending an email message: Such actions also define the template to be used for sending the email as well as the other parameters of the message like the recipients, importance, etc.<br />
A special page: <a href="../setup/email.test.php" target="_blank">email.test.php</a> is available for testing and troubleshooting your PHP mail configuration.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Outgoing webhooks: Allow integration with a third-party application by sending structured data to a defined URL.</li>
</ol>
</p>

View File

@@ -401,39 +401,6 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
'BooleanLabel:no' => 'No',
'UI:Login:Title' => 'Inicio de Sesión',
'UI:WelcomeMenu:Title' => 'Bienvenido a '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' es un completo portal de administración de servicios de TI basado en código abierto.</p>
<p>Incluye:</p>
<ul><li>Una CMDB completa (Base de datos de Configuraciones) para documentar y manejar el inventario de TI.</li>
<li>Un módulo de Administración de Incidentes, para llevar el seguimiento y comunicar los eventos que están afectando a los servicios TI.</li>
<li>Un módulo de Administración de Cambios para planear y llevar el seguimiento de cambios hechos al ambiente de TI.</li>
<li>Una base de Conocimiento para acelerar la correción de Incidentes.</li>
<li>Un módulo de Cortes/Caídas para documentar todas las caídas planeadas o no y notificar a los contactos del caso.</li>
<li>Tableros de Control para rápidamente tener visión general del ambiente de TI.</li>
</ul>
<p>Todos los módulos pueden ser configurados, paso a paso, individual e independientemente de los otros.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' está orientado a los proveedores de servicios, le permite al personal de TI administrar fácilmente múltiples Organizaciones.
<p>'.ITOP_APPLICATION_SHORT.', provee un conjunto de funciones de procesos de negocio que: </p>
<ul><li>Mejora la efectividad de la adminitración de TI</li>
<li>Dirige el desempeño de la operaciones de TI</li>
<li>Incrementa la satisfacción del cliente y provee a los ejecutivos con detalles del desempeño del negocio.</li>
</ul>
</p>
<p>'.ITOP_APPLICATION_SHORT.' es completamente abierto para ser integrado con su actual infraestructura de administración de TI.</p>
<p>
<p>Adoptar esta nueva generación de portales de operaciones de TI le ayudará a:</p>
<ul><li>Mejorar la administración de entornos de TI más y más complejos.</li>
<li>Implementar los procesos de ITIL a su propio ritmo.</li>
<li>Administrar el bien más importante de su infraestructura de TI: La Documentación.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Felicidades, se encuentra en '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>Esta versión cuenta con un moderno diseño accesible y receptivo.</div>
<div>Mantuvimos en '.ITOP_APPLICATION.' las funciones básicas que le gustan y se modernizaron.
Esperamos distrute de esta versión tanto como nosotros la imaginamos y creamos.</div>
<div>Configure las preferencias de '.ITOP_APPLICATION.' para una experiencia personalizada.</div>',
'UI:WelcomeMenu:AllOpenRequests' => 'Requerimientos Abiertos: %1$d',
'UI:WelcomeMenu:MyCalls' => 'Mis Requerimientos',
'UI:WelcomeMenu:OpenIncidents' => 'Incidentes Abiertos: %1$d',
@@ -1061,6 +1028,7 @@ Esperamos distrute de esta versión tanto como nosotros la imaginamos y creamos.
<ol>
<li>Enviar un mensaje de correo: Dichas acciones también definen la plantilla que se utilizará para enviar el correo electrónico, así como los demás parámetros del mensaje, como los destinatarios, la importancia, etc.<br />
Una página especial: <a href="../setup/email.test.php" target="_blank">email.test.php</a> está disponible para probar y diagnosticar su configuración de correo de PHP.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Webhooks de Salida: permite la integración con una aplicación de terceros mediante el envío de datos estructurados a una URL definida.</li>
</ol>
</p>

View File

@@ -161,12 +161,15 @@ Opérateurs :<br/>
'Core:FriendlyName-Description' => 'Nom complet',
'Core:AttributeTag' => 'Taxon',
'Core:AttributeTag+' => '',
'Core:Context=REST/JSON' => 'REST',
'Core:Context=REST/JSON' => 'Webservice',
'Core:Context=Synchro' => 'Synchro',
'Core:Context=Setup' => 'Setup',
'Core:Context=GUI:Console' => 'Console',
'Core:Context=CRON' => 'cron',
'Core:Context=CRON' => 'Tâche de fond',
'Core:Context=GUI:Portal' => 'Portal',
'Core:Context=GUI' => 'Interface graphique',
'Core:Context=Import' => 'Import',
'Core:Context=Export' => 'Export',
));

View File

@@ -160,6 +160,8 @@ Dict::Add('FR FR', 'French', 'Français', array(
'Class:User/Attribute:status+' => 'Est-ce que ce compte utilisateur est actif, ou non?',
'Class:User/Attribute:status/Value:enabled' => 'Actif',
'Class:User/Attribute:status/Value:disabled' => 'Désactivé',
'Class:User/Attribute:allowed_contexts' => 'Contextes de connexion autorisés',
'Class:User/Attribute:allowed_contexts+' => 'Liste des contextes de connexion autorisés pour cet utilisateur',
'Class:User/Error:LoginMustBeUnique' => 'Le login doit être unique - "%1s" est déjà utilisé.',
'Class:User/Error:AtLeastOneProfileIsNeeded' => 'L\'utilisateur doit avoir au moins un profil.',
'Class:User/Error:ProfileNotAllowed' => 'Le profil "%1$s" ne peux pas être ajouté à son propre utilisateur, il interdit l\'accès à la console',
@@ -391,31 +393,6 @@ Dict::Add('FR FR', 'French', 'Français', array(
'BooleanLabel:no' => 'non',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.' login',
'UI:WelcomeMenu:Title' => 'Bienvenue dans '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' est un portail opérationnel complet et libre pour gérer votre SI.</p>
<ul>il contient:
<li>Une base de gestion des configurations (CMDB - Configuration management database) pour documenter et gérer votre parc informatique.</li>
<li>Un module de gestion des incidents pour suivre les incidents d\'exploitation et gérer la communication à propos de ces incidents.</li>
<li>Un module de gestion des changements pour planifier et suivre les modifications de votre SI.</li>
<li>Une base des erreurs connues, pour accélérer la résolution des incidents.</li>
<li>Un module de gestion de la maintenance pour documenter les maintenances planifiées et informer les contacts appropriés.</li>
<li>Des tableaux de bord pour avoir rapidement une vue synthétique de votre SI.</li>
</ul>
<p>Tous ces modules peuvent être installés séparément, à votre rythme.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' a été conçu pour les fournisseurs de service, il permet à vos équipes IT de gérer facilement de multiples clients et organisations.
<ul>iTop fournit un riche ensemble de processus métier&nbsp;pour:
<li>Augmenter l\'efficacité de la gestion de votre SI</li>
<li>Accroitre la performance de vos équipes d\'exploitation</li>
<li>Améliorer la satisfaction client et fournir aux responsables des vues sur la performance interne du SI.</li>
</ul>
</p>
<p>iTop est complètement ouvert pour s\'intégrer avec votre environnement informatique.</p>
<p>
<ul>Grâce à ce portail opérationnel de nouvelle génération:
<li>Gérez un environnement informatique de plus en plus complexe.</li>
<li>Mettez en place la méthodologie ITIL à votre rythme.</li>
<li>Contrôlez l\'actif le plus important de votre SI&nbsp;: la documentation.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Félicitations, vous avez atterri sur '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.' !</div>
<div>Cette version présente un tout nouveau design moderne et accessible pour la console de support.</div>
@@ -424,6 +401,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Nous espérons que vous aimerez cette version autant que nous avons eu du plaisir à l\'imaginer et à la créer.</div>
<div>Configurez vos préférences '.ITOP_APPLICATION.' pour une expérience personnalisée.</div>',
'UI:WelcomePopup:Button:Acknowledge' => 'Ok, supprimer ce message',
'UI:WelcomeMenu:AllOpenRequests' => 'Requêtes en cours: %1$d',
'UI:WelcomeMenu:MyCalls' => 'Mes appels support',
'UI:WelcomeMenu:OpenIncidents' => 'Incidents en cours: %1$d',
@@ -1048,6 +1026,7 @@ Nous espérons que vous aimerez cette version autant que nous avons eu du plaisi
<ol>
<li>L\'envoi de mél : Les actions de type mél définissent le modèle du message ainsi que les autres paramètres (destinataires, importance, etc.).<br />
Une page spéciale : <a href="../setup/email.test.php" target="_blank">email.test.php</a> permet de tester votre configuration mail PHP.</li>
<li>L\'envoi de message newsroom : Les actions de type newsroom permettent d\'afficher une news à l\'utilisateur directement dans l\'application à travers la newsroom (icône de cloche dans le menu de gauche)</li>
<li>Les webhooks sortants : Les actions de type webhooks permettent l\'intégration avec une application tierce en transmettant des données structurées à une URL définie.</li>
</ol>
</p>

View File

@@ -390,39 +390,6 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
'BooleanLabel:no' => 'Nem',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.' bejelentkezés',
'UI:WelcomeMenu:Title' => 'Üdvözli az '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' egy teljeskörű, OpenSource, IT üzemeltetés támogató portál.</p>
<ul>A következőket tartalmazza:
<li>Teljeskörű CMDB (Konfigurációkezelés adatbázis) az IT eszközök dokumentálására és verzió kezelésére.</li>
<li>Incidenskezelés modul az összes IT-hez kapcsolódó kérelem életciklusának követésére.</li>
<li>Változáskezelés modul az IT infrastruktúra változásainak nyomonkövetésére és tervezésére.</li>
<li>Ismert hibák adatbázisa az incidens kezelés sebességének növelésére.</li>
<li>Üzemszünet modul az összes tervezett leállás tervezésére és azzal kapcsolatos kommunikáció támogatására.</li>
<li>Műszerfalak az IT infrastruktúra pillanatnyi állapotának gyors áttekintésére.</li>
</ul>
<p>Mindegyik modul önállóan telepíthető és használható.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' egy szolgáltatás orientált megoldás, amely segít az IT szakembereknek több ügyfél és szervezet egyidejű menedzselését.
<ul>az iTop az üzleti folyamatok javításához egy hatékony eszköz, mert:
<li>javítja az IT menedzsment hatékonyságát</li>
<li>növeli IT üzemeltetés teljesítményét</li>
<li>növeli az ügyfél elégedettséget és a vezetők számára lehetőséget ad az üzleti teljesítmény növelésére</li>
</ul>
</p>
<p>Az iTop teljesn nyílt ezért, egyszerűen integrálható a jelenlegi IT infrastruktúrába</p>
<p>
<ul>Az üzemeltetési portál bevezetésével:
<li>jobban menedzselhető az egyre komplexebb IT infrastruktúra</li>
<li>az ITIL folyamatok bevezetésre kerülnek</li>
<li>hatékonyan tudja kezelni az egyik legfontosabb IT eszközt, a dokumentációt.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Gratulálunk, megérkezett a '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.' oldalára!</div>
<div>Ez a verzió egy vadonatúj, modern és könnyen hozzáférhető backoffice dizájnnal rendelkezik..</div>
<div>Megtartottuk az '.ITOP_APPLICATION.' alapvető funkcióit és modernizáltuk őket, hogy megszerettessük önnel.
Reméljük, hogy ezt a verziót ugyanúgy kedvelni fogja, mint ahogy mi élveztük a megtervezését és létrehozását.</div>
<div>Szabja testre az '.ITOP_APPLICATION.' beállításait a kényelmesebb használathoz.</div>',
'UI:WelcomeMenu:AllOpenRequests' => 'Nyitott kérelmek: %1$d',
'UI:WelcomeMenu:MyCalls' => 'Saját kérelmek',
'UI:WelcomeMenu:OpenIncidents' => 'Nyitott incidensek: %1$d',
@@ -1044,6 +1011,7 @@ Reméljük, hogy ezt a verziót ugyanúgy kedvelni fogja, mint ahogy mi élvezt
<i><b>A műveletek</b></i> meghatározzák a kiváltó programok végrehajtásakor végrehajtandó műveleteket. Egyelőre csak kétféle művelet létezik:
<ol>
<li>Email üzenet küldése: Az ilyen műveletek meghatározzák az email küldéséhez használandó sablont, valamint az üzenet egyéb paramétereit, mint például a címzettek, fontosság stb.<br />
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
Egy speciális oldalon: <a href="../setup/email.test.php" target="_blank">email.test.php</a> oldalon keresztül a PHP mail konfiguráció tesztelhető.</li>
<li>Kimenő webhook-ok: Lehetővé teszik a harmadik fél alkalmazásával való integrációt strukturált adatok küldésével egy meghatározott URL-címen keresztül.</li>
</ol>

View File

@@ -406,39 +406,6 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
'BooleanLabel:no' => 'no',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.' login',
'UI:WelcomeMenu:Title' => 'Benveuto su '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' è un completo Portale Funzionale IT, Open Source.</p>
<ul>Esso include:
<li>Un completo CMDB (Configuration management database) per documentare e gestire l\'IT di inventario.</li>
<li>Un modulo di gestione degli incidenti per monitorare e comunicare su tutte le problematiche che si verificano nel settore IT.</li>
<li>Un modulo di gestione delle modifiche per pianificare e monitorare i cambiamenti all\'ambiente IT.</li>
<li>Una banca dati errori noti per accelerare la risoluzione di incidenti.</li>
<li>Un modulo di interruzione per documentare tutte le interruzioni pianificate e notificare gli opportuni contatti.</li>
<li>Un cruscotto per ottenere rapidamente una panoramica del sistema IT.</li>
</ul>
<p>Tutti i moduli possono essere installati, passo dopo passo, indipendentemente l\'uno dall\'altro.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' è fornitore di servizi di orientamento, che consente ai progettisti di gestire più o organizzazioni o clienti con facilità.
<ul>>'.ITOP_APPLICATION_SHORT.', offre un set ricco di funzionalità dei processi di business che:
<li>Migliora l\'efficacia di gestione IT</li>
<li>Guida le prestazione delle operazioni IT</li>
<li>Migliora la soddisfazione del cliente e fornisce ai dirigenti un idea della performance del business.</li>
</ul>
</p>
<p>'.ITOP_APPLICATION_SHORT.' è completamente aperto per essere integrato all\'interno della vostra infrastruttura di gestione dell\'IT.</p>
<p>
<ul>L\'adozione di questa nuova generazione di portale funzionale IT vi aiuterà a:
<li>Meglio gestire un ambiente IT sempre più complesso.</li>
<li>Implementare i processi ITIL al proprio ritmo.</li>
<li>Gestire la risorsa più importante della tua IT: Documentazione.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Congratulazioni, sei atterrato su '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>Questa versione presenta un nuovissimo design del backoffice moderno e accessibile.</div>
<div>Abbiamo mantenuto le funzioni principali di '.ITOP_APPLICATION.' che ti piacevano e le abbiamo modernizzate per farti apprezzare ancora di più.
Speriamo che tu possa apprezzare questa versione tanto quanto noi abbiamo apprezzato immaginarla e crearla.</div>
<div>Personalizza le tue '.ITOP_APPLICATION.' preferenze per un esperienza personalizzata.</div>',
'UI:WelcomeMenu:AllOpenRequests' => 'Apri le richieste: %1$d',
'UI:WelcomeMenu:MyCalls' => 'Le mie richieste',
'UI:WelcomeMenu:OpenIncidents' => 'Apri gli incidenti: %1$d',
@@ -1061,6 +1028,7 @@ Speriamo che tu possa apprezzare questa versione tanto quanto noi abbiamo apprez
<ol>
<li>Sending an email message: Such actions also define the template to be used for sending the email as well as the other parameters of the message like the recipients, importance, etc.<br />
Una Pagina speciale: <a href="../setup/email.test.php" target="_blank">email.test.php</a> è disponibile per il testing e la risoluzione dei problemi di configurazione PHP mail.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Outgoing webhooks: Allow integration with a third-party application by sending structured data to a defined URL.</li>
</ol>
</p>

View File

@@ -389,39 +389,6 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
'BooleanLabel:no' => 'いいえ',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.' login~~',
'UI:WelcomeMenu:Title' => 'ようこそ、'.ITOP_APPLICATION_SHORT.'へ',
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.'は、オープンソースの、完結したIT運用ポータルです。</p>
<ul>以下を含みます。
<li>ITインベントリを文書化し、管理するための完全なCMDB(構成管理データベース)。</li>
<li>IT環境で発生する出来事を追跡、共有するためのインシデント管理モジュール。</li>
<li>IT環境への変更を計画、追跡するための変更管理モジュール。</li>
<li>インシデントの解決をスピードアップするための既知のエラーデータベース。</li>
<li>すべての計画停止を文書化し、適切な連絡先を通知するために停止モジュール。</li>
<li>ITの概観を素早く得るためのダッシュボード。</li>
</ul>
<p>すべてのモジュールはお互いに独立しており、別個にセットアップが可能です。</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.'はサービスプロバイダ志向であり、ITエンジニアが複数の顧客や組織を簡単に管理できるようになります。
<ul>iTopは、機能豊富な下記のビジネスプロセスのセットを提供します。
<li>IT管理の実効性の強化。</li>
<li>IT運用効率化の推進。</li>
<li>顧客満足度の改善と、業績への洞察を経営経営幹部へ提供。</li>
</ul>
</p>
<p>iTopは完全にオープンなので、あなたが今使っているIT管理インフラとの統合が可能です。</p>
<p>
<ul>この新世代IT運用ポータルの採用は、下記のお手伝いをします。
<li>ますます複雑になるIT環境のより良い管理。</li>
<li>あなたのペースでのITILプロセス実装。</li>
<li>ITの中でもっとも重要な財産である「文書化」の管理。</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>This version features a brand new modern and accessible backoffice design.</div>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>~~',
'UI:WelcomeMenu:AllOpenRequests' => '要求を開く: %1$d',
'UI:WelcomeMenu:MyCalls' => '担当中の要求',
'UI:WelcomeMenu:OpenIncidents' => 'インシデントを開く: %1$d',
@@ -1044,6 +1011,7 @@ We hope youll enjoy this version as much as we enjoyed imagining and creating
<ol>
<li>Sending an email message: Such actions also define the template to be used for sending the email as well as the other parameters of the message like the recipients, importance, etc.<br />
特別なページ: <a href="../setup/email.test.php" target="_blank">email.test.php</a> は、PHPのメール設定をテストしたりトラブルシュートするのに利用可能であす。</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Outgoing webhooks: Allow integration with a third-party application by sending structured data to a defined URL.</li>
</ol>
</p>

View File

@@ -400,39 +400,6 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
'BooleanLabel:no' => 'Nee',
'UI:Login:Title' => 'Aanmelden in '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:Title' => 'Welkom in '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' is een compleet en open source portaal voor IT-operaties.</p>
<ul>Op maat van jouw IT-omgeving:
<li>Complete CMDB (Configuration Management Database) voor het documenteren en beheren van de IT-inventaris.</li>
<li>Incident Management-module voor het vinden van en communiceren over alle problemen die optreden .</li>
<li>Change Management-module voor het plannen en opvolgen van de veranderingen.</li>
<li>Database met gekende problemen om het oplossen van incidenten te versnellen.</li>
<li>Storingsmodule voor het documenteren van alle geplande storingen en voor het informeren van de juiste contacten.</li>
<li>Dashboards om snel een overzicht te krijgen.</li>
</ul>
<p>Alle modules kunnen volledig onafhankelijk van elkaar worden opgezet, stap voor stap.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' is gericht op serviceproviders. Het zorgt ervoor dat IT-engineers gemakkelijk meerdere klanten of organisaties kunnen beheren.
<ul>'.ITOP_APPLICATION_SHORT.' zorgt dankzij een uitgebreide set van bedrijfsprocessen voor een reeks voordelen:
<li>De efficientië van het IT-management versterkt.</li>
<li>De prestaties van IT-operaties verbetert.</li>
<li>De klanttevredenheid verhoogt en leidinggevenden inzicht biedt in hun bedrijfsperformantie.</li>
</ul>
</p>
<p>'.ITOP_APPLICATION_SHORT.' is klaar om geïntegreerd te worden met jouw huidige infrastructuur rond IT-management.</p>
<p>
<ul>De adoptie van dit IT-operationele portaal zal je helpen met:
<li>Het beter beheren van een steeds complexere IT-omgeving.</li>
<li>Het implementeren van ITIL-processen op jouw eigen tempo.</li>
<li>Het beheren van het belangrijkste middel: documentatie.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Proficiat, je werkt nu met '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>Deze versie heeft een volledig nieuw, modern en toegankelijk uiterlijk.</div>
<div>De belangrijkste en meest vertrouwde '.ITOP_APPLICATION.' functies hebben we behouden en een modern jasje gegeven.
We hopen dat je even hard van deze versie geniet als dat we zelf ervan hebben genoten om het te ontwerpen.</div>
<div>Wijzig je '.ITOP_APPLICATION.'-voorkeuren voor een gepersonaliseerde ervaring.</div>',
'UI:WelcomeMenu:AllOpenRequests' => 'Open aanvragen: %1$d',
'UI:WelcomeMenu:MyCalls' => 'Mijn aanvragen',
'UI:WelcomeMenu:OpenIncidents' => 'Open incidenten: %1$d',
@@ -1058,6 +1025,7 @@ We hopen dat je even hard van deze versie geniet als dat we zelf ervan hebben ge
<ol>
<li>Stuur een e-mail: Bij deze acties definieer je een sjabloon voor het bericht en ook parameters zoals ontvanger(s), prioriteit, enz.<br />
Een <a href="../setup/email.test.php" target="_blank">speciale testpagina (email.test.php)</a> is beschikbaar voor het testen en oplossen van eventuele problemen met jouw PHP e-mailconfiguratie.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Webhooks: Staat toe om te integreren met toepassingen van derde partijen, door gestructureerde data te sturen naar een URL.</li>
</ol>
</p>

View File

@@ -400,39 +400,6 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
'BooleanLabel:no' => 'nie',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.' login',
'UI:WelcomeMenu:Title' => 'Witaj w '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' to kompletny portal operacyjny OpenSource IT.</p>
<ul>Obejmuje:
<li>Kompletna baza danych CMDB (baza danych zarządzania konfiguracją) do dokumentowania inwentaryzacji IT i zarządzania nią.</li>
<li>Moduł zarządzania incydentami do śledzenia i komunikowania się o wszystkich problemach występujących w IT.</li>
<li>Moduł zarządzania zmianami do planowania i śledzenia zmian w środowisku IT.</li>
<li>Baza danych znanych błędów przyspieszająca rozwiązywanie incydentów.</li>
<li>Moduł przestojów do dokumentowania wszystkich planowanych przestojów i powiadamiania odpowiednich kontaktów.</li>
<li>Pulpity nawigacyjne, aby szybko uzyskać przegląd swojego IT.</li>
</ul>
<p>Wszystkie moduły można ustawiać krok po kroku niezależnie od siebie.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' jest zorientowany na usługodawcę, umożliwia inżynierom IT łatwe zarządzanie wieloma klientami lub organizacjami.
<ul>'.ITOP_APPLICATION_SHORT.', dostarcza bogaty w funkcje zestaw procesów biznesowych:
<li>Zwiększa efektywność zarządzania IT</li>
<li>Napędza wydajność operacji IT</li>
<li>Zwiększa satysfakcję klientów i zapewnia kierownictwu wgląd w wyniki biznesowe.</li>
</ul>
</p>
<p>'.ITOP_APPLICATION_SHORT.' jest całkowicie otwarty na integrację z obecną infrastrukturą zarządzania IT.</p>
<p>
<ul>Pomoże Ci w tym przyjęcie nowej generacji portalu operacyjnego IT:
<li>Lepiej zarządzaj coraz bardziej złożonym środowiskiem IT.</li>
<li>Wdrażaj procesy ITIL we własnym tempie.</li>
<li>Zarządzaj najważniejszym zasobem swojego IT: dokumentacją.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Gratulacje, wylądowałeś na '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>Ta wersja ma zupełnie nowy, bardziej nowoczesny i dostępny projekt zaplecza.</div>
<div>Urzymaliśmy podstawowe funkcje '.ITOP_APPLICATION.', które Ci się spodobały i zmodernizowaliśmy je, aby je bardziej pokochać.
Mamy nadzieję, że spodoba ci się ta wersja tak samo, jak nam się podobało jej wymyślanie i tworzenie.</div>
<div>Dostosuj swój '.ITOP_APPLICATION.' poprzez spersonalizowane preferencje.</div>',
'UI:WelcomeMenu:AllOpenRequests' => 'Otwarte zgłoszenia: %1$d',
'UI:WelcomeMenu:MyCalls' => 'Moje zgłoszenia',
'UI:WelcomeMenu:OpenIncidents' => 'Otwarte incydenty: %1$d',
@@ -1055,6 +1022,7 @@ Mamy nadzieję, że spodoba ci się ta wersja tak samo, jak nam się podobało j
<ol>
<li>Sending an email message: Such actions also define the template to be used for sending the email as well as the other parameters of the message like the recipients, importance, etc.<br />
Specjalna strona: <a href="../setup/email.test.php" target="_blank">email.test.php</a> jest dostępna do testowania i rozwiązywania problemów z konfiguracją poczty PHP.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Outgoing webhooks: Allow integration with a third-party application by sending structured data to a defined URL.</li>
</ol>
</p>

View File

@@ -400,39 +400,6 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
'BooleanLabel:no' => 'Não',
'UI:Login:Title' => 'Login no '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:Title' => 'Bem-vindo ao '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>O '.ITOP_APPLICATION_SHORT.' é um Portal Operacional de TI de código aberto completo.</p>
<ul>Ele inclui:
<li>Um CMDB (Configuration Management Database) completo para documentar e gerenciar o inventário de TI.</li>
<li>Um módulo de Gerenciamento de Incidentes para rastrear e comunicar todos os incidentes que ocorrem na TI.</li>
<li>Um módulo de Gerenciamento de Mudanças para planejar e acompanhar as mudanças no ambiente de TI.</li>
<li>Um banco de dados de Erros conhecidos para acelerar a solução de incidentes.</li>
<li>Um módulo de interrupção para documentar todas as interrupções planejadas e notificar os contatos apropriados.</li>
<li>Painéis para obter rapidamente uma visão geral de sua TI.</li>
</ul>
<p>Todos os módulos podem ser configurados, passo a passo, independentemente uns dos outros.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>O '.ITOP_APPLICATION_SHORT.' é orientado para o provedor de serviços, ele permite que os especialistas de TI gerenciem facilmente vários clientes ou organizações.
<ul>O '.ITOP_APPLICATION_SHORT.' oferece um conjunto rico em recursos de processos de negócios que:
<li>Melhora a eficácia do gerenciamento de TI</li>
<li>Impulsiona o desempenho das operações de TI</li>
<li>Melhora a satisfação do cliente e fornece aos executivos insights sobre o desempenho dos negócios.</li>
</ul>
</p>
<p>O '.ITOP_APPLICATION_SHORT.' está totalmente aberto para ser integrado à sua infraestrutura de gerenciamento de TI atual.</p>
<p>
<ul>Adotar esta nova geração de portal operacional de TI ajudará você a:
<li>Gerenciar melhor um ambiente de TI cada vez mais complexo.</li>
<li>Implementar processos ITIL no seu próprio ritmo.</li>
<li>Gerenciar o ativo mais importante de sua TI: Documentação.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Parabéns, você desembarcou no '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>Esta versão apresenta um novo design de backoffice moderno e acessível.</div>
<div>Nós mantivemos as funções principais do '.ITOP_APPLICATION.' que você gostou e as modernizou para fazer você amá-las.
Esperamos que você goste desta versão tanto quanto gostamos de imaginá-la e criá-la.</div>
<div>Personalize as preferências de seu '.ITOP_APPLICATION.' para uma experiência personalizada.</div>',
'UI:WelcomeMenu:AllOpenRequests' => 'Solicitações abertas: %1$d',
'UI:WelcomeMenu:MyCalls' => 'Minhas solicitações',
'UI:WelcomeMenu:OpenIncidents' => 'Incidentes abertos: %1$d',
@@ -1055,6 +1022,7 @@ Esperamos que você goste desta versão tanto quanto gostamos de imaginá-la e c
<ol>
<li>Envio de uma mensagem de e-mail: Tais ações também definem o modelo a ser usado para enviar o e-mail, bem como os demais parâmetros da mensagem, como destinatário(s), prioridade, etc.<br />
Uma página especial: <a href="../setup/email.test.php" target="_blank">email.test.php</a> está disponível para testar e solucionar problemas de configuração de e-mail PHP.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Webhooks de saída: permite a integração com um aplicativo de terceiros enviando dados estruturados para um URL definido.</li>
</ol>
</p>

View File

@@ -401,39 +401,6 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
'BooleanLabel:no' => 'нет',
'UI:Login:Title' => 'Вход в '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:Title' => 'Добро пожаловать в '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' является порталом оперативного централизованного управления IT инфраструктурой с открытым исходным кодом.</p>
<ul>Он включает:
<li>A complete CMDB (Configuration management database) to document and manage the IT inventory.</li>
<li>Модуль управления инцидентами для отслеживания и общения по вопросам IT.</li>
<li>Модуль управления изменениями для планирования и отслеживания изменений в IT.</li>
<li>База данных известных ошибок для ускорения устранения инцидентов.</li>
<li>Модуль простоев для документирования всех запланированных простоев и оповещения соответстсвующих контактов.</li>
<li>Панели для быстрого обзора IT.</li>
</ul>
<p>Все модули могут быть настроены, шаг за шагом, независмо друг от друга.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' ориентирован на предоставления сервисов, он позволяет IT специалистам легко управляться с несколькими заказчиками или организациями.
<ul>'.ITOP_APPLICATION_SHORT.' обеспечивает многофункциональный набор бизнес-процессов, которые:
<li>Повышают эффективность управления IT</li>
<li>Повышают производительность IT-операций</li>
<li>Улучшают удовлетворенность клиентов и обеспечивают понимание бизнес-процессов.</li>
</ul>
</p>
<p>'.ITOP_APPLICATION_SHORT.' полностью открыт для интеграции в рамках текущего управления ИТ-инфраструктурой.</p>
<p>
<ul>Внедрение ИТ-портала нового поколения поможет вам:
<li>Лучше управлять более и более сложными ИТ-окружениями.</li>
<li>Реализовывать процессы ITIL в вашем собственном темпе.</li>
<li>Управлять наиболее важным активом ИТ: документацией.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Поздравляем, вы приземлились на '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>Эта версия имеет совершенно новый современный и отзывчивый дизайн бэк-офиса.</div>
<div>Мы сохранили основные функции '.ITOP_APPLICATION.' и модернизировали их, чтобы вы полюбили их ещё больше.
Мы надеемся, что вам понравится эта версия так же, как нам понравилось ее придумывать и создавать.</div>
<div>Обновите свои персональные <a href="/pages/preferences.php">предпочтения</a> для более комфортной работы в '.ITOP_APPLICATION.'.</div>',
'UI:WelcomeMenu:AllOpenRequests' => 'Открытые запросы: %1$d',
'UI:WelcomeMenu:MyCalls' => 'Мои запросы',
'UI:WelcomeMenu:OpenIncidents' => 'Открытые инциденты: %1$d',
@@ -1056,6 +1023,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
<ol>
<li>Sending an email message: Such actions also define the template to be used for sending the email as well as the other parameters of the message like the recipients, importance, etc.<br />
Для тестирования и устранения неполадок в настройках почты доступна специальная страница: <a href="../setup/email.test.php" target="_blank">email.test.php</a>.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Outgoing webhooks: Allow integration with a third-party application by sending structured data to a defined URL.</li>
</ol>
</p>

View File

@@ -389,40 +389,6 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
'BooleanLabel:no' => 'no~~',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.' login~~',
'UI:WelcomeMenu:Title' => 'Vitajte v '.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.' je kompletne voľne šíriteľný operačný IT program.</p>
<ul>Zahŕňa:
<li>Kompletnú CMDB (Konfiguračná databáza manažmentu) pre zdokumentovanie a manažovanie IT inventáru.</li>
<li>Modul manažmentu incidentov pre sledovanie a komunikovanie o všetkých problémoch vyskytujúcich sa v IT.</li>
<li>Modul manažmentu zmien pre plánovanie a sledovanie zmien v IT prostredí.</li>
<li>Databáza známych chýb pre urýchlenie riešenia incidentov.</li>
<li>Modul výpadkov pre zdokumentovanie všetkých plánovaných výpadkov a oboznámenie vhodných kontaktov o výpadkoch.</li>
<li>Dashboard panel pre rýchle získanie prehľadu o Vašom IT.</li>
</ul>
<p>Všetky moduly môžu byť nastavené, krok po kroku, nezávisle jeden od druhého.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.' orientovaný na poskytovateľa služieb, dovoľuje IT technikom ľahko manažovať viacerých zákazníkov alebo organizácií.
<ul>iTop, dodáva súbor biznis procesov bohatých na služby, ktoré:
<li>Zdokonalujú efektivitu IT manažmentu</li>
<li>Poháňa výkon IT operácií</li>
<li>Zlepšuje spokojnosť zákazníka a poskytuje vedúcim osobám náhľad do výkonu biznisu.</li>
</ul>
</p>
<p>iTop je kompletne otvorený myšlienke byť integrovaný vo Vašej súčasnej infraštruktúre IT manažmentu.</p>
<p>
<ul>Adoptovanie tejto novej generácie IT operačného portálu Vám pomôže:
<li>Lepšie manažovať viac a viac zložitejšie IT prostredie.</li>
<li>Implementovať ITIL procesy Vaším vlastným tempom.</li>
<li>Manažovať najdôležitejšie aktíva Vášho IT: Dokumentáciu.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>This version features a brand new modern and accessible backoffice design.</div>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>~~',
'UI:WelcomeMenu:AllOpenRequests' => 'Otvoriť žiadosť: %1$d',
'UI:WelcomeMenu:MyCalls' => 'Moje žiadosti',
'UI:WelcomeMenu:OpenIncidents' => 'Otvoriť incidenty: %1$d',
@@ -1047,6 +1013,7 @@ We hope youll enjoy this version as much as we enjoyed imagining and creating
<ol>
<li>Sending an email message: Such actions also define the template to be used for sending the email as well as the other parameters of the message like the recipients, importance, etc.<br />
Špeciálna stránka: <a href="../setup/email.test.php" target="_blank">email.test.php</a> je dostupná pre testovanie a odstraňovanie problémov Vašej PHP mailovej konfigurácie.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Outgoing webhooks: Allow integration with a third-party application by sending structured data to a defined URL.</li>
</ol>
</p>

View File

@@ -400,39 +400,6 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
'BooleanLabel:no' => 'hayır',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.' login~~',
'UI:WelcomeMenu:Title' => ITOP_APPLICATION_SHORT.'\'a Hoşgeldiniz',
'UI:WelcomeMenu:LeftBlock' => '<p>iTop açık kaynak Bilişim İşlem Potalıdır.</p>
<ul>Kapsamı:
<li>Bilişim altyapısının tanımlandığı ve dokümante edildiği Konfigürasyon Yönetimi CMDB (Configuration management database)modülü.</li>
<li>Bilişim altyapısı ile ilgili tüm olayların takibi.</li>
<li>Bilişim altyapısının değişim yönetimi.</li>
<li>Bilinen hatalar bilgi kütüphanesi.</li>
<li>Planlı kesintilerin kayıt altına alınması ve ilgililerin uyarılması.</li>
<li>Özet gösterge ekranları</li>
</ul>
<p>Tüm modüller bağımsız olarak, adım adım kurulabilir.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>iTop servis sağlayıcı maktığı ile hazırlanmış olup, birden fazla müşteri ve kuruma kolaylıkla hizmet vermeye imkan sağlar.
<ul>iTop, zengin iş süreçleri tanımlama imkanıyla:
<li>Bilişim yönetim etkinliğini</li>
<li>Operasyon performansını</li>
<li>Müşteri memnuniyetini ve yönetimin iş performansı hakkında bilgi sahibi olmasını sağlar.</li>
</ul>
</p>
<p>iTop mevcut Bilşim altyapınızla entegre edilmeye açıktır.</p>
<p>
<ul>Yeni nesil operasyonel Bilişim portalı :
<li>Bilişim ortamının daha iyi yönetilmesini.</li>
<li>ITIL süreçlerinin kendi başınıza uygulanmaya.</li>
<li>İşletmenin en önemli kaynağı olan dokümantasyonu yönetmesine imkan sağlar.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>This version features a brand new modern and accessible backoffice design.</div>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>~~',
'UI:WelcomeMenu:AllOpenRequests' => 'Açık istekler: %1$d',
'UI:WelcomeMenu:MyCalls' => 'İsteklerim',
'UI:WelcomeMenu:OpenIncidents' => 'Açık Arızalar: %1$d',
@@ -1055,6 +1022,7 @@ We hope youll enjoy this version as much as we enjoyed imagining and creating
<ol>
<li>Sending an email message: Such actions also define the template to be used for sending the email as well as the other parameters of the message like the recipients, importance, etc.<br />
Özel sayfa: <a href="../setup/email.test.php" target="_blank">email.test.php</a> PHP e-posta konfigürnunu test ediniz.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>Outgoing webhooks: Allow integration with a third-party application by sending structured data to a defined URL.</li>
</ol>
</p>

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('CS CZ', 'Czech', 'Čeština', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('CS CZ', 'Czech', 'Čeština', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>This version features a brand new modern and accessible backoffice design.</div>
<br>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<br>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>~~',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('DA DA', 'Danish', 'Dansk', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('DA DA', 'Danish', 'Dansk', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>This version features a brand new modern and accessible backoffice design.</div>
<br>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<br>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>~~',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('DE DE', 'German', 'Deutsch', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Verstanden',
]);
// Message
Dict::Add('DE DE', 'German', 'Deutsch', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Willkommen bei '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>Diese Version bietet ein brandneues, modernes und zugängliches Backoffice-Design.</div>
<br>
<div>Wir haben die Kernfunktionen von '.ITOP_APPLICATION.' beibehalten, die Sie mögen, und sie modernisiert, damit Sie sie lieben.
Wir hoffen, dass Ihnen diese Version genauso viel Spaß macht, wie uns die Vorstellung und die Erstellung dieser Version.</div>
<br>
<div>Passen Sie Ihre '.ITOP_APPLICATION.'-Einstellungen für ein personalisiertes Benutzererlebnis an.</div>',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('EN US', 'English', 'English', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it',
]);
// Message
Dict::Add('EN US', 'English', 'English', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>This version features a brand new modern and accessible backoffice design.</div>
<br>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<br>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Felicidades, se encuentra en '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>Esta versión cuenta con un moderno diseño accesible y receptivo.</div>
<br>
<div>Mantuvimos en '.ITOP_APPLICATION.' las funciones básicas que le gustan y se modernizaron.
Esperamos distrute de esta versión tanto como nosotros la imaginamos y creamos.</div>
<br>
<div>Configure las preferencias de '.ITOP_APPLICATION.' para una experiencia personalizada.</div>',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('FR FR', 'French', 'Français', [
'UI:WelcomePopup:Button:RemindLater' => 'Me le rappeler plus tard',
'UI:WelcomePopup:Button:Acknowledge' => 'Compris',
]);
// Message
Dict::Add('FR FR', 'French', 'Français', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3 : Présentation du design fullmoon',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Félicitations, vous avez atterri sur '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.' !</div>
<br>
<div>Cette version présente un tout nouveau design moderne et accessible pour la console de support.</div>
<br>
<div>Nous avons conservé les fonctions de base d\''.ITOP_APPLICATION.' que vous aviez apprécié et les avons modernisées pour vous les faire adorer.
Nous espérons que vous aimerez cette version autant que nous avons eu du plaisir à l\'imaginer et à la créer.</div>
<br>
<div>Configurez vos préférences '.ITOP_APPLICATION.' pour une expérience personnalisée.</div>',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Gratulálunk, megérkezett a '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.' oldalára!</div>
<br>
<div>Ez a verzió egy vadonatúj, modern és könnyen hozzáférhető backoffice dizájnnal rendelkezik..</div>
<br>
<div>Megtartottuk az '.ITOP_APPLICATION.' alapvető funkcióit és modernizáltuk őket, hogy megszerettessük önnel.
Reméljük, hogy ezt a verziót ugyanúgy kedvelni fogja, mint ahogy mi élveztük a megtervezését és létrehozását.</div>
<br>
<div>Szabja testre az '.ITOP_APPLICATION.' beállításait a kényelmesebb használathoz.</div>',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('IT IT', 'Italian', 'Italiano', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('IT IT', 'Italian', 'Italiano', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Congratulazioni, sei atterrato su '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>Questa versione presenta un nuovissimo design del backoffice moderno e accessibile.</div>
<br>
<div>Abbiamo mantenuto le funzioni principali di '.ITOP_APPLICATION.' che ti piacevano e le abbiamo modernizzate per farti apprezzare ancora di più.
Speriamo che tu possa apprezzare questa versione tanto quanto noi abbiamo apprezzato immaginarla e crearla.</div>
<br>
<div>Personalizza le tue '.ITOP_APPLICATION.' preferenze per un esperienza personalizzata.</div>',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('JA JP', 'Japanese', '日本語', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('JA JP', 'Japanese', '日本語', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>This version features a brand new modern and accessible backoffice design.</div>
<br>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<br>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>~~',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Proficiat, je werkt nu met '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>Deze versie heeft een volledig nieuw, modern en toegankelijk uiterlijk.</div>
<br>
<div>De belangrijkste en meest vertrouwde '.ITOP_APPLICATION.' functies hebben we behouden en een modern jasje gegeven.
We hopen dat je even hard van deze versie geniet als dat we zelf ervan hebben genoten om het te ontwerpen.</div>
<br>
<div>Wijzig je '.ITOP_APPLICATION.'-voorkeuren voor een gepersonaliseerde ervaring.</div>',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('PL PL', 'Polish', 'Polski', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('PL PL', 'Polish', 'Polski', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Gratulacje, wylądowałeś na '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>Ta wersja ma zupełnie nowy, bardziej nowoczesny i dostępny projekt zaplecza.</div>
<br>
<div>Urzymaliśmy podstawowe funkcje '.ITOP_APPLICATION.', które Ci się spodobały i zmodernizowaliśmy je, aby je bardziej pokochać.
Mamy nadzieję, że spodoba ci się ta wersja tak samo, jak nam się podobało jej wymyślanie i tworzenie.</div>
<br>
<div>Dostosuj swój '.ITOP_APPLICATION.' poprzez spersonalizowane preferencje.</div>',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Parabéns, você desembarcou no '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>Esta versão apresenta um novo design de backoffice moderno e acessível.</div>
<br>
<div>Nós mantivemos as funções principais do '.ITOP_APPLICATION.' que você gostou e as modernizou para fazer você amá-las.
Esperamos que você goste desta versão tanto quanto gostamos de imaginá-la e criá-la.</div>
<br>
<div>Personalize as preferências de seu '.ITOP_APPLICATION.' para uma experiência personalizada.</div>',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('RU RU', 'Russian', 'Русский', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('RU RU', 'Russian', 'Русский', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Поздравляем, вы приземлились на '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>Эта версия имеет совершенно новый современный и отзывчивый дизайн бэк-офиса.</div>
<br>
<div>Мы сохранили основные функции '.ITOP_APPLICATION.' и модернизировали их, чтобы вы полюбили их ещё больше.
Мы надеемся, что вам понравится эта версия так же, как нам понравилось ее придумывать и создавать.</div>
<br>
<div>Обновите свои персональные <a href="/pages/preferences.php">предпочтения</a> для более комфортной работы в '.ITOP_APPLICATION.'.</div>',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>This version features a brand new modern and accessible backoffice design.</div>
<br>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<br>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>~~',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>This version features a brand new modern and accessible backoffice design.</div>
<br>
<div>We kept '.ITOP_APPLICATION.' core functions that you liked and modernized them to make you love them.
We hope youll enjoy this version as much as we enjoyed imagining and creating it.</div>
<br>
<div>Customize your '.ITOP_APPLICATION.' preferences for a personalized experience.</div>~~',
]);

View File

@@ -0,0 +1,24 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
// UI elements
Dict::Add('ZH CN', 'Chinese', '简体中文', [
'UI:WelcomePopup:Button:RemindLater' => 'Remind me later~~',
'UI:WelcomePopup:Button:Acknowledge' => 'Got it~~',
]);
// Message
Dict::Add('ZH CN', 'Chinese', '简体中文', [
'UI:WelcomePopup:Message:320_01:Title' => ITOP_APPLICATION_SHORT . ' 3: Introducing fullmoon design~~',
'UI:WelcomePopup:Message:320_01:Description' => '<div>恭喜, 您运行的是'.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<br>
<div>此版本全新设计了一个现代且易用的后台界面.</div>
<br>
<div>我们不仅保留'.ITOP_APPLICATION.'中您所喜爱的核心功能,同时使其更具现代化.
我们衷心地希望您喜爱此版本,正如我们在设计和实现它的时候一样.</div>
<br>
<div>定制化您的'.ITOP_APPLICATION.'设置,实现个性化体验.</div>',
]);

View File

@@ -408,41 +408,6 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'BooleanLabel:no' => '否',
'UI:Login:Title' => ITOP_APPLICATION_SHORT.'登录',
'UI:WelcomeMenu:Title' => '欢迎使用'.ITOP_APPLICATION_SHORT,
'UI:WelcomeMenu:LeftBlock' => '<p>'.ITOP_APPLICATION_SHORT.'是完全开源的IT运维门户.</p>
<ul>它包括:
<li>完整的CMDB(配置管理数据库),用于登记和管理您的IT资产.</li>
<li>事件管理模块用于跟踪和传递所有发生在IT系统中的事件.</li>
<li>变更管理模块用于规划和跟踪IT环境中发生的变化.</li>
<li>已知问题数据库可加速事件的处理.</li>
<li>停机模块记录所有计划内的停机并通知对应的联系人.</li>
<li>通过仪表盘快速获得您的IT概况.</li>
</ul>
<p>所有模块互相独立,可以单独部署.</p>',
'UI:WelcomeMenu:RightBlock' => '<p>'.ITOP_APPLICATION_SHORT.'是面向服务供应商的, 它使得IT工程师能够更方便地管理多客户和多组织.
<ul>'.ITOP_APPLICATION_SHORT.'提供功能丰富的业务处理流程:
<li>提高IT管理效率</li>
<li>提升IT可操作能力</li>
<li>提高用户满意度,提升业务能力.</li>
</ul>
</p>
<p>'.ITOP_APPLICATION_SHORT.'是完全开放的,可被集成到现有的IT管理架构之中.</p>
<p>
<ul>利用这个新一代的IT操作门户, 可以帮助您:
<li>更好地管理越来越复杂的IT环境.</li>
<li>逐步实现ITIL流程.</li>
<li>管理IT中最重要的资产: 文档.</li>
</ul>
</p>',
'UI:WelcomeMenu:Text' => '<div>恭喜, 您运行的是'.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
<div>此版本全新设计了一个现代且易用的后台界面.</div>
<div>我们不仅保留'.ITOP_APPLICATION.'中您所喜爱的核心功能,同时使其更具现代化.
我们衷心地希望您喜爱此版本,正如我们在设计和实现它的时候一样.</div>
<div>定制化您的'.ITOP_APPLICATION.'设置,实现个性化体验.</div>',
'UI:WelcomeMenu:AllOpenRequests' => '所有打开的需求: %1$d',
'UI:WelcomeMenu:MyCalls' => '我办理的需求',
'UI:WelcomeMenu:OpenIncidents' => '所有打开的事件: %1$d',
@@ -1095,6 +1060,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
<ol>
<li>发送电子邮件: 此动作同时需要指定发送的邮件所使用的模板, 以及一些其他参数, 例如收件人, 优先级, 等.<br />
这里有一个专用的页面: <a href="../setup/email.test.php" target="_blank">email.test.php</a>可用于测试和调试PHP的邮件配置.</li>
<li>Sending a newsroom message: Display a news to user directly in the application through the newsroom (bell icon on the left menu)</li>
<li>外部webhook: 允许通过发送结构化数据到指定URL来与第三方应用集成.</li>
</ol>
</p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -57,6 +57,7 @@ import MentionsMarkup from "./plugins/mentions-markup/mentions-markup.plugin";
import TriggerUpdateOnReady from "./plugins/trigger_update_on_ready/trigger_update_on_ready.plugin";
import Maximize from './plugins/maximize/maximize.plugin';
import ObjectShortcut from './plugins/object-shortcut/object-shortcut.plugin';
import DetectChanges from "./plugins/detect-change/detect-change.plugin";
// You can read more about extending the build with additional plugins in the "Installing plugins" guide.
// See https://ckeditor.com/docs/ckeditor5/latest/installation/plugins/installing-plugins.html for details.
@@ -116,7 +117,8 @@ class Editor extends ClassicEditor {
TriggerUpdateOnReady,
Maximize,
ObjectShortcut,
InsertHtml
InsertHtml,
DetectChanges
];
// default configuration editor

View File

@@ -0,0 +1,34 @@
import { Plugin, type Editor } from 'ckeditor5/src/core.js';
import iTopDataProcessor from "./itop-data-processor";
/**
* DetectChanges Plugin.
*
*/
export default class DetectChanges extends Plugin {
constructor( editor: Editor ) {
super( editor );
const sInitialValue:string = editor.config.get('detectChanges.initialValue') as string;
// TODO 3.2.0: How to use CombodoJSConsole here ?
console.debug('DetectChanges initial value', sInitialValue);
// If the initial value is not set or empty, we don't need to do anything
if( !sInitialValue || sInitialValue === '') {
return;
}
// Initialize our own data processor
editor.data.processor= new iTopDataProcessor( editor.data.viewDocument, sInitialValue, editor.getData() ) as iTopDataProcessor;
// Listen for the dataReady event only once
editor.model.document.once('change:data', () => {
// Ignore linter as processor can be any kind of DataProcessor but we're sure that we have an iTopDataProcessor
// @ts-ignore
editor.data.processor.setTransformedInitialValue( editor.getData());
});
}
init() {
}
static get pluginName() {
return 'DetectChanges';
}
}

View File

@@ -0,0 +1,50 @@
import {HtmlDataProcessor,
type ViewDocument,
type ViewDocumentFragment
} from 'ckeditor5/src/engine.js';
export default class iTopDataProcessor extends HtmlDataProcessor {
/**
* HTML data processor used to process HTML if we detect changes
* @private
*/
private _htmlDP: HtmlDataProcessor;
/**
* Initial value of the editor, we'll return it if we don't detect any changes
* @private
*/
private readonly _initialValue: string;
/**
* Transformed initial value of the editor, we'll use it to detect changes
* @private
*/
private _transformedInitialValue: string;
/**
* Creates a new instance of the Markdown data processor class.
*/
constructor( document: ViewDocument, initialValue: string, transformedInitialValue: string) {
super( document );
this._htmlDP = new HtmlDataProcessor( document );
this._initialValue = initialValue;
// It'll probably be empty on the first call, we'll set it later
this._transformedInitialValue = transformedInitialValue;
}
setTransformedInitialValue( transformedInitialValue: string ) {
this._transformedInitialValue = transformedInitialValue;
}
override toData( viewFragment: ViewDocumentFragment ): string {
const html = this._htmlDP.toData( viewFragment );
// TODO 3.2.0: How to use CombodoJSConsole here ?
console.debug('DataProcessor toData', html);
if( html === this._transformedInitialValue ) {
// TODO 3.2.0: How to use CombodoJSConsole here ?
console.debug('iTopDataProcessor: initialData detected, returning initial value');
return this._initialValue;
}
// TODO 3.2.0: How to use CombodoJSConsole here ?
console.debug('iTopDataProcessor: initialData not detected, returning transformed value');
return html;
}
}

View File

@@ -14,6 +14,7 @@ return array(
'AbstractPortalUIExtension' => $baseDir . '/application/applicationextension.inc.php',
'AbstractPreferencesExtension' => $baseDir . '/application/applicationextension.inc.php',
'AbstractWeeklyScheduledProcess' => $baseDir . '/core/backgroundprocess.inc.php',
'AbstractWelcomePopupExtension' => $baseDir . '/application/applicationextension.inc.php',
'Action' => $baseDir . '/core/action.class.inc.php',
'ActionChecker' => $baseDir . '/core/userrights.class.inc.php',
'ActionEmail' => $baseDir . '/core/action.class.inc.php',
@@ -38,6 +39,7 @@ return array(
'AttributeClass' => $baseDir . '/core/attributedef.class.inc.php',
'AttributeClassAttCodeSet' => $baseDir . '/core/attributedef.class.inc.php',
'AttributeClassState' => $baseDir . '/core/attributedef.class.inc.php',
'AttributeContextTagSet' => $baseDir . '/core/attributedef.class.inc.php',
'AttributeCustomFields' => $baseDir . '/core/attributedef.class.inc.php',
'AttributeDBField' => $baseDir . '/core/attributedef.class.inc.php',
'AttributeDBFieldVoid' => $baseDir . '/core/attributedef.class.inc.php',
@@ -389,6 +391,10 @@ return array(
'Combodo\\iTop\\Application\\WebPage\\iTopPDF' => $baseDir . '/sources/Application/WebPage/iTopPDF.php',
'Combodo\\iTop\\Application\\WebPage\\iTopWebPage' => $baseDir . '/sources/Application/WebPage/iTopWebPage.php',
'Combodo\\iTop\\Application\\WebPage\\iTopWizardWebPage' => $baseDir . '/sources/Application/WebPage/iTopWizardWebPage.php',
'Combodo\\iTop\\Application\\WelcomePopup\\Message' => $baseDir . '/sources/Application/WelcomePopup/Message.php',
'Combodo\\iTop\\Application\\WelcomePopup\\MessageFactory' => $baseDir . '/sources/Application/WelcomePopup/MessageFactory.php',
'Combodo\\iTop\\Application\\WelcomePopup\\Provider\\DefaultProvider' => $baseDir . '/sources/Application/WelcomePopup/Provider/DefaultProvider.php',
'Combodo\\iTop\\Application\\WelcomePopup\\WelcomePopupService' => $baseDir . '/sources/Application/WelcomePopup/WelcomePopupService.php',
'Combodo\\iTop\\Controller\\AbstractAppController' => $baseDir . '/sources/Controller/AbstractAppController.php',
'Combodo\\iTop\\Controller\\AbstractController' => $baseDir . '/sources/Controller/AbstractController.php',
'Combodo\\iTop\\Controller\\AjaxRenderController' => $baseDir . '/sources/Controller/AjaxRenderController.php',
@@ -401,6 +407,7 @@ return array(
'Combodo\\iTop\\Controller\\OAuth\\OAuthLandingController' => $baseDir . '/sources/Controller/OAuth/OAuthLandingController.php',
'Combodo\\iTop\\Controller\\PreferencesController' => $baseDir . '/sources/Controller/PreferencesController.php',
'Combodo\\iTop\\Controller\\TemporaryObjects\\TemporaryObjectController' => $baseDir . '/sources/Controller/TemporaryObjects/TemporaryObjectController.php',
'Combodo\\iTop\\Controller\\WelcomePopupController' => $baseDir . '/sources/Controller/WelcomePopupController.php',
'Combodo\\iTop\\Controller\\iController' => $baseDir . '/sources/Controller/iController.php',
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\IOAuthClientProvider' => $baseDir . '/sources/Core/Authentication/Client/OAuth/IOAuthClientProvider.php',
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderAbstract' => $baseDir . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAbstract.php',
@@ -417,7 +424,6 @@ return array(
'Combodo\\iTop\\Core\\Kpi\\KpiLogData' => $baseDir . '/sources/Core/Kpi/KpiLogData.php',
'Combodo\\iTop\\Core\\MetaModel\\FriendlyNameType' => $baseDir . '/sources/Core/MetaModel/FriendlyNameType.php',
'Combodo\\iTop\\Core\\MetaModel\\HierarchicalKey' => $baseDir . '/sources/Core/MetaModel/HierarchicalKey.php',
'Combodo\\iTop\\Core\\Trigger\\Enum\\SubscriptionPolicy' => $baseDir . '/sources/Core/Trigger/Enum/SubscriptionPolicy.php',
'Combodo\\iTop\\Dependencies\\AbstractFolderAnalyzer' => $baseDir . '/sources/Dependencies/AbstractFolderAnalyzer.php',
'Combodo\\iTop\\Dependencies\\Composer\\iTopComposer' => $baseDir . '/sources/Dependencies/Composer/iTopComposer.php',
'Combodo\\iTop\\Dependencies\\NPM\\iTopNPM' => $baseDir . '/sources/Dependencies/NPM/iTopNPM.php',
@@ -2051,7 +2057,6 @@ return array(
'Symfony\\Component\\Console\\Messenger\\RunCommandContext' => $vendorDir . '/symfony/console/Messenger/RunCommandContext.php',
'Symfony\\Component\\Console\\Messenger\\RunCommandMessage' => $vendorDir . '/symfony/console/Messenger/RunCommandMessage.php',
'Symfony\\Component\\Console\\Messenger\\RunCommandMessageHandler' => $vendorDir . '/symfony/console/Messenger/RunCommandMessageHandler.php',
'Symfony\\Component\\Console\\Output\\AnsiColorMode' => $vendorDir . '/symfony/console/Output/AnsiColorMode.php',
'Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Output/BufferedOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutput' => $vendorDir . '/symfony/console/Output/ConsoleOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => $vendorDir . '/symfony/console/Output/ConsoleOutputInterface.php',
@@ -2706,7 +2711,6 @@ return array(
'Symfony\\Component\\Routing\\RequestContext' => $vendorDir . '/symfony/routing/RequestContext.php',
'Symfony\\Component\\Routing\\RequestContextAwareInterface' => $vendorDir . '/symfony/routing/RequestContextAwareInterface.php',
'Symfony\\Component\\Routing\\Requirement\\EnumRequirement' => $vendorDir . '/symfony/routing/Requirement/EnumRequirement.php',
'Symfony\\Component\\Routing\\Requirement\\Requirement' => $vendorDir . '/symfony/routing/Requirement/Requirement.php',
'Symfony\\Component\\Routing\\Route' => $vendorDir . '/symfony/routing/Route.php',
'Symfony\\Component\\Routing\\RouteCollection' => $vendorDir . '/symfony/routing/RouteCollection.php',
'Symfony\\Component\\Routing\\RouteCompiler' => $vendorDir . '/symfony/routing/RouteCompiler.php',
@@ -3176,6 +3180,7 @@ return array(
'iTopOwnershipToken' => $baseDir . '/core/ownershiplock.class.inc.php',
'iTopStandardURLMaker' => $baseDir . '/application/applicationcontext.class.inc.php',
'iTopXmlException' => $baseDir . '/application/exceptions/iTopXmlException.php',
'iWelcomePopupExtension' => $baseDir . '/application/applicationextension.inc.php',
'iWorkingTimeComputer' => $baseDir . '/core/computing.inc.php',
'lnkAuditCategoryToAuditDomain' => $baseDir . '/application/audit.domain.class.inc.php',
'lnkTriggerAction' => $baseDir . '/core/trigger.class.inc.php',

View File

@@ -397,6 +397,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'AbstractPortalUIExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
'AbstractPreferencesExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
'AbstractWeeklyScheduledProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',
'AbstractWelcomePopupExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
'Action' => __DIR__ . '/../..' . '/core/action.class.inc.php',
'ActionChecker' => __DIR__ . '/../..' . '/core/userrights.class.inc.php',
'ActionEmail' => __DIR__ . '/../..' . '/core/action.class.inc.php',
@@ -421,6 +422,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'AttributeClass' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
'AttributeClassAttCodeSet' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
'AttributeClassState' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
'AttributeContextTagSet' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
'AttributeCustomFields' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
'AttributeDBField' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
'AttributeDBFieldVoid' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
@@ -772,6 +774,10 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Application\\WebPage\\iTopPDF' => __DIR__ . '/../..' . '/sources/Application/WebPage/iTopPDF.php',
'Combodo\\iTop\\Application\\WebPage\\iTopWebPage' => __DIR__ . '/../..' . '/sources/Application/WebPage/iTopWebPage.php',
'Combodo\\iTop\\Application\\WebPage\\iTopWizardWebPage' => __DIR__ . '/../..' . '/sources/Application/WebPage/iTopWizardWebPage.php',
'Combodo\\iTop\\Application\\WelcomePopup\\Message' => __DIR__ . '/../..' . '/sources/Application/WelcomePopup/Message.php',
'Combodo\\iTop\\Application\\WelcomePopup\\MessageFactory' => __DIR__ . '/../..' . '/sources/Application/WelcomePopup/MessageFactory.php',
'Combodo\\iTop\\Application\\WelcomePopup\\Provider\\DefaultProvider' => __DIR__ . '/../..' . '/sources/Application/WelcomePopup/Provider/DefaultProvider.php',
'Combodo\\iTop\\Application\\WelcomePopup\\WelcomePopupService' => __DIR__ . '/../..' . '/sources/Application/WelcomePopup/WelcomePopupService.php',
'Combodo\\iTop\\Controller\\AbstractAppController' => __DIR__ . '/../..' . '/sources/Controller/AbstractAppController.php',
'Combodo\\iTop\\Controller\\AbstractController' => __DIR__ . '/../..' . '/sources/Controller/AbstractController.php',
'Combodo\\iTop\\Controller\\AjaxRenderController' => __DIR__ . '/../..' . '/sources/Controller/AjaxRenderController.php',
@@ -784,6 +790,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Controller\\OAuth\\OAuthLandingController' => __DIR__ . '/../..' . '/sources/Controller/OAuth/OAuthLandingController.php',
'Combodo\\iTop\\Controller\\PreferencesController' => __DIR__ . '/../..' . '/sources/Controller/PreferencesController.php',
'Combodo\\iTop\\Controller\\TemporaryObjects\\TemporaryObjectController' => __DIR__ . '/../..' . '/sources/Controller/TemporaryObjects/TemporaryObjectController.php',
'Combodo\\iTop\\Controller\\WelcomePopupController' => __DIR__ . '/../..' . '/sources/Controller/WelcomePopupController.php',
'Combodo\\iTop\\Controller\\iController' => __DIR__ . '/../..' . '/sources/Controller/iController.php',
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\IOAuthClientProvider' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/OAuth/IOAuthClientProvider.php',
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderAbstract' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAbstract.php',
@@ -800,7 +807,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Core\\Kpi\\KpiLogData' => __DIR__ . '/../..' . '/sources/Core/Kpi/KpiLogData.php',
'Combodo\\iTop\\Core\\MetaModel\\FriendlyNameType' => __DIR__ . '/../..' . '/sources/Core/MetaModel/FriendlyNameType.php',
'Combodo\\iTop\\Core\\MetaModel\\HierarchicalKey' => __DIR__ . '/../..' . '/sources/Core/MetaModel/HierarchicalKey.php',
'Combodo\\iTop\\Core\\Trigger\\Enum\\SubscriptionPolicy' => __DIR__ . '/../..' . '/sources/Core/Trigger/Enum/SubscriptionPolicy.php',
'Combodo\\iTop\\Dependencies\\AbstractFolderAnalyzer' => __DIR__ . '/../..' . '/sources/Dependencies/AbstractFolderAnalyzer.php',
'Combodo\\iTop\\Dependencies\\Composer\\iTopComposer' => __DIR__ . '/../..' . '/sources/Dependencies/Composer/iTopComposer.php',
'Combodo\\iTop\\Dependencies\\NPM\\iTopNPM' => __DIR__ . '/../..' . '/sources/Dependencies/NPM/iTopNPM.php',
@@ -2434,7 +2440,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\Console\\Messenger\\RunCommandContext' => __DIR__ . '/..' . '/symfony/console/Messenger/RunCommandContext.php',
'Symfony\\Component\\Console\\Messenger\\RunCommandMessage' => __DIR__ . '/..' . '/symfony/console/Messenger/RunCommandMessage.php',
'Symfony\\Component\\Console\\Messenger\\RunCommandMessageHandler' => __DIR__ . '/..' . '/symfony/console/Messenger/RunCommandMessageHandler.php',
'Symfony\\Component\\Console\\Output\\AnsiColorMode' => __DIR__ . '/..' . '/symfony/console/Output/AnsiColorMode.php',
'Symfony\\Component\\Console\\Output\\BufferedOutput' => __DIR__ . '/..' . '/symfony/console/Output/BufferedOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutput' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleOutputInterface.php',
@@ -3089,7 +3094,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\Routing\\RequestContext' => __DIR__ . '/..' . '/symfony/routing/RequestContext.php',
'Symfony\\Component\\Routing\\RequestContextAwareInterface' => __DIR__ . '/..' . '/symfony/routing/RequestContextAwareInterface.php',
'Symfony\\Component\\Routing\\Requirement\\EnumRequirement' => __DIR__ . '/..' . '/symfony/routing/Requirement/EnumRequirement.php',
'Symfony\\Component\\Routing\\Requirement\\Requirement' => __DIR__ . '/..' . '/symfony/routing/Requirement/Requirement.php',
'Symfony\\Component\\Routing\\Route' => __DIR__ . '/..' . '/symfony/routing/Route.php',
'Symfony\\Component\\Routing\\RouteCollection' => __DIR__ . '/..' . '/symfony/routing/RouteCollection.php',
'Symfony\\Component\\Routing\\RouteCompiler' => __DIR__ . '/..' . '/symfony/routing/RouteCompiler.php',
@@ -3559,6 +3563,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'iTopOwnershipToken' => __DIR__ . '/../..' . '/core/ownershiplock.class.inc.php',
'iTopStandardURLMaker' => __DIR__ . '/../..' . '/application/applicationcontext.class.inc.php',
'iTopXmlException' => __DIR__ . '/../..' . '/application/exceptions/iTopXmlException.php',
'iWelcomePopupExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
'iWorkingTimeComputer' => __DIR__ . '/../..' . '/core/computing.inc.php',
'lnkAuditCategoryToAuditDomain' => __DIR__ . '/../..' . '/application/audit.domain.class.inc.php',
'lnkTriggerAction' => __DIR__ . '/../..' . '/core/trigger.class.inc.php',

View File

@@ -23,7 +23,9 @@ use Combodo\iTop\Application\WebPage\ErrorPage;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Controller\Base\Layout\ObjectController;
use Combodo\iTop\Controller\WelcomePopupController;
use Combodo\iTop\Service\Router\Router;
use Combodo\iTop\Application\WelcomePopup\WelcomePopupService;
/**
* Displays a popup welcome message, once per session at maximum
@@ -33,19 +35,19 @@ use Combodo\iTop\Service\Router\Router;
*
* @return void
*/
function DisplayWelcomePopup(WebPage $oP)
function DisplayWelcomePopup(WebPage $oP): void
{
if (!Session::IsSet('welcome'))
{
// Check, only once per session, if the popup should be displayed...
// If the user did not already ask for hiding it forever
$bPopup = appUserPreferences::GetPref('welcome_popup', true);
if ($bPopup)
{
TwigHelper::RenderIntoPage($oP, APPROOT.'/', 'templates/pages/backoffice/welcome_popup/welcome_popup');
Session::Set('welcome', 'ok');
if (!Session::IsSet("welcome")) {
$oWelcomePopupService = WelcomePopupService::GetInstance();
$aProvidersMessagesData = $oWelcomePopupService->GetMessages();
if (count($aProvidersMessagesData) > 0) {
TwigHelper::RenderIntoPage($oP, APPROOT."/", "templates/application/welcome_popup/layout", [
"aProvidersMessagesData" => $aProvidersMessagesData,
"sEndpointAbsURIForAcknowledgeMessage" => Router::GetInstance()->GenerateUrl(WelcomePopupController::ROUTE_NAMESPACE . ".acknowledge_message"),
]);
}
}
Session::Set("welcome", "ok"); // Try just once per session
}
}
/**
@@ -312,6 +314,8 @@ try
$oKPI = new ExecutionKPI();
$oContextGUI = new ContextTag(ContextTag::TAG_GUI);
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
$sLoginMessage = LoginWebPage::DoLogin(); // Check user rights and prompt if needed
$oAppContext = new ApplicationContext();

View File

@@ -19,6 +19,7 @@ use Combodo\iTop\Controller\AjaxRenderController;
use Combodo\iTop\Controller\Base\Layout\ActivityPanelController;
use Combodo\iTop\Controller\Base\Layout\ObjectController;
use Combodo\iTop\Controller\PreferencesController;
use Combodo\iTop\Controller\WelcomePopupController;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
use Combodo\iTop\Service\Router\Router;
@@ -1103,31 +1104,28 @@ EOF
$aUpdatedDecoded[] = $sDecodedProp;
}
$oDashlet->FromParams($aCurrentValues);
$sPrevClass = get_class($oDashlet);
$oDashlet = $oDashlet->Update($aValues, $aUpdatedDecoded);
$sNewClass = get_class($oDashlet);
if ($sNewClass != $sPrevClass) {
$oPage->add_ready_script("$('#dashlet_$sDashletId').dashlet('option', {dashlet_class: '$sNewClass'});");
}
if ($oDashlet->IsRedrawNeeded()) {
$oBlock = $oDashlet->DoRender($oPage, true, false, $aExtraParams);
$sHtml = ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
$sHtml = str_replace("\n", '', $sHtml);
$sHtml = str_replace("\r", '', $sHtml);
$sHtml = str_replace("'", "\'", $sHtml);
$oPage->add_script("$('#dashlet_$sDashletId').html('$sHtml');");
}
if ($oDashlet->IsFormRedrawNeeded()) {
$oForm = $oDashlet->GetForm(); // Rebuild the form since the values/content changed
$oForm->SetSubmitParams(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', array('operation' => 'update_dashlet_property', 'extra_params' => $aExtraParams));
$sHtml = addslashes($oForm->RenderAsPropertySheet($oPage, true, '.itop-dashboard'));
$sHtml = str_replace("\n", '', $sHtml);
$sHtml = str_replace("\r", '', $sHtml);
$oPage->add_script("$('#dashlet_properties_$sDashletId').html('$sHtml')");
}
$oDashlet->FromParams($aCurrentValues);
$sPrevClass = get_class($oDashlet);
$oDashlet = $oDashlet->Update($aValues, $aUpdatedDecoded);
$sNewClass = get_class($oDashlet);
if ($sNewClass != $sPrevClass) {
$oPage->add_ready_script("$('#dashlet_$sDashletId').dashlet('option', {dashlet_class: '$sNewClass'});");
}
break;
if ($oDashlet->IsRedrawNeeded()) {
$oBlock = $oDashlet->DoRender($oPage, true, false, $aExtraParams);
$sHtml = ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
$sHtml= json_encode($sHtml);
$oPage->add_script("$('#dashlet_$sDashletId').html({$sHtml});");
}
if ($oDashlet->IsFormRedrawNeeded()) {
$oForm = $oDashlet->GetForm(); // Rebuild the form since the values/content changed
$oForm->SetSubmitParams(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', array('operation' => 'update_dashlet_property', 'extra_params' => $aExtraParams));
$sHtml = $oForm->RenderAsPropertySheet($oPage, true, '.itop-dashboard');
$sHtml= json_encode($sHtml);
$oPage->add_script("$('#dashlet_$sDashletId').html({$sHtml});");
}
}
break;
case 'dashlet_creation_dlg':
$sOQL = utils::ReadParam('oql', '', false, 'raw_data');
@@ -2571,6 +2569,25 @@ EOF
$oPage = $oController->OperationModify();
break;
//--------------------------------
// WelcomePopupMenu
//--------------------------------
case 'welcome_popup.acknowledge_message':
$oPage = new JsonPage();
try {
$oController = new WelcomePopupController();
$oController->AcknowledgeMessage();
$aResult = ['success' => true];
}
catch (Exception $oException) {
$aResult = [
'success' => false,
'error_message' => $oException->getMessage(),
];
}
$oPage->SetData($aResult);
break;
default:
$oPage->p("Invalid query.");
}

View File

@@ -2421,14 +2421,14 @@ EOF
/**
* @param string $sPropertyName
* @param array $aProperty
* @param \DOMElement $oField
* @param DesignElement $oField
* @param array $aParameters
*
* @return array
* @throws \DOMFormatException
* @since 3.1.0 N°6040
*/
protected function CompileDynamicProperty(string $sPropertyName, array $aProperty, DOMElement $oField, array $aParameters): array
protected function CompileDynamicProperty(string $sPropertyName, array $aProperty, DesignElement $oField, array $aParameters): array
{
$sPHPParam = $aProperty['php_param'] ?? $sPropertyName;
$bMandatory = $aProperty['mandatory'] ?? false;
@@ -2471,6 +2471,34 @@ EOF
$aParameters[$sPHPParam] = 'null';
}
break;
case 'collection':
$sCollectionElementName = $aProperty['collection_element_name'] ?? null;
$sCollectionType = $aProperty['collection_type'] ?? null;
if (is_null($sCollectionElementName) || is_null($sCollectionType)) {
throw new DOMFormatException("Missing 'collection_element_name' or 'collection_type' in collection definition in meta", null, null, $oField);
}
$oValues = $oField->GetOptionalElement($sPropertyName);
if ($oValues) {
$oValuesNodes = $oValues->getElementsByTagName($sCollectionElementName);
$aValues = [];
/** @var \MFElement $oValueNode */
foreach ($oValuesNodes as $oValueNode) {
switch ($sCollectionType) {
case 'id':
$aValues[] = $oValueNode->GetAttribute('id');
break;
case 'text':
$aValues[] = $oValueNode->textContent;
break;
}
}
$aParameters[$sPHPParam] = var_export($aValues, true);
} elseif ($bMandatory) {
$aParameters[$sPHPParam] = var_export([$sDefault], true);
} else {
$aParameters[$sPHPParam] = 'null';
}
break;
case 'null':
$aParameters[$sPHPParam] = 'null';
break;
@@ -3995,6 +4023,10 @@ PHP;
$aDefinition['default'] = $oNode->GetText();
}
}
if (($aDefinition['type'] ?? null) === 'collection') {
$aDefinition['collection_element_name'] = $oProperty->GetChildText('collection_element_name');
$aDefinition['collection_type'] = $oProperty->GetChildText('collection_type');
}
return $aDefinition;
}

View File

@@ -1114,6 +1114,12 @@ class iTopDesignFormat
$this->RemoveNodeFromXPath('/itop_design/branding/main_favicon');
$this->RemoveNodeFromXPath('/itop_design/branding/portal_favicon');
$this->RemoveNodeFromXPath('/itop_design/branding/login_favicon');
// N°7423 - remove attributes Context Tag Set
$sPath = "/itop_design/classes/class/class/fields/field[@xsi:type='AttributeContextTagSet']";
$this->RemoveNodeFromXPath($sPath);
}
/**

View File

@@ -2591,7 +2591,13 @@ class WizStepDone extends WizardStep
$oProductionEnv->InitDataModel($oConfig, true);
$sIframeUrl = $oConfig->GetModuleSetting('itop-hub-connector', 'setup_url', '');
if ($sIframeUrl != '') {
$sSetupTokenFile = APPROOT.'data/.setup';
$sSetupToken = bin2hex(random_bytes(12));
file_put_contents($sSetupTokenFile, $sSetupToken);
$sIframeUrl.= "&setup_token=$sSetupToken";
if ($sIframeUrl != '')
{
$oPage->add('<iframe id="fresh_content" frameborder="0" scrolling="auto" src="'.$sIframeUrl.'"></iframe>');
$oPage->add_script("

View File

@@ -68,6 +68,9 @@ class RichText extends UIBlock
public function SetValue(?string $sValue)
{
$this->sValue = $sValue;
if(is_array($this->aConfig)) {
$this->aConfig['detectChanges'] = ['initialValue' => $sValue];
}
return $this;
}

View File

@@ -0,0 +1,194 @@
<?php
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\WelcomePopup;
use iWelcomePopupExtension;
use utils;
/**
* Class Message
*
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
* @package Combodo\iTop\Application\WelcomePopup
*/
class Message {
/** @var string Default TWIG template */
protected const DEFAULT_TWIG_TEMPLATE_REL_PATH = 'templates/application/welcome_popup/templates/left-title-description-right-illustration.html.twig';
/** @var string Unique ID of the message within its provider */
protected readonly string $sId;
/** @var int Importance of the message {@see \iWelcomePopupExtension::ENUM_IMPORTANCE_HIGH} and {@see \iWelcomePopupExtension::ENUM_IMPORTANCE_CRITICAL} */
protected int $iImportance;
/** @var string Title of the message in plain text */
protected string $sTitle;
/** @var string Description of the message, can contain HTML */
protected string $sDescription;
/** @var string|null Optional illustration to display with the description, should be an absolute URI (illustration can be on another server) */
protected null|string $sIllustrationAbsURI;
/** @var array Additional parameters to pass to {@see \Combodo\iTop\Application\WelcomePopup\Message::$sTWIGTemplateRelPath} */
protected array $aAdditionalParameters;
/** @var string|null TWIG template to use for the rendering of the message content (title, description, illustration) */
protected readonly null|string $sTWIGTemplateRelPath;
/**
* @param string $sId {@see \Combodo\iTop\Application\WelcomePopup\Message::$sId}
* @param string $sTitle {@see \Combodo\iTop\Application\WelcomePopup\Message::$sTitle}
* @param string $sDescription {@see \Combodo\iTop\Application\WelcomePopup\Message::$sDescription}
* @param string|null $sIllustrationAbsURI {@see \Combodo\iTop\Application\WelcomePopup\Message::$sIllustrationAbsURI}
* @param array $aAdditionalParameters {@see \Combodo\iTop\Application\WelcomePopup\Message::$aAdditionalParameters}
* @param int $iImportance {@see \Combodo\iTop\Application\WelcomePopup\Message::$iImportance}
* @param string|null $sTWIGTemplateRelPath {@see \Combodo\iTop\Application\WelcomePopup\Message::$sTWIGTemplateRelPath}
*/
public function __construct(string $sId, string $sTitle, string $sDescription, null|string $sIllustrationAbsURI = null, array $aAdditionalParameters = [], int $iImportance = iWelcomePopupExtension::DEFAULT_IMPORTANCE, null|string $sTWIGTemplateRelPath = null)
{
$this->sId = $sId;
$this->sTitle = $sTitle;
$this->sDescription = $sDescription;
$this->sIllustrationAbsURI = $sIllustrationAbsURI;
$this->aAdditionalParameters = $aAdditionalParameters;
$this->iImportance = $iImportance;
$this->sTWIGTemplateRelPath = $sTWIGTemplateRelPath ?? static::DEFAULT_TWIG_TEMPLATE_REL_PATH;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$sId
* @return string
*/
public function GetID(): string
{
return $this->sId;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$sDescription
* @return string
*/
public function GetTitle(): string
{
return $this->sTitle;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$sTitle
* @param string $sTitle
*
* @return static
*/
public function SetTitle(string $sTitle): static
{
$this->sTitle = $sTitle;
return $this;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$sDescription
* @return string
*/
public function GetDescription(): string
{
return $this->sDescription;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$sDescription
* @param string $sDescription
*
* @return static
*/
public function SetDescription(string $sDescription): static
{
$this->sDescription = $sDescription;
return $this;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$sIllustrationAbsURI
* @return string|null
*/
public function GetIllustrationAbsURI(): ?string
{
return $this->sIllustrationAbsURI;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$sIllustrationAbsURI
*
* @param string|null $sIllustrationAbsURI
*
* @return static
*/
public function SetIllustrationAbsURI(?string $sIllustrationAbsURI): static
{
$this->sIllustrationAbsURI = $sIllustrationAbsURI;
return $this;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::HasIllustration()
* @return bool
*/
public function HasIllustration(): bool
{
return utils::IsNotNullOrEmptyString($this->sIllustrationAbsURI);
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$aAdditionalParameters
* @return array
*/
public function GetAdditionalParameters(): array
{
return $this->aAdditionalParameters;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$aAdditionalParameters
*
* @param array $aAdditionalParameters
*
* @return static
*/
public function SetAdditionalParameters(array $aAdditionalParameters): static
{
$this->aAdditionalParameters = $aAdditionalParameters;
return $this;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$iImportance
* @return int
*/
public function GetImportance(): int
{
return $this->iImportance;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$iImportance
*
* @param int $iImportance
*
* @return static
*/
public function SetImportance(int $iImportance): static
{
$this->iImportance = $iImportance;
return $this;
}
/**
* @see \Combodo\iTop\Application\WelcomePopup\Message::$sTWIGTemplateRelPath
* @return string|null
*/
public function GetTWIGTemplateRelPath(): ?string
{
return $this->sTWIGTemplateRelPath;
}
}

View File

@@ -0,0 +1,92 @@
<?php
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\WelcomePopup;
use iWelcomePopupExtension;
/**
* Class MessageFactory
*
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
* @package Combodo\iTop\Application\WelcomePopup
* @api
*/
class MessageFactory {
/**
* @param string $sId Unique ID of the message within its provider
* @param string $sTitle Title of the message in plain text
* @param string $sDescription Description of the message, can contain HTML
* @param string|null $sIllustrationAbsURI Optional illustration to display with the description, should be an absolute URI (illustration can be on another server)
* @param int $iImportance Importance of the message {@see \iWelcomePopupExtension::ENUM_IMPORTANCE_HIGH} and {@see \iWelcomePopupExtension::ENUM_IMPORTANCE_CRITICAL}
*
* @api
* @return \Combodo\iTop\Application\WelcomePopup\Message Message with title / description on the left side, and an optional illustration on the right
*/
public static function MakeForLeftTextsRightIllustration(string $sId, string $sTitle, string $sDescription, null|string $sIllustrationAbsURI = null, int $iImportance = iWelcomePopupExtension::DEFAULT_IMPORTANCE): Message
{
return new Message(
$sId,
$sTitle,
$sDescription,
$sIllustrationAbsURI,
[],
$iImportance,
"templates/application/welcome_popup/templates/left-title-description-right-illustration.html.twig"
);
}
/**
* @param string $sId Unique ID of the message within its provider
* @param string $sTitle Title of the message in plain text
* @param string $sDescription Description of the message, can contain HTML
* @param string|null $sIllustrationAbsURI Optional illustration to display with the description, should be an absolute URI (illustration can be on another server)
* @param int $iImportance Importance of the message {@see \iWelcomePopupExtension::ENUM_IMPORTANCE_HIGH} and {@see \iWelcomePopupExtension::ENUM_IMPORTANCE_CRITICAL}
*
* @api
* @return \Combodo\iTop\Application\WelcomePopup\Message Message with title / description on the right side, and an optional illustration on the left
*/
public static function MakeForLeftIllustrationRightTexts(string $sId, string $sTitle, string $sDescription, null|string $sIllustrationAbsURI = null, int $iImportance = iWelcomePopupExtension::DEFAULT_IMPORTANCE): Message
{
return new Message(
$sId,
$sTitle,
$sDescription,
$sIllustrationAbsURI,
[],
$iImportance,
"templates/application/welcome_popup/templates/left-illustration-right-title-description.html.twig"
);
}
/**
* @param string $sId Unique ID of the message within its provider
* @param string $sTitle Title of the message in plain text
* @param string $sDescription Description of the message, can contain HTML
* @param string $sTWIGTemplateRelPath Rel. path (from app. root) to the TWIG template to use for the rendering of the message content
* @param string|null $sIllustrationAbsURI Optional illustration to display with the description, should be an absolute URI (illustration can be on another server)
* @param array $aAdditionalParameters Additional parameters to pass to the TWIG
* @param int $iImportance Importance of the message {@see \iWelcomePopupExtension::ENUM_IMPORTANCE_HIGH} and {@see \iWelcomePopupExtension::ENUM_IMPORTANCE_CRITICAL}
*
* @api
* @return \Combodo\iTop\Application\WelcomePopup\Message Message with title / description on the right side, and an optional illustration on the left
*/
public static function MakeForCustomTemplate(string $sId, string $sTitle, string $sDescription, string $sTWIGTemplateRelPath, null|string $sIllustrationAbsURI = null, array $aAdditionalParameters = [], int $iImportance = iWelcomePopupExtension::DEFAULT_IMPORTANCE): Message
{
return new Message(
$sId,
$sTitle,
$sDescription,
$sIllustrationAbsURI,
$aAdditionalParameters,
$iImportance,
$sTWIGTemplateRelPath
);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Application\WelcomePopup\Provider;
use Dict;
use AbstractWelcomePopupExtension;
use utils;
use Combodo\iTop\Application\WelcomePopup\MessageFactory;
/**
* Implementation of the "default" Welcome Popup message
* @since 3.2.0
*/
class DefaultProvider extends AbstractWelcomePopupExtension
{
/**
* @inheritDoc
*/
public function GetMessages(): array
{
return [
MessageFactory::MakeForLeftTextsRightIllustration(
"320_01",
Dict::S("UI:WelcomePopup:Message:320_01:Title"),
Dict::S("UI:WelcomePopup:Message:320_01:Description"),
utils::GetAbsoluteUrlAppRoot() . "images/illustrations/undraw_relaunch_day.svg"
),
];
}
}

View File

@@ -0,0 +1,255 @@
<?php
namespace Combodo\iTop\Application\WelcomePopup;
use AttributeDateTime;
use DBObjectSearch;
use DBObjectSet;
use Exception;
use IssueLog;
use LogChannels;
use MetaModel;
use UserRights;
use WelcomePopupAcknowledge;
use iWelcomePopupExtension;
use utils;
/**
* Handling of the messages displayed in the "Welcome Popup"
* @since 3.1.0
*
*/
class WelcomePopupService
{
private const PROVIDER_KEY_LENGTH = 128;
/** @var \Combodo\iTop\Application\WelcomePopup\WelcomePopupService|null Singleton instance */
protected static ?WelcomePopupService $oSingleton = null;
/** @var \Combodo\iTop\Application\WelcomePopup\Message[]|null Acknowledged messages for the current user */
protected static $aAcknowledgedMessages = null;
/** @var \iWelcomePopupExtension[]|null "Providers" of welcome popup messages */
protected $aMessagesProviders = null;
/**
* @internal
* @return $this The singleton instance of the service
*/
public static function GetInstance(): WelcomePopupService
{
if (null === static::$oSingleton) {
static::$oSingleton = new static();
}
return static::$oSingleton;
}
/**
* Helper function for usort to compare two items based on their 'importance' field
*
* @param array $aProviderMessageData1
* @param array $aProviderMessageData2
*
* @return int
*/
public static function SortOnImportance(array $aProviderMessageData1, array $aProviderMessageData2): int
{
if ($aProviderMessageData1['message']->GetImportance() === $aProviderMessageData2['message']->GetImportance()) {
return strcmp($aProviderMessageData1['message']->GetID(), $aProviderMessageData2['message']->GetID());
}
return ($aProviderMessageData1['message']->GetImportance() < $aProviderMessageData2['message']->GetImportance()) ? -1 : 1;
}
/**********************/
/* Non-static methods */
/**********************/
/**
* Singleton pattern, can't use the constructor. Use {@see \Combodo\iTop\Application\WelcomePopup\WelcomePopupService::GetInstance()} instead.
*
* @return void
*/
protected function __construct()
{
// Don't do anything, we don't want to be initialized
}
/**
* Get the list of {@see \Combodo\iTop\Application\WelcomePopup\Message} to display in the Welcome popup dialog
* @return \Combodo\iTop\Application\WelcomePopup\Message[]
*/
public function GetMessages(): array
{
$this->LoadProviders();
return $this->ProcessMessages();
}
/**
* Get the {@see \Combodo\iTop\Application\WelcomePopup\Message} to display from a list of {@see \iWelcomePopupExtension} instances
* The messages are ordered by importance ({@see \iWelcomePopupExtension::ENUM_IMPORTANCE_CRITICAL} first) then by ID
* Invalid messages or acknowledged messages are removed from the list
*
* @return array
*/
protected function ProcessMessages(): array
{
$this->LoadProviders();
/** @var array $aAllProvidersMessagesData */
$aAllProvidersMessagesData = [];
foreach($this->aMessagesProviders as $oProvider) {
$aProviderMessages = $oProvider->GetMessages();
if (count($aProviderMessages) === 0) {
IssueLog::Debug('Empty list of messages for '.$oProvider::class, LogChannels::CONSOLE);
continue;
}
$sProviderIconRelPath = $oProvider->GetIconRelPath();
foreach($aProviderMessages as $oMessage) {
if (false === ($oMessage instanceof Message)) {
IssueLog::Error('Invalid message returned by iWelcomePopupExtension::GetMessages(), must be of class ' . Message::class, LogChannels::CONSOLE, [
'provider_class' => $oProvider::class,
'message' => $oMessage,
]);
continue; // Fail silently
}
$aAllProvidersMessagesData[] = [
'uuid' => $this->MakeStringFitIn($oProvider::class, static::PROVIDER_KEY_LENGTH).'::'.$oMessage->GetID(),
'message' => $oMessage,
'provider_icon_rel_path' => $sProviderIconRelPath,
];
}
}
// Filter the acknowledged messages AFTER getting all messages
// This allows for "replacing" a message (from another provider for example)
// by automatically acknowledging it when called in GetMessages()
foreach($aAllProvidersMessagesData as $key => $aProviderMessageData) {
if ($this->IsMessageAcknowledged($aProviderMessageData['uuid'])) {
IssueLog::Debug('Ignoring already acknowledged message '.$aProviderMessageData['uuid'], LogChannels::CONSOLE);
unset($aAllProvidersMessagesData[$key]);
}
}
usort($aAllProvidersMessagesData, [static::class, 'SortOnImportance']);
return $aAllProvidersMessagesData;
}
/**
* Acknowledge a message (from a specific provider) for the current user, then notifies the provider (in case it wants to do some extra processing)
*
* @param string $sMessageUUID Format <PROVIDER_FQCN>::<MESSAGE_ID>
*
* @return void
* @throws \CoreException
*/
public function AcknowledgeMessage(string $sMessageUUID): void
{
$this->LoadProviders();
$oAcknowledge = MetaModel::NewObject(WelcomePopupAcknowledge::class, [
'message_uuid' => $sMessageUUID,
'acknowledge_date' => date(AttributeDateTime::GetSQLFormat()),
'user_id' => UserRights::GetConnectedUserId(),
]);
try {
$oAcknowledge->DBInsert();
$oProvider = $this->GetProviderByUUID($sMessageUUID);
if (static::$aAcknowledgedMessages !== null) {
static::$aAcknowledgedMessages[] = $sMessageUUID; // Update the cache
}
// Notify the provider of the message
$sMessageId = substr($sMessageUUID, strpos($sMessageUUID, '::') + 2);
if ($oProvider !== null) {
$oProvider->AcknowledgeMessage($sMessageId);
}
} catch(Exception $e) {
IssueLog::Error("Failed to acknowledge the message $sMessageUUID for user ".UserRights::GetConnectedUserId().". Reason: ".$e->getMessage(), LogChannels::CONSOLE);
}
}
/**
* Load the provider of messages, decoupled from the constructor for testability
*/
protected function LoadProviders(): void
{
if ($this->aMessagesProviders !== null) return;
$aProviders = [];
$aProviderClasses = utils::GetClassesForInterface(iWelcomePopupExtension::class, '', array('[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]'));
foreach($aProviderClasses as $sProviderClass) {
$aProviders[] = new $sProviderClass();
}
$this->SetMessagesProviders($aProviders);
}
/**
* Check if a given message was acknowledged by the current user
* @param string $sMessageId
* @return bool
*/
protected function IsMessageAcknowledged(string $sMessageUUID): bool
{
$iUserId = UserRights::GetConnectedUserId();
if (static::$aAcknowledgedMessages === null) {
$oSearch = new DBObjectSearch(WelcomePopupAcknowledge::class);
$oSearch->AddCondition('user_id', $iUserId);
$oSet = new DBObjectSet($oSearch);
$aAcknowledgedMessages = $oSet->GetColumnAsArray('message_uuid');
$this->SetAcknowledgedMessagesCache($aAcknowledgedMessages);
}
return in_array($sMessageUUID, static::$aAcknowledgedMessages);
}
/**
* Set the cache of acknowledged messages (useful for testing)
* @param array $aAcknowledgedMessages
*/
protected function SetAcknowledgedMessagesCache(array $aAcknowledgedMessages): void
{
static::$aAcknowledgedMessages = $aAcknowledgedMessages;
}
/**
* Set the cache of welcome popup message providers (useful for testing)
* @param iWelcomePopupExtension[] $aMessagesProviders
*/
protected function SetMessagesProviders(array $aMessagesProviders): void
{
$this->aMessagesProviders = $aMessagesProviders;
}
/**
* Retrieve the provider associated with a message
* @param string $sMessageUUID
* @return iWelcomePopupExtension|NULL
*/
protected function GetProviderByUUID(string $sMessageUUID): ?iWelcomePopupExtension
{
$this->LoadProviders();
$sProviderKey = substr($sMessageUUID, 0, strpos($sMessageUUID, '::'));
foreach($this->aMessagesProviders as $oProvider) {
if ($this->MakeStringFitIn($oProvider::class, static::PROVIDER_KEY_LENGTH) === $sProviderKey) {
return $oProvider;
}
}
return null;
}
/**
* Shorten the given string (if needed) but preserving its uniqueness
* @param string $sProviderClass
* @param int $iLengthLimit
* @return string
*/
protected function MakeStringFitIn(string $sProviderClass, int $iLengthLimit): string
{
if(mb_strlen($sProviderClass) <= $iLengthLimit) {
return $sProviderClass;
}
// Truncate the string to $iLimitLength and replace the first carahcters with the MD5 of the complete string
$sMD5 = md5($sProviderClass, false);
return $sMD5.'-'.mb_substr($sProviderClass, -($iLengthLimit - strlen($sMD5) - 1)); // strlen is OK on the MD5 string, and '-' is not allowed in a class name
}
}

View File

@@ -117,7 +117,7 @@ class AjaxRenderController
}
}
}
$sObjHighlightClass = $aObject[$sAlias]->GetHilightClass();
$sObjHighlightClass = MetaModel::GetHilightClass($sClass, $aObject[$sAlias]);
if (!empty($sObjHighlightClass)) {
$aObj['@class'] = 'ibo-is-'.$sObjHighlightClass;
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Combodo\iTop\Controller;
use Combodo\iTop\Application\WebPage\JsonPage;
use Combodo\iTop\Application\WelcomePopup\WelcomePopupService;
use Exception;
use utils;
/**
* Simple controller to acknowledge (via Ajax) welcome popup messages
* @since 3.2.0
*/
class WelcomePopupController extends AbstractController
{
/** @inheritDoc */
const ROUTE_NAMESPACE = "welcome_popup";
/**
* Acknowledge a specific message for the current user
* @return \Combodo\iTop\Application\WebPage\JsonPage
*/
public function OperationAcknowledgeMessage(): JsonPage
{
$oPage = new JsonPage();
$oPage->SetOutputDataOnly(true);
try {
$oService = WelcomePopupService::GetInstance();
$sMessageUUID = utils::ReadPostedParam('message_uuid', '', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
$oService->AcknowledgeMessage($sMessageUUID);
$aResult = ['success' => true];
}
catch (Exception $oException) {
$aResult = [
'success' => false,
'error_message' => $oException->getMessage(),
];
}
$oPage->SetData($aResult);
return $oPage;
}
}

View File

@@ -21,6 +21,7 @@
namespace Combodo\iTop\Form;
use Combodo\iTop\Renderer\FormRenderer;
use CoreException;
/**
* Description of formmanager
@@ -59,6 +60,12 @@ abstract class FormManager
$oFormManager = new static();
$sFormRendererClass = $aJson['formrenderer_class'];
// N°7455 - Ensure form renderer class extends FormRenderer
if (false === is_a($sFormRendererClass, FormRenderer::class, true))
{
throw new CoreException('Form renderer class must extend '.FormRenderer::class);
}
/** @var \Combodo\iTop\Renderer\FormRenderer $oFormRenderer */
$oFormRenderer = new $sFormRendererClass();
$oFormRenderer->SetEndpoint($aJson['formrenderer_endpoint']);

View File

@@ -173,14 +173,17 @@ EOF
// Some additional stuff if we are displaying it with a rich editor
if ($bRichEditor) {
$aConfig = CKEditorHelper::GetCkeditorPref();
$aConfig['extraPlugins'] = 'codesnippet';
// TODO 3.2.0 How to get a config for portal without mentions ?
// $aConfig = CKEditorHelper::GetCkeditorPref();
$aConfig = [];
$aConfig['detectChanges'] = ['initialValue' => $this->oField->GetCurrentValue()];
$sJsConfig = json_encode($aConfig);
$oOutput->AddJs(
<<<JS
$('#{$this->oField->GetGlobalId()}').addClass('htmlEditor');
CombodoCKEditorHandler.CreateInstance('#{$this->oField->GetGlobalId()}').then(( oEditor) => {
CombodoCKEditorHandler.CreateInstance('#{$this->oField->GetGlobalId()}', $sJsConfig).then(( oEditor) => {
oEditor.model.document.on('change:data', (event) => {
$('#{$this->oField->GetGlobalId()}').val(oEditor.getData()).trigger("change");

View File

@@ -0,0 +1,30 @@
<div id="ibo-welcome-popup--dialog" class="ibo-welcome-popup--dialog ibo-is-hidden"
data-role="ibo-welcome-popup--dialog"
data-title="{{ 'UI:WelcomeMenu:Title'|dict_s }}"
>
{% if aProvidersMessagesData|length > 1 %}
<ul class="ibo-welcome-popup--messages-stack">
{% for aProviderMessageData in aProvidersMessagesData %}
<li>
<a class="ibo-welcome-popup--stack-item {% if loop.index == 1 %}ibo-is-active{% endif %}"
data-role="ibo-welcome-popup--stack-item"
data-uuid="{{ aProviderMessageData.uuid }}"
href="#"
>
<div class="ibo-welcome-popup--stack-item-icon">
<img src="{{ get_absolute_url_app_root() ~ aProviderMessageData.provider_icon_rel_path }}" />
</div>
<div class="ibo-welcome-popup--stack-item-title" data-tooltip-content="{{ aProviderMessageData.message.GetTitle() }}">{{ aProviderMessageData.message.GetTitle() }}</div>
</a>
</li>
{% endfor %}
</ul>
{% endif %}
<div class="ibo-welcome-popup--message-content-wrapper">
{% for aProviderMessageData in aProvidersMessagesData %}
{% include aProviderMessageData.message.GetTWIGTemplateRelPath() with {'oMessage': aProviderMessageData.message, 'sUUID': aProviderMessageData.uuid, 'bIsActive': loop.index == 1} %}
{% endfor %}
</div>
</div>

View File

@@ -0,0 +1,93 @@
const oWelcomePopupDialogElem = $('#ibo-welcome-popup--dialog');
// Dialog is hidden by default to avoid a flash of unstyled content
oWelcomePopupDialogElem.removeClass('ibo-is-hidden');
// Prepare dialog
oWelcomePopupDialogElem.dialog({
modal: true,
width: '70%',
maxHeight: $(window).innerHeight() * 0.8,
autoOpen: true,
title: oWelcomePopupDialogElem.attr('data-title'),
open: function () {
// Focus on acknowledge button
oWelcomePopupDialogElem.closest('[role="dialog"]').find('.ui-dialog-buttonset .ibo-is-primary:first').trigger('focus');
},
close: function() {
oWelcomePopupDialogElem.remove();
},
buttons: [
{
text: "Remind me later",
class: 'ibo-is-alternative',
click: function() {
oWelcomePopupDialogElem.dialog( "close" );
}
},
{
text: "Got it",
class: 'ibo-is-regular ibo-is-primary',
click: function() {
oWelcomePopupDialogElem.trigger('acknowledge_message.itop.welcome_popup');
}
}
]
});
// Bind events
oWelcomePopupDialogElem
// - On stack item click, display active message
.on('click', '[data-role="ibo-welcome-popup--stack-item"]', function () {
const sUUID = $(this).attr('data-uuid');
const sUUIDEscapedForSelector = sUUID.replace(/\\/g, '\\\\');
// Display active stack item
oWelcomePopupDialogElem.find('[data-role="ibo-welcome-popup--stack-item"]').removeClass('ibo-is-active');
oWelcomePopupDialogElem.find('[data-role="ibo-welcome-popup--stack-item"][data-uuid="' + sUUIDEscapedForSelector + '"]').addClass('ibo-is-active');
// Display active content
oWelcomePopupDialogElem.find('[data-role="ibo-welcome-popup--message-content"]').removeClass('ibo-is-active');
oWelcomePopupDialogElem.find('[data-role="ibo-welcome-popup--message-content"][data-uuid="' + sUUIDEscapedForSelector + '"]').addClass('ibo-is-active');
})
.on('acknowledge_message.itop.welcome_popup', function (oEvent, oData) {
const sUUID = oData?.uuid ?? oWelcomePopupDialogElem.find('.ibo-is-active[data-role="ibo-welcome-popup--message-content"]').attr('data-uuid');
const sUUIDEscapedForSelector = sUUID.replace(/\\/g, '\\\\');
// Acknowledge message on server
$.post(
'{{ sEndpointAbsURIForAcknowledgeMessage }}',
{
message_uuid: sUUID
},
'json'
)
.done(function(oResponse) {
if (oResponse.success) {
// Mark message as acknowledged
oWelcomePopupDialogElem.find('[data-role="ibo-welcome-popup--stack-item"][data-uuid="' + sUUIDEscapedForSelector + '"]').addClass('ibo-is-acknowledged');
// Display next message if any
const oNextStackItemelem = oWelcomePopupDialogElem.find('[data-role="ibo-welcome-popup--stack-item"]:not(.ibo-is-acknowledged):first');
if (oNextStackItemelem.length > 0) {
oNextStackItemelem.trigger('click');
} else {
// Close dialog
oWelcomePopupDialogElem.dialog('close');
}
} else {
// Display error message
CombodoModal.OpenErrorModal(oResponse.error_message);
}
})
.fail(function(oXHR, sTextStatus, sErrorThrown) {
// Display error message
CombodoModal.OpenErrorModal(sErrorThrown);
});
});
// - Close the dialog when clicking outside of it
$('.ui-widget-overlay').on('click', function() { oWelcomePopupDialogElem.dialog('close'); } );

View File

@@ -0,0 +1,35 @@
<div class="ibo-welcome-popup--message-content
{% if bIsActive == true %}ibo-is-active{% endif %}
{% block wpMessageContentExtraCssClasses %}{% endblock %}"
data-role="ibo-welcome-popup--message-content"
data-uuid="{{ sUUID }}"
>
{% block wpMessageContentInner %}
{% block wpMessageTextsOuter %}
<div class="ibo-welcome-popup--message-texts">
{% block wpMessageTextsInner %}
{% block wpMessageTitleOuter %}
<h2 class="ibo-welcome-popup--message-title">
{% block wpMessageTitleInner %}
{{ oMessage.GetTitle() }}
{% endblock %}
</h2>
{% endblock %}
{% block wpMessageDescriptionOuter %}
<div class="ibo-welcome-popup--message-description ibo-is-html-content">
{% block wpMessageDescriptionInner %}
{# Mind that only description should have a "raw" filter as it can contains HTML #}
{{ oMessage.GetDescription()|raw }}
{% endblock %}
</div>
{% endblock %}
{% endblock %}
</div>
{% endblock %}
{% block wpMessageIllustrationOuter %}
{% if oMessage.HasIllustration() %}
<div class="ibo-welcome-popup--message-illustration" style="background-image: url('{{ oMessage.GetIllustrationAbsURI() }}')"></div>
{% endif %}
{% endblock %}
{% endblock %}
</div>

View File

@@ -0,0 +1,3 @@
{% extends 'templates/application/welcome_popup/templates/layout.html.twig' %}
{% block wpMessageContentExtraCssClasses %}{{ parent() }} ibo-is-illustration-on-left-side{% endblock %}

View File

@@ -0,0 +1,3 @@
{% extends 'templates/application/welcome_popup/templates/layout.html.twig' %}
{# Nothing there, it's exactly the default template. The file only exists to ease people understanding what the default layout is. #}

View File

@@ -1,14 +0,0 @@
<div id="welcome_popup">
<div class="ibo-welcome-popup--image ibo-svg-illustration--container">
{{ source("images/illustrations/undraw_relaunch_day.svg") }}
</div>
<div class="ibo-welcome-popup--text">
<div>
{{ 'UI:WelcomeMenu:Text'| dict_s|raw }}
</div>
<div class="ibo-welcome-popup--text--options">
<input type="checkbox" checked id="display_welcome_popup"/><label for="display_welcome_popup">{{'UI:DisplayThisMessageAtStartup'| dict_s}}</label>
</div>
</div>
</div>

View File

@@ -1,14 +0,0 @@
$('#welcome_popup').dialog( { width:'60%', height: 'auto', title: '{{ 'UI:WelcomeMenu:Title'|dict_s }}', autoOpen: true, modal:true,
close: function() {
var bDisplay = $('#display_welcome_popup:checked').length;
SetUserPreference('welcome_popup', bDisplay, true);
},
buttons: [{
text: "{{ 'UI:Button:Ok'|dict_s }}", click: function() {
$(this).dialog( "close" ); $(this).remove();
}}],
});
if ($('#welcome_popup').height() > ($(window).height()-70))
{
$('#welcome_popup').height($(window).height()-70);
}

View File

@@ -7,7 +7,7 @@
<div id="login-content">
<h1>{{ 'UI:ResetPwd-Title'|dict_s }}</h1>
{% if bNoUser %}
<p>{{ 'UI:ResetPwd-Error-WrongLogin'|dict_format(sAuthUser) }}</p>
<p>{{ 'UI:ResetPwd-EmailSent'|dict_s }}</p>
{% elseif bBadToken %}
<p>{{ 'UI:ResetPwd-Error-InvalidToken'|dict_s }}</p>
{% else %}

View File

@@ -8,7 +8,7 @@
<div id="login-title">
<h1>{{ 'UI:ResetPwd-Title'|dict_s }}</h1>
{% if bNoUser and sErrorMessage is null %}
<p>{{ 'UI:ResetPwd-Error-WrongLogin'|dict_format(sAuthUser) }}</p>
<p>{{ 'UI:ResetPwd-EmailSent'|dict_s }}</p>
{% elseif bBadToken and sErrorMessage is null %}
<p>{{ 'UI:ResetPwd-Error-InvalidToken'|dict_s }}</p>
{% else %}

View File

@@ -4,6 +4,9 @@
"sempro/phpunit-pretty-print": "^1.4"
},
"autoload": {
"classmap": [
"unitary-tests/"
],
"psr-4": {
"Combodo\\iTop\\Test\\UnitTest\\": "src/BaseTestCase/",
"Combodo\\iTop\\Test\\UnitTest\\Hook\\": "src/Hook/",

View File

@@ -9,9 +9,11 @@ namespace Combodo\iTop\Test\UnitTest\Service;
use Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase;
use IssueLog;
use LogChannels;
use MFCoreModule;
use ReflectionClass;
use RunTimeEnvironment;
use utils;
/**
@@ -33,12 +35,15 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
/** @var string[] $aDeltaFiles Referential of loaded deltas. Mostly to avoid duplicates. */
$aDeltaFiles = [];
foreach (get_declared_classes() as $sClass) {
// Filter on classes derived from this \Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCaseItopCustomDatamodelTestCase
if (false === is_a($sClass, ItopCustomDatamodelTestCase::class, true)) {
continue;
}
$aRelatedClasses = $this->GetClassesExtending(
ItopCustomDatamodelTestCase::class,
array(
'[\\\\/]tests[\\\\/]php-unit-tests[\\\\/]vendor[\\\\/]',
'[\\\\/]tests[\\\\/]php-unit-tests[\\\\/]unitary-tests[\\\\/]datamodels[\\\\/]2.x[\\\\/]authent-local',
));
//Combodo\iTop\Test\UnitTest\Application\ApplicationExtensionTest
//Combodo\iTop\Test\UnitTest\Application\ApplicationExtensionTest
foreach ($aRelatedClasses as $sClass) {
$oReflectionClass = new ReflectionClass($sClass);
$oReflectionMethod = $oReflectionClass->getMethod('GetDatamodelDeltaAbsPath');
@@ -83,4 +88,50 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
return $aRet;
}
protected function GetClassesExtending (string $sExtendedClass, array $aExcludedPath = []) : array {
$aMatchingClasses = [];
$aAutoloadClassMaps =[__DIR__."/../../vendor/composer/autoload_classmap.php"];
$aClassMap = [];
$aAutoloaderErrors = [];
foreach ($aAutoloadClassMaps as $sAutoloadFile) {
$aTmpClassMap = include $sAutoloadFile;
/** @noinspection SlowArrayOperationsInLoopInspection we are getting an associative array so the documented workarounds cannot be used */
$aClassMap = array_merge($aClassMap, $aTmpClassMap);
}
foreach ($aClassMap as $sPHPClass => $sPHPFile) {
$bSkipped = false;
if (utils::IsNotNullOrEmptyString($sPHPFile)) {
$sPHPFile = utils::LocalPath($sPHPFile);
if ($sPHPFile !== false) {
$sPHPFile = '/'.$sPHPFile; // for regex
foreach ($aExcludedPath as $sExcludedPath) {
// Note: We use '#' as delimiters as usual '/' is often used in paths.
if ($sExcludedPath !== '' && preg_match('#'.$sExcludedPath.'#', $sPHPFile) === 1) {
$bSkipped = true;
break;
}
}
} else {
$bSkipped = true; // file not found
}
}
if (!$bSkipped) {
try {
$oRefClass = new ReflectionClass($sPHPClass);
if ($oRefClass->isSubclassOf($sExtendedClass) &&
!$oRefClass->isInterface() && !$oRefClass->isAbstract() && !$oRefClass->isTrait()) {
$aMatchingClasses[] = $sPHPClass;
}
}
catch (Exception $e) {
}
}
}
return $aMatchingClasses;
}
}

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