Skip to content

Customizing Node Processing

The customNodeProcessingService option allows you to intercept and modify individual Luigi Nodes dynamically before they are rendered in the navigation tree. This is specifically useful for implementing custom access policies, dynamic labeling based on context, or modifying node properties (like icons or descriptions) on the fly.

CustomNodeProcessingService Interface

The CustomNodeProcessingService interface requires a single asynchronous method. It receives the current navigation context and the specific node being processed.

ts
import { Context } from '@luigi-project/client';
import { LuigiNode } from '@openmfp/portal-ui-lib';

export interface CustomNodeProcessingService {
    /**
     * @param ctx The current Luigi context.
     * @param node The node currently being processed by the library.
     * @returns A Promise resolving to the modified (or original) LuigiNode.
     */
    processNode(ctx: Context, node: LuigiNode): Promise<LuigiNode>;
}

Provide your implemented service

In this example, the service checks for a custom property requiredPermission in the node context. If the user doesn't have that permission (based on the global context), the node is hidden. It also demonstrates how to dynamically update a node's label.

ts
import { Injectable } from '@angular/core';
import { Context } from '@luigi-project/client';
import { CustomNodeProcessingService, LuigiNode } from '@openmfp/portal-ui-lib';

@Injectable({
    providedIn: 'root',
})
export class CustomNodeProcessingServiceImpl implements CustomNodeProcessingService {

    public async processNode(ctx: Context, node: LuigiNode): Promise<LuigiNode> {
        // 1. Implementation of a custom access policy
        if (node.context?.requiredPermission) {
            const userPermissions = ctx.userPermissions || [];
            if (!userPermissions.includes(node.context.requiredPermission)) {
                node.hideFromNav = true;
            }
        }

        // 2. Dynamic modification of node properties
        if (node.pathSegment === 'project-details' && ctx.projectName) {
            node.label = `Project: ${ctx.projectName}`;
        }

        // Return the potentially modified node
        return node;
    }
}

Registering the service during application bootstrap

ts
import { bootstrapApplication } from '@angular/platform-browser';
import {
    PortalComponent,
    PortalOptions,
    providePortal,
} from '@openmfp/portal-ui-lib';
import { CustomNodeProcessingServiceImpl } from './custom-node-processing.service';

const portalOptions: PortalOptions = {
    // Reference the service class here.
    customNodeProcessingService: CustomNodeProcessingServiceImpl,
    // ... other portal options
};

bootstrapApplication(PortalComponent, {
    providers: [providePortal(portalOptions)],
}).catch((err) => console.error(err));
EU and German government funding logos

Funded by the European Union – NextGenerationEU.

The views and opinions expressed are solely those of the author(s) and do not necessarily reflect the views of the European Union or the European Commission. Neither the European Union nor the European Commission can be held responsible for them.