Remove tab "Data explorer" for specific device type

What product/components do you use and which version/fix level are you on?

Cumulocity IoT (backend 1014.0.172 frontend 1011.0.4)

Is your question related to the free trial, or to a production (customer) instance?

Customer license

Hi it’s Luca.

We would like to get rid of the tab “Data Explorer” for specific device type.
I tried to adapt the solution suggested here. I also tried to use the aforementioned solution in combination with this (even though it’s about tab creation).

So far, I’m able to filter out the Data Explorer tab but once it gets removed it’ll never be shown again (even though I land on a device which type should allow to use data explorer)

This is what I have

The Injectable

@Injectable()
export class ExampleTabFactory implements TabFactory {

    constructor(public router: Router, public tabService: TabsService, public inventoryService: InventoryService) { }

    private findByLabel(tabs, label) {
        return tabs.find(tab => tab.label === label);
    }

    async get() {
        const tabs: Tab[] = [];
        console.log(this.router.url);


        if(this.router.url.match(/device/g)) {

            const matcher = this.router.url.match(/(?!device\/)\d+(?=\/dashboard)/);
            let id: string;
            if(matcher != null) { id = matcher[0]; } 
            const type = await this.inventoryService.detail(id).then(device => device.data.type);
            console.log(type);
            this.tabService.items$ = this.tabService.items$.pipe(
                map(tabs => type != "dac_rfDetector" ? tabs.filter(tab => tab !== this.findByLabel(tabs, 'Data explorer')) : tabs),
                map(tabs => tabs.filter(tab => tab !== this.findByLabel(tabs, 'Location')))
            );

        }

        
        return tabs;                                     
    }
}

In the app.module.ts I added in the providers

 {
      provide: HOOK_TABS, 
      useClass: ExampleTabFactory,
      multi: true
 }

I know I’m messing up a lot of things… I need sort things down

Regards
Luca

Hi Luca,

I guess the easiest way to achieve this is by removing the default Data explorer tab and adding a custom one.

For this you will have to override the TabsService with a custom implementation that removes the default Data explorer tab:

import { Injector, Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { TabsService, OptionsService } from '@c8y/ngx-components';
import { map } from 'rxjs/operators'

@Injectable({ providedIn: 'root' }) 
export class TabsRemover extends TabsService {
    constructor(injector: Injector, router: Router, translateService: TranslateService, options: OptionsService) {
        super(injector, router, translateService, options);

        this.items$ = this.items$.pipe(
            map((tabs) => {
                return tabs.filter(tab => tab.label !== 'Data explorer' || (tab as any).custom == true)
            })
        );
    }
}

To add your own Data explorer tab, you have to implement a TabFactory:

import { Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Tab, TabFactory, ViewContext } from '@c8y/ngx-components';
import { get } from 'lodash';
import { IManagedObject } from '@c8y/client';

@Injectable({ providedIn: 'root' }) 
export class TabsFactory implements TabFactory {

    get(activatedRoute?: ActivatedRoute): Tab | Tab[] {
        const context = get(activatedRoute, 'snapshot.data.context') || get(activatedRoute, 'parent.snapshot.data.context');
        // No Tab if not navigated to device or group
        if (context !== ViewContext.Group && context !== ViewContext.Device) {
            return [];
        }
        const contextData: IManagedObject = get(activatedRoute, 'snapshot.data.contextData') || get(activatedRoute, 'parent.snapshot.data.contextData');

        // Tab for groups
        if (context === ViewContext.Group) {
            return this.getTab(this.getPath(context, contextData));
        }

        // Tab for devices of type dac_rfDetector
        if (contextData.type === 'dac_rfDetector') {
            return this.getTab(this.getPath(context, contextData));
        }

        // No Tab for normal devices
        return [];
    }

    private getTab(path: string): Tab & { custom: boolean } {
        return {
            label: 'Data explorer',
            path,
            priority: -Infinity,
            icon: 'c8y-data-explorer',
            custom: true
        }
    }

    private getPath(context: ViewContext, contextData: IManagedObject): string {
        return `${context}/data_explorer`.replace(':id', contextData.id);
    }
}

To use these factories/services you have to provide these within your module in the providers array:

providers: [
    {
      provide: TabsService,
      useExisting: TabsRemover
    },
    {
      provide: HOOK_TABS,
      useExisting: TabsFactory,
      multi: true
    }
  ]

Regards,
Tristan

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.