mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 10:38:45 +02:00
N°930 Better UI on object details part 1. (Careful, Bulf modify and CSV import might be partly broken...)
SVN:trunk[4814]
This commit is contained in:
@@ -629,6 +629,7 @@ EOF
|
||||
// Compute the list of properties to display, first the attributes in the 'details' list, then
|
||||
// all the remaining attributes that are not external fields
|
||||
$sHtml = '';
|
||||
$sEditMode = ($bEditMode) ? 'edit' : 'view';
|
||||
$aDetails = array();
|
||||
$iInputId = 0;
|
||||
$aFieldsMap = array();
|
||||
@@ -639,9 +640,18 @@ EOF
|
||||
foreach($aDetailsStruct as $sTab => $aCols )
|
||||
{
|
||||
$aDetails[$sTab] = array();
|
||||
ksort($aCols);
|
||||
$aTableStyles[] = 'vertical-align:top';
|
||||
|
||||
ksort($aCols);
|
||||
$iColCount = count($aCols);
|
||||
if($iColCount > 1)
|
||||
{
|
||||
$aTableStyles[] = 'width: 100%';
|
||||
}
|
||||
// Else, will size regarding the largest field of the column
|
||||
|
||||
$oPage->SetCurrentTab(Dict::S($sTab));
|
||||
$oPage->add('<table style="vertical-align:top"><tr>');
|
||||
$oPage->add('<table style="'.implode('; ', $aTableStyles).'" data-mode="'.$sEditMode.'"><tr>');
|
||||
foreach($aCols as $sColIndex => $aFieldsets)
|
||||
{
|
||||
$oPage->add('<td style="vertical-align:top">');
|
||||
@@ -651,7 +661,7 @@ EOF
|
||||
$aDetails[$sTab][$sColIndex] = array();
|
||||
foreach($aFieldsets as $sFieldsetName => $aFields)
|
||||
{
|
||||
if (!empty($sFieldsetName) && ($sFieldsetName[0] != '_'))
|
||||
if (!empty($sFieldsetName) && ($sFieldsetName[0] != '_'))
|
||||
{
|
||||
$sLabel = $sFieldsetName;
|
||||
}
|
||||
@@ -680,8 +690,8 @@ EOF
|
||||
{
|
||||
|
||||
|
||||
$sComments = isset($aFieldsComments[$sAttCode]) ? $aFieldsComments[$sAttCode] : ' ';
|
||||
$sInfos = ' ';
|
||||
$sComments = isset($aFieldsComments[$sAttCode]) ? $aFieldsComments[$sAttCode] : '';
|
||||
$sInfos = '';
|
||||
$iFlags = $this->GetFormAttributeFlags($sAttCode);
|
||||
if (array_key_exists($sAttCode, $aExtraFlags))
|
||||
{
|
||||
@@ -698,7 +708,7 @@ EOF
|
||||
{
|
||||
// State attribute is always read-only from the UI
|
||||
$sHTMLValue = $this->GetStateLabel();
|
||||
$val = array('label' => '<span>'.$oAttDef->GetLabel().'</span>', 'value' => $sHTMLValue, 'comments' => $sComments, 'infos' => $sInfos);
|
||||
$val = array('label' => '<label>'.$oAttDef->GetLabel().'</label>', 'value' => $sHTMLValue, 'comments' => $sComments, 'infos' => $sInfos, 'attcode' => $sAttCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -732,17 +742,28 @@ EOF
|
||||
$sValue = $this->Get($sAttCode);
|
||||
$sDisplayValue = $this->GetEditValue($sAttCode);
|
||||
$aArgs = array('this' => $this, 'formPrefix' => $sPrefix);
|
||||
$sHTMLValue = "<span id=\"field_{$sInputId}\">".self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).'</span>';
|
||||
$sHTMLValue = "<div id=\"field_{$sInputId}\" class=\"field_value_container\">".self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).'</div>';
|
||||
}
|
||||
$aFieldsMap[$sAttCode] = $sInputId;
|
||||
$val = array('label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().'</span>', 'value' => $sHTMLValue, 'comments' => $sComments, 'infos' => $sInfos);
|
||||
$val = array('label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().'</span>', 'value' => $sHTMLValue, 'comments' => $sComments, 'infos' => $sInfos, 'attcode' => $sAttCode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$val = array('label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().'</span>', 'value' => "<span id=\"field_{$sInputId}\">".$this->GetAsHTML($sAttCode)."</span>", 'comments' => $sComments, 'infos' => $sInfos);
|
||||
$val = array('label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().'</span>', 'value' => "<span id=\"field_{$sInputId}\">".$this->GetAsHTML($sAttCode)."</span>", 'comments' => $sComments, 'infos' => $sInfos, 'attcode' => $sAttCode);
|
||||
$aFieldsMap[$sAttCode] = $sInputId;
|
||||
}
|
||||
|
||||
// Checking how the field should be rendered
|
||||
// Note: For view mode, this is done in cmdbAbstractObject::GetFieldAsHtml()
|
||||
if(in_array($oAttDef->GetEditClass(), array('Text', 'HTML', 'CaseLog', 'CustomFields')))
|
||||
{
|
||||
$val['layout'] = 'large';
|
||||
}
|
||||
else
|
||||
{
|
||||
$val['layout'] = 'small';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -761,7 +782,7 @@ EOF
|
||||
|
||||
if ($val != null)
|
||||
{
|
||||
// The field is visible, add it to the current column
|
||||
// The field is visible, add it to the current column
|
||||
$aDetails[$sTab][$sColIndex][] = $val;
|
||||
$iInputId++;
|
||||
}
|
||||
@@ -1786,7 +1807,7 @@ EOF
|
||||
$aEventsList[] ='change';
|
||||
$sPlaceholderValue = 'placeholder="'.htmlentities(AttributeDate::GetFormat()->ToPlaceholder(), ENT_QUOTES, 'UTF-8').'"';
|
||||
|
||||
$sHTMLValue = "<input title=\"$sHelpText\" class=\"date-pick\" type=\"text\" size=\"12\" $sPlaceholderValue name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"".htmlentities($sDisplayValue, ENT_QUOTES, 'UTF-8')."\" id=\"$iId\"/> {$sValidationSpan}{$sReloadSpan}";
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_date\"><input title=\"$sHelpText\" class=\"date-pick\" type=\"text\" $sPlaceholderValue name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"".htmlentities($sDisplayValue, ENT_QUOTES, 'UTF-8')."\" id=\"$iId\"/></div>{$sValidationSpan}{$sReloadSpan}";
|
||||
break;
|
||||
|
||||
case 'DateTime':
|
||||
@@ -1795,7 +1816,7 @@ EOF
|
||||
$aEventsList[] ='change';
|
||||
|
||||
$sPlaceholderValue = 'placeholder="'.htmlentities(AttributeDateTime::GetFormat()->ToPlaceholder(), ENT_QUOTES, 'UTF-8').'"';
|
||||
$sHTMLValue = "<input title=\"$sHelpText\" class=\"datetime-pick\" type=\"text\" size=\"19\" $sPlaceholderValue name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"".htmlentities($sDisplayValue, ENT_QUOTES, 'UTF-8')."\" id=\"$iId\"/> {$sValidationSpan}{$sReloadSpan}";
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_datetime\"><input title=\"$sHelpText\" class=\"datetime-pick\" type=\"text\" size=\"19\" $sPlaceholderValue name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"".htmlentities($sDisplayValue, ENT_QUOTES, 'UTF-8')."\" id=\"$iId\"/></div>{$sValidationSpan}{$sReloadSpan}";
|
||||
break;
|
||||
|
||||
case 'Duration':
|
||||
@@ -1819,7 +1840,7 @@ EOF
|
||||
$aEventsList[] ='validate';
|
||||
$aEventsList[] ='keyup';
|
||||
$aEventsList[] ='change';
|
||||
$sHTMLValue = "<input title=\"$sHelpText\" type=\"password\" size=\"30\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"".htmlentities($value, ENT_QUOTES, 'UTF-8')."\" id=\"$iId\"/> {$sValidationSpan}{$sReloadSpan}";
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_password\"><input title=\"$sHelpText\" type=\"password\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"".htmlentities($value, ENT_QUOTES, 'UTF-8')."\" id=\"$iId\"/></div>{$sValidationSpan}{$sReloadSpan}";
|
||||
break;
|
||||
|
||||
case 'OQLExpression':
|
||||
@@ -1828,10 +1849,10 @@ EOF
|
||||
$aEventsList[] ='keyup';
|
||||
$aEventsList[] ='change';
|
||||
$sEditValue = $oAttDef->GetEditValue($value);
|
||||
|
||||
$aStyles = array();
|
||||
$sStyle = '';
|
||||
$sWidth = $oAttDef->GetWidth('width', '');
|
||||
|
||||
if (!empty($sWidth))
|
||||
{
|
||||
$aStyles[] = 'width:'.$sWidth;
|
||||
@@ -1845,6 +1866,7 @@ EOF
|
||||
{
|
||||
$sStyle = 'style="'.implode('; ', $aStyles).'"';
|
||||
}
|
||||
|
||||
if ($oAttDef->GetEditClass() == 'OQLExpression')
|
||||
{
|
||||
$sTestResId = 'query_res_'.$sFieldPrefix.$sAttCode.$sNameSuffix; //$oPage->GetUniqueId();
|
||||
@@ -1858,7 +1880,7 @@ EOF
|
||||
$sAdditionalStuff = "";
|
||||
}
|
||||
// Ok, the text area is drawn here
|
||||
$sHTMLValue = "<table><tr><td><textarea class=\"resizable\" title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" rows=\"8\" cols=\"40\" id=\"$iId\" $sStyle>".htmlentities($sEditValue, ENT_QUOTES, 'UTF-8')."</textarea>$sAdditionalStuff</td><td>{$sValidationSpan}{$sReloadSpan}</td></tr></table>";
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_text\"><textarea class=\"\" title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" rows=\"8\" cols=\"40\" id=\"$iId\" $sStyle>".htmlentities($sEditValue, ENT_QUOTES, 'UTF-8')."</textarea>$sAdditionalStuff</div>{$sValidationSpan}{$sReloadSpan}";
|
||||
|
||||
break;
|
||||
|
||||
@@ -1879,12 +1901,14 @@ EOF
|
||||
{
|
||||
$sStyle = 'style="'.implode('; ', $aStyles).'"';
|
||||
}
|
||||
|
||||
$sHeader = '<div class="caselog_input_header"></div>'; // will be hidden in CSS (via :empty) if it remains empty
|
||||
$sEditValue = is_object($value) ? $value->GetModifiedEntry('html') : '';
|
||||
$sPreviousLog = is_object($value) ? $value->GetAsHTML($oPage, true /* bEditMode */, array('AttributeText', 'RenderWikiHtml')) : '';
|
||||
$iEntriesCount = is_object($value) ? count($value->GetIndex()) : 0;
|
||||
$sHidden = "<input type=\"hidden\" id=\"{$iId}_count\" value=\"$iEntriesCount\"/>"; // To know how many entries the case log already contains
|
||||
$sHTMLValue = "<div class=\"caselog\" $sStyle><table style=\"width:100%;\"><tr><td>$sHeader<textarea class=\"htmlEditor\" style=\"border:0;width:100%\" title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" rows=\"8\" cols=\"40\" id=\"$iId\">".htmlentities($sEditValue, ENT_QUOTES, 'UTF-8')."</textarea>$sPreviousLog</td><td>{$sValidationSpan}{$sReloadSpan}</td></tr></table>$sHidden</div>";
|
||||
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_caselog caselog\" $sStyle>$sHeader<textarea class=\"htmlEditor\" style=\"border:0;width:100%\" title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" rows=\"8\" cols=\"40\" id=\"$iId\">".htmlentities($sEditValue, ENT_QUOTES, 'UTF-8')."</textarea>$sPreviousLog</div>{$sValidationSpan}{$sReloadSpan}$sHidden";
|
||||
$oPage->add_ready_script("$('#$iId').bind('keyup change validate', function(evt, sFormId) { return ValidateCaseLogField('$iId', $bMandatory, sFormId) } );"); // Custom validation function
|
||||
break;
|
||||
|
||||
@@ -1919,10 +1943,13 @@ EOF
|
||||
$sFileName = $oDocument->GetFileName();
|
||||
}
|
||||
$iMaxFileSize = utils::ConvertToBytes(ini_get('upload_max_filesize'));
|
||||
$sHTMLValue = "<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"$iMaxFileSize\" />\n";
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_document\">\n";
|
||||
$sHTMLValue .= "<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"$iMaxFileSize\" />\n";
|
||||
$sHTMLValue .= "<input name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}[filename]\" type=\"hidden\" id=\"$iId\" \" value=\"".htmlentities($sFileName, ENT_QUOTES, 'UTF-8')."\"/>\n";
|
||||
$sHTMLValue .= "<span id=\"name_$iInputId\">".htmlentities($sFileName, ENT_QUOTES, 'UTF-8')."</span><br/>\n";
|
||||
$sHTMLValue .= "<input title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}[fcontents]\" type=\"file\" id=\"file_$iId\" onChange=\"UpdateFileName('$iId', this.value)\"/> {$sValidationSpan}{$sReloadSpan}\n";
|
||||
$sHTMLValue .= "<span id=\"name_$iInputId\"'>".htmlentities($sFileName, ENT_QUOTES, 'UTF-8')."</span><br/>\n";
|
||||
$sHTMLValue .= "<input title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}[fcontents]\" type=\"file\" id=\"file_$iId\" onChange=\"UpdateFileName('$iId', this.value)\"/>\n";
|
||||
$sHTMLValue .= "</div>\n";
|
||||
$sHTMLValue .= "{$sValidationSpan}{$sReloadSpan}\n";
|
||||
break;
|
||||
|
||||
case 'Image':
|
||||
@@ -1940,8 +1967,8 @@ EOF
|
||||
$sUrl = $sDefaultUrl;
|
||||
}
|
||||
|
||||
$sHTMLValue = "<div id=\"edit_$iInputId\" class=\"edit-image\"></div>";
|
||||
$sHTMLValue .= " {$sValidationSpan}{$sReloadSpan}\n";
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_image\"><div id=\"edit_$iInputId\" class=\"edit-image\"></div></div>\n";
|
||||
$sHTMLValue .= "{$sValidationSpan}{$sReloadSpan}\n";
|
||||
|
||||
$aEditImage = array(
|
||||
'input_name' => 'attr_'.$sFieldPrefix.$sAttCode.$sNameSuffix,
|
||||
@@ -2075,7 +2102,7 @@ EOF
|
||||
|
||||
case 'select':
|
||||
default:
|
||||
$sHTMLValue = "<select title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" id=\"$iId\">\n";
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_string\"><select title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" id=\"$iId\">\n";
|
||||
$sHTMLValue .= "<option value=\"\">".Dict::S('UI:SelectOne')."</option>\n";
|
||||
foreach($aAllowedValues as $key => $display_value)
|
||||
{
|
||||
@@ -2090,13 +2117,13 @@ EOF
|
||||
}
|
||||
$sHTMLValue .= "<option value=\"$key\"$sSelected>$display_value</option>\n";
|
||||
}
|
||||
$sHTMLValue .= "</select> {$sValidationSpan}{$sReloadSpan}\n";
|
||||
$sHTMLValue .= "</select></div>{$sValidationSpan}{$sReloadSpan}\n";
|
||||
$aEventsList[] ='change';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHTMLValue = "<input title=\"$sHelpText\" type=\"text\" size=\"30\" maxlength=\"$iFieldSize\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"".htmlentities($sDisplayValue, ENT_QUOTES, 'UTF-8')."\" id=\"$iId\"/> {$sValidationSpan}{$sReloadSpan}";
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_string\"><input title=\"$sHelpText\" type=\"text\" maxlength=\"$iFieldSize\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}\" value=\"".htmlentities($sDisplayValue, ENT_QUOTES, 'UTF-8')."\" id=\"$iId\"/></div>{$sValidationSpan}{$sReloadSpan}";
|
||||
$aEventsList[] ='keyup';
|
||||
$aEventsList[] ='change';
|
||||
}
|
||||
@@ -2763,7 +2790,18 @@ EOF
|
||||
{
|
||||
$sDisplayValue = $this->GetAsHTML($sAttCode);
|
||||
}
|
||||
$retVal = array('label' => '<span title="'.MetaModel::GetDescription($sClass, $sAttCode).'">'.MetaModel::GetLabel($sClass, $sAttCode).'</span>', 'value' => $sDisplayValue);
|
||||
$retVal = array('label' => '<span title="'.MetaModel::GetDescription($sClass, $sAttCode).'">'.MetaModel::GetLabel($sClass, $sAttCode).'</span>', 'value' => $sDisplayValue, 'attcode' => $sAttCode);
|
||||
|
||||
// Checking how the field should be rendered
|
||||
// Note: For edit mode, this is done in self::GetBareProperties()
|
||||
if(in_array($oAttDef->GetEditClass(), array('Text', 'HTML', 'CaseLog', 'CustomFields')))
|
||||
{
|
||||
$retVal['layout'] = 'large';
|
||||
}
|
||||
else
|
||||
{
|
||||
$retVal['layout'] = 'small';
|
||||
}
|
||||
}
|
||||
return $retVal;
|
||||
}
|
||||
|
||||
@@ -236,7 +236,9 @@ EOF;
|
||||
// note: each action implemented here must be idempotent,
|
||||
// because this helper function might be called several times on a given page
|
||||
|
||||
$(".date-pick").datepicker($sJSDatePickerOptions);
|
||||
// Note: Trigger image is wrapped in a span so we can display it we want
|
||||
$(".date-pick").datepicker($sJSDatePickerOptions)
|
||||
.next("img").wrap("<span>");
|
||||
|
||||
// Hack for the date and time picker addon issue on Chrome (see #1305)
|
||||
// The workaround is to instantiate the widget on demand
|
||||
@@ -244,7 +246,7 @@ EOF;
|
||||
$(".datetime-pick:not(.is-widget-ready)").each(function(){
|
||||
var oInput = this;
|
||||
$(oInput).addClass('is-widget-ready');
|
||||
$('<img class="datetime-pick-button" src="../images/calendar.png">')
|
||||
$('<span><img class="datetime-pick-button" src="../images/calendar.png"></span>')
|
||||
.insertAfter($(this))
|
||||
.on('click', function(){
|
||||
$(oInput)
|
||||
|
||||
@@ -116,7 +116,7 @@ class UIExtKeyWidget
|
||||
$sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
|
||||
|
||||
$sHTMLValue = "<span style=\"white-space:nowrap\">"; // no wrap
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey\">";
|
||||
$sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL());
|
||||
if($this->bSearchMode)
|
||||
{
|
||||
@@ -144,14 +144,14 @@ class UIExtKeyWidget
|
||||
$oAllowedValues->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
if ($oAllowedValues->Count() < $iMaxComboLength)
|
||||
{
|
||||
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||
switch($sDisplayStyle)
|
||||
{
|
||||
case 'radio':
|
||||
case 'radio_horizontal':
|
||||
case 'radio_vertical':
|
||||
$sValidationField = "<span id=\"v_{$this->iId}\"></span><span id=\"fstatus_{$this->iId}\"></span>";
|
||||
$sHTMLValue = '';
|
||||
$sValidationField = null;
|
||||
|
||||
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
||||
$bExtensions = false;
|
||||
$oAllowedValues->Rewind();
|
||||
@@ -160,7 +160,7 @@ class UIExtKeyWidget
|
||||
{
|
||||
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
||||
}
|
||||
$sHTMLValue = $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", $bMandatory, $bVertical, $sValidationField);
|
||||
$sHTMLValue .= $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", false /* $bMandatory will be placed manually */, $bVertical, $sValidationField);
|
||||
$aEventsList[] ='change';
|
||||
break;
|
||||
|
||||
@@ -170,25 +170,27 @@ class UIExtKeyWidget
|
||||
$sSelectMode = 'true';
|
||||
|
||||
$sHelpText = ''; //$this->oAttDef->GetHelpOnEdition();
|
||||
|
||||
$sHTMLValue .= "<div class=\"field_select_wrapper\">\n";
|
||||
|
||||
if ($this->bSearchMode)
|
||||
{
|
||||
if ($bSearchMultiple)
|
||||
{
|
||||
$sHTMLValue = "<select class=\"multiselect\" multiple title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}[]\" id=\"$this->iId\">\n";
|
||||
$sHTMLValue .= "<select class=\"multiselect\" multiple title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}[]\" id=\"$this->iId\">\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHTMLValue = "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\">\n";
|
||||
$sHTMLValue .= "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\">\n";
|
||||
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : Dict::S('UI:SearchValue:Any');
|
||||
$sHTMLValue .= "<option value=\"\">$sDisplayValue</option>\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHTMLValue = "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\">\n";
|
||||
$sHTMLValue .= "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\">\n";
|
||||
$sHTMLValue .= "<option value=\"\">".Dict::S('UI:SelectOne')."</option>\n";
|
||||
}
|
||||
|
||||
$oAllowedValues->Rewind();
|
||||
while($oObj = $oAllowedValues->Fetch())
|
||||
{
|
||||
@@ -207,6 +209,8 @@ class UIExtKeyWidget
|
||||
$sHTMLValue .= "<option value=\"$key\"$sSelected>$display_value</option>\n";
|
||||
}
|
||||
$sHTMLValue .= "</select>\n";
|
||||
$sHTMLValue .= "</div>\n";
|
||||
|
||||
if (($this->bSearchMode) && $bSearchMultiple)
|
||||
{
|
||||
$aOptions = array(
|
||||
@@ -257,8 +261,8 @@ EOF
|
||||
$iFieldSize = isset($aArgs['iFieldSize']) ? $aArgs['iFieldSize'] : 20; //@@@ $this->oAttDef->GetMaxSize();
|
||||
|
||||
// the input for the auto-complete
|
||||
$sHTMLValue = "<input count=\"".$oAllowedValues->Count()."\" type=\"text\" id=\"label_$this->iId\" size=\"$iFieldSize\" value=\"$sDisplayValue\"/> ";
|
||||
$sHTMLValue .= "<img id=\"mini_search_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_search.gif?itopversion=".ITOP_VERSION."\" onClick=\"oACWidget_{$this->iId}.Search();\"/>";
|
||||
$sHTMLValue .= "<input class=\"field_autocomplete\" count=\"".$oAllowedValues->Count()."\" type=\"text\" id=\"label_$this->iId\" value=\"$sDisplayValue\"/>";
|
||||
$sHTMLValue .= "<span class=\"field_input_btn\"><img id=\"mini_search_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_search.gif?itopversion=".ITOP_VERSION."\" onClick=\"oACWidget_{$this->iId}.Search();\"/></span>";
|
||||
|
||||
// another hidden input to store & pass the object's Id
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"$this->iId\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"".htmlentities($value, ENT_QUOTES, 'UTF-8')."\" />\n";
|
||||
@@ -282,7 +286,7 @@ EOF
|
||||
}
|
||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||
{
|
||||
$sHTMLValue .= "<img id=\"mini_tree_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_tree.gif?itopversion=".ITOP_VERSION."\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"/> ";
|
||||
$sHTMLValue .= "<span class=\"field_input_btn\"><img id=\"mini_tree_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_tree.gif?itopversion=".ITOP_VERSION."\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"/></span>";
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||
@@ -294,7 +298,7 @@ EOF
|
||||
}
|
||||
if ($bCreate && $bExtensions)
|
||||
{
|
||||
$sHTMLValue .= "<img id=\"mini_add_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_add.gif?itopversion=".ITOP_VERSION."\" onClick=\"oACWidget_{$this->iId}.CreateObject();\"/> ";
|
||||
$sHTMLValue .= "<span class=\"field_input_btn\"><img id=\"mini_add_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_add.gif?itopversion=".ITOP_VERSION."\" onClick=\"oACWidget_{$this->iId}.CreateObject();\"/></span>";
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
if ($('#ajax_{$this->iId}').length == 0)
|
||||
@@ -304,11 +308,14 @@ EOF
|
||||
EOF
|
||||
);
|
||||
}
|
||||
if (($sDisplayStyle == 'select') || ($sDisplayStyle == 'list'))
|
||||
{
|
||||
$sHTMLValue .= "<span id=\"v_{$this->iId}\"></span><span id=\"fstatus_{$this->iId}\"></span>";
|
||||
}
|
||||
$sHTMLValue .= "</span>"; // end of no wrap
|
||||
$sHTMLValue .= "</div>";
|
||||
|
||||
// Note: This test is no longer necessary as we changed the markup to extract validation decoration in the standard .field_input_xxx container
|
||||
//if (($sDisplayStyle == 'select') || ($sDisplayStyle == 'list'))
|
||||
//{
|
||||
$sHTMLValue .= "<span class=\"form_validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
|
||||
//}
|
||||
|
||||
return $sHTMLValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class UIHTMLEditorWidget
|
||||
$sHelpText = $this->m_sHelpText;
|
||||
$sValidationField = $this->m_sValidationField;
|
||||
|
||||
$sHtmlValue = "<table><tr><td><textarea class=\"htmlEditor\" title=\"$sHelpText\" name=\"attr_{$this->m_sFieldPrefix}{$sCode}\" rows=\"10\" cols=\"10\" id=\"$iId\">$sValue</textarea></td><td>$sValidationField</td></tr></table>";
|
||||
$sHtmlValue = "<div class=\"field_input_zone field_input_html\"><textarea class=\"htmlEditor\" title=\"$sHelpText\" name=\"attr_{$this->m_sFieldPrefix}{$sCode}\" rows=\"10\" cols=\"10\" id=\"$iId\">$sValue</textarea></div>$sValidationField";
|
||||
|
||||
// Replace the text area with CKEditor
|
||||
// To change the default settings of the editor,
|
||||
|
||||
@@ -345,27 +345,38 @@ class WebPage implements Page
|
||||
*/
|
||||
public function GetDetails($aFields)
|
||||
{
|
||||
$sHtml = "<table class=\"details\">\n";
|
||||
$sHtml .= "<tbody>\n";
|
||||
$sHtml = "<div class=\"details\">\n";
|
||||
foreach($aFields as $aAttrib)
|
||||
{
|
||||
$sHtml .= "<tr>\n";
|
||||
$sHtml .= "<div class=\"field_container field_{$aAttrib['layout']}\" data-attcode=\"{$aAttrib['attcode']}\">\n";
|
||||
$sHtml .= "<div class=\"field_label label\">{$aAttrib['label']}</div>\n";
|
||||
|
||||
$sHtml .= "<div class=\"field_data\">\n";
|
||||
// By Rom, for csv import, proposed to show several values for column selection
|
||||
if (is_array($aAttrib['value']))
|
||||
{
|
||||
$sHtml .= "<td class=\"label\">".$aAttrib['label']."</td><td>".implode("</td><td>", $aAttrib['value'])."</td>\n";
|
||||
$sHtml .= "<div class=\"field_value\">".implode("</div><div>", $aAttrib['value'])."</div>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= "<td class=\"label\">".$aAttrib['label']."</td><td>".$aAttrib['value']."</td>\n";
|
||||
$sHtml .= "<div class=\"field_value\">".$aAttrib['value']."</div>\n";
|
||||
}
|
||||
$sComment = (isset($aAttrib['comments'])) ? $aAttrib['comments'] : ' ';
|
||||
$sInfo = (isset($aAttrib['infos'])) ? $aAttrib['infos'] : ' ';
|
||||
$sHtml .= "<td>$sComment</td><td>$sInfo</td>\n";
|
||||
$sHtml .= "</tr>\n";
|
||||
// Checking if we should add comments & infos
|
||||
$sComment = (isset($aAttrib['comments'])) ? $aAttrib['comments'] : '';
|
||||
$sInfo = (isset($aAttrib['infos'])) ? $aAttrib['infos'] : '';
|
||||
if($sComment !== '')
|
||||
{
|
||||
$sHtml .= "<div class=\"field_comments\">$sComment</div>\n";
|
||||
}
|
||||
if($sInfo !== '')
|
||||
{
|
||||
$sHtml .= "<div class=\"field_infos\">$sInfo</div>\n";
|
||||
}
|
||||
$sHtml .= "</div>\n";
|
||||
|
||||
$sHtml .= "</div>\n";
|
||||
}
|
||||
$sHtml .= "</tbody>\n";
|
||||
$sHtml .= "</table>\n";
|
||||
$sHtml .= "</div>\n";
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
|
||||
@@ -1138,21 +1138,165 @@ span.form_validation {
|
||||
margin-top: 0.25em;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
table.details {
|
||||
.details {
|
||||
border-collapse: collapse;
|
||||
noborder-bottom: 2px #fff solid;
|
||||
nowidth: 100%;
|
||||
}
|
||||
table.details > tbody > tr > td {
|
||||
border-bottom: 2px #ddd solid;
|
||||
padding-bottom: 5px;
|
||||
padding-top: 3px;
|
||||
.details * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
fieldset table.details > tbody > tr > td {
|
||||
padding-top: 3px;
|
||||
.details > .field_container {
|
||||
display: table;
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
border-bottom: 2px #ddd solid;
|
||||
/* .field_label, .field_data */
|
||||
}
|
||||
.details > .field_container:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.details > .field_container.field_large {
|
||||
display: inherit;
|
||||
/* .field_label, .field_data */
|
||||
}
|
||||
.details > .field_container.field_large > div {
|
||||
display: inherit;
|
||||
/* .field_value, .field_comments, .field_infos */
|
||||
}
|
||||
.details > .field_container.field_large > div.field_label {
|
||||
width: inherit;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.details > .field_container > div {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
/* .field_value, .field_comments, .field_infos */
|
||||
}
|
||||
.details > .field_container > div.field_label {
|
||||
width: 30%;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.details > .field_container > div.field_label > label, .details > .field_container > div.field_label span {
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
.details > .field_container > div.field_data {
|
||||
display: table;
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.details > .field_container > div > div {
|
||||
display: table-cell;
|
||||
width: auto;
|
||||
}
|
||||
.details > .field_container > div > div.field_comments, .details > .field_container > div > div.field_infos {
|
||||
width: 20px;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit {
|
||||
display: table;
|
||||
width: 100%;
|
||||
/* TODO: Refactor so status icon show over mandatory icon */
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .form_validation, .details > .field_container > div > div.field_value .attribute-edit .field_status {
|
||||
display: table-cell;
|
||||
width: 20px;
|
||||
padding-left: 0.4em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone {
|
||||
width: 100%;
|
||||
/* auto; */
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_string > select, .details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_password > select, .details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_string input, .details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_password input {
|
||||
width: 100%;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_date, .details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_datetime {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_date > input, .details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_datetime > input {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_date > span, .details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_datetime > span {
|
||||
display: table-cell;
|
||||
width: 20px;
|
||||
padding-left: 0.4em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_date > span > img, .details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_datetime > span > img {
|
||||
max-width: 16px;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_text {
|
||||
border: none;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_text textarea {
|
||||
width: 100%;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_document > input {
|
||||
width: 100%;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_document > span {
|
||||
display: inline-block;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_image input {
|
||||
width: 100%;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_extkey {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_extkey > .field_select_wrapper {
|
||||
display: table-cell;
|
||||
width: auto;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_extkey > .field_select_wrapper > select {
|
||||
width: 100%;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_extkey > .field_autocomplete {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_extkey > .field_input_btn {
|
||||
display: table-cell;
|
||||
width: 25px;
|
||||
padding-left: 0.4em;
|
||||
}
|
||||
.details > .field_container > div > div.field_value .attribute-edit .field_input_zone.field_input_extkey > .field_input_btn > img {
|
||||
max-width: 20px;
|
||||
}
|
||||
fieldset .details > .field_container {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
#SiloSelection {
|
||||
padding-top: 3px;
|
||||
padding-right: 30px;
|
||||
text-align: left;
|
||||
}
|
||||
#SiloSelection * {
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#SiloSelection .field_input_extkey {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
#SiloSelection .field_input_extkey .field_select_wrapper {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
}
|
||||
#SiloSelection .field_input_extkey .field_select_wrapper > select {
|
||||
width: 100%;
|
||||
max-width: initial;
|
||||
}
|
||||
#SiloSelection .field_input_extkey .field_input_btn {
|
||||
display: table-cell;
|
||||
width: 20px;
|
||||
margin-left: 0.4em;
|
||||
}
|
||||
.ac_dlg_loading {
|
||||
background: white url('../images/indicator.gif') right center no-repeat;
|
||||
}
|
||||
|
||||
@@ -1227,21 +1227,232 @@ span.form_validation {
|
||||
margin-top: 0.25em;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
table.details {
|
||||
|
||||
.details {
|
||||
border-collapse: collapse;
|
||||
noborder-bottom: 2px #fff solid;
|
||||
nowidth:100%;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
> .field_container {
|
||||
display: table;
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
border-bottom: 2px #ddd solid;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
&.field_large{
|
||||
display: inherit;
|
||||
|
||||
/* .field_label, .field_data */
|
||||
> div {
|
||||
display: inherit;
|
||||
|
||||
&.field_label{
|
||||
width: inherit;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
/* .field_value, .field_comments, .field_infos */
|
||||
> div {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* .field_label, .field_data */
|
||||
> div {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
|
||||
&.field_label {
|
||||
width: 30%;
|
||||
padding-right: 10px;
|
||||
|
||||
> label,span {
|
||||
color: #000000;
|
||||
font-weight:bold;
|
||||
}
|
||||
}
|
||||
|
||||
&.field_data {
|
||||
display: table;
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
/* .field_value, .field_comments, .field_infos */
|
||||
> div {
|
||||
display: table-cell;
|
||||
width: auto;
|
||||
|
||||
&.field_comments,
|
||||
&.field_infos{
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
&.field_value{
|
||||
|
||||
.attribute-edit{
|
||||
display: table;
|
||||
width: 100%;
|
||||
|
||||
/* TODO: Refactor so status icon show over mandatory icon */
|
||||
.form_validation, .field_status{
|
||||
display: table-cell;
|
||||
width: 20px;
|
||||
padding-left: 0.4em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.field_input_zone{
|
||||
width: 100%; /* auto; */
|
||||
|
||||
&.field_input_string,
|
||||
&.field_input_password{
|
||||
> select, input{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.field_input_onewaypassword{
|
||||
// Not implemented yet
|
||||
}
|
||||
|
||||
&.field_input_date,
|
||||
&.field_input_datetime{
|
||||
display: table;
|
||||
width: 100%;
|
||||
|
||||
> input {
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
> span {
|
||||
display: table-cell;
|
||||
width: 20px;
|
||||
padding-left: 0.4em;
|
||||
vertical-align: middle;
|
||||
|
||||
> img {
|
||||
max-width: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.field_input_text{
|
||||
border: none;
|
||||
|
||||
//.f_i_text_header{
|
||||
// padding: 6px 8px 2px;
|
||||
// white-space: normal;
|
||||
// border-bottom: 1px solid #fff;
|
||||
// background: #f2f2f2;
|
||||
//}
|
||||
textarea{
|
||||
width: 100%;
|
||||
//padding: 5px;
|
||||
//border: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.field_input_html{
|
||||
// Nothing
|
||||
}
|
||||
|
||||
&.field_input_document{
|
||||
> input{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
> span {
|
||||
display: inline-block;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
&.field_input_image{
|
||||
input{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.field_input_extkey{
|
||||
display: table;
|
||||
width: 100%;
|
||||
|
||||
> .field_select_wrapper{
|
||||
display: table-cell;
|
||||
width: auto;
|
||||
|
||||
> select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
> .field_autocomplete{
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
> .field_input_btn{
|
||||
display: table-cell;
|
||||
width: 25px;
|
||||
padding-left: 0.4em;
|
||||
|
||||
> img {
|
||||
max-width: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
table.details>tbody>tr>td {
|
||||
border-bottom: 2px #ddd solid;
|
||||
padding-bottom: 5px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
fieldset table.details>tbody>tr>td {
|
||||
padding-top: 3px;
|
||||
fieldset .details>.field_container {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
#SiloSelection{
|
||||
padding-top: 3px;
|
||||
padding-right: 30px;
|
||||
text-align: left;
|
||||
|
||||
*{
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.field_input_extkey{
|
||||
display: table;
|
||||
width: 100%;
|
||||
|
||||
.field_select_wrapper{
|
||||
display: table-cell;
|
||||
width: 100%;
|
||||
|
||||
> select{
|
||||
width: 100%;
|
||||
max-width: initial;
|
||||
}
|
||||
}
|
||||
|
||||
.field_input_btn{
|
||||
display: table-cell;
|
||||
width: 20px;
|
||||
margin-left: 0.4em;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ac_dlg_loading {
|
||||
background: white url('../images/indicator.gif') right center no-repeat;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user