Merge branch 'develop' into SessionManagement

This commit is contained in:
Eric
2021-08-26 10:28:43 +02:00
31 changed files with 463 additions and 205 deletions

View File

@@ -270,6 +270,8 @@ class DisplayBlock
'panel_title',
/** string class for panel block style */
'panel_class',
/** string class for panel block style */
'panel_icon',
];
if (isset($aAllowedParams[$sStyle])) {
@@ -1196,6 +1198,9 @@ JS
$sTitle = Dict::Format($sFormat, $iTotalCount);
$oBlock = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
$oBlock->AddSubTitleBlock(new Html($sTitle));
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
$oBlock->SetIcon($aExtraParams["panel_icon"]);
}
$oDataTable = DataTableUIBlockFactory::MakeForStaticData("", $aAttribs, $aData, null, $aExtraParams, $this->m_oFilter->ToOQL(), $aOption);
$oBlock->AddSubBlock($oDataTable);
} else {
@@ -1212,6 +1217,9 @@ JS
}
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
$oBlock = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
$oBlock->SetIcon($aExtraParams["panel_icon"]);
}
$oBlock->AddSubBlock(new Html('<p>'.Dict::Format($sFormat, $iCount).'</p>'));
} else {
$oBlock = new Html('<p>'.Dict::Format($sFormat, $iCount).'</p>');
@@ -1347,6 +1355,9 @@ JS
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
$oPanel = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
$oPanel->SetIcon($aExtraParams["panel_icon"]);
}
$oPanel->AddSubBlock($oBlock);
return $oPanel;
@@ -1544,6 +1555,9 @@ JS
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
$oPanel = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
$oPanel->SetIcon($aExtraParams["panel_icon"]);
}
$oPanel->AddSubBlock($oBlock);
return $oPanel;
@@ -1632,6 +1646,9 @@ JS
}
if (isset($aExtraParams["surround_with_panel"]) && $aExtraParams["surround_with_panel"]) {
$oPanel = PanelUIBlockFactory::MakeForClass($aExtraParams["panel_class"], $aExtraParams["panel_title"]);
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
$oPanel->SetIcon($aExtraParams["panel_icon"]);
}
$oPanel->AddSubBlock($oBlock);
return $oPanel;

View File

@@ -464,7 +464,7 @@ class DisplayableNode extends GraphNode
{
$aRootCauses[] = $oRootCause->GetHyperlink();
}
$sHtml .= '<p><img style="max-height: 24px; vertical-align:bottom;" src="'.utils::GetAbsoluteUrlModulesRoot().$aContext['icon'].'" title="'.htmlentities(Dict::S($aContext['dict'])).'">&nbsp;'.implode(', ', $aRootCauses).'</p>';
$sHtml .= '<p><img style="max-height: 24px; vertical-align:bottom;" class="ibo-class-icon ibo-is-small" src="'.utils::GetAbsoluteUrlModulesRoot().$aContext['icon'].'" title="'.htmlentities(Dict::S($aContext['dict'])).'">&nbsp;'.implode(', ', $aRootCauses).'</p>';
}
$sHtml .= '<hr/>';
}
@@ -805,7 +805,7 @@ class DisplayableGroupNode extends DisplayableNode
$sHtml .= '<a href="#" onclick="$(\'.itop-simple-graph\').simple_graph(\'show_group\', \'relation_group_'.$iGroupIdx.'\');">'.Dict::Format('UI:RelationGroupNumber_N', (1+$iGroupIdx))."</a>";
$sHtml .= '<hr/>';
$sHtml .= '<table><tbody><tr>';
$sHtml .= '<td style="vertical-align:top;padding-right: 0.5em;"><img src="'.$this->GetProperty('icon_url').'"></td><td style="vertical-align:top">'.MetaModel::GetName($this->GetObjectClass()).'<br/>';
$sHtml .= '<td style="vertical-align:top;padding-right: 0.5em;"><img class="ibo-class-icon ibo-is-small" src="'.$this->GetProperty('icon_url').'"></td><td style="vertical-align:top">'.MetaModel::GetName($this->GetObjectClass()).'<br/>';
$sHtml .= Dict::Format('UI_CountOfObjectsShort', $this->GetObjectCount()).'</td>';
$sHtml .= '</tr></tbody></table>';
return $sHtml;

View File

