npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@smartbit4all/tree

v2.2.13

Published

**Please note the all versions from `@smartbit4all/tree^2.0.0` are not backward compatible!**

Downloads

86

Readme

Smart Tree

Please note the all versions from @smartbit4all/tree^2.0.0 are not backward compatible!

Stable versions:

References

These packages must be updated in case of a new version:

  • There are no references yet

How to use

Installation

Go to your project, open the terminal and use the following command:

npm i @smartbit4all/tree

Then import it in the AppModule:

app.module.ts:

import { SmarttreeModule } from '@smartbit4all/tree';
...
@NgModule({
    declarations: [...]
    imports: [
        ...
        SmarttreeModule,
    ],
    providers: [
        ...
        SmarttreeService,
	    TreeService
    ]
    ...
})

Usage

terminal:

>>> cd src/app
>>> mkdir services
>>> cd ./services
>>> ng g s tree

First option: Create a custom inheritance of the SmarttreeService: tree.service.ts:

@Injectable({
    providedIn: 'root'
})
export class MainTreeService extends SmarttreeService<SmartTreeModel> {
    constructor(
        private apiService: BffApiTreeService
    ) {
        super();
    }

    override async downloadTree(): Promise<SmartTreeModel> {
        const treeModel = await this.apiService.getRootNodes().toPromise();
        if (!treeModel) {
            throw new Error('TreeModel is undefined!');
        }
        return treeModel;
    }

    override async downloadChildren(parentNode: SmartTreeNode): Promise<SmartTreeModel> {
        const children = await this.apiService.getChildrenNodes(parentNode).toPromise();
        if (!children) {
            throw new Error(`Node with uri ${parentNode.identifier} does not have children.`);
        }

        return children;
    }

    override onTreeNodeClick(treeNode: SmartTreeNode): void {
        // Handle tree node click
    }

    override onTreeNodeOpen(treeNode: SmartTreeNode): void {
        if (treeNode.expanded && treeNode.childrenNodes && treeNode.childrenNodes.length) {
            treeNode.expanded = false;

            await this.apiService
                .nodeClosed({ identifier: treeNode.identifier! })
                .toPromise()
                .then(() => {
                    this.downloadTree().then((tree) => {
                        this.treeFromBackend = tree;
                        this.syncTree();
                    });
                });
            return;
        }
        await this.downloadChildren(treeNode).then((children: SmartTreeNode[]) => {
            treeNode.expanded = true;
            treeNode.children = children.nodes;

            this.syncTree();
        });
    }

    actionLabelTranslator(code: string): string {
        // Return a readable version of the code
        // Example:
        //  code: addUser
        //  return: Add user
     }

    override syncTree(): void {
        if (!this.treeFromBackend) {
            throw new Error('There is no treeFromBackend available!');
        }
        if (!this.smartTreeModel) {
            this.smartTreeModel = {
                navigationUrlsByNodeType: [],
                rootNodes: []
            };
        }

        let smartTreeNodes: SmartTreeNode[] = this.treeFromBackend.nodes.map((node: SmartTreeNode) => {
            if (node.actions && node.actions.length) {
                // The buttons are customizable
                // Example:
                let button: SmartTreeNodeButton = {
                    type: SmartTreeNodeButtonType.MENU,
                    icon: 'more_vert',
                    menuItemButtons: node.actions.map((action: UiAction) => {
                        type: SmartTreeNodeButtonType.NORMAL,
                        label: this.actionLabelTranslator(action.code),
                        callback: this.doAction.bind(this),
                        args: [action, node.identifier]
                    }),
                }
                node.button = button;
            }
        })

        // Choose from the followings:
        // #1 set up custom buttons
        this.smartTreeModel.rootNodes = this.setButtonsForTreeNodes(this.treeFromBackend.rootNodes);
        // #2 use the tree without custom buttons
        this.smartTreeModel.rootNodes = this.treeFromBackend.rootNodes;

        this.findSelected(this.smartTreeModel.rootNodes);

        this.smartTreeModelChanged.next(this.smartTreeModel);
    }

    // This function is not mandatory and also not defined in the SmarttreeService<T>!
    // The setButtonsForTreeNodes(rootNodes: SmartTreeNode[]) is just a recommendation, place it
    // into your custom TreeService or into a util file.
    setButtonsForTreeNodes(rootNodes: SmartTreeNode[]): SmartTreeNode[] {
        let smartTreeNodes: SmartTreeNode[] = [];

        rootNodes.map((node: SmartTreeNode) => {
            if (node.actions && node.actions.length) {
                // The buttons are customizable
                // Example usage:
                let button: SmartTreeNodeButton = {
                    type: SmartTreeNodeButtonType.MENU,
                    icon: 'more_vert',
                    menuItemButtons: node.actions.map((action: UiAction) => {
                        type: SmartTreeNodeButtonType.NORMAL,
                        label: this.actionLabelTranslator(action.code),
                        callback: this.doAction.bind(this),
                        args: [action, node.identifier]
                    }),
                }
                node.button = button;
            }

            if (node.childrenNodes) {
                node.childrenNodes = this.setButtonsForTreeNodes(node.childrenNodes);
            }

            smartTreeNodes.push(node);
        })

        return smartTreeNodes;
    }

    // Feel free to choose from the followings:
    // First option
    doAction(action: UiAction, identifier: string, args?: any[]): void { ... }
    // Second option
    doAction(args: any[]): void { ... }
}

Second option: Create a custom inheritance of the SmarttreeGenericService:

export class MainTreeService extends SmarttreeGenericService {
    constructor(
        viewContext: SmartViewContextService,
        treeService: TreeService,
    ) {
        super(viewContext, treeService);

        // Example data
        this.configureTree({
            pageName: Pages.Main,
            treeid: `model.tree`,
            viewContextName: Pages.VIEW_CONTEXT
        });
    }

    override getLabelByAction(action: UiAction): string {
        return getActionTranslator(action.code!).title;
    }

    override async doAction(args: any[]): Promise<void> {
        let uiAction: UiAction = args[0];
        let nodeUuid: string = args[1];
        // Do action...
    }
}

app.component.html:

<smart-tree [treeStyle]="treeStyle!" [treeService]="treeService"></smart-tree>

app.component.ts:

export class AppComponent {
    treeStyle?: TreeStyle;

    constructor(public treeService: MainTreeService) {
        // set up the BffApiTreeService (headers and url)

        this.treeService.initialize();

        this.treeStyle = {
            levelBackgroundColor: ['rgba(34, 107, 193, 0.3)', 'rgba(0, 0, 0, 0.15)'],
            activeStyle: {
                backgroundColor: '#1A5DBE',
                color: '#FFF'
            }
        };
    }

}

Version logs

@smartbit4all/tree v2.1.12

Type: Update The SmarttreeService<T> got a new property: errorMessage: string.

This error message will appear when the tree is not available.

@smartbit4all/tree v2.1.2

Type: Update

From now on the backend's responsibility to handle clicking on an already selected node.

@smartbit4all/tree v2.1.1

Type: Update

In this update a generic tree service has been added to the package.

@smartbit4all/tree v2.0.1

Type: Update

@smartbit4all/icon support.

@smartbit4all/tree v2.0.0

Type: Major update

The tree requires a new SmartTreeModel from the backend with the changed SmartTreeNodes:

export interface SmartTreeModel {
    identifier?: string;
    rootNodes?: Array<SmartTreeNode>;
}

export interface SmartTreeNode {
    identifier?: string;
    icon?: string;
    caption?: string;
    classes?: Array<string>;
    hasChildren?: boolean;
    childrenNodes?: Array<SmartTreeNode>;
    expanded?: boolean;
    selected?: boolean;
    level?: number;
    shortDescription?: string;
    nodeType?: string;
    button?: object;
    actions?: Array<UiAction>;
}

SmartreeService changes:

  • SmarttreeService<T, N> -> SmarttreeService<T>
  • The convertRootNodesToSmartTreeNodes(rootNodes: Array<N>) function has been removed.

@smartbit4all/tree v1.1.4

Type: Bugfix

Click event on customly defined button was not stopped from propagation.

@smartbit4all/tree v1.1.1

Type: Bugfix

A bug has been fixed which caused that the tree could only expand the root nodes of the tree.

@smartbit4all/tree v1.1.0

Type: Feature

This update contains two changes:

  1. SmartForm treeStyle before this update could not set the styling of the root nodes. From now the root nodes styling can be setted too.
  2. SmartTreeNode interface has been extended with a new SmartTreeNodeButton typed property. With this property you can define and add buttons to every treeNode and define the callback functions.

How to use the features of this update:

  1. TreeStyle: levelBackground is an array contains the colors in string. The index of an element refers to the level of the treeNode

    this.treeStyle = {
        levelBackgroundColor: ['rgba(34, 107, 193, 0.3)', 'rgba(0, 0, 0, 0.15)'],
            activeStyle: {
                backgroundColor: '#1A5DBE',
                color: '#FFF'
            }
        };
  2. SmartTreeNodeButton: add button property to the treeNode object. SmartTreeNodeButton has 3 different type:

  • ICON
  • MENU
  • NORMAL

@smartbit4all/tree v1.0.1

Type: Update

The package has been published.

@smartbit4all/tree v0.1.0

Type: Feature

The usage of tree has been redesigned in order to support the BFF APIs.

New things in this update:

  • SmarttreeServiceDescriptor<T, N>
  • export class SmarttreeService<T, N> implements SmarttreeServiceDescriptor<T, N>

Things that have been changed:

  • SmarttreeComponent does not require a SmarttreeModel anymore
  • SmarttreeComponent requires an inheritance of the SmarttreeService
  • Node click events are no longer handled by the component
  • Node click events can be handled manually in the inheritance of the SmarttreeService

@smartbit4all/tree v0.0.8

Type: Feature

This version contains a routing update, which allows you to navigate to a named outlet.

The change:

The navigationUrl property of the SmartTreeNodeType has changed from string to any[].

export interface SmartTreeNodeType {
    nodeType: string;
    navigationUrl: any[];
}

@smartbit4all/tree v0.0.7

Type: Bugfix

A bug has been fixed which caused routing problems while navigating with objectUri.

The change itself: this.router.navigate(['${navigationUrlByNodeType.navigationUrl}'], { queryParams: { uri: node.objectUri }});

@smartbit4all/tree v0.0.6

Type: Bugfix

The last deselected node could not be selected directly.

@smartbit4all/tree v0.0.5

Type: Bugfix

There were no option to deselect an already selected tree node.

@smartbit4all/tree v0.0.4

Type: Bugfix

Navigating on node click was not working properly.

this.router.navigateByUrl has been replaced with this.router.navigate.

@smartbit4all/tree v0.0.3

Type: Feature

The generated TreeModel has been replaced with SmartTreeModel.

The new SmartTreeModel and SmartTreeNode have new features like setting the node type and its navigation target. Also some optional fields have been changed to required ones.