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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@visma-swno/module-navigator

v1.0.30

Published

A module navigator for Visma Nordics

Downloads

440

Readme

VSN Module Switcher

The VSN Module Switcher (Module Navigator) is a Web Component designed for Visma Nordic applications to provide a consistent navigation experience across different services. It allows users to easily switch between various applications while maintaining a cohesive user experience.

Table of Contents

  1. Package Installation
  2. Configuration
  3. Authentication Integration
  4. Static Application Data
  5. Dynamic Application Data
  6. CI/CD Integration

Package Installation

Install the module navigator component in your project:

npm install @visma-swno/module-navigator --save

Configuration

Basic Implementation

First, include the script reference in your HTML file:

<script type="module" src="node_modules/@visma-swno/module-navigator/dist/assets/index.js"></script>

Then, add the component in your HTML, typically in a header or navigation section:

<vsn-module-navigator 
  application-name="YourAppName" 
  locale="en-US">
</vsn-module-navigator>

If using an Angular application, add the script reference in your angular.json:

"scripts": [
  "@visma-swno/module-navigator/dist/assets/index.js"
],

For Angular components, you'll also need to add CUSTOM_ELEMENTS_SCHEMA to your component or module:

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss'],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]  // Required for custom elements
})

Component Attributes

The component supports the following attributes:

| Attribute | Type | Default | Description | |------------------------|----------|---------|--------------------------------------------------------------| | application-name | String | "" | Name of the current application | | application-name-alt | String | "" | Secondary/alternative name of the current application (e.g., Admin - Business Unit) | | locale | String | "en-US" | Locale for the component UI (supported: en-US, en-GB, nb-NO, sv-SE, fi-FI, da-DK) | | applications | Array/JSON String | [] | List of application modules to display in the menu. Note: This attribute is for testing and transitional integration purposes only. It will be deprecated in future versions as the component is designed to retrieve consistent module data across all applications via its API endpoints using provided access token. |

CSS Variables

You can customize the appearance of the component using CSS variables:

vsn-module-navigator {
  /* Font styling */
  --vsn-module-menu-font-family: Inter, ui-sans-serif, system-ui, sans-serif;
  --vsn-module-menu-font-feature-settings: "liga" 1, "calt" 1;
  
  /* Scrollbar styling - works in both webkit browsers and Firefox */
  --vsn-module-menu-scrollbar-width: 4px;
  --vsn-module-menu-scrollbar-thumb-color: #b9b9b9;
  --vsn-module-menu-scrollbar-track-color: transparent;
}

For Angular applications that have global scrollbar styling, you might need to add higher-specificity rules:

/* In your global Angular styles */
vsn-module-navigator::part(modules-menu) {
  scrollbar-width: thin !important;
  scrollbar-color: #b9b9b9 transparent !important;
}

Authentication Integration

The component requires an access token to fetch available applications. It emits a request-token event that your application must handle.

Authentication with Local Token

If you store your authentication token in sessionStorage or localStorage:

document.querySelector('vsn-module-navigator')?.addEventListener('request-token', (event) => {
  const token = sessionStorage.getItem('accessToken');
  if (event.detail && typeof event.detail.callback === 'function') {
    event.detail.callback(token);
  }
});

In an Angular component:

ngOnInit() {
  this.elementRef.nativeElement.addEventListener('request-token', this.handleTokenRequest.bind(this));
}

private handleTokenRequest(event: Event) {
  // Access the callback function passed via the event detail
  const customEvent = event as CustomEvent;
  const { callback } = customEvent.detail;

  const tokenStr = sessionStorage.getItem('tokenResponse');
  if (tokenStr) {
    const token = JSON.parse(tokenStr);
    const accessToken = token.access_token;
    callback(accessToken);
  }
}

Authentication with API

If you need to fetch the token from an API:

document.addEventListener('request-token', async (event) => {
  try {
    const response = await fetch('your-token-endpoint');
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    const token = data.accessToken;
    
    if (event.detail && typeof event.detail.callback === 'function') {
      event.detail.callback(token);
    }
  } catch (error) {
    console.error('Token fetch error:', error);
  }
});

Static Application Data

Important: Static application data through the applications attribute is intended for transitional integration and testing purposes only. In production environments, the component should fetch application data through its API endpoints using an access token to ensure consistency across all Visma applications.

During the integration phase, you can provide a static list of applications directly through the applications attribute:

const appModules = [
  {
    "id": "home-app",
    "name": "Home",
    "url": "https://example.com/home",
  },
  {
    "id": "admin-app",
    "name": "Admin",
    "url": "https://example.com/admin",
  }
];

// JSON stringify for attribute setting
document.querySelector('vsn-module-navigator')
  .setAttribute('applications', JSON.stringify(appModules));

// Or direct object assignment if using framework bindings
// component.applications = appModules;

Each application object should have the following properties:

  • id: Unique identifier for the application
  • name: Display name of the application
  • url: URL to navigate to when clicking the application

Dynamic Application Data

The recommended approach for production environments is to provide an access token to the component, which will then fetch a consistent set of applications from the API endpoints. This ensures all Visma applications display the same navigation menu.

When an access token is provided (via the request-token event handler), the component will automatically fetch applications from the API endpoint:

GET: {api-base-url}/v1/me/applications

The API base URL is determined automatically based on your hostname:

  • localhost: "http://localhost:3000"
  • .int.: "https://gw.access-management.api.aws.int.test.visma.net"
  • .stag.: "https://gw.access-management.api.odp.aws.stag.visma.net"
  • production: "https://gw.access-management.api.odp.aws.visma.net"

The API should return an array of application objects with the same format described in the Static Application Data section. This eliminates the need to manually maintain the application list in each individual application, ensuring a consistent user experience across the Visma application ecosystem.