Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions core/config.class.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,14 @@ class Config
'quick_create.max_history_results' => [
'type' => 'integer',
'description' => 'Max. number of elements in the history',
'default' => 5,
'value' => 5,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'quick_create.max_popular_results' => [
'type' => 'integer',
'description' => 'Max. number of elements in the popular classes section',
'default' => 10,
'value' => 10,
'source_of_value' => '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<class id="FunctionalCI" _delta="define">
<parent>cmdbAbstractObject</parent>
<properties>
<category>bizmodel,searchable</category>
<category>bizmodel,searchable,popular</category>
<abstract>true</abstract>
Comment thread
v-dumas marked this conversation as resolved.
<key_type>autoincrement</key_type>
<db_table>functionalci</db_table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/]]></comment>
<category>bizmodel,searchable,requestmgmt</category>
<category>bizmodel,searchable,requestmgmt,popular</category>
<abstract>false</abstract>
<key_type>autoincrement</key_type>
<db_table>ticket_request</db_table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/]]></comment>
<category>bizmodel,searchable,requestmgmt</category>
<category>bizmodel,searchable,requestmgmt,popular</category>
<abstract>false</abstract>
<key_type>autoincrement</key_type>
<db_table>ticket_request</db_table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Open quick create~~',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'You haven\'t create any object yet~~',
'UI:Component:QuickCreate:Recents:Title' => 'Recents~~',
'UI:Component:QuickCreate:MostPopular:Title' => 'Populární',
'UI:Component:QuickCreate:Tooltip' => 'Quickly create any type of object~~',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Select object type...~~',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Open quick create~~',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'You haven\'t create any object yet~~',
'UI:Component:QuickCreate:MostPopular:Title' => 'Most popular~~',
'UI:Component:QuickCreate:Recents:Title' => 'Recents~~',
'UI:Component:QuickCreate:Tooltip' => 'Quickly create any type of object~~',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Wählen Sie einen Objekttyp aus...',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Quick-Create-Menu öffnen',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'Sie haben noch keine Objekte erstellt',
'UI:Component:QuickCreate:MostPopular:Title' => 'Am beliebtesten',
'UI:Component:QuickCreate:Recents:Title' => 'Letzte',
'UI:Component:QuickCreate:Tooltip' => 'Erstellen Sie schnell jeden Typ von Objekt',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Select object type...',
'UI:Component:QuickCreate:Recents:Title' => 'Recents',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'You haven\'t create any object yet',
'UI:Component:QuickCreate:MostPopular:Title' => 'Most popular',
'UI:Component:QuickCreate:HistoryDisabled' => 'History is disabled',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Open quick create',
));
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Select object type...',
'UI:Component:QuickCreate:Recents:Title' => 'Recents',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'You haven\'t create any object yet',
'UI:Component:QuickCreate:MostPopular:Title' => 'Most popular',
'UI:Component:QuickCreate:HistoryDisabled' => 'History is disabled',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Open quick create',
));
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Seleccionar tipo de objeto...',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Abrir creación rápida',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'Aún no has creado ningún objeto.',
'UI:Component:QuickCreate:MostPopular:Title' => 'Más popular',
'UI:Component:QuickCreate:Recents:Title' => 'Recientes',
'UI:Component:QuickCreate:Tooltip' => 'Crear rápidamente cualquier tipo de objeto',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Type d\'objet...',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Ouvrir la création rapide',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'Vous n\'avez pas encore créé d\'objet',
'UI:Component:QuickCreate:MostPopular:Title' => 'Populaires',
'UI:Component:QuickCreate:Recents:Title' => 'Types récents',
'UI:Component:QuickCreate:Tooltip' => 'Création rapide de n\'importe quel objet',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Objektumtípus kiválasztása...',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Gyors létrehozás megnyitása',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'Még nem hozott létre objektumot',
'UI:Component:QuickCreate:MostPopular:Title' => 'Legnépszerűbb',
'UI:Component:QuickCreate:Recents:Title' => 'Legutóbbiak',
'UI:Component:QuickCreate:Tooltip' => 'Bármilyen típusú objektum gyors létrehozása',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Seleziona il tipo di oggetto...',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Apri la creazione rapida',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'Non hai ancora creato alcun oggetto',
'UI:Component:QuickCreate:MostPopular:Title' => 'Più popolari',
'UI:Component:QuickCreate:Recents:Title' => 'Recenti',
'UI:Component:QuickCreate:Tooltip' => 'Crea rapidamente qualsiasi tipo di oggetto',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Select object type...~~',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Open quick create~~',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'You haven\'t create any object yet~~',
'UI:Component:QuickCreate:MostPopular:Title' => 'Most popular~~',
'UI:Component:QuickCreate:Recents:Title' => 'Recents~~',
'UI:Component:QuickCreate:Tooltip' => 'Quickly create any type of object~~',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Selecteer een objectsoort…',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Open snel object aanmaken',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'Je hebt nog geen objecten gemaakt',
'UI:Component:QuickCreate:MostPopular:Title' => 'Meest populair',
'UI:Component:QuickCreate:Recents:Title' => 'Recente',
'UI:Component:QuickCreate:Tooltip' => 'Snel een object aanmaken',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Wybierz typ obiektu...',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Otwórz szybkie tworzenie',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'Nie utworzyłeś jeszcze żadnego obiektu',
'UI:Component:QuickCreate:MostPopular:Title' => 'Najbardziej popularne',
'UI:Component:QuickCreate:Recents:Title' => 'Ostatnie',
'UI:Component:QuickCreate:Tooltip' => 'Szybko utwórz dowolny rodzaj obiektu',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Selecione o tipo de objeto...',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Abrir criação rápida',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'Você ainda não criou nenhum objeto',
'UI:Component:QuickCreate:MostPopular:Title' => 'Mais popular',
'UI:Component:QuickCreate:Recents:Title' => 'Recentes',
'UI:Component:QuickCreate:Tooltip' => 'Crie rapidamente qualquer tipo de objeto',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Выбрать тип объекта...',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Открыть быстрое создание объекта',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'Вы ещё не создавали объекты',
'UI:Component:QuickCreate:MostPopular:Title' => 'Популярные',
'UI:Component:QuickCreate:Recents:Title' => 'Недавние',
'UI:Component:QuickCreate:Tooltip' => 'Быстрое создание объекта любого типа',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Select object type...~~',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Open quick create~~',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'You haven\'t create any object yet~~',
'UI:Component:QuickCreate:MostPopular:Title' => 'Most popular~~',
'UI:Component:QuickCreate:Recents:Title' => 'Recents~~',
'UI:Component:QuickCreate:Tooltip' => 'Quickly create any type of object~~',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => 'Select object type...~~',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => 'Open quick create~~',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => 'You haven\'t create any object yet~~',
'UI:Component:QuickCreate:MostPopular:Title' => 'Most popular~~',
'UI:Component:QuickCreate:Recents:Title' => 'Recents~~',
'UI:Component:QuickCreate:Tooltip' => 'Quickly create any type of object~~',
]);
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'UI:Component:QuickCreate:Input:Placeholder' => '请选择对象类型...',
'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer' => '打开快速创建',
'UI:Component:QuickCreate:LastClasses:NoClass:Placeholder' => '您尚未创建任何对象',
'UI:Component:QuickCreate:MostPopular:Title' => '最常用',
'UI:Component:QuickCreate:Recents:Title' => '最近',
'UI:Component:QuickCreate:Tooltip' => '快速创建任意类型的对象',
]);
28 changes: 26 additions & 2 deletions sources/Application/UI/Base/Component/QuickCreate/QuickCreate.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ class QuickCreate extends UIBlock implements iKeyboardShortcut
protected $aLastClasses;
/** @var int $iMaxAutocompleteResults Max. number of elements returned by the autocomplete */
protected $iMaxAutocompleteResults;
/** @var bool $bShowHistory Whether or not to display the elements in the history */
/** @var bool $bShowHistory Whether to display the elements in the history */
protected $bShowHistory;
/** @var int $iMaxHistoryResults Max. number of elements in the history */
protected $iMaxHistoryResults;
/** @var int $iMaxPopularResults Max. number of elements in the popular section */
protected $iMaxPopularResults;
/** @var array $aPopularClasses */
protected $aPopularClasses;

/**
* QuickCreate constructor.
Expand All @@ -82,14 +86,16 @@ public function __construct(array $aLastClasses = [], ?string $sId = null)
$this->iMaxAutocompleteResults = (int) MetaModel::GetConfig()->Get('quick_create.max_autocomplete_results');
$this->bShowHistory = (bool) MetaModel::GetConfig()->Get('quick_create.show_history');
$this->iMaxHistoryResults = (int) MetaModel::GetConfig()->Get('quick_create.max_history_results');
$this->iMaxPopularResults = (int) MetaModel::GetConfig()->Get('quick_create.max_popular_results');
$this->aPopularClasses = QuickCreateHelper::GetPopularClasses();
}

/**
* Set the creation form endpoint URL.
* If $bRelativeUrl is true, then $sEndpoint will be complete with the app_root_url
*
* @param string $sEndpoint URL to the endpoint
* @param bool $bRelativeUrl Whether or not the $sEndpoint parameter is a relative URL
* @param bool $bRelativeUrl Whether the $sEndpoint parameter is a relative URL
*
* @return $this
* @throws \Exception
Expand Down Expand Up @@ -203,6 +209,24 @@ public function GetMaxHistoryResults(): int
return $this->iMaxHistoryResults;
}

/**
* @see $aMaxPopularClasses
* @return array
*/
public function GetPopularClasses(): array
{
return $this->aPopularClasses;
}

/**
* @see $iMaxPopularResults
* @return int
*/
public function GetMaxPopularResults(): int
{
return $this->iMaxPopularResults;
}

public static function GetShortcutKeys(): array
{
return [['id' => 'ibo-open-quick-create', 'label' => 'UI:Component:QuickCreate:KeyboardShortcut:OpenDrawer', 'key' => 'c', 'event' => 'open_drawer']];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use DBObject;
use MetaModel;
use utils;
use UserRights;

/**
* Class QuickCreateHelper
Expand Down Expand Up @@ -71,7 +72,7 @@ public static function AddClassToHistory(string $sClass)
array_unshift($aHistoryEntries, $aNewEntry);

// Truncate history
static::TruncateHistory($aHistoryEntries);
static::Truncate($aHistoryEntries, 'quick_create.max_history_results');

appUserPreferences::SetPref(static::USER_PREF_CODE, $aHistoryEntries);
}
Expand All @@ -88,7 +89,8 @@ public static function GetLastClasses()
{
/** @var array $aHistoryEntries */
$aHistoryEntries = appUserPreferences::GetPref(static::USER_PREF_CODE, []);
static::TruncateHistory($aHistoryEntries);

static::Truncate($aHistoryEntries, 'quick_create.max_history_results');

for($iIdx = 0; $iIdx < count($aHistoryEntries); $iIdx++)
{
Expand Down Expand Up @@ -125,16 +127,70 @@ public static function GetLastClasses()
}

/**
* Truncate $aHistoryEntries to 'global_search.max_history_results' entries
* Return an array of popular object classes
*
* @return array
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \MySQLException
*/
public static function GetPopularClasses(): array
{
$aHistoryEntries = appUserPreferences::GetPref(static::USER_PREF_CODE, []);
static::Truncate($aHistoryEntries, 'quick_create.max_history_results');
$aPopularClassesNames = UserRights::GetAllowedClasses(UR_ACTION_CREATE, array('popular'), false);

// Prevent classes in both Popular and Recent to appear twice
for($iIdx = 0; $iIdx < count($aHistoryEntries); $iIdx++)
{
if (($key = array_search($aHistoryEntries[$iIdx]['class'], $aPopularClassesNames)) !== false) {
unset($aPopularClassesNames[$key]);
}
}
Comment on lines +143 to +149
//die(var_dump($aPopularClassesNames));
static::Truncate($aPopularClassesNames, 'quick_create.max_popular_results');
Comment on lines +150 to +151
$aPopularClasses = array();
foreach($aPopularClassesNames as $sClass)
{
if (!MetaModel::IsValidClass($sClass)) {
continue;
}

// Add class icon
$sClassIconUrl = MetaModel::GetClassIcon($sClass, false);
// Mind that some classes don't have an icon
$sClassIconUrl = !empty($sClassIconUrl) ? $sClassIconUrl : null;

// Add class label
$sLabelHtml = utils::EscapeHtml(MetaModel::GetName($sClass));

// Add URL
$sTargetUrl = DBObject::ComputeStandardUIPage($sClass).'?operation=new&class='.$sClass;

$aPopularClasses[] = array(
'class' => $sClass,
'icon_url' => $sClassIconUrl,
'label_html' => $sLabelHtml,
'target_url' => $sTargetUrl
);
}
return $aPopularClasses;
}

/**
* Truncate an array to $sMaxEntriesParam
*
* @param array $aHistoryEntries
* @param array $aEntries
* @param string $sMaxEntriesParam
*/
protected static function TruncateHistory(array &$aHistoryEntries): void
protected static function Truncate(array &$aEntries, string $sMaxEntriesParam = 'global_search.max_history_results'): void
{
$iMaxHistoryResults = (int) MetaModel::GetConfig()->Get('quick_create.max_history_results');
if(count($aHistoryEntries) > $iMaxHistoryResults)
$iMaxResults = (int) MetaModel::GetConfig()->Get($sMaxEntriesParam);
if(count($aEntries) > $iMaxResults)
{
$aHistoryEntries = array_slice($aHistoryEntries, 0, $iMaxHistoryResults);
$aEntries = array_slice($aEntries, 0, $iMaxResults);
}
}


}
22 changes: 20 additions & 2 deletions templates/base/components/quick-create/layout.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
<div class="ibo-quick-create--compartment">
<div class="ibo-quick-create--compartment-content" data-role="ibo-quick-create--compartment-results">
</div>
<div class="ibo-quick-create--compartment-title" data-role="ibo-quick-create--compartment-title">
{# History section #}
<div class="ibo-quick-create--compartment-title ibo-quick-create--history-classes--title" data-role="ibo-quick-create--compartment-title">
<span>{{ 'UI:Component:QuickCreate:Recents:Title'|dict_s }}</span>
</div>
<div class="ibo-quick-create--compartment-content" data-role="ibo-quick-create--compartment-content">
<div class="ibo-quick-create--compartment-content ibo-quick-create--history-classes--content" data-role="ibo-quick-create--compartment-content">
{% if oUIBlock.GetShowHistory == false %}
<div class="ibo-quick-create--compartment--placeholder">
<div class="ibo-quick-create--compartment--placeholder-hint">{{ 'UI:Component:QuickCreate:HistoryDisabled'|dict_s }}</div>
Expand All @@ -48,6 +49,23 @@
</div>
{% endif %}
</div>
{# Popular classes section #}
{% if oUIBlock.GetPopularClasses()|length > 0 %}
<div class="ibo-quick-create--compartment-title ibo-quick-create--popular-classes--title" data-role="ibo-quick-create--compartment-title">
<span>{{ 'UI:Component:QuickCreate:MostPopular:Title'|dict_s }}</span>
</div>
<div class="ibo-quick-create--compartment-content ibo-quick-create--popular-classes--content" data-role="ibo-quick-create--compartment-content">
{% for aClass in oUIBlock.GetPopularClasses() %}
<a href="{{ aClass.target_url }}" class="ibo-quick-create--compartment-element" data-role="ibo-quick-create--compartment-element" data-class-code="{{ aQuery.class }}">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Popular Links Lose Class Code

The popular loop defines aClass, but this attribute reads aQuery.class. Each new popular link therefore receives an undefined or empty data-class-code, so code that identifies the selected class from this attribute receives the wrong value.

Suggested change
<a href="{{ aClass.target_url }}" class="ibo-quick-create--compartment-element" data-role="ibo-quick-create--compartment-element" data-class-code="{{ aQuery.class }}">
<a href="{{ aClass.target_url }}" class="ibo-quick-create--compartment-element" data-role="ibo-quick-create--compartment-element" data-class-code="{{ aClass.class }}">

{% if aClass.icon_url is defined and aClass.icon_url is not null%}
{# Mind the empty "alt" attribute https://www.w3.org/WAI/tutorials/images/decorative/ #}
<img src="{{ aClass.icon_url}}" alt="" class="ibo-quick-create--compartment-element-image">
{% endif %}
{{ aClass.label_html|raw }}
</a>
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
Loading