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

@jlguenego/angular-tools

v0.0.17

Published

<div align="center" style="text-align: center; color: green; font-weight: bold"> <h1>@jlguenego/angular-tools</h1> <img src="docs/logo.svg" height="50px"> <p>Simple and useful tools for angular apps.</p> </div>

Downloads

10

Readme

cd <angular-app>
npm i @jlguenego/angular-tools

JlgWidgetsModule

directive autofocus

Like the HTML autofocus attribute, but refresh when the component starts.

Just set the focus,

<input jlgAutofocus />

or set the focus and select all the input text.

<input jlgAutofocus="select" />

Validators

The Angular out of the box validators are great but we need more.

JlgValidators class

integer

This validator checks if the input is an integer.

new FormControl(1, [Validators.required, JlgValidators.integer]);

DuplicateAsyncValidator

Do a http request to get a JSON array response. If the response is not empty then the field is invalid. The error object is:

{
  duplicate: {
    value: control.value;
  }
}

Example:

new FormControl('', {
  validators: [
    Validators.required,
    Validators.maxLength(10),
    Validators.minLength(3),
  ],
  asyncValidators: [
    this.duplicateAsyncValidator.validate(
      (val: string) => '/api/articles?filter[name]=' + val
    ),
  ],
}),

Interceptors

Credentials

Set the withCredentials: true to all HTTP requests.

In app.module.ts set the providers as follows:

providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: CredentialsInterceptor,
      multi: true,
    },
  ],

Network

The NetworkService can work correctly only if the NetworkInterceptor is installed. This interceptor detects if the browser can access to the back-end server and set the NetworkService status$ observable accordingly.

The interceptor will set the network status to online or offline according the HTTP response.

providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: NetworkInterceptor,
      multi: true,
    },
  ],

Timeout

The TimeoutInterceptor adds a timeout on every HTTP request made with the HttpClient service.

providers: [
  {
    provide: HTTP_INTERCEPTORS,
    useClass: TimeoutInterceptor,
    multi: true,
  }
],

Services

AngularToolsConfigService

This service is only for configuring all the other tools of this library.

To change the configuration, you should subclass this service, and change only the parameters you need.

In the app.module.ts file:

providers: [
  // ...
  {
    provide: AngularToolsConfigService,
    useClass: CustomAngularToolsConfigService,
  },
],

You create a service called CustomAngularToolsConfigService like this:

import { Injectable } from "@angular/core";
import { AngularToolsConfigService } from "@jlguenego/angular-tools";

@Injectable({
  providedIn: "root",
})
export class CustomAngularToolsConfigService extends AngularToolsConfigService {
  override timeoutMsg = `Le serveur n'a pas répondu dans le délai imparti de ${this.timeoutDelay}ms.`;
}

You can see all the configuration parameters inside the AngularToolsConfigService class.

ColorSchemeService

This service tracks and controls the prefered color scheme in css, and the primary hue.

  • The theme adds a dark or light class to the body HTML element that is synchronized with the css prefered color scheme.
  • The theme adds in the local storage the user preferences about the dark or light wanted color scheme.
  • The service exposes a method toggleColorScheme to toggle the color scheme.
  • The service uses 2 favicons that must be located under assets/favicon-dark.svg and assets/favicon-light.svg.
// to change the theme from 'dark' to 'light' and vice versa.
toggleColorScheme();

CrudService

Allow to Create, Retrieve, Update, Delete documents on a REST backend.

This service is designed to work well with the crudity library. It works with Observables.

First declare a service like this:

import { Injectable } from "@angular/core";
import { CrudService } from "@jlguenego/angular-tools";
import { Article } from "../interfaces/article";

@Injectable({
  providedIn: "root",
})
export class ArticleService extends CrudService<Article> {
  getEndpoint(): string {
    return "/api/articles";
  }
}

This service exposes the following:

  • documents$: BehaviorSubject<Article[]> that reflect the list of documents
  • retrieveAll(): Observable<void>
  • add(): Observable<void>
  • remove(set: Set<T>): Observable<void>

So components can call these at will.

NetworkService

Give an observable reflecting the network status (online, offline).

TitleService

This service set the document.title (title in the browser tab) to <defaultTitle>: <pageTitle>. The pageTitle is set to the route definition under data.title.

Example:

app-routing.module.ts

{
  path: 'legal',
  component: LegalComponent,
  data: {
    title: 'Mentions Légales',
  },
},

app.component.ts

import { Component } from "@angular/core";
import { TitleService } from "@jlguenego/angular-tools";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"],
})
export class AppComponent {
  constructor(private titleService: TitleService) {
    this.titleService.setDefaultTitle("Gestion Stock");
  }
}

will set the document.title to Gestion Stock: Mentions Légales when the router navigates to /legal.

THe service take the data recursively through the children page. If the children has no data title then it tries to get the parent data title.

Module Connect

This module gives all user management tools.

interfaces

User

export interface User {
  id: string;
  displayName: string;
  email: string;
  identityProvider: string;
}

Services

Authentication

The authentication service gives an behavior subject user$ that returns undefined when no user is connected, and a user object when someone is connected.

The service has the following methods:

  • isConnected(): It gives a way to test if someone is connected to the back-end by calling an API.
  • disconnect(): disconnect a user
  • setAfterLoginRoute(): Specify the route url to go after being logged.

As you can see, you cannot connect through the authentication service. You need the Oauth2Service to connect.

Authorization

The authorization service gives access to the authorization config for a given connected user.

  • getAuthConfig(): get the user authorization config from the back-end.
  • canGoToPath(path: string): Observable<boolean>: indicates if the connected user can go the specified route path.
  • can(privilege: string): Observable<boolean>: indicates if the connected user has the given privilege.

A privilege is just a string, that the developer can configure on the back-end side, in the authorization config object in order to specify what the user can do or cannot do with the front-end. The developer can disable/enable button, hide/show text, etc. according a privilege.

OAuth2

The OAuth2 service allows to connect a user with the OAUTH2 protocol and a given identity provider (like Github, Google, Facebook, Twitter, Microsoft Azure AD, etc.)

It just gives what the front-end needs: the url config for the "Connect with ..." button/link. The rest is done by the back-end. The method is the following:

  • getAuthorizeUrl(provider: string): string: for a given provider (GITHUB, etc.), return the url that the connect button needs.
  • config$ is a BehaviorSubject that show the full configuration for all providers. If you need the provider list, look at this object.

Guards

Authentication

This guards redirects to the /user/login page if the user is not authenticated.

The guard uses the AuthenticationService.

Authorization

This guards redirect to the /403 page if the user is not authorized to go the desired route path.

The guards uses the AuthorizationService.

Example:

Tips: you should always test the authentication guard before the authorization guard.

const routes: Routes = [
  {
    path: "",
    component: StockComponent,
    canActivate: [AuthenticationGuard, AuthorizationGuard],
  },
  {
    path: "add",
    component: AddComponent,
    canActivate: [AuthenticationGuard, AuthorizationGuard],
  },
];

Module OfflineStorage

This module allows the Angular application to run HTTP request in offline mode. The offline mode is detected via the NetworkInterceptor.

In the app.module.ts declare the module with the forRoot method:

 imports: [
    BrowserModule,
    AppRoutingModule,
    // ...
    OfflineStorageModule.forRoot({ /* config */ }),
  ],

Interceptors

NetworkInterceptor

The NetworkInterceptor is already added to the interceptors when the module is declared.

Services

CacheService

Part of the OfflineStorage module.

The CacheService gives some primitives that allows a persistant cache to be used to manage progressive web request. In this library we call Progressive web request an HTTP request that has the following properties:

  • GET method:
    • online: the request is done with the back-end, then the response is stored in the front-end cache.
    • offline: the response is extracted from the front-end cache.
  • POST/PUT/PATCH/DELETE methods:
    • online: the request is done on the back-end, and normally the user does not need the response.
    • offline: the request cannot be done on the back-end, so the request is stored in the front-end cache. The stored request is called an offline order. The offline order will be executed as soons as the front-end will be able to reach the back-end (online mode). The request is also functionnaly executed, but with the front-end cache.

The cache service gives the way to load image that are stored in the cache into an image HTML element <img>. The method is cacheService.loadImage(img: HTMLImageElement, url: string).

NetworkService

The network service exposes an observable that reflects the network status (online, or offline) in real time.

Authors

Jean-Louis GUENEGO [email protected]