diff --git a/application/dashboardlayout.class.inc.php b/application/dashboardlayout.class.inc.php index 013f162f1..1211b09a5 100644 --- a/application/dashboardlayout.class.inc.php +++ b/application/dashboardlayout.class.inc.php @@ -151,7 +151,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout } $iCellIdx++; } - $sJSReload .= $oDashboardRow->GetJSRefreshCallback()."\n"; + $sJSReload .= $oDashboardRow->GetJSRefreshCallback()." "; } $oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}"); diff --git a/application/forms.class.inc.php b/application/forms.class.inc.php index af6f945b0..e65cf38b3 100644 --- a/application/forms.class.inc.php +++ b/application/forms.class.inc.php @@ -102,23 +102,21 @@ class DesignerForm $sReturn .= '
'; $sReturn .= ''.$sLabel.''; } - foreach($aFields as $oField) - { + foreach($aFields as $oField) { $aRow = $oField->Render($oP, $sFormId); - if ($oField->IsVisible()) - { + if ($oField->IsVisible()) { $sValidation = ''.$this->GetValidationArea($oField->GetFieldId()).''; $sField = $aRow['value'].$sValidation; $aDetails[] = array('label' => $aRow['label'], 'value' => $sField); - } - else - { + } else { $sHiddenFields .= $aRow['value']; } } + $sReturn .= '
'; $sReturn .= $oP->GetDetails($aDetails); - if ($sLabel != '') - { + $sReturn .= '
'; + + if ($sLabel != '') { $sReturn .= '
'; } } @@ -1304,6 +1302,7 @@ EOF ); } return array('label' => $this->sLabel, 'value' => $sHtml); + } public function ReadParam(&$aValues) diff --git a/core/bulkexport.class.inc.php b/core/bulkexport.class.inc.php index dec6973e9..aa0de46be 100644 --- a/core/bulkexport.class.inc.php +++ b/core/bulkexport.class.inc.php @@ -369,20 +369,36 @@ abstract class BulkExport utils::PopArchiveMode(); } } - + public function EnumFormParts() { return array(); } - + + /** + * @deprecated since 3.0 replaced by GetFormPart + */ public function DisplayFormPart(WebPage $oP, $sPartId) { + $oP->AddSubBlock($this->GetFormPart($oP, $sPartId)); } - + + + /** + * @param \WebPage $oP + * @param $sPartId + * + * @return UIContentBlock + */ + public function GetFormPart(WebPage $oP, $sPartId) + { + } + public function DisplayUsage(Page $oP) { - + } + public function ReadParameters() { $this->bLocalizeOutput = !((bool)utils::ReadParam('no_localize', 0, true, 'integer')); diff --git a/core/csvbulkexport.class.inc.php b/core/csvbulkexport.class.inc.php index fad0c38f0..42f9bc539 100644 --- a/core/csvbulkexport.class.inc.php +++ b/core/csvbulkexport.class.inc.php @@ -15,6 +15,12 @@ // // You should have received a copy of the GNU Affero General Public License // along with iTop. If not, see +use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSetUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Html\Html; +use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory; /** * Bulk export: CSV export @@ -22,7 +28,6 @@ * @copyright Copyright (C) 2015-2016 Combodo SARL * @license http://opensource.org/licenses/AGPL-3.0 */ - class CSVBulkExport extends TabularBulkExport { public function DisplayUsage(Page $oP) @@ -100,21 +105,34 @@ class CSVBulkExport extends TabularBulkExport public function EnumFormParts() { - return array_merge(parent::EnumFormParts(), array('csv_options' => array('separator', 'charset', 'text-qualifier', 'no_localize', 'formatted_text') ,'interactive_fields_csv' => array('interactive_fields_csv'))); + return array_merge(parent::EnumFormParts(), array('csv_options' => array('separator', 'charset', 'text-qualifier', 'no_localize', 'formatted_text'), 'interactive_fields_csv' => array('interactive_fields_csv'))); } - public function DisplayFormPart(WebPage $oP, $sPartId) + /** + * @param \WebPage $oP + * @param $sPartId + * + * @return UIContentBlock + */ + public function GetFormPart(WebPage $oP, $sPartId) { - switch($sPartId) - { + switch ($sPartId) { case 'interactive_fields_csv': - $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_csv'); + return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_csv'); break; case 'csv_options': - $oP->add('
'.Dict::S('Core:BulkExport:CSVOptions').''); - $oP->add('
'); - $oP->add('

'.Dict::S('UI:CSVImport:SeparatorCharacter').'

'); + $oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:CSVOptions')); + + $oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard(); + $oMulticolumn->AddCSSClass('ibo-multi-column'); + $oPanel->AddSubBlock($oMulticolumn); + + //SeparatorCharacter + $oFieldSetSeparator = FieldSetUIBlockFactory::MakeStandard(Dict::S('UI:CSVImport:SeparatorCharacter')); + $oFieldSetSeparator->AddCSSClass('ibo-column'); + $oMulticolumn->AddSubBlock($oFieldSetSeparator); + $sRawSeparator = utils::ReadParam('separator', ',', true, 'raw_data'); $sCustomDateTimeFormat = utils::ReadParam('', ',', true, 'raw_data'); $aSep = array( @@ -123,22 +141,25 @@ class CSVBulkExport extends TabularBulkExport 'tab' => Dict::S('UI:CSVImport:SeparatorTab+'), ); $sOtherSeparator = ''; - if (!array_key_exists($sRawSeparator, $aSep)) - { + if (!array_key_exists($sRawSeparator, $aSep)) { $sOtherSeparator = $sRawSeparator; $sRawSeparator = 'other'; } $aSep['other'] = Dict::S('UI:CSVImport:SeparatorOther').' '; - foreach($aSep as $sVal => $sLabel) - { - $sChecked = ($sVal == $sRawSeparator) ? 'checked' : ''; - $oP->add(' '.$sLabel.'
'); + foreach ($aSep as $sVal => $sLabel) { + $oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "separator", htmlentities($sVal, ENT_QUOTES, 'UTF-8'), $sLabel, "radio"); + $oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator)); + $oRadio->SetBeforeInput(false); + $oRadio->AddCSSClass('ibo-input--label-right'); + $oFieldSetSeparator->AddSubBlock($oRadio); + $oFieldSetSeparator->AddSubBlock(new Html('
')); } - - $oP->add('
'); - - $oP->add('

'.Dict::S('UI:CSVImport:TextQualifierCharacter').'

'); + + //TextQualifierCharacter + $oFieldSetTextQualifier = FieldSetUIBlockFactory::MakeStandard(Dict::S('UI:CSVImport:TextQualifierCharacter')); + $oFieldSetTextQualifier->AddCSSClass('ibo-column'); + $oMulticolumn->AddSubBlock($oFieldSetTextQualifier); $sRawQualifier = utils::ReadParam('text-qualifier', '"', true, 'raw_data'); $aQualifiers = array( @@ -146,60 +167,77 @@ class CSVBulkExport extends TabularBulkExport '\'' => Dict::S('UI:CSVImport:QualifierSimpleQuote+'), ); $sOtherQualifier = ''; - if (!array_key_exists($sRawQualifier, $aQualifiers)) - { + if (!array_key_exists($sRawQualifier, $aQualifiers)) { $sOtherQualifier = $sRawQualifier; $sRawQualifier = 'other'; } $aQualifiers['other'] = Dict::S('UI:CSVImport:QualifierOther').' '; - - foreach($aQualifiers as $sVal => $sLabel) - { - $sChecked = ($sVal == $sRawQualifier) ? 'checked' : ''; - $oP->add(' '.$sLabel.'
'); + + foreach ($aQualifiers as $sVal => $sLabel) { + $oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "separator", htmlentities($sVal, ENT_QUOTES, 'UTF-8'), $sLabel, "radio"); + $oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator)); + $oRadio->SetBeforeInput(false); + $oRadio->GetInput()->AddCSSClass('ibo-input--label-right'); + $oFieldSetTextQualifier->AddSubBlock($oRadio); + $oFieldSetTextQualifier->AddSubBlock(new Html('
')); } - - $sChecked = (utils::ReadParam('no_localize', 0) == 1) ? ' checked ' : ''; - $oP->add('
'); - $oP->add('

'.Dict::S('Core:BulkExport:CSVLocalization').'

'); - $oP->add(''); - $oP->add('
'); - $oP->add('
'); - $oP->add(Dict::S('UI:CSVImport:Encoding').': '); + //markup + $oFieldSetMarkup = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:TextFormat')); + $oFieldSetMarkup->AddCSSClass('ibo-column'); + $oMulticolumn->AddSubBlock($oFieldSetMarkup); + + $oCheckBoxMarkup = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionFormattedText'), "formatted_text", "1", "csv_formatted_text", "checkbox"); + $oCheckBoxMarkup->GetInput()->SetIsChecked((utils::ReadParam('formatted_text', 0) == 1)); + $oCheckBoxMarkup->SetBeforeInput(false); + $oFieldSetMarkup->AddSubBlock($oCheckBoxMarkup); + + //date format + $oFieldSetDate = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:DateTimeFormat')); + $oFieldSetDate->AddCSSClass('ibo-column'); + $oMulticolumn->AddSubBlock($oFieldSetDate); - $sChecked = (utils::ReadParam('formatted_text', 0) == 1) ? ' checked ' : ''; - $oP->add('

'.Dict::S('Core:BulkExport:TextFormat').'

'); - $oP->add(''); - $oP->add('
'); - $sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data'); - $sDefaultChecked = ($sDateTimeFormat == (string)AttributeDateTime::GetFormat()) ? ' checked' : ''; - $sCustomChecked = ($sDateTimeFormat !== (string)AttributeDateTime::GetFormat()) ? ' checked' : ''; - $oP->add('

'.Dict::S('Core:BulkExport:DateTimeFormat').'

'); + $sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8'); $sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8'); - $oP->add('
'); - $sFormatInput = ''; - $oP->add(''); - $oP->add('
'); - - $oP->add('
'); + $oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "csv_custom_date_time_format", "default", "csv_date_time_format_default", "radio"); + $oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat())); + $oRadioDefault->SetBeforeInput(false); + $oFieldSetDate->AddSubBlock($oRadioDefault); + $oFieldSetDate->AddSubBlock(new Html('
')); + + $sFormatInput = ''; + $oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "csv_custom_date_time_format", "custom", "csv_date_time_format_custom", "radio"); + $oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat()); + $oRadioCustom->SetBeforeInput(false); + $oFieldSetDate->AddSubBlock($oRadioCustom); + $sJSTooltip = json_encode('
'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'
'); $oP->add_ready_script( -<<aStatusInfo['date_format'] = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data'); break; - + default: - // Export from the command line (or scripted) => default format is SQL, as in previous versions of iTop, unless specified otherwise - $this->aStatusInfo['date_format'] = utils::ReadParam('date_format', (string)AttributeDateTime::GetSQLFormat(), true, 'raw_data'); + // Export from the command line (or scripted) => default format is SQL, as in previous versions of iTop, unless specified otherwise + $this->aStatusInfo['date_format'] = utils::ReadParam('date_format', (string)AttributeDateTime::GetSQLFormat(), true, 'raw_data'); } } - + public function EnumFormParts() { - return array_merge(parent::EnumFormParts(), array('xlsx_options' => array('formatted_text') ,'interactive_fields_xlsx' => array('interactive_fields_xlsx'))); + return array_merge(parent::EnumFormParts(), array('xlsx_options' => array('formatted_text'), 'interactive_fields_xlsx' => array('interactive_fields_xlsx'))); } - public function DisplayFormPart(WebPage $oP, $sPartId) + /** + * @param \WebPage $oP + * @param $sPartId + * + * @return UIContentBlock + */ + public function GetFormPart(WebPage $oP, $sPartId) { - switch($sPartId) - { + switch ($sPartId) { case 'interactive_fields_xlsx': - $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_xlsx'); + return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_xlsx'); break; - + case 'xlsx_options': - $oP->add('
'.Dict::S('Core:BulkExport:XLSXOptions').''); - $oP->add('
'); - - $sChecked = (utils::ReadParam('formatted_text', 0) == 1) ? ' checked ' : ''; - $oP->add('

'.Dict::S('Core:BulkExport:TextFormat').'

'); - $oP->add(''); - - $oP->add('
'); - + $oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:XLSXOptions')); + + $oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard(); + $oMulticolumn->AddCSSClass('ibo-multi-column'); + $oPanel->AddSubBlock($oMulticolumn); + + $oFieldSetFormat = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:TextFormat')); + $oFieldSetFormat->AddCSSClass('ibo-column'); + $oMulticolumn->AddSubBlock($oFieldSetFormat); + + $oCheckBox = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionFormattedText'), "formatted_text", "1", "xlsx_formatted_text", "checkbox"); + $oCheckBox->GetInput()->SetIsChecked((utils::ReadParam('formatted_text', 0) == 1)); + $oCheckBox->SetBeforeInput(false); + $oFieldSetFormat->AddSubBlock($oCheckBox); + + $oFieldSetDate = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:DateTimeFormat')); + $oFieldSetDate->AddCSSClass('ibo-column'); + $oMulticolumn->AddSubBlock($oFieldSetDate); + $sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data'); - $sDefaultChecked = ($sDateTimeFormat == (string)AttributeDateTime::GetFormat()) ? ' checked' : ''; - $sCustomChecked = ($sDateTimeFormat !== (string)AttributeDateTime::GetFormat()) ? ' checked' : ''; - $oP->add('

'.Dict::S('Core:BulkExport:DateTimeFormat').'

'); + $sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8'); $sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8'); - $oP->add('
'); + $oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "excel_date_format_radio", "default", "excel_date_time_format_default", "radio"); + $oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat())); + $oRadioDefault->SetBeforeInput(false); + $oFieldSetDate->AddSubBlock($oRadioDefault); + $oFieldSetDate->AddSubBlock(new Html('
')); + $sFormatInput = ''; - $oP->add(''); - - $oP->add('
'); - - $oP->add('
'); + $oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "excel_date_format_radio", "custom", "excel_date_time_format_custom", "radio"); + $oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat()); + $oRadioCustom->SetBeforeInput(false); + $oFieldSetDate->AddSubBlock($oRadioCustom); + + $sJSTooltip = json_encode('
'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'
'); $oP->add_ready_script( -<< array('interactive_fields_html'))); } - public function DisplayFormPart(WebPage $oP, $sPartId) + /** + * @param \WebPage $oP + * @param $sPartId + * + * @return UIContentBlock + */ + public function GetFormPart(WebPage $oP, $sPartId) { - switch($sPartId) - { + switch ($sPartId) { case 'interactive_fields_html': - $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_html'); + return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_html'); break; - + default: - return parent:: DisplayFormPart($oP, $sPartId); + return parent:: GetFormPart($oP, $sPartId); } } diff --git a/core/pdfbulkexport.class.inc.php b/core/pdfbulkexport.class.inc.php index 5f8df7c6d..9738a8098 100644 --- a/core/pdfbulkexport.class.inc.php +++ b/core/pdfbulkexport.class.inc.php @@ -15,6 +15,12 @@ // // You should have received a copy of the GNU Affero General Public License // along with iTop. If not, see +use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSetUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Html\Html; +use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory; /** * Bulk export: PDF export, based on the HTML export converted to PDF @@ -22,7 +28,6 @@ * @copyright Copyright (C) 2015 Combodo SARL * @license http://opensource.org/licenses/AGPL-3.0 */ - class PDFBulkExport extends HTMLBulkExport { public function DisplayUsage(Page $oP) @@ -39,43 +44,72 @@ class PDFBulkExport extends HTMLBulkExport return array_merge(array('pdf_options' => array('pdf_options')), parent::EnumFormParts()); } - public function DisplayFormPart(WebPage $oP, $sPartId) + /** + * @param \WebPage $oP + * @param $sPartId + * + * @return UIContentBlock + */ + public function GetFormPart(WebPage $oP, $sPartId) { - switch($sPartId) - { + switch ($sPartId) { case 'pdf_options': - $oP->add('
'.Dict::S('Core:BulkExport:PDFOptions').''); - $oP->add('
'); - $oP->add('

'.Dict::S('Core:BulkExport:PDFPageFormat').'

'); - $oP->add(''); - $oP->add(''); - $oP->add(''); - $oP->add(''); - $oP->add(''); - $oP->add(''); - $oP->add(''); - $oP->add(''); - $oP->add('
'.Dict::S('Core:BulkExport:PDFPageSize').''.$this->GetSelectCtrl('page_size', array('A3', 'A4', 'Letter'), 'Core:BulkExport:PageSize-', 'A4').'
'.Dict::S('Core:BulkExport:PDFPageOrientation').''.$this->GetSelectCtrl('page_orientation', array('P', 'L'), 'Core:BulkExport:PageOrientation-', 'L').'
'); - - $oP->add('
'); - + $oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:PDFOptions')); + + $oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard(); + $oMulticolumn->AddCSSClass('ibo-multi-column'); + $oPanel->AddSubBlock($oMulticolumn); + + $oFieldSetFormat = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:PDFPageFormat')); + $oFieldSetFormat->AddCSSClass('ibo-column'); + $oMulticolumn->AddSubBlock($oFieldSetFormat); + + //page format + $oSelectFormat = InputUIBlockFactory::MakeForSelectWithLabel("page_size", Dict::S('Core:BulkExport:PDFPageSize')); + $oSelectFormat->SetBeforeInput(false); + $oFieldSetFormat->AddSubBlock($oSelectFormat); + + $aPossibleFormat = ['A3', 'A4', 'Letter']; + $sDefaultFormat = 'A4'; + foreach ($aPossibleFormat as $sVal) { + $oSelectFormat->GetInput()->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption($sVal, htmlentities(Dict::S('Core:BulkExport:PageSize-'.$sVal), ENT_QUOTES, 'UTF-8'), ($sVal == $sDefaultFormat))); + } + $oFieldSetFormat->AddSubBlock(new Html('
')); + + $oSelectOrientation = InputUIBlockFactory::MakeForSelectWithLabel("page_size", Dict::S('Core:BulkExport:PDFPageOrientation')); + $oSelectOrientation->SetBeforeInput(false); + $oFieldSetFormat->AddSubBlock($oSelectOrientation); + + $aPossibleOrientation = ['P', 'L']; + $sDefaultOrientation = 'L'; + foreach ($aPossibleOrientation as $sVal) { + $oSelectOrientation->GetInput()->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption($sVal, htmlentities(Dict::S('Core:BulkExport:PageOrientation-'.$sVal), ENT_QUOTES, 'UTF-8'), ($sVal == $sDefaultOrientation))); + } + + //date format + $oFieldSetDate = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:DateTimeFormat')); + $oFieldSetDate->AddCSSClass('ibo-column'); + $oMulticolumn->AddSubBlock($oFieldSetDate); + $sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data'); - $sDefaultChecked = ($sDateTimeFormat == (string)AttributeDateTime::GetFormat()) ? ' checked' : ''; - $sCustomChecked = ($sDateTimeFormat !== (string)AttributeDateTime::GetFormat()) ? ' checked' : ''; - $oP->add('

'.Dict::S('Core:BulkExport:DateTimeFormat').'

'); + $sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8'); $sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8'); - $oP->add('
'); - $sFormatInput = ''; - $oP->add(''); - - $oP->add('
'); - - - $oP->add('
'); + $oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "pdf_custom_date_time_format", "default", "pdf_date_time_format_default", "radio"); + $oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat())); + $oRadioDefault->SetBeforeInput(false); + $oFieldSetDate->AddSubBlock($oRadioDefault); + $oFieldSetDate->AddSubBlock(new Html('
')); + + $sFormatInput = ''; + $oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "pdf_custom_date_time_format", "custom", "pdf_date_time_format_custom", "radio"); + $oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat()); + $oRadioCustom->SetBeforeInput(false); + $oFieldSetDate->AddSubBlock($oRadioCustom); + $sJSTooltip = json_encode('
'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'
'); $oP->add_ready_script( -<<'; - foreach($aLabels as $sVal => $sLabel) - { - $sSelected = ($sVal == $sCurrentValue) ? 'selected' : ''; - $sHtml .= ''; - } - $sHtml .= ''; - return $sHtml; - } - public function ReadParameters() { diff --git a/core/spreadsheetbulkexport.class.inc.php b/core/spreadsheetbulkexport.class.inc.php index 84bf35b8d..89c3c0a5a 100644 --- a/core/spreadsheetbulkexport.class.inc.php +++ b/core/spreadsheetbulkexport.class.inc.php @@ -15,14 +15,18 @@ // // You should have received a copy of the GNU Affero General Public License // along with iTop. If not, see +use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSetUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Html\Html; +use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory; /** * Bulk export: "spreadsheet" export: a simplified HTML export in which the date/time columns are split in two column: date AND time -* -* @copyright Copyright (C) 2015 Combodo SARL -* @license http://opensource.org/licenses/AGPL-3.0 -*/ - + * + * @copyright Copyright (C) 2015 Combodo SARL + * @license http://opensource.org/licenses/AGPL-3.0 + */ class SpreadsheetBulkExport extends TabularBulkExport { public function DisplayUsage(Page $oP) @@ -36,50 +40,67 @@ class SpreadsheetBulkExport extends TabularBulkExport public function EnumFormParts() { - return array_merge(parent::EnumFormParts(), array('spreadsheet_options' => array('no-localize') ,'interactive_fields_spreadsheet' => array('interactive_fields_spreadsheet'))); + return array_merge(parent::EnumFormParts(), array('spreadsheet_options' => array('no-localize'), 'interactive_fields_spreadsheet' => array('interactive_fields_spreadsheet'))); } - public function DisplayFormPart(WebPage $oP, $sPartId) + /** + * @param \WebPage $oP + * @param $sPartId + * + * @return UIContentBlock + */ + public function GetFormPart(WebPage $oP, $sPartId) { - switch($sPartId) - { + switch ($sPartId) { case 'interactive_fields_spreadsheet': - $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_spreadsheet'); + return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_spreadsheet'); break; - - case 'spreadsheet_options': - $sChecked = (utils::ReadParam('no_localize', 0) == 1) ? ' checked ' : ''; - $oP->add('
'.Dict::S('Core:BulkExport:SpreadsheetOptions').''); - $oP->add(''); - $oP->add(''); - $oP->add(''); + case 'spreadsheet_options': + $oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:SpreadsheetOptions')); + + $oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard(); + $oMulticolumn->AddCSSClass('ibo-multi-column'); + $oPanel->AddSubBlock($oMulticolumn); + + $oFieldSetFormat = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:TextFormat')); + $oFieldSetFormat->AddCSSClass('ibo-column'); + $oMulticolumn->AddSubBlock($oFieldSetFormat); + + $oCheckBox = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionFormattedText'), "formatted_text", "1", "spreadsheet_formatted_text", "checkbox"); + $oCheckBox->GetInput()->SetIsChecked((utils::ReadParam('formatted_text', 0) == 1)); + $oCheckBox->SetBeforeInput(false); + $oFieldSetFormat->AddSubBlock($oCheckBox); + $oFieldSetFormat->AddSubBlock(new Html('
')); + + $oCheckBox = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionNoLocalize'), "no_localize", "1", "spreadsheet_no_localize", "checkbox"); + $oCheckBox->GetInput()->SetIsChecked((utils::ReadParam('no_localize', 0) == 1)); + $oCheckBox->SetBeforeInput(false); + $oFieldSetFormat->AddSubBlock($oCheckBox); + + $oFieldSetDate = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:DateTimeFormat')); + $oFieldSetDate->AddCSSClass('ibo-column'); + $oMulticolumn->AddSubBlock($oFieldSetDate); $sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data'); - $sDefaultChecked = ($sDateTimeFormat == (string)AttributeDateTime::GetFormat()) ? ' checked' : ''; - $sCustomChecked = ($sDateTimeFormat !== (string)AttributeDateTime::GetFormat()) ? ' checked' : ''; - $oP->add(''); + $oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "spreadsheet_date_format_radio", "default", "spreadsheet_date_time_format_default", "radio"); + $oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat())); + $oRadioDefault->SetBeforeInput(false); + $oFieldSetDate->AddSubBlock($oRadioDefault); + $oFieldSetDate->AddSubBlock(new Html('
')); + + $sFormatInput = ''; + $oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "spreadsheet_date_format_radio", "custom", "spreadsheet_date_time_format_custom", "radio"); + $oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat()); + $oRadioCustom->SetBeforeInput(false); + $oFieldSetDate->AddSubBlock($oRadioCustom); - $oP->add(''); - $oP->add('
'); - $sChecked = (utils::ReadParam('formatted_text', 1) == 1) ? ' checked ' : ''; - $oP->add('

'.Dict::S('Core:BulkExport:TextFormat').'

'); - $oP->add(''); // Trick to pass the zero value if the checkbox below is unchecked, since we want the default value to be "1" - $oP->add('

'); - $oP->add(''); - $oP->add('
'); - $oP->add('

'.Dict::S('Core:BulkExport:DateTimeFormat').'

'); $sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8'); $sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8'); - $oP->add('
'); - $sFormatInput = ''; - $oP->add(''); - $oP->add('
'); - $oP->add('
'); $sJSTooltip = json_encode('
'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'
'); $oP->add_ready_script( - << +use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory; /** * Bulk export: Tabular export: abstract base class for all "tabular" exports. @@ -23,7 +24,6 @@ * @copyright Copyright (C) 2015 Combodo SARL * @license http://opensource.org/licenses/AGPL-3.0 */ - abstract class TabularBulkExport extends BulkExport { public function EnumFormParts() @@ -31,23 +31,30 @@ abstract class TabularBulkExport extends BulkExport return array_merge(parent::EnumFormParts(), array('tabular_fields' => array('fields'))); } - public function DisplayFormPart(WebPage $oP, $sPartId) + /** + * @param \WebPage $oP + * @param $sPartId + * + * @return UIContentBlock + */ + public function GetFormPart(WebPage $oP, $sPartId) { - switch($sPartId) - { + switch ($sPartId) { case 'tabular_fields': $sFields = utils::ReadParam('fields', '', true, 'raw_data'); $sSuggestedFields = utils::ReadParam('suggested_fields', null, true, 'raw_data'); - if (($sSuggestedFields !== null) && ($sSuggestedFields !== '')) - { + if (($sSuggestedFields !== null) && ($sSuggestedFields !== '')) { $aSuggestedFields = explode(',', $sSuggestedFields); $sFields = implode(',', $this->SuggestFields($aSuggestedFields)); } $oP->add(''); + + //TODO 3.0 test + return null; break; - + default: - return parent::DisplayFormPart($oP, $sPartId); + return parent::GetFormPart($oP, $sPartId); } } @@ -272,7 +279,6 @@ abstract class TabularBulkExport extends BulkExport } } - $oP->add('
'); $JSAllFields = json_encode($aAllFieldsByAlias); // First, fetch only the ids - the rest will be fetched by an object reload @@ -321,10 +327,14 @@ abstract class TabularBulkExport extends BulkExport ); $sJSLabels = json_encode($aLabels); $oP->add_ready_script( -<<AddCSSClass('ibo-tabularbulkexport'); + + return $oUIContentBlock; } static public function SortOnLabel($aItem1, $aItem2) diff --git a/core/xmlbulkexport.class.inc.php b/core/xmlbulkexport.class.inc.php index 6c5d6bdb6..09bda227a 100644 --- a/core/xmlbulkexport.class.inc.php +++ b/core/xmlbulkexport.class.inc.php @@ -15,6 +15,9 @@ // // You should have received a copy of the GNU Affero General Public License // along with iTop. If not, see +use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory; /** * Bulk export: XML export @@ -22,7 +25,6 @@ * @copyright Copyright (C) 2015-2017 Combodo SARL * @license http://opensource.org/licenses/AGPL-3.0 */ - class XMLBulkExport extends BulkExport { public function DisplayUsage(Page $oP) @@ -36,28 +38,39 @@ class XMLBulkExport extends BulkExport { return array_merge(parent::EnumFormParts(), array('xml_options' => array('xml_no_options'))); } - - public function DisplayFormPart(WebPage $oP, $sPartId) + + /** + * @param \WebPage $oP + * @param $sPartId + * + * @return UIContentBlock + */ + public function GetFormPart(WebPage $oP, $sPartId) { - switch($sPartId) - { + switch ($sPartId) { case 'xml_options': - $sNoLocalizeChecked = (utils::ReadParam('no_localize', 0) == 1) ? ' checked ' : ''; - $sLinksetChecked = (utils::ReadParam('linksets', 0) == 1) ? ' checked ' : ''; - $oP->add('
'.Dict::S('Core:BulkExport:XMLOptions').''); - $oP->add(''); - $oP->add(''); - $oP->add(''); - $oP->add(''); - $oP->add(''); - $oP->add(''); - $oP->add(''); - $oP->add('
'); - $oP->add('
'); + + $oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:XMLOptions')); + + $oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard(); + $oMulticolumn->AddCSSClass('ibo-multi-column'); + $oPanel->AddSubBlock($oMulticolumn); + + $oCheckBoxLocalize = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionNoLocalize'), "no_localize", "1", "xml_no_localize", "checkbox"); + $oCheckBoxLocalize->GetInput()->SetIsChecked((utils::ReadParam('no_localize', 0) == 1)); + $oCheckBoxLocalize->SetBeforeInput(false); + $oPanel->AddSubBlock($oCheckBoxLocalize); + + $oCheckBoxLink = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionLinkSets'), "linksets", "1", "xml_linksets", "checkbox"); + $oCheckBoxLink->GetInput()->SetIsChecked((utils::ReadParam('linksets', 0) == 1)); + $oCheckBoxLink->SetBeforeInput(false); + $oPanel->AddSubBlock($oCheckBoxLink); + + return $oPanel; break; - + default: - return parent:: DisplayFormPart($oP, $sPartId); + return parent:: GetFormPart($oP, $sPartId); } } diff --git a/css/backoffice/components/_button.scss b/css/backoffice/components/_button.scss index 8d8ac943a..c3d0c2a52 100644 --- a/css/backoffice/components/_button.scss +++ b/css/backoffice/components/_button.scss @@ -8,15 +8,18 @@ $ibo-button--box-shadow-top: inset 0px 2px 0px !default; $ibo-button--label--margin-left: 4px !default; +$ibo-button--vertical-align--margin-bottom: 4px !default; +$ibo-button--vertical-align--margin-top: 4px !default; + $ibo-button-colors: ( - 'regular': ( - /* Semantics */ - 'neutral': ( - '': ( - $ibo-color-secondary-100, - $ibo-color-grey-900, - $ibo-button--box-shadow-bottom $ibo-color-secondary-300, - ), + 'regular': ( + /* Semantics */ + 'neutral': ( + '': ( + $ibo-color-secondary-100, + $ibo-color-grey-900, + $ibo-button--box-shadow-bottom $ibo-color-secondary-300, + ), ':hover': ( $ibo-color-secondary-200, $ibo-color-grey-900, @@ -399,13 +402,18 @@ $ibo-button-colors: ( margin-left: $ibo-button--sibling-spacing; } - &.ibo-action-button { - float: right; - } + &.ibo-action-button { + float: right; + } } /* Only when a button has both an icon and a label */ .ibo-button--icon + .ibo-button--label { - margin-left: $ibo-button--label--margin-left; + margin-left: $ibo-button--label--margin-left; +} + +.ibo-button--vertical-align { + margin-top: $ibo-button--vertical-align--margin-top; + margin-bottom: $ibo-button--vertical-align--margin-bottom; } diff --git a/css/backoffice/components/_datatable.scss b/css/backoffice/components/_datatable.scss index d4e794109..cc9291a4b 100644 --- a/css/backoffice/components/_datatable.scss +++ b/css/backoffice/components/_datatable.scss @@ -47,31 +47,34 @@ $ibo-datatable--sorting--right: 1em !default; $ibo-datatable-panel--body--padding: $ibo-panel--body--padding-top 0px $ibo-panel--body--padding-bottom !default; $ibo-datatable--selection-validation-buttons-toolbar--margin-top: 10px !default; +$ibo-list-column--max-height: 150px; + .ibo-datatable { - padding-bottom: $ibo-datatable--padding-y; - padding-top: $ibo-datatable--padding-y; + padding-bottom: $ibo-datatable--padding-y; + padding-top: $ibo-datatable--padding-y; - thead tr th, tbody tr td { - line-height: $ibo-datatable-cell-row--line-height; - padding-right: $ibo-datatable-cell-row--padding-x; - padding-left: $ibo-datatable-cell-row--padding-x; - @extend %ibo-font-ral-med-100; - a { - color: $ibo-datatable-cell-row--link--color; - } - } + thead tr th, tbody tr td { + line-height: $ibo-datatable-cell-row--line-height; + padding-right: $ibo-datatable-cell-row--padding-x; + padding-left: $ibo-datatable-cell-row--padding-x; + @extend %ibo-font-ral-med-100; - .ibo-datatable-header.sorting, .ibo-datatable-header.sorting_asc, .ibo-datatable-header.sorting_desc { - cursor: pointer; - } + a { + color: $ibo-datatable-cell-row--link--color; + } + } - tbody tr:nth-child(odd) { - background-color: $ibo-datatable-row--odd--background-color; - } + .ibo-datatable-header.sorting, .ibo-datatable-header.sorting_asc, .ibo-datatable-header.sorting_desc { + cursor: pointer; + } - tbody tr:nth-child(even) { - background-color: $ibo-datatable-row--even--background-color; - } + tbody tr:nth-child(odd) { + background-color: $ibo-datatable-row--odd--background-color; + } + + tbody tr:nth-child(even) { + background-color: $ibo-datatable-row--even--background-color; + } } .dataTables_length { @extend %ibo-font-ral-med-100; @@ -151,37 +154,47 @@ $ibo-datatable--selection-validation-buttons-toolbar--margin-top: 10px !default; box-shadow: $ibo-datatable--paginate-button-active--link--box-shadow; border-radius: $ibo-border-radius-300; } -.ibo-datatable thead tr th{ - position: relative; + +.ibo-datatable thead tr th { + position: relative; } -.ibo-datatable thead tr th.sorting::after{ - position: absolute; - font-family: "Font Awesome 5 Free"; - content: "\f0dc"; - font-weight: 900; - opacity: $ibo-datatable--sorting--opacity; - right: $ibo-datatable--sorting--right; + +.dataTables_scrollHead thead tr th.sorting::after { + position: absolute; + font-family: "Font Awesome 5 Free"; + content: "\f0dc"; + font-weight: 900; + opacity: $ibo-datatable--sorting--opacity; + right: $ibo-datatable--sorting--right; } -.ibo-datatable thead tr th.sorting_desc:after{ - position: absolute; - font-family: "Font Awesome 5 Free"; - content: "\f0d7"; - font-weight: 900; - right: $ibo-datatable--sorting--right; + +.dataTables_scrollHead thead tr th.sorting_desc:after { + position: absolute; + font-family: "Font Awesome 5 Free"; + content: "\f0d7"; + font-weight: 900; + right: $ibo-datatable--sorting--right; } -.ibo-datatable thead tr th.sorting_asc:after{ - position: absolute; - font-family: "Font Awesome 5 Free"; - font-weight: 900; - content: "\f0d8"; - right: $ibo-datatable--sorting--right; + +.dataTables_scrollHead thead tr th.sorting_asc:after { + position: absolute; + font-family: "Font Awesome 5 Free"; + font-weight: 900; + content: "\f0d8"; + right: $ibo-datatable--sorting--right; } + .ibo-datatable-panel > .ibo-panel--body { - padding: $ibo-datatable-panel--body--padding; + padding: $ibo-datatable-panel--body--padding; } // For cancel / OK / next... selection validation buttons .ibo-datatable--selection-validation-buttons-toolbar { - clear: both; + clear: both; margin-top: $ibo-datatable--selection-validation-buttons-toolbar--margin-top; } + +.ibo-list-column { + max-height: $ibo-list-column--max-height; + overflow-y: auto; +} \ No newline at end of file diff --git a/css/backoffice/components/_fieldset.scss b/css/backoffice/components/_fieldset.scss index ef0d60b90..f615f0920 100644 --- a/css/backoffice/components/_fieldset.scss +++ b/css/backoffice/components/_fieldset.scss @@ -13,7 +13,7 @@ $ibo-fieldset--legend--border-bottom-color: $ibo-color-grey-500 !default; $ibo-fieldset--legend--border-bottom-style: solid !default; .ibo-fieldset { - & ~ .ibo-fieldset { + & ~ .ibo-fieldset:not(.ibo-column) { margin-top: $ibo-fieldset--sibling-spacing; } } diff --git a/css/backoffice/components/dashlet/_dashlet.scss b/css/backoffice/components/dashlet/_dashlet.scss index 473595c66..c4fc7e301 100644 --- a/css/backoffice/components/dashlet/_dashlet.scss +++ b/css/backoffice/components/dashlet/_dashlet.scss @@ -21,3 +21,9 @@ $ibo-dashlet--elements-spacing-y: 24px !default; .ibo-dashlet--is-inline{ width: $ibo-dashlet--width--is-inline; } +.ibo-details > .ibo-prop--apply { + display: table-column; +} +.ibo-details{ + margin-top: 5px; +} \ No newline at end of file diff --git a/css/backoffice/components/input/_input-textarea.scss b/css/backoffice/components/input/_input-textarea.scss index b50d4d30a..aec469af7 100644 --- a/css/backoffice/components/input/_input-textarea.scss +++ b/css/backoffice/components/input/_input-textarea.scss @@ -1,5 +1,10 @@ $ibo-input-text-area--min-height: 4rem !default; -.ibo-input-text-area{ - min-height: $ibo-input-text-area--min-height; +.ibo-input-text-area { + min-height: $ibo-input-text-area--min-height; +} + +.ibo-input-text-area--export { + width: 100%; + min-height: 15em; } \ No newline at end of file diff --git a/css/backoffice/components/input/_input.scss b/css/backoffice/components/input/_input.scss index 6a99b1668..86f7f8e5f 100644 --- a/css/backoffice/components/input/_input.scss +++ b/css/backoffice/components/input/_input.scss @@ -26,15 +26,18 @@ $ibo-input--placeholder--color: $ibo-color-grey-700 !default; $ibo-input-wrapper--is-error--background-color: $ibo-color-red-200 !default; $ibo-input-wrapper--is-error--border-color: $ibo-color-red-600 !default; $ibo-field-validation: $ibo-color-red-700 !default; -.ibo-input{ - @extend %ibo-vertically-centered-content; - height: $ibo-input--height; - width: $ibo-input--width; - background-color: $ibo-input--background-color; - color: $ibo-input--color; - padding: $ibo-input--padding-y $ibo-input--padding-x; - border: 1px solid $ibo-input--border-color; - border-radius: $ibo-input--border-radius; + +$ibo-input--margin-x: 5px !default; + +.ibo-input { + @extend %ibo-vertically-centered-content; + height: $ibo-input--height; + width: $ibo-input--width; + background-color: $ibo-input--background-color; + color: $ibo-input--color; + padding: $ibo-input--padding-y $ibo-input--padding-x; + border: 1px solid $ibo-input--border-color; + border-radius: $ibo-input--border-radius; &:focus{ border: 1px solid $ibo-input--focus--border-color; @@ -50,13 +53,23 @@ $ibo-field-validation: $ibo-color-red-700 !default; .ibo-input-wrapper.is-error { .ibo-input{ background-color: $ibo-input-wrapper--is-error--background-color; - border: 1px solid $ibo-input-wrapper--is-error--border-color; - } + border: 1px solid $ibo-input-wrapper--is-error--border-color; + } } -.ibo-field-validation{ - color: $ibo-field-validation; + +.ibo-field-validation { + color: $ibo-field-validation; } + .file-input { - display:block; - position: relative; + display: block; + position: relative; +} + +.ibo-input--label-right { + margin-right: $ibo-input--margin-x; +} + +.ibo-input--label-left { + margin-leftt: $ibo-input--margin-x; } diff --git a/css/backoffice/layout/multi-column/_column.scss b/css/backoffice/layout/multi-column/_column.scss index 7c688bd79..8c97ef4b5 100644 --- a/css/backoffice/layout/multi-column/_column.scss +++ b/css/backoffice/layout/multi-column/_column.scss @@ -4,6 +4,7 @@ */ $ibo-column--min-width: 300px !default; +$ibo-mini-column--min-width: 30px !default; $ibo-column--padding-x: abs($ibo-multi-column--margin-x) !default; $ibo-column--padding-y: 0 !default; @@ -16,7 +17,19 @@ $ibo-column--margin-bottom--is-last-element: 48px !default; padding: $ibo-column--padding-y $ibo-column--padding-x; flex-basis: 10%; - &:not(:last-child){ + &:not(:last-child) &:not(.ibo-without-margin) { + margin-bottom: $ibo-column--margin-bottom--is-last-element; + } +} + +.ibo-mini-column { + min-width: $ibo-mini-column--min-width; + flex-grow: 1; + flex-shrink: 1; + padding: $ibo-column--padding-y $ibo-column--padding-x; + flex-basis: 10%; + + &:not(:last-child) { margin-bottom: $ibo-column--margin-bottom--is-last-element; } } diff --git a/css/backoffice/pages/_all.scss b/css/backoffice/pages/_all.scss index 7f589fc89..21d8e7e2b 100644 --- a/css/backoffice/pages/_all.scss +++ b/css/backoffice/pages/_all.scss @@ -19,4 +19,5 @@ @import "base"; @import "preferences"; @import "attachments"; +@import "tabularfieldsselector"; @import "impact-analysis"; \ No newline at end of file diff --git a/css/backoffice/pages/_tabularfieldsselector.scss b/css/backoffice/pages/_tabularfieldsselector.scss new file mode 100644 index 000000000..e550608fa --- /dev/null +++ b/css/backoffice/pages/_tabularfieldsselector.scss @@ -0,0 +1,35 @@ +/*! + * @copyright Copyright (C) 2010-2021 Combodo SARL + * @license http://opensource.org/licenses/AGPL-3.0 + */ + +.ibo-table-preview { + margin-top: 20px; + + th { + padding: 5px; + border-width: 1px 1px 0; + border-style: groove groove none; + background: $ibo-body-background-color; + } + + td { + padding-right: 5px; + padding-left: 5px; + border-width: 0 1px; + border-style: none groove; + } + + tr:last-child td { + border-bottom-width: 1px; + border-bottom-style: groove; + } +} + +.ibo-preview-header { + margin-bottom: 5px; +} + +#form_part_interactive_fields_xlsx, #form_part_interactive_fields_csv, #form_part_interactive_fields_pdf { + margin-top: $ibo-panel--spacing-top; +} diff --git a/css/backoffice/vendors/_jqueryui.scss b/css/backoffice/vendors/_jqueryui.scss index ff3763382..ace95f264 100644 --- a/css/backoffice/vendors/_jqueryui.scss +++ b/css/backoffice/vendors/_jqueryui.scss @@ -81,6 +81,7 @@ $ibo-vendors-jqueryui--ui-slider--ui-slider-handle--hover--border-color: $ibo-co .ui-dialog-content { position: relative; padding: 16px $ibo-vendors-jqueryui--ui-dialog--padding-x; + overflow: auto; } .ui-dialog-buttonpane { margin-top: auto; diff --git a/datamodels/2.x/itop-portal-base/portal/public/js/export.js b/datamodels/2.x/itop-portal-base/portal/public/js/export.js index dfd251b1d..27df60758 100644 --- a/datamodels/2.x/itop-portal-base/portal/public/js/export.js +++ b/datamodels/2.x/itop-portal-base/portal/public/js/export.js @@ -36,10 +36,10 @@ function ExportStartExport() { } function ExportError(sMessage) { - sDataState = 'error'; - $('#export-feedback').hide(); - $('#export-text-result').show(); - $('#export-error').html(sMessage); + sDataState = 'error'; + $('#export-feedback').addClass('ibo-is-hidden'); + $('#export-text-result').removeClass('ibo-is-hidden'); + $('#export-error').html(sMessage); } function ExportRun(data) { @@ -51,9 +51,9 @@ function ExportRun(data) { oParams = {}; oParams.token = data.token; if (sDataState == 'cancelled') { - oParams.operation = 'export_cancel'; - $('#export-cancel').hide(); - $('#export-close').show(); + oParams.operation = 'export_cancel'; + $('#export-cancel').addClass('ibo-is-hidden'); + $('#export-close').removeClass('ibo-is-hidden'); } else { oParams.operation = 'export_build_portal'; @@ -65,20 +65,19 @@ function ExportRun(data) { 'json'); break; - case 'done': - sDataState = 'done'; - $('#export-cancel').hide(); - $('#export-close').show(); - $('.progress').progressbar({value: data.percentage}); - sMessage = '' + data.message + ''; - $('.export-message').html(sMessage); - if (data.text_result != undefined) { - if (data.mime_type == 'text/html') { - $('#export-content').parent().html(data.text_result); - $('#export-text-result').show(); - } - else { - if ($('#export-text-result').closest('ui-dialog').length == 0) { + case 'done': + sDataState = 'done'; + $('#export-cancel').addClass('ibo-is-hidden'); + $('#export-close').removeClass('ibo-is-hidden'); + $('.progress').progressbar({value: data.percentage}); + sMessage = ''+data.message+''; + $('.export-message').html(sMessage); + if (data.text_result != undefined) { + if (data.mime_type == 'text/html') { + $('#export-content').parent().html(data.text_result); + $('#export-text-result').show(); + } else { + if ($('#export-text-result').closest('ui-dialog').length == 0) { // not inside a dialog box, adjust the height... approximately var jPane = $('#export-text-result').closest('.ui-layout-content'); var iTotalHeight = jPane.height(); @@ -89,20 +88,20 @@ function ExportRun(data) { }); $('#export-content').height(iTotalHeight - 80); } - $('#export-content').val(data.text_result); - $('#export-text-result').show(); + $('#export-content').val(data.text_result); + $('#export-text-result').removeClass('ibo-is-hidden'); } } break; - case 'error': - sDataState = 'error'; - $('#export-feedback').hide(); - $('#export-text-result').show(); - $('#export-error').html(data.message); - $('#export-cancel').hide(); - $('#export-close').show(); - break; + case 'error': + sDataState = 'error'; + $('#export-feedback').addClass('ibo-is-hidden'); + $('#export-text-result').removeClass('ibo-is-hidden'); + $('#export-error').html(data.message); + $('#export-cancel').addClass('ibo-is-hidden'); + $('#export-close').removeClass('ibo-is-hidden'); + break; default: } diff --git a/js/field_sorter.js b/js/field_sorter.js index 733756978..6eb5bfa6f 100644 --- a/js/field_sorter.js +++ b/js/field_sorter.js @@ -16,21 +16,24 @@ $(function() // the constructor _create: function() { - var me = this; + var me = this; this.element - .addClass('itop-fieldsorter'); - + .addClass('itop-fieldsorter'); + var me = this; this._initFields(); - - var width = 10+this.element.width(); - this.moveup_btn = $(''); - this.movedown_btn = $(''); - this.element.wrap('
'); - this.element.parent().append(this.moveup_btn).append(this.movedown_btn); - this.moveup_btn.click(function() { me._moveUp(); }); - this.movedown_btn.click(function() { me._moveDown(); }); + + this.moveup_btn = $(''); + this.movedown_btn = $(''); + columnWithButtons = $('
'); + this.element.parent().parent().append(columnWithButtons.append(this.moveup_btn).append('
').append(this.movedown_btn)); + this.moveup_btn.click(function () { + me._moveUp(); + }); + this.movedown_btn.click(function () { + me._moveDown(); + }); }, // called when created, and later when changing options diff --git a/js/tabularfieldsselector.js b/js/tabularfieldsselector.js index 8000d4e78..86a6f81cf 100644 --- a/js/tabularfieldsselector.js +++ b/js/tabularfieldsselector.js @@ -23,70 +23,92 @@ $(function() no_field_selected: 'Select at least one column to be exported' } }, - + // the constructor - _create: function() - { + _create: function () { var me = this; this._flatten_fields(this.options.fields); this.sId = this.element.attr('id'); - this.element - .addClass('itop-tabularfieldsselector'); - this.element.parent().bind('form-part-activate', function() { me._update_from_holder(); me._update_preview(); }); - this.element.parent().bind('validate', function() { me.validate(); }); - + this.element.addClass('itop-tabularfieldsselector'); + this.element.parent().bind('form-part-activate', function () { + me._update_from_holder(); + me._update_preview(); + }); + this.element.parent().bind('validate', function () { + me.validate(); + }); + this.aSelected = []; - - for(var i in this.options.fields) - { - var sContent = '
'+this._format(this.options.labels.columns_selection, i)+''; - sContent += '
 
'; - for(var j in this.options.fields[i]) - { - sContent += this._get_field_checkbox(this.options.fields[i][j].code, this.options.fields[i][j].label, (this.options.fields[i][j].subattr.length > 0), false, null); + + for (var i in this.options.fields) { + var sContent = `
+
+
+
`+this._format(this.options.labels.columns_selection, i)+`
+
`; + sContent += ` +
+
+ + +
+
`; + sContent += `
+
`; + for (var j in this.options.fields[i]) { + sContent += this._get_field_checkbox(this.options.fields[i][j].code, this.options.fields[i][j].label, (this.options.fields[i][j].subattr.length > 0), false, null); } - sContent += '
'; + sContent += ` + `; this.element.append(sContent); } - sContent = '
'+this.options.labels.columns_order+''; - - sContent += '
'+this._format(this.options.labels.preview_header, Math.min(this.options.preview_limit, this.options.total_count), this.options.total_count)+'
'; - sContent += '
'; - sContent += '
'; + sContent = `
+
+
+
`+this.options.labels.columns_order+`
+
+
+
`; + + + sContent += '
'+this._format(this.options.labels.preview_header, Math.min(this.options.preview_limit, this.options.total_count), this.options.total_count)+'
'; + sContent += '
'; + sContent += '
'; this.element.append(sContent); - + this._update_from_holder(); - - $('body').on('click change', '.tfs_checkbox', function() { + + $('body').on('click change', '.tfs_checkbox', function () { var sInstanceId = $(this).attr('data-instance-id'); - if (sInstanceId != me.sId) return; + if (sInstanceId != me.sId) { + return; + } me._on_click($(this)); }); - + var maxWidth = 0; - $('#'+this.sId+' .tfs_checkbox, #'+this.sId+' .tfs_checkbox_multi').each(function() { + $('#'+this.sId+' .tfs_checkbox, #'+this.sId+' .tfs_checkbox_multi').each(function () { maxWidth = Math.max(maxWidth, $(this).parent().width()); }); - $('#'+this.sId+' .tfs_checkbox, #'+this.sId+' .tfs_checkbox_multi').each(function() { + $('#'+this.sId+' .tfs_checkbox, #'+this.sId+' .tfs_checkbox_multi').each(function () { $(this).parent().parent().width(maxWidth).css({display: 'inline-block'}); }); - $('#'+this.sId+' .tfs_checkbox_multi').click(function() { + $('#'+this.sId+' .tfs_checkbox_multi').click(function () { me._on_multi_click($(this).val(), this.checked); }); - $('#'+this.sId+' .check_all').click(function() { - me._on_check_all($(this).closest('fieldset'), true); + $('#'+this.sId+' .check_all').click(function () { + me._on_check_all($(this).closest('.ibo-panel'), true); }); - $('#'+this.sId+' .uncheck_all').click(function() { - me._on_check_all($(this).closest('fieldset'), false); + $('#'+this.sId+' .uncheck_all').click(function () { + me._on_check_all($(this).closest('.ibo-panel'), false); }); - + this._update_preview(); this._make_tooltips(); }, - _on_click: function(jItemClicked) - { + _on_click: function (jItemClicked) { var bChecked = jItemClicked.prop('checked'); var sValue = jItemClicked.val(); @@ -94,19 +116,15 @@ $(function() this._update_holder(); this._update_preview(); var sDataParent = jItemClicked.attr('data-parent'); - if (sDataParent != '') - { + if (sDataParent != '') { this._update_tristate(sDataParent+'_multi'); } }, - _on_multi_click: function(sMultiFieldCode, bChecked) - { + _on_multi_click: function (sMultiFieldCode, bChecked) { var oField = this._get_main_field_by_code(sMultiFieldCode); - if (oField != null) - { + if (oField != null) { var sPrefix = '#tfs_'+this.sId+'_'; - for(var k in oField.subattr) - { + for (var k in oField.subattr) { this._mark_as_selected(oField.subattr[k].code, bChecked); // In case the tooltip is visible, also update the checkboxes sElementId = (sPrefix+oField.subattr[k].code).replace('.', '_'); @@ -116,243 +134,201 @@ $(function() this._update_preview(); } }, - _on_check_all: function(jSelector, bChecked) - { + _on_check_all: function (jSelector, bChecked) { var me = this; - jSelector.find('.tfs_checkbox').each(function() { + jSelector.find('.tfs_checkbox').each(function () { $(this).prop('checked', bChecked); me._mark_as_selected($(this).val(), bChecked); }); - jSelector.find('.tfs_checkbox_multi').each(function() { + jSelector.find('.tfs_checkbox_multi').each(function () { var oField = me._get_main_field_by_code($(this).val()); - if (oField != null) - { + if (oField != null) { $(this).prop('checked', bChecked); $(this).prop('indeterminate', false); var sPrefix = '#tfs_'+this.sId+'_'; - for(var k in oField.subattr) - { + for (var k in oField.subattr) { me._mark_as_selected(oField.subattr[k].code, bChecked); // In case the tooltip is visible, also update the checkboxes sElementId = (sPrefix+oField.subattr[k].code).replace('.', '_'); $(sElementId).prop('checked', bChecked); } - } + } }); this._update_holder(); this._update_preview(); }, - _update_tristate: function(sParentId) - { + _update_tristate: function (sParentId) { // Check if the parent is checked, unchecked or indeterminate var sParentId = sParentId.replace('.', '_'); var sAttCode = $('#'+sParentId).val(); var oField = this._get_main_field_by_code(sAttCode); - if (oField != null) - { + if (oField != null) { var iNbChecked = 0; var aDebug = []; - for(var j in oField.subattr) - { - if ($.inArray(oField.subattr[j].code, this.aSelected) != -1) - { + for (var j in oField.subattr) { + if ($.inArray(oField.subattr[j].code, this.aSelected) != -1) { aDebug.push(oField.subattr[j].code); iNbChecked++; } } - if (iNbChecked == oField.subattr.length) - { + if (iNbChecked == oField.subattr.length) { $('#'+sParentId).prop('checked', true); $('#'+sParentId).prop('indeterminate', false); - } - else if (iNbChecked == 0) - { + } else if (iNbChecked == 0) { $('#'+sParentId).prop('checked', false); $('#'+sParentId).prop('indeterminate', false); - } - else - { + } else { $('#'+sParentId).prop('checked', false); $('#'+sParentId).prop('indeterminate', true); - } - } - }, - _mark_as_selected: function(sValue, bSelected) - { - if(bSelected) - { - if ($.inArray(sValue, this.aSelected) == -1) - { - this.aSelected.push(sValue); } } - else - { + }, + _mark_as_selected: function (sValue, bSelected) { + if (bSelected) { + if ($.inArray(sValue, this.aSelected) == -1) { + this.aSelected.push(sValue); + } + } else { aSelected = []; - for(var k in this.aSelected) - { - if (this.aSelected[k] != sValue) - { + for (var k in this.aSelected) { + if (this.aSelected[k] != sValue) { aSelected.push(this.aSelected[k]); } } this.aSelected = aSelected; - } + } }, - _update_holder: function() - { + _update_holder: function () { $(this.options.value_holder).val(this.aSelected.join(',')); }, - _update_from_holder: function() - { + _update_from_holder: function () { var sFields = $(this.options.value_holder).val(); var bAdvanced = parseInt($(this.options.advanced_holder).val(), 10); - if (sFields != '') - { + if (sFields != '') { this.aSelected = sFields.split(','); var safeSelected = []; var me = this; var bModified = false; - for(var k in this.aSelected) - { + for (var k in this.aSelected) { var oField = this._get_field_by_code(this.aSelected[k]) - if (oField == null) - { + if (oField == null) { // Invalid field code supplied, don't copy it bModified = true; - } - else - { + } else { safeSelected.push(this.aSelected[k]); } } - if (bModified) - { + if (bModified) { this.aSelected = safeSelected; this._update_holder(); } - $('#'+this.sId+' .tfs_checkbox').each(function() { - if ($.inArray($(this).val(), me.aSelected) != -1) - { + $('#'+this.sId+' .tfs_checkbox').each(function () { + if ($.inArray($(this).val(), me.aSelected) != -1) { $(this).prop('checked', true); - } - else - { + } else { $(this).prop('checked', false); } }); } var me = this; - $('#'+this.sId+' .tfs_checkbox_multi').each(function() { + $('#'+this.sId+' .tfs_checkbox_multi').each(function () { me._update_tristate($(this).attr('id')); }); }, - _update_preview: function() - { + _update_preview: function () { var sHtml = ''; - if(this.aSelected.length > 0) - { + if (this.aSelected.length > 0) { sHtml += ''; - for(var k in this.aSelected) - { + for (var k in this.aSelected) { var sField = this.aSelected[k]; - if ($.inArray(sField, this.aSelected) != -1) - { + if ($.inArray(sField, this.aSelected) != -1) { var sRemoveBtn = ' ×'; - sHtml += ''; + sHtml += ''; } } sHtml += ''; - - for(var i=0; i'; - } + } sHtml += ''; } - + sHtml += '
'+this.aFieldsByCode[sField].unique_label+''+sRemoveBtn+''+this.aFieldsByCode[sField].unique_label+''+sRemoveBtn+'
'; - + $('#'+this.sId+' .preview_header').show(); - $('#'+this.sId+' .table_preview').html(sHtml); + $('#'+this.sId+' .ibo-table-preview').html(sHtml); var me = this; - $('#'+this.sId+' .table_preview table').dragtable({persistState: function(table) { me._on_drag_columns(table); }, dragHandle: '.drag-handle'}); - $('#'+this.sId+' .table_preview table .export-field-close').click( function(event) { me._on_remove_column($(this).attr('data-attcode')); event.preventDefault(); return false; } ); - } - else - { + $('#'+this.sId+' .ibo-table-preview table').dragtable({ + persistState: function (table) { + me._on_drag_columns(table); + }, dragHandle: '.drag-handle' + }); + $('#'+this.sId+' .ibo-table-preview table .export-field-close').click(function (event) { + me._on_remove_column($(this).attr('data-attcode')); + event.preventDefault(); + return false; + }); + } else { $('#'+this.sId+' .preview_header').hide(); - $('#'+this.sId+' .table_preview').html('
'+this.options.labels.empty_preview+'
'); + $('#'+this.sId+' .ibo-table-preview').html('
'+this.options.labels.empty_preview+'
'); } $('.form_part:visible').trigger('preview_updated'); }, - _get_field_by_code: function(sFieldCode) - { - for(var k in this.aFieldsByCode) - { - if (k == sFieldCode) - { + _get_field_by_code: function (sFieldCode) { + for (var k in this.aFieldsByCode) { + if (k == sFieldCode) { return this.aFieldsByCode[k]; } } return null; }, - _get_main_field_by_code: function(sFieldCode) - { - for(var i in this.options.fields) - { - for(var j in this.options.fields[i]) - { - if (this.options.fields[i][j].code == sFieldCode) - { + _get_main_field_by_code: function (sFieldCode) { + for (var i in this.options.fields) { + for (var j in this.options.fields[i]) { + if (this.options.fields[i][j].code == sFieldCode) { return this.options.fields[i][j]; } } } return null; }, - _on_drag_columns: function(table) - { + _on_drag_columns: function (table) { var me = this; me.aSelected = []; - table.el.find('th').each(function(i) { + table.el.find('th').each(function (i) { me.aSelected.push($(this).attr('data-attcode')); }); this._update_holder(); }, - _on_remove_column: function(sField) - { + _on_remove_column: function (sField) { var sElementId = this.sId+'_'+sField; sElementId = '#tfs_'+sElementId.replace('.', '_'); $(sElementId).prop('checked', false); - + this._mark_as_selected(sField, false); this._update_holder(); this._update_preview(); var me = this; - $('#'+this.sId+' .tfs_checkbox_multi').each(function() { + $('#'+this.sId+' .tfs_checkbox_multi').each(function () { me._update_tristate($(this).attr('id')); }); }, - _format: function() - { + _format: function () { var s = arguments[0]; - for (var i = 0; i < arguments.length - 1; i++) { - var reg = new RegExp("%" + (i+1) + "\\$s", "gm"); + for (var i = 0; i < arguments.length-1; i++) { + var reg = new RegExp("%"+(i+1)+"\\$s", "gm"); s = s.replace(reg, arguments[i+1]); } return s; }, - validate: function() - { - if (this.aSelected.length == 0) - { + validate: function () { + if (this.aSelected.length == 0) { var aMessages = $('#export-form').data('validation_messages'); aMessages.push(this.options.labels.no_field_selected); $('#export-form').data('validation_messages', aMessages); @@ -360,158 +336,89 @@ $(function() }, // events bound via _bind are removed automatically // revert other modifications here - destroy: function() - { + destroy: function () { this.element - .removeClass('itop-tabularfieldsselector'); - + .removeClass('itop-tabularfieldsselector'); + this.element.parent().unbind('activate'); this.element.parent().unbind('validate'); }, // _setOptions is called with a hash of all options that are changing - _setOptions: function() - { + _setOptions: function () { this._superApply(arguments); }, // _setOption is called for each individual option that is changing - _setOption: function( key, value ) - { - if (key == 'fields') - { + _setOption: function (key, value) { + if (key == 'fields') { this._flatten_fields(value); } this._superApply(arguments); }, - _flatten_fields: function(aFields) - { + _flatten_fields: function (aFields) { // Update the "flattened" via of the fields this.aFieldsByCode = {}; // Must be an object since indexes are non-numeric - for(var k in aFields) - { - for(var i in aFields[k]) - { + for (var k in aFields) { + for (var i in aFields[k]) { this.aFieldsByCode[aFields[k][i].code] = aFields[k][i]; - for(var j in aFields[k][i].subattr) - { + for (var j in aFields[k][i].subattr) { this.aFieldsByCode[aFields[k][i].subattr[j].code] = aFields[k][i].subattr[j]; } } } }, - _make_tooltips: function() - { - var me = this; - $('#'+this.sId+' .tfs_advanced').tooltip({ - content: function() { - var sDataAttcode = $(this).attr('data-attcode'); - var sTooltipContent = ''; - sTooltipContent += me._get_tooltip_content(sDataAttcode); - return sTooltipContent; - }, - items: '.tfs_advanced', - classes: { - 'ui-tooltip': 'tooltip-tfs' - }, - position: { - my: "center bottom-10", - at: "center top", - using: function( position, feedback ) { - $(this).css( position ); - $( "
" ) - .addClass( "arrow" ) - .addClass( feedback.vertical ) - .addClass( feedback.horizontal ) - .appendTo( this ); - } - } - }) - .off( "mouseover mouseout" ) - .on( "mouseover", function(event){ - event.stopImmediatePropagation(); - var jMe = $(this); - $(this).data('openTimeoutId', setTimeout(function() { - jMe.tooltip('open'); - }, 500)); - }) - .on( "mouseout", function(event){ - event.stopImmediatePropagation(); - clearTimeout($(this).data('openTimeoutId')); - }); - /* - .on( "click", function(){ - var sDataId = $(this).attr('data-attcode'); - if ($('.tooltip-close-button[data-attcode="'+sDataId+'"]').length == 0) - { - $(this).tooltip( 'open' ); - } - else - { - $(this).tooltip( 'close' ); - } - $( this ).unbind( "mouseleave" ); - return false; - }); - */ - - $('body').on('click', '.tooltip-close-button', function() { - var sDataId = $(this).attr('data-attcode'); - $('#'+me.sId+' .tfs_advanced[data-attcode="'+sDataId+'"]').tooltip('close'); - }); - this.element.parent().on("click", ":not(.tooltip-tfs *,.tooltip-tfs)", function(){ - me.close_all_tooltips(); + _make_tooltips: function () { + var me = this; + $('#'+this.sId+' .tfs_advanced').each(function (index, elt) { + var sDataAttcode = $(elt).attr('data-attcode'); + var sTooltipContent = me._get_tooltip_content(sDataAttcode); + tippy(elt, { + 'content': sTooltipContent, + allowHTML: true, + interactive: true, + zIndex: 9999, + role: 'tooltip', + popperOptions: { + strategy: 'fixed' + } + }); }); + }, - _get_tooltip_content: function(sDataAttCode) - { + _get_tooltip_content: function (sDataAttCode) { var oField = this._get_main_field_by_code(sDataAttCode); var sContent = ''; - if (oField != null) - { - sContent += '
'+oField.label+'
×
'; - for(var k in oField.subattr) - { + if (oField != null) { + sContent += '
'+oField.label+'
'; + for (var k in oField.subattr) { bChecked = ($.inArray(oField.subattr[k].code, this.aSelected) != -1); sContent += this._get_field_checkbox(oField.subattr[k].code, oField.subattr[k].label, false, bChecked, sDataAttCode); } } return sContent; }, - _get_field_checkbox: function(sCode, sLabel, bHasTooltip, bChecked, sParentId) - { + _get_field_checkbox: function (sCode, sLabel, bHasTooltip, bChecked, sParentId) { var sPrefix = 'tfs_'+this.sId+'_'; sParentId = (sPrefix+sParentId).replace('.', '_'); sElementId = (sPrefix+sCode).replace('.', '_'); var aClasses = []; - if (bHasTooltip) - { + if (bHasTooltip) { aClasses.push('tfs_advanced'); sLabel += ' [+]'; } var sChecked = ''; - if (bChecked) - { + if (bChecked) { sChecked = ' checked '; } var sDataParent = ''; - if (sParentId != null) - { + if (sParentId != null) { sDataParent = ' data-parent="'+sParentId+'" '; } - if (bHasTooltip) - { + if (bHasTooltip) { sContent = '
'; - } - else - { - sContent = '
'; + } else { + sContent = '
'; } return sContent; - }, - close_all_tooltips: function() - { - $('.tfs_advanced').each(function (i) { - $(this).tooltip("close"); - }); } - }); + }); }); diff --git a/js/utils.js b/js/utils.js index 1256c464d..b0428385b 100644 --- a/js/utils.js +++ b/js/utils.js @@ -430,13 +430,11 @@ function ExportStartExport() { if (this.checked) { oParams[this.name] = $(this).val(); } - } - else { + } else { oParams[this.name] = $(this).val(); } } }); - $(':itop-tabularfieldsselector:visible').tabularfieldsselector('close_all_tooltips'); $('#export-form').hide(); $('#export-feedback').show(); oParams.operation = 'export_build'; @@ -445,8 +443,7 @@ function ExportStartExport() { if ($(':input[name=query_mode]:checked').length > 0) { if (sQueryMode == 'oql') { oParams.expression = $('#export-form :input[name=expression]').val(); - } - else { + } else { oParams.query = $('#export-form :input[name=query]').val(); } } diff --git a/pages/run_query.php b/pages/run_query.php index 69702cf4b..216cf59bc 100644 --- a/pages/run_query.php +++ b/pages/run_query.php @@ -180,7 +180,7 @@ try //--- Query textarea $oQueryTitle = new Html('

'.Dict::S('UI:RunQuery:ExpressionToEvaluate').'

'); $oQueryForm->AddSubBlock($oQueryTitle); - $oQueryTextArea = new TextArea(utils::EscapeHtml($sExpression), 'expression', 120, 8); + $oQueryTextArea = new TextArea('expression', utils::EscapeHtml($sExpression), 'expression', 120, 8); $oQueryTextArea->SetName('expression'); $oQueryForm->AddSubBlock($oQueryTextArea); diff --git a/sources/application/UI/Base/Component/Input/AbstractInput.php b/sources/application/UI/Base/Component/Input/AbstractInput.php index 0c0d6346c..b20cebb71 100644 --- a/sources/application/UI/Base/Component/Input/AbstractInput.php +++ b/sources/application/UI/Base/Component/Input/AbstractInput.php @@ -18,6 +18,8 @@ abstract class AbstractInput extends UIBlock protected $sName; /** @var string */ protected $sValue; + /**@var string */ + protected $sPlaceholder; public function GetName(): string { @@ -52,4 +54,25 @@ abstract class AbstractInput extends UIBlock return $this; } + + /** + * @return string + */ + public function GetPlaceholder(): ?string + { + return $this->sPlaceholder; + } + + /** + * @param string $sPlaceholder + * + * @return $this + */ + public function SetPlaceholder(string $sPlaceholder) + { + $this->sPlaceholder = $sPlaceholder; + + return $this; + } + } \ No newline at end of file diff --git a/sources/application/UI/Base/Component/Input/InputUIBlockFactory.php b/sources/application/UI/Base/Component/Input/InputUIBlockFactory.php index 67f9b7b94..93faa9fc9 100644 --- a/sources/application/UI/Base/Component/Input/InputUIBlockFactory.php +++ b/sources/application/UI/Base/Component/Input/InputUIBlockFactory.php @@ -94,4 +94,24 @@ class InputUIBlockFactory extends AbstractUIBlockFactory return new InputWithLabel($sLabel, $oInput, $sId); } + /** + * If you need to have a real field with a label, you might use a {@link Field} component instead + * + * @param string $sName + * @param string|null $sId + * + * @return \Combodo\iTop\Application\UI\Base\Component\Input\Select + */ + public static function MakeForSelect(string $sName, ?string $sId = null): Select + { + $oInput = new Select($sId); + $oInput->SetName($sName); + + if (is_null($sId)) { + $sId = $oInput->GetId(); + } + + return $oInput; + } + } \ No newline at end of file diff --git a/sources/application/UI/Base/Component/Input/InputWithLabel.php b/sources/application/UI/Base/Component/Input/InputWithLabel.php index bd5ed1d1b..8df94628e 100644 --- a/sources/application/UI/Base/Component/Input/InputWithLabel.php +++ b/sources/application/UI/Base/Component/Input/InputWithLabel.php @@ -23,6 +23,8 @@ class InputWithLabel extends UIBlock protected $sLabel; /** @var \Combodo\iTop\Application\UI\Base\UIBlock */ protected $oInput; + /** @var bool Label before input ? */ + protected $bBeforeInput; /** * @param string $sLabel @@ -34,6 +36,7 @@ class InputWithLabel extends UIBlock parent::__construct($sId); $this->sLabel = $sLabel; $this->oInput = $oInput; + $this->bBeforeInput = true; } /** @@ -56,6 +59,30 @@ class InputWithLabel extends UIBlock return $this; } + /** + * @param bool $bBeforeInput + * + * @return $this + */ + public function SetBeforeInput(bool $bBeforeInput) + { + $this->bBeforeInput = $bBeforeInput; + if ($bBeforeInput) { + $this->oInput->AddCSSClass('ibo-input--label-left'); + } else { + $this->oInput->AddCSSClass('ibo-input--label-right'); + } + + return $this; + } + + /** + * @return bool + */ + public function IsLabelBefore(): bool + { + return $this->bBeforeInput; + } /** * @return string diff --git a/sources/application/UI/Base/Component/Input/TextArea.php b/sources/application/UI/Base/Component/Input/TextArea.php index f0f7b80bf..40d05b63d 100644 --- a/sources/application/UI/Base/Component/Input/TextArea.php +++ b/sources/application/UI/Base/Component/Input/TextArea.php @@ -21,16 +21,17 @@ class TextArea extends AbstractInput /** @var int */ protected $iRows; - public function __construct(?string $sValue, ?string $sId = null, ?int $iCols = null, ?int $iRows = null) + public function __construct(string $sName, ?string $sValue, ?string $sId = null, ?int $iCols = null, ?int $iRows = null) { parent::__construct($sId); + $this->sName = $sName; $this->sValue = $sValue; $this->iCols = $iCols; $this->iRows = $iRows; } - public function GetCols(): int + public function GetCols(): ?int { return $this->iCols; } @@ -47,7 +48,7 @@ class TextArea extends AbstractInput return $this; } - public function GetRows(): int + public function GetRows(): ?int { return $this->iRows; } diff --git a/sources/application/WebPage/WebPage.php b/sources/application/WebPage/WebPage.php index acd7e0bd8..97429f887 100644 --- a/sources/application/WebPage/WebPage.php +++ b/sources/application/WebPage/WebPage.php @@ -832,7 +832,7 @@ class WebPage implements Page { $aPossibleAttFlags = MetaModel::EnumPossibleAttributeFlags(); - $sHtml = "
\n"; + $sHtml = "
\n"; foreach ($aFields as $aAttrib) { $sLayout = isset($aAttrib['layout']) ? $aAttrib['layout'] : 'small'; diff --git a/templates/base/components/datatable/config/layout.html.twig b/templates/base/components/datatable/config/layout.html.twig index 0cb06c72b..8c24d447f 100644 --- a/templates/base/components/datatable/config/layout.html.twig +++ b/templates/base/components/datatable/config/layout.html.twig @@ -1,44 +1,49 @@ - +

{{ 'UI:Display_X_ItemsPerPage_prefix'|dict_s }}{{ 'UI:Display_X_ItemsPerPage_suffix'|dict_s }}

+
+
+
+
+
+ + +
+
+
     -

- - - - - - -
- - - -
+
+
+
+
+ + +
+
\ No newline at end of file diff --git a/templates/base/components/datatable/static/formtable/layout.ready.js.twig b/templates/base/components/datatable/static/formtable/layout.ready.js.twig index ac04707ed..749d505a5 100644 --- a/templates/base/components/datatable/static/formtable/layout.ready.js.twig +++ b/templates/base/components/datatable/static/formtable/layout.ready.js.twig @@ -9,7 +9,7 @@ var table{{ oUIBlock.GetId()|sanitize(constant('utils::ENUM_SANITIZATION_FILTER_ search: false, dom: "t", }); - - -//table{{ oUIBlock.GetId()|sanitize(constant('utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER')) }}.columns.adjust().draw(); -//$(".dataTables_scrollBody thead").hide(); \ No newline at end of file +if ($('#{{ oUIBlock.GetId() }}').find('thead').is(':visible')) +{ + table{{ oUIBlock.GetId()|sanitize(constant('utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER')) }}.columns.adjust().draw(); +} diff --git a/templates/base/components/fieldset/layout.html.twig b/templates/base/components/fieldset/layout.html.twig index 4ee38ee80..2156d52a6 100644 --- a/templates/base/components/fieldset/layout.html.twig +++ b/templates/base/components/fieldset/layout.html.twig @@ -1,5 +1,5 @@ {% if oUIBlock.GetSubBlocks() %} -
+
{{ oUIBlock.GetLegend() }} {% for oSubBlock in oUIBlock.GetSubBlocks() %} {{ render_block(oSubBlock, {aPage: aPage}) }} diff --git a/templates/base/components/form/layout.html.twig b/templates/base/components/form/layout.html.twig index 12b8ee5da..284bd42de 100644 --- a/templates/base/components/form/layout.html.twig +++ b/templates/base/components/form/layout.html.twig @@ -6,6 +6,11 @@ {% if oUIBlock.GetAction() %} action="{{ oUIBlock.GetAction() }}" {% endif %} + {% if oUIBlock.GetDataAttributes() %} + {% for sName, sValue in oUIBlock.GetDataAttributes() %} + data-{{ sName }}="{{ sValue }}" + {% endfor %} + {% endif %} > {% apply spaceless %} {% block iboContentBlockContainer %} diff --git a/templates/base/components/input/input-textarea.html.twig b/templates/base/components/input/input-textarea.html.twig index d95b545f7..aa5df6e0c 100644 --- a/templates/base/components/input/input-textarea.html.twig +++ b/templates/base/components/input/input-textarea.html.twig @@ -1,8 +1,14 @@ {% block iboInputLabel %} {% endblock %} {% block iboInput %} - {% endblock %} \ No newline at end of file diff --git a/templates/base/components/input/inputwithlabel.html.twig b/templates/base/components/input/inputwithlabel.html.twig index 898a2273f..de770a7ef 100644 --- a/templates/base/components/input/inputwithlabel.html.twig +++ b/templates/base/components/input/inputwithlabel.html.twig @@ -1,4 +1,10 @@ {% block iboInputLabel %} - - {{ render_block(oUIBlock.GetInput()) }} + {% if oUIBlock.IsLabelBefore() %} + + {{ render_block(oUIBlock.GetInput()) }} + {% else %} + {{ render_block(oUIBlock.GetInput()) }} + + {% endif %} {% endblock %} + diff --git a/templates/base/components/input/layout.html.twig b/templates/base/components/input/layout.html.twig index 650f0115b..409e3116b 100644 --- a/templates/base/components/input/layout.html.twig +++ b/templates/base/components/input/layout.html.twig @@ -2,8 +2,14 @@ {% endblock %} {% block iboInput %} {% endblock %} \ No newline at end of file diff --git a/webservices/export-v2.php b/webservices/export-v2.php index 5923af86b..642ac6c4b 100644 --- a/webservices/export-v2.php +++ b/webservices/export-v2.php @@ -17,7 +17,18 @@ * You should have received a copy of the GNU Affero General Public License */ -if (!defined('__DIR__')) define('__DIR__', dirname(__FILE__)); +use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Field\FieldUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Html\Html; +use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Input\TextArea; +use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory; + +if (!defined('__DIR__')) { + define('__DIR__', dirname(__FILE__)); +} require_once(__DIR__.'/../approot.inc.php'); require_once(APPROOT.'/application/application.inc.php'); require_once(APPROOT.'/application/nicewebpage.class.inc.php'); @@ -127,10 +138,32 @@ function Usage(Page $oP) function DisplayExpressionForm(WebPage $oP, $sAction, $sExpression = '', $sExceptionMessage = '') { - $oP->add('
'.Dict::S('Core:BulkExport:ScopeDefinition').''); - $oP->add('
'); - $oP->add(''); - $oP->add(''); + $oForm = FormUIBlockFactory::MakeStandard('form'); + $oForm->SetAction($sAction); + $oP->AddSubBlock($oForm); + + $oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('interactive', '1')); + + $oFieldQuery = FieldUIBlockFactory::MakeStandard(''); + $oTextArea = new TextArea('expression', htmlentities($sExpression, ENT_QUOTES, 'UTF-8'), "textarea_oql", 70, 8); + $oTextArea->SetPlaceholder(Dict::S('Core:BulkExportQueryPlaceholder')); + $oFieldQuery->AddSubBlock($oTextArea); + $oForm->AddSubBlock($oFieldQuery); + + $oFieldPhraseBook = FieldUIBlockFactory::MakeStandard(''); + $oSelect = InputUIBlockFactory::MakeForSelect("select_phrasebook"); + $oSelect->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption("", Dict::S('UI:SelectOne'), false)); + + $oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL'); + $oSearch->UpdateContextFromUser(); + $oQueries = new DBObjectSet($oSearch); + while ($oQuery = $oQueries->Fetch()) { + $oSelect->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption($oQuery->GetKey(), htmlentities($oQuery->Get('name'), ENT_QUOTES, 'UTF-8'), false)); + } + $oFieldPhraseBook->AddSubBlock($oSelect); + $oForm->AddSubBlock($oFieldPhraseBook); + + /*oP->add('
'); $sExpressionHint = empty($sExceptionMessage) ? '' : ''; $oP->add(''); $oP->add(''); @@ -139,24 +172,20 @@ function DisplayExpressionForm(WebPage $oP, $sAction, $sExpression = '', $sExcep $oP->add(''); - $oP->add(''); - $oP->add('
'.htmlentities($sExceptionMessage, ENT_QUOTES, 'UTF-8').'
'); - $oP->add('
'); - $oP->add('
'); + $oP->add('');*/ + $oForm->AddSubBlock(ButtonUIBlockFactory::MakeForPrimaryAction(Dict::S('UI:Button:Next'), "", "", true, "next-btn")); $oP->p(''.Dict::S('Core:BulkExportCanRunNonInteractive').''); $oP->p(''.Dict::S('Core:BulkExportLegacyExport').''); $sJSEmptyOQL = json_encode(Dict::S('Core:BulkExportMessageEmptyOQL')); $sJSEmptyQueryId = json_encode(Dict::S('Core:BulkExportMessageEmptyPhrasebookEntry')); - + $oP->add_ready_script( -<<add_script(DateTimeFormat::GetJSSQLToCustomFormat()); $sJSDefaultDateTimeFormat = json_encode((string)AttributeDateTime::GetFormat()); $oP->add_script( -<<add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/tabularfieldsselector.js'); $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.dragtable.js'); $oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/dragtable.css'); - $oP->add('
'); + + $oForm = FormUIBlockFactory::MakeStandard("export-form"); + $oForm->SetAction($sAction); + $oForm->AddDataAttribute("state", "not-yet-started"); + $oP->AddSubBlock($oForm); + $bExpressionIsValid = true; $sExpressionError = ''; - if (($sExpression === null) && ($sQueryId === null)) - { - $bExpressionIsValid = false; - } - else if ($sExpression !== '') - { - try - { + if (($sExpression === null) && ($sQueryId === null)) { + $bExpressionIsValid = false; + } else if ($sExpression !== '') { + try { $oExportSearch = DBObjectSearch::FromOQL($sExpression); $oExportSearch->UpdateContextFromUser(); } - catch(OQLException $e) - { + catch (OQLException $e) { $bExpressionIsValid = false; $sExpressionError = $e->getMessage(); } } - - if (!$bExpressionIsValid) - { + + if (!$bExpressionIsValid) { DisplayExpressionForm($oP, $sAction, $sExpression, $sExpressionError); + return; } - - if ($sExpression !== '') - { - $oP->add(''); + + if ($sExpression !== '') { + $oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden("expression", htmlentities($sExpression, ENT_QUOTES, 'UTF-8'))); $oExportSearch = DBObjectSearch::FromOQL($sExpression); - $oExportSearch->UpdateContextFromUser(); - } - else - { + $oExportSearch->UpdateContextFromUser(); + } else { $oQuery = MetaModel::GetObject('QueryOQL', $sQueryId); $oExportSearch = DBObjectSearch::FromOQL($oQuery->Get('oql')); - $oExportSearch->UpdateContextFromUser(); - $oP->add(''); + $oExportSearch->UpdateContextFromUser(); + $oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden("query", htmlentities($sQueryId, ENT_QUOTES, 'UTF-8'))); } $aFormPartsByFormat = array(); $aAllFormParts = array(); - if ($sFormat == null) - { + if ($sFormat == null) { // No specific format chosen $sDefaultFormat = utils::ReadParam('format', 'xlsx'); - $oP->add('

'.Dict::S('Core:BulkExport:ExportFormatPrompt').'

'); - } - else - { + + } else { // One specific format was chosen - $oP->add(''); - + $oSelect = InputUIBlockFactory::MakeForHidden("format", htmlentities($sFormat, ENT_QUOTES, 'UTF-8')); + $oForm->AddSubBlock($oSelect); + $oExporter = BulkExport::FindExporter($sFormat, $oExportSearch); $aParts = $oExporter->EnumFormParts(); - foreach($aParts as $sPartId => $void) - { + foreach ($aParts as $sPartId => $void) { $aAllFormParts[$sPartId] = $oExporter; } $aFormPartsByFormat[$sFormat] = array_keys($aAllFormParts); } - foreach($aAllFormParts as $sPartId => $oExport) - { - $oP->add('
'); - $oExport->DisplayFormPart($oP, $sPartId); - $oP->add('
'); + foreach ($aAllFormParts as $sPartId => $oExport) { + $UIContentBlock = UIContentBlockUIBlockFactory::MakeStandard('form_part_'.$sPartId)->AddCSSClass('form_part'); + $oForm->AddSubBlock($UIContentBlock); + $UIContentBlock->AddSubBlock($oExport->GetFormPart($oP, $sPartId)); } - $oP->add('
'); - $oP->add(''); - $oP->add(''); - $oP->add(''); - + //end of form + $oBlockExport = UIContentBlockUIBlockFactory::MakeStandard("export-feedback")->SetIsHidden(true); + $oBlockExport->AddSubBlock(new Html('

'.Dict::S('ExcelExport:PreparingExport').'

')); + $oBlockExport->AddSubBlock(new Html('
')); + $oP->AddSubBlock($oBlockExport); + if ($sFormat == null) {//if it's global export + $oP->AddSubBlock(ButtonUIBlockFactory::MakeForPrimaryAction('export', Dict::S('UI:Button:Export'), 'export', false, 'export-btn')); + } + $oBlockResult = UIContentBlockUIBlockFactory::MakeStandard("export-export_text_result")->SetIsHidden(true); + $oBlockResult->AddSubBlock(new Html(Dict::S('Core:BulkExport:ExportResult'))); + + $oTextArea = new TextArea('export_content', '', 'export_content'); + $oTextArea->AddCSSClass('ibo-input-text-area--export'); + $oBlockResult->AddSubBlock($oTextArea); + $oP->AddSubBlock($oBlockResult); + $sJSParts = json_encode($aFormPartsByFormat); $oP->add_ready_script( -<<add_ready_script( -<<SetBreadCrumbEntry('ui-tool-export', Dict::S('Menu:ExportMenu'), Dict::S('Menu:ExportMenu+'), '', 'fas fa-file-export', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES); } - - if ($sExpression === null) - { + + if ($sExpression === null) { // No expression supplied, let's check if phrasebook entry is given - if ($sQueryId !== null) - { + if ($sQueryId !== null) { $oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId)); - $oSearch->UpdateContextFromUser(); + $oSearch->UpdateContextFromUser(); $oQueries = new DBObjectSet($oSearch); - if ($oQueries->Count() > 0) - { + if ($oQueries->Count() > 0) { $oQuery = $oQueries->Fetch(); $sExpression = $oQuery->Get('oql'); - } - else - { + } else { ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'"); } - } - else - { - if (utils::IsModeCLI()) - { + } else { + if (utils::IsModeCLI()) { Usage($oP); ReportErrorAndExit("No expression or query phrasebook identifier supplied."); - } - else - { + } else { // form to enter an OQL query or pick a query phrasebook identifier DisplayForm($oP, utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php', $sExpression, $sQueryId, $sFormat); $oP->output(); @@ -414,29 +435,22 @@ EOF } } - - if ($sFormat !== null) - { + + if ($sFormat !== null) { $oExporter = BulkExport::FindExporter($sFormat); - if ($oExporter === null) - { + if ($oExporter === null) { $aSupportedFormats = BulkExport::FindSupportedFormats(); ReportErrorAndExit("Invalid output format: '$sFormat'. The supported formats are: ".implode(', ', array_keys($aSupportedFormats))); - } - else - { + } else { DisplayForm($oP, utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php', $sExpression, $sQueryId, $sFormat); } - } - else - { + } else { DisplayForm($oP, utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php', $sExpression, $sQueryId, $sFormat); } - if ($sMode == 'dialog') - { + if ($sMode == 'dialog') { $oP->add(''); } - $oP->output(); + $oP->output(); } /** @@ -448,54 +462,42 @@ EOF */ function CheckParameters($sExpression, $sQueryId, $sFormat) { - $oExporter = null; + $oExporter = null; - if (utils::IsArchiveMode() && !UserRights::CanBrowseArchive()) - { + if (utils::IsArchiveMode() && !UserRights::CanBrowseArchive()) { ReportErrorAndExit("The user account is not authorized to access the archives"); } - if (($sExpression === null) && ($sQueryId === null)) - { + if (($sExpression === null) && ($sQueryId === null)) { ReportErrorAndUsage("Missing parameter. The parameter 'expression' or 'query' must be specified."); } - + // Either $sExpression or $sQueryId must be specified - if ($sExpression === null) - { + if ($sExpression === null) { $oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId)); - $oSearch->UpdateContextFromUser(); - $oQueries = new DBObjectSet($oSearch); - if ($oQueries->Count() > 0) - { + $oSearch->UpdateContextFromUser(); + $oQueries = new DBObjectSet($oSearch); + if ($oQueries->Count() > 0) { $oQuery = $oQueries->Fetch(); $sExpression = $oQuery->Get('oql'); - } - else - { + } else { ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'"); } } - if ($sFormat === null) - { + if ($sFormat === null) { ReportErrorAndUsage("Missing parameter 'format'."); } - + // Check if the supplied query is valid (and all the parameters are supplied - try - { + try { $oSearch = DBObjectSearch::FromOQL($sExpression); - $oSearch->UpdateContextFromUser(); + $oSearch->UpdateContextFromUser(); $aArgs = array(); - foreach($oSearch->GetQueryParams() as $sParam => $foo) - { + foreach ($oSearch->GetQueryParams() as $sParam => $foo) { $value = utils::ReadParam('arg_'.$sParam, null, true, 'raw_data'); - if (!is_null($value)) - { + if (!is_null($value)) { $aArgs[$sParam] = $value; - } - else - { + } else { throw new MissingQueryArgument("Missing parameter '--arg_$sParam'"); } } @@ -524,12 +526,12 @@ function CheckParameters($sExpression, $sQueryId, $sFormat) $oSearch = null; ReportErrorAndExit($e->getMessage()); } - + $oExporter->SetFormat($sFormat); $oExporter->SetChunkSize(EXPORTER_DEFAULT_CHUNK_SIZE); $oExporter->SetObjectList($oSearch); $oExporter->ReadParameters(); - + return $oExporter; } @@ -543,7 +545,7 @@ function DoExport(WebPage $oP, BulkExport $oExporter, $bInteractive = false) $exportResult .= $oExporter->GetNextChunk($aStatus); } while (($aStatus['code'] != 'done') && ($aStatus['code'] != 'error')); - + if ($aStatus['code'] == 'error') { $oExporter->Cleanup(); @@ -570,83 +572,64 @@ function DoExport(WebPage $oP, BulkExport $oExporter, $bInteractive = false) // Command Line mode // ///////////////////////////////////////////////////////////////////////////// -if (utils::IsModeCLI()) -{ +if (utils::IsModeCLI()) { SetupUtils::CheckPhpAndExtensionsForCli(new CLIPage('iTop - Export')); - try - { + try { // Do this before loging, in order to allow setting user credentials from within the file utils::UseParamFile(); } - catch(Exception $e) - { + catch (Exception $e) { echo "Error: ".$e->GetMessage()."
\n"; exit(EXIT_CODE_FATAL); } - + $sAuthUser = utils::ReadParam('auth_user', null, true /* Allow CLI */, 'raw_data'); $sAuthPwd = utils::ReadParam('auth_pwd', null, true /* Allow CLI */, 'raw_data'); - if ($sAuthUser == null) - { + if ($sAuthUser == null) { ReportErrorAndUsage("Missing parameter '--auth_user'"); } - if ($sAuthPwd == null) - { + if ($sAuthPwd == null) { ReportErrorAndUsage("Missing parameter '--auth_pwd'"); } - - if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd)) - { + + if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd)) { UserRights::Login($sAuthUser); // Login & set the user's language - } - else - { + } else { ReportErrorAndExit("Access restricted or wrong credentials for user '$sAuthUser'"); } - + $sExpression = utils::ReadParam('expression', null, true /* Allow CLI */, 'raw_data'); $sQueryId = utils::ReadParam('query', null, true /* Allow CLI */, 'raw_data'); $bLocalize = (utils::ReadParam('no_localize', 0) != 1); - if (utils::IsArchiveMode() && !UserRights::CanBrowseArchive()) - { + if (utils::IsArchiveMode() && !UserRights::CanBrowseArchive()) { ReportErrorAndExit("The user account is not authorized to access the archives"); } - if (($sExpression == null) && ($sQueryId == null)) - { + if (($sExpression == null) && ($sQueryId == null)) { ReportErrorAndUsage("Missing parameter. At least one of '--expression' or '--query' must be specified."); } - - if ($sExpression === null) - { + + if ($sExpression === null) { $oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId)); - $oSearch->UpdateContextFromUser(); + $oSearch->UpdateContextFromUser(); $oQueries = new DBObjectSet($oSearch); - if ($oQueries->Count() > 0) - { + if ($oQueries->Count() > 0) { $oQuery = $oQueries->Fetch(); $sExpression = $oQuery->Get('oql'); - } - else - { + } else { ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'"); - } + } } - try - { + try { $oSearch = DBObjectSearch::FromOQL($sExpression); - $oSearch->UpdateContextFromUser(); + $oSearch->UpdateContextFromUser(); $aArgs = array(); - foreach($oSearch->GetQueryParams() as $sParam => $foo) - { + foreach ($oSearch->GetQueryParams() as $sParam => $foo) { $value = utils::ReadParam('arg_'.$sParam, null, true, 'raw_data'); - if (!is_null($value)) - { + if (!is_null($value)) { $aArgs[$sParam] = $value; - } - else - { + } else { throw new MissingQueryArgument("Missing parameter '--arg_$sParam'"); } } @@ -659,21 +642,21 @@ if (utils::IsModeCLI()) $aSupportedFormats = BulkExport::FindSupportedFormats(); ReportErrorAndExit("Invalid output format: '$sFormat'. The supported formats are: ".implode(', ', array_keys($aSupportedFormats))); } - + $oExporter->SetFormat($sFormat); $oExporter->SetChunkSize(EXPORTER_DEFAULT_CHUNK_SIZE); $oExporter->SetObjectList($oSearch); $oExporter->ReadParameters(); - + $exportResult = $oExporter->GetHeader(); $aStatus = array(); - + do { $exportResult .= $oExporter->GetNextChunk($aStatus); } while (($aStatus['code'] != 'done') && ($aStatus['code'] != 'error')); - + if ($aStatus['code'] == 'error') { ReportErrorAndExit("Export failed: '{$aStatus['message']}'"); @@ -684,7 +667,7 @@ if (utils::IsModeCLI()) echo $exportResult; } $oExporter->Cleanup(); - + } catch(MissingQueryArgument $e) { @@ -698,7 +681,7 @@ if (utils::IsModeCLI()) { ReportErrorAndExit($e->getMessage()); } - + exit; } @@ -711,7 +694,7 @@ if (utils::IsModeCLI()) try { require_once(APPROOT.'/application/loginwebpage.class.inc.php'); - + // Main parameters $sExpression = utils::ReadParam('expression', null, true /* Allow CLI */, 'raw_data'); $sQueryId = utils::ReadParam('query', null, true /* Allow CLI */, 'raw_data'); @@ -723,26 +706,21 @@ try LoginWebPage::DoLogin(); // Check user rights and prompt if needed ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker'); - - if ($bInteractive) - { + + if ($bInteractive) { InteractiveShell($sExpression, $sQueryId, $sFormat, $sFileName, $sMode); - } - else - { + } else { $oExporter = CheckParameters($sExpression, $sQueryId, $sFormat); $sMimeType = $oExporter->GetMimeType(); - if ($sMimeType == 'text/html') - { + if ($sMimeType == 'text/html') { // Note: Using NiceWebPage only for HTML export as it includes JS scripts & files, which makes no sense in other export formats. More over, it breaks Excel spreadsheet import. - if($oExporter instanceof HTMLBulkExport) { + if ($oExporter instanceof HTMLBulkExport) { $oP = new NiceWebPage('iTop export'); $oP->add_xframe_options(); $oP->add_ready_script("$('table.listResults').tablesorter({widgets: ['MyZebra']});"); $oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css'); $oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/v4-shims.min.css'); - } - else { + } else { $oP = new WebPage('iTop export'); $oP->add_xframe_options(); $oP->add_style("table br { mso-data-placement:same-cell; }"); // Trick for Excel: keep line breaks inside the same cell !