ngx-los
TypeScript icon, indicating that this package has built-in type declarations

9.2.1 • Public • Published

ngx-los

npm version

Contenido

  1. Iniciando proyecto en Angular
  2. Requisitos
  3. Instalación
  4. SCSS
  5. HTML
  6. Configuración de enviroments
  7. Configuración de Angular CLI
  8. Configuración de package.json
  9. Configuración de Suscripciones de Graphql
  10. Configuración de Sentry
  11. Redux
  12. Errores de Graphql
  13. AppModule
  14. AppComponent HTML
  15. AppComponent TS

Iniciar proyecto en Angular

Para iniciar un proyecto que contenga la seguridad de LOS es necesario contar con la versión 9 de Angular, para validar que versión tienes instalada es necesario teclear en consola lo siguiente:

ng version

Se tendrá que mostrar en pantalla la versión de Angular CLI y tendrá que ser la 9 mas estable.

 
     _                      _                 ____ _     ___
    /   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
 
 
Angular CLI: 9.1.3
Node: 12.16.1
OS: win32 x64
 
Angular: 9.1.3
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes
 
Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.901.3
@angular-devkit/build-angular      0.901.3
@angular-devkit/build-ng-packagr   0.901.3
@angular-devkit/build-optimizer    0.901.3
@angular-devkit/build-webpack      0.901.3
@angular-devkit/core               9.1.3
@angular-devkit/schematics         9.1.3
@angular/cdk                       9.2.1
@angular/flex-layout               9.0.0-beta.29
@angular/material                  9.2.1
@ngtools/webpack                   9.1.3
@schematics/angular                9.1.3
@schematics/update                 0.901.3
ng-packagr                         9.1.1
rxjs                               6.5.5
typescript                         3.8.3
webpack                            4.42.0

Confirmando que tenemos la versión 9 mas estable, procedemos a crear el proyecto con el siguiente comando.

ng new [Nombre-aplicación] --style=scss

Nota: El nombre de las aplicaciones debe ser escrito en minúsculas y separadas por un signo de menos (-) en caso de ser dos palabras. Agregamos el argumento --style=scss para indicarle que queremos usar scss en nuestro proyecto

Creará la plantilla base de Angular necesaria para trabajar e instalará todos las dependencias de npm.

CREATE nombre-aplicacion/angular.json (3742 bytes)
CREATE nombre-aplicacion/package.json (1293 bytes)
CREATE nombre-aplicacion/README.md (1033 bytes)
CREATE nombre-aplicacion/tsconfig.json (489 bytes)
CREATE nombre-aplicacion/tslint.json (3125 bytes)
CREATE nombre-aplicacion/.editorconfig (274 bytes)
CREATE nombre-aplicacion/.gitignore (631 bytes)
CREATE nombre-aplicacion/browserslist (429 bytes)
CREATE nombre-aplicacion/karma.conf.js (1029 bytes)
CREATE nombre-aplicacion/tsconfig.app.json (210 bytes)
CREATE nombre-aplicacion/tsconfig.spec.json (270 bytes)
CREATE nombre-aplicacion/src/favicon.ico (948 bytes)
CREATE nombre-aplicacion/src/index.html (302 bytes)
CREATE nombre-aplicacion/src/main.ts (372 bytes)
CREATE nombre-aplicacion/src/polyfills.ts (2835 bytes)
CREATE nombre-aplicacion/src/styles.scss (80 bytes)
CREATE nombre-aplicacion/src/test.ts (753 bytes)
CREATE nombre-aplicacion/src/assets/.gitkeep (0 bytes)
CREATE nombre-aplicacion/src/environments/environment.prod.ts (51 bytes)
CREATE nombre-aplicacion/src/environments/environment.ts (662 bytes)
CREATE nombre-aplicacion/src/app/app.module.ts (314 bytes)
CREATE nombre-aplicacion/src/app/app.component.html (25725 bytes)
CREATE nombre-aplicacion/src/app/app.component.spec.ts (975 bytes)
CREATE nombre-aplicacion/src/app/app.component.ts (222 bytes)
CREATE nombre-aplicacion/src/app/app.component.scss (0 bytes)
CREATE nombre-aplicacion/e2e/protractor.conf.js (808 bytes)
CREATE nombre-aplicacion/e2e/tsconfig.json (214 bytes)
CREATE nombre-aplicacion/e2e/src/app.e2e-spec.ts (650 bytes)
CREATE nombre-aplicacion/e2e/src/app.po.ts (301 bytes)
- Installing packages...
√ Packages installed successfully.
    Successfully initialized git.

Una vez finalice con la leyenda de Successfully initialized git. tendremos listo nuestra plantilla base de Angular 9 lista para hacer la instalación de nuestra plantilla de seguridad.

Requisitos

Una vez creado el proyecto es necesario realizar la instalación de Angular Material mediante el siguiente comando.

ng add @angular/material

El proceso de instalación nos pedirá seleccionar un tema por defecto, seleccionamos Indigo/Pink. También nos preguntará si queremos establecer globalmente la tipografía de Angular Material, ademas de las animaciones del navegador, aceptamos ambas.

Skipping installation: Package already installed
? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink[ Preview: https://material.angular.io?theme=indigo-pink ]
? Set up global Angular Material typography styles? Yes
? Set up browser animations for Angular Material? Yes
 
```bash
Installing packages for tooling via npm.
Installed packages for tooling via npm.
UPDATE package.json (1357 bytes)
- Installing packages...
√ Packages installed successfully.
UPDATE src/app/app.module.ts (423 bytes)
UPDATE angular.json (3908 bytes)
UPDATE src/index.html (496 bytes)
UPDATE src/styles.scss (181 bytes)

(Opcional) Para verficar que se realizo la instalacion correctamente podemos mostrar un componente de Angular material en pantalla realizando la importacion del modulo corresponiente del componente que queremos usar, en este caso un mat-slider

import { MatSliderModule } from '@angular/material/slider';
@NgModule ({....
  imports: [...,
  MatSliderModule,
…]
})

Agregamos el tag <mat-slider> a nuestro app.component.html como sigue:

<mat-slider min="1" max="100" step="1" value="1"></mat-slider>

Ejecutamos nuestra aplicacion con el comando ng serve ingresa en el explorador a la direccio http://localhost:4200 Deberias ver el componente mat-slider en pantalla.

Instalación

Para la instalación comenzaremos con la siguiente instrucción dentro del proyecto vacío.

npm i ngx-los

SCSS

Es necesario configurar el SCSS para heredar todos los temas diseñados para la plantilla, buscamos el archivo de estilos de capas localizado en src/styles.scss y agregamos la siguiente línea.

@import "~ngx-los/theme.scss";

HTML

En la seccion <head> agregamos la siguiente linea de codigo html

<link
  href="https://fonts.googleapis.com/icon?family=Material+Icons|Assistant|ZCOOL+XiaoWei"
  rel="stylesheet"
/>

El cuerpo <body> lo dejaremos de la siguiente manera.

<body>
  <app-root>
    <div class="app-loading">
      <div class="logo"></div>
      <svg class="spinner" viewBox="25 25 50 50">
        <circle
          class="path"
          cx="50"
          cy="50"
          r="20"
          fill="none"
          stroke-width="2"
          stroke-miterlimit="10"
        />
      </svg>
    </div>
  </app-root>
</body>

Esto para dejar un "loading" cuando la pagina aun se este cargando.

Configuración de enviroments

Nota: Nota: Los archivos de ambiente deben hacer referencia al archivo package.json para realizar la importación del mismo es necesario agregar la siguiente configuracion en el archivo tsconfig.json.

{
    "compilerOptions": {
        ...
        "resolveJsonModule": true,
    }
}

Para hacer la configuración de ambientes es necesario tener la siguiente estructura en los archivos localizados en src/enviroments/enviroment.ts y src/enviroments/enviroment.prod.ts con su respectiva información de ambiente.

El archivo tiene que contener lo siguiente

import * as packagejson from "../../package.json";
export const environment = {
  production: false,
  app: {
    id: "",
    version: packagejson.version,
    commit: "{COMMIT}",
    branch: "{BRANCH}",
    clientId: "",
    clientSecret: "",
    urls: [
      {
        key: "oauth",
        value: "http://host/url_endpoint_token",
      },
      {
        key: "login",
        value: "host/url_login",
      },
    ],
    sentry: {
      dsn: "http://url_sentry",
      showReportDialog: false,
    },
  },
  template: {
    storageName: "storage-name",
    graphql: {
      uri: "host/url_endpoint_graphql",
      subscriptions: {
        enabled: true,
        uri: "ws://url_endpoint_graphql_subscriptions",
      },
    },
  },
  header: {
    title: "Titulo de Apliacion",
    theme: "nombre-tema",
    darkTheme: false,
    colorThemeVisible: true,
    fullScreenVisible: true,
    wishHappyBirthday: true,
  },
  sidemenu: {
    menuOpen: true,
    menuOpenApps: false,
    selectRoomsVisible: true,
  },
};
Llave Descripción
production Saber si el ambiente es producción
urls Contiene todas las URLs necesarias para el proyecto
urls.auth Validar credenciales de acceso
urls.auth.host URL para validar credenciales de acceso
urls.auth.path.token End point para solicitar el token de acceso
urls.auth.path.userChangePassword End point para que el usuario pueda cambiar su contraseña
app.id Id de la aplicación
app.version Version de la aplicacion obtenida del archivo package.json
app.commit Id de commit del Git (este campo lo remplaza automaticamente gitlab)
app.branch Branch de Git (este campo lo remplaza automaticamente gitlab)
app.clientId Identificador client de la aplicacion
app.clientSecret Secreto de aplicación cliente
app.urls Arreglo con las urls que usara la aplicacion
app.urls[indice].key llave para accesar al elemento en el arreglo
app.urls[indice].value valor de la url
app.sentry.dsn (Data Source Name) es la URL que representa la configuracion requerida por sentry
app.showReportDialog Indica si se debe mostrar el dialog de feedback de usuario cuando se presenta un error
template.storageName Nombre de la llave que se usara para guardar el token de la aplicacion en el storage
template.graphql.subscriptions.enabled Indica si el socket de suscripciones estara habilitado
template.graphql.subscriptions.uri url del socket de suscripciónes de graphql
template.graphql.uri url del endpoint de graphql que usará el template
header.title Titulo de la aplicación
header.theme Tema que usara por default nuestra aplicacion
header.darkTheme Indica si la aplicacion usara el tema osucuro
header.colorThemeVisible Indica si se mostrara visible la opcion para cambiar tema
header.fullScreenVisible Indica si se mostrara visible la opcion para cambiar a pantalla completa
header.wishHappyBirthday Indica si se mostrara una felicitacion cuando el empleado cumpla año
sidemenu.menuOpen Indica si al ingresar al sistema el menu se mostrara abierto
sidemenu.menuOpenApps Indica si al ingresar al sistema los menus de aplicaciones se mostraran abierto
sidemenu.selectRoomsVisible Indica si al ingresar al sistema la aplicación mostrara el combo de salas a las que se tiene acceso

Es necesario también realizar una copia del archivo src/enviroments/enviroment.prod.ts y renombrarlos de la siguiente manera src/enviroments/enviroment.dev.ts y src/enviroments/enviroment.qa.ts.

Configuración de Angular CLI

Abrimos el archivo angular.json ubicado en la raiz del proyecto, a continuación ubicamos la siguiente propiedad projects/[nombre-proyecto]/architect/build/configurations y agregamos la siguiente configuracion

"dev": {
  "fileReplacements": [
    {
      "replace": "src/environments/environment.ts",
      "with": "src/environments/environment.dev.ts"
    }
  ]
},
"qa": {
  "fileReplacements": [
    {
      "replace": "src/environments/environment.ts",
      "with": "src/environments/environment.qa.ts"
    }
  ]
}

Configuración de package.json

Abrimos el archivo package.json ubicado en la raiz del proyecto, en la propiedad scripts agregamos la siguientes tareas:

    "build:qa": "ng build --prod --configuration=qa",
    "build:dev": "ng build --prod --configuration=dev",

Una vez realizado el paso anterior podremos compilar nuestra aplicación apuntando a cualquiera de los ambientes previamente definidos, por ejemplo la siguiente instruccion de terminal compiará la aplicacion para el ambiente dev :

npm run build:dev

Suscripciónes de Graphql

En nuestro archivos environment ubicamos la propiedad template/graphql y agregamos la siguiente sub propiedad:

subscriptions: {
  enabled: true,
  uri: 'ws://url_subscriptions'
}

Sentry

En nuestro archivos environment ubicamos la propiedad template/graphql/app y agregamos la siguiente sub propiedad:

sentry: {
  dsn: 'http://url_dsn',
  showReportDialog: false,
}

Redux

Para hacer la configuración de Redux es necesario crear un archivo en la siguiente estructura src/app/app.redux.ts con el siguiente contenido

import * as Template from "ngx-los";
import * as Auth from "ngx-los-auth";
 
export const reducers = {
  auth: Auth.authReducers,
  app: Template.appReducers,
  room: Auth.roomReducers,
  header: Template.headerReducers,
  sidemenu: Template.sideMenuReducers,
  footer: Template.footerReducers,
};

Manejo de errores de graphql

Es necesario crear el siguiente archivo: src/app/app.error.ts

 
import { HttpErrorResponse } from '@angular/common/http';
import { MatSnackBar } from '@angular/material/snack-bar';
import { onError } from 'apollo-link-error';
import { GraphQLError } from 'graphql';
import { environment } from '../environments/environment';
 
const getToken = (storageName) => {
    const authStorage = localStorage.getItem(storageName);
    if (authStorage) {
        return JSON.parse(authStorage).access_token;
    }
    return '';
};
 
const hasErrorMessage = (grapqhlErrors: GraphQLError[], name: string): boolean => {
    let hasError = false;
 
    for (const error of grapqhlErrors) {
        const messageError = typeof error.message === 'object' ? (error.message as any).error : error.message;
        if (messageError === name) {
            hasError = true;
        }
    }
 
    return hasError;
};
 
const hasStatusCode = (grapqhlErrors: GraphQLError[], statusCode: number): boolean => {
    let hasError = false;
 
    for (const error of grapqhlErrors) {
        const code: number = typeof error.message === 'object' ? (error.message as any).statusCode as number : Number(error.message);
        if (code === statusCode) {
            hasError = true;
        }
    }
 
    return hasError;
};
 
const validateAuth = (graphqlErrors) => {
    let message = '';
 
    if (hasStatusCode(graphqlErrors, 401)) {
        const token = getToken('los-auth');
        if (token) {
            message = 'No tienes los permisos necesarios para hacer esta acción';
        } else {
            const hash = '/login';
            if (window.location.hash.indexOf(hash) > -1) {
            } else {
                const redirectUrl = window.location.href;
                setTimeout(() => {
                    window.location.href = `${getUrl(environment.app.urls, 'login')}?URL_Ref=${redirectUrl}`;
                }, 3000);
            }
            message = 'No has iniciado sesión, serás redireccionado en 3 segundos';
        }
    }
 
    return message;
};
 
export function errorLink(snack: MatSnackBar) {
    return onError((error) => {
        let message = '';
 
        if (error.graphQLErrors) {
            message = validateAuth(error.graphQLErrors);
        }
 
        if (error.networkError) {
            const networkError: HttpErrorResponse = error.networkError as HttpErrorResponse;
            if (networkError.status === 0) {
                message = 'Revisa la conexión con el servidor de GraphQL';
            }
            if (networkError.status === 404) {
                message = 'Servidor de GraphQL no encontrado';
            }
        }
 
        if (message) {
            snack.open(message, '', { duration: 3000, panelClass: 'snackbar-error' });
        }
    });
}
 
const getUrl = (urls: any[], key: string) => {
    const item = urls.find(x => x.key === key);
    if (item) {
        return item.value;
    } else {
        return '';
    }
};
 
// ###### Escribe aquí tus funciones
 
// Code...
 
// ######

AppModule

import { MatPasswordStrengthModule } from "@angular-material-extensions/password-strength";
import { HttpClientModule } from "@angular/common/http";
import { NgModule } from "@angular/core";
import { MatButtonModule } from "@angular/material/button";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { StoreModule } from "@ngrx/store";
import { StoreDevtoolsModule } from "@ngrx/store-devtools";
import { ApolloBoostModule } from "apollo-angular-boost";
import { LosTemplateModule } from "ngx-los";
import { LosAuthModule } from "ngx-los-auth";
import { environment } from "../environments/environment";
import { errorLink } from "../app/app.error";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { reducers } from "./app.redux";
 
const options = {
  storageName: environment.template.storageName,
  graphql: {
    uri: environment.template.graphql.uri,
    subscriptions: environment.template.graphql.subscriptions,
    errorLink,
  },
  sentry: environment.app.sentry,
};
 
@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    ApolloBoostModule,
    HttpClientModule,
    LosTemplateModule.forRoot(options),
    LosAuthModule.forRoot(options),
    StoreModule.forRoot(
      { ...reducers },
      {
        runtimeChecks: {
          strictStateImmutability: false,
          strictActionImmutability: false,
        },
      }
    ),
    StoreDevtoolsModule.instrument({
      maxAge: 25,
      logOnly: environment.production,
    }),
    MatButtonModule,
    MatPasswordStrengthModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

AppComponent HTML

Localizamos el archivo src/app/app.component.html borramos su contenido y dejamos la siguiente configuración.

<los-header></los-header>
<los-side-menu></los-side-menu>
<los-footer></los-footer>

AppComponent TS

Localizamos el archivo src/app/app.component.ts dejamos la siguiente configuración.

import { Component, OnInit } from '@angular/core';
import { LosAppService, LosHeaderService, LosSideMenuService } from 'ngx-los';
import { environment } from '../environments/environment';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
 
  constructor(
    private losAppService: LosAppService,
    private losHeaderService: LosHeaderService,
    private losSideMenuService: LosSideMenuService,
  ) { }
 
  async ngOnInit() {
    this.losAppService.set(environment.app);
    this.losHeaderService.set(environment.header);
    this.losSideMenuService.set(environment.sidemenu);
  }
}

Readme

Keywords

none

Package Sidebar

Install

npm i ngx-los

Weekly Downloads

42

Version

9.2.1

License

none

Unpacked Size

1.48 MB

Total Files

135

Last publish

Collaborators

  • moises.aleman
  • carlos.ibarra.castro