@@ -894,25 +894,23 @@ $ibo-search-results-area--datatable-scrollhead--border--is-sticking: $ibo-search
border-bottom-color: transparent;
}
}
.sf_results_area {
.ibo-datatable-panel.ibo-is-sticking {
.ibo-panel--header {
z-index: 0;
}
.ibo-datatable--toolbar {
position: fixed;
z-index: 2;
padding-bottom: 4px;
background-color: $ibo-search-results-area--datatable-toolbar--background-color--is-sticking;
border-left: $ibo-search-results-area--datatable-toolbar--border--is-sticking;
border-right: $ibo-search-results-area--datatable-toolbar--border--is-sticking;
}
.dataTables_scrollHead {
position: fixed !important; /* Important is required as the property is already set in the style attribute by the JS lib */
z-index: 2;
background-color: $ibo-search-results-area--datatable-scrollhead--background-color--is-sticking;
border-left: $ibo-search-results-area--datatable-scrollhead--border--is-sticking !important; /* Unfortunately the !important is necessary to overload the lib style attribute */
border-right: $ibo-search-results-area--datatable-scrollhead--border--is-sticking !important; /* Unfortunately the !important is necessary to overload the lib style attribute */
}
.ibo-datatable-panel.ibo-is-sticking {
.ibo-panel--header {
z-index: 0;
}
.ibo-datatable--toolbar {
position: fixed;
z-index: 2;
padding-bottom: 4px;
background-color: $ibo-search-results-area--datatable-toolbar--background-color--is-sticking;
border-left: $ibo-search-results-area--datatable-toolbar--border--is-sticking;
border-right: $ibo-search-results-area--datatable-toolbar--border--is-sticking;
}
.dataTables_scrollHead {
position: fixed !important; /* Important is required as the property is already set in the style attribute by the JS lib */
z-index: 2;
background-color: $ibo-search-results-area--datatable-scrollhead--background-color--is-sticking;
border-left: $ibo-search-results-area--datatable-scrollhead--border--is-sticking !important; /* Unfortunately the !important is necessary to overload the lib style attribute */
border-right: $ibo-search-results-area--datatable-scrollhead--border--is-sticking !important; /* Unfortunately the !important is necessary to overload the lib style attribute */
}
}

View File

@@ -165,7 +165,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
}
.selectize-dropdown {
z-index: 2000; /* Note: This is not great as it does not take into account other elements z-index, but as selectize puts its dropdown under the <body> tag, we cannot have a z-index relative to input container */
z-index: 2000 !important; /* Note: This is not great as it does not take into account other elements z-index, but as selectize puts its dropdown under the <body> tag, we cannot have a z-index relative to input container. "!important" is necessary to overload the default selectize CSS rule 😕 */
max-height: $ibo-input-select-selectize--dropdown--max-height;
overflow-y: auto;
}

View File

@@ -94,6 +94,7 @@ $ibo-activity-panel--load-all-entries--is-hover--margin-left: ($ibo-activity-pan
/* Current or not user specificities */
&.ibo-is-current-user{
flex-direction: row-reverse;
min-width: max-content;
.ibo-activity-entry--medallion{
margin-right: initial;

View File

@@ -65,7 +65,7 @@ $ibo-tab--temporary-remote-content--button--hover--color: $ibo-color-grey-200 !d
color: $ibo-tab-container--tab-header--text-color;
&:hover {
&:hover:not(.ui-state-disabled) {
color: $ibo-tab-container--tab-header--text-color--on-hover;
background-color: $ibo-tab-container--tab-header--background-color--on-hover;
}

View File

@@ -10,6 +10,7 @@ $ibo-simple-graph--grouping-threshold-additional-context--container--margin-righ
$ibo-simple-graph--grouping-threshold-additional-context--content--margin-right: 1em !default;
$ibo-impact-analysis--graph-zoom-slider--width: 10em !default;
$ibo-impact-analysis--impacted-objects-lists--elements-spacing: 24px !default;
$ibo-display-graph--search-box--criterion--content--padding-y: 0 !default;
$ibo-display-graph--search-box--criterion--content--padding-x: 15px !default;
@@ -108,4 +109,12 @@ $ibo-display-graph--search-box--criterion--content--checkbox--margin-right: 10px
#ReloadMovieBtn {
align-self: flex-end;
}
}
}
#impacted_objects_lists{
> div ~ div{
margin-top: $ibo-impact-analysis--impacted-objects-lists--elements-spacing;
}
}
#impacted_objects_lists_placeholder, #impacted_groups_placeholder{
height: 250px;
}

View File

@@ -23,3 +23,4 @@
@import "font-icon";
@import "typography";
@import "misc";
@import "class-icon";

View File

@@ -0,0 +1,17 @@
.ibo-class-icon{
&.ibo-is-small{
width: 32px;
min-width: 32px;
max-height: 32px;
}
&.ibo-is-medium{
width: 48px;
min-width: 48px;
max-height: 48px;
}
&.ibo-is-large{
width: 64px;
min-width: 64px;
max-height: 64px;
}
}

View File

@@ -599,4 +599,9 @@ $ibo-vendors-jqueryui--ui-slider--ui-slider-handle--hover--border-color: $ibo-co
padding: 0;
position: absolute;
width: 1px;
}
// Tabs
.ui-tabs-tab.ui-state-disabled a{
cursor: not-allowed !important;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -4,7 +4,7 @@
<name>Bearbeiter des Tickets</name>
<description>Kann in Benachrichtigungen genutzt werden, um den Bearbeiter des Tickets zu verständigen.</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id=:this-&gt;agent_id</oql>
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -14,7 +14,7 @@
Es wird keine E-Mail gesendet, wenn die auslösende Person der Benachrichtigung der Bearbeiter des Tickets ist.
</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id=:this-&gt;agent_id AND id != :current_contact_id</oql>
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id AND id != :current_contact_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -22,10 +22,10 @@
<name>Melder und Kontaktliste des Tickets</name>
<description>Kann in Benachrichtigungen verwendet werden, um den Melder und alle verknüpften Kontakte eines Tickets zu verständigen.</description>
<is_template>yes</is_template>
<oql>SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this-&gt;id
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this->id
UNION
SELECT Person WHERE id=:this-&gt;caller_id
</oql>
SELECT Person WHERE id=:this->caller_id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -33,7 +33,7 @@
<name>Melder des Tickets</name>
<description>Kann in Benachrichtigungen verwendet werden, um den Melder zu verständigen.</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id=:this-&gt;caller_id</oql>
<oql><![CDATA[SELECT Person WHERE id=:this->caller_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -41,7 +41,7 @@
<name>Kontaktliste des Tickets</name>
<description>Kann in Benachrichtigungen verwendet werden, um alle verknüpften Kontakte eines Tickets zu verständigen</description>
<is_template>yes</is_template>
<oql>SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this-&gt;id</oql>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this->id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -49,7 +49,7 @@
<name>Manager des Ticketmelders</name>
<description>Kann in Benachrichtigungen verwendet werden, um den Manager des Melders eines Tickets zu verständigen.</description>
<is_template>yes</is_template>
<oql>SELECT Person AS manager JOIN Person AS employee ON employee.manager_id = manager.id WHERE employee.id=:this-&gt;caller_id</oql>
<oql><![CDATA[SELECT Person AS manager JOIN Person AS employee ON employee.manager_id = manager.id WHERE employee.id=:this->caller_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -59,7 +59,7 @@
Wird dieser Befehl allein ausgelöst, wird die Person zurückgegeben, die mit dem angemeldeten Benutzer verknüpft ist, der diesen Befehl ausführt.
</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id = :current_contact_id</oql>
<oql><![CDATA[SELECT Person WHERE id = :current_contact_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -67,9 +67,9 @@
<name>Teammitglieder des Tickets</name>
<description>Kann in Benachrichtigungen verwendet werden, um den alle Mitglieder des Teams zu verständigen, an das das Ticket verteilt ist.</description>
<is_template>yes</is_template>
<oql>SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this-&gt;team_id
</oql>
<oql><![CDATA[SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this->team_id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -79,9 +79,9 @@
Der Bearbeiter des Tickets ist aus dieser Liste ausgeschlossen.
</description>
<is_template>yes</is_template>
<oql>SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this-&gt;team_id AND P.id != :this-&gt;agent_id
</oql>
<oql><![CDATA[SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this->team_id AND P.id != :this->agent_id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -89,7 +89,37 @@
<name>Team des Tickets</name>
<description>Kann in Benachrichtigungen verwendet werden, um das Team, an das das Ticket verteilt ist, über eine hinterlegte Team-Mail-Ad­res­se zu benachrichtigen.</description>
<is_template>yes</is_template>
<oql>SELECT Team WHERE id = :this-&gt;team_id</oql>
<oql><![CDATA[SELECT Team WHERE id = :this->team_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
<QueryOQL alias="QueryOQL" id="11">
<name>Kontaktliste eines Funktionales CI</name>
<description>Kann in Benachrichtigungen verwendet werden, um alle verknüpften Kontakte eines Funktionales CI zu verständigen</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToFunctionalCI AS L ON L.contact_id=C.id
WHERE L.functionalci_id = :this->id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
<QueryOQL alias="QueryOQL" id="12">
<name>Kontaktliste eines Dienstes</name>
<description>Kann in Benachrichtigungen verwendet werden, um alle verknüpften Kontakte eines Dienstes zu verständigen</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToService AS L ON L.contact_id=C.id
WHERE L.service_id = :this->id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
<QueryOQL alias="QueryOQL" id="13">
<name>Kontaktliste eines Vertrages</name>
<description>Kann in Benachrichtigungen verwendet werden, um alle verknüpften Kontakte eines Vertrages zu verständigen</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToContract AS L ON L.contact_id=C.id
WHERE L.contract_id = :this->id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>

View File

@@ -4,7 +4,7 @@
<name>Agent of the Ticket</name>
<description>Can be used in Notification, to notify the agent of a Ticket.</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id=:this-&gt;agent_id</oql>
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -14,7 +14,7 @@
No email will be send if the person who triggered that notification is the agent himself.
</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id=:this-&gt;agent_id AND id != :current_contact_id</oql>
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id AND id != :current_contact_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -22,10 +22,10 @@
<name>Caller and Contacts linked to the Ticket</name>
<description>Can be used in Notification, to notify the caller and all contacts associated to a Ticket</description>
<is_template>yes</is_template>
<oql>SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this-&gt;id
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this->id
UNION
SELECT Person WHERE id=:this-&gt;caller_id
</oql>
SELECT Person WHERE id=:this->caller_id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -33,7 +33,7 @@
<name>Caller of the Ticket</name>
<description>To be used in Notification, to notify the caller of a Ticket</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id=:this-&gt;caller_id</oql>
<oql><![CDATA[SELECT Person WHERE id=:this->caller_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -41,7 +41,7 @@
<name>Contacts linked to the Ticket</name>
<description>Can be used in Notification, to notify contacts associated to a Ticket</description>
<is_template>yes</is_template>
<oql>SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this-&gt;id</oql>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this->id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -49,7 +49,7 @@
<name>Manager of the Ticket caller</name>
<description>Can be used in Ticket Notification, to notify the manager of the caller.</description>
<is_template>yes</is_template>
<oql>SELECT Person AS manager JOIN Person AS employee ON employee.manager_id = manager.id WHERE employee.id=:this-&gt;caller_id</oql>
<oql><![CDATA[SELECT Person AS manager JOIN Person AS employee ON employee.manager_id = manager.id WHERE employee.id=:this->caller_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -59,7 +59,7 @@
If used alone, it returns the person connected to iTop and running that query.
</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id = :current_contact_id</oql>
<oql><![CDATA[SELECT Person WHERE id = :current_contact_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -67,9 +67,9 @@
<name>Team members of the Ticket</name>
<description>Can be used in Notification, to notify the team members, to which the Ticket was dispatched.</description>
<is_template>yes</is_template>
<oql>SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this-&gt;team_id
</oql>
<oql><![CDATA[SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this->team_id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -79,9 +79,9 @@
The agent himself is excluded from that list.
</description>
<is_template>yes</is_template>
<oql>SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this-&gt;team_id AND P.id != :this-&gt;agent_id
</oql>
<oql><![CDATA[SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this->team_id AND P.id != :this->agent_id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -89,7 +89,37 @@
<name>Team of the Ticket</name>
<description>Can be used in Notification, to notify the team generic email, to which the Ticket was dispatched.</description>
<is_template>yes</is_template>
<oql>SELECT Team WHERE id = :this-&gt;team_id</oql>
<oql><![CDATA[SELECT Team WHERE id = :this->team_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
<QueryOQL alias="QueryOQL" id="11">
<name>Contacts of a Functional CI</name>
<description>Can be used in Notification, to notify the Contacts linked to the Functional CI.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToFunctionalCI AS L ON L.contact_id=C.id
WHERE L.functionalci_id = :this->id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
<QueryOQL alias="QueryOQL" id="12">
<name>Contacts of a Service</name>
<description>Can be used in Notification, to notify the Contacts linked to the Service.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToService AS L ON L.contact_id=C.id
WHERE L.service_id = :this->id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
<QueryOQL alias="QueryOQL" id="13">
<name>Contacts of a Contract</name>
<description>Can be used in Notification, to notify the Contacts linked to the Contract.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToContract AS L ON L.contact_id=C.id
WHERE L.contract_id = :this->id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>

View File

@@ -4,7 +4,7 @@
<name>L'agent du ticket</name>
<description>Utilisable dans les notifications, pour informer l'agent en charge du ticket.</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id=:this-&gt;agent_id</oql>
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -13,7 +13,7 @@
<description>Utilisable dans les notifications, pour informer l'agent en charge du ticket, sauf si c'est l'agent lui-même qui déclenche la notification
</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id=:this-&gt;agent_id AND id != :current_contact_id</oql>
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id AND id != :current_contact_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -21,9 +21,9 @@
<name>Le demandeur et les contacts liés au Ticket</name>
<description>Utilisable dans les notifications, pour informer le demandeur ainsi que tout les contacts liés au ticket</description>
<is_template>yes</is_template>
<oql>SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this-&gt;id
UNION SELECT Person WHERE id=:this-&gt;caller_id
</oql>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this->id
UNION SELECT Person WHERE id=:this->caller_id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -31,7 +31,7 @@
<name>Le demandeur du Ticket</name>
<description>Utilisable dans les notifications, pour informer le demandeur du ticket</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id=:this-&gt;caller_id</oql>
<oql><![CDATA[SELECT Person WHERE id=:this->caller_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -39,7 +39,7 @@
<name>Les contacts liés au Ticket</name>
<description>Utilisable dans les notifications, pour informer tout les contacts liés au ticket</description>
<is_template>yes</is_template>
<oql>SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this-&gt;id</oql>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this->id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -47,7 +47,7 @@
<name>Le manager du demandeur</name>
<description>Utilisable dans les notifications, pour informer le manager du demandeur d'un Ticket</description>
<is_template>yes</is_template>
<oql>SELECT Person AS manager JOIN Person AS employee ON employee.manager_id = manager.id WHERE employee.id=:this-&gt;caller_id</oql>
<oql><![CDATA[SELECT Person AS manager JOIN Person AS employee ON employee.manager_id = manager.id WHERE employee.id=:this->caller_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -57,7 +57,7 @@
Utilisée seule, cette requête retourne la personne liée à l'utilisateur iTop qui l'execute.
</description>
<is_template>yes</is_template>
<oql>SELECT Person WHERE id = :current_contact_id</oql>
<oql><![CDATA[SELECT Person WHERE id = :current_contact_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -65,9 +65,9 @@
<name>Les membres de l'équipe en charge du Ticket</name>
<description>Utilisable dans les notifications, pour informer les membres de l'équipe en charge du ticket.</description>
<is_template>yes</is_template>
<oql>SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this-&gt;team_id
</oql>
<oql><![CDATA[SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this->team_id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -77,9 +77,9 @@
L'agent lui-même est exclus de cette liste.
</description>
<is_template>yes</is_template>
<oql>SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this-&gt;team_id AND P.id != :this-&gt;agent_id
</oql>
<oql><![CDATA[SELECT Person AS P JOIN lnkPersonToTeam AS L ON L.person_id=P.id
WHERE L.team_id = :this->team_id AND P.id != :this->agent_id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
@@ -87,7 +87,37 @@
<name>L'équipe du Ticket</name>
<description>Utilisable dans les notifications, pour informer l'équipe en charge du ticket, via son email générique.</description>
<is_template>yes</is_template>
<oql>SELECT Team WHERE id = :this-&gt;team_id</oql>
<oql><![CDATA[SELECT Team WHERE id = :this->team_id]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
<QueryOQL alias="QueryOQL" id="11">
<name>Les contacts d'un CI fonctionnel</name>
<description>Utilisable dans les notifications, pour informer les contacts liés au CI fonctionnel courant.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToFunctionalCI AS L ON L.contact_id=C.id
WHERE L.functionalci_id = :this->id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
<QueryOQL alias="QueryOQL" id="12">
<name>Les contacts d'un Service</name>
<description>Utilisable dans les notifications, pour informer les contacts liés au Service courant.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToService AS L ON L.contact_id=C.id
WHERE L.service_id = :this->id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>
<QueryOQL alias="QueryOQL" id="13">
<name>Les contacts d'un Contrat</name>
<description>Utilisable dans les notifications, pour informer les contacts liés au Contrat courant.</description>
<is_template>yes</is_template>
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToContract AS L ON L.contact_id=C.id
WHERE L.contract_id = :this->id
]]></oql>
<fields>id,email</fields>
<finalclass>QueryOQL</finalclass>
</QueryOQL>

View File

@@ -133,7 +133,7 @@ Dict::Add('EN US', 'English', 'English', array(
'Class:User/Error:AtLeastOneOrganizationIsNeeded' => 'At least one organization must be assigned to this user.',
'Class:User/Error:OrganizationNotAllowed' => 'Organization not allowed.',
'Class:User/Error:UserOrganizationNotAllowed' => 'The user account does not belong to your allowed organizations.',
'Class:User/Error:PersonIsMandatory' > 'The Contact is mandatory.',
'Class:User/Error:PersonIsMandatory' => 'The Contact is mandatory.',
'Class:UserInternal' => 'User Internal',
'Class:UserInternal+' => 'User defined within '.ITOP_APPLICATION_SHORT,
));

View File

@@ -1,4 +1,5 @@
$.widget( "itop.regulartabs", $.ui.tabs, {
widgetEventPrefix: 'tabs',
js_selectors:
{
tab_container_list: '[data-role="ibo-tab-container--tab-container-list"]'

View File

@@ -1,4 +1,5 @@
$.widget( "itop.scrollabletabs", $.ui.tabs, {
widgetEventPrefix: 'tabs',
js_selectors:
{
tab_toggler: '[data-role="ibo-tab-container--tab-toggler"]',

View File

@@ -100,6 +100,17 @@ $(function()
this.element.regulartabs(oParams);
}
},
/**
* Return tabs widget instance
* @public
*/
GetTabsWidget: function () {
if (this.element.hasClass(this.css_classes.is_scrollable)) {
return this.element.scrollabletabs('instance');
} else {
return this.element.regulartabs('instance');
}
},
// events bound via _bind are removed automatically
// revert other modifications here
_destroy: function()

View File

@@ -242,10 +242,14 @@ $(function()
// Refresh handler when the list has changed
// - Initialization
// - Destroy / reinitialization (changing the DM class of the search form)
this.element.scrollParent().on('init.dt', function(oEvent) {
me._updateStickyHeaderHandler();
});
// Refresh sticky positions when results are redrawn
// - AJAX pagination, filtering
// - Page length changes
this.element.scrollParent().on('init.dt draw.dt column-sizing.dt', function(oEvent) {
me._updateStickyHeaderHandler();
this.element.scrollParent().on('draw.dt column-sizing.dt', function(oEvent) {
me._updateStickyPositions();
});
// Refresh handler when resising:
@@ -1087,6 +1091,8 @@ $(function()
this.submit.xhr.abort();
}
// Remove sticky state as we want to return at the beginning of the results
this._exitStickyState();
// Show loader
this._showLoader();
this._cleanMessageArea();
@@ -1206,12 +1212,17 @@ $(function()
const me = this;
const oFormPanelHeaderElem = this._getFormPanelHeaderElem();
// Note: As offset() starts from the very top of the window, we need to take into account the top container height!
let fOffset = this._getResultsPanelElem().find('.ibo-panel--body:first').offset().top - $('#ibo-top-container').outerHeight() - this._getFormPanelBodyElem().outerHeight();
if (this._isInAModal()) {
fOffset = fOffset - this.element.closest('[role="dialog"]').offset().top;
}
new ScrollMagic.Scene({
triggerElement: oFormPanelHeaderElem[0],
triggerHook: 0,
// Careful, this won't get updated dynamically, meaning that if the elements move or resize, it won't be exact anymore
// Note: As offset() starts from the very top of the window, we need to take into account the top container height!
offset: this._getResultsPanelElem().find('.ibo-panel--body:first').offset().top - $('#ibo-top-container').outerHeight() - this._getFormPanelBodyElem().outerHeight(),
offset: fOffset,
})
.on('enter', function () {
me._onResultsBecomesSticky();
@@ -1365,6 +1376,16 @@ $(function()
});
}
},
/**
* Exit the sticky state for the whole search, returning to the top of the results
* @return {void}
*/
_exitStickyState: function()
{
this._onFormStopsBeingSticky();
this._onResultsStopsBeingSticky();
this.element.scrollParent().scrollTop();
},
/**
* @param oElem {Object} jQuery object representing the element to test
* @return {boolean} True if oElem is currently sticking
@@ -1467,6 +1488,15 @@ $(function()
{
this.elements.results_area.unblock();
},
/**
* @return {boolean} True if the search form is in a modal window
* @private
* @since 3.0.0
*/
_isInAModal: function()
{
return this.element.closest('[role="dialog"]').length > 0;
},
// - Converts a snake_case string to CamelCase
_toCamelCase: function(sString)
{

View File

@@ -66,7 +66,7 @@ $(function()
this.bInUpdateSliderZoom = false;
this.bRedrawNeeded = false;
this.oPaper = Raphael(this.element.get(0), 16*this.element.width(), 16*this.element.height());
this.oPaper = Raphael(this.element.get(0), this.element.width(), this.element.height());
this.element
.addClass('panel-resized')
@@ -81,7 +81,7 @@ $(function()
{
// We are inside a tab, find out which one and hook its activation
this.sTabId = jTabPanel.attr('id');
var jTabs = this.element.closest('.ui-tabs');
var jTabs = this.element.closest('.ibo-tab-container');
jTabs.on( "tabsactivate", function( event, ui ) {
me._on_tabs_activate(ui);
});
@@ -392,25 +392,9 @@ $(function()
}
return null;
},
adjust_height: function()
{
var maxHeight = this.element.parent().height();
// Compute the available height
var element = this.element;
this.element.parent().children().each(function() {
if($(this).is(':visible') && !$(this).hasClass('graph') && ($(this).attr('id') != element.attr('id')))
{
maxHeight = maxHeight - $(this).height();
}
});
this.element.height(maxHeight - 8);
this.oPaper.setSize(this.element.width(), this.element.height());
},
auto_scale: function()
{
var fMaxZoom = 1.5;
this.adjust_height();
iMargin = 10;
xmin = this.options.xmin - iMargin;
@@ -466,7 +450,7 @@ $(function()
{
this._close_all_tooltips();
// Activate the 3rd tab
this.element.closest('.ui-tabs').tabs("option", "active", 2);
this.element.closest('[data-role="ibo-tab-container"]').tab_container("GetTabsWidget").option("active", 2);
// Scroll into view the group
if ($('#'+sGroupId).length > 0)
{
@@ -481,7 +465,7 @@ $(function()
sHtml += '<div class="ibo-simple-graph--grouping-threshold--container"><label for="'+sId+'_grouping_threshold">'+this.options.labels.grouping_threshold+'</label><input type="number" name="g" value="'+this.options.grouping_threshold+'" id="'+sId+'_grouping_threshold" size="2" class="ibo-input"></div>';
if (this.options.additional_contexts.length > 0)
{
sHtml += '<div class="ibo-simple-graph--additional-context--container"><label for="'+sId+'_contexts">'+this.options.labels.additional_context_info+'</label><div class="ibo-input-select-wrapper"><select id="'+sId+'_contexts" name="contexts" class="multiselect ibo-input' +
sHtml += '<div class="ibo-simple-graph--additional-context--container"><label for="'+sId+'_contexts">'+this.options.labels.additional_context_info+'</label><div><select id="'+sId+'_contexts" name="contexts" class="multiselect ibo-input' +
' ibo-input-select" multiple size="1">';
for(var k in this.options.additional_contexts)
{
@@ -698,14 +682,13 @@ $(function()
},
_on_resize: function()
{
this.element.closest('.ui-tabs').tabs({ heightStyle: "content" });
this.auto_scale();
this._close_all_tooltips();
this.draw();
},
_on_tabs_activate: function(ui)
{
if (ui.newPanel.selector == ('#'+this.sTabId))
if (ui.newPanel[0] === $('#'+this.sTabId)[0])
{
if (this.bRedrawNeeded)
{
@@ -754,25 +737,30 @@ $(function()
},
refresh_groups: function(aGroups)
{
if ($('#impacted_groups').length > 0)
{
// The "Groups" tab is present, refresh it
if (aGroups.length == 0)
if(this.element.parents('.ibo-tab-container').attr('data-status') === 'loaded'){
if ($('#impacted_groups').length > 0)
{
this.element.closest('.ui-tabs').tabs("disable", 2);
$('#impacted_groups').html('');
}
else
{
this.element.closest('.ui-tabs').tabs("enable", 2);
$('#impacted_groups').html('<img src="../images/indicator.gif">');
var sUrl = GetAbsoluteUrlAppRoot()+'pages/ajax.render.php';
$.post(sUrl, { operation: 'relation_groups', groups: aGroups }, function(data) {
$('#impacted_groups').html(data);
});
// The "Groups" tab is present, refresh it
if (aGroups.length == 0)
{
this.element.closest('[data-role="ibo-tab-container"]').tab_container("GetTabsWidget").disable(2);
$('#impacted_groups').html('');
}
else
{
this.element.closest('[data-role="ibo-tab-container"]').tab_container("GetTabsWidget").enable(2);
$('#impacted_groups').block({message:this.options.labels.loading});
var sUrl = GetAbsoluteUrlAppRoot()+'pages/ajax.render.php';
$.post(sUrl, { operation: 'relation_groups', groups: aGroups }, function(data) {
$('#impacted_groups').unblock();
$('#impacted_groups').html(data);
});
}
}
}
else{
setTimeout(this.refresh_groups(aGroups), 800);
}
},
refresh_lists: function(aLists)
{
@@ -785,9 +773,10 @@ $(function()
}
else
{
$('#impacted_objects_lists').html('<img src="../images/indicator.gif">');
$('#impacted_objects_lists').block({message:this.options.labels.loading});
var sUrl = GetAbsoluteUrlAppRoot()+'pages/ajax.render.php';
$.post(sUrl, { operation: 'relation_lists', lists: aLists }, function(data) {
$('#impacted_objects_lists').unblock();
$('#impacted_objects_lists').html(data);
});
}
@@ -818,16 +807,13 @@ $(function()
var aContexts = [];
$('#'+sId+'_contexts').multiselect('getChecked').each(function() { aContexts[$(this).val()] = me.options.additional_contexts[$(this).val()].oql; });
this.adjust_height();
this._close_all_tooltips();
this.oPaper.rect(this.xPan, this.yPan, this.element.width(), this.element.height()).attr({fill: '#000', opacity: 0.4, 'stroke-width': 0});
this.oPaper.rect(this.xPan + this.element.width()/2 - 100, this.yPan + this.element.height()/2 - 10, 200, 20)
.attr({fill: 'url(../setup/orange-progress.gif)', stroke: '#000', 'stroke-width': 1});
this.oPaper.text(this.xPan + this.element.width()/2, this.yPan + this.element.height()/2 - 20, this.options.labels.loading);
this.element.block({message:this.options.labels.loading});
$('#'+sId+'_refresh_btn').button('disable');
$.post(sUrl, {excluded_classes: this.options.excluded_classes, g: this.options.grouping_threshold, sources: this.options.sources, excluded: this.options.excluded, contexts: aContexts, context_key: this.options.context_key }, function(data) {
me.load(data);
me.element.unblock();
$('#'+sId+'_refresh_btn').button('enable');
}, 'json');
},
@@ -902,6 +888,7 @@ $(function()
_make_tooltips: function()
{
var me = this;
let aTooltipGroups = [];
$( ".popupMenuTarget" ).each(function(){
var sDataId = $(this).attr('data-id');
var sTooltipContent = me._get_tooltip_content(sDataId);
@@ -911,7 +898,13 @@ $(function()
.attr('data-tooltip-append-to', 'body')
.attr('data-tooltip-hide-delay', '1500');
CombodoTooltip.InitTooltipFromMarkup($(this));
if(aTooltipGroups.indexOf(sDataId) < 0) {
aTooltipGroups.push(sDataId);
}
});
for(let sTooltipGroupKey in aTooltipGroups) {
CombodoTooltip.InitSingletonFromSelector('.itop-simple-graph [data-id="' + aTooltipGroups[sTooltipGroupKey] + '"]');
}
},
_get_tooltip_content: function(sNodeId)
{

View File

@@ -878,6 +878,25 @@ const CombodoTooltip = {
oContainerElem.find('[data-tooltip-content]' + (bForce ? '' : ':not([data-tooltip-instantiated="true"])')).each(function () {
CombodoTooltip.InitTooltipFromMarkup($(this), bForce);
});
},
/**
* Instantiate a singleton for tooltips of elements matching sSelector.
* Used to guarantee that tooltips from said selector elements won't show at same time.
* Require selector elements tooltips to be instantiated before.
*
* @param {string} sSelector jQuery selector used to get elements tooltips
*/
InitSingletonFromSelector: function (sSelector) {
let oTippyInstances = [];
$(sSelector).each(function(){
if($(this)[0]._tippy !== undefined){
oTippyInstances.push($(this)[0]._tippy);
}
});
let aOptions = {
moveTransition: 'transform 0.2s ease-out',
}
tippy.createSingleton(oTippyInstances, $.extend(aOptions, oTippyInstances[0].props));
}
};

View File

@@ -245,15 +245,14 @@ function DisplayMultipleSelectionForm(WebPage $oP, DBSearch $oFilter, string $sN
function DisplayNavigatorListTab($oP, $aResults, $sRelation, $sDirection, $oObj)
{
$oP->SetCurrentTab('UI:RelationshipList');
$oP->add("<div id=\"impacted_objects\" style=\"width:100%;background-color:#fff;padding:10px;\">");
$oP->add("<div id=\"impacted_objects\">");
$sOldRelation = $sRelation;
if (($sRelation == 'impacts') && ($sDirection == 'up'))
{
$sOldRelation = 'depends on';
}
$oP->add("<h1>".MetaModel::GetRelationDescription($sOldRelation).' '.$oObj->GetName()."</h1>\n");
$oP->add("<div id=\"impacted_objects_lists\">");
$oP->add('<img src="../images/indicator.gif">');
$oP->add("<div id=\"impacted_objects_lists_placeholder\"></div>");
/*
* Content is rendered asynchronously via pages/ajax.render.php?operation=relation_lists
*/
@@ -265,8 +264,9 @@ function DisplayNavigatorListTab($oP, $aResults, $sRelation, $sDirection, $oObj)
function DisplayNavigatorGroupTab($oP)
{
$oP->SetCurrentTab('UI:RelationGroups');
$oP->add("<div id=\"impacted_groups\" style=\"width:100%;background-color:#fff;padding:10px;\">");
$oP->add('<img src="../images/indicator.gif">');
$oP->add("<div id=\"impacted_groups\">");
$oP->add("<div id=\"impacted_groups_placeholder\"></div>");
/*
* Content is rendered asynchronously via pages/ajax.render.php?operation=relation_groups
*/
@@ -1776,8 +1776,14 @@ EOF
$aResults = $oRelGraph->GetObjectsByClass();
$oDisplayGraph = DisplayableGraph::FromRelationGraph($oRelGraph, $iGroupingThreshold, ($sDirection == 'down'));
$oP->AddTabContainer('Navigator');
$oPanel = PanelUIBlockFactory::MakeForClass($sClass, MetaModel::GetRelationDescription($sRelation).' '.$oObj->GetName());
$sClassIcon = MetaModel::GetClassIcon($sClass, false);
if (strlen($sClassIcon) > 0){
$oPanel->SetIcon($sClassIcon);
}
$oP->AddUiBlock($oPanel);
$oP->AddTabContainer('Navigator', '', $oPanel);
$oP->SetCurrentTabContainer('Navigator');
$sFirstTab = MetaModel::GetConfig()->Get('impact_analysis_first_tab');

View File

@@ -2237,13 +2237,13 @@ EOF
$oSearch = new DBObjectSearch($sListClass);
$oSearch->AddCondition('id', $aDefinition['keys'], 'IN');
$oSearch->SetShowObsoleteData(utils::ShowObsoleteData());
$oPage->add("<h1>".Dict::Format('UI:RelationGroupNumber_N', (1 + $idx))."</h1>\n");
$oPage->add("<div id=\"relation_group_$idx\" class=\"page_header\">\n");
$oPage->add("<h2>".MetaModel::GetClassIcon($sListClass)."&nbsp;<span class=\"hilite\">".Dict::Format('UI:Search:Count_ObjectsOf_Class_Found', count($aDefinition['keys']), Metamodel::GetName($sListClass))."</h2>\n");
$oPage->add("</div>\n");
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral(Dict::Format('UI:RelationGroupNumber_N', (1 + $idx))));
$oBlock = new DisplayBlock($oSearch, 'list');
$oBlock->Display($oPage, 'group_'.$iBlock++);
$oPage->p('&nbsp;'); // Some space ?
$oBlock->Display($oPage, 'group_'.$iBlock++, array('surround_with_panel' => true,
'panel_class' => $sListClass,
'panel_title' => Dict::Format('UI:Search:Count_ObjectsOf_Class_Found', count($aDefinition['keys']), Metamodel::GetName($sListClass)),
'panel_icon' => MetaModel::GetClassIcon($sListClass, false),
));
}
$oKPI->ComputeAndReport('Data fetch and format');
break;
@@ -2257,12 +2257,13 @@ EOF
$oSearch = new DBObjectSearch($sListClass);
$oSearch->AddCondition('id', $aKeys, 'IN');
$oSearch->SetShowObsoleteData(utils::ShowObsoleteData());
$oPage->add("<div class=\"page_header\">\n");
$oPage->add("<h2>".MetaModel::GetClassIcon($sListClass)."&nbsp;<span class=\"hilite\">".Dict::Format('UI:Search:Count_ObjectsOf_Class_Found', count($aKeys), Metamodel::GetName($sListClass))."</h2>\n");
$oPage->add("</div>\n");
$oBlock = new DisplayBlock($oSearch, 'list');
$oBlock->Display($oPage, 'list_'.$iBlock++, array('table_id' => 'ImpactAnalysis_'.$sListClass));
$oPage->p('&nbsp;'); // Some space ?
$oBlock->Display($oPage, 'list_'.$iBlock++, array('table_id' => 'ImpactAnalysis_'.$sListClass,
'surround_with_panel' => true,
'panel_class' => $sListClass,
'panel_title' => Dict::Format('UI:Search:Count_ObjectsOf_Class_Found', count($aKeys), Metamodel::GetName($sListClass)),
'panel_icon' => MetaModel::GetClassIcon($sListClass, false),
));
}
$oKPI->ComputeAndReport('Data fetch and format');
break;

View File

@@ -26,6 +26,7 @@ use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactor
use Combodo\iTop\Application\UI\Base\Layout\TabContainer\Tab\AjaxTab;
use Combodo\iTop\Application\UI\Base\Layout\TabContainer\TabContainer;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Core\CMDBChange\CMDBChangeOrigin;
use Combodo\iTop\Renderer\BlockRenderer;
try {
@@ -343,6 +344,7 @@ try {
// We're doing it for real, let's create a change
$sUserString = CMDBChange::GetCurrentUserName().' (CSV)';
CMDBObject::SetTrackInfo($sUserString);
CMDBObject::SetTrackOrigin(CMDBChangeOrigin::CSV_INTERACTIVE);
$oMyChange = CMDBObject::GetCurrentChange();
}
CMDBObject::SetTrackOrigin('csv-interactive');

View File

@@ -7,6 +7,7 @@
namespace Combodo\iTop\Application\UI\Base\Component\DataTable;
use ApplicationException;
use ApplicationContext;
use appUserPreferences;
use AttributeLinkedSet;
use cmdbAbstractObject;
@@ -134,6 +135,9 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
$sTitle = (isset($aExtraParams['panel_title'])) ? $aExtraParams['panel_title'] : "";
$oContainer = PanelUIBlockFactory::MakeForClass($oSet->GetClass(), $sTitle)->AddCSSClass('ibo-datatable-panel');
$oContainer->SetSubTitle(Dict::Format("UI:Pagination:HeaderNoSelection", $iCount));
if(isset($aExtraParams["panel_icon"]) && strlen($aExtraParams["panel_icon"]) > 0){
$oContainer->SetIcon($aExtraParams["panel_icon"]);
}
$oContainer->AddToolbarBlock($oBlockMenu);
$oContainer->AddMainBlock($oDataTable);
} else {
@@ -294,7 +298,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
$oCustomSettings->aSortOrder = $oDefaultSettings->aSortOrder;
}
$sIdName = isset($extraParams["id_for_select"]) ? $extraParams["id_for_select"] : "";
$sIdName = isset($aExtraParams["id_for_select"]) ? $aExtraParams["id_for_select"] : "";
// Load only the requested columns
$aColumnsToLoad = array();
foreach ($oCustomSettings->aColumns as $sAlias => $aColumnsInfo) {

View File

@@ -22,6 +22,7 @@ namespace Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityEntry;
use AttributeDateTime;
use Combodo\iTop\Application\UI\Base\UIBlock;
use Combodo\iTop\Core\CMDBChange\CMDBChangeOrigin;
use DateTime;
use UserRights;
use utils;
@@ -41,7 +42,7 @@ class ActivityEntry extends UIBlock
public const DEFAULT_HTML_TEMPLATE_REL_PATH = 'base/layouts/activity-panel/activity-entry/layout';
/** @var string DEFAULT_ORIGIN */
public const DEFAULT_ORIGIN = 'unknown';
public const DEFAULT_ORIGIN = CMDBChangeOrigin::INTERACTIVE;
/** @var string DEFAULT_TYPE */
public const DEFAULT_TYPE = 'generic';
/** @var string DEFAULT_DECORATION_CLASSES */
@@ -67,7 +68,10 @@ class ActivityEntry extends UIBlock
protected $sAuthorPictureAbsUrl;
/** @var bool $bIsFromCurrentUser Flag to know if the user who made the activity was the current user */
protected $bIsFromCurrentUser;
/** @var string $sOrigin Origin of the entry (case log, cron, lifecycle, user edit, ...) */
/**
* @var string $sOrigin Origin of the entry (interactive, CSV import, ...)
* @see \Combodo\iTop\Core\CMDBChange\CMDBChangeOrigin
*/
protected $sOrigin;
/**
@@ -301,4 +305,43 @@ class ActivityEntry extends UIBlock
{
return $this->sOrigin;
}
/**
* @return string|null The CSS decoration classes for the origin of the entry
* @see \CMDBChangeOrigin
*/
public function GetOriginDecorationClasses(): ?string
{
$sDecorationClasses = null;
// Note: We put fa-fw on all cases instead of just in the template as one of the cases could (in the future) not use FA icons. This will ensure that any use of the FA icons are always the same width.
switch($this->GetOrigin()) {
case CMDBChangeOrigin::CSV_INTERACTIVE:
case CMDBChangeOrigin::CSV_IMPORT:
$sDecorationClasses = 'fas fa-fw fa-file-import';
break;
case CMDBChangeOrigin::EMAIL_PROCESSING:
$sDecorationClasses = 'fas fa-fw fa-envelope-open';
break;
case CMDBChangeOrigin::SYNCHRO_DATA_SOURCE:
$sDecorationClasses = 'fas fa-fw fa-lock';
break;
case CMDBChangeOrigin::WEBSERVICE_REST:
case CMDBChangeOrigin::WEBSERVICE_SOAP:
$sDecorationClasses = 'fas fa-fw fa-cloud';
break;
case CMDBChangeOrigin::CUSTOM_EXTENSION:
$sDecorationClasses = 'fas fa-fw fa-parachute-box';
break;
default:
break;
}
return $sDecorationClasses;
}
}

View File

@@ -69,7 +69,6 @@ class CaseLogEntry extends ActivityEntry
$this->sAttCode = $sAttCode;
$this->SetCaseLogRank(static::DEFAULT_CASELOG_RANK);
$this->SetOrigin('caselog:'.$this->sAttCode);
}
/*

View File

@@ -20,7 +20,6 @@
namespace Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\ActivityEntry;
use Combodo\iTop\Core\CMDBChange\CMDBChangeOrigin;
use DateTime;
use Dict;
use Exception;
@@ -52,7 +51,7 @@ class EditsEntry extends ActivityEntry
* EditsEntry constructor.
*
* @param \DateTime $oDateTime
* @param \User $sAuthorLogin
* @param string $sAuthorLogin
* @param string $sObjectClass Class of the object concerned by the edits
* @param string|null $sId
*
@@ -223,40 +222,4 @@ class EditsEntry extends ActivityEntry
return $sDescriptionAsHtml;
}
/**
* @return string|null The CSS decoration classes for the origin of the entry
* @see \CMDBChangeOrigin
*/
public function GetOriginDecorationClasses(): ?string
{
$sDecorationClasses = null;
// Note: We put fa-fw on all cases instead of just in the template as one of the cases could (in the future) not use FA icons. This will ensure that any use of the FA icons are always the same width.
switch($this->GetOrigin()) {
case CMDBChangeOrigin::CSV_INTERACTIVE:
case CMDBChangeOrigin::CSV_IMPORT:
$sDecorationClasses = 'fas fa-fw fa-file-import';
break;
case CMDBChangeOrigin::EMAIL_PROCESSING:
$sDecorationClasses = 'fas fa-fw fa-envelope-open';
break;
case CMDBChangeOrigin::SYNCHRO_DATA_SOURCE:
$sDecorationClasses = 'fas fa-fw fa-lock';
break;
case CMDBChangeOrigin::WEBSERVICE_REST:
case CMDBChangeOrigin::WEBSERVICE_SOAP:
$sDecorationClasses = 'fas fa-fw fa-cloud';
break;
case CMDBChangeOrigin::CUSTOM_EXTENSION:
$sDecorationClasses = 'fas fa-fw fa-parachute-box';
break;
}
return $sDecorationClasses;
}
}

View File

@@ -19,13 +19,4 @@
{% endfor %}
</ul>
{% endif %}
{% endblock %}
{% block iboActivityEntrySubInformation %}
{% if oUIBlock.GetOrigin() is not null and oUIBlock.GetOrigin != constant('Combodo\\iTop\\Core\\CMDBChange\\CMDBChangeOrigin::INTERACTIVE') %}
<span class="ibo-activity-entry--origin" data-role="ibo-activity-entry--origin" data-tooltip-content="{{ ('Class:CMDBChange/Attribute:origin/Value:' ~ oUIBlock.GetOrigin())|dict_s }}">
<span class="{{ oUIBlock.GetOriginDecorationClasses() }}"></span>
</span>
{% endif %}
{{ parent() }}
{% endblock %}

View File

@@ -34,11 +34,17 @@
</div>
<div class="ibo-activity-entry--sub-information" data-role="ibo-activity-entry--sub-information">
{% block iboActivityEntrySubInformation %}
{% if oUIBlock.GetOrigin() is not null and oUIBlock.GetOrigin != constant('Combodo\\iTop\\Core\\CMDBChange\\CMDBChangeOrigin::INTERACTIVE') %}
<span class="ibo-activity-entry--origin" data-role="ibo-activity-entry--origin" data-tooltip-content="{{ ('Class:CMDBChange/Attribute:origin/Value:' ~ oUIBlock.GetOrigin())|dict_s }}" data-tooltip-placement="bottom">
<span class="{{ oUIBlock.GetOriginDecorationClasses() }}"></span>
</span>
{% endif %}
{% if get_config_parameter('activity_panel.show_author_name_below_entries') %}
<span class="ibo-activity-entry--author-name ibo-is-hidden" data-role="ibo-activity-entry--author-name">{{ oUIBlock.GetAuthorFriendlyname() }}</span>
{% endif %}
<span class="ibo-activity-entry--datetime" data-role="ibo-activity-entry--datetime"
data-tooltip-content="{{ oUIBlock.GetFormattedDateTime() }}"
data-tooltip-placement="bottom"
data-raw-datetime="{{ oUIBlock.GetRawDateTime() }}"
data-formatted-datetime="{{ oUIBlock.GetFormattedDateTime() }}">{{ oUIBlock.GetFormattedDateTime() }}</span>
{% endblock %}