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++;
}
$sJSReload .= $oDashboardRow->GetJSRefreshCallback()."\n";
$sJSReload .= $oDashboardRow->GetJSRefreshCallback()." ";
}
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");

View File

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

View File

@@ -375,7 +375,22 @@ abstract class BulkExport
return array();
}
/**
* @deprecated since 3.0 replaced by GetFormPart
*/
public function DisplayFormPart(WebPage $oP, $sPartId)
{
$oP->AddSubBlock($this->GetFormPart($oP, $sPartId));
}
/**
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
*/
public function GetFormPart(WebPage $oP, $sPartId)
{
}
@@ -383,6 +398,7 @@ abstract class BulkExport
{
}
public function ReadParameters()
{
$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
// 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
@@ -22,7 +28,6 @@
* @copyright Copyright (C) 2015-2016 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
class CSVBulkExport extends TabularBulkExport
{
public function DisplayUsage(Page $oP)
@@ -103,18 +108,31 @@ class CSVBulkExport extends TabularBulkExport
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)
{
switch($sPartId)
/**
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
*/
public function GetFormPart(WebPage $oP, $sPartId)
{
switch ($sPartId) {
case 'interactive_fields_csv':
$this->GetInteractiveFieldsWidget($oP, 'interactive_fields_csv');
return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_csv');
break;
case 'csv_options':
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:CSVOptions').'</legend>');
$oP->add('<table class="export_parameters"><tr><td style="vertical-align:top">');
$oP->add('<h3>'.Dict::S('UI:CSVImport:SeparatorCharacter').'</h3>');
$oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:CSVOptions'));
$oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard();
$oMulticolumn->AddCSSClass('ibo-multi-column');
$oPanel->AddSubBlock($oMulticolumn);
//SeparatorCharacter
$oFieldSetSeparator = FieldSetUIBlockFactory::MakeStandard(Dict::S('UI:CSVImport:SeparatorCharacter'));
$oFieldSetSeparator->AddCSSClass('ibo-column');
$oMulticolumn->AddSubBlock($oFieldSetSeparator);
$sRawSeparator = utils::ReadParam('separator', ',', true, 'raw_data');
$sCustomDateTimeFormat = utils::ReadParam('', ',', true, 'raw_data');
$aSep = array(
@@ -123,22 +141,25 @@ class CSVBulkExport extends TabularBulkExport
'tab' => Dict::S('UI:CSVImport:SeparatorTab+'),
);
$sOtherSeparator = '';
if (!array_key_exists($sRawSeparator, $aSep))
{
if (!array_key_exists($sRawSeparator, $aSep)) {
$sOtherSeparator = $sRawSeparator;
$sRawSeparator = 'other';
}
$aSep['other'] = Dict::S('UI:CSVImport:SeparatorOther').' <input type="text" size="3" name="other-separator" value="'.htmlentities($sOtherSeparator, ENT_QUOTES, 'UTF-8').'"/>';
foreach($aSep as $sVal => $sLabel)
{
$sChecked = ($sVal == $sRawSeparator) ? 'checked' : '';
$oP->add('<input type="radio" name="separator" value="'.htmlentities($sVal, ENT_QUOTES, 'UTF-8').'" '.$sChecked.'/>&nbsp;'.$sLabel.'<br/>');
foreach ($aSep as $sVal => $sLabel) {
$oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "separator", htmlentities($sVal, ENT_QUOTES, 'UTF-8'), $sLabel, "radio");
$oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator));
$oRadio->SetBeforeInput(false);
$oRadio->AddCSSClass('ibo-input--label-right');
$oFieldSetSeparator->AddSubBlock($oRadio);
$oFieldSetSeparator->AddSubBlock(new Html('</br>'));
}
$oP->add('</td><td style="vertical-align:top">');
$oP->add('<h3>'.Dict::S('UI:CSVImport:TextQualifierCharacter').'</h3>');
//TextQualifierCharacter
$oFieldSetTextQualifier = FieldSetUIBlockFactory::MakeStandard(Dict::S('UI:CSVImport:TextQualifierCharacter'));
$oFieldSetTextQualifier->AddCSSClass('ibo-column');
$oMulticolumn->AddSubBlock($oFieldSetTextQualifier);
$sRawQualifier = utils::ReadParam('text-qualifier', '"', true, 'raw_data');
$aQualifiers = array(
@@ -146,56 +167,73 @@ class CSVBulkExport extends TabularBulkExport
'\'' => Dict::S('UI:CSVImport:QualifierSimpleQuote+'),
);
$sOtherQualifier = '';
if (!array_key_exists($sRawQualifier, $aQualifiers))
{
if (!array_key_exists($sRawQualifier, $aQualifiers)) {
$sOtherQualifier = $sRawQualifier;
$sRawQualifier = 'other';
}
$aQualifiers['other'] = Dict::S('UI:CSVImport:QualifierOther').' <input type="text" size="3" name="other-text-qualifier" value="'.htmlentities($sOtherQualifier, ENT_QUOTES, 'UTF-8').'"/>';
foreach($aQualifiers as $sVal => $sLabel)
{
$sChecked = ($sVal == $sRawQualifier) ? 'checked' : '';
$oP->add('<input type="radio" name="text-qualifier" value="'.htmlentities($sVal, ENT_QUOTES, 'UTF-8').'" '.$sChecked.'/>&nbsp;'.$sLabel.'<br/>');
foreach ($aQualifiers as $sVal => $sLabel) {
$oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "separator", htmlentities($sVal, ENT_QUOTES, 'UTF-8'), $sLabel, "radio");
$oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator));
$oRadio->SetBeforeInput(false);
$oRadio->GetInput()->AddCSSClass('ibo-input--label-right');
$oFieldSetTextQualifier->AddSubBlock($oRadio);
$oFieldSetTextQualifier->AddSubBlock(new Html('</br>'));
}
$sChecked = (utils::ReadParam('no_localize', 0) == 1) ? ' checked ' : '';
$oP->add('</td><td style="vertical-align:top">');
$oP->add('<h3>'.Dict::S('Core:BulkExport:CSVLocalization').'</h3>');
$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>');
$oP->add('<br/>');
$oP->add('<br/>');
$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
//Localization
$oFieldSetLocalization = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:CSVLocalization'));
$oFieldSetLocalization->AddCSSClass('ibo-column');
$oMulticolumn->AddSubBlock($oFieldSetLocalization);
$oCheckBox = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionNoLocalize'), "no_localize", "1", "csv_no_localize", "checkbox");
$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());
$sDefaultEncoding = MetaModel::GetConfig()->Get('csv_file_default_charset');
foreach($aPossibleEncodings as $sIconvCode => $sDisplayName )
{
$sSelected = '';
if ($sIconvCode == $sDefaultEncoding)
{
$sSelected = ' selected';
foreach ($aPossibleEncodings as $sIconvCode => $sDisplayName) {
$oSelect->GetInput()->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption('$sIconvCode', $sDisplayName, ($sIconvCode == $sDefaultEncoding)));
}
$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);
$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">');
$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);
$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');
$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/>');
$sFormatInput = '<input type="text" size="15" name="date_format" id="csv_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
$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>');
$oP->add('</td></tr></table>');
$oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "csv_custom_date_time_format", "default", "csv_date_time_format_default", "radio");
$oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
$oRadioDefault->SetBeforeInput(false);
$oFieldSetDate->AddSubBlock($oRadioDefault);
$oFieldSetDate->AddSubBlock(new Html('</br>'));
$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);
$oP->add('</fieldset>');
$sJSTooltip = json_encode('<div class="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>');
$oP->add_ready_script(
@@ -208,11 +246,12 @@ $('#csv_custom_date_time_format').on('click', function() { $('#csv_date_time_for
EOF
);
return $oPanel;
break;
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
*/
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');
class ExcelBulkExport extends TabularBulkExport
@@ -79,37 +85,56 @@ class ExcelBulkExport extends TabularBulkExport
return array_merge(parent::EnumFormParts(), array('xlsx_options' => array('formatted_text'), 'interactive_fields_xlsx' => array('interactive_fields_xlsx')));
}
public function DisplayFormPart(WebPage $oP, $sPartId)
{
switch($sPartId)
/**
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
*/
public function GetFormPart(WebPage $oP, $sPartId)
{
switch ($sPartId) {
case 'interactive_fields_xlsx':
$this->GetInteractiveFieldsWidget($oP, 'interactive_fields_xlsx');
return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_xlsx');
break;
case 'xlsx_options':
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:XLSXOptions').'</legend>');
$oP->add('<table class="export_parameters"><tr><td style="vertical-align:top">');
$oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:XLSXOptions'));
$sChecked = (utils::ReadParam('formatted_text', 0) == 1) ? ' checked ' : '';
$oP->add('<h3>'.Dict::S('Core:BulkExport:TextFormat').'</h3>');
$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>');
$oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard();
$oMulticolumn->AddCSSClass('ibo-multi-column');
$oPanel->AddSubBlock($oMulticolumn);
$oP->add('</td><td style="vertical-align:top">');
$oFieldSetFormat = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:TextFormat'));
$oFieldSetFormat->AddCSSClass('ibo-column');
$oMulticolumn->AddSubBlock($oFieldSetFormat);
$oCheckBox = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionFormattedText'), "formatted_text", "1", "xlsx_formatted_text", "checkbox");
$oCheckBox->GetInput()->SetIsChecked((utils::ReadParam('formatted_text', 0) == 1));
$oCheckBox->SetBeforeInput(false);
$oFieldSetFormat->AddSubBlock($oCheckBox);
$oFieldSetDate = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:DateTimeFormat'));
$oFieldSetDate->AddCSSClass('ibo-column');
$oMulticolumn->AddSubBlock($oFieldSetDate);
$sDateTimeFormat = utils::ReadParam('date_format', (string)AttributeDateTime::GetFormat(), true, 'raw_data');
$sDefaultChecked = ($sDateTimeFormat == (string)AttributeDateTime::GetFormat()) ? ' checked' : '';
$sCustomChecked = ($sDateTimeFormat !== (string)AttributeDateTime::GetFormat()) ? ' checked' : '';
$oP->add('<h3>'.Dict::S('Core:BulkExport:DateTimeFormat').'</h3>');
$sDefaultFormat = htmlentities((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').'"/>';
$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());
$oRadioCustom->SetBeforeInput(false);
$oFieldSetDate->AddSubBlock($oRadioCustom);
$oP->add('</td></tr></table>');
$oP->add('</fieldset>');
$sJSTooltip = json_encode('<div class="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>');
$oP->add_ready_script(
<<<EOF
@@ -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'); });
EOF
);
return $oPanel;
break;
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')));
}
public function DisplayFormPart(WebPage $oP, $sPartId)
{
switch($sPartId)
/**
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
*/
public function GetFormPart(WebPage $oP, $sPartId)
{
switch ($sPartId) {
case 'interactive_fields_html':
$this->GetInteractiveFieldsWidget($oP, 'interactive_fields_html');
return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_html');
break;
default:
return parent:: DisplayFormPart($oP, $sPartId);
return parent:: GetFormPart($oP, $sPartId);
}
}

View File

@@ -15,6 +15,12 @@
//
// You should have received a copy of the GNU Affero General Public License
// 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
@@ -22,7 +28,6 @@
* @copyright Copyright (C) 2015 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
class PDFBulkExport extends HTMLBulkExport
{
public function DisplayUsage(Page $oP)
@@ -39,40 +44,69 @@ class PDFBulkExport extends HTMLBulkExport
return array_merge(array('pdf_options' => array('pdf_options')), parent::EnumFormParts());
}
public function DisplayFormPart(WebPage $oP, $sPartId)
{
switch($sPartId)
/**
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
*/
public function GetFormPart(WebPage $oP, $sPartId)
{
switch ($sPartId) {
case 'pdf_options':
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:PDFOptions').'</legend>');
$oP->add('<table class="export_parameters"><tr><td style="vertical-align:top">');
$oP->add('<h3>'.Dict::S('Core:BulkExport:PDFPageFormat').'</h3>');
$oP->add('<table>');
$oP->add('<tr>');
$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>');
$oP->add('</tr>');
$oP->add('<td>'.Dict::S('Core:BulkExport:PDFPageOrientation').'</td>');
$oP->add('<td>'.$this->GetSelectCtrl('page_orientation', array('P', 'L'), 'Core:BulkExport:PageOrientation-', 'L').'</td>');
$oP->add('</tr>');
$oP->add('</table>');
$oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:PDFOptions'));
$oP->add('</td><td style="vertical-align:top">');
$oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard();
$oMulticolumn->AddCSSClass('ibo-multi-column');
$oPanel->AddSubBlock($oMulticolumn);
$oFieldSetFormat = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:PDFPageFormat'));
$oFieldSetFormat->AddCSSClass('ibo-column');
$oMulticolumn->AddSubBlock($oFieldSetFormat);
//page format
$oSelectFormat = InputUIBlockFactory::MakeForSelectWithLabel("page_size", Dict::S('Core:BulkExport:PDFPageSize'));
$oSelectFormat->SetBeforeInput(false);
$oFieldSetFormat->AddSubBlock($oSelectFormat);
$aPossibleFormat = ['A3', 'A4', 'Letter'];
$sDefaultFormat = 'A4';
foreach ($aPossibleFormat as $sVal) {
$oSelectFormat->GetInput()->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption($sVal, htmlentities(Dict::S('Core:BulkExport:PageSize-'.$sVal), ENT_QUOTES, 'UTF-8'), ($sVal == $sDefaultFormat)));
}
$oFieldSetFormat->AddSubBlock(new Html('</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');
$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');
$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/>');
$sFormatInput = '<input type="text" size="15" name="date_format" id="pdf_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
$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 = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "pdf_custom_date_time_format", "default", "pdf_date_time_format_default", "radio");
$oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
$oRadioDefault->SetBeforeInput(false);
$oFieldSetDate->AddSubBlock($oRadioDefault);
$oFieldSetDate->AddSubBlock(new Html('</br>'));
$oP->add('</td></tr></table>');
$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), "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);
$oP->add('</fieldset>');
$sJSTooltip = json_encode('<div id="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>');
$oP->add_ready_script(
<<<EOF
@@ -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'); });
EOF
);
return $oPanel;
break;
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()
{

View File

@@ -15,6 +15,11 @@
//
// You should have received a copy of the GNU Affero General Public License
// 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
@@ -22,7 +27,6 @@
* @copyright Copyright (C) 2015 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
class SpreadsheetBulkExport extends TabularBulkExport
{
public function DisplayUsage(Page $oP)
@@ -39,44 +43,61 @@ class SpreadsheetBulkExport extends TabularBulkExport
return array_merge(parent::EnumFormParts(), array('spreadsheet_options' => array('no-localize'), 'interactive_fields_spreadsheet' => array('interactive_fields_spreadsheet')));
}
public function DisplayFormPart(WebPage $oP, $sPartId)
{
switch($sPartId)
/**
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
*/
public function GetFormPart(WebPage $oP, $sPartId)
{
switch ($sPartId) {
case 'interactive_fields_spreadsheet':
$this->GetInteractiveFieldsWidget($oP, 'interactive_fields_spreadsheet');
return $this->GetInteractiveFieldsWidget($oP, 'interactive_fields_spreadsheet');
break;
case 'spreadsheet_options':
$sChecked = (utils::ReadParam('no_localize', 0) == 1) ? ' checked ' : '';
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:SpreadsheetOptions').'</legend>');
$oP->add('<table>');
$oP->add('<tr>');
$oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:SpreadsheetOptions'));
$oP->add('<td style="vertical-align:top">');
$sChecked = (utils::ReadParam('formatted_text', 1) == 1) ? ' checked ' : '';
$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"
$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/>');
$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>');
$oP->add('</td>');
$oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard();
$oMulticolumn->AddCSSClass('ibo-multi-column');
$oPanel->AddSubBlock($oMulticolumn);
$oFieldSetFormat = FieldSetUIBlockFactory::MakeStandard(Dict::S('Core:BulkExport:TextFormat'));
$oFieldSetFormat->AddCSSClass('ibo-column');
$oMulticolumn->AddSubBlock($oFieldSetFormat);
$oCheckBox = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionFormattedText'), "formatted_text", "1", "spreadsheet_formatted_text", "checkbox");
$oCheckBox->GetInput()->SetIsChecked((utils::ReadParam('formatted_text', 0) == 1));
$oCheckBox->SetBeforeInput(false);
$oFieldSetFormat->AddSubBlock($oCheckBox);
$oFieldSetFormat->AddSubBlock(new Html('<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');
$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');
$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/>');
$sFormatInput = '<input type="text" size="15" name="date_format" id="spreadsheet_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
$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>');
$oP->add('</td>');
$oRadioDefault = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatDefault_Example', $sDefaultFormat, $sExample), "spreadsheet_date_format_radio", "default", "spreadsheet_date_time_format_default", "radio");
$oRadioDefault->GetInput()->SetIsChecked(($sDateTimeFormat == (string)AttributeDateTime::GetFormat()));
$oRadioDefault->SetBeforeInput(false);
$oFieldSetDate->AddSubBlock($oRadioDefault);
$oFieldSetDate->AddSubBlock(new Html('</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>');
$oP->add_ready_script(
<<<EOF
@@ -88,10 +109,12 @@ $('#spreadsheet_custom_date_time_format').on('click', function() { $('#spreadshe
$('#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
);
return $oPanel;
break;
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
// 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.
@@ -23,7 +24,6 @@
* @copyright Copyright (C) 2015 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
abstract class TabularBulkExport extends BulkExport
{
public function EnumFormParts()
@@ -31,23 +31,30 @@ abstract class TabularBulkExport extends BulkExport
return array_merge(parent::EnumFormParts(), array('tabular_fields' => array('fields')));
}
public function DisplayFormPart(WebPage $oP, $sPartId)
{
switch($sPartId)
/**
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
*/
public function GetFormPart(WebPage $oP, $sPartId)
{
switch ($sPartId) {
case 'tabular_fields':
$sFields = utils::ReadParam('fields', '', true, 'raw_data');
$sSuggestedFields = utils::ReadParam('suggested_fields', null, true, 'raw_data');
if (($sSuggestedFields !== null) && ($sSuggestedFields !== ''))
{
if (($sSuggestedFields !== null) && ($sSuggestedFields !== '')) {
$aSuggestedFields = explode(',', $sSuggestedFields);
$sFields = implode(',', $this->SuggestFields($aSuggestedFields));
}
$oP->add('<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;
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);
// First, fetch only the ids - the rest will be fetched by an object reload
@@ -325,6 +331,10 @@ abstract class TabularBulkExport extends BulkExport
$('#$sWidgetId').tabularfieldsselector({fields: $JSAllFields, value_holder: '#tabular_fields', advanced_holder: '#tabular_advanced', sample_data: $sJSSampleData, total_count: $iCount, preview_limit: $iPreviewLimit, labels: $sJSLabels });
EOF
);
$oUIContentBlock = UIContentBlockUIBlockFactory::MakeStandard($sWidgetId);
$oUIContentBlock->AddCSSClass('ibo-tabularbulkexport');
return $oUIContentBlock;
}
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
// 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
@@ -22,7 +25,6 @@
* @copyright Copyright (C) 2015-2017 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
class XMLBulkExport extends BulkExport
{
public function DisplayUsage(Page $oP)
@@ -37,27 +39,38 @@ class XMLBulkExport extends BulkExport
return array_merge(parent::EnumFormParts(), array('xml_options' => array('xml_no_options')));
}
public function DisplayFormPart(WebPage $oP, $sPartId)
{
switch($sPartId)
/**
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
*/
public function GetFormPart(WebPage $oP, $sPartId)
{
switch ($sPartId) {
case 'xml_options':
$sNoLocalizeChecked = (utils::ReadParam('no_localize', 0) == 1) ? ' checked ' : '';
$sLinksetChecked = (utils::ReadParam('linksets', 0) == 1) ? ' checked ' : '';
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:XMLOptions').'</legend>');
$oP->add('<table>');
$oP->add('<tr>');
$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>');
$oP->add('</tr>');
$oP->add('<tr>');
$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>');
$oP->add('</tr>');
$oP->add('</table>');
$oP->add('</fieldset>');
$oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:XMLOptions'));
$oMulticolumn = UIContentBlockUIBlockFactory::MakeStandard();
$oMulticolumn->AddCSSClass('ibo-multi-column');
$oPanel->AddSubBlock($oMulticolumn);
$oCheckBoxLocalize = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionNoLocalize'), "no_localize", "1", "xml_no_localize", "checkbox");
$oCheckBoxLocalize->GetInput()->SetIsChecked((utils::ReadParam('no_localize', 0) == 1));
$oCheckBoxLocalize->SetBeforeInput(false);
$oPanel->AddSubBlock($oCheckBoxLocalize);
$oCheckBoxLink = InputUIBlockFactory::MakeForInputWithLabel(Dict::S('Core:BulkExport:OptionLinkSets'), "linksets", "1", "xml_linksets", "checkbox");
$oCheckBoxLink->GetInput()->SetIsChecked((utils::ReadParam('linksets', 0) == 1));
$oCheckBoxLink->SetBeforeInput(false);
$oPanel->AddSubBlock($oCheckBoxLink);
return $oPanel;
break;
default:
return parent:: DisplayFormPart($oP, $sPartId);
return parent:: GetFormPart($oP, $sPartId);
}
}

View File

@@ -8,6 +8,9 @@ $ibo-button--box-shadow-top: inset 0px 2px 0px !default;
$ibo-button--label--margin-left: 4px !default;
$ibo-button--vertical-align--margin-bottom: 4px !default;
$ibo-button--vertical-align--margin-top: 4px !default;
$ibo-button-colors: (
'regular': (
/* Semantics */
@@ -409,3 +412,8 @@ $ibo-button-colors: (
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,6 +47,8 @@ $ibo-datatable--sorting--right: 1em !default;
$ibo-datatable-panel--body--padding: $ibo-panel--body--padding-top 0px $ibo-panel--body--padding-bottom !default;
$ibo-datatable--selection-validation-buttons-toolbar--margin-top: 10px !default;
$ibo-list-column--max-height: 150px;
.ibo-datatable {
padding-bottom: $ibo-datatable--padding-y;
padding-top: $ibo-datatable--padding-y;
@@ -56,6 +58,7 @@ $ibo-datatable--selection-validation-buttons-toolbar--margin-top: 10px !default;
padding-right: $ibo-datatable-cell-row--padding-x;
padding-left: $ibo-datatable-cell-row--padding-x;
@extend %ibo-font-ral-med-100;
a {
color: $ibo-datatable-cell-row--link--color;
}
@@ -151,10 +154,12 @@ $ibo-datatable--selection-validation-buttons-toolbar--margin-top: 10px !default;
box-shadow: $ibo-datatable--paginate-button-active--link--box-shadow;
border-radius: $ibo-border-radius-300;
}
.ibo-datatable thead tr th {
position: relative;
}
.ibo-datatable thead tr th.sorting::after{
.dataTables_scrollHead thead tr th.sorting::after {
position: absolute;
font-family: "Font Awesome 5 Free";
content: "\f0dc";
@@ -162,20 +167,23 @@ $ibo-datatable--selection-validation-buttons-toolbar--margin-top: 10px !default;
opacity: $ibo-datatable--sorting--opacity;
right: $ibo-datatable--sorting--right;
}
.ibo-datatable thead tr th.sorting_desc:after{
.dataTables_scrollHead thead tr th.sorting_desc:after {
position: absolute;
font-family: "Font Awesome 5 Free";
content: "\f0d7";
font-weight: 900;
right: $ibo-datatable--sorting--right;
}
.ibo-datatable thead tr th.sorting_asc:after{
.dataTables_scrollHead thead tr th.sorting_asc:after {
position: absolute;
font-family: "Font Awesome 5 Free";
font-weight: 900;
content: "\f0d8";
right: $ibo-datatable--sorting--right;
}
.ibo-datatable-panel > .ibo-panel--body {
padding: $ibo-datatable-panel--body--padding;
}
@@ -185,3 +193,8 @@ $ibo-datatable--selection-validation-buttons-toolbar--margin-top: 10px !default;
clear: both;
margin-top: $ibo-datatable--selection-validation-buttons-toolbar--margin-top;
}
.ibo-list-column {
max-height: $ibo-list-column--max-height;
overflow-y: auto;
}

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 {
& ~ .ibo-fieldset {
& ~ .ibo-fieldset:not(.ibo-column) {
margin-top: $ibo-fieldset--sibling-spacing;
}
}

View File

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

View File

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

View File

@@ -26,6 +26,9 @@ $ibo-input--placeholder--color: $ibo-color-grey-700 !default;
$ibo-input-wrapper--is-error--background-color: $ibo-color-red-200 !default;
$ibo-input-wrapper--is-error--border-color: $ibo-color-red-600 !default;
$ibo-field-validation: $ibo-color-red-700 !default;
$ibo-input--margin-x: 5px !default;
.ibo-input {
@extend %ibo-vertically-centered-content;
height: $ibo-input--height;
@@ -53,10 +56,20 @@ $ibo-field-validation: $ibo-color-red-700 !default;
border: 1px solid $ibo-input-wrapper--is-error--border-color;
}
}
.ibo-field-validation {
color: $ibo-field-validation;
}
.file-input {
display: block;
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-mini-column--min-width: 30px !default;
$ibo-column--padding-x: abs($ibo-multi-column--margin-x) !default;
$ibo-column--padding-y: 0 !default;
@@ -16,6 +17,18 @@ $ibo-column--margin-bottom--is-last-element: 48px !default;
padding: $ibo-column--padding-y $ibo-column--padding-x;
flex-basis: 10%;
&:not(:last-child) &:not(.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;
}

View File

@@ -19,4 +19,5 @@
@import "base";
@import "preferences";
@import "attachments";
@import "tabularfieldsselector";
@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 {
position: relative;
padding: 16px $ibo-vendors-jqueryui--ui-dialog--padding-x;
overflow: auto;
}
.ui-dialog-buttonpane {
margin-top: auto;

View File

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

View File

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

View File

@@ -25,41 +25,64 @@ $(function()
},
// the constructor
_create: function()
{
_create: function () {
var me = this;
this._flatten_fields(this.options.fields);
this.sId = this.element.attr('id');
this.element
.addClass('itop-tabularfieldsselector');
this.element.parent().bind('form-part-activate', function() { me._update_from_holder(); me._update_preview(); });
this.element.parent().bind('validate', function() { me.validate(); });
this.element.addClass('itop-tabularfieldsselector');
this.element.parent().bind('form-part-activate', function () {
me._update_from_holder();
me._update_preview();
});
this.element.parent().bind('validate', function () {
me.validate();
});
this.aSelected = [];
for(var i in this.options.fields)
{
var sContent = '<fieldset><legend>'+this._format(this.options.labels.columns_selection, i)+'</legend>';
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>';
for(var j in this.options.fields[i])
{
for (var i in this.options.fields) {
var sContent = `<div class="ibo-panel ibo-is-blue ">
<div class="ibo-panel--header">
<div class="ibo-panel--header-left">
<div class= "ibo-panel--title" > `+this._format(this.options.labels.columns_selection, i)+`</div>
</div>`;
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);
}
sContent = '<fieldset><legend>'+this.options.labels.columns_order+'</legend>';
sContent = `<div class="ibo-panel ibo-is-blue ">
<div class="ibo-panel--header">
<div class="ibo-panel--header-left">
<div class="ibo-panel--title">`+this.options.labels.columns_order+`</div>
</div>
</div>
<div class="ibo-panel--body"> `;
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>';
sContent += '<div class="table_preview"></div>';
sContent += '</fieldset>';
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._update_from_holder();
$('body').on('click change', '.tfs_checkbox', function () {
var sInstanceId = $(this).attr('data-instance-id');
if (sInstanceId != me.sId) return;
if (sInstanceId != me.sId) {
return;
}
me._on_click($(this));
});
@@ -75,18 +98,17 @@ $(function()
me._on_multi_click($(this).val(), this.checked);
});
$('#'+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 () {
me._on_check_all($(this).closest('fieldset'), false);
me._on_check_all($(this).closest('.ibo-panel'), false);
});
this._update_preview();
this._make_tooltips();
},
_on_click: function(jItemClicked)
{
_on_click: function (jItemClicked) {
var bChecked = jItemClicked.prop('checked');
var sValue = jItemClicked.val();
@@ -94,19 +116,15 @@ $(function()
this._update_holder();
this._update_preview();
var sDataParent = jItemClicked.attr('data-parent');
if (sDataParent != '')
{
if (sDataParent != '') {
this._update_tristate(sDataParent+'_multi');
}
},
_on_multi_click: function(sMultiFieldCode, bChecked)
{
_on_multi_click: function (sMultiFieldCode, bChecked) {
var oField = this._get_main_field_by_code(sMultiFieldCode);
if (oField != null)
{
if (oField != null) {
var sPrefix = '#tfs_'+this.sId+'_';
for(var k in oField.subattr)
{
for (var k in oField.subattr) {
this._mark_as_selected(oField.subattr[k].code, bChecked);
// In case the tooltip is visible, also update the checkboxes
sElementId = (sPrefix+oField.subattr[k].code).replace('.', '_');
@@ -116,8 +134,7 @@ $(function()
this._update_preview();
}
},
_on_check_all: function(jSelector, bChecked)
{
_on_check_all: function (jSelector, bChecked) {
var me = this;
jSelector.find('.tfs_checkbox').each(function () {
$(this).prop('checked', bChecked);
@@ -125,13 +142,11 @@ $(function()
});
jSelector.find('.tfs_checkbox_multi').each(function () {
var oField = me._get_main_field_by_code($(this).val());
if (oField != null)
{
if (oField != null) {
$(this).prop('checked', bChecked);
$(this).prop('indeterminate', false);
var sPrefix = '#tfs_'+this.sId+'_';
for(var k in oField.subattr)
{
for (var k in oField.subattr) {
me._mark_as_selected(oField.subattr[k].code, bChecked);
// In case the tooltip is visible, also update the checkboxes
sElementId = (sPrefix+oField.subattr[k].code).replace('.', '_');
@@ -142,103 +157,76 @@ $(function()
this._update_holder();
this._update_preview();
},
_update_tristate: function(sParentId)
{
_update_tristate: function (sParentId) {
// Check if the parent is checked, unchecked or indeterminate
var sParentId = sParentId.replace('.', '_');
var sAttCode = $('#'+sParentId).val();
var oField = this._get_main_field_by_code(sAttCode);
if (oField != null)
{
if (oField != null) {
var iNbChecked = 0;
var aDebug = [];
for(var j in oField.subattr)
{
if ($.inArray(oField.subattr[j].code, this.aSelected) != -1)
{
for (var j in oField.subattr) {
if ($.inArray(oField.subattr[j].code, this.aSelected) != -1) {
aDebug.push(oField.subattr[j].code);
iNbChecked++;
}
}
if (iNbChecked == oField.subattr.length)
{
if (iNbChecked == oField.subattr.length) {
$('#'+sParentId).prop('checked', true);
$('#'+sParentId).prop('indeterminate', false);
}
else if (iNbChecked == 0)
{
} else if (iNbChecked == 0) {
$('#'+sParentId).prop('checked', false);
$('#'+sParentId).prop('indeterminate', false);
}
else
{
} else {
$('#'+sParentId).prop('checked', false);
$('#'+sParentId).prop('indeterminate', true);
}
}
},
_mark_as_selected: function(sValue, bSelected)
{
if(bSelected)
{
if ($.inArray(sValue, this.aSelected) == -1)
{
_mark_as_selected: function (sValue, bSelected) {
if (bSelected) {
if ($.inArray(sValue, this.aSelected) == -1) {
this.aSelected.push(sValue);
}
}
else
{
} else {
aSelected = [];
for(var k in this.aSelected)
{
if (this.aSelected[k] != sValue)
{
for (var k in this.aSelected) {
if (this.aSelected[k] != sValue) {
aSelected.push(this.aSelected[k]);
}
}
this.aSelected = aSelected;
}
},
_update_holder: function()
{
_update_holder: function () {
$(this.options.value_holder).val(this.aSelected.join(','));
},
_update_from_holder: function()
{
_update_from_holder: function () {
var sFields = $(this.options.value_holder).val();
var bAdvanced = parseInt($(this.options.advanced_holder).val(), 10);
if (sFields != '')
{
if (sFields != '') {
this.aSelected = sFields.split(',');
var safeSelected = [];
var me = this;
var bModified = false;
for(var k in this.aSelected)
{
for (var k in this.aSelected) {
var oField = this._get_field_by_code(this.aSelected[k])
if (oField == null)
{
if (oField == null) {
// Invalid field code supplied, don't copy it
bModified = true;
}
else
{
} else {
safeSelected.push(this.aSelected[k]);
}
}
if (bModified)
{
if (bModified) {
this.aSelected = safeSelected;
this._update_holder();
}
$('#'+this.sId+' .tfs_checkbox').each(function () {
if ($.inArray($(this).val(), me.aSelected) != -1)
{
if ($.inArray($(this).val(), me.aSelected) != -1) {
$(this).prop('checked', true);
}
else
{
} else {
$(this).prop('checked', false);
}
});
@@ -249,28 +237,22 @@ $(function()
});
},
_update_preview: function()
{
_update_preview: function () {
var sHtml = '';
if(this.aSelected.length > 0)
{
if (this.aSelected.length > 0) {
sHtml += '<table><thead><tr>';
for(var k in this.aSelected)
{
for (var k in this.aSelected) {
var sField = this.aSelected[k];
if ($.inArray(sField, this.aSelected) != -1)
{
if ($.inArray(sField, this.aSelected) != -1) {
var sRemoveBtn = '&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 += '</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>';
for(var k in this.aSelected)
{
for (var k in this.aSelected) {
var sField = this.aSelected[k];
sHtml += '<td>'+this.options.sample_data[i][sField]+'</td>';
}
@@ -280,45 +262,43 @@ $(function()
sHtml += '</tbody></table>';
$('#'+this.sId+' .preview_header').show();
$('#'+this.sId+' .table_preview').html(sHtml);
$('#'+this.sId+' .ibo-table-preview').html(sHtml);
var me = this;
$('#'+this.sId+' .table_preview table').dragtable({persistState: function(table) { me._on_drag_columns(table); }, dragHandle: '.drag-handle'});
$('#'+this.sId+' .table_preview table .export-field-close').click( function(event) { me._on_remove_column($(this).attr('data-attcode')); event.preventDefault(); return false; } );
}
else
{
$('#'+this.sId+' .ibo-table-preview table').dragtable({
persistState: function (table) {
me._on_drag_columns(table);
}, dragHandle: '.drag-handle'
});
$('#'+this.sId+' .ibo-table-preview table .export-field-close').click(function (event) {
me._on_remove_column($(this).attr('data-attcode'));
event.preventDefault();
return false;
});
} else {
$('#'+this.sId+' .preview_header').hide();
$('#'+this.sId+' .table_preview').html('<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');
},
_get_field_by_code: function(sFieldCode)
{
for(var k in this.aFieldsByCode)
{
if (k == sFieldCode)
{
_get_field_by_code: function (sFieldCode) {
for (var k in this.aFieldsByCode) {
if (k == sFieldCode) {
return this.aFieldsByCode[k];
}
}
return null;
},
_get_main_field_by_code: function(sFieldCode)
{
for(var i in this.options.fields)
{
for(var j in this.options.fields[i])
{
if (this.options.fields[i][j].code == sFieldCode)
{
_get_main_field_by_code: function (sFieldCode) {
for (var i in this.options.fields) {
for (var j in this.options.fields[i]) {
if (this.options.fields[i][j].code == sFieldCode) {
return this.options.fields[i][j];
}
}
}
return null;
},
_on_drag_columns: function(table)
{
_on_drag_columns: function (table) {
var me = this;
me.aSelected = [];
table.el.find('th').each(function (i) {
@@ -326,8 +306,7 @@ $(function()
});
this._update_holder();
},
_on_remove_column: function(sField)
{
_on_remove_column: function (sField) {
var sElementId = this.sId+'_'+sField;
sElementId = '#tfs_'+sElementId.replace('.', '_');
$(sElementId).prop('checked', false);
@@ -340,8 +319,7 @@ $(function()
me._update_tristate($(this).attr('id'));
});
},
_format: function()
{
_format: function () {
var s = arguments[0];
for (var i = 0; i < arguments.length-1; i++) {
var reg = new RegExp("%"+(i+1)+"\\$s", "gm");
@@ -349,10 +327,8 @@ $(function()
}
return s;
},
validate: function()
{
if (this.aSelected.length == 0)
{
validate: function () {
if (this.aSelected.length == 0) {
var aMessages = $('#export-form').data('validation_messages');
aMessages.push(this.options.labels.no_field_selected);
$('#export-form').data('validation_messages', aMessages);
@@ -360,8 +336,7 @@ $(function()
},
// events bound via _bind are removed automatically
// revert other modifications here
destroy: function()
{
destroy: function () {
this.element
.removeClass('itop-tabularfieldsselector');
@@ -369,149 +344,81 @@ $(function()
this.element.parent().unbind('validate');
},
// _setOptions is called with a hash of all options that are changing
_setOptions: function()
{
_setOptions: function () {
this._superApply(arguments);
},
// _setOption is called for each individual option that is changing
_setOption: function( key, value )
{
if (key == 'fields')
{
_setOption: function (key, value) {
if (key == 'fields') {
this._flatten_fields(value);
}
this._superApply(arguments);
},
_flatten_fields: function(aFields)
{
_flatten_fields: function (aFields) {
// Update the "flattened" via of the fields
this.aFieldsByCode = {}; // Must be an object since indexes are non-numeric
for(var k in aFields)
{
for(var i in aFields[k])
{
for (var k in aFields) {
for (var i in aFields[k]) {
this.aFieldsByCode[aFields[k][i].code] = aFields[k][i];
for(var j in aFields[k][i].subattr)
{
for (var j in aFields[k][i].subattr) {
this.aFieldsByCode[aFields[k][i].subattr[j].code] = aFields[k][i].subattr[j];
}
}
}
},
_make_tooltips: function()
{
_make_tooltips: function () {
var me = this;
$('#'+this.sId+' .tfs_advanced').tooltip({
content: function() {
var sDataAttcode = $(this).attr('data-attcode');
var sTooltipContent = '';
sTooltipContent += me._get_tooltip_content(sDataAttcode);
return sTooltipContent;
},
items: '.tfs_advanced',
classes: {
'ui-tooltip': 'tooltip-tfs'
},
position: {
my: "center bottom-10",
at: "center top",
using: function( position, feedback ) {
$(this).css( position );
$( "<div>" )
.addClass( "arrow" )
.addClass( feedback.vertical )
.addClass( feedback.horizontal )
.appendTo( this );
$('#'+this.sId+' .tfs_advanced').each(function (index, elt) {
var sDataAttcode = $(elt).attr('data-attcode');
var sTooltipContent = me._get_tooltip_content(sDataAttcode);
tippy(elt, {
'content': sTooltipContent,
allowHTML: true,
interactive: true,
zIndex: 9999,
role: 'tooltip',
popperOptions: {
strategy: 'fixed'
}
}
})
.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 sContent = '';
if (oField != null)
{
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)
{
if (oField != null) {
sContent += '<div display:block;">'+oField.label+'</div>';
for (var k in oField.subattr) {
bChecked = ($.inArray(oField.subattr[k].code, this.aSelected) != -1);
sContent += this._get_field_checkbox(oField.subattr[k].code, oField.subattr[k].label, false, bChecked, sDataAttCode);
}
}
return sContent;
},
_get_field_checkbox: function(sCode, sLabel, bHasTooltip, bChecked, sParentId)
{
_get_field_checkbox: function (sCode, sLabel, bHasTooltip, bChecked, sParentId) {
var sPrefix = 'tfs_'+this.sId+'_';
sParentId = (sPrefix+sParentId).replace('.', '_');
sElementId = (sPrefix+sCode).replace('.', '_');
var aClasses = [];
if (bHasTooltip)
{
if (bHasTooltip) {
aClasses.push('tfs_advanced');
sLabel += ' [+]';
}
var sChecked = '';
if (bChecked)
{
if (bChecked) {
sChecked = ' checked ';
}
var sDataParent = '';
if (sParentId != null)
{
if (sParentId != null) {
sDataParent = ' data-parent="'+sParentId+'" ';
}
if (bHasTooltip)
{
if (bHasTooltip) {
sContent = '<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>';
}
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) {
oParams[this.name] = $(this).val();
}
}
else {
} else {
oParams[this.name] = $(this).val();
}
}
});
$(':itop-tabularfieldsselector:visible').tabularfieldsselector('close_all_tooltips');
$('#export-form').hide();
$('#export-feedback').show();
oParams.operation = 'export_build';
@@ -445,8 +443,7 @@ function ExportStartExport() {
if ($(':input[name=query_mode]:checked').length > 0) {
if (sQueryMode == 'oql') {
oParams.expression = $('#export-form :input[name=expression]').val();
}
else {
} else {
oParams.query = $('#export-form :input[name=query]').val();
}
}

View File

@@ -180,7 +180,7 @@ try
//--- Query textarea
$oQueryTitle = new Html('<h2>'.Dict::S('UI:RunQuery:ExpressionToEvaluate').'</h2>');
$oQueryForm->AddSubBlock($oQueryTitle);
$oQueryTextArea = new TextArea(utils::EscapeHtml($sExpression), 'expression', 120, 8);
$oQueryTextArea = new TextArea('expression', utils::EscapeHtml($sExpression), 'expression', 120, 8);
$oQueryTextArea->SetName('expression');
$oQueryForm->AddSubBlock($oQueryTextArea);

View File

@@ -18,6 +18,8 @@ abstract class AbstractInput extends UIBlock
protected $sName;
/** @var string */
protected $sValue;
/**@var string */
protected $sPlaceholder;
public function GetName(): string
{
@@ -52,4 +54,25 @@ abstract class AbstractInput extends UIBlock
return $this;
}
/**
* @return string
*/
public function GetPlaceholder(): ?string
{
return $this->sPlaceholder;
}
/**
* @param string $sPlaceholder
*
* @return $this
*/
public function SetPlaceholder(string $sPlaceholder)
{
$this->sPlaceholder = $sPlaceholder;
return $this;
}
}

View File

@@ -94,4 +94,24 @@ class InputUIBlockFactory extends AbstractUIBlockFactory
return new InputWithLabel($sLabel, $oInput, $sId);
}
/**
* If you need to have a real field with a label, you might use a {@link Field} component instead
*
* @param string $sName
* @param string|null $sId
*
* @return \Combodo\iTop\Application\UI\Base\Component\Input\Select
*/
public static function MakeForSelect(string $sName, ?string $sId = null): Select
{
$oInput = new Select($sId);
$oInput->SetName($sName);
if (is_null($sId)) {
$sId = $oInput->GetId();
}
return $oInput;
}
}

View File

@@ -23,6 +23,8 @@ class InputWithLabel extends UIBlock
protected $sLabel;
/** @var \Combodo\iTop\Application\UI\Base\UIBlock */
protected $oInput;
/** @var bool Label before input ? */
protected $bBeforeInput;
/**
* @param string $sLabel
@@ -34,6 +36,7 @@ class InputWithLabel extends UIBlock
parent::__construct($sId);
$this->sLabel = $sLabel;
$this->oInput = $oInput;
$this->bBeforeInput = true;
}
/**
@@ -56,6 +59,30 @@ class InputWithLabel extends UIBlock
return $this;
}
/**
* @param bool $bBeforeInput
*
* @return $this
*/
public function SetBeforeInput(bool $bBeforeInput)
{
$this->bBeforeInput = $bBeforeInput;
if ($bBeforeInput) {
$this->oInput->AddCSSClass('ibo-input--label-left');
} else {
$this->oInput->AddCSSClass('ibo-input--label-right');
}
return $this;
}
/**
* @return bool
*/
public function IsLabelBefore(): bool
{
return $this->bBeforeInput;
}
/**
* @return string

View File

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

View File

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

View File

@@ -5,40 +5,45 @@
<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>
</p>
<fieldset>
<legend class="transparent">
<div class="ibo-panel ibo-is-neutral">
<div class="ibo-panel--header">
<div class="ibo-panel--header-left">
<input id="dtbl_dlg_specific_{{ oUIBlock.GetTableId() }}" type="radio" class="specific_settings" name="settings" {% if oUIBlock.GetOption("bUseCustomSettings") %} checked {% endif %} value="specific">
<label for="dtbl_dlg_specific_{{ oUIBlock.GetTableId() }}">&nbsp;&nbsp;{{ 'UI:UseSpecificSettings'|dict_s }}</label>
</legend>
</div>
</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>
</div>
</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>
<fieldset>
<legend class="transparent">
</div>
</div>
<div class="ibo-panel ibo-is-neutral">
<div class="ibo-panel--header">
<div class="ibo-panel--header-left">
<input id="dtbl_dlg_save_{{ oUIBlock.GetTableId() }}" type="checkbox" {% if oUIBlock.GetOption("sTableId") != null %}checked{% endif %} name="save_settings">
<label for="dtbl_dlg_save_{{ oUIBlock.GetTableId() }}">&nbsp;&nbsp;{{ 'UI:UseSavetheSettings'|dict_s }}</label>
</legend>
<p>
</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">
<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">
<label for="dtbl_dlg_all_{{ oUIBlock.GetTableId() }}">&nbsp;&nbsp;{{ 'UI:ForAllLists'|dict_s }}</label>
</p>
</fieldset>
<table style="width:100%">
<tr>
<td style="text-align:center;">
<button type="button" onclick="$('#datatable_dlg_{{ oUIBlock.GetTableId() }}').dialog('close')">&nbsp;{{ 'UI:Button:Cancel'|dict_s }}</button>
</td>
<td style="text-align:center;">
<button type="submit" onclick="$('#datatable_dlg_{{ oUIBlock.GetTableId() }}').DataTableSettings('onDlgOk'); ">&nbsp;{{ 'UI:Button:Ok'|dict_s }}</button>
</td>
</tr>
</table>
</div>
</div>
<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
<div class=" ui-dialog-buttonset">
<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="submit" class="ibo-button ibo-is-regular ibo-is-primary" onclick="$('#datatable_dlg_{{ oUIBlock.GetTableId() }}').DataTableSettings('onDlgOk'); ">&nbsp;{{ 'UI:Button:Ok'|dict_s }}</button>
</div>
</div>
</form>
</div>

View File

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

View File

@@ -1,5 +1,5 @@
{% 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>
{% for oSubBlock in oUIBlock.GetSubBlocks() %}
{{ render_block(oSubBlock, {aPage: aPage}) }}

View File

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

View File

@@ -4,5 +4,11 @@
<textarea
id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}"
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>
{% endblock %}

View File

@@ -1,4 +1,10 @@
{% block iboInputLabel %}
<label for="{{ oUIBlock.GetId() }}">{{ oUIBlock.GetLabel() }}</label>
{% if oUIBlock.IsLabelBefore() %}
<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 %}

View File

@@ -2,8 +2,14 @@
{% endblock %}
{% block iboInput %}
<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.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 %}

View File

@@ -17,7 +17,18 @@
* You should have received a copy of the GNU Affero General Public License
*/
if (!defined('__DIR__')) define('__DIR__', dirname(__FILE__));
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Field\FieldUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\TextArea;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
if (!defined('__DIR__')) {
define('__DIR__', dirname(__FILE__));
}
require_once(__DIR__.'/../approot.inc.php');
require_once(APPROOT.'/application/application.inc.php');
require_once(APPROOT.'/application/nicewebpage.class.inc.php');
@@ -127,10 +138,32 @@ function Usage(Page $oP)
function DisplayExpressionForm(WebPage $oP, $sAction, $sExpression = '', $sExceptionMessage = '')
{
$oP->add('<fieldset><legend>'.Dict::S('Core:BulkExport:ScopeDefinition').'</legend>');
$oP->add('<form id="export-form" action="'.$sAction.'" method="post">');
$oP->add('<input type="hidden" name="interactive" value="1">');
$oP->add('<table style="width:100%" class="export_parameters">');
$oForm = FormUIBlockFactory::MakeStandard('form');
$oForm->SetAction($sAction);
$oP->AddSubBlock($oForm);
$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>';
$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>');
@@ -141,15 +174,11 @@ function DisplayExpressionForm(WebPage $oP, $sAction, $sExpression = '', $sExcep
$oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL');
$oSearch->UpdateContextFromUser();
$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('</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>');
$oP->add('</table>');
$oP->add('</form>');
$oP->add('</fieldset>');
$oP->add('</select></td></tr>');*/
$oForm->AddSubBlock(ButtonUIBlockFactory::MakeForPrimaryAction(Dict::S('UI:Button:Next'), "", "", true, "next-btn"));
$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>');
$sJSEmptyOQL = json_encode(Dict::S('Core:BulkExportMessageEmptyOQL'));
@@ -230,102 +259,106 @@ EOF
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/tabularfieldsselector.js');
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.dragtable.js');
$oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/dragtable.css');
$oP->add('<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;
$sExpressionError = '';
if (($sExpression === null) && ($sQueryId === null))
{
if (($sExpression === null) && ($sQueryId === null)) {
$bExpressionIsValid = false;
}
else if ($sExpression !== '')
{
try
{
} else if ($sExpression !== '') {
try {
$oExportSearch = DBObjectSearch::FromOQL($sExpression);
$oExportSearch->UpdateContextFromUser();
}
catch(OQLException $e)
{
catch (OQLException $e) {
$bExpressionIsValid = false;
$sExpressionError = $e->getMessage();
}
}
if (!$bExpressionIsValid)
{
if (!$bExpressionIsValid) {
DisplayExpressionForm($oP, $sAction, $sExpression, $sExpressionError);
return;
}
if ($sExpression !== '')
{
$oP->add('<input type="hidden" name="expression" value="'.htmlentities($sExpression, ENT_QUOTES, 'UTF-8').'">');
if ($sExpression !== '') {
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden("expression", htmlentities($sExpression, ENT_QUOTES, 'UTF-8')));
$oExportSearch = DBObjectSearch::FromOQL($sExpression);
$oExportSearch->UpdateContextFromUser();
}
else
{
} else {
$oQuery = MetaModel::GetObject('QueryOQL', $sQueryId);
$oExportSearch = DBObjectSearch::FromOQL($oQuery->Get('oql'));
$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();
$aAllFormParts = array();
if ($sFormat == null)
{
if ($sFormat == null) {
// No specific format chosen
$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();
asort($aSupportedFormats);
foreach($aSupportedFormats as $sFormatCode => $sLabel)
{
$sSelected = ($sFormatCode == $sDefaultFormat) ? 'selected' : '';
$oP->add('<option value="'.$sFormatCode.'" '.$sSelected.'>'.htmlentities($sLabel, ENT_QUOTES, 'UTF-8').'</option>');
foreach ($aSupportedFormats as $sFormatCode => $sLabel) {
$oSelect->GetInput()->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption($sFormatCode, htmlentities($sLabel, ENT_QUOTES, 'UTF-8'), ($sFormatCode == $sDefaultFormat)));
$oExporter = BulkExport::FindExporter($sFormatCode);
$oExporter->SetObjectList($oExportSearch);
$aParts = $oExporter->EnumFormParts();
foreach($aParts as $sPartId => $void)
{
foreach ($aParts as $sPartId => $void) {
$aAllFormParts[$sPartId] = $oExporter;
}
$aFormPartsByFormat[$sFormatCode] = array_keys($aParts);
}
$oP->add('</select></p>');
}
else
{
} else {
// 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);
$aParts = $oExporter->EnumFormParts();
foreach($aParts as $sPartId => $void)
{
foreach ($aParts as $sPartId => $void) {
$aAllFormParts[$sPartId] = $oExporter;
}
$aFormPartsByFormat[$sFormat] = array_keys($aAllFormParts);
}
foreach($aAllFormParts as $sPartId => $oExport)
{
$oP->add('<div class="form_part" id="form_part_'.$sPartId.'">');
$oExport->DisplayFormPart($oP, $sPartId);
$oP->add('</div>');
foreach ($aAllFormParts as $sPartId => $oExport) {
$UIContentBlock = UIContentBlockUIBlockFactory::MakeStandard('form_part_'.$sPartId)->AddCSSClass('form_part');
$oForm->AddSubBlock($UIContentBlock);
$UIContentBlock->AddSubBlock($oExport->GetFormPart($oP, $sPartId));
}
$oP->add('</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>');
$oP->add('<button type="button" id="export-btn">'.Dict::S('UI:Button:Export').'</button>');
$oP->add('<div id="export_text_result" style="display:none;">');
$oP->add('<div>'.Dict::S('Core:BulkExport:ExportResult').'</div>');
$oP->add('<textarea id="export_content" style="width:100%;min-height:15em;"></textarea>');
$oP->add('</div>');
//end of form
$oBlockExport = UIContentBlockUIBlockFactory::MakeStandard("export-feedback")->SetIsHidden(true);
$oBlockExport->AddSubBlock(new Html('<p class="export-message" style="text-align:center;">'.Dict::S('ExcelExport:PreparingExport').'</p>'));
$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->AddSubBlock($oBlockExport);
if ($sFormat == null) {//if it's global export
$oP->AddSubBlock(ButtonUIBlockFactory::MakeForPrimaryAction('export', Dict::S('UI:Button:Export'), 'export', false, 'export-btn'));
}
$oBlockResult = UIContentBlockUIBlockFactory::MakeStandard("export-export_text_result")->SetIsHidden(true);
$oBlockResult->AddSubBlock(new Html(Dict::S('Core:BulkExport:ExportResult')));
$oTextArea = new TextArea('export_content', '', 'export_content');
$oTextArea->AddCSSClass('ibo-input-text-area--export');
$oBlockResult->AddSubBlock($oTextArea);
$oP->AddSubBlock($oBlockResult);
$sJSParts = json_encode($aFormPartsByFormat);
$oP->add_ready_script(
<<<EOF
window.aFormParts = $sJSParts;
$('#format_selector').on('change init', function() {
console.warn('yo'+$(this).val());
ExportToggleFormat($(this).val());
}).trigger('init');
@@ -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);
EOF
);
}
else
{
} else {
$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);
}
if ($sExpression === null)
{
if ($sExpression === null) {
// No expression supplied, let's check if phrasebook entry is given
if ($sQueryId !== null)
{
if ($sQueryId !== null) {
$oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId));
$oSearch->UpdateContextFromUser();
$oQueries = new DBObjectSet($oSearch);
if ($oQueries->Count() > 0)
{
if ($oQueries->Count() > 0) {
$oQuery = $oQueries->Fetch();
$sExpression = $oQuery->Get('oql');
}
else
{
} else {
ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'");
}
}
else
{
if (utils::IsModeCLI())
{
} else {
if (utils::IsModeCLI()) {
Usage($oP);
ReportErrorAndExit("No expression or query phrasebook identifier supplied.");
}
else
{
} else {
// form to enter an OQL query or pick a query phrasebook identifier
DisplayForm($oP, utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php', $sExpression, $sQueryId, $sFormat);
$oP->output();
@@ -415,25 +436,18 @@ EOF
}
if ($sFormat !== null)
{
if ($sFormat !== null) {
$oExporter = BulkExport::FindExporter($sFormat);
if ($oExporter === null)
{
if ($oExporter === null) {
$aSupportedFormats = BulkExport::FindSupportedFormats();
ReportErrorAndExit("Invalid output format: '$sFormat'. The supported formats are: ".implode(', ', array_keys($aSupportedFormats)));
}
else
{
} else {
DisplayForm($oP, utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php', $sExpression, $sQueryId, $sFormat);
}
}
else
{
} else {
DisplayForm($oP, utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php', $sExpression, $sQueryId, $sFormat);
}
if ($sMode == 'dialog')
{
if ($sMode == 'dialog') {
$oP->add('</div>');
}
$oP->output();
@@ -450,52 +464,40 @@ function CheckParameters($sExpression, $sQueryId, $sFormat)
{
$oExporter = null;
if (utils::IsArchiveMode() && !UserRights::CanBrowseArchive())
{
if (utils::IsArchiveMode() && !UserRights::CanBrowseArchive()) {
ReportErrorAndExit("The user account is not authorized to access the archives");
}
if (($sExpression === null) && ($sQueryId === null))
{
if (($sExpression === null) && ($sQueryId === null)) {
ReportErrorAndUsage("Missing parameter. The parameter 'expression' or 'query' must be specified.");
}
// Either $sExpression or $sQueryId must be specified
if ($sExpression === null)
{
if ($sExpression === null) {
$oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId));
$oSearch->UpdateContextFromUser();
$oQueries = new DBObjectSet($oSearch);
if ($oQueries->Count() > 0)
{
if ($oQueries->Count() > 0) {
$oQuery = $oQueries->Fetch();
$sExpression = $oQuery->Get('oql');
}
else
{
} else {
ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'");
}
}
if ($sFormat === null)
{
if ($sFormat === null) {
ReportErrorAndUsage("Missing parameter 'format'.");
}
// Check if the supplied query is valid (and all the parameters are supplied
try
{
try {
$oSearch = DBObjectSearch::FromOQL($sExpression);
$oSearch->UpdateContextFromUser();
$aArgs = array();
foreach($oSearch->GetQueryParams() as $sParam => $foo)
{
foreach ($oSearch->GetQueryParams() as $sParam => $foo) {
$value = utils::ReadParam('arg_'.$sParam, null, true, 'raw_data');
if (!is_null($value))
{
if (!is_null($value)) {
$aArgs[$sParam] = $value;
}
else
{
} else {
throw new MissingQueryArgument("Missing parameter '--arg_$sParam'");
}
}
@@ -570,83 +572,64 @@ function DoExport(WebPage $oP, BulkExport $oExporter, $bInteractive = false)
// Command Line mode
//
/////////////////////////////////////////////////////////////////////////////
if (utils::IsModeCLI())
{
if (utils::IsModeCLI()) {
SetupUtils::CheckPhpAndExtensionsForCli(new CLIPage('iTop - Export'));
try
{
try {
// Do this before loging, in order to allow setting user credentials from within the file
utils::UseParamFile();
}
catch(Exception $e)
{
catch (Exception $e) {
echo "Error: ".$e->GetMessage()."<br/>\n";
exit(EXIT_CODE_FATAL);
}
$sAuthUser = utils::ReadParam('auth_user', null, true /* Allow CLI */, 'raw_data');
$sAuthPwd = utils::ReadParam('auth_pwd', null, true /* Allow CLI */, 'raw_data');
if ($sAuthUser == null)
{
if ($sAuthUser == null) {
ReportErrorAndUsage("Missing parameter '--auth_user'");
}
if ($sAuthPwd == null)
{
if ($sAuthPwd == null) {
ReportErrorAndUsage("Missing parameter '--auth_pwd'");
}
if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd))
{
if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd)) {
UserRights::Login($sAuthUser); // Login & set the user's language
}
else
{
} else {
ReportErrorAndExit("Access restricted or wrong credentials for user '$sAuthUser'");
}
$sExpression = utils::ReadParam('expression', null, true /* Allow CLI */, 'raw_data');
$sQueryId = utils::ReadParam('query', null, true /* Allow CLI */, 'raw_data');
$bLocalize = (utils::ReadParam('no_localize', 0) != 1);
if (utils::IsArchiveMode() && !UserRights::CanBrowseArchive())
{
if (utils::IsArchiveMode() && !UserRights::CanBrowseArchive()) {
ReportErrorAndExit("The user account is not authorized to access the archives");
}
if (($sExpression == null) && ($sQueryId == null))
{
if (($sExpression == null) && ($sQueryId == null)) {
ReportErrorAndUsage("Missing parameter. At least one of '--expression' or '--query' must be specified.");
}
if ($sExpression === null)
{
if ($sExpression === null) {
$oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId));
$oSearch->UpdateContextFromUser();
$oQueries = new DBObjectSet($oSearch);
if ($oQueries->Count() > 0)
{
if ($oQueries->Count() > 0) {
$oQuery = $oQueries->Fetch();
$sExpression = $oQuery->Get('oql');
}
else
{
} else {
ReportErrorAndExit("Invalid query phrasebook identifier: '$sQueryId'");
}
}
try
{
try {
$oSearch = DBObjectSearch::FromOQL($sExpression);
$oSearch->UpdateContextFromUser();
$aArgs = array();
foreach($oSearch->GetQueryParams() as $sParam => $foo)
{
foreach ($oSearch->GetQueryParams() as $sParam => $foo) {
$value = utils::ReadParam('arg_'.$sParam, null, true, 'raw_data');
if (!is_null($value))
{
if (!is_null($value)) {
$aArgs[$sParam] = $value;
}
else
{
} else {
throw new MissingQueryArgument("Missing parameter '--arg_$sParam'");
}
}
@@ -724,16 +707,12 @@ try
ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker');
if ($bInteractive)
{
if ($bInteractive) {
InteractiveShell($sExpression, $sQueryId, $sFormat, $sFileName, $sMode);
}
else
{
} else {
$oExporter = CheckParameters($sExpression, $sQueryId, $sFormat);
$sMimeType = $oExporter->GetMimeType();
if ($sMimeType == 'text/html')
{
if ($sMimeType == 'text/html') {
// Note: Using NiceWebPage only for HTML export as it includes JS scripts & files, which makes no sense in other export formats. More over, it breaks Excel spreadsheet import.
if ($oExporter instanceof HTMLBulkExport) {
$oP = new NiceWebPage('iTop export');
@@ -741,8 +720,7 @@ try
$oP->add_ready_script("$('table.listResults').tablesorter({widgets: ['MyZebra']});");
$oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
$oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/v4-shims.min.css');
}
else {
} else {
$oP = new WebPage('iTop export');
$oP->add_xframe_options();
$oP->add_style("table br { mso-data-placement:same-cell; }"); // Trick for Excel: keep line breaks inside the same cell !