N°3746 - Migrate modal to new UIBlock system

This commit is contained in:
acognet
2021-02-26 10:05:02 +01:00
parent 1060c0ca94
commit cebbc215d7
38 changed files with 1094 additions and 868 deletions

View File

@@ -151,7 +151,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
} }
$iCellIdx++; $iCellIdx++;
} }
$sJSReload .= $oDashboardRow->GetJSRefreshCallback()."\n"; $sJSReload .= $oDashboardRow->GetJSRefreshCallback()." ";
} }
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}"); $oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");

View File

@@ -102,23 +102,21 @@ class DesignerForm
$sReturn .= '<fieldset>'; $sReturn .= '<fieldset>';
$sReturn .= '<legend>'.$sLabel.'</legend>'; $sReturn .= '<legend>'.$sLabel.'</legend>';
} }
foreach($aFields as $oField) foreach($aFields as $oField) {
{
$aRow = $oField->Render($oP, $sFormId); $aRow = $oField->Render($oP, $sFormId);
if ($oField->IsVisible()) if ($oField->IsVisible()) {
{
$sValidation = '<span class="prop_apply ibo-prop--apply">'.$this->GetValidationArea($oField->GetFieldId()).'</span>'; $sValidation = '<span class="prop_apply ibo-prop--apply">'.$this->GetValidationArea($oField->GetFieldId()).'</span>';
$sField = $aRow['value'].$sValidation; $sField = $aRow['value'].$sValidation;
$aDetails[] = array('label' => $aRow['label'], 'value' => $sField); $aDetails[] = array('label' => $aRow['label'], 'value' => $sField);
} } else {
else
{
$sHiddenFields .= $aRow['value']; $sHiddenFields .= $aRow['value'];
} }
} }
$sReturn .= '<table><tr><td>';
$sReturn .= $oP->GetDetails($aDetails); $sReturn .= $oP->GetDetails($aDetails);
if ($sLabel != '') $sReturn .= '</td></tr></table>';
{
if ($sLabel != '') {
$sReturn .= '</fieldset>'; $sReturn .= '</fieldset>';
} }
} }
@@ -1304,6 +1302,7 @@ EOF
); );
} }
return array('label' => $this->sLabel, 'value' => $sHtml); return array('label' => $this->sLabel, 'value' => $sHtml);
} }
public function ReadParam(&$aValues) public function ReadParam(&$aValues)

View File

@@ -369,20 +369,36 @@ abstract class BulkExport
utils::PopArchiveMode(); utils::PopArchiveMode();
} }
} }
public function EnumFormParts() public function EnumFormParts()
{ {
return array(); return array();
} }
/**
* @deprecated since 3.0 replaced by GetFormPart
*/
public function DisplayFormPart(WebPage $oP, $sPartId) 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 DisplayUsage(Page $oP)
{ {
} }
public function ReadParameters() public function ReadParameters()
{ {
$this->bLocalizeOutput = !((bool)utils::ReadParam('no_localize', 0, true, 'integer')); $this->bLocalizeOutput = !((bool)utils::ReadParam('no_localize', 0, true, 'integer'));

View File

@@ -15,6 +15,12 @@
// //
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/> // along with iTop. If not, see <http://www.gnu.org/licenses/>
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 * Bulk export: CSV export
@@ -22,7 +28,6 @@
* @copyright Copyright (C) 2015-2016 Combodo SARL * @copyright Copyright (C) 2015-2016 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
class CSVBulkExport extends TabularBulkExport class CSVBulkExport extends TabularBulkExport
{ {
public function DisplayUsage(Page $oP) public function DisplayUsage(Page $oP)
@@ -100,21 +105,34 @@ class CSVBulkExport extends TabularBulkExport
public function EnumFormParts() 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': case 'interactive_fields_csv':
$this->GetInteractiveFieldsWidget($oP, 'interactive_fields_csv'); return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_csv');
break; break;
case 'csv_options': case 'csv_options':
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:CSVOptions').'</legend>'); $oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:CSVOptions'));
$oP->add('<table class="export_parameters"><tr><td style="vertical-align:top">');
$oP->add('<h3>'.Dict::S('UI:CSVImport:SeparatorCharacter').'</h3>'); $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'); $sRawSeparator = utils::ReadParam('separator', ',', true, 'raw_data');
$sCustomDateTimeFormat = utils::ReadParam('', ',', true, 'raw_data'); $sCustomDateTimeFormat = utils::ReadParam('', ',', true, 'raw_data');
$aSep = array( $aSep = array(
@@ -123,22 +141,25 @@ class CSVBulkExport extends TabularBulkExport
'tab' => Dict::S('UI:CSVImport:SeparatorTab+'), 'tab' => Dict::S('UI:CSVImport:SeparatorTab+'),
); );
$sOtherSeparator = ''; $sOtherSeparator = '';
if (!array_key_exists($sRawSeparator, $aSep)) if (!array_key_exists($sRawSeparator, $aSep)) {
{
$sOtherSeparator = $sRawSeparator; $sOtherSeparator = $sRawSeparator;
$sRawSeparator = 'other'; $sRawSeparator = 'other';
} }
$aSep['other'] = Dict::S('UI:CSVImport:SeparatorOther').' <input type="text" size="3" name="other-separator" value="'.htmlentities($sOtherSeparator, ENT_QUOTES, 'UTF-8').'"/>'; $aSep['other'] = Dict::S('UI:CSVImport:SeparatorOther').' <input type="text" size="3" name="other-separator" value="'.htmlentities($sOtherSeparator, ENT_QUOTES, 'UTF-8').'"/>';
foreach($aSep as $sVal => $sLabel) foreach ($aSep as $sVal => $sLabel) {
{ $oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "separator", htmlentities($sVal, ENT_QUOTES, 'UTF-8'), $sLabel, "radio");
$sChecked = ($sVal == $sRawSeparator) ? 'checked' : ''; $oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator));
$oP->add('<input type="radio" name="separator" value="'.htmlentities($sVal, ENT_QUOTES, 'UTF-8').'" '.$sChecked.'/>&nbsp;'.$sLabel.'<br/>'); $oRadio->SetBeforeInput(false);
$oRadio->AddCSSClass('ibo-input--label-right');
$oFieldSetSeparator->AddSubBlock($oRadio);
$oFieldSetSeparator->AddSubBlock(new Html('</br>'));
} }
$oP->add('</td><td style="vertical-align:top">'); //TextQualifierCharacter
$oFieldSetTextQualifier = FieldSetUIBlockFactory::MakeStandard(Dict::S('UI:CSVImport:TextQualifierCharacter'));
$oP->add('<h3>'.Dict::S('UI:CSVImport:TextQualifierCharacter').'</h3>'); $oFieldSetTextQualifier->AddCSSClass('ibo-column');
$oMulticolumn->AddSubBlock($oFieldSetTextQualifier);
$sRawQualifier = utils::ReadParam('text-qualifier', '"', true, 'raw_data'); $sRawQualifier = utils::ReadParam('text-qualifier', '"', true, 'raw_data');
$aQualifiers = array( $aQualifiers = array(
@@ -146,60 +167,77 @@ class CSVBulkExport extends TabularBulkExport
'\'' => Dict::S('UI:CSVImport:QualifierSimpleQuote+'), '\'' => Dict::S('UI:CSVImport:QualifierSimpleQuote+'),
); );
$sOtherQualifier = ''; $sOtherQualifier = '';
if (!array_key_exists($sRawQualifier, $aQualifiers)) if (!array_key_exists($sRawQualifier, $aQualifiers)) {
{
$sOtherQualifier = $sRawQualifier; $sOtherQualifier = $sRawQualifier;
$sRawQualifier = 'other'; $sRawQualifier = 'other';
} }
$aQualifiers['other'] = Dict::S('UI:CSVImport:QualifierOther').' <input type="text" size="3" name="other-text-qualifier" value="'.htmlentities($sOtherQualifier, ENT_QUOTES, 'UTF-8').'"/>'; $aQualifiers['other'] = Dict::S('UI:CSVImport:QualifierOther').' <input type="text" size="3" name="other-text-qualifier" value="'.htmlentities($sOtherQualifier, ENT_QUOTES, 'UTF-8').'"/>';
foreach($aQualifiers as $sVal => $sLabel) foreach ($aQualifiers as $sVal => $sLabel) {
{ $oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "separator", htmlentities($sVal, ENT_QUOTES, 'UTF-8'), $sLabel, "radio");
$sChecked = ($sVal == $sRawQualifier) ? 'checked' : ''; $oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator));
$oP->add('<input type="radio" name="text-qualifier" value="'.htmlentities($sVal, ENT_QUOTES, 'UTF-8').'" '.$sChecked.'/>&nbsp;'.$sLabel.'<br/>'); $oRadio->SetBeforeInput(false);
$oRadio->GetInput()->AddCSSClass('ibo-input--label-right');
$oFieldSetTextQualifier->AddSubBlock($oRadio);
$oFieldSetTextQualifier->AddSubBlock(new Html('</br>'));
} }
$sChecked = (utils::ReadParam('no_localize', 0) == 1) ? ' checked ' : ''; //Localization
$oP->add('</td><td style="vertical-align:top">'); $oFieldSetLocalization = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:CSVLocalization'));
$oP->add('<h3>'.Dict::S('Core:BulkExport:CSVLocalization').'</h3>'); $oFieldSetLocalization->AddCSSClass('ibo-column');
$oP->add('<input type="checkbox" id="csv_no_localize" name="no_localize" value="1"'.$sChecked.'><label for="csv_no_localize"> '.Dict::S('Core:BulkExport:OptionNoLocalize').'</label>'); $oMulticolumn->AddSubBlock($oFieldSetLocalization);
$oP->add('<br/>');
$oP->add('<br/>'); $oCheckBox = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionNoLocalize'), "no_localize", "1", "csv_no_localize", "checkbox");
$oP->add(Dict::S('UI:CSVImport:Encoding').': <select name="charset" style="font-family:Arial,Helvetica,Sans-serif">'); // IE 8 has some troubles if the font is different $oCheckBox->GetInput()->SetIsChecked((utils::ReadParam('no_localize', 0) == 1));
$oCheckBox->SetBeforeInput(false);
$oCheckBox->GetInput()->AddCSSClass('ibo-input--label-right');
$oFieldSetLocalization->AddSubBlock($oCheckBox);
$oFieldSetLocalization->AddSubBlock(new Html('</br>'));
$oSelect = InputUIBlockFactory::MakeForSelectWithLabel("charset", Dict::S('UI:CSVImport:Encoding'));
$oSelect->SetBeforeInput(true);
$oFieldSetLocalization->AddSubBlock($oSelect);
$aPossibleEncodings = utils::GetPossibleEncodings(MetaModel::GetConfig()->GetCSVImportCharsets()); $aPossibleEncodings = utils::GetPossibleEncodings(MetaModel::GetConfig()->GetCSVImportCharsets());
$sDefaultEncoding = MetaModel::GetConfig()->Get('csv_file_default_charset'); $sDefaultEncoding = MetaModel::GetConfig()->Get('csv_file_default_charset');
foreach($aPossibleEncodings as $sIconvCode => $sDisplayName ) foreach ($aPossibleEncodings as $sIconvCode => $sDisplayName) {
{ $oSelect->GetInput()->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption('$sIconvCode', $sDisplayName, ($sIconvCode == $sDefaultEncoding)));
$sSelected = '';
if ($sIconvCode == $sDefaultEncoding)
{
$sSelected = ' selected';
}
$oP->add('<option value="'.$sIconvCode.'"'.$sSelected.'>'.$sDisplayName.'</option>');
} }
$oP->add('</select>'); //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('<h3>'.Dict::S('Core:BulkExport:TextFormat').'</h3>');
$oP->add('<input type="checkbox" id="csv_formatted_text" name="formatted_text" value="1"'.$sChecked.'><label for="csv_formatted_text"> '.Dict::S('Core:BulkExport:OptionFormattedText').'</label>');
$oP->add('</td><td style="vertical-align:top">');
$sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data'); $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('<h3>'.Dict::S('Core:BulkExport:DateTimeFormat').'</h3>');
$sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8'); $sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8');
$sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8'); $sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8');
$oP->add('<input type="radio" id="csv_date_time_format_default" name="csv_date_format_radio" value="default"'.$sDefaultChecked.'><label for="csv_date_time_format_default"> '.Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample).'</label><br/>'); $oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "csv_custom_date_time_format", "default", "csv_date_time_format_default", "radio");
$sFormatInput = '<input type="text" size="15" name="date_format" id="csv_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>'; $oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
$oP->add('<input type="radio" id="csv_date_time_format_custom" name="csv_date_format_radio" value="custom"'.$sCustomChecked.'><label for="csv_date_time_format_custom"> '.Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput).'</label>'); $oRadioDefault->SetBeforeInput(false);
$oP->add('</td></tr></table>'); $oFieldSetDate->AddSubBlock($oRadioDefault);
$oFieldSetDate->AddSubBlock(new Html('</br>'));
$oP->add('</fieldset>');
$sFormatInput = '<input type="text" size="15" name="date_format" id="excel_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
$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('<div class="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>'); $sJSTooltip = json_encode('<div class="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>');
$oP->add_ready_script( $oP->add_ready_script(
<<<EOF <<<EOF
$('#csv_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } }); $('#csv_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } });
$('#form_part_csv_options').on('preview_updated', function() { FormatDatesInPreview('csv', 'csv'); }); $('#form_part_csv_options').on('preview_updated', function() { FormatDatesInPreview('csv', 'csv'); });
$('#csv_date_time_format_default').on('click', function() { FormatDatesInPreview('csv', 'csv'); }); $('#csv_date_time_format_default').on('click', function() { FormatDatesInPreview('csv', 'csv'); });
@@ -207,12 +245,13 @@ $('#csv_date_time_format_custom').on('click', function() { FormatDatesInPreview(
$('#csv_custom_date_time_format').on('click', function() { $('#csv_date_time_format_custom').prop('checked', true); FormatDatesInPreview('csv', 'csv'); }).on('keyup', function() { FormatDatesInPreview('csv', 'csv'); }); $('#csv_custom_date_time_format').on('click', function() { $('#csv_date_time_format_custom').prop('checked', true); FormatDatesInPreview('csv', 'csv'); }).on('keyup', function() { FormatDatesInPreview('csv', 'csv'); });
EOF EOF
); );
return $oPanel;
break; break;
default: default:
return parent:: DisplayFormPart($oP, $sPartId); return parent:: GetFormPart($oP, $sPartId);
} }
} }

View File

@@ -23,6 +23,12 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
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;
require_once(APPROOT.'application/xlsxwriter.class.php'); require_once(APPROOT.'application/xlsxwriter.class.php');
class ExcelBulkExport extends TabularBulkExport class ExcelBulkExport extends TabularBulkExport
@@ -67,52 +73,71 @@ class ExcelBulkExport extends TabularBulkExport
// Custom format specified from the UI // Custom format specified from the UI
$this->aStatusInfo['date_format'] = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data'); $this->aStatusInfo['date_format'] = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data');
break; break;
default: default:
// Export from the command line (or scripted) => default format is SQL, as in previous versions of iTop, unless specified otherwise // 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'); $this->aStatusInfo['date_format'] = utils::ReadParam('date_format', (string)AttributeDateTime::GetSQLFormat(), true, 'raw_data');
} }
} }
public function EnumFormParts() 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': case 'interactive_fields_xlsx':
$this->GetInteractiveFieldsWidget($oP, 'interactive_fields_xlsx'); return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_xlsx');
break; break;
case 'xlsx_options': case 'xlsx_options':
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:XLSXOptions').'</legend>'); $oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:XLSXOptions'));
$oP->add('<table class="export_parameters"><tr><td style="vertical-align:top">');
$oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard();
$sChecked = (utils::ReadParam('formatted_text', 0) == 1) ? ' checked ' : ''; $oMulticolumn->AddCSSClass('ibo-multi-column');
$oP->add('<h3>'.Dict::S('Core:BulkExport:TextFormat').'</h3>'); $oPanel->AddSubBlock($oMulticolumn);
$oP->add('<input type="checkbox" id="xlsx_formatted_text" name="formatted_text" value="1"'.$sChecked.'><label for="xlsx_formatted_text"> '.Dict::S('Core:BulkExport:OptionFormattedText').'</label>');
$oFieldSetFormat = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:TextFormat'));
$oP->add('</td><td style="vertical-align:top">'); $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'); $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('<h3>'.Dict::S('Core:BulkExport:DateTimeFormat').'</h3>');
$sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8'); $sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8');
$sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8'); $sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8');
$oP->add('<input type="radio" id="excel_date_time_format_default" name="excel_date_format_radio" value="default"'.$sDefaultChecked.'><label for="excel_date_time_format_default"> '.Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample).'</label><br/>'); $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('</br>'));
$sFormatInput = '<input type="text" size="15" name="date_format" id="excel_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>'; $sFormatInput = '<input type="text" size="15" name="date_format" id="excel_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
$oP->add('<input type="radio" id="excel_date_time_format_custom" name="excel_date_format_radio" value="custom"'.$sCustomChecked.'><label for="excel_date_time_format_custom"> '.Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput).'</label>'); $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());
$oP->add('</td></tr></table>'); $oRadioCustom->SetBeforeInput(false);
$oFieldSetDate->AddSubBlock($oRadioCustom);
$oP->add('</fieldset>');
$sJSTooltip = json_encode('<div class="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>'); $sJSTooltip = json_encode('<div class="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>');
$oP->add_ready_script( $oP->add_ready_script(
<<<EOF <<<EOF
$('#excel_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } }); $('#excel_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } });
$('#form_part_xlsx_options').on('preview_updated', function() { FormatDatesInPreview('excel', 'xlsx'); }); $('#form_part_xlsx_options').on('preview_updated', function() { FormatDatesInPreview('excel', 'xlsx'); });
$('#excel_date_time_format_default').on('click', function() { FormatDatesInPreview('excel', 'xlsx'); }); $('#excel_date_time_format_default').on('click', function() { FormatDatesInPreview('excel', 'xlsx'); });
@@ -120,10 +145,12 @@ $('#excel_date_time_format_custom').on('click', function() { FormatDatesInPrevie
$('#excel_custom_date_time_format').on('click', function() { $('#excel_date_time_format_custom').prop('checked', true); FormatDatesInPreview('excel', 'xlsx'); }).on('keyup', function() { FormatDatesInPreview('excel', 'xlsx'); }); $('#excel_custom_date_time_format').on('click', function() { $('#excel_date_time_format_custom').prop('checked', true); FormatDatesInPreview('excel', 'xlsx'); }).on('keyup', function() { FormatDatesInPreview('excel', 'xlsx'); });
EOF EOF
); );
return $oPanel;
break; break;
default: default:
return parent:: DisplayFormPart($oP, $sPartId); return parent::GetFormPart($oP, $sPartId);
} }
} }

View File

@@ -36,16 +36,21 @@ class HTMLBulkExport extends TabularBulkExport
return array_merge(parent::EnumFormParts(), array('interactive_fields_html' => array('interactive_fields_html'))); return array_merge(parent::EnumFormParts(), array('interactive_fields_html' => 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': case 'interactive_fields_html':
$this->GetInteractiveFieldsWidget($oP, 'interactive_fields_html'); return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_html');
break; break;
default: default:
return parent:: DisplayFormPart($oP, $sPartId); return parent:: GetFormPart($oP, $sPartId);
} }
} }

View File

@@ -15,6 +15,12 @@
// //
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/> // along with iTop. If not, see <http://www.gnu.org/licenses/>
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 * Bulk export: PDF export, based on the HTML export converted to PDF
@@ -22,7 +28,6 @@
* @copyright Copyright (C) 2015 Combodo SARL * @copyright Copyright (C) 2015 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
class PDFBulkExport extends HTMLBulkExport class PDFBulkExport extends HTMLBulkExport
{ {
public function DisplayUsage(Page $oP) public function DisplayUsage(Page $oP)
@@ -39,43 +44,72 @@ class PDFBulkExport extends HTMLBulkExport
return array_merge(array('pdf_options' => array('pdf_options')), parent::EnumFormParts()); 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': case 'pdf_options':
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:PDFOptions').'</legend>'); $oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:PDFOptions'));
$oP->add('<table class="export_parameters"><tr><td style="vertical-align:top">');
$oP->add('<h3>'.Dict::S('Core:BulkExport:PDFPageFormat').'</h3>'); $oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard();
$oP->add('<table>'); $oMulticolumn->AddCSSClass('ibo-multi-column');
$oP->add('<tr>'); $oPanel->AddSubBlock($oMulticolumn);
$oP->add('<td>'.Dict::S('Core:BulkExport:PDFPageSize').'</td>');
$oP->add('<td>'.$this->GetSelectCtrl('page_size', array('A3', 'A4', 'Letter'), 'Core:BulkExport:PageSize-', 'A4').'</td>'); $oFieldSetFormat = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:PDFPageFormat'));
$oP->add('</tr>'); $oFieldSetFormat->AddCSSClass('ibo-column');
$oP->add('<td>'.Dict::S('Core:BulkExport:PDFPageOrientation').'</td>'); $oMulticolumn->AddSubBlock($oFieldSetFormat);
$oP->add('<td>'.$this->GetSelectCtrl('page_orientation', array('P', 'L'), 'Core:BulkExport:PageOrientation-', 'L').'</td>');
$oP->add('</tr>'); //page format
$oP->add('</table>'); $oSelectFormat = InputUIBlockFactory::MakeForSelectWithLabel("page_size", Dict::S('Core:BulkExport:PDFPageSize'));
$oSelectFormat->SetBeforeInput(false);
$oP->add('</td><td style="vertical-align:top">'); $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('</br>'));
$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'); $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('<h3>'.Dict::S('Core:BulkExport:DateTimeFormat').'</h3>');
$sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8'); $sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8');
$sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8'); $sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8');
$oP->add('<input type="radio" id="pdf_date_time_format_default" name="pdf_date_format_radio" value="default"'.$sDefaultChecked.'><label for="pdf_date_time_format_default"> '.Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample).'</label><br/>'); $oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "pdf_custom_date_time_format", "default", "pdf_date_time_format_default", "radio");
$sFormatInput = '<input type="text" size="15" name="date_format" id="pdf_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>'; $oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
$oP->add('<input type="radio" id="pdf_date_time_format_custom" name="pdf_date_format_radio" value="custom"'.$sCustomChecked.'><label for="pdf_date_time_format_custom"> '.Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput).'</label>'); $oRadioDefault->SetBeforeInput(false);
$oFieldSetDate->AddSubBlock($oRadioDefault);
$oP->add('</td></tr></table>'); $oFieldSetDate->AddSubBlock(new Html('</br>'));
$sFormatInput = '<input type="text" size="15" name="date_format" id="excel_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
$oP->add('</fieldset>'); $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('<div id="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>'); $sJSTooltip = json_encode('<div id="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>');
$oP->add_ready_script( $oP->add_ready_script(
<<<EOF <<<EOF
$('#pdf_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } }); $('#pdf_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } });
$('#form_part_pdf_options').on('preview_updated', function() { FormatDatesInPreview('pdf', 'html'); }); $('#form_part_pdf_options').on('preview_updated', function() { FormatDatesInPreview('pdf', 'html'); });
$('#pdf_date_time_format_default').on('click', function() { FormatDatesInPreview('pdf', 'html'); }); $('#pdf_date_time_format_default').on('click', function() { FormatDatesInPreview('pdf', 'html'); });
@@ -83,33 +117,15 @@ $('#pdf_date_time_format_custom').on('click', function() { FormatDatesInPreview(
$('#pdf_custom_date_time_format').on('click', function() { $('#pdf_date_time_format_custom').prop('checked', true); FormatDatesInPreview('pdf', 'html'); }).on('keyup', function() { FormatDatesInPreview('pdf', 'html'); }); $('#pdf_custom_date_time_format').on('click', function() { $('#pdf_date_time_format_custom').prop('checked', true); FormatDatesInPreview('pdf', 'html'); }).on('keyup', function() { FormatDatesInPreview('pdf', 'html'); });
EOF EOF
); );
return $oPanel;
break; break;
default: default:
return parent:: DisplayFormPart($oP, $sPartId); return parent:: GetFormPart($oP, $sPartId);
} }
} }
protected function GetSelectCtrl($sName, $aValues, $sDictPrefix, $sDefaultValue)
{
$sCurrentValue = utils::ReadParam($sName, $sDefaultValue, false, 'raw_data');
$aLabels = array();
foreach($aValues as $sVal)
{
$aLabels[$sVal] = Dict::S($sDictPrefix.$sVal);
}
asort($aLabels);
$sHtml = '<select name="'.$sName.'">';
foreach($aLabels as $sVal => $sLabel)
{
$sSelected = ($sVal == $sCurrentValue) ? 'selected' : '';
$sHtml .= '<option value="'.$sVal.'" '.$sSelected.'>'.htmlentities($sLabel, ENT_QUOTES, 'UTF-8').'</option>';
}
$sHtml .= '</select>';
return $sHtml;
}
public function ReadParameters() public function ReadParameters()
{ {

View File

@@ -15,14 +15,18 @@
// //
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/> // along with iTop. If not, see <http://www.gnu.org/licenses/>
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 * 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 * @copyright Copyright (C) 2015 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
class SpreadsheetBulkExport extends TabularBulkExport class SpreadsheetBulkExport extends TabularBulkExport
{ {
public function DisplayUsage(Page $oP) public function DisplayUsage(Page $oP)
@@ -36,50 +40,67 @@ class SpreadsheetBulkExport extends TabularBulkExport
public function EnumFormParts() 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': case 'interactive_fields_spreadsheet':
$this->GetInteractiveFieldsWidget($oP, 'interactive_fields_spreadsheet'); return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_spreadsheet');
break; break;
case 'spreadsheet_options':
$sChecked = (utils::ReadParam('no_localize', 0) == 1) ? ' checked ' : '';
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:SpreadsheetOptions').'</legend>');
$oP->add('<table>');
$oP->add('<tr>');
$oP->add('<td style="vertical-align:top">'); case 'spreadsheet_options':
$sChecked = (utils::ReadParam('formatted_text', 1) == 1) ? ' checked ' : ''; $oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:SpreadsheetOptions'));
$oP->add('<h3>'.Dict::S('Core:BulkExport:TextFormat').'</h3>');
$oP->add('<input type="hidden" name="formatted_text" value="0">'); // Trick to pass the zero value if the checkbox below is unchecked, since we want the default value to be "1" $oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard();
$oP->add('<input type="checkbox" id="spreadsheet_formatted_text" name="formatted_text" value="1"'.$sChecked.'><label for="spreadsheet_formatted_text"> '.Dict::S('Core:BulkExport:OptionFormattedText').'</label><br/><br/>'); $oMulticolumn->AddCSSClass('ibo-multi-column');
$oP->add('<input type="checkbox" id="spreadsheet_no_localize" name="no_localize" value="1"'.$sChecked.'><label for="spreadsheet_no_localize"> '.Dict::S('Core:BulkExport:OptionNoLocalize').'</label>'); $oPanel->AddSubBlock($oMulticolumn);
$oP->add('</td>');
$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('<br>'));
$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'); $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('<td>');
$oP->add('<h3>'.Dict::S('Core:BulkExport:DateTimeFormat').'</h3>');
$sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8'); $sDefaultFormat = htmlentities((string)AttributeDateTime::GetFormat(), ENT_QUOTES, 'UTF-8');
$sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8'); $sExample = htmlentities(date((string)AttributeDateTime::GetFormat()), ENT_QUOTES, 'UTF-8');
$oP->add('<input type="radio" id="spreadsheet_date_time_format_default" name="spreadsheet_date_format_radio" value="default"'.$sDefaultChecked.'><label for="spreadsheet_date_time_format_default"> '.Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample).'</label><br/>'); $oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "spreadsheet_date_format_radio", "default", "spreadsheet_date_time_format_default", "radio");
$sFormatInput = '<input type="text" size="15" name="date_format" id="spreadsheet_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>'; $oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
$oP->add('<input type="radio" id="spreadsheet_date_time_format_custom" name="spreadsheet_date_format_radio" value="custom"'.$sCustomChecked.'><label for="spreadsheet_date_time_format_custom"> '.Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput).'</label>'); $oRadioDefault->SetBeforeInput(false);
$oP->add('</td>'); $oFieldSetDate->AddSubBlock($oRadioDefault);
$oFieldSetDate->AddSubBlock(new Html('</br>'));
$sFormatInput = '<input type="text" size="15" name="date_format" id="spreadsheet_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
$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('</tr>');
$oP->add('</table>');
$oP->add('</fieldset>');
$sJSTooltip = json_encode('<div class="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>'); $sJSTooltip = json_encode('<div class="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>');
$oP->add_ready_script( $oP->add_ready_script(
<<<EOF <<<EOF
$('#spreadsheet_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } }); $('#spreadsheet_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } });
$('#form_part_spreadsheet_options').on('preview_updated', function() { FormatDatesInPreview('spreadsheet', 'spreadsheet'); }); $('#form_part_spreadsheet_options').on('preview_updated', function() { FormatDatesInPreview('spreadsheet', 'spreadsheet'); });
$('#spreadsheet_date_time_format_default').on('click', function() { FormatDatesInPreview('spreadsheet', 'spreadsheet'); }); $('#spreadsheet_date_time_format_default').on('click', function() { FormatDatesInPreview('spreadsheet', 'spreadsheet'); });
@@ -87,11 +108,13 @@ $('#spreadsheet_date_time_format_custom').on('click', function() { FormatDatesIn
$('#spreadsheet_custom_date_time_format').on('click', function() { $('#spreadsheet_date_time_format_custom').prop('checked', true); }); $('#spreadsheet_custom_date_time_format').on('click', function() { $('#spreadsheet_date_time_format_custom').prop('checked', true); });
$('#spreadsheet_custom_date_time_format').on('click', function() { $('#spreadsheet_date_time_format_custom').prop('checked', true); FormatDatesInPreview('spreadsheet', 'spreadsheet'); }).on('keyup', function() { FormatDatesInPreview('spreadsheet', 'spreadsheet'); }); $('#spreadsheet_custom_date_time_format').on('click', function() { $('#spreadsheet_date_time_format_custom').prop('checked', true); FormatDatesInPreview('spreadsheet', 'spreadsheet'); }).on('keyup', function() { FormatDatesInPreview('spreadsheet', 'spreadsheet'); });
EOF EOF
); );
return $oPanel;
break; break;
default: default:
return parent:: DisplayFormPart($oP, $sPartId); return parent:: GetFormPart($oP, $sPartId);
} }
} }

View File

@@ -15,6 +15,7 @@
// //
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/> // along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
/** /**
* Bulk export: Tabular export: abstract base class for all "tabular" exports. * Bulk export: Tabular export: abstract base class for all "tabular" exports.
@@ -23,7 +24,6 @@
* @copyright Copyright (C) 2015 Combodo SARL * @copyright Copyright (C) 2015 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
abstract class TabularBulkExport extends BulkExport abstract class TabularBulkExport extends BulkExport
{ {
public function EnumFormParts() public function EnumFormParts()
@@ -31,23 +31,30 @@ abstract class TabularBulkExport extends BulkExport
return array_merge(parent::EnumFormParts(), array('tabular_fields' => array('fields'))); 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': case 'tabular_fields':
$sFields = utils::ReadParam('fields', '', true, 'raw_data'); $sFields = utils::ReadParam('fields', '', true, 'raw_data');
$sSuggestedFields = utils::ReadParam('suggested_fields', null, true, 'raw_data'); $sSuggestedFields = utils::ReadParam('suggested_fields', null, true, 'raw_data');
if (($sSuggestedFields !== null) && ($sSuggestedFields !== '')) if (($sSuggestedFields !== null) && ($sSuggestedFields !== '')) {
{
$aSuggestedFields = explode(',', $sSuggestedFields); $aSuggestedFields = explode(',', $sSuggestedFields);
$sFields = implode(',', $this->SuggestFields($aSuggestedFields)); $sFields = implode(',', $this->SuggestFields($aSuggestedFields));
} }
$oP->add('<input id="tabular_fields" type="hidden" size="50" name="fields" value="'.htmlentities($sFields, ENT_QUOTES, 'UTF-8').'"></input>'); $oP->add('<input id="tabular_fields" type="hidden" size="50" name="fields" value="'.htmlentities($sFields, ENT_QUOTES, 'UTF-8').'"></input>');
//TODO 3.0 test
return null;
break; break;
default: default:
return parent::DisplayFormPart($oP, $sPartId); return parent::GetFormPart($oP, $sPartId);
} }
} }
@@ -272,7 +279,6 @@ abstract class TabularBulkExport extends BulkExport
} }
} }
$oP->add('<div id="'.$sWidgetId.'"></div>');
$JSAllFields = json_encode($aAllFieldsByAlias); $JSAllFields = json_encode($aAllFieldsByAlias);
// First, fetch only the ids - the rest will be fetched by an object reload // 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); $sJSLabels = json_encode($aLabels);
$oP->add_ready_script( $oP->add_ready_script(
<<<EOF <<<EOF
$('#$sWidgetId').tabularfieldsselector({fields: $JSAllFields, value_holder: '#tabular_fields', advanced_holder: '#tabular_advanced', sample_data: $sJSSampleData, total_count: $iCount, preview_limit: $iPreviewLimit, labels: $sJSLabels }); $('#$sWidgetId').tabularfieldsselector({fields: $JSAllFields, value_holder: '#tabular_fields', advanced_holder: '#tabular_advanced', sample_data: $sJSSampleData, total_count: $iCount, preview_limit: $iPreviewLimit, labels: $sJSLabels });
EOF EOF
); );
$oUIContentBlock = UIContentBlockUIBlockFactory::MakeStandard($sWidgetId);
$oUIContentBlock->AddCSSClass('ibo-tabularbulkexport');
return $oUIContentBlock;
} }
static public function SortOnLabel($aItem1, $aItem2) static public function SortOnLabel($aItem1, $aItem2)

View File

@@ -15,6 +15,9 @@
// //
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/> // along with iTop. If not, see <http://www.gnu.org/licenses/>
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 * Bulk export: XML export
@@ -22,7 +25,6 @@
* @copyright Copyright (C) 2015-2017 Combodo SARL * @copyright Copyright (C) 2015-2017 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
class XMLBulkExport extends BulkExport class XMLBulkExport extends BulkExport
{ {
public function DisplayUsage(Page $oP) 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'))); 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': case 'xml_options':
$sNoLocalizeChecked = (utils::ReadParam('no_localize', 0) == 1) ? ' checked ' : '';
$sLinksetChecked = (utils::ReadParam('linksets', 0) == 1) ? ' checked ' : ''; $oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:XMLOptions'));
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:XMLOptions').'</legend>');
$oP->add('<table>'); $oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard();
$oP->add('<tr>'); $oMulticolumn->AddCSSClass('ibo-multi-column');
$oP->add('<td><input type="checkbox" id="xml_no_localize" name="no_localize" value="1"'.$sNoLocalizeChecked.'><label for="xml_no_localize"> '.Dict::S('Core:BulkExport:OptionNoLocalize').'</label></td>'); $oPanel->AddSubBlock($oMulticolumn);
$oP->add('</tr>');
$oP->add('<tr>'); $oCheckBoxLocalize = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionNoLocalize'), "no_localize", "1", "xml_no_localize", "checkbox");
$oP->add('<td><input type="checkbox" id="xml_linksets" name="linksets" value="1"'.$sLinksetChecked.'><label for="xml_linksets"> '.Dict::S('Core:BulkExport:OptionLinkSets').'</label></td>'); $oCheckBoxLocalize->GetInput()->SetIsChecked((utils::ReadParam('no_localize', 0) == 1));
$oP->add('</tr>'); $oCheckBoxLocalize->SetBeforeInput(false);
$oP->add('</table>'); $oPanel->AddSubBlock($oCheckBoxLocalize);
$oP->add('</fieldset>');
$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; break;
default: default:
return parent:: DisplayFormPart($oP, $sPartId); return parent:: GetFormPart($oP, $sPartId);
} }
} }

View File

@@ -8,15 +8,18 @@ $ibo-button--box-shadow-top: inset 0px 2px 0px !default;
$ibo-button--label--margin-left: 4px !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: ( $ibo-button-colors: (
'regular': ( 'regular': (
/* Semantics */ /* Semantics */
'neutral': ( 'neutral': (
'': ( '': (
$ibo-color-secondary-100, $ibo-color-secondary-100,
$ibo-color-grey-900, $ibo-color-grey-900,
$ibo-button--box-shadow-bottom $ibo-color-secondary-300, $ibo-button--box-shadow-bottom $ibo-color-secondary-300,
), ),
':hover': ( ':hover': (
$ibo-color-secondary-200, $ibo-color-secondary-200,
$ibo-color-grey-900, $ibo-color-grey-900,
@@ -399,13 +402,18 @@ $ibo-button-colors: (
margin-left: $ibo-button--sibling-spacing; margin-left: $ibo-button--sibling-spacing;
} }
&.ibo-action-button { &.ibo-action-button {
float: right; float: right;
} }
} }
/* Only when a button has both an icon and a label */ /* Only when a button has both an icon and a label */
.ibo-button--icon + .ibo-button--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;
} }

View File

@@ -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-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-datatable--selection-validation-buttons-toolbar--margin-top: 10px !default;
$ibo-list-column--max-height: 150px;
.ibo-datatable { .ibo-datatable {
padding-bottom: $ibo-datatable--padding-y; padding-bottom: $ibo-datatable--padding-y;
padding-top: $ibo-datatable--padding-y; padding-top: $ibo-datatable--padding-y;
thead tr th, tbody tr td { thead tr th, tbody tr td {
line-height: $ibo-datatable-cell-row--line-height; line-height: $ibo-datatable-cell-row--line-height;
padding-right: $ibo-datatable-cell-row--padding-x; padding-right: $ibo-datatable-cell-row--padding-x;
padding-left: $ibo-datatable-cell-row--padding-x; padding-left: $ibo-datatable-cell-row--padding-x;
@extend %ibo-font-ral-med-100; @extend %ibo-font-ral-med-100;
a {
color: $ibo-datatable-cell-row--link--color;
}
}
.ibo-datatable-header.sorting, .ibo-datatable-header.sorting_asc, .ibo-datatable-header.sorting_desc { a {
cursor: pointer; color: $ibo-datatable-cell-row--link--color;
} }
}
tbody tr:nth-child(odd) { .ibo-datatable-header.sorting, .ibo-datatable-header.sorting_asc, .ibo-datatable-header.sorting_desc {
background-color: $ibo-datatable-row--odd--background-color; cursor: pointer;
} }
tbody tr:nth-child(even) { tbody tr:nth-child(odd) {
background-color: $ibo-datatable-row--even--background-color; background-color: $ibo-datatable-row--odd--background-color;
} }
tbody tr:nth-child(even) {
background-color: $ibo-datatable-row--even--background-color;
}
} }
.dataTables_length { .dataTables_length {
@extend %ibo-font-ral-med-100; @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; box-shadow: $ibo-datatable--paginate-button-active--link--box-shadow;
border-radius: $ibo-border-radius-300; 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; .dataTables_scrollHead thead tr th.sorting::after {
font-family: "Font Awesome 5 Free"; position: absolute;
content: "\f0dc"; font-family: "Font Awesome 5 Free";
font-weight: 900; content: "\f0dc";
opacity: $ibo-datatable--sorting--opacity; font-weight: 900;
right: $ibo-datatable--sorting--right; opacity: $ibo-datatable--sorting--opacity;
right: $ibo-datatable--sorting--right;
} }
.ibo-datatable thead tr th.sorting_desc:after{
position: absolute; .dataTables_scrollHead thead tr th.sorting_desc:after {
font-family: "Font Awesome 5 Free"; position: absolute;
content: "\f0d7"; font-family: "Font Awesome 5 Free";
font-weight: 900; content: "\f0d7";
right: $ibo-datatable--sorting--right; font-weight: 900;
right: $ibo-datatable--sorting--right;
} }
.ibo-datatable thead tr th.sorting_asc:after{
position: absolute; .dataTables_scrollHead thead tr th.sorting_asc:after {
font-family: "Font Awesome 5 Free"; position: absolute;
font-weight: 900; font-family: "Font Awesome 5 Free";
content: "\f0d8"; font-weight: 900;
right: $ibo-datatable--sorting--right; content: "\f0d8";
right: $ibo-datatable--sorting--right;
} }
.ibo-datatable-panel > .ibo-panel--body { .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 // For cancel / OK / next... selection validation buttons
.ibo-datatable--selection-validation-buttons-toolbar { .ibo-datatable--selection-validation-buttons-toolbar {
clear: both; clear: both;
margin-top: $ibo-datatable--selection-validation-buttons-toolbar--margin-top; margin-top: $ibo-datatable--selection-validation-buttons-toolbar--margin-top;
} }
.ibo-list-column {
max-height: $ibo-list-column--max-height;
overflow-y: auto;
}

View File

@@ -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--legend--border-bottom-style: solid !default;
.ibo-fieldset { .ibo-fieldset {
& ~ .ibo-fieldset { & ~ .ibo-fieldset:not(.ibo-column) {
margin-top: $ibo-fieldset--sibling-spacing; margin-top: $ibo-fieldset--sibling-spacing;
} }
} }

View File

@@ -21,3 +21,9 @@ $ibo-dashlet--elements-spacing-y: 24px !default;
.ibo-dashlet--is-inline{ .ibo-dashlet--is-inline{
width: $ibo-dashlet--width--is-inline; width: $ibo-dashlet--width--is-inline;
} }
.ibo-details > .ibo-prop--apply {
display: table-column;
}
.ibo-details{
margin-top: 5px;
}

View File

@@ -1,5 +1,10 @@
$ibo-input-text-area--min-height: 4rem !default; $ibo-input-text-area--min-height: 4rem !default;
.ibo-input-text-area{ .ibo-input-text-area {
min-height: $ibo-input-text-area--min-height; min-height: $ibo-input-text-area--min-height;
}
.ibo-input-text-area--export {
width: 100%;
min-height: 15em;
} }

View File

@@ -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--background-color: $ibo-color-red-200 !default;
$ibo-input-wrapper--is-error--border-color: $ibo-color-red-600 !default; $ibo-input-wrapper--is-error--border-color: $ibo-color-red-600 !default;
$ibo-field-validation: $ibo-color-red-700 !default; $ibo-field-validation: $ibo-color-red-700 !default;
.ibo-input{
@extend %ibo-vertically-centered-content; $ibo-input--margin-x: 5px !default;
height: $ibo-input--height;
width: $ibo-input--width; .ibo-input {
background-color: $ibo-input--background-color; @extend %ibo-vertically-centered-content;
color: $ibo-input--color; height: $ibo-input--height;
padding: $ibo-input--padding-y $ibo-input--padding-x; width: $ibo-input--width;
border: 1px solid $ibo-input--border-color; background-color: $ibo-input--background-color;
border-radius: $ibo-input--border-radius; 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{ &:focus{
border: 1px solid $ibo-input--focus--border-color; 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-wrapper.is-error {
.ibo-input{ .ibo-input{
background-color: $ibo-input-wrapper--is-error--background-color; 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 { .file-input {
display:block; display: block;
position: relative; position: relative;
}
.ibo-input--label-right {
margin-right: $ibo-input--margin-x;
}
.ibo-input--label-left {
margin-leftt: $ibo-input--margin-x;
} }

View File

@@ -4,6 +4,7 @@
*/ */
$ibo-column--min-width: 300px !default; $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-x: abs($ibo-multi-column--margin-x) !default;
$ibo-column--padding-y: 0 !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; padding: $ibo-column--padding-y $ibo-column--padding-x;
flex-basis: 10%; 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; margin-bottom: $ibo-column--margin-bottom--is-last-element;
} }
} }

View File

@@ -19,4 +19,5 @@
@import "base"; @import "base";
@import "preferences"; @import "preferences";
@import "attachments"; @import "attachments";
@import "tabularfieldsselector";
@import "impact-analysis"; @import "impact-analysis";

View File

@@ -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;
}

View File

@@ -81,6 +81,7 @@ $ibo-vendors-jqueryui--ui-slider--ui-slider-handle--hover--border-color: $ibo-co
.ui-dialog-content { .ui-dialog-content {
position: relative; position: relative;
padding: 16px $ibo-vendors-jqueryui--ui-dialog--padding-x; padding: 16px $ibo-vendors-jqueryui--ui-dialog--padding-x;
overflow: auto;
} }
.ui-dialog-buttonpane { .ui-dialog-buttonpane {
margin-top: auto; margin-top: auto;

View File

@@ -36,10 +36,10 @@ function ExportStartExport() {
} }
function ExportError(sMessage) { function ExportError(sMessage) {
sDataState = 'error'; sDataState = 'error';
$('#export-feedback').hide(); $('#export-feedback').addClass('ibo-is-hidden');
$('#export-text-result').show(); $('#export-text-result').removeClass('ibo-is-hidden');
$('#export-error').html(sMessage); $('#export-error').html(sMessage);
} }
function ExportRun(data) { function ExportRun(data) {
@@ -51,9 +51,9 @@ function ExportRun(data) {
oParams = {}; oParams = {};
oParams.token = data.token; oParams.token = data.token;
if (sDataState == 'cancelled') { if (sDataState == 'cancelled') {
oParams.operation = 'export_cancel'; oParams.operation = 'export_cancel';
$('#export-cancel').hide(); $('#export-cancel').addClass('ibo-is-hidden');
$('#export-close').show(); $('#export-close').removeClass('ibo-is-hidden');
} }
else { else {
oParams.operation = 'export_build_portal'; oParams.operation = 'export_build_portal';
@@ -65,20 +65,19 @@ function ExportRun(data) {
'json'); 'json');
break; break;
case 'done': case 'done':
sDataState = 'done'; sDataState = 'done';
$('#export-cancel').hide(); $('#export-cancel').addClass('ibo-is-hidden');
$('#export-close').show(); $('#export-close').removeClass('ibo-is-hidden');
$('.progress').progressbar({value: data.percentage}); $('.progress').progressbar({value: data.percentage});
sMessage = '<a href="' + GetAbsoluteUrlAppRoot() + 'pages/ajax.render.php?operation=export_download&token=' + data.token + '" target="_blank">' + data.message + '</a>'; sMessage = '<a href="'+GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?operation=export_download&token='+data.token+'" target="_blank">'+data.message+'</a>';
$('.export-message').html(sMessage); $('.export-message').html(sMessage);
if (data.text_result != undefined) { if (data.text_result != undefined) {
if (data.mime_type == 'text/html') { if (data.mime_type == 'text/html') {
$('#export-content').parent().html(data.text_result); $('#export-content').parent().html(data.text_result);
$('#export-text-result').show(); $('#export-text-result').show();
} } else {
else { if ($('#export-text-result').closest('ui-dialog').length == 0) {
if ($('#export-text-result').closest('ui-dialog').length == 0) {
// not inside a dialog box, adjust the height... approximately // not inside a dialog box, adjust the height... approximately
var jPane = $('#export-text-result').closest('.ui-layout-content'); var jPane = $('#export-text-result').closest('.ui-layout-content');
var iTotalHeight = jPane.height(); var iTotalHeight = jPane.height();
@@ -89,20 +88,20 @@ function ExportRun(data) {
}); });
$('#export-content').height(iTotalHeight - 80); $('#export-content').height(iTotalHeight - 80);
} }
$('#export-content').val(data.text_result); $('#export-content').val(data.text_result);
$('#export-text-result').show(); $('#export-text-result').removeClass('ibo-is-hidden');
} }
} }
break; break;
case 'error': case 'error':
sDataState = 'error'; sDataState = 'error';
$('#export-feedback').hide(); $('#export-feedback').addClass('ibo-is-hidden');
$('#export-text-result').show(); $('#export-text-result').removeClass('ibo-is-hidden');
$('#export-error').html(data.message); $('#export-error').html(data.message);
$('#export-cancel').hide(); $('#export-cancel').addClass('ibo-is-hidden');
$('#export-close').show(); $('#export-close').removeClass('ibo-is-hidden');
break; break;
default: default:
} }

View File

@@ -16,21 +16,24 @@ $(function()
// the constructor // the constructor
_create: function() _create: function()
{ {
var me = this; var me = this;
this.element this.element
.addClass('itop-fieldsorter'); .addClass('itop-fieldsorter');
var me = this; var me = this;
this._initFields(); this._initFields();
var width = 10+this.element.width(); this.moveup_btn = $('<button type="button" disabled class="ibo-button ibo-button--vertical-align">'+this.options.labels.moveup+'</button>');
this.moveup_btn = $('<button type="button" disabled style="position: absolute; top: 0; left: '+width+'px;">'+this.options.labels.moveup+'</button>'); this.movedown_btn = $('<button type="button" disabled class="ibo-button ibo-button--vertical-align">'+this.options.labels.movedown+'</button>');
this.movedown_btn = $('<button type="button" disabled style="position: absolute; top: 30px; left: '+width+'px;">'+this.options.labels.movedown+'</button>'); columnWithButtons = $('<div class="ibo-mini-column"></div>');
this.element.wrap('<div style="position:relative;"></div>'); this.element.parent().parent().append(columnWithButtons.append(this.moveup_btn).append('<br>').append(this.movedown_btn));
this.element.parent().append(this.moveup_btn).append(this.movedown_btn); this.moveup_btn.click(function () {
this.moveup_btn.click(function() { me._moveUp(); }); me._moveUp();
this.movedown_btn.click(function() { me._moveDown(); }); });
this.movedown_btn.click(function () {
me._moveDown();
});
}, },
// called when created, and later when changing options // called when created, and later when changing options

View File

@@ -23,70 +23,92 @@ $(function()
no_field_selected: 'Select at least one column to be exported' no_field_selected: 'Select at least one column to be exported'
} }
}, },
// the constructor // the constructor
_create: function() _create: function () {
{
var me = this; var me = this;
this._flatten_fields(this.options.fields); this._flatten_fields(this.options.fields);
this.sId = this.element.attr('id'); this.sId = this.element.attr('id');
this.element this.element.addClass('itop-tabularfieldsselector');
.addClass('itop-tabularfieldsselector'); this.element.parent().bind('form-part-activate', function () {
this.element.parent().bind('form-part-activate', function() { me._update_from_holder(); me._update_preview(); }); me._update_from_holder();
this.element.parent().bind('validate', function() { me.validate(); }); me._update_preview();
});
this.element.parent().bind('validate', function () {
me.validate();
});
this.aSelected = []; this.aSelected = [];
for(var i in this.options.fields) for (var i in this.options.fields) {
{ var sContent = `<div class="ibo-panel ibo-is-blue ">
var sContent = '<fieldset><legend>'+this._format(this.options.labels.columns_selection, i)+'</legend>'; <div class="ibo-panel--header">
sContent += '<div style="text-align:right"><button class="check_all" type="button">'+this.options.labels.check_all+'</button>&nbsp;<button class="uncheck_all" type="button">'+this.options.labels.uncheck_all+'</button></div>'; <div class="ibo-panel--header-left">
for(var j in this.options.fields[i]) <div class= "ibo-panel--title" > `+this._format(this.options.labels.columns_selection, i)+`</div>
{ </div>`;
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 += `
<div className="ibo-panel--header-right">
<div className="ibo-panel--toolbar">
<button class="check_all ibo-button ibo-is-regular ibo-is-neutral action" type="button"><span class=""ibo-button-label">`+this.options.labels.check_all+`</span></button>
<button class="uncheck_all ibo-button ibo-is-regular ibo-is-neutral action" type="button"><span class=""ibo-button-label">`+this.options.labels.uncheck_all+`</span></button>
</div>
</div>`;
sContent += `</div>
<div class="ibo-panel--body">`;
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 += '</fieldset>'; sContent += `</div>
</div>`;
this.element.append(sContent); this.element.append(sContent);
} }
sContent = '<fieldset><legend>'+this.options.labels.columns_order+'</legend>'; sContent = `<div class="ibo-panel ibo-is-blue ">
<div class="ibo-panel--header">
sContent += '<div class="preview_header">'+this._format(this.options.labels.preview_header, Math.min(this.options.preview_limit, this.options.total_count), this.options.total_count)+'</div>'; <div class="ibo-panel--header-left">
sContent += '<div class="table_preview"></div>'; <div class="ibo-panel--title">`+this.options.labels.columns_order+`</div>
sContent += '</fieldset>'; </div>
</div>
<div class="ibo-panel--body"> `;
sContent += '<div class="ibo-preview-header">'+this._format(this.options.labels.preview_header, Math.min(this.options.preview_limit, this.options.total_count), this.options.total_count)+'</div>';
sContent += '<div class="ibo-table-preview"></div>';
sContent += '</div></div>';
this.element.append(sContent); this.element.append(sContent);
this._update_from_holder(); 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'); var sInstanceId = $(this).attr('data-instance-id');
if (sInstanceId != me.sId) return; if (sInstanceId != me.sId) {
return;
}
me._on_click($(this)); me._on_click($(this));
}); });
var maxWidth = 0; 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()); 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).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); me._on_multi_click($(this).val(), this.checked);
}); });
$('#'+this.sId+' .check_all').click(function() { $('#'+this.sId+' .check_all').click(function () {
me._on_check_all($(this).closest('fieldset'), true); me._on_check_all($(this).closest('.ibo-panel'), true);
}); });
$('#'+this.sId+' .uncheck_all').click(function() { $('#'+this.sId+' .uncheck_all').click(function () {
me._on_check_all($(this).closest('fieldset'), false); me._on_check_all($(this).closest('.ibo-panel'), false);
}); });
this._update_preview(); this._update_preview();
this._make_tooltips(); this._make_tooltips();
}, },
_on_click: function(jItemClicked) _on_click: function (jItemClicked) {
{
var bChecked = jItemClicked.prop('checked'); var bChecked = jItemClicked.prop('checked');
var sValue = jItemClicked.val(); var sValue = jItemClicked.val();
@@ -94,19 +116,15 @@ $(function()
this._update_holder(); this._update_holder();
this._update_preview(); this._update_preview();
var sDataParent = jItemClicked.attr('data-parent'); var sDataParent = jItemClicked.attr('data-parent');
if (sDataParent != '') if (sDataParent != '') {
{
this._update_tristate(sDataParent+'_multi'); 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); var oField = this._get_main_field_by_code(sMultiFieldCode);
if (oField != null) if (oField != null) {
{
var sPrefix = '#tfs_'+this.sId+'_'; 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); this._mark_as_selected(oField.subattr[k].code, bChecked);
// In case the tooltip is visible, also update the checkboxes // In case the tooltip is visible, also update the checkboxes
sElementId = (sPrefix+oField.subattr[k].code).replace('.', '_'); sElementId = (sPrefix+oField.subattr[k].code).replace('.', '_');
@@ -116,243 +134,201 @@ $(function()
this._update_preview(); this._update_preview();
} }
}, },
_on_check_all: function(jSelector, bChecked) _on_check_all: function (jSelector, bChecked) {
{
var me = this; var me = this;
jSelector.find('.tfs_checkbox').each(function() { jSelector.find('.tfs_checkbox').each(function () {
$(this).prop('checked', bChecked); $(this).prop('checked', bChecked);
me._mark_as_selected($(this).val(), 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()); var oField = me._get_main_field_by_code($(this).val());
if (oField != null) if (oField != null) {
{
$(this).prop('checked', bChecked); $(this).prop('checked', bChecked);
$(this).prop('indeterminate', false); $(this).prop('indeterminate', false);
var sPrefix = '#tfs_'+this.sId+'_'; 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); me._mark_as_selected(oField.subattr[k].code, bChecked);
// In case the tooltip is visible, also update the checkboxes // In case the tooltip is visible, also update the checkboxes
sElementId = (sPrefix+oField.subattr[k].code).replace('.', '_'); sElementId = (sPrefix+oField.subattr[k].code).replace('.', '_');
$(sElementId).prop('checked', bChecked); $(sElementId).prop('checked', bChecked);
} }
} }
}); });
this._update_holder(); this._update_holder();
this._update_preview(); this._update_preview();
}, },
_update_tristate: function(sParentId) _update_tristate: function (sParentId) {
{
// Check if the parent is checked, unchecked or indeterminate // Check if the parent is checked, unchecked or indeterminate
var sParentId = sParentId.replace('.', '_'); var sParentId = sParentId.replace('.', '_');
var sAttCode = $('#'+sParentId).val(); var sAttCode = $('#'+sParentId).val();
var oField = this._get_main_field_by_code(sAttCode); var oField = this._get_main_field_by_code(sAttCode);
if (oField != null) if (oField != null) {
{
var iNbChecked = 0; var iNbChecked = 0;
var aDebug = []; var aDebug = [];
for(var j in oField.subattr) for (var j in oField.subattr) {
{ if ($.inArray(oField.subattr[j].code, this.aSelected) != -1) {
if ($.inArray(oField.subattr[j].code, this.aSelected) != -1)
{
aDebug.push(oField.subattr[j].code); aDebug.push(oField.subattr[j].code);
iNbChecked++; iNbChecked++;
} }
} }
if (iNbChecked == oField.subattr.length) if (iNbChecked == oField.subattr.length) {
{
$('#'+sParentId).prop('checked', true); $('#'+sParentId).prop('checked', true);
$('#'+sParentId).prop('indeterminate', false); $('#'+sParentId).prop('indeterminate', false);
} } else if (iNbChecked == 0) {
else if (iNbChecked == 0)
{
$('#'+sParentId).prop('checked', false); $('#'+sParentId).prop('checked', false);
$('#'+sParentId).prop('indeterminate', false); $('#'+sParentId).prop('indeterminate', false);
} } else {
else
{
$('#'+sParentId).prop('checked', false); $('#'+sParentId).prop('checked', false);
$('#'+sParentId).prop('indeterminate', true); $('#'+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 = []; aSelected = [];
for(var k in this.aSelected) for (var k in this.aSelected) {
{ if (this.aSelected[k] != sValue) {
if (this.aSelected[k] != sValue)
{
aSelected.push(this.aSelected[k]); aSelected.push(this.aSelected[k]);
} }
} }
this.aSelected = aSelected; this.aSelected = aSelected;
} }
}, },
_update_holder: function() _update_holder: function () {
{
$(this.options.value_holder).val(this.aSelected.join(',')); $(this.options.value_holder).val(this.aSelected.join(','));
}, },
_update_from_holder: function() _update_from_holder: function () {
{
var sFields = $(this.options.value_holder).val(); var sFields = $(this.options.value_holder).val();
var bAdvanced = parseInt($(this.options.advanced_holder).val(), 10); var bAdvanced = parseInt($(this.options.advanced_holder).val(), 10);
if (sFields != '') if (sFields != '') {
{
this.aSelected = sFields.split(','); this.aSelected = sFields.split(',');
var safeSelected = []; var safeSelected = [];
var me = this; var me = this;
var bModified = false; 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]) var oField = this._get_field_by_code(this.aSelected[k])
if (oField == null) if (oField == null) {
{
// Invalid field code supplied, don't copy it // Invalid field code supplied, don't copy it
bModified = true; bModified = true;
} } else {
else
{
safeSelected.push(this.aSelected[k]); safeSelected.push(this.aSelected[k]);
} }
} }
if (bModified) if (bModified) {
{
this.aSelected = safeSelected; this.aSelected = safeSelected;
this._update_holder(); this._update_holder();
} }
$('#'+this.sId+' .tfs_checkbox').each(function() { $('#'+this.sId+' .tfs_checkbox').each(function () {
if ($.inArray($(this).val(), me.aSelected) != -1) if ($.inArray($(this).val(), me.aSelected) != -1) {
{
$(this).prop('checked', true); $(this).prop('checked', true);
} } else {
else
{
$(this).prop('checked', false); $(this).prop('checked', false);
} }
}); });
} }
var me = this; var me = this;
$('#'+this.sId+' .tfs_checkbox_multi').each(function() { $('#'+this.sId+' .tfs_checkbox_multi').each(function () {
me._update_tristate($(this).attr('id')); me._update_tristate($(this).attr('id'));
}); });
}, },
_update_preview: function() _update_preview: function () {
{
var sHtml = ''; var sHtml = '';
if(this.aSelected.length > 0) if (this.aSelected.length > 0) {
{
sHtml += '<table><thead><tr>'; sHtml += '<table><thead><tr>';
for(var k in this.aSelected) for (var k in this.aSelected) {
{
var sField = this.aSelected[k]; var sField = this.aSelected[k];
if ($.inArray(sField, this.aSelected) != -1) if ($.inArray(sField, this.aSelected) != -1) {
{
var sRemoveBtn = '&nbsp;<span style="display:inline-block;float:right;cursor:pointer;" class="export-field-close" data-attcode="'+sField+'">×</span>'; var sRemoveBtn = '&nbsp;<span style="display:inline-block;float:right;cursor:pointer;" class="export-field-close" data-attcode="'+sField+'">×</span>';
sHtml += '<th data-attcode="'+sField+'"><span class="drag-handle">'+this.aFieldsByCode[sField].unique_label+'</span>'+sRemoveBtn+'</th>'; sHtml += '<th data-attcode="'+sField+'"><span class="drag-handle">'+this.aFieldsByCode[sField].unique_label+'</span>'+sRemoveBtn+'</th>';
} }
} }
sHtml += '</tr></thead><tbody>'; sHtml += '</tr></thead><tbody>';
for(var i=0; i<Math.min(this.options.preview_limit, this.options.total_count); i++) for (var i = 0; i < Math.min(this.options.preview_limit, this.options.total_count); i++) {
{
sHtml += '<tr>'; sHtml += '<tr>';
for(var k in this.aSelected) for (var k in this.aSelected) {
{
var sField = this.aSelected[k]; var sField = this.aSelected[k];
sHtml += '<td>'+this.options.sample_data[i][sField]+'</td>'; sHtml += '<td>'+this.options.sample_data[i][sField]+'</td>';
} }
sHtml += '</tr>'; sHtml += '</tr>';
} }
sHtml += '</tbody></table>'; sHtml += '</tbody></table>';
$('#'+this.sId+' .preview_header').show(); $('#'+this.sId+' .preview_header').show();
$('#'+this.sId+' .table_preview').html(sHtml); $('#'+this.sId+' .ibo-table-preview').html(sHtml);
var me = this; var me = this;
$('#'+this.sId+' .table_preview table').dragtable({persistState: function(table) { me._on_drag_columns(table); }, dragHandle: '.drag-handle'}); $('#'+this.sId+' .ibo-table-preview table').dragtable({
$('#'+this.sId+' .table_preview table .export-field-close').click( function(event) { me._on_remove_column($(this).attr('data-attcode')); event.preventDefault(); return false; } ); persistState: function (table) {
} me._on_drag_columns(table);
else }, 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+' .preview_header').hide();
$('#'+this.sId+' .table_preview').html('<div class="export_empty_preview">'+this.options.labels.empty_preview+'</div>'); $('#'+this.sId+' .ibo-table-preview').html('<div class="export_empty_preview">'+this.options.labels.empty_preview+'</div>');
} }
$('.form_part:visible').trigger('preview_updated'); $('.form_part:visible').trigger('preview_updated');
}, },
_get_field_by_code: function(sFieldCode) _get_field_by_code: function (sFieldCode) {
{ for (var k in this.aFieldsByCode) {
for(var k in this.aFieldsByCode) if (k == sFieldCode) {
{
if (k == sFieldCode)
{
return this.aFieldsByCode[k]; return this.aFieldsByCode[k];
} }
} }
return null; return null;
}, },
_get_main_field_by_code: function(sFieldCode) _get_main_field_by_code: function (sFieldCode) {
{ for (var i in this.options.fields) {
for(var i in this.options.fields) for (var j in this.options.fields[i]) {
{ if (this.options.fields[i][j].code == sFieldCode) {
for(var j in this.options.fields[i])
{
if (this.options.fields[i][j].code == sFieldCode)
{
return this.options.fields[i][j]; return this.options.fields[i][j];
} }
} }
} }
return null; return null;
}, },
_on_drag_columns: function(table) _on_drag_columns: function (table) {
{
var me = this; var me = this;
me.aSelected = []; me.aSelected = [];
table.el.find('th').each(function(i) { table.el.find('th').each(function (i) {
me.aSelected.push($(this).attr('data-attcode')); me.aSelected.push($(this).attr('data-attcode'));
}); });
this._update_holder(); this._update_holder();
}, },
_on_remove_column: function(sField) _on_remove_column: function (sField) {
{
var sElementId = this.sId+'_'+sField; var sElementId = this.sId+'_'+sField;
sElementId = '#tfs_'+sElementId.replace('.', '_'); sElementId = '#tfs_'+sElementId.replace('.', '_');
$(sElementId).prop('checked', false); $(sElementId).prop('checked', false);
this._mark_as_selected(sField, false); this._mark_as_selected(sField, false);
this._update_holder(); this._update_holder();
this._update_preview(); this._update_preview();
var me = this; var me = this;
$('#'+this.sId+' .tfs_checkbox_multi').each(function() { $('#'+this.sId+' .tfs_checkbox_multi').each(function () {
me._update_tristate($(this).attr('id')); me._update_tristate($(this).attr('id'));
}); });
}, },
_format: function() _format: function () {
{
var s = arguments[0]; var s = arguments[0];
for (var i = 0; i < arguments.length - 1; i++) { for (var i = 0; i < arguments.length-1; i++) {
var reg = new RegExp("%" + (i+1) + "\\$s", "gm"); var reg = new RegExp("%"+(i+1)+"\\$s", "gm");
s = s.replace(reg, arguments[i+1]); s = s.replace(reg, arguments[i+1]);
} }
return s; return s;
}, },
validate: function() validate: function () {
{ if (this.aSelected.length == 0) {
if (this.aSelected.length == 0)
{
var aMessages = $('#export-form').data('validation_messages'); var aMessages = $('#export-form').data('validation_messages');
aMessages.push(this.options.labels.no_field_selected); aMessages.push(this.options.labels.no_field_selected);
$('#export-form').data('validation_messages', aMessages); $('#export-form').data('validation_messages', aMessages);
@@ -360,158 +336,89 @@ $(function()
}, },
// events bound via _bind are removed automatically // events bound via _bind are removed automatically
// revert other modifications here // revert other modifications here
destroy: function() destroy: function () {
{
this.element this.element
.removeClass('itop-tabularfieldsselector'); .removeClass('itop-tabularfieldsselector');
this.element.parent().unbind('activate'); this.element.parent().unbind('activate');
this.element.parent().unbind('validate'); this.element.parent().unbind('validate');
}, },
// _setOptions is called with a hash of all options that are changing // _setOptions is called with a hash of all options that are changing
_setOptions: function() _setOptions: function () {
{
this._superApply(arguments); this._superApply(arguments);
}, },
// _setOption is called for each individual option that is changing // _setOption is called for each individual option that is changing
_setOption: function( key, value ) _setOption: function (key, value) {
{ if (key == 'fields') {
if (key == 'fields')
{
this._flatten_fields(value); this._flatten_fields(value);
} }
this._superApply(arguments); this._superApply(arguments);
}, },
_flatten_fields: function(aFields) _flatten_fields: function (aFields) {
{
// Update the "flattened" via of the fields // Update the "flattened" via of the fields
this.aFieldsByCode = {}; // Must be an object since indexes are non-numeric this.aFieldsByCode = {}; // Must be an object since indexes are non-numeric
for(var k in aFields) for (var k in aFields) {
{ for (var i in aFields[k]) {
for(var i in aFields[k])
{
this.aFieldsByCode[aFields[k][i].code] = aFields[k][i]; 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]; this.aFieldsByCode[aFields[k][i].subattr[j].code] = aFields[k][i].subattr[j];
} }
} }
} }
}, },
_make_tooltips: function() _make_tooltips: function () {
{ var me = this;
var me = this; $('#'+this.sId+' .tfs_advanced').each(function (index, elt) {
$('#'+this.sId+' .tfs_advanced').tooltip({ var sDataAttcode = $(elt).attr('data-attcode');
content: function() { var sTooltipContent = me._get_tooltip_content(sDataAttcode);
var sDataAttcode = $(this).attr('data-attcode'); tippy(elt, {
var sTooltipContent = ''; 'content': sTooltipContent,
sTooltipContent += me._get_tooltip_content(sDataAttcode); allowHTML: true,
return sTooltipContent; interactive: true,
}, zIndex: 9999,
items: '.tfs_advanced', role: 'tooltip',
classes: { popperOptions: {
'ui-tooltip': 'tooltip-tfs' strategy: 'fixed'
}, }
position: { });
my: "center bottom-10",
at: "center top",
using: function( position, feedback ) {
$(this).css( position );
$( "<div>" )
.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();
}); });
}, },
_get_tooltip_content: function(sDataAttCode) _get_tooltip_content: function (sDataAttCode) {
{
var oField = this._get_main_field_by_code(sDataAttCode); var oField = this._get_main_field_by_code(sDataAttCode);
var sContent = ''; var sContent = '';
if (oField != null) if (oField != null) {
{ sContent += '<div display:block;">'+oField.label+'</div>';
sContent += '<div display:block;">'+oField.label+'<div class="tooltip-close-button" data-attcode="'+sDataAttCode+'" style="display:inline-block; float:right; cursor:pointer; padding-left:0.25em; padding-bottom:0.25em;">×</div></div>'; for (var k in oField.subattr) {
for(var k in oField.subattr)
{
bChecked = ($.inArray(oField.subattr[k].code, this.aSelected) != -1); 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); sContent += this._get_field_checkbox(oField.subattr[k].code, oField.subattr[k].label, false, bChecked, sDataAttCode);
} }
} }
return sContent; 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+'_'; var sPrefix = 'tfs_'+this.sId+'_';
sParentId = (sPrefix+sParentId).replace('.', '_'); sParentId = (sPrefix+sParentId).replace('.', '_');
sElementId = (sPrefix+sCode).replace('.', '_'); sElementId = (sPrefix+sCode).replace('.', '_');
var aClasses = []; var aClasses = [];
if (bHasTooltip) if (bHasTooltip) {
{
aClasses.push('tfs_advanced'); aClasses.push('tfs_advanced');
sLabel += ' [+]'; sLabel += ' [+]';
} }
var sChecked = ''; var sChecked = '';
if (bChecked) if (bChecked) {
{
sChecked = ' checked '; sChecked = ' checked ';
} }
var sDataParent = ''; var sDataParent = '';
if (sParentId != null) if (sParentId != null) {
{
sDataParent = ' data-parent="'+sParentId+'" '; sDataParent = ' data-parent="'+sParentId+'" ';
} }
if (bHasTooltip) if (bHasTooltip) {
{
sContent = '<div style="display:block; clear:both;"><span style="white-space: nowrap;"><input data-instance-id="'+this.sId+'" class="tfs_checkbox_multi" type="checkbox" id="'+sElementId+'_multi" value="'+sCode+'"'+sChecked+sDataParent+'><label data-attcode="'+sCode+'" class="'+aClasses.join(' ')+'" title="'+sCode+'">&nbsp;'+sLabel+'</label></div>'; sContent = '<div style="display:block; clear:both;"><span style="white-space: nowrap;"><input data-instance-id="'+this.sId+'" class="tfs_checkbox_multi" type="checkbox" id="'+sElementId+'_multi" value="'+sCode+'"'+sChecked+sDataParent+'><label data-attcode="'+sCode+'" class="'+aClasses.join(' ')+'" title="'+sCode+'">&nbsp;'+sLabel+'</label></div>';
} } else {
else sContent = '<div style="display:block; clear:both;"><span style="white-space: nowrap;"><input data-instance-id="'+this.sId+'" class="tfs_checkbox" type="checkbox" id="'+sElementId+'" value="'+sCode+'"'+sChecked+sDataParent+'><label data-attcode="'+sCode+'" class="'+aClasses.join(' ')+'" title="'+sCode+'" for="'+sElementId+'">&nbsp;'+sLabel+'</label></div>';
{
sContent = '<div style="display:block; clear:both;"><span style="white-space: nowrap;"><input data-instance-id="'+this.sId+'" class="tfs_checkbox" type="checkbox" id="'+sElementId+'" value="'+sCode+'"'+sChecked+sDataParent+'><label data-attcode="'+sCode+'" class="'+aClasses.join(' ')+'" title="'+sCode+'" for="'+sElementId+'">&nbsp;'+sLabel+'</label></div>';
} }
return sContent; return sContent;
},
close_all_tooltips: function()
{
$('.tfs_advanced').each(function (i) {
$(this).tooltip("close");
});
} }
}); });
}); });

View File

@@ -430,13 +430,11 @@ function ExportStartExport() {
if (this.checked) { if (this.checked) {
oParams[this.name] = $(this).val(); oParams[this.name] = $(this).val();
} }
} } else {
else {
oParams[this.name] = $(this).val(); oParams[this.name] = $(this).val();
} }
} }
}); });
$(':itop-tabularfieldsselector:visible').tabularfieldsselector('close_all_tooltips');
$('#export-form').hide(); $('#export-form').hide();
$('#export-feedback').show(); $('#export-feedback').show();
oParams.operation = 'export_build'; oParams.operation = 'export_build';
@@ -445,8 +443,7 @@ function ExportStartExport() {
if ($(':input[name=query_mode]:checked').length > 0) { if ($(':input[name=query_mode]:checked').length > 0) {
if (sQueryMode == 'oql') { if (sQueryMode == 'oql') {
oParams.expression = $('#export-form :input[name=expression]').val(); oParams.expression = $('#export-form :input[name=expression]').val();
} } else {
else {
oParams.query = $('#export-form :input[name=query]').val(); oParams.query = $('#export-form :input[name=query]').val();
} }
} }

View File

@@ -180,7 +180,7 @@ try
//--- Query textarea //--- Query textarea
$oQueryTitle = new Html('<h2>'.Dict::S('UI:RunQuery:ExpressionToEvaluate').'</h2>'); $oQueryTitle = new Html('<h2>'.Dict::S('UI:RunQuery:ExpressionToEvaluate').'</h2>');
$oQueryForm->AddSubBlock($oQueryTitle); $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'); $oQueryTextArea->SetName('expression');
$oQueryForm->AddSubBlock($oQueryTextArea); $oQueryForm->AddSubBlock($oQueryTextArea);

View File

@@ -18,6 +18,8 @@ abstract class AbstractInput extends UIBlock
protected $sName; protected $sName;
/** @var string */ /** @var string */
protected $sValue; protected $sValue;
/**@var string */
protected $sPlaceholder;
public function GetName(): string public function GetName(): string
{ {
@@ -52,4 +54,25 @@ abstract class AbstractInput extends UIBlock
return $this; 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;
}
} }

View File

@@ -94,4 +94,24 @@ class InputUIBlockFactory extends AbstractUIBlockFactory
return new InputWithLabel($sLabel, $oInput, $sId); 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;
}
} }

View File

@@ -23,6 +23,8 @@ class InputWithLabel extends UIBlock
protected $sLabel; protected $sLabel;
/** @var \Combodo\iTop\Application\UI\Base\UIBlock */ /** @var \Combodo\iTop\Application\UI\Base\UIBlock */
protected $oInput; protected $oInput;
/** @var bool Label before input ? */
protected $bBeforeInput;
/** /**
* @param string $sLabel * @param string $sLabel
@@ -34,6 +36,7 @@ class InputWithLabel extends UIBlock
parent::__construct($sId); parent::__construct($sId);
$this->sLabel = $sLabel; $this->sLabel = $sLabel;
$this->oInput = $oInput; $this->oInput = $oInput;
$this->bBeforeInput = true;
} }
/** /**
@@ -56,6 +59,30 @@ class InputWithLabel extends UIBlock
return $this; 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 * @return string

View File

@@ -21,16 +21,17 @@ class TextArea extends AbstractInput
/** @var int */ /** @var int */
protected $iRows; 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); parent::__construct($sId);
$this->sName = $sName;
$this->sValue = $sValue; $this->sValue = $sValue;
$this->iCols = $iCols; $this->iCols = $iCols;
$this->iRows = $iRows; $this->iRows = $iRows;
} }
public function GetCols(): int public function GetCols(): ?int
{ {
return $this->iCols; return $this->iCols;
} }
@@ -47,7 +48,7 @@ class TextArea extends AbstractInput
return $this; return $this;
} }
public function GetRows(): int public function GetRows(): ?int
{ {
return $this->iRows; return $this->iRows;
} }

View File

@@ -832,7 +832,7 @@ class WebPage implements Page
{ {
$aPossibleAttFlags = MetaModel::EnumPossibleAttributeFlags(); $aPossibleAttFlags = MetaModel::EnumPossibleAttributeFlags();
$sHtml = "<div class=\"details\">\n"; $sHtml = "<div class=\"ibo-details\">\n";
foreach ($aFields as $aAttrib) foreach ($aFields as $aAttrib)
{ {
$sLayout = isset($aAttrib['layout']) ? $aAttrib['layout'] : 'small'; $sLayout = isset($aAttrib['layout']) ? $aAttrib['layout'] : 'small';

View File

@@ -1,44 +1,49 @@
<div id="datatable_dlg_{{ oUIBlock.GetTableId() }}" style="display: none; background : white;" class="{{ oUIBlock.GetBlockCode() }}"> <div id="datatable_dlg_{{ oUIBlock.GetTableId() }}" style="display: none; background : white;" class=" {{ oUIBlock.GetBlockCode() }}">
<input type="hidden" name="action" value="none"> <input type="hidden" name="action" value="none">
<form id="form_{{ oUIBlock.GetTableId() }}" onsubmit="return false"> <form id="form_{{ oUIBlock.GetTableId() }}" onsubmit="return false">
<p> <p>
<input id="dtbl_dlg_settings_{{ oUIBlock.GetTableId() }}" type="radio" name="settings" {% if (oUIBlock.GetOption("bUseCustomSettings") == false) %} checked {% endif %} value="defaults"> <input id="dtbl_dlg_settings_{{ oUIBlock.GetTableId() }}" type="radio" name="settings" {% if (oUIBlock.GetOption("bUseCustomSettings") == false) %} checked {% endif %} value="defaults">
<label for="dtbl_dlg_settings_{{ oUIBlock.GetTableId() }}">&nbsp;{{ 'UI:UseDefaultSettings'|dict_s }}</label> <label for="dtbl_dlg_settings_{{ oUIBlock.GetTableId() }}">&nbsp;{{ 'UI:UseDefaultSettings'|dict_s }}</label>
</p> </p>
<fieldset> <div class="ibo-panel ibo-is-neutral">
<legend class="transparent"> <div class="ibo-panel--header">
<input id="dtbl_dlg_specific_{{ oUIBlock.GetTableId() }}" type="radio" class="specific_settings" name="settings" {% if oUIBlock.GetOption("bUseCustomSettings") %} checked {% endif %} value="specific"> <div class="ibo-panel--header-left">
<label for="dtbl_dlg_specific_{{ oUIBlock.GetTableId() }}">&nbsp;&nbsp;{{ 'UI:UseSpecificSettings'|dict_s }}</label> <input id="dtbl_dlg_specific_{{ oUIBlock.GetTableId() }}" type="radio" class="specific_settings" name="settings" {% if oUIBlock.GetOption("bUseCustomSettings") %} checked {% endif %} value="specific">
</legend> <label for="dtbl_dlg_specific_{{ oUIBlock.GetTableId() }}">&nbsp;&nbsp;{{ 'UI:UseSpecificSettings'|dict_s }}</label>
{{ 'UI:ColumnsAndSortOrder'|dict_s }}<br> </div>
<ul class="sortable_field_list" id="sfl_{{ oUIBlock.GetTableId() }}"> </div>
<div class="ibo-panel--body ibo-font-ral-nor-100">
{{ 'UI:ColumnsAndSortOrder'|dict_s }}<br>
<div class="ibo-multi-column">
<div class="ibo-column ibo-without-margin ibo-list-column" style="max-height:150px; overflow-y: scroll;">
<ul class="sortable_field_list" id="sfl_{{ oUIBlock.GetTableId() }}">
</ul> </ul>
</div>
<p> {{ 'UI:Display_X_ItemsPerPage_prefix'|dict_s }}<input type="text" size="4" name="page_size" value="{{ oUIBlock.GetOption("iPageSize") }}">{{ 'UI:Display_X_ItemsPerPage_suffix'|dict_s }}</p> </div>
<p> {{ 'UI:Display_X_ItemsPerPage_prefix'|dict_s }}<input type="text" size="4" name="page_size" value="{{ oUIBlock.GetOption("iPageSize") }}">{{ 'UI:Display_X_ItemsPerPage_suffix'|dict_s }}</p>
</fieldset> </div>
<fieldset> </div>
<legend class="transparent"> <div class="ibo-panel ibo-is-neutral">
<input id="dtbl_dlg_save_{{ oUIBlock.GetTableId() }}" type="checkbox" {% if oUIBlock.GetOption("sTableId") != null %}checked{% endif %} name="save_settings"> <div class="ibo-panel--header">
<label for="dtbl_dlg_save_{{ oUIBlock.GetTableId() }}">&nbsp;&nbsp;{{ 'UI:UseSavetheSettings'|dict_s }}</label> <div class="ibo-panel--header-left">
</legend> <input id="dtbl_dlg_save_{{ oUIBlock.GetTableId() }}" type="checkbox" {% if oUIBlock.GetOption("sTableId") != null %}checked{% endif %} name="save_settings">
<p> <label for="dtbl_dlg_save_{{ oUIBlock.GetTableId() }}">&nbsp;&nbsp;{{ 'UI:UseSavetheSettings'|dict_s }}</label>
</div>
</div>
<div class="ibo-panel--body .ibo-font-ral-nor-100">
<input id="dtbl_dlg_this_list_{{ oUIBlock.GetTableId() }}" type="radio" name="scope" {% if oUIBlock.GetOption("sTableId") != null %} checked {% else %} disabled="disabled" stay-disabled="true"{% endif %} value="this_list"> <input id="dtbl_dlg_this_list_{{ oUIBlock.GetTableId() }}" type="radio" name="scope" {% if oUIBlock.GetOption("sTableId") != null %} checked {% else %} disabled="disabled" stay-disabled="true"{% endif %} value="this_list">
<label for="dtbl_dlg_this_list_{{ oUIBlock.GetTableId() }}">&nbsp;&nbsp;{{ 'UI:OnlyForThisList'|dict_s }}</label>&nbsp;&nbsp;&nbsp;&nbsp; <label for="dtbl_dlg_this_list_{{ oUIBlock.GetTableId() }}">&nbsp;&nbsp;{{ 'UI:OnlyForThisList'|dict_s }}</label>&nbsp;&nbsp;&nbsp;&nbsp;
<input id="dtbl_dlg_all_{{ oUIBlock.GetTableId() }}" type="radio" name="scope" {% if oUIBlock.GetOption("sTableId") == null %} checked {% endif %} value="defaults"> <input id="dtbl_dlg_all_{{ oUIBlock.GetTableId() }}" type="radio" name="scope" {% if oUIBlock.GetOption("sTableId") == null %} checked {% endif %} value="defaults">
<label for="dtbl_dlg_all_{{ oUIBlock.GetTableId() }}">&nbsp;&nbsp;{{ 'UI:ForAllLists'|dict_s }}</label> <label for="dtbl_dlg_all_{{ oUIBlock.GetTableId() }}">&nbsp;&nbsp;{{ 'UI:ForAllLists'|dict_s }}</label>
</p> </div>
</fieldset> </div>
<table style="width:100%"> <div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
<tr> <div class=" ui-dialog-buttonset">
<td style="text-align:center;"> <button type="button" class="ibo-button ibo-is-regular ibo-is-secondary " onclick="$('#datatable_dlg_{{ oUIBlock.GetTableId() }}').dialog('close')">&nbsp;{{ 'UI:Button:Cancel'|dict_s }}</button>
<button type="button" onclick="$('#datatable_dlg_{{ oUIBlock.GetTableId() }}').dialog('close')">&nbsp;{{ 'UI:Button:Cancel'|dict_s }}</button> <button type="submit" class="ibo-button ibo-is-regular ibo-is-primary" onclick="$('#datatable_dlg_{{ oUIBlock.GetTableId() }}').DataTableSettings('onDlgOk'); ">&nbsp;{{ 'UI:Button:Ok'|dict_s }}</button>
</td> </div>
<td style="text-align:center;"> </div>
<button type="submit" onclick="$('#datatable_dlg_{{ oUIBlock.GetTableId() }}').DataTableSettings('onDlgOk'); ">&nbsp;{{ 'UI:Button:Ok'|dict_s }}</button>
</td>
</tr>
</table>
</form> </form>
</div> </div>

View File

@@ -9,7 +9,7 @@ var table{{ oUIBlock.GetId()|sanitize(constant('utils::ENUM_SANITIZATION_FILTER_
search: false, search: false,
dom: "t", dom: "t",
}); });
if ($('#{{ oUIBlock.GetId() }}').find('thead').is(':visible'))
{
//table{{ oUIBlock.GetId()|sanitize(constant('utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER')) }}.columns.adjust().draw(); table{{ oUIBlock.GetId()|sanitize(constant('utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER')) }}.columns.adjust().draw();
//$(".dataTables_scrollBody thead").hide(); }

View File

@@ -1,5 +1,5 @@
{% if oUIBlock.GetSubBlocks() %} {% if oUIBlock.GetSubBlocks() %}
<fieldset class="ibo-fieldset{% if oUIBlock.IsHidden() %} ibo-is-hidden{% endif %}" id="{{ oUIBlock.GetId() }}"> <fieldset class="ibo-fieldset{% if oUIBlock.IsHidden() %} ibo-is-hidden{% endif %} {{ oUIBlock.GetAdditionalCSSClassesAsString() }}" id="{{ oUIBlock.GetId() }}">
<legend class="ibo-fieldset-legend">{{ oUIBlock.GetLegend() }}</legend> <legend class="ibo-fieldset-legend">{{ oUIBlock.GetLegend() }}</legend>
{% for oSubBlock in oUIBlock.GetSubBlocks() %} {% for oSubBlock in oUIBlock.GetSubBlocks() %}
{{ render_block(oSubBlock, {aPage: aPage}) }} {{ render_block(oSubBlock, {aPage: aPage}) }}

View File

@@ -6,6 +6,11 @@
{% if oUIBlock.GetAction() %} {% if oUIBlock.GetAction() %}
action="{{ oUIBlock.GetAction() }}" action="{{ oUIBlock.GetAction() }}"
{% endif %} {% endif %}
{% if oUIBlock.GetDataAttributes() %}
{% for sName, sValue in oUIBlock.GetDataAttributes() %}
data-{{ sName }}="{{ sValue }}"
{% endfor %}
{% endif %}
> >
{% apply spaceless %} {% apply spaceless %}
{% block iboContentBlockContainer %} {% block iboContentBlockContainer %}

View File

@@ -1,8 +1,14 @@
{% block iboInputLabel %} {% block iboInputLabel %}
{% endblock %} {% endblock %}
{% block iboInput %} {% block iboInput %}
<textarea <textarea
id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}" id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}"
cols="{{ oUIBlock.GetCols() }}" rows="{{ oUIBlock.GetRows() }}" cols="{{ oUIBlock.GetCols() }}" rows="{{ oUIBlock.GetRows() }}"
{% if oUIBlock.GetDataAttributes() %}
{% for sName, sValue in oUIBlock.GetDataAttributes() %}
data-{{ sName }}="{{ sValue }}"
{% endfor %}
{% endif %}
{% if oUIBlock.GetPlaceHolder() %} placeholder="{{ oUIBlock.GetPlaceHolder() }}" {% endif %}
>{{ oUIBlock.GetValue()|raw }}</textarea> >{{ oUIBlock.GetValue()|raw }}</textarea>
{% endblock %} {% endblock %}

View File

@@ -1,4 +1,10 @@
{% block iboInputLabel %} {% block iboInputLabel %}
<label for="{{ oUIBlock.GetId() }}">{{ oUIBlock.GetLabel() }}</label> {% if oUIBlock.IsLabelBefore() %}
{{ render_block(oUIBlock.GetInput()) }} <label for="{{ oUIBlock.GetId() }}">{{ oUIBlock.GetLabel() |raw }}</label>
{{ render_block(oUIBlock.GetInput()) }}
{% else %}
{{ render_block(oUIBlock.GetInput()) }}
<label for="{{ oUIBlock.GetId() }}">{{ oUIBlock.GetLabel() |raw }}</label>
{% endif %}
{% endblock %} {% endblock %}

View File

@@ -2,8 +2,14 @@
{% endblock %} {% endblock %}
{% block iboInput %} {% block iboInput %}
<input type="{{ oUIBlock.GetType() }}" id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}" value="{{ oUIBlock.GetValue()|raw }}" <input type="{{ oUIBlock.GetType() }}" id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}" value="{{ oUIBlock.GetValue()|raw }}"
class="{% if oUIBlock.IsHidden() %} ibo-is-hidden{% endif %}{% if oUIBlock.GetAdditionalCSSClassesAsString() %} {{ oUIBlock.GetAdditionalCSSClassesAsString() }}{% endif %}" class="{% if oUIBlock.IsHidden() %} ibo-is-hidden{% endif %}{% if oUIBlock.GetAdditionalCSSClassesAsString() %}{% endif %} {{ oUIBlock.GetAdditionalCSSClassesAsString() }}"
{% if oUIBlock.IsChecked() %} checked="checked"{% endif %} {% if oUIBlock.IsChecked() %} checked="checked"{% endif %}
{% if oUIBlock.IsDisabled() %} disabled{% endif %} {% if oUIBlock.IsDisabled() %} disabled{% endif %}
{% if oUIBlock.GetDataAttributes() %}
{% for sName, sValue in oUIBlock.GetDataAttributes() %}
data-{{ sName }}="{{ sValue }}"
{% endfor %}
{% endif %}
{% if oUIBlock.GetPlaceHolder() %} placeholder="{{ oUIBlock.GetPlaceHolder() }}" {% endif %}
> >
{% endblock %} {% endblock %}

View File

@@ -17,7 +17,18 @@
* You should have received a copy of the GNU Affero General Public License * 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(__DIR__.'/../approot.inc.php');
require_once(APPROOT.'/application/application.inc.php'); require_once(APPROOT.'/application/application.inc.php');
require_once(APPROOT.'/application/nicewebpage.class.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 = '') function DisplayExpressionForm(WebPage $oP, $sAction, $sExpression = '', $sExceptionMessage = '')
{ {
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:ScopeDefinition').'</legend>'); $oForm = FormUIBlockFactory::MakeStandard('form');
$oP->add('<form id="export-form" action="'.$sAction.'" method="post">'); $oForm->SetAction($sAction);
$oP->add('<input type="hidden" name="interactive" value="1">'); $oP->AddSubBlock($oForm);
$oP->add('<table style="width:100%" class="export_parameters">');
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('interactive', '1'));
$oFieldQuery = FieldUIBlockFactory::MakeStandard('<input type="radio" name="query_mode" value="oql" id="radio_oql" checked><label for="radio_oql">'.Dict::S('Core:BulkExportLabelOQLExpression').'</label>');
$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('<input type="radio" name="query_mode" value="phrasebook" id="radio_phrasebook"><label for="radio_phrasebook">'.Dict::S('Core:BulkExportLabelPhrasebookEntry').'</label>');
$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('<table style="width:100%" class="export_parameters">');
$sExpressionHint = empty($sExceptionMessage) ? '' : '<tr><td colspan="2">'.htmlentities($sExceptionMessage, ENT_QUOTES, 'UTF-8').'</td></tr>'; $sExpressionHint = empty($sExceptionMessage) ? '' : '<tr><td colspan="2">'.htmlentities($sExceptionMessage, ENT_QUOTES, 'UTF-8').'</td></tr>';
$oP->add('<tr><td class="column-label"><span style="white-space: nowrap;"><input type="radio" name="query_mode" value="oql" id="radio_oql" checked><label for="radio_oql">'.Dict::S('Core:BulkExportLabelOQLExpression').'</label></span></td>'); $oP->add('<tr><td class="column-label"><span style="white-space: nowrap;"><input type="radio" name="query_mode" value="oql" id="radio_oql" checked><label for="radio_oql">'.Dict::S('Core:BulkExportLabelOQLExpression').'</label></span></td>');
$oP->add('<td><textarea style="width:100%" cols="70" rows="8" name="expression" id="textarea_oql" placeholder="'.Dict::S('Core:BulkExportQueryPlaceholder').'">'.htmlentities($sExpression, ENT_QUOTES, 'UTF-8').'</textarea></td></tr>'); $oP->add('<td><textarea style="width:100%" cols="70" rows="8" name="expression" id="textarea_oql" placeholder="'.Dict::S('Core:BulkExportQueryPlaceholder').'">'.htmlentities($sExpression, ENT_QUOTES, 'UTF-8').'</textarea></td></tr>');
@@ -139,24 +172,20 @@ function DisplayExpressionForm(WebPage $oP, $sAction, $sExpression = '', $sExcep
$oP->add('<td><select name="query" id="select_phrasebook">'); $oP->add('<td><select name="query" id="select_phrasebook">');
$oP->add('<option value="">'.Dict::S('UI:SelectOne').'</option>'); $oP->add('<option value="">'.Dict::S('UI:SelectOne').'</option>');
$oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL'); $oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL');
$oSearch->UpdateContextFromUser(); $oSearch->UpdateContextFromUser();
$oQueries = new DBObjectSet($oSearch); $oQueries = new DBObjectSet($oSearch);
while ($oQuery = $oQueries->Fetch()) while ($oQuery = $oQueries->Fetch()) {
{
$oP->add('<option value="'.$oQuery->GetKey().'">'.htmlentities($oQuery->Get('name'), ENT_QUOTES, 'UTF-8').'</option>'); $oP->add('<option value="'.$oQuery->GetKey().'">'.htmlentities($oQuery->Get('name'), ENT_QUOTES, 'UTF-8').'</option>');
} }
$oP->add('</select></td></tr>'); $oP->add('</select></td></tr>');*/
$oP->add('<tr><td colspan="2" style="text-align:right"><button type="submit" id="next-btn">'.Dict::S('UI:Button:Next').'</button></td></tr>'); $oForm->AddSubBlock(ButtonUIBlockFactory::MakeForPrimaryAction(Dict::S('UI:Button:Next'), "", "", true, "next-btn"));
$oP->add('</table>');
$oP->add('</form>');
$oP->add('</fieldset>');
$oP->p('<a target="_blank" href="'.utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php">'.Dict::S('Core:BulkExportCanRunNonInteractive').'</a>'); $oP->p('<a target="_blank" href="'.utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php">'.Dict::S('Core:BulkExportCanRunNonInteractive').'</a>');
$oP->p('<a target="_blank" href="'.utils::GetAbsoluteUrlAppRoot().'webservices/export.php">'.Dict::S('Core:BulkExportLegacyExport').'</a>'); $oP->p('<a target="_blank" href="'.utils::GetAbsoluteUrlAppRoot().'webservices/export.php">'.Dict::S('Core:BulkExportLegacyExport').'</a>');
$sJSEmptyOQL = json_encode(Dict::S('Core:BulkExportMessageEmptyOQL')); $sJSEmptyOQL = json_encode(Dict::S('Core:BulkExportMessageEmptyOQL'));
$sJSEmptyQueryId = json_encode(Dict::S('Core:BulkExportMessageEmptyPhrasebookEntry')); $sJSEmptyQueryId = json_encode(Dict::S('Core:BulkExportMessageEmptyPhrasebookEntry'));
$oP->add_ready_script( $oP->add_ready_script(
<<<EOF <<<EOF
var colWidth = 0; var colWidth = 0;
$('td.column-label').each(function() { $('td.column-label').each(function() {
var jLabel = $(this).find('span'); var jLabel = $(this).find('span');
@@ -203,7 +232,7 @@ function DisplayForm(WebPage $oP, $sAction = '', $sExpression = '', $sQueryId =
$oP->add_script(DateTimeFormat::GetJSSQLToCustomFormat()); $oP->add_script(DateTimeFormat::GetJSSQLToCustomFormat());
$sJSDefaultDateTimeFormat = json_encode((string)AttributeDateTime::GetFormat()); $sJSDefaultDateTimeFormat = json_encode((string)AttributeDateTime::GetFormat());
$oP->add_script( $oP->add_script(
<<<EOF <<<EOF
function FormatDatesInPreview(sRadioSelector, sPreviewSelector) function FormatDatesInPreview(sRadioSelector, sPreviewSelector)
{ {
if ($('#'+sRadioSelector+'_date_time_format_default').prop('checked')) if ($('#'+sRadioSelector+'_date_time_format_default').prop('checked'))
@@ -230,102 +259,106 @@ EOF
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/tabularfieldsselector.js'); $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/tabularfieldsselector.js');
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.dragtable.js'); $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.dragtable.js');
$oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/dragtable.css'); $oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/dragtable.css');
$oP->add('<form id="export-form" action="'.$sAction.'" method="post" data-state="not-yet-started">');
$oForm = FormUIBlockFactory::MakeStandard("export-form");
$oForm->SetAction($sAction);
$oForm->AddDataAttribute("state", "not-yet-started");
$oP->AddSubBlock($oForm);
$bExpressionIsValid = true; $bExpressionIsValid = true;
$sExpressionError = ''; $sExpressionError = '';
if (($sExpression === null) && ($sQueryId === null)) if (($sExpression === null) && ($sQueryId === null)) {
{ $bExpressionIsValid = false;
$bExpressionIsValid = false; } else if ($sExpression !== '') {
} try {
else if ($sExpression !== '')
{
try
{
$oExportSearch = DBObjectSearch::FromOQL($sExpression); $oExportSearch = DBObjectSearch::FromOQL($sExpression);
$oExportSearch->UpdateContextFromUser(); $oExportSearch->UpdateContextFromUser();
} }
catch(OQLException $e) catch (OQLException $e) {
{
$bExpressionIsValid = false; $bExpressionIsValid = false;
$sExpressionError = $e->getMessage(); $sExpressionError = $e->getMessage();
} }
} }
if (!$bExpressionIsValid) if (!$bExpressionIsValid) {
{
DisplayExpressionForm($oP, $sAction, $sExpression, $sExpressionError); DisplayExpressionForm($oP, $sAction, $sExpression, $sExpressionError);
return; return;
} }
if ($sExpression !== '') if ($sExpression !== '') {
{ $oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden("expression", htmlentities($sExpression, ENT_QUOTES, 'UTF-8')));
$oP->add('<input type="hidden" name="expression" value="'.htmlentities($sExpression, ENT_QUOTES, 'UTF-8').'">');
$oExportSearch = DBObjectSearch::FromOQL($sExpression); $oExportSearch = DBObjectSearch::FromOQL($sExpression);
$oExportSearch->UpdateContextFromUser(); $oExportSearch->UpdateContextFromUser();
} } else {
else
{
$oQuery = MetaModel::GetObject('QueryOQL', $sQueryId); $oQuery = MetaModel::GetObject('QueryOQL', $sQueryId);
$oExportSearch = DBObjectSearch::FromOQL($oQuery->Get('oql')); $oExportSearch = DBObjectSearch::FromOQL($oQuery->Get('oql'));
$oExportSearch->UpdateContextFromUser(); $oExportSearch->UpdateContextFromUser();
$oP->add('<input type="hidden" name="query" value="'.htmlentities($sQueryId, ENT_QUOTES, 'UTF-8').'">'); $oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden("query", htmlentities($sQueryId, ENT_QUOTES, 'UTF-8')));
} }
$aFormPartsByFormat = array(); $aFormPartsByFormat = array();
$aAllFormParts = array(); $aAllFormParts = array();
if ($sFormat == null) if ($sFormat == null) {
{
// No specific format chosen // No specific format chosen
$sDefaultFormat = utils::ReadParam('format', 'xlsx'); $sDefaultFormat = utils::ReadParam('format', 'xlsx');
$oP->add('<p>'.Dict::S('Core:BulkExport:ExportFormatPrompt').' <select name="format" id="format_selector">');
$oSelect = InputUIBlockFactory::MakeForSelectWithLabel("format", Dict::S('Core:BulkExport:ExportFormatPrompt'), "format_selector");
$oSelect->SetBeforeInput(true);
$oForm->AddSubBlock($oSelect);
$aSupportedFormats = BulkExport::FindSupportedFormats(); $aSupportedFormats = BulkExport::FindSupportedFormats();
asort($aSupportedFormats); asort($aSupportedFormats);
foreach($aSupportedFormats as $sFormatCode => $sLabel) foreach ($aSupportedFormats as $sFormatCode => $sLabel) {
{ $oSelect->GetInput()->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption($sFormatCode, htmlentities($sLabel, ENT_QUOTES, 'UTF-8'), ($sFormatCode == $sDefaultFormat)));
$sSelected = ($sFormatCode == $sDefaultFormat) ? 'selected' : '';
$oP->add('<option value="'.$sFormatCode.'" '.$sSelected.'>'.htmlentities($sLabel, ENT_QUOTES, 'UTF-8').'</option>');
$oExporter = BulkExport::FindExporter($sFormatCode); $oExporter = BulkExport::FindExporter($sFormatCode);
$oExporter->SetObjectList($oExportSearch); $oExporter->SetObjectList($oExportSearch);
$aParts = $oExporter->EnumFormParts(); $aParts = $oExporter->EnumFormParts();
foreach($aParts as $sPartId => $void) foreach ($aParts as $sPartId => $void) {
{
$aAllFormParts[$sPartId] = $oExporter; $aAllFormParts[$sPartId] = $oExporter;
} }
$aFormPartsByFormat[$sFormatCode] = array_keys($aParts); $aFormPartsByFormat[$sFormatCode] = array_keys($aParts);
} }
$oP->add('</select></p>');
} } else {
else
{
// One specific format was chosen // One specific format was chosen
$oP->add('<input type="hidden" name="format" value="'.htmlentities($sFormat, ENT_QUOTES, 'UTF-8').'">'); $oSelect = InputUIBlockFactory::MakeForHidden("format", htmlentities($sFormat, ENT_QUOTES, 'UTF-8'));
$oForm->AddSubBlock($oSelect);
$oExporter = BulkExport::FindExporter($sFormat, $oExportSearch); $oExporter = BulkExport::FindExporter($sFormat, $oExportSearch);
$aParts = $oExporter->EnumFormParts(); $aParts = $oExporter->EnumFormParts();
foreach($aParts as $sPartId => $void) foreach ($aParts as $sPartId => $void) {
{
$aAllFormParts[$sPartId] = $oExporter; $aAllFormParts[$sPartId] = $oExporter;
} }
$aFormPartsByFormat[$sFormat] = array_keys($aAllFormParts); $aFormPartsByFormat[$sFormat] = array_keys($aAllFormParts);
} }
foreach($aAllFormParts as $sPartId => $oExport) foreach ($aAllFormParts as $sPartId => $oExport) {
{ $UIContentBlock = UIContentBlockUIBlockFactory::MakeStandard('form_part_'.$sPartId)->AddCSSClass('form_part');
$oP->add('<div class="form_part" id="form_part_'.$sPartId.'">'); $oForm->AddSubBlock($UIContentBlock);
$oExport->DisplayFormPart($oP, $sPartId); $UIContentBlock->AddSubBlock($oExport->GetFormPart($oP, $sPartId));
$oP->add('</div>');
} }
$oP->add('</form>'); //end of form
$oP->add('<div id="export-feedback" style="display:none;"><p class="export-message" style="text-align:center;">'.Dict::S('ExcelExport:PreparingExport').'</p><div class="export-progress-bar" style="max-width:30em; margin-left:auto;margin-right:auto;"><div class="export-progress-message" style="text-align:center;"></div></div></div>'); $oBlockExport = UIContentBlockUIBlockFactory::MakeStandard("export-feedback")->SetIsHidden(true);
$oP->add('<button type="button" id="export-btn">'.Dict::S('UI:Button:Export').'</button>'); $oBlockExport->AddSubBlock(new Html('<p class="export-message" style="text-align:center;">'.Dict::S('ExcelExport:PreparingExport').'</p>'));
$oP->add('<div id="export_text_result" style="display:none;">'); $oBlockExport->AddSubBlock(new Html('<div class="export-progress-bar" style="max-width:30em; margin-left:auto;margin-right:auto;"><div class="export-progress-message" style="text-align:center;"></div></div>'));
$oP->add('<div>'.Dict::S('Core:BulkExport:ExportResult').'</div>'); $oP->AddSubBlock($oBlockExport);
$oP->add('<textarea id="export_content" style="width:100%;min-height:15em;"></textarea>'); if ($sFormat == null) {//if it's global export
$oP->add('</div>'); $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); $sJSParts = json_encode($aFormPartsByFormat);
$oP->add_ready_script( $oP->add_ready_script(
<<<EOF <<<EOF
window.aFormParts = $sJSParts; window.aFormParts = $sJSParts;
$('#format_selector').on('change init', function() { $('#format_selector').on('change init', function() {
console.warn('yo'+$(this).val());
ExportToggleFormat($(this).val()); ExportToggleFormat($(this).val());
}).trigger('init'); }).trigger('init');
@@ -343,7 +376,7 @@ ExportInitButton('#export-btn');
EOF EOF
); );
} }
function InteractiveShell($sExpression, $sQueryId, $sFormat, $sFileName, $sMode) function InteractiveShell($sExpression, $sQueryId, $sFormat, $sFileName, $sMode)
@@ -355,7 +388,7 @@ function InteractiveShell($sExpression, $sQueryId, $sFormat, $sFileName, $sMode)
$sExportBtnLabel = json_encode(Dict::S('UI:Button:Export')); $sExportBtnLabel = json_encode(Dict::S('UI:Button:Export'));
$sJSTitle = json_encode(htmlentities(utils::ReadParam('dialog_title', '', false, 'raw_data'), ENT_QUOTES, 'UTF-8')); $sJSTitle = json_encode(htmlentities(utils::ReadParam('dialog_title', '', false, 'raw_data'), ENT_QUOTES, 'UTF-8'));
$oP->add_ready_script( $oP->add_ready_script(
<<<EOF <<<EOF
$('#interactive_export_dlg').dialog({ $('#interactive_export_dlg').dialog({
autoOpen: true, autoOpen: true,
modal: true, modal: true,
@@ -372,40 +405,28 @@ function InteractiveShell($sExpression, $sQueryId, $sFormat, $sFileName, $sMode)
setTimeout(function() { $('#interactive_export_dlg').dialog('option', { position: { my: "center", at: "center", of: window }}); $('#export-btn').hide(); ExportInitButton('#export-dlg-submit'); }, 100); setTimeout(function() { $('#interactive_export_dlg').dialog('option', { position: { my: "center", at: "center", of: window }}); $('#export-btn').hide(); ExportInitButton('#export-dlg-submit'); }, 100);
EOF EOF
); );
} } else {
else
{
$oP = new iTopWebPage('iTop Export'); $oP = new iTopWebPage('iTop Export');
$oP->SetBreadCrumbEntry('ui-tool-export', Dict::S('Menu:ExportMenu'), Dict::S('Menu:ExportMenu+'), '', 'fas fa-file-export', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES); $oP->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 // 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 = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId));
$oSearch->UpdateContextFromUser(); $oSearch->UpdateContextFromUser();
$oQueries = new DBObjectSet($oSearch); $oQueries = new DBObjectSet($oSearch);
if ($oQueries->Count() > 0) if ($oQueries->Count() > 0) {
{
$oQuery = $oQueries->Fetch(); $oQuery = $oQueries->Fetch();
$sExpression = $oQuery->Get('oql'); $sExpression = $oQuery->Get('oql');
} } else {
else
{
ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'"); ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'");
} }
} } else {
else if (utils::IsModeCLI()) {
{
if (utils::IsModeCLI())
{
Usage($oP); Usage($oP);
ReportErrorAndExit("No expression or query phrasebook identifier supplied."); ReportErrorAndExit("No expression or query phrasebook identifier supplied.");
} } else {
else
{
// form to enter an OQL query or pick a query phrasebook identifier // form to enter an OQL query or pick a query phrasebook identifier
DisplayForm($oP, utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php', $sExpression, $sQueryId, $sFormat); DisplayForm($oP, utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php', $sExpression, $sQueryId, $sFormat);
$oP->output(); $oP->output();
@@ -414,29 +435,22 @@ EOF
} }
} }
if ($sFormat !== null) if ($sFormat !== null) {
{
$oExporter = BulkExport::FindExporter($sFormat); $oExporter = BulkExport::FindExporter($sFormat);
if ($oExporter === null) if ($oExporter === null) {
{
$aSupportedFormats = BulkExport::FindSupportedFormats(); $aSupportedFormats = BulkExport::FindSupportedFormats();
ReportErrorAndExit("Invalid output format: '$sFormat'. The supported formats are: ".implode(', ', array_keys($aSupportedFormats))); 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); DisplayForm($oP, utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php', $sExpression, $sQueryId, $sFormat);
} }
} } else {
else
{
DisplayForm($oP, utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php', $sExpression, $sQueryId, $sFormat); DisplayForm($oP, utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php', $sExpression, $sQueryId, $sFormat);
} }
if ($sMode == 'dialog') if ($sMode == 'dialog') {
{
$oP->add('</div>'); $oP->add('</div>');
} }
$oP->output(); $oP->output();
} }
/** /**
@@ -448,54 +462,42 @@ EOF
*/ */
function CheckParameters($sExpression, $sQueryId, $sFormat) 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"); 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."); ReportErrorAndUsage("Missing parameter. The parameter 'expression' or 'query' must be specified.");
} }
// Either $sExpression or $sQueryId 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 = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId));
$oSearch->UpdateContextFromUser(); $oSearch->UpdateContextFromUser();
$oQueries = new DBObjectSet($oSearch); $oQueries = new DBObjectSet($oSearch);
if ($oQueries->Count() > 0) if ($oQueries->Count() > 0) {
{
$oQuery = $oQueries->Fetch(); $oQuery = $oQueries->Fetch();
$sExpression = $oQuery->Get('oql'); $sExpression = $oQuery->Get('oql');
} } else {
else
{
ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'"); ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'");
} }
} }
if ($sFormat === null) if ($sFormat === null) {
{
ReportErrorAndUsage("Missing parameter 'format'."); ReportErrorAndUsage("Missing parameter 'format'.");
} }
// Check if the supplied query is valid (and all the parameters are supplied // Check if the supplied query is valid (and all the parameters are supplied
try try {
{
$oSearch = DBObjectSearch::FromOQL($sExpression); $oSearch = DBObjectSearch::FromOQL($sExpression);
$oSearch->UpdateContextFromUser(); $oSearch->UpdateContextFromUser();
$aArgs = array(); $aArgs = array();
foreach($oSearch->GetQueryParams() as $sParam => $foo) foreach ($oSearch->GetQueryParams() as $sParam => $foo) {
{
$value = utils::ReadParam('arg_'.$sParam, null, true, 'raw_data'); $value = utils::ReadParam('arg_'.$sParam, null, true, 'raw_data');
if (!is_null($value)) if (!is_null($value)) {
{
$aArgs[$sParam] = $value; $aArgs[$sParam] = $value;
} } else {
else
{
throw new MissingQueryArgument("Missing parameter '--arg_$sParam'"); throw new MissingQueryArgument("Missing parameter '--arg_$sParam'");
} }
} }
@@ -524,12 +526,12 @@ function CheckParameters($sExpression, $sQueryId, $sFormat)
$oSearch = null; $oSearch = null;
ReportErrorAndExit($e->getMessage()); ReportErrorAndExit($e->getMessage());
} }
$oExporter->SetFormat($sFormat); $oExporter->SetFormat($sFormat);
$oExporter->SetChunkSize(EXPORTER_DEFAULT_CHUNK_SIZE); $oExporter->SetChunkSize(EXPORTER_DEFAULT_CHUNK_SIZE);
$oExporter->SetObjectList($oSearch); $oExporter->SetObjectList($oSearch);
$oExporter->ReadParameters(); $oExporter->ReadParameters();
return $oExporter; return $oExporter;
} }
@@ -543,7 +545,7 @@ function DoExport(WebPage $oP, BulkExport $oExporter, $bInteractive = false)
$exportResult .= $oExporter->GetNextChunk($aStatus); $exportResult .= $oExporter->GetNextChunk($aStatus);
} }
while (($aStatus['code'] != 'done') && ($aStatus['code'] != 'error')); while (($aStatus['code'] != 'done') && ($aStatus['code'] != 'error'));
if ($aStatus['code'] == 'error') if ($aStatus['code'] == 'error')
{ {
$oExporter->Cleanup(); $oExporter->Cleanup();
@@ -570,83 +572,64 @@ function DoExport(WebPage $oP, BulkExport $oExporter, $bInteractive = false)
// Command Line mode // Command Line mode
// //
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
if (utils::IsModeCLI()) if (utils::IsModeCLI()) {
{
SetupUtils::CheckPhpAndExtensionsForCli(new CLIPage('iTop - Export')); SetupUtils::CheckPhpAndExtensionsForCli(new CLIPage('iTop - Export'));
try try {
{
// Do this before loging, in order to allow setting user credentials from within the file // Do this before loging, in order to allow setting user credentials from within the file
utils::UseParamFile(); utils::UseParamFile();
} }
catch(Exception $e) catch (Exception $e) {
{
echo "Error: ".$e->GetMessage()."<br/>\n"; echo "Error: ".$e->GetMessage()."<br/>\n";
exit(EXIT_CODE_FATAL); exit(EXIT_CODE_FATAL);
} }
$sAuthUser = utils::ReadParam('auth_user', null, true /* Allow CLI */, 'raw_data'); $sAuthUser = utils::ReadParam('auth_user', null, true /* Allow CLI */, 'raw_data');
$sAuthPwd = utils::ReadParam('auth_pwd', 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'"); ReportErrorAndUsage("Missing parameter '--auth_user'");
} }
if ($sAuthPwd == null) if ($sAuthPwd == null) {
{
ReportErrorAndUsage("Missing parameter '--auth_pwd'"); ReportErrorAndUsage("Missing parameter '--auth_pwd'");
} }
if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd)) if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd)) {
{
UserRights::Login($sAuthUser); // Login & set the user's language UserRights::Login($sAuthUser); // Login & set the user's language
} } else {
else
{
ReportErrorAndExit("Access restricted or wrong credentials for user '$sAuthUser'"); ReportErrorAndExit("Access restricted or wrong credentials for user '$sAuthUser'");
} }
$sExpression = utils::ReadParam('expression', null, true /* Allow CLI */, 'raw_data'); $sExpression = utils::ReadParam('expression', null, true /* Allow CLI */, 'raw_data');
$sQueryId = utils::ReadParam('query', null, true /* Allow CLI */, 'raw_data'); $sQueryId = utils::ReadParam('query', null, true /* Allow CLI */, 'raw_data');
$bLocalize = (utils::ReadParam('no_localize', 0) != 1); $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"); 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."); 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 = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId));
$oSearch->UpdateContextFromUser(); $oSearch->UpdateContextFromUser();
$oQueries = new DBObjectSet($oSearch); $oQueries = new DBObjectSet($oSearch);
if ($oQueries->Count() > 0) if ($oQueries->Count() > 0) {
{
$oQuery = $oQueries->Fetch(); $oQuery = $oQueries->Fetch();
$sExpression = $oQuery->Get('oql'); $sExpression = $oQuery->Get('oql');
} } else {
else
{
ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'"); ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'");
} }
} }
try try {
{
$oSearch = DBObjectSearch::FromOQL($sExpression); $oSearch = DBObjectSearch::FromOQL($sExpression);
$oSearch->UpdateContextFromUser(); $oSearch->UpdateContextFromUser();
$aArgs = array(); $aArgs = array();
foreach($oSearch->GetQueryParams() as $sParam => $foo) foreach ($oSearch->GetQueryParams() as $sParam => $foo) {
{
$value = utils::ReadParam('arg_'.$sParam, null, true, 'raw_data'); $value = utils::ReadParam('arg_'.$sParam, null, true, 'raw_data');
if (!is_null($value)) if (!is_null($value)) {
{
$aArgs[$sParam] = $value; $aArgs[$sParam] = $value;
} } else {
else
{
throw new MissingQueryArgument("Missing parameter '--arg_$sParam'"); throw new MissingQueryArgument("Missing parameter '--arg_$sParam'");
} }
} }
@@ -659,21 +642,21 @@ if (utils::IsModeCLI())
$aSupportedFormats = BulkExport::FindSupportedFormats(); $aSupportedFormats = BulkExport::FindSupportedFormats();
ReportErrorAndExit("Invalid output format: '$sFormat'. The supported formats are: ".implode(', ', array_keys($aSupportedFormats))); ReportErrorAndExit("Invalid output format: '$sFormat'. The supported formats are: ".implode(', ', array_keys($aSupportedFormats)));
} }
$oExporter->SetFormat($sFormat); $oExporter->SetFormat($sFormat);
$oExporter->SetChunkSize(EXPORTER_DEFAULT_CHUNK_SIZE); $oExporter->SetChunkSize(EXPORTER_DEFAULT_CHUNK_SIZE);
$oExporter->SetObjectList($oSearch); $oExporter->SetObjectList($oSearch);
$oExporter->ReadParameters(); $oExporter->ReadParameters();
$exportResult = $oExporter->GetHeader(); $exportResult = $oExporter->GetHeader();
$aStatus = array(); $aStatus = array();
do do
{ {
$exportResult .= $oExporter->GetNextChunk($aStatus); $exportResult .= $oExporter->GetNextChunk($aStatus);
} }
while (($aStatus['code'] != 'done') && ($aStatus['code'] != 'error')); while (($aStatus['code'] != 'done') && ($aStatus['code'] != 'error'));
if ($aStatus['code'] == 'error') if ($aStatus['code'] == 'error')
{ {
ReportErrorAndExit("Export failed: '{$aStatus['message']}'"); ReportErrorAndExit("Export failed: '{$aStatus['message']}'");
@@ -684,7 +667,7 @@ if (utils::IsModeCLI())
echo $exportResult; echo $exportResult;
} }
$oExporter->Cleanup(); $oExporter->Cleanup();
} }
catch(MissingQueryArgument $e) catch(MissingQueryArgument $e)
{ {
@@ -698,7 +681,7 @@ if (utils::IsModeCLI())
{ {
ReportErrorAndExit($e->getMessage()); ReportErrorAndExit($e->getMessage());
} }
exit; exit;
} }
@@ -711,7 +694,7 @@ if (utils::IsModeCLI())
try try
{ {
require_once(APPROOT.'/application/loginwebpage.class.inc.php'); require_once(APPROOT.'/application/loginwebpage.class.inc.php');
// Main parameters // Main parameters
$sExpression = utils::ReadParam('expression', null, true /* Allow CLI */, 'raw_data'); $sExpression = utils::ReadParam('expression', null, true /* Allow CLI */, 'raw_data');
$sQueryId = utils::ReadParam('query', 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 LoginWebPage::DoLogin(); // Check user rights and prompt if needed
ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker'); ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker');
if ($bInteractive) if ($bInteractive) {
{
InteractiveShell($sExpression, $sQueryId, $sFormat, $sFileName, $sMode); InteractiveShell($sExpression, $sQueryId, $sFormat, $sFileName, $sMode);
} } else {
else
{
$oExporter = CheckParameters($sExpression, $sQueryId, $sFormat); $oExporter = CheckParameters($sExpression, $sQueryId, $sFormat);
$sMimeType = $oExporter->GetMimeType(); $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. // 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 = new NiceWebPage('iTop export');
$oP->add_xframe_options(); $oP->add_xframe_options();
$oP->add_ready_script("$('table.listResults').tablesorter({widgets: ['MyZebra']});"); $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/all.min.css');
$oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/v4-shims.min.css'); $oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/v4-shims.min.css');
} } else {
else {
$oP = new WebPage('iTop export'); $oP = new WebPage('iTop export');
$oP->add_xframe_options(); $oP->add_xframe_options();
$oP->add_style("table br { mso-data-placement:same-cell; }"); // Trick for Excel: keep line breaks inside the same cell ! $oP->add_style("table br { mso-data-placement:same-cell; }"); // Trick for Excel: keep line breaks inside the same cell !