Skip to content

N°9542 - Portal : add the possibility to choose subclass in search screen#894

Open
accognet wants to merge 2 commits intodevelopfrom
feature/9542-Portal_search_choose_subclass
Open

N°9542 - Portal : add the possibility to choose subclass in search screen#894
accognet wants to merge 2 commits intodevelopfrom
feature/9542-Portal_search_choose_subclass

Conversation

@accognet
Copy link
Copy Markdown
Contributor

internal
image

@accognet accognet self-assigned this Apr 24, 2026
@CombodoApplicationsAccount CombodoApplicationsAccount added the internal Work made by Combodo label Apr 24, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 24, 2026

Greptile Summary

This PR adds a subclass selector to the portal's regular search screen so users can restrict results to a specific leaf class when an external key points to an abstract parent. It introduces a new GetColumnsFromAttributeAction endpoint that returns column metadata for a chosen subclass, and refactors SearchFromAttributeAction to accept a finalclass query parameter that filters both the scope query and column definitions.

  • P1: EnumChildClasses('FunctionalCI') is hardcoded in SearchFromAttributeAction instead of EnumChildClasses($sTargetObjectClass), causing wrong subclasses to appear for every target class other than FunctionalCI.
  • P1: The "all classes" option in the Twig template uses 'Class:FunctionalCI'|dict_s instead of the sParentClass variable already passed in $aData, showing the wrong label for every other class.

Confidence Score: 4/5

Not safe to merge as-is — two P1 copy-paste bugs make the feature non-functional for any target class other than FunctionalCI.

Two P1 bugs (hardcoded FunctionalCI in PHP and Twig) need to be fixed; the architecture is sound and the remaining findings are P2.

ObjectController.php (line 1094) and mode_search_regular.html.twig (line 15)

Important Files Changed

Filename Overview
datamodels/2.x/itop-portal-base/portal/src/Controller/ObjectController.php Adds GetColumnsFromAttributeAction (new endpoint) and extends SearchFromAttributeAction to support finalclass filtering and lazy data loading; contains a critical copy-paste bug where EnumChildClasses('FunctionalCI') is hardcoded instead of using $sTargetObjectClass.
datamodels/2.x/itop-portal-base/portal/templates/bricks/object/mode_search_regular.html.twig Adds a subclass selector dropdown and refactors DataTable initialisation into a reusable createDatatable() function; the default option label is hardcoded to 'Class:FunctionalCI' instead of the dynamic sParentClass, and several JS variables are assigned without var/let/const.
datamodels/2.x/itop-portal-base/portal/config/routes/object_brick.yaml Adds a new route p_columns_from_attribute_with_class pointing to the new GetColumnsFromAttributeAction; straightforward and correct.

Sequence Diagram

sequenceDiagram
    participant Browser
    participant SearchFromAttributeAction
    participant GetColumnsFromAttributeAction
    participant MetaModel

    Browser->>SearchFromAttributeAction: POST /object/search/{attCode} (initial pass)
    SearchFromAttributeAction->>MetaModel: HasChildrenClasses($sTargetObjectClass)
    MetaModel-->>SearchFromAttributeAction: true/false
    alt has child classes
        SearchFromAttributeAction->>MetaModel: EnumChildClasses('FunctionalCI') ⚠️ hardcoded bug
        MetaModel-->>SearchFromAttributeAction: child class list
    end
    SearchFromAttributeAction-->>Browser: HTML with subclass dropdown + column metadata

    Browser->>Browser: User selects subclass from dropdown
    Browser->>GetColumnsFromAttributeAction: POST /columns-from-attribute-with-class/{attCode}?finalclass=X
    GetColumnsFromAttributeAction->>MetaModel: IsParentClass + GetAttributeDef(finalclass)
    GetColumnsFromAttributeAction-->>Browser: JSON {levelsProperties}

    Browser->>SearchFromAttributeAction: POST /object/search/{attCode}?finalclass=X (data pass)
    SearchFromAttributeAction->>MetaModel: GetScopeFilterForProfiles(finalclass)
    SearchFromAttributeAction->>MetaModel: oSearch.AddCondition('finalclass', X)
    SearchFromAttributeAction-->>Browser: JSON {data, recordsTotal, …}
Loading

Reviews (1): Last reviewed commit: "N°9542 - Portal : add the possibility to..." | Re-trigger Greptile

<div class="form_field_label">
<label>{{ 'UI:SearchFor_Class'|dict_format('') }}</label>
<select id="finalclass{{ sFormId }}">
<option value="">{{ 'Class:FunctionalCI'|dict_s }}</option>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 The default option label is hardcoded to the FunctionalCI dictionary key instead of using the actual parent class passed in sParentClass. When searching for objects of any other class (e.g. Contact), the "all classes" option will still read "Functional CI" instead of the correct class name.

Suggested change
<option value="">{{ 'Class:FunctionalCI'|dict_s }}</option>
<option value="">{{ ('Class:' ~ sParentClass)|dict_s }}</option>

Comment on lines +289 to +291
sUrl = "{{ app.url_generator.generate('p_object_search_from_attribute', {'sTargetAttCode': sTargetAttCode, 'sHostObjectClass': sHostObjectClass, 'sHostObjectId': sHostObjectId, 'ar_token': sActionRulesToken})|raw }}";
aColumnsDefinition = getColumnsDefinition();
oTable = createDatatable(sUrl);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Implicit globals from missing var declarations

sUrl and aColumnsDefinition (lines 289-290) are assigned without var/let/const, making them implicit globals. The same issue applies to sUrlAjax and sUrlColumns in the change handler (lines 333-334). In non-strict mode this is silently allowed, but if the template is rendered more than once on the same page (e.g. two search modals open simultaneously) the globals will collide and one widget will corrupt the other's state.

Comment on lines +1093 to +1095
if (MetaModel::HasChildrenClasses($sTargetObjectClass)) {
$aEnumChildClasses = \MetaModel::EnumChildClasses('FunctionalCI');
$aChildClasses = [];
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Hardcoded FunctionalCI breaks subclass enumeration for all other target classes

Line 1093 correctly checks HasChildrenClasses($sTargetObjectClass), but line 1094 ignores $sTargetObjectClass and hardcodes 'FunctionalCI'. Whenever a user opens the search screen for any external key whose target is not FunctionalCI (e.g. Contact, Organization), the dropdown will still list FunctionalCI subclasses. The fix is MetaModel::EnumChildClasses($sTargetObjectClass).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Work made by Combodo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants