2
0
forked from Wavyzz/dolibarr

Work on custom report feature

This commit is contained in:
Laurent Destailleur
2022-02-15 11:03:48 +01:00
parent f2d5e43381
commit 1b53ed09f9
11 changed files with 211 additions and 58 deletions

View File

@@ -173,6 +173,7 @@ class DolibarrApi
unset($object->stats_mrptoproduce); unset($object->stats_mrptoproduce);
unset($object->element); unset($object->element);
unset($object->element_for_permission);
unset($object->fk_element); unset($object->fk_element);
unset($object->table_element); unset($object->table_element);
unset($object->table_element_line); unset($object->table_element_line);

View File

@@ -209,7 +209,7 @@ class Setup extends DolibarrApi
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
} }
@@ -272,7 +272,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -373,7 +373,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -665,7 +665,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -729,7 +729,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -797,7 +797,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -860,7 +860,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -933,7 +933,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -1004,7 +1004,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -1078,7 +1078,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -1143,9 +1143,9 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(400, 'error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
} }
@@ -1202,9 +1202,9 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(400, 'error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
} }
@@ -1261,7 +1261,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -1324,7 +1324,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -1383,7 +1383,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -1449,7 +1449,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -1508,7 +1508,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -1567,7 +1567,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
@@ -1628,7 +1628,7 @@ class Setup extends DolibarrApi
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
} }
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";

View File

@@ -2591,6 +2591,12 @@ class ContratLigne extends CommonObjectLine
*/ */
public $table_element = 'contratdet'; public $table_element = 'contratdet';
/**
* @var string Name to use for 'features' parameter to check module permissions with restrictedArea()
*/
public $element_for_permission = 'contrat';
/** /**
* @var int ID * @var int ID
*/ */
@@ -2723,6 +2729,34 @@ class ContratLigne extends CommonObjectLine
const STATUS_CLOSED = 5; const STATUS_CLOSED = 5;
// BEGIN MODULEBUILDER PROPERTIES
/**
* @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
*/
public $fields = array(
'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>30, 'index'=>1),
'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35),
'qty' =>array('type'=>'integer', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35, 'isameasure'=>1),
'total_ht' =>array('type'=>'integer', 'label'=>'AmountHT', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>36, 'isameasure'=>1),
'total_tva' =>array('type'=>'integer', 'label'=>'AmountVAT', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>37, 'isameasure'=>1),
'total_ttc' =>array('type'=>'integer', 'label'=>'AmountTTC', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>38, 'isameasure'=>1),
//'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>40),
//'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70),
'fk_contrat' =>array('type'=>'integer:Contrat:contrat/class/contrat.class.php', 'label'=>'Contract', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70),
'fk_product' =>array('type'=>'integer:Product:product/class/product.class.php:1', 'label'=>'Product', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
//'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>90),
'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>105),
'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>110),
//'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>115),
//'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>120),
//'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
'fk_user_ouverture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserOpen', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135),
'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserCloture', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135),
'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 4=>'Open', 5=>'Closed'))
);
// END MODULEBUILDER PROPERTIES
/** /**
* Constructor * Constructor

View File

@@ -83,6 +83,11 @@ abstract class CommonObject
*/ */
public $element; public $element;
/**
* @var string Name to use for 'features' parameter to check module permissions with restrictedArea(). Undefined means same value than $element.
*/
public $element_for_permission;
/** /**
* @var string Name of table without prefix where object is stored * @var string Name of table without prefix where object is stored
*/ */

View File

@@ -9744,24 +9744,45 @@ class Form
$ret = ''; $ret = '';
$ret .= '<div class="nowrap centpercent">'; $ret .= '<div class="divadvancedsearchfieldcomp inline-block">';
//$ret .= '<button type="submit" class="liste_titre button_removefilter" name="button_removefilter_x" value="x"><span class="fa fa-remove"></span></button>'; //$ret .= '<button type="submit" class="liste_titre button_removefilter" name="button_removefilter_x" value="x"><span class="fa fa-remove"></span></button>';
$ret .= '<a href="#" class="dropdownsearch-toggle unsetcolor paddingright">'; $ret .= '<a href="#" class="dropdownsearch-toggle unsetcolor paddingright">';
$ret .= '<span class="fas fa-filter linkobject boxfilter" title="Filter" id="idsubimgproductdistribution"></span>'; $ret .= '<span class="fas fa-filter linkobject boxfilter" title="'.dol_escape_htmltag($langs->trans("Filters")).'" id="idsubimgproductdistribution"></span>';
$ret .= $langs->trans("Filters"); //$ret .= $langs->trans("Filters");
$ret .= '</a>'; $ret .= '</a>';
//$ret .= '<button type="submit" class="liste_titre button_search paddingleftonly" name="button_search_x" value="x"><span class="fa fa-search"></span></button>';
$ret .= '<div name="search_component_params" class="search_component_params inline-block minwidth500 maxwidth300onsmartphone valignmiddle">';
$texttoshow = '<div class="opacitymedium inline-block search_component_searchtext">'.$langs->trans("Search").'</div>';
$ret .= '<div class="search_component inline-block valignmiddle">'.$texttoshow.'</div>'; $ret .= '<div class="divadvancedsearchfieldcompinput inline-block minwidth500 maxwidth300onsmartphone">';
$ret .= '</div>';
$ret .= "<!-- Syntax of Generic filter string: t.ref:like:'SO-%', t.date_creation:<:'20160101', t.date_creation:<:'2016-01-01 12:30:00', t.nature:is:NULL, t.field2:isnot:NULL -->\n"; // Show select fields as tags.
if (GETPOST('show_search_component_params_hidden', 'int')) { $ret .= '<div name="divsearch_component_params" class="noborderbottom search_component_params inline-block valignmiddle">';
if ($search_component_params_hidden) {
if (!preg_match('/^\(.*\)$/', $search_component_params_hidden)) { // If $search_component_params_hidden does not start and end with ()
$search_component_params_hidden .= '('.$search_component_params_hidden.')';
}
$errormessage = '';
if (!dolCheckFilters($search_component_params_hidden, $errormessage)) {
print 'ERROR in parsing search string';
}
$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
//var_dump($search_component_params_hidden);
$htmltags = preg_replace_callback('/'.$regexstring.'/', 'dolForgeCriteriaCallback', $search_component_params_hidden);
//var_dump($htmltags);
$ret .= '<span class="marginleftonlyshort valignmiddle tagsearch"><span class="tagsearchdelete select2-selection__choice__remove">x</span> '.$htmltags.'</span>';
}
//$ret .= '<button type="submit" class="liste_titre button_search paddingleftonly" name="button_search_x" value="x"><span class="fa fa-search"></span></button>';
//$ret .= search_component_params
//$texttoshow = '<div class="opacitymedium inline-block search_component_searchtext">'.$langs->trans("Search").'</div>';
//$ret .= '<div class="search_component inline-block valignmiddle">'.$texttoshow.'</div>';
$show_search_component_params_hidden = 1;
if ($show_search_component_params_hidden) {
$ret .= '<input type="hidden" name="show_search_component_params_hidden" value="1">'; $ret .= '<input type="hidden" name="show_search_component_params_hidden" value="1">';
} }
$ret .= '<input type="'.(GETPOST('show_search_component_params_hidden', 'int') ? 'text' : 'hidden').'" name="search_component_params_hidden" class="search_component_params_hidden marginleftonly" value="'.$search_component_params_hidden.'">'; $ret .= "<!-- We store the full search string into this field. For example: (t.ref:like:'SO-%') and ((t.ref:like:'CO-%') or (t.ref:like:'AA%')) -->";
$ret .= '<input type="hidden" name="search_component_params_hidden" value="'.dol_escape_htmltag($search_component_params_hidden).'">';
// For compatibility with forms that show themself the search criteria in addition of this component, we output the fields // For compatibility with forms that show themself the search criteria in addition of this component, we output the fields
foreach ($arrayofcriterias as $criterias) { foreach ($arrayofcriterias as $criterias) {
foreach ($criterias as $criteriafamilykey => $criteriafamilyval) { foreach ($criterias as $criteriafamilykey => $criteriafamilyval) {
@@ -9785,8 +9806,14 @@ class Form
} }
} }
} }
$ret .= '</div>'; $ret .= '</div>';
$ret .= "<!-- Syntax of Generic filter string: t.ref:like:'SO-%', t.date_creation:<:'20160101', t.date_creation:<:'2016-01-01 12:30:00', t.nature:is:NULL, t.field2:isnot:NULL -->\n";
$ret .= '<input type="text" placeholder="'.$langs->trans("Search").'" name="search_component_params_input" class="noborderbottom search_component_input" value="">';
$ret .= '</div>';
$ret .= '</div>';
return $ret; return $ret;
} }

View File

@@ -1479,9 +1479,10 @@ class FormOther
* @param array $search_groupby Array of preselected fields * @param array $search_groupby Array of preselected fields
* @param array $arrayofgroupby Array of groupby to fill * @param array $arrayofgroupby Array of groupby to fill
* @param string $morecss More CSS * @param string $morecss More CSS
* @param string $showempty '1' or 'text'
* @return string HTML string component * @return string HTML string component
*/ */
public function selectGroupByField($object, $search_groupby, &$arrayofgroupby, $morecss = 'minwidth200 maxwidth250') public function selectGroupByField($object, $search_groupby, &$arrayofgroupby, $morecss = 'minwidth200 maxwidth250', $showempty = '1')
{ {
global $langs, $extrafields, $form; global $langs, $extrafields, $form;
@@ -1493,7 +1494,7 @@ class FormOther
$SS = substr($langs->trans("Second"), 0, 1).substr($langs->trans("Second"), 0, 1); $SS = substr($langs->trans("Second"), 0, 1).substr($langs->trans("Second"), 0, 1);
foreach ($object->fields as $key => $val) { foreach ($object->fields as $key => $val) {
if (!$val['measure']) { if (!$val['isameasure']) {
if (in_array($key, array( if (in_array($key, array(
'id', 'ref_int', 'ref_ext', 'rowid', 'entity', 'last_main_doc', 'logo', 'logo_squarred', 'extraparams', 'id', 'ref_int', 'ref_ext', 'rowid', 'entity', 'last_main_doc', 'logo', 'logo_squarred', 'extraparams',
'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) { 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) {
@@ -1541,7 +1542,7 @@ class FormOther
foreach ($arrayofgroupby as $key => $val) { foreach ($arrayofgroupby as $key => $val) {
$arrayofgroupbylabel[$key] = $val['label']; $arrayofgroupbylabel[$key] = $val['label'];
} }
$result = $form->selectarray('search_groupby', $arrayofgroupbylabel, $search_groupby, 1, 0, 0, '', 0, 0, 0, '', $morecss, 1); $result = $form->selectarray('search_groupby', $arrayofgroupbylabel, $search_groupby, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, 1);
return $result; return $result;
} }
@@ -1552,9 +1553,10 @@ class FormOther
* @param mixed $object Object analyzed * @param mixed $object Object analyzed
* @param array $search_xaxis Array of preselected fields * @param array $search_xaxis Array of preselected fields
* @param array $arrayofxaxis Array of groupby to fill * @param array $arrayofxaxis Array of groupby to fill
* @return string HTML string component * @param string $showempty '1' or 'text'
* @return string HTML string component
*/ */
public function selectXAxisField($object, $search_xaxis, &$arrayofxaxis) public function selectXAxisField($object, $search_xaxis, &$arrayofxaxis, $showempty = '1')
{ {
global $langs, $extrafields, $form; global $langs, $extrafields, $form;
@@ -1589,9 +1591,9 @@ class FormOther
continue; continue;
} }
if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) { if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
$arrayofxaxis['t.'.$key.'-year'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.')', 'position' => $val['position'].'-y'); $arrayofxaxis['t.'.$key.'-year'] = array('label' => $langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.')</span>', 'position' => $val['position'].'-y');
$arrayofxaxis['t.'.$key.'-month'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', 'position' => $val['position'].'-m'); $arrayofxaxis['t.'.$key.'-month'] = array('label' => $langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.')</span>', 'position' => $val['position'].'-m');
$arrayofxaxis['t.'.$key.'-day'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', 'position' => $val['position'].'-d'); $arrayofxaxis['t.'.$key.'-day'] = array('label' => $langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.'-'.$DD.')</span>', 'position' => $val['position'].'-d');
} else { } else {
$arrayofxaxis['t.'.$key] = array('label' => $langs->trans($val['label']), 'position' => (int) $val['position']); $arrayofxaxis['t.'.$key] = array('label' => $langs->trans($val['label']), 'position' => (int) $val['position']);
} }
@@ -1617,7 +1619,7 @@ class FormOther
foreach ($arrayofxaxis as $key => $val) { foreach ($arrayofxaxis as $key => $val) {
$arrayofxaxislabel[$key] = $val['label']; $arrayofxaxislabel[$key] = $val['label'];
} }
$result = $form->selectarray('search_xaxis', $arrayofxaxislabel, $search_xaxis, 1, 0, 0, '', 0, 0, 0, '', 'minwidth250', 1); $result = $form->selectarray('search_xaxis', $arrayofxaxislabel, $search_xaxis, $showempty, 0, 0, '', 0, 0, 0, '', 'minwidth250', 1);
return $result; return $result;
} }

View File

@@ -99,7 +99,8 @@ $arrayoftype = array(
'order' => array('label' => 'Orders', 'ObjectClassName' => 'Commande', 'enabled' => $conf->commande->enabled, 'ClassPath' => "/commande/class/commande.class.php"), 'order' => array('label' => 'Orders', 'ObjectClassName' => 'Commande', 'enabled' => $conf->commande->enabled, 'ClassPath' => "/commande/class/commande.class.php"),
'invoice' => array('label' => 'Invoices', 'ObjectClassName' => 'Facture', 'enabled' => $conf->facture->enabled, 'ClassPath' => "/compta/facture/class/facture.class.php"), 'invoice' => array('label' => 'Invoices', 'ObjectClassName' => 'Facture', 'enabled' => $conf->facture->enabled, 'ClassPath' => "/compta/facture/class/facture.class.php"),
'invoice_template'=>array('label' => 'PredefinedInvoices', 'ObjectClassName' => 'FactureRec', 'enabled' => $conf->facture->enabled, 'ClassPath' => "/compta/class/facturerec.class.php", 'langs'=>'bills'), 'invoice_template'=>array('label' => 'PredefinedInvoices', 'ObjectClassName' => 'FactureRec', 'enabled' => $conf->facture->enabled, 'ClassPath' => "/compta/class/facturerec.class.php", 'langs'=>'bills'),
'contract' => array('label' => 'Contracts', 'ObjectClassName' => 'Contrat', 'enabled' => $conf->contrat->enabled, 'ClassPath' => "/contrat/class/contrat.class.php", 'langs'=>'contract'), 'contract' => array('label' => 'Contracts', 'ObjectClassName' => 'Contrat', 'enabled' => $conf->contrat->enabled, 'ClassPath' => "/contrat/class/contrat.class.php", 'langs'=>'contracts'),
'contractdet' => array('label' => 'ContractLines', 'ObjectClassName' => 'ContratLigne', 'enabled' => $conf->contrat->enabled, 'ClassPath' => "/contrat/class/contrat.class.php", 'langs'=>'contracts'),
'bom' => array('label' => 'BOM', 'ObjectClassName' => 'Bom', 'enabled' => $conf->bom->enabled), 'bom' => array('label' => 'BOM', 'ObjectClassName' => 'Bom', 'enabled' => $conf->bom->enabled),
'mo' => array('label' => 'MO', 'ObjectClassName' => 'Mo', 'enabled' => $conf->mrp->enabled, 'ClassPath' => "/mrp/class/mo.class.php"), 'mo' => array('label' => 'MO', 'ObjectClassName' => 'Mo', 'enabled' => $conf->mrp->enabled, 'ClassPath' => "/mrp/class/mo.class.php"),
'ticket' => array('label' => 'Ticket', 'ObjectClassName' => 'Ticket', 'enabled' => $conf->ticket->enabled), 'ticket' => array('label' => 'Ticket', 'ObjectClassName' => 'Ticket', 'enabled' => $conf->ticket->enabled),
@@ -159,6 +160,11 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen
$search_component_params = array(''); $search_component_params = array('');
$search_component_params_hidden = GETPOST('search_component_params_hidden', 'alphanohtml'); $search_component_params_hidden = GETPOST('search_component_params_hidden', 'alphanohtml');
// For the case we enter a criteria manually, the search_component_params_input will be defined and must be used in priority
if (GETPOST('search_component_params_input', 'alphanohtml')) {
$search_component_params_hidden = GETPOST('search_component_params_input', 'alphanohtml');
}
$MAXUNIQUEVALFORGROUP = 20; $MAXUNIQUEVALFORGROUP = 20;
$MAXMEASURESINBARGRAPH = 20; $MAXMEASURESINBARGRAPH = 20;
@@ -175,7 +181,12 @@ $arrayofgroupby = array();
$arrayofyaxis = array(); $arrayofyaxis = array();
$arrayofvaluesforgroupby = array(); $arrayofvaluesforgroupby = array();
restrictedArea($user, $object->element, 0, ''); $features = $object->element;
if (!empty($object->element_for_permission)) {
$features = $object->element_for_permission;
}
restrictedArea($user, $features, 0, '');
$error = 0; $error = 0;
@@ -420,22 +431,22 @@ if ($object->isextrafieldmanaged) {
} }
} }
} }
print '<div class="inline-block"><span class="fas fa-chart-line paddingright" title="'.$langs->trans("Measures").'"></span>'.$langs->trans("Measures").'</div> '; print '<div class="inline-block"><span class="fas fa-ruler-combined paddingright" title="'.$langs->trans("Measures").'"></span><span class="fas fa-caret-left caretleftaxis" title="'.dol_escape_htmltag($langs->trans("Measures")).'"></span>'.$langs->trans("Measures").'</div> ';
print $form->multiselectarray('search_measures', $arrayofmesures, $search_measures, 0, 0, 'minwidth400', 1); print $form->multiselectarray('search_measures', $arrayofmesures, $search_measures, 0, 0, 'minwidth400', 1); // Fill the array $arrayofmeasures with possible fields
print '</div>'; print '</div>';
// XAxis // XAxis
print '<div class="divadvancedsearchfield">'; print '<div class="divadvancedsearchfield">';
print '<div class="inline-block"><span class="fas fa-ruler-horizontal paddingright" title="'.$langs->trans("XAxis").'"></span>'.$langs->trans("XAxis").'</div> '; print '<div class="inline-block"><span class="fas fa-ruler-combined paddingright" title="'.dol_escape_htmltag($langs->trans("XAxis")).'"></span><span class="fas fa-caret-down caretdownaxis" title="'.dol_escape_htmltag($langs->trans("XAxis")).'"></span></div> ';
print $formother->selectXAxisField($object, $search_xaxis, $arrayofxaxis); print $formother->selectXAxisField($object, $search_xaxis, $arrayofxaxis, $langs->trans("XAxis")); // Fill the array $arrayofxaxis with possible fields
print '</div>'; print '</div>';
// Group by // Group by
print '<div class="divadvancedsearchfield">'; print '<div class="divadvancedsearchfield">';
print '<div class="inline-block opacitymedium"><span class="fas fa-ruler-horizontal paddingright" title="'.$langs->trans("GroupBy").'"></span>'.$langs->trans("GroupBy").'</div> '; print '<div class="inline-block opacitymedium"><span class="fas fa-ruler-horizontal paddingright" title="'.dol_escape_htmltag($langs->trans("GroupBy")).'"></span></div> ';
print $formother->selectGroupByField($object, $search_groupby, $arrayofgroupby); print $formother->selectGroupByField($object, $search_groupby, $arrayofgroupby, 'minwidth200 maxwidth250', $langs->trans("GroupBy")); // Fill the array $arrayofgroupby with possible fields
print '</div>'; print '</div>';
@@ -561,7 +572,7 @@ if (!empty($search_measures) && !empty($search_xaxis)) {
$sql .= ' AND entity IN ('.getEntity($object->element).')'; $sql .= ' AND entity IN ('.getEntity($object->element).')';
} }
// Add the where here // Add the where here
$sqlfilters = GETPOST('search_component_params_hidden', 'alphanohtml'); $sqlfilters = $search_component_params_hidden;
if ($sqlfilters) { if ($sqlfilters) {
$errormessage = ''; $errormessage = '';
if (dolCheckFilters($sqlfilters, $errormessage)) { if (dolCheckFilters($sqlfilters, $errormessage)) {

View File

@@ -10801,7 +10801,7 @@ function dolForgeCriteriaCallback($matches)
{ {
global $db; global $db;
//dol_syslog("Convert matches ".$matches[1]); dol_syslog("Convert matches ".$matches[1]);
if (empty($matches[1])) { if (empty($matches[1])) {
return ''; return '';
} }

View File

@@ -20,6 +20,7 @@ ContractsSubscriptions=Contracts/Subscriptions
ContractsAndLine=Contracts and line of contracts ContractsAndLine=Contracts and line of contracts
Contract=Contract Contract=Contract
ContractLine=Contract line ContractLine=Contract line
ContractLines=Contract lines
Closing=Closing Closing=Closing
NoContracts=No contracts NoContracts=No contracts
MenuServices=Services MenuServices=Services

View File

@@ -189,7 +189,7 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla
border<?php echo empty($conf->global->THEME_SHOW_BORDER_ON_INPUT) ? '-bottom' : ''; ?>: solid 1px var(--inputbordercolor); border<?php echo empty($conf->global->THEME_SHOW_BORDER_ON_INPUT) ? '-bottom' : ''; ?>: solid 1px var(--inputbordercolor);
/* padding: 5px; */ /* padding: 5px; */
} }
.pageplusone, .pageplusone, .divadvancedsearchfieldcompinput,
div.tabBar input, div.tabBar input.flat, div.tabBar textarea, div.tabBar textarea.flat, div.tabBar form.flat select, div.tabBar select, div.tabBar select.flat, div.tabBar .dataTables_length label select div.tabBar input, div.tabBar input.flat, div.tabBar textarea, div.tabBar textarea.flat, div.tabBar form.flat select, div.tabBar select, div.tabBar select.flat, div.tabBar .dataTables_length label select
{ {
border<?php echo empty($conf->global->THEME_SHOW_BORDER_ON_INPUT) ? '-bottom' : ''; ?>: solid 1px var(--inputbordercolor); border<?php echo empty($conf->global->THEME_SHOW_BORDER_ON_INPUT) ? '-bottom' : ''; ?>: solid 1px var(--inputbordercolor);
@@ -202,6 +202,10 @@ div.tabBar input, div.tabBar input.flat, div.tabBar textarea, div.tabBar textare
} }
?> ?>
} }
.divadvancedsearchfieldcompinput {
background: #fff;
border-bottom: solid 1px var(--inputbordercolor);
}
input[name=duration_value], input[name=durationhour] input[name=duration_value], input[name=durationhour]
{ {
margin-right: 4px !important; margin-right: 4px !important;
@@ -269,7 +273,7 @@ section.setupsection {
div.tabBar textarea:focus { div.tabBar textarea:focus {
border: 1px solid #aaa !important; border: 1px solid #aaa !important;
} }
input:focus:not(.button):not(.select2-search__field):not(#top-bookmark-search-input), select:focus, .select2-container--open .select2-selection--single { input:focus:not(.button):not(.select2-search__field):not(#top-bookmark-search-input):not(.search_component_input), select:focus, .select2-container--open .select2-selection--single {
/* div.tabBar input:focus, div.tabBar select:focus { */ /* div.tabBar input:focus, div.tabBar select:focus { */
border-bottom: 1px solid #666 !important; border-bottom: 1px solid #666 !important;
border-bottom-left-radius: 0 !important; border-bottom-left-radius: 0 !important;
@@ -1032,8 +1036,8 @@ div.divsearchfield {
background: #fff; background: #fff;
padding-top: 3px; padding-top: 3px;
padding-bottom: 3px; padding-bottom: 3px;
padding-left: 10px; padding-<?php echo $left; ?>: 0;
padding-right: 10px; padding-<?php echo $right; ?>: 0;
border-bottom: solid 1px var(--inputbordercolor); border-bottom: solid 1px var(--inputbordercolor);
height: 24px; height: 24px;
} }
@@ -1046,6 +1050,32 @@ div.divsearchfield {
margin: 0 !important; margin: 0 !important;
padding: 3px; padding: 3px;
} }
.tagsearch {
padding: 2px;
padding-right: 4px;
padding-bottom: 3px;
background: #ddd;
border-radius: 4px;
}
.tagsearchdelete {
color: #999;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px;
padding-left: 4px;
}
.caretleftaxis {
margin-left: -13px;
margin-top: -1px;
position: absolute;
}
.caretdownaxis {
margin-left: -12px;
margin-top: 0;
position: absolute;
}
.a-filter, .a-mesure { .a-filter, .a-mesure {
border-radius: 50px; border-radius: 50px;

View File

@@ -623,12 +623,12 @@ td.amount, span.amount, div.amount, b.amount {
td.actionbuttons a { td.actionbuttons a {
padding-left: 6px; padding-left: 6px;
} }
select.flat, form.flat select, .pageplusone { select.flat, form.flat select, .pageplusone, .divadvancedsearchfieldcompinput, {
font-weight: normal; font-weight: normal;
font-size: unset; font-size: unset;
height: 2em; height: 2em;
} }
input.pageplusone { input.pageplusone, .divadvancedsearchfieldcompinput, {
padding-bottom: 4px; padding-bottom: 4px;
padding-top: 4px; padding-top: 4px;
} }
@@ -1155,6 +1155,48 @@ div.divsearchfield {
.divadvancedsearchfield span.select2.select2-container.select2-container--default { .divadvancedsearchfield span.select2.select2-container.select2-container--default {
padding-bottom: 4px; padding-bottom: 4px;
} }
.divadvancedsearchfieldcompinput {
background: #fff;
border-bottom: solid 1px var(--inputbordercolor);
}
.search_component_params {
/*display: flex; */
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
background: #fff;
padding-top: 3px;
padding-bottom: 3px;
padding-<?php echo $left; ?>: 0;
padding-<?php echo $right; ?>: 0;
border-bottom: solid 1px var(--inputbordercolor);
height: 24px;
}
.search_component_searchtext {
padding-top: 2px;
}
.search_component_params_text, .search_component_params_text:focus {
border-bottom: none;
width: auto;
margin: 0 !important;
padding: 3px;
}
.tagsearch {
padding: 2px;
padding-right: 4px;
padding-bottom: 3px;
background: #ddd;
border-radius: 4px;
}
.tagsearchdelete {
color: #999;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px;
padding-left: 4px;
}
<?php <?php
// Add a nowrap on smartphone, so long list of field used for filter are overflowed with clip // Add a nowrap on smartphone, so long list of field used for filter are overflowed with clip
if ($conf->browser->layout == 'phone') { if ($conf->browser->layout == 'phone') {