mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 10:38:45 +02:00
N°2836 - Portal: Introduce bubbles conversation as default caselog rendering
This commit is contained in:
@@ -1110,12 +1110,13 @@ class UserRights
|
||||
/**
|
||||
* Return the absolute URL of the contact picture
|
||||
*
|
||||
* @param string $sLogin Login of the user from which we return the picture URL
|
||||
* @param bool $bAllowDefaultPicture Set to false if you want it to return null instead of the default picture URL when the contact has no picture defined. This can be useful when we want to display something else than the default picture (eg. initials)
|
||||
* @param string $sLogin Login of the user from which we return the picture URL
|
||||
* @param bool $bAllowDefaultPicture Set to false if you want it to return null instead of the default picture URL when the contact has no picture defined. This can be useful when we want to display something else than the default picture (eg. initials)
|
||||
*
|
||||
* @return null|string
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static function GetContactPictureAbsUrl($sLogin = '', $bAllowDefaultPicture = true)
|
||||
@@ -1134,10 +1135,10 @@ class UserRights
|
||||
$sContactId = UserRights::GetContactId($sLogin);
|
||||
if(!empty($sContactId))
|
||||
{
|
||||
$oContact = MetaModel::GetObject('Contact', $sContactId);
|
||||
$oContact = MetaModel::GetObject('Contact', $sContactId, false, true);
|
||||
$sContactClass = get_class($oContact);
|
||||
|
||||
// Check that contact has a picture attribute
|
||||
// Check that Contact object still exists and that Contact class has a picture attribute
|
||||
if(!is_null($oContact) && MetaModel::IsValidAttCode($sContactClass, static::DEFAULT_CONTACT_PICTURE_ATTCODE))
|
||||
{
|
||||
/** @var \ormDocument $oPicture */
|
||||
@@ -1157,7 +1158,12 @@ class UserRights
|
||||
}
|
||||
else
|
||||
{
|
||||
$sPictureUrl = $oPicture->GetDisplayURL($sContactClass, $oContact->GetKey(), static::DEFAULT_CONTACT_PICTURE_ATTCODE);
|
||||
if (ContextTag::Check(ContextTag::TAG_PORTAL)) {
|
||||
$sPictureUrl = utils::GetAbsoluteUrlAppRoot().'pages/exec.php/object/document/display/'.$sContactClass.'/'.$oContact->GetKey().'/'.static::DEFAULT_CONTACT_PICTURE_ATTCODE.'?exec_module=itop-portal-base&exec_page=index.php&portal_id='.PORTAL_ID;
|
||||
}
|
||||
else {
|
||||
$sPictureUrl = $oPicture->GetDisplayURL($sContactClass, $oContact->GetKey(), static::DEFAULT_CONTACT_PICTURE_ATTCODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,11 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Portal:File:DisplayInfo' => '<a href="%2$s" class="file_download_link">%1$s</a>',
|
||||
'Portal:File:DisplayInfo+' => '%1$s (%2$s) <a href="%3$s" class="file_open_link" target="_blank">Open</a> / <a href="%4$s" class="file_download_link">Download</a>',
|
||||
'Portal:Calendar-FirstDayOfWeek' => 'en-us', //work with moment.js locales
|
||||
));
|
||||
|
||||
// Object form
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
'Portal:Form:Caselog:Entry:Close:Tooltip' => 'Close this entry',
|
||||
'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost',
|
||||
));
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
@charset "UTF-8";
|
||||
/*!
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
@@ -1066,39 +1065,250 @@ table .group-actions .item-action-wrapper .panel-body > p:last-child {
|
||||
cursor: zoom-in; }
|
||||
|
||||
/* CaseLog field */
|
||||
.caselog_field_entry {
|
||||
.caselog-thread {
|
||||
position: relative;
|
||||
border: 1px solid #ddd;
|
||||
border-top: none; }
|
||||
|
||||
.caselog_field_entry_header {
|
||||
padding: 6px;
|
||||
font-size: 0.9em;
|
||||
border-bottom: 1px solid #FFFFFF;
|
||||
background-color: #F2F2F2; }
|
||||
.caselog-thread--header {
|
||||
padding: 8px;
|
||||
font-size: 11px;
|
||||
background-color: rgba(242, 242, 242, 0.38);
|
||||
border-bottom: 1px solid #ddd; }
|
||||
.caselog-thread--header span {
|
||||
color: #777;
|
||||
/* body: color */ }
|
||||
|
||||
.caselog_field_entry_button {
|
||||
display: block;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
.caselog-thread--header-toggler {
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
text-decoration: none; }
|
||||
.caselog-thread--header-toggler:hover, .caselog-thread--header-toggler:active, .caselog-thread--header-toggler:focus {
|
||||
color: inherit;
|
||||
text-decoration: none; }
|
||||
.caselog-thread--header-toggler:not(:first-child)::before {
|
||||
content: "-";
|
||||
margin: 0 0.4em 0 0.2em;
|
||||
/* Note: Difference between left and right margin is due to a left space being output because the line break in the HTML isn't tidy */ }
|
||||
|
||||
.caselog-thread--header-info > span {
|
||||
margin-left: 0.5em; }
|
||||
.caselog-thread--header-info > span > span {
|
||||
margin-left: 0.5em; }
|
||||
.caselog-thread--header-info > span:first-child {
|
||||
margin-left: 0; }
|
||||
|
||||
.caselog-thread--content {
|
||||
padding: 5px;
|
||||
/*max-height: 400px;
|
||||
overflow: auto;*/
|
||||
background-color: #f2f2f2; }
|
||||
|
||||
.caselog-thread--date {
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
line-height: 15px;
|
||||
font-size: 16px;
|
||||
border: 1px solid #a6a6a6;
|
||||
border-bottom-color: #979797;
|
||||
cursor: pointer; }
|
||||
color: #808080; }
|
||||
.caselog-thread--date:first-child {
|
||||
display: none; }
|
||||
|
||||
.caselog_field_entry_button:hover {
|
||||
background-color: #cccccc; }
|
||||
.caselog-thread--block {
|
||||
position: relative;
|
||||
min-height: 40px;
|
||||
/* .caselog-thread--block-medallion height */
|
||||
margin-bottom: 15px; }
|
||||
.caselog-thread--block:last-child {
|
||||
margin-bottom: 0px; }
|
||||
|
||||
.caselog_field_entry_button:before {
|
||||
content: "▴"; }
|
||||
.caselog-thread--block-medallion,
|
||||
.caselog-thread--block-entries {
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15); }
|
||||
|
||||
.caselog_field_entry_button.collapsed:before {
|
||||
content: "▾"; }
|
||||
.caselog-thread--block-medallion {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
font-size: 18px;
|
||||
color: #444;
|
||||
/* .caselog-thread--block-entries color */
|
||||
background-size: 85%;
|
||||
background-position: center center;
|
||||
background-color: #FFFFFF;
|
||||
/* .caselog-thread--block-entries background-color */
|
||||
background-repeat: no-repeat;
|
||||
border-radius: 100%; }
|
||||
|
||||
.caselog_field_entry_content {
|
||||
margin: 10px;
|
||||
.caselog-thread--block-user {
|
||||
display: none;
|
||||
margin-left: 54px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
/* .caselog-thread--block-entries background-color */ }
|
||||
|
||||
.caselog-thread--block-entries {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-left: 60px;
|
||||
background-color: #FFFFFF;
|
||||
color: #444; }
|
||||
|
||||
.caselog-thread--block-entry {
|
||||
position: relative;
|
||||
padding: 8px 10px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05); }
|
||||
.caselog-thread--block-entry img {
|
||||
max-width: 100%; }
|
||||
.caselog-thread--block-entry.closed {
|
||||
cursor: pointer; }
|
||||
.caselog-thread--block-entry.closed .caselog-thread--block-entry-content {
|
||||
height: 0px;
|
||||
overflow-y: hidden; }
|
||||
.caselog-thread--block-entry.closed .caselog-thread--block-entry-content:after {
|
||||
content: "...";
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 9px; }
|
||||
.caselog-thread--block-entry:first-child .caselog-thread--block-entry-content:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: -15px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 8px solid transparent;
|
||||
border-top-color: #FFFFFF;
|
||||
/* .caselog-thread--block-entries background-color */
|
||||
border-right-color: #FFFFFF;
|
||||
/* .caselog-thread--block-entries background-color */ }
|
||||
.caselog-thread--block-entry:last-child {
|
||||
border-bottom: none; }
|
||||
.caselog-thread--block-entry:hover .caselog-thread--block-entry-date {
|
||||
opacity: 1; }
|
||||
.caselog-thread--block-entry:hover:not(.closed) .caselog-thread--block-entry-toggler {
|
||||
opacity: 1; }
|
||||
|
||||
.caselog-thread--block-entry-content {
|
||||
display: block;
|
||||
overflow-x: auto; }
|
||||
.caselog-thread--block-entry-content > p:last-of-type {
|
||||
margin-bottom: 0px; }
|
||||
|
||||
.caselog-thread--block-entry-date {
|
||||
margin-top: 5px;
|
||||
opacity: 0.6;
|
||||
font-size: 10px;
|
||||
text-align: right;
|
||||
transition: all 0.2s linear; }
|
||||
|
||||
.caselog-thread--block-entry-toggler {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 5px;
|
||||
padding: 2px 5px;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
background-color: #FFFFFF;
|
||||
/* .caselog-thread--block-entries background-color */
|
||||
transition: all 0.2s linear; }
|
||||
|
||||
.caselog-thread--block-me {
|
||||
text-align: right; }
|
||||
.caselog-thread--block-me .caselog-thread--block-medallion {
|
||||
left: initial;
|
||||
right: 0px; }
|
||||
.caselog-thread--block-me .caselog-thread--block-user {
|
||||
display: none;
|
||||
margin-left: initial;
|
||||
margin-right: 54px; }
|
||||
.caselog-thread--block-me .caselog-thread--block-entries {
|
||||
margin-left: initial;
|
||||
margin-right: 60px;
|
||||
text-align: right; }
|
||||
.caselog-thread--block-me .caselog-thread--block-entries .caselog-thread--block-entry {
|
||||
text-align: left; }
|
||||
.caselog-thread--block-me .caselog-thread--block-entries .caselog-thread--block-entry .caselog-thread--block-entry-toggler {
|
||||
right: initial;
|
||||
left: 5px; }
|
||||
.caselog-thread--block-me .caselog-thread--block-entries .caselog-thread--block-entry:first-child .caselog-thread--block-entry-content:before {
|
||||
left: initial;
|
||||
right: -15px;
|
||||
border-right-color: transparent;
|
||||
border-left-color: #FFFFFF;
|
||||
/* .caselog-thread--block-entries background-color */ }
|
||||
|
||||
.caselog-thread--block-color-1 .caselog-thread--block-medallion {
|
||||
color: #FFFFFF;
|
||||
background-color: #EA7D1E; }
|
||||
.caselog-thread--block-color-1 .caselog-thread--block-user {
|
||||
color: #EA7D1E; }
|
||||
.caselog-thread--block-color-1 .caselog-thread--block-entries {
|
||||
color: #FFFFFF;
|
||||
background-color: #EA7D1E; }
|
||||
.caselog-thread--block-color-1 .caselog-thread--block-entries .caselog-thread--block-entry .caselog-thread--block-entry-toggler {
|
||||
background-color: #EA7D1E; }
|
||||
.caselog-thread--block-color-1 .caselog-thread--block-entries .caselog-thread--block-entry:first-child .caselog-thread--block-entry-content:before {
|
||||
border-top-color: #EA7D1E;
|
||||
border-right-color: #EA7D1E; }
|
||||
|
||||
.caselog-thread--block-color-2 .caselog-thread--block-medallion {
|
||||
color: #FFFFFF;
|
||||
background-color: #e9a537; }
|
||||
.caselog-thread--block-color-2 .caselog-thread--block-user {
|
||||
color: #e9a537; }
|
||||
.caselog-thread--block-color-2 .caselog-thread--block-entries {
|
||||
color: #FFFFFF;
|
||||
background-color: #e9a537; }
|
||||
.caselog-thread--block-color-2 .caselog-thread--block-entries .caselog-thread--block-entry .caselog-thread--block-entry-toggler {
|
||||
background-color: #e9a537; }
|
||||
.caselog-thread--block-color-2 .caselog-thread--block-entries .caselog-thread--block-entry:first-child .caselog-thread--block-entry-content:before {
|
||||
border-top-color: #e9a537;
|
||||
border-right-color: #e9a537; }
|
||||
|
||||
.caselog-thread--block-color-3 .caselog-thread--block-medallion {
|
||||
color: #FFFFFF;
|
||||
background-color: #d16c13; }
|
||||
.caselog-thread--block-color-3 .caselog-thread--block-user {
|
||||
color: #d16c13; }
|
||||
.caselog-thread--block-color-3 .caselog-thread--block-entries {
|
||||
color: #FFFFFF;
|
||||
background-color: #d16c13; }
|
||||
.caselog-thread--block-color-3 .caselog-thread--block-entries .caselog-thread--block-entry .caselog-thread--block-entry-toggler {
|
||||
background-color: #d16c13; }
|
||||
.caselog-thread--block-color-3 .caselog-thread--block-entries .caselog-thread--block-entry:first-child .caselog-thread--block-entry-content:before {
|
||||
border-top-color: #d16c13;
|
||||
border-right-color: #d16c13; }
|
||||
|
||||
.caselog-thread--block-color-4 .caselog-thread--block-medallion {
|
||||
color: #FFFFFF;
|
||||
background-color: #e3952c; }
|
||||
.caselog-thread--block-color-4 .caselog-thread--block-user {
|
||||
color: #e3952c; }
|
||||
.caselog-thread--block-color-4 .caselog-thread--block-entries {
|
||||
color: #FFFFFF;
|
||||
background-color: #e3952c; }
|
||||
.caselog-thread--block-color-4 .caselog-thread--block-entries .caselog-thread--block-entry .caselog-thread--block-entry-toggler {
|
||||
background-color: #e3952c; }
|
||||
.caselog-thread--block-color-4 .caselog-thread--block-entries .caselog-thread--block-entry:first-child .caselog-thread--block-entry-content:before {
|
||||
border-top-color: #e3952c;
|
||||
border-right-color: #e3952c; }
|
||||
|
||||
.caselog-thread--block-color-5 .caselog-thread--block-medallion {
|
||||
color: #FFFFFF;
|
||||
background-color: #b05b10; }
|
||||
.caselog-thread--block-color-5 .caselog-thread--block-user {
|
||||
color: #b05b10; }
|
||||
.caselog-thread--block-color-5 .caselog-thread--block-entries {
|
||||
color: #FFFFFF;
|
||||
background-color: #b05b10; }
|
||||
.caselog-thread--block-color-5 .caselog-thread--block-entries .caselog-thread--block-entry .caselog-thread--block-entry-toggler {
|
||||
background-color: #b05b10; }
|
||||
.caselog-thread--block-color-5 .caselog-thread--block-entries .caselog-thread--block-entry:first-child .caselog-thread--block-entry-content:before {
|
||||
border-top-color: #b05b10;
|
||||
border-right-color: #b05b10; }
|
||||
|
||||
/* collapsable sections*/
|
||||
.form_linkedset_toggler, .form_linkedset_toggler:hover, .form_linkedset_toggler:focus, .form_upload_toggler, .form_upload_toggler:hover, .form_upload_toggler:focus {
|
||||
|
||||
@@ -1146,39 +1146,349 @@ table .group-actions .item-action-wrapper .panel-body > p:last-child{
|
||||
cursor: zoom-in;
|
||||
}
|
||||
/* CaseLog field */
|
||||
.caselog_field_entry{
|
||||
.caselog-thread {
|
||||
position: relative;
|
||||
border: 1px solid $gray-lighter;
|
||||
border-top: none;
|
||||
}
|
||||
.caselog_field_entry_header{
|
||||
padding: 6px;
|
||||
font-size: 0.9em;
|
||||
border-bottom: 1px solid $white;
|
||||
background-color: #F2F2F2;
|
||||
.caselog-thread--header{
|
||||
padding: 8px;
|
||||
font-size: 11px;
|
||||
background-color: rgba(242, 242, 242, 0.38);
|
||||
border-bottom: 1px solid $gray-lighter;
|
||||
|
||||
span{
|
||||
color: $gray; /* body: color */
|
||||
}
|
||||
}
|
||||
.caselog_field_entry_button{
|
||||
display: block;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
text-align: center;
|
||||
line-height: 15px;
|
||||
font-size: 16px;
|
||||
border: 1px solid #a6a6a6;
|
||||
border-bottom-color: #979797;
|
||||
.caselog-thread--header-toggler{
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus{
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:not(:first-child){
|
||||
&::before{
|
||||
content: "-";
|
||||
margin: 0 0.4em 0 0.2em; /* Note: Difference between left and right margin is due to a left space being output because the line break in the HTML isn't tidy */
|
||||
}
|
||||
}
|
||||
}
|
||||
.caselog_field_entry_button:hover{
|
||||
background-color: #cccccc;
|
||||
.caselog-thread--header-info{
|
||||
> span{
|
||||
margin-left: 0.5em;
|
||||
|
||||
> span{
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
&:first-child{
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.caselog_field_entry_button:before{
|
||||
content: "▴";
|
||||
.caselog-thread--content{
|
||||
padding: 5px;
|
||||
/*max-height: 400px;
|
||||
overflow: auto;*/
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
.caselog_field_entry_button.collapsed:before{
|
||||
content: "▾";
|
||||
.caselog-thread--date{
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
color: $gray-light;
|
||||
|
||||
&:first-child{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.caselog_field_entry_content{
|
||||
margin: 10px;
|
||||
.caselog-thread--block{
|
||||
position: relative;
|
||||
min-height: 40px; /* .caselog-thread--block-medallion height */
|
||||
margin-bottom: 15px;
|
||||
|
||||
&:last-child{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-medallion,
|
||||
.caselog-thread--block-entries{
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.caselog-thread--block-medallion{
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
font-size: 18px;
|
||||
color: $messaging-self-secondary-color; /* .caselog-thread--block-entries color */
|
||||
|
||||
background-size: 85%;
|
||||
background-position: center center;
|
||||
background-color: $messaging-self-primary-color; /* .caselog-thread--block-entries background-color */
|
||||
background-repeat: no-repeat;
|
||||
border-radius: 100%;
|
||||
}
|
||||
.caselog-thread--block-user{
|
||||
display: none;
|
||||
margin-left: 54px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: $messaging-self-secondary-color; /* .caselog-thread--block-entries background-color */
|
||||
}
|
||||
.caselog-thread--block-entries{
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-left: 60px;
|
||||
background-color: $messaging-self-primary-color;
|
||||
color: $messaging-self-secondary-color;
|
||||
}
|
||||
.caselog-thread--block-entry{
|
||||
position: relative;
|
||||
padding: 8px 10px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
|
||||
img{
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
|
||||
&.closed{
|
||||
cursor: pointer;
|
||||
|
||||
.caselog-thread--block-entry-content{
|
||||
height: 0px;
|
||||
overflow-y: hidden;
|
||||
|
||||
&:after{
|
||||
content: "...";
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 9px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:first-child{
|
||||
.caselog-thread--block-entry-content:before{
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: -15px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 8px solid transparent;
|
||||
border-top-color: $messaging-self-primary-color; /* .caselog-thread--block-entries background-color */
|
||||
border-right-color: $messaging-self-primary-color; /* .caselog-thread--block-entries background-color */
|
||||
}
|
||||
}
|
||||
&:last-child{
|
||||
border-bottom: none;
|
||||
}
|
||||
&:hover{
|
||||
.caselog-thread--block-entry-date{
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:not(.closed){
|
||||
.caselog-thread--block-entry-toggler{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-entry-content{
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
|
||||
> p:last-of-type{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-entry-date{
|
||||
margin-top: 5px;
|
||||
opacity: 0.6;
|
||||
font-size: 10px;
|
||||
text-align: right;
|
||||
transition: all 0.2s linear;
|
||||
}
|
||||
.caselog-thread--block-entry-toggler{
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 5px;
|
||||
padding: 2px 5px;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
background-color: $messaging-self-primary-color; /* .caselog-thread--block-entries background-color */
|
||||
transition: all 0.2s linear;
|
||||
}
|
||||
.caselog-thread--block-me{
|
||||
text-align: right;
|
||||
|
||||
.caselog-thread--block-medallion{
|
||||
left: initial;
|
||||
right: 0px;
|
||||
}
|
||||
.caselog-thread--block-user{
|
||||
display: none;
|
||||
margin-left: initial;
|
||||
margin-right: 54px;
|
||||
}
|
||||
.caselog-thread--block-entries{
|
||||
margin-left: initial;
|
||||
margin-right: 60px;
|
||||
text-align: right;
|
||||
|
||||
.caselog-thread--block-entry{
|
||||
text-align: left;
|
||||
|
||||
.caselog-thread--block-entry-toggler{
|
||||
right: initial;
|
||||
left: 5px;
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-entry:first-child{
|
||||
.caselog-thread--block-entry-content:before{
|
||||
left: initial;
|
||||
right: -15px;
|
||||
border-right-color: transparent;
|
||||
border-left-color: $messaging-self-primary-color; /* .caselog-thread--block-entries background-color */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-color-1{
|
||||
.caselog-thread--block-medallion{
|
||||
color: $messaging-1st-peer-secondary-color;
|
||||
background-color: $messaging-1st-peer-primary-color;
|
||||
}
|
||||
.caselog-thread--block-user{
|
||||
color: $messaging-1st-peer-primary-color;
|
||||
}
|
||||
.caselog-thread--block-entries{
|
||||
color: $messaging-1st-peer-secondary-color;
|
||||
background-color: $messaging-1st-peer-primary-color;
|
||||
|
||||
.caselog-thread--block-entry{
|
||||
.caselog-thread--block-entry-toggler{
|
||||
background-color: $messaging-1st-peer-primary-color;
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-entry:first-child{
|
||||
.caselog-thread--block-entry-content:before{
|
||||
border-top-color: $messaging-1st-peer-primary-color;
|
||||
border-right-color: $messaging-1st-peer-primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-color-2{
|
||||
.caselog-thread--block-medallion{
|
||||
color: $messaging-2nd-peer-secondary-color;
|
||||
background-color: $messaging-2nd-peer-primary-color;
|
||||
}
|
||||
.caselog-thread--block-user{
|
||||
color: $messaging-2nd-peer-primary-color;
|
||||
}
|
||||
.caselog-thread--block-entries{
|
||||
color: $messaging-2nd-peer-secondary-color;
|
||||
background-color: $messaging-2nd-peer-primary-color;
|
||||
|
||||
.caselog-thread--block-entry{
|
||||
.caselog-thread--block-entry-toggler{
|
||||
background-color: $messaging-2nd-peer-primary-color;
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-entry:first-child{
|
||||
.caselog-thread--block-entry-content:before{
|
||||
border-top-color: $messaging-2nd-peer-primary-color;
|
||||
border-right-color: $messaging-2nd-peer-primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-color-3{
|
||||
.caselog-thread--block-medallion{
|
||||
color: $messaging-3rd-peer-secondary-color;
|
||||
background-color: $messaging-3rd-peer-primary-color;
|
||||
}
|
||||
.caselog-thread--block-user{
|
||||
color: $messaging-3rd-peer-primary-color;
|
||||
}
|
||||
.caselog-thread--block-entries{
|
||||
color: $messaging-3rd-peer-secondary-color;
|
||||
background-color: $messaging-3rd-peer-primary-color;
|
||||
|
||||
.caselog-thread--block-entry{
|
||||
.caselog-thread--block-entry-toggler{
|
||||
background-color: $messaging-3rd-peer-primary-color;
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-entry:first-child{
|
||||
.caselog-thread--block-entry-content:before{
|
||||
border-top-color: $messaging-3rd-peer-primary-color;
|
||||
border-right-color: $messaging-3rd-peer-primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-color-4{
|
||||
.caselog-thread--block-medallion{
|
||||
color: $messaging-4th-peer-secondary-color;
|
||||
background-color: $messaging-4th-peer-primary-color;
|
||||
}
|
||||
.caselog-thread--block-user{
|
||||
color: $messaging-4th-peer-primary-color;
|
||||
}
|
||||
.caselog-thread--block-entries{
|
||||
color: $messaging-4th-peer-secondary-color;
|
||||
background-color: $messaging-4th-peer-primary-color;
|
||||
|
||||
.caselog-thread--block-entry{
|
||||
.caselog-thread--block-entry-toggler{
|
||||
background-color: $messaging-4th-peer-primary-color;
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-entry:first-child{
|
||||
.caselog-thread--block-entry-content:before{
|
||||
border-top-color: $messaging-4th-peer-primary-color;
|
||||
border-right-color: $messaging-4th-peer-primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-color-5{
|
||||
.caselog-thread--block-medallion{
|
||||
color: $messaging-5th-peer-secondary-color;
|
||||
background-color: $messaging-5th-peer-primary-color;
|
||||
}
|
||||
.caselog-thread--block-user{
|
||||
color: $messaging-5th-peer-primary-color;
|
||||
}
|
||||
.caselog-thread--block-entries{
|
||||
color: $messaging-5th-peer-secondary-color;
|
||||
background-color: $messaging-5th-peer-primary-color;
|
||||
|
||||
.caselog-thread--block-entry{
|
||||
.caselog-thread--block-entry-toggler{
|
||||
background-color: $messaging-5th-peer-primary-color;
|
||||
}
|
||||
}
|
||||
.caselog-thread--block-entry:first-child{
|
||||
.caselog-thread--block-entry-content:before{
|
||||
border-top-color: $messaging-5th-peer-primary-color;
|
||||
border-right-color: $messaging-5th-peer-primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* collapsable sections*/
|
||||
.form_linkedset_toggler, .form_upload_toggler {
|
||||
|
||||
@@ -937,3 +937,21 @@ $dl-horizontal-offset: $component-offset-horizontal !default;
|
||||
$dl-horizontal-breakpoint: $grid-float-breakpoint !default;
|
||||
//** Horizontal line color.
|
||||
$hr-border: $gray-lighter !default;
|
||||
|
||||
|
||||
//== Messaging
|
||||
//
|
||||
//##
|
||||
|
||||
$messaging-self-primary-color: $white !default;
|
||||
$messaging-self-secondary-color: $gray-dark !default;
|
||||
$messaging-1st-peer-primary-color: $combodo-orange !default;
|
||||
$messaging-1st-peer-secondary-color: $white !default;
|
||||
$messaging-2nd-peer-primary-color: #e9a537 !default;
|
||||
$messaging-2nd-peer-secondary-color: $white !default;
|
||||
$messaging-3rd-peer-primary-color: darken($combodo-orange, 7%) !default;
|
||||
$messaging-3rd-peer-secondary-color: $white !default;
|
||||
$messaging-4th-peer-primary-color: #e3952c !default;
|
||||
$messaging-4th-peer-secondary-color: $white !default;
|
||||
$messaging-5th-peer-primary-color: darken($combodo-orange, 14%) !default;
|
||||
$messaging-5th-peer-secondary-color: $white !default;
|
||||
|
||||
@@ -1025,6 +1025,7 @@ class ObjectController extends BrickController
|
||||
$sObjectClass = $oRequestManipulator->ReadParam('sObjectClass', '');
|
||||
$sObjectId = $oRequestManipulator->ReadParam('sObjectId', '');
|
||||
$sObjectField = $oRequestManipulator->ReadParam('sObjectField', '');
|
||||
$bCheckSecurity = true;
|
||||
|
||||
// When reaching to an Attachment, we have to check security on its host object instead of the Attachment itself
|
||||
if ($sObjectClass === 'Attachment')
|
||||
@@ -1037,11 +1038,17 @@ class ObjectController extends BrickController
|
||||
{
|
||||
$sHostClass = $sObjectClass;
|
||||
$sHostId = $sObjectId;
|
||||
|
||||
// Security bypass for the image attribute of a class
|
||||
// Note: This will be changed with a proper DM check when corresponding bug is being worked on
|
||||
if(is_a($sObjectClass, 'Contact', true) && ($sObjectField === 'picture')){
|
||||
$bCheckSecurity = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Checking security layers
|
||||
// Note: Checking if host object already exists as we can try to download document from an object that is being created
|
||||
if (($sHostId > 0) && !$oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sHostClass, $sHostId))
|
||||
if (($bCheckSecurity === true) && ($sHostId > 0) && !$oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sHostClass, $sHostId))
|
||||
{
|
||||
IssueLog::Warning(__METHOD__.' at line '.__LINE__.' : User #'.UserRights::GetUserId().' not allowed to retrieve document from attribute '.$sObjectField.' as it not allowed to read '.$sHostClass.'::'.$sHostId.' object.');
|
||||
throw new HttpException(Response::HTTP_NOT_FOUND, Dict::S('UI:ObjectDoesNotExist'));
|
||||
|
||||
@@ -24,8 +24,10 @@ use utils;
|
||||
use Dict;
|
||||
use UserRights;
|
||||
use AttributeDateTime;
|
||||
use AttributeDate;
|
||||
use AttributeText;
|
||||
use InlineImage;
|
||||
use MetaModel;
|
||||
use Combodo\iTop\Renderer\RenderingOutput;
|
||||
use Combodo\iTop\Form\Field\TextAreaField;
|
||||
use Combodo\iTop\Form\Field\MultipleChoicesField;
|
||||
@@ -38,11 +40,10 @@ use Combodo\iTop\Form\Field\MultipleChoicesField;
|
||||
class BsSimpleFieldRenderer extends BsFieldRenderer
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function Render()
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function Render() {
|
||||
$oOutput = parent::Render();
|
||||
|
||||
$sFieldClass = get_class($this->oField);
|
||||
@@ -50,79 +51,74 @@ class BsSimpleFieldRenderer extends BsFieldRenderer
|
||||
$sFieldDescriptionForHTMLTag = ($this->oField->HasDescription()) ? 'data-tooltip-content="'.utils::HtmlEntities($this->oField->GetDescription()).'"' : '';
|
||||
|
||||
// Rendering field in edition mode
|
||||
if (!$this->oField->GetReadOnly() && !$this->oField->GetHidden())
|
||||
{
|
||||
// HTML content
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PasswordField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':
|
||||
// Opening container
|
||||
$oOutput->AddHtml('<div class="form-group form_group_small ' . $sFieldMandatoryClass . '">');
|
||||
if (!$this->oField->GetReadOnly() && !$this->oField->GetHidden()) {
|
||||
// HTML content
|
||||
switch ($sFieldClass) {
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PasswordField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':
|
||||
// Opening container
|
||||
$oOutput->AddHtml('<div class="form-group form_group_small ' . $sFieldMandatoryClass . '">');
|
||||
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '') {
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
// - Help block
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
// - Value regarding the field type
|
||||
switch($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
$oOutput->AddHtml('<div class="input-group date" id="datepicker_' . $this->oField->GetGlobalId() . '">');
|
||||
$oOutput->AddHtml('<input type="text" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($this->oField->GetDisplayValue(), true)->AddHtml('" class="form-control" maxlength="255" />');
|
||||
$oOutput->AddHtml('<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
$sJSFormat = json_encode($this->oField->GetJSDateTimeFormat());
|
||||
$sLocale = Dict::S('Portal:Calendar-FirstDayOfWeek');
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
// - Help block
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
// - Value regarding the field type
|
||||
switch($sFieldClass) {
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
$oOutput->AddHtml('<div class="input-group date" id="datepicker_' . $this->oField->GetGlobalId() . '">');
|
||||
$oOutput->AddHtml('<input type="text" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($this->oField->GetDisplayValue(), true)->AddHtml('" class="form-control" maxlength="255" />');
|
||||
$oOutput->AddHtml('<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
$sJSFormat = json_encode($this->oField->GetJSDateTimeFormat());
|
||||
$sLocale = Dict::S('Portal:Calendar-FirstDayOfWeek');
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$('#datepicker_{$this->oField->GetGlobalId()}').datetimepicker({format: $sJSFormat, locale: '$sLocale'});
|
||||
EOF
|
||||
);
|
||||
break;
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\PasswordField':
|
||||
$oOutput->AddHtml('<input type="password" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($this->oField->GetCurrentValue(), true)->AddHtml('" class="form-control" maxlength="255" autocomplete="off" />');
|
||||
break;
|
||||
case 'Combodo\\iTop\\Form\\Field\\PasswordField':
|
||||
$oOutput->AddHtml('<input type="password" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($this->oField->GetCurrentValue(), true)->AddHtml('" class="form-control" maxlength="255" autocomplete="off" />');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
$oOutput->AddHtml('<input type="text" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($this->oField->GetCurrentValue(), true)->AddHtml('" class="form-control" maxlength="255" />');
|
||||
break;
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
$oOutput->AddHtml('<input type="text" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($this->oField->GetCurrentValue(), true)->AddHtml('" class="form-control" maxlength="255" />');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':
|
||||
$oOutput->AddHtml('<select id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" ' . ( ($this->oField->GetMultipleValuesEnabled()) ? 'multiple' : '' ) . ' class="form-control">');
|
||||
foreach ($this->oField->GetChoices() as $sChoice => $sLabel)
|
||||
{
|
||||
// Note : The test is a double equal on purpose as the type of the value received from the XHR is not always the same as the type of the allowed values. (eg : string vs int)
|
||||
$sSelectedAtt = ($this->oField->GetCurrentValue() == $sChoice) ? 'selected' : '';
|
||||
$oOutput->AddHtml('<option value="' . $sChoice . '" ' . $sSelectedAtt . ' >')->AddHtml($sLabel)->AddHtml('</option>');
|
||||
}
|
||||
$oOutput->AddHtml('</select>');
|
||||
break;
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':
|
||||
$oOutput->AddHtml('<select id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" ' . ( ($this->oField->GetMultipleValuesEnabled()) ? 'multiple' : '' ) . ' class="form-control">');
|
||||
foreach ($this->oField->GetChoices() as $sChoice => $sLabel) {
|
||||
// Note : The test is a double equal on purpose as the type of the value received from the XHR is not always the same as the type of the allowed values. (eg : string vs int)
|
||||
$sSelectedAtt = ($this->oField->GetCurrentValue() == $sChoice) ? 'selected' : '';
|
||||
$oOutput->AddHtml('<option value="' . $sChoice . '" ' . $sSelectedAtt . ' >')->AddHtml($sLabel)->AddHtml('</option>');
|
||||
}
|
||||
$oOutput->AddHtml('</select>');
|
||||
break;
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Closing container
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
// Closing container
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CaseLogField':
|
||||
@@ -132,24 +128,22 @@ EOF
|
||||
$oOutput->AddHtml('<div class="form-group ' . $sFieldMandatoryClass . '">');
|
||||
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '') {
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
// - Help block
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
// - Help block
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
// First the edition area
|
||||
$oOutput->AddHtml('<div>');
|
||||
$oOutput->AddHtml('<textarea id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" class="form-control" rows="8">' . $this->oField->GetCurrentValue() . '</textarea>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
// Then the previous entries if necessary
|
||||
if ($sFieldClass === 'Combodo\\iTop\\Form\\Field\\CaseLogField')
|
||||
{
|
||||
if ($sFieldClass === 'Combodo\\iTop\\Form\\Field\\CaseLogField') {
|
||||
$this->PreparingCaseLogEntries($oOutput);
|
||||
// Trigger highlighter for all code blocks in this caselog
|
||||
$oOutput->AddJs(
|
||||
@@ -166,8 +160,7 @@ JS
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Some additional stuff if we are displaying it with a rich editor
|
||||
if ($bRichEditor)
|
||||
{
|
||||
if ($bRichEditor) {
|
||||
$sEditorLanguage = strtolower(trim(UserRights::GetUserLanguage()));
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
@@ -177,8 +170,7 @@ JS
|
||||
});
|
||||
EOF
|
||||
);
|
||||
if (($this->oField->GetObject() !== null) && ($this->oField->GetTransactionId() !== null))
|
||||
{
|
||||
if (($this->oField->GetObject() !== null) && ($this->oField->GetTransactionId() !== null)) {
|
||||
$oOutput->AddJs(InlineImage::EnableCKEditorImageUpload($this->oField->GetObject(), utils::GetUploadTempId($this->oField->GetTransactionId())));
|
||||
}
|
||||
}
|
||||
@@ -193,20 +185,18 @@ EOF
|
||||
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
if ($this->oField->GetLabel() !== '') {
|
||||
$oOutput->AddHtml('<div><label class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label></div>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
// - Help block
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
// - Help block
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
$oOutput->AddHtml('<div class="btn-group" data-toggle="buttons">');
|
||||
$i = 0;
|
||||
foreach ($this->oField->GetChoices() as $sChoice => $sLabel)
|
||||
{
|
||||
foreach ($this->oField->GetChoices() as $sChoice => $sLabel) {
|
||||
// Note : The test is a double equal on purpose as the type of the value received from the XHR is not always the same as the type of the allowed values. (eg : string vs int)
|
||||
$sCheckedAtt = ($this->oField->IsAmongValues($sChoice)) ? 'checked' : '';
|
||||
$sCheckedClass = ($this->oField->IsAmongValues($sChoice)) ? 'active' : '';
|
||||
@@ -225,21 +215,20 @@ EOF
|
||||
break;
|
||||
}
|
||||
|
||||
// JS FieldChange trigger (:input are not always at the same depth)
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\PasswordField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CaseLogField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\HiddenField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
// JS FieldChange trigger (:input are not always at the same depth)
|
||||
switch ($sFieldClass) {
|
||||
case 'Combodo\\iTop\\Form\\Field\\PasswordField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CaseLogField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\HiddenField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("#{$this->oField->GetGlobalId()}").off("change keyup").on("change keyup", function(){
|
||||
var me = this;
|
||||
|
||||
@@ -250,12 +239,12 @@ EOF
|
||||
});
|
||||
}).on("mouseup", function(){this.focus();});
|
||||
EOF
|
||||
);
|
||||
break;
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
// We need the focusout event has the datepicker widget seems to override the change event
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
);
|
||||
break;
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
// We need the focusout event has the datepicker widget seems to override the change event
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("#{$this->oField->GetGlobalId()}").off("change keyup focusout").on("change keyup focusout", function(){
|
||||
var me = this;
|
||||
|
||||
@@ -266,13 +255,13 @@ EOF
|
||||
});
|
||||
});
|
||||
EOF
|
||||
);
|
||||
break;
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CheckboxField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CheckboxField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("#{$this->oField->GetGlobalId()} input").off("change").on("change", function(){
|
||||
var me = this;
|
||||
|
||||
@@ -283,84 +272,75 @@ EOF
|
||||
});
|
||||
});
|
||||
EOF
|
||||
);
|
||||
break;
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ... and in read-only mode (or hidden)
|
||||
else
|
||||
{
|
||||
else {
|
||||
// ... specific rendering for fields with multiple values
|
||||
if (($this->oField instanceof MultipleChoicesField) && ($this->oField->GetMultipleValuesEnabled()))
|
||||
{
|
||||
if (($this->oField instanceof MultipleChoicesField) && ($this->oField->GetMultipleValuesEnabled())) {
|
||||
// TODO
|
||||
}
|
||||
// ... classic rendering for fields with only one value
|
||||
else
|
||||
{
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
else {
|
||||
switch ($sFieldClass) {
|
||||
case 'Combodo\\iTop\\Form\\Field\\LabelField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\DurationField':
|
||||
// Opening container
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\DurationField':
|
||||
// Opening container
|
||||
$oOutput->AddHtml('<div class="form-group form_group_small">');
|
||||
|
||||
// Showing label / value only if read-only but not hidden
|
||||
if (!$this->oField->GetHidden())
|
||||
{
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Value
|
||||
$bEncodeHtmlEntities = ( in_array($sFieldClass, array('Combodo\\iTop\\Form\\Field\\UrlField', 'Combodo\\iTop\\Form\\Field\\EmailField', 'Combodo\\iTop\\Form\\Field\\PhoneField')) ) ? false : true;
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
$oOutput->AddHtml('<div class="form-control-static">')->AddHtml($this->oField->GetDisplayValue(), $bEncodeHtmlEntities)->AddHtml('</div>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
}
|
||||
|
||||
// Adding hidden input if not a label
|
||||
if($sFieldClass !== 'Combodo\\iTop\\Form\\Field\\LabelField')
|
||||
{
|
||||
$sValueForInput = ($sFieldClass === 'Combodo\\iTop\\Form\\Field\\DateTimeField') ? $this->oField->GetDisplayValue() : $this->oField->GetCurrentValue();
|
||||
$oOutput->AddHtml('<input type="hidden" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($sValueForInput, true)->AddHtml('" class="form-control" />');
|
||||
}
|
||||
|
||||
// Closing container
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
// Opening container
|
||||
$oOutput->AddHtml('<div class="form-group">');
|
||||
|
||||
// Showing label / value only if read-only but not hidden
|
||||
if (!$this->oField->GetHidden())
|
||||
{
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
if (!$this->oField->GetHidden()) {
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '') {
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
$oOutput->AddHtml('<div class="form-control-static">')->AddHtml($this->oField->GetDisplayValue(), false)->AddHtml('</div>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
// Trigger highlighter for all code blocks in this html text field
|
||||
$oOutput->AddJs(
|
||||
<<<JS
|
||||
// Value
|
||||
$bEncodeHtmlEntities = ( in_array($sFieldClass, array('Combodo\\iTop\\Form\\Field\\UrlField', 'Combodo\\iTop\\Form\\Field\\EmailField', 'Combodo\\iTop\\Form\\Field\\PhoneField')) ) ? false : true;
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
$oOutput->AddHtml('<div class="form-control-static">')->AddHtml($this->oField->GetDisplayValue(), $bEncodeHtmlEntities)->AddHtml('</div>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
}
|
||||
|
||||
// Adding hidden input if not a label
|
||||
if($sFieldClass !== 'Combodo\\iTop\\Form\\Field\\LabelField') {
|
||||
$sValueForInput = ($sFieldClass === 'Combodo\\iTop\\Form\\Field\\DateTimeField') ? $this->oField->GetDisplayValue() : $this->oField->GetCurrentValue();
|
||||
$oOutput->AddHtml('<input type="hidden" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($sValueForInput, true)->AddHtml('" class="form-control" />');
|
||||
}
|
||||
|
||||
// Closing container
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
// Opening container
|
||||
$oOutput->AddHtml('<div class="form-group">');
|
||||
|
||||
// Showing label / value only if read-only but not hidden
|
||||
if (!$this->oField->GetHidden()) {
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '') {
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
$oOutput->AddHtml('<div class="form-control-static">')->AddHtml($this->oField->GetDisplayValue(), false)->AddHtml('</div>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
// Trigger highlighter for all code blocks in this html text field
|
||||
$oOutput->AddJs(
|
||||
<<<JS
|
||||
$("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}'] .HTML pre").each(function(i, block) {
|
||||
hljs.highlightBlock(block);
|
||||
});
|
||||
@@ -376,26 +356,25 @@ JS
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\CaseLogField':
|
||||
// Opening container
|
||||
$oOutput->AddHtml('<div class="form-group ' . $sFieldMandatoryClass . '">');
|
||||
// Opening container
|
||||
$oOutput->AddHtml('<div class="form-group ' . $sFieldMandatoryClass . '">');
|
||||
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '') {
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
// - Entries if necessary
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
// - Entries if necessary
|
||||
$this->PreparingCaseLogEntries($oOutput);
|
||||
$oOutput->AddHtml('</div>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Closing container
|
||||
$oOutput->AddHtml('</div>');
|
||||
// Trigger highlighter for all code blocks in this caselog
|
||||
// Closing container
|
||||
$oOutput->AddHtml('</div>');
|
||||
// Trigger highlighter for all code blocks in this caselog
|
||||
$oOutput->AddJs(
|
||||
<<<JS
|
||||
$("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}'] .caselog_field_entry_content pre").each(function(i, block) {
|
||||
@@ -406,32 +385,28 @@ JS
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\BlobField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\ImageField':
|
||||
// Opening container
|
||||
case 'Combodo\\iTop\\Form\\Field\\ImageField':
|
||||
// Opening container
|
||||
$oOutput->AddHtml('<div class="form-group">');
|
||||
|
||||
// Showing label / value only if read-only but not hidden
|
||||
if (!$this->oField->GetHidden())
|
||||
{
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
if (!$this->oField->GetHidden()) {
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '') {
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
$oOutput->AddHtml('<div class="form-control-static">');
|
||||
if($sFieldClass === 'Combodo\\iTop\\Form\\Field\\ImageField')
|
||||
{
|
||||
$oOutput->AddHtml('<img src="' . $this->oField->GetDisplayUrl() . '" />', false);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oOutput->AddHtml($this->oField->GetDisplayValue(), false);
|
||||
}
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
$oOutput->AddHtml('<div class="form-control-static">');
|
||||
if($sFieldClass === 'Combodo\\iTop\\Form\\Field\\ImageField') {
|
||||
$oOutput->AddHtml('<img src="' . $this->oField->GetDisplayUrl() . '" />', false);
|
||||
}
|
||||
else {
|
||||
$oOutput->AddHtml($this->oField->GetDisplayValue(), false);
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
}
|
||||
@@ -451,20 +426,18 @@ JS
|
||||
$oOutput->AddHtml('<div class="form-group form_group_small">');
|
||||
|
||||
// Showing label / value only if read-only but not hidden
|
||||
if (!$this->oField->GetHidden())
|
||||
{
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
if (!$this->oField->GetHidden()) {
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '') {
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
$oOutput->AddHtml('<div class="form-control-static">' . $sFieldValue . '</div>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
}
|
||||
|
||||
// Adding hidden value
|
||||
@@ -482,78 +455,71 @@ JS
|
||||
}
|
||||
|
||||
// Attaching JS widget only if field is hidden or NOT read only
|
||||
if($this->oField->GetHidden() || !$this->oField->GetReadOnly())
|
||||
{
|
||||
if($this->oField->GetHidden() || !$this->oField->GetReadOnly()) {
|
||||
|
||||
// JS Form field widget construct
|
||||
$aValidators = array();
|
||||
foreach ($this->oField->GetValidators() as $oValidator)
|
||||
{
|
||||
$aValidators[$oValidator::GetName()] = array(
|
||||
'reg_exp' => $oValidator->GetRegExp(),
|
||||
'message' => Dict::S($oValidator->GetErrorMessage())
|
||||
);
|
||||
}
|
||||
// JS Form field widget construct
|
||||
$aValidators = array();
|
||||
foreach ($this->oField->GetValidators() as $oValidator) {
|
||||
$aValidators[$oValidator::GetName()] = array(
|
||||
'reg_exp' => $oValidator->GetRegExp(),
|
||||
'message' => Dict::S($oValidator->GetErrorMessage())
|
||||
);
|
||||
}
|
||||
|
||||
$sFormFieldOptions = json_encode(array(
|
||||
'validators' => $aValidators
|
||||
));
|
||||
$sFormFieldOptions = json_encode(array(
|
||||
'validators' => $aValidators
|
||||
));
|
||||
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\PasswordField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\HiddenField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CheckboxField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
switch ($sFieldClass) {
|
||||
case 'Combodo\\iTop\\Form\\Field\\PasswordField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\HiddenField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CheckboxField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}']").portal_form_field($sFormFieldOptions);
|
||||
EOF
|
||||
);
|
||||
break;
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CaseLogField':
|
||||
$bRichEditor = ($this->oField->GetFormat() === TextAreaField::ENUM_FORMAT_HTML);
|
||||
if($bRichEditor)
|
||||
{
|
||||
// Overloading $sFormFieldOptions to include the set_current_value_callback. It would have been nicer to refactor the variable for all field types, but as this is a fix for a maintenance release, we rather be safe.
|
||||
$sValidators = json_encode($aValidators);
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
);
|
||||
break;
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CaseLogField':
|
||||
$bRichEditor = ($this->oField->GetFormat() === TextAreaField::ENUM_FORMAT_HTML);
|
||||
if($bRichEditor) {
|
||||
// Overloading $sFormFieldOptions to include the set_current_value_callback. It would have been nicer to refactor the variable for all field types, but as this is a fix for a maintenance release, we rather be safe.
|
||||
$sValidators = json_encode($aValidators);
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}']").portal_form_field_html({
|
||||
validators: $sValidators,
|
||||
set_current_value_callback: function(me, oEvent, oData){ $(me.element).find('textarea').val(oData); }
|
||||
});
|
||||
EOF
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
);
|
||||
}
|
||||
else {
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}']").portal_form_field($sFormFieldOptions);
|
||||
EOF
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, no matter the field mode
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
// Finally, no matter the field mode
|
||||
switch ($sFieldClass) {
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CaseLogField':
|
||||
$bRichEditor = ($this->oField->GetFormat() === TextAreaField::ENUM_FORMAT_HTML);
|
||||
if($bRichEditor)
|
||||
{
|
||||
if($bRichEditor) {
|
||||
// MagnificPopup on images
|
||||
$oOutput->AddJs(InlineImage::FixImagesWidth());
|
||||
}
|
||||
@@ -563,49 +529,191 @@ EOF
|
||||
return $oOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RenderingOutput $oOutput
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function PreparingCaseLogEntries(RenderingOutput &$oOutput)
|
||||
{
|
||||
/**
|
||||
* Note: Since 3.0.0 this is highly inspired from an extension of the community (see https://github.com/Molkobain/itop-bubble-caselogs)
|
||||
*
|
||||
* @param RenderingOutput $oOutput
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function PreparingCaseLogEntries(RenderingOutput &$oOutput) {
|
||||
$aEntries = $this->oField->GetEntries();
|
||||
if (count($aEntries) > 0)
|
||||
{
|
||||
$oOutput->AddHtml('<div>');
|
||||
for ($i = 0; $i < count($aEntries); $i++)
|
||||
{
|
||||
$sEntryDate = AttributeDateTime::GetFormat()->Format($aEntries[$i]['date']);
|
||||
$sEntryUser = $aEntries[$i]['user_login'];
|
||||
$sEntryHeader = Dict::Format('UI:CaseLog:Header_Date_UserName', $sEntryDate, $sEntryUser);
|
||||
$iNbEntries = count($aEntries);
|
||||
|
||||
// Only the last 2 entries are expanded by default
|
||||
$sEntryContentExpanded = ($i < 2) ? 'true' : 'false';
|
||||
$sEntryHeaderButtonClass = ($i < 2) ? '' : 'collapsed';
|
||||
$sEntryContentClass = ($i < 2) ? 'in' : '';
|
||||
$sEntryContentId = 'caselog_field_entry_content-' . $this->oField->GetGlobalId() . '-' . $i;
|
||||
if ($iNbEntries > 0) {
|
||||
// Dict entries
|
||||
$sOpenAllEntriesTooltip = utils::HtmlEntities(Dict::S('UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:OpenAll:Tooltip'));
|
||||
$sCloseAllEntriesTooltip = utils::HtmlEntities(Dict::S('UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:CloseAll:Tooltip'));
|
||||
$sUsersCountTooltip = utils::HtmlEntities(Dict::S('UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:AuthorsCount:Tooltip'));
|
||||
$sEntriesCountTooltip = utils::HtmlEntities(Dict::S('UI:Layout:ActivityPanel:Tab:Caselog:Toolbar:MessagesCount:Tooltip'));
|
||||
$sCloseEntryTooltip = utils::HtmlEntities(Dict::S('Portal:Form:Caselog:Entry:Close:Tooltip'));
|
||||
|
||||
// First pass to retrieve number of users
|
||||
$aUserIds = array();
|
||||
for ($i = 0; $i < $iNbEntries; $i++) {
|
||||
$iEntryUserId = $aEntries[$i]['user_id'];
|
||||
if (!in_array($iEntryUserId, $aUserIds)) {
|
||||
$aUserIds[] = $iEntryUserId;
|
||||
}
|
||||
}
|
||||
$iNbUsers = count($aUserIds);
|
||||
|
||||
// Opening thread
|
||||
$oOutput->AddHtml(<<<HTML
|
||||
<div class="caselog-thread">
|
||||
HTML
|
||||
);
|
||||
// - Header
|
||||
$oOutput->AddHtml(<<<HTML
|
||||
<div class="caselog-thread--header">
|
||||
<span class="caselog-thread--header-togglers">
|
||||
<a href="#" class="caselog-thread--header-toggler caselog-thread--open-all-toggler" data-tooltip-content="{$sOpenAllEntriesTooltip}"><span class="fas fa-book-open"></span></a>
|
||||
<a href="#" class="caselog-thread--header-toggler caselog-thread--close-all-toggler" data-tooltip-content="{$sCloseAllEntriesTooltip}"><span class="fas fa-book"></span></a>
|
||||
</span>
|
||||
<span class="caselog-thread--header-info pull-right">
|
||||
<span class="caselog-thread--participants-count" data-tooltip-content="{$sUsersCountTooltip}">{$iNbUsers}<span class="fas fa-users"></span></span>
|
||||
<span class="caselog-thread--messages-count" data-tooltip-content="{$sEntriesCountTooltip}">{$iNbEntries}<span class="fas fa-comment-alt"></span></span>
|
||||
</span>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
// - Content
|
||||
$oOutput->AddHtml(<<<HTML
|
||||
<div class="caselog-thread--content">
|
||||
HTML
|
||||
);
|
||||
|
||||
$sThreadUniqueId = uniqid();
|
||||
$sLastDate = null;
|
||||
$sLastUserId = null;
|
||||
$iLastLoopIndex = $iNbEntries - 1;
|
||||
|
||||
// Caching profile picture url as it is resource consuming
|
||||
$aContactPicturesCache = array();
|
||||
$aPeerColorClassCache = array();
|
||||
// Current user
|
||||
$iCurrentUserId = UserRights::GetUserId();
|
||||
|
||||
for ($i = 0; $i < $iNbEntries; $i++) {
|
||||
$sEntryDatetime = AttributeDateTime::GetFormat()->Format($aEntries[$i]['date']);
|
||||
$sEntryDate = AttributeDate::GetFormat()->Format($aEntries[$i]['date']);
|
||||
|
||||
$sEntryUserLogin = $aEntries[$i]['user_login'];
|
||||
$iEntryUserId = $aEntries[$i]['user_id'];
|
||||
|
||||
// Retrieve (and cache) profile picture if available (standard datamodel)
|
||||
if (!array_key_exists($iEntryUserId, $aContactPicturesCache)) {
|
||||
$oEntryUser = MetaModel::GetObject('User', $iEntryUserId, false, true);
|
||||
if(is_null($oEntryUser)) {
|
||||
$sEntryContactPictureAbsoluteUrl = null;
|
||||
}
|
||||
else {
|
||||
$sEntryContactPictureAbsoluteUrl = UserRights::GetContactPictureAbsUrl($oEntryUser->Get('login'), false);
|
||||
}
|
||||
$aContactPicturesCache[$iEntryUserId] = $sEntryContactPictureAbsoluteUrl;
|
||||
}
|
||||
|
||||
// Open user block if previous user was different or if previous date was different
|
||||
if (($iEntryUserId !== $sLastUserId) || ($sEntryDate !== $sLastDate)) {
|
||||
if ($sEntryDate !== $sLastDate) {
|
||||
$oOutput->AddHtml(<<<HTML
|
||||
<div class="caselog-thread--date">{$sEntryDate}</div>
|
||||
HTML
|
||||
);
|
||||
}
|
||||
|
||||
// Open block
|
||||
if ($iEntryUserId === $iCurrentUserId) {
|
||||
$sEntryBlockClass = 'caselog-thread--block-me';
|
||||
}
|
||||
else {
|
||||
if (!array_key_exists($iEntryUserId, $aPeerColorClassCache)) {
|
||||
$iPeerClassNumber = (count($aPeerColorClassCache) % 5) + 1;
|
||||
$aPeerColorClassCache[$iEntryUserId] = 'caselog-thread--block-color-'.$iPeerClassNumber;
|
||||
}
|
||||
$sEntryBlockClass = $aPeerColorClassCache[$iEntryUserId];
|
||||
}
|
||||
$oOutput->AddHtml(<<<HTML
|
||||
<div class="caselog-thread--block {$sEntryBlockClass}">
|
||||
HTML
|
||||
);
|
||||
|
||||
// Open medallion from profile picture or first name letter
|
||||
$sEntryMedallionStyle = (empty($aContactPicturesCache[$iEntryUserId]) === false) ? ' background-image: url(\''.$aContactPicturesCache[$iEntryUserId].'\');' : '';
|
||||
$sEntryMedallionContent = (empty($aContactPicturesCache[$iEntryUserId]) === false) ? '' : UserRights::GetUserInitials($sEntryUserLogin);
|
||||
// - Entry tooltip
|
||||
$sEntryMedallionTooltip = utils::HtmlEntities($sEntryUserLogin);
|
||||
$sEntryMedallionTooltipPlacement = ($iEntryUserId === $iCurrentUserId) ? 'left' : 'right';
|
||||
$oOutput->AddHtml(<<<HTML
|
||||
<div class="caselog-thread--block-medallion" style="{$sEntryMedallionStyle}" data-tooltip-content="{$sEntryMedallionTooltip}" data-placement="{$sEntryMedallionTooltipPlacement}">
|
||||
$sEntryMedallionContent
|
||||
</div>
|
||||
<div class="caselog-thread--block-user">{$sEntryUserLogin}</div>
|
||||
HTML
|
||||
);
|
||||
|
||||
// Open entries
|
||||
$oOutput->AddHtml(<<<HTML
|
||||
<div class="caselog-thread--block-entries">
|
||||
HTML
|
||||
);
|
||||
}
|
||||
|
||||
// Prepare entry content
|
||||
$sEntryId = 'caselog-thread--block-entry-'.$sThreadUniqueId.'-'.$i;
|
||||
$sEntryHtml = AttributeText::RenderWikiHtml($aEntries[$i]['message_html'], true /* wiki only */);
|
||||
$sEntryHtml = InlineImage::FixUrls($sEntryHtml);
|
||||
|
||||
// Note : We use CKEditor stylesheet to format this
|
||||
$oOutput->AddHtml(
|
||||
<<<EOF
|
||||
<div class="caselog_field_entry cke_inner">
|
||||
<div class="caselog_field_entry_header">
|
||||
{$sEntryHeader}
|
||||
<div class="pull-right">
|
||||
<span class="caselog_field_entry_button {$sEntryHeaderButtonClass}" data-toggle="collapse" href="#{$sEntryContentId}" aria-expanded="{$sEntryContentExpanded}" aria-controls="{$sEntryContentId}"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="caselog_field_entry_content collapse {$sEntryContentClass}" id="{$sEntryContentId}">
|
||||
{$sEntryHtml}
|
||||
</div>
|
||||
</div>
|
||||
EOF
|
||||
// Add entry
|
||||
$oOutput->AddHtml(<<<HTML
|
||||
<div class="caselog-thread--block-entry" id="{$sEntryId}">
|
||||
<div class="caselog-thread--block-entry-content">{$sEntryHtml}</div>
|
||||
<div class="caselog-thread--block-entry-date">{$sEntryDatetime}</div>
|
||||
<div class="caselog-thread--block-entry-toggler"><span class="fas fa-caret-up" title="{$sCloseEntryTooltip}"></span></div>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
|
||||
// Close user block if next user is different or if last entry or if next entry is for another date
|
||||
if (($i === $iLastLoopIndex)
|
||||
|| ($i < $iLastLoopIndex && $iEntryUserId !== $aEntries[$i + 1]['user_id'])
|
||||
|| ($i < $iLastLoopIndex && $sEntryDate !== AttributeDate::GetFormat()->Format($aEntries[$i + 1]['date']))) {
|
||||
// Close entries and block
|
||||
$oOutput->AddHtml(<<<HTML
|
||||
</div>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
}
|
||||
|
||||
// Update current loop informations
|
||||
$sLastDate = $sEntryDate;
|
||||
$sLastUserId = $iEntryUserId;
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Close thread content and thread
|
||||
$oOutput->AddHtml(<<<HTML
|
||||
</div>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
|
||||
// Add JS handlers
|
||||
$oOutput->AddJs(<<<JS
|
||||
$('[data-field-id="{$this->oField->GetId()}"][data-form-path="{$this->oField->GetFormPath()}"]')
|
||||
.on('click', '.caselog-thread--block-entry-toggler, .caselog-thread--block-entry.closed', function(){
|
||||
$(this).closest('.caselog-thread--block-entry').toggleClass('closed');
|
||||
})
|
||||
.on('click', '.caselog-thread--open-all-toggler', function(oEvent){
|
||||
oEvent.preventDefault()
|
||||
$('[data-field-id="{$this->oField->GetId()}"][data-form-path="{$this->oField->GetFormPath()}"]').find('.caselog-thread--block-entry').removeClass('closed');
|
||||
})
|
||||
.on('click', '.caselog-thread--close-all-toggler', function(oEvent){
|
||||
oEvent.preventDefault()
|
||||
$('[data-field-id="{$this->oField->GetId()}"][data-form-path="{$this->oField->GetFormPath()}"]').find('.caselog-thread--block-entry').addClass('closed');
|
||||
});
|
||||
JS
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user