9.2.1 • Published 4 years ago

ngx-los v9.2.1

Weekly downloads
156
License
-
Repository
-
Last release
4 years ago

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,
  },
};
LlaveDescripción
productionSaber si el ambiente es producción
urlsContiene todas las URLs necesarias para el proyecto
urls.authValidar credenciales de acceso
urls.auth.hostURL para validar credenciales de acceso
urls.auth.path.tokenEnd point para solicitar el token de acceso
urls.auth.path.userChangePasswordEnd point para que el usuario pueda cambiar su contraseña
app.idId de la aplicación
app.versionVersion de la aplicacion obtenida del archivo package.json
app.commitId de commit del Git (este campo lo remplaza automaticamente gitlab)
app.branchBranch de Git (este campo lo remplaza automaticamente gitlab)
app.clientIdIdentificador client de la aplicacion
app.clientSecretSecreto de aplicación cliente
app.urlsArreglo con las urls que usara la aplicacion
app.urls[indice].keyllave para accesar al elemento en el arreglo
app.urls[indice].valuevalor de la url
app.sentry.dsn(Data Source Name) es la URL que representa la configuracion requerida por sentry
app.showReportDialogIndica si se debe mostrar el dialog de feedback de usuario cuando se presenta un error
template.storageNameNombre de la llave que se usara para guardar el token de la aplicacion en el storage
template.graphql.subscriptions.enabledIndica si el socket de suscripciones estara habilitado
template.graphql.subscriptions.uriurl del socket de suscripciónes de graphql
template.graphql.uriurl del endpoint de graphql que usará el template
header.titleTitulo de la aplicación
header.themeTema que usara por default nuestra aplicacion
header.darkThemeIndica si la aplicacion usara el tema osucuro
header.colorThemeVisibleIndica si se mostrara visible la opcion para cambiar tema
header.fullScreenVisibleIndica si se mostrara visible la opcion para cambiar a pantalla completa
header.wishHappyBirthdayIndica si se mostrara una felicitacion cuando el empleado cumpla año
sidemenu.menuOpenIndica si al ingresar al sistema el menu se mostrara abierto
sidemenu.menuOpenAppsIndica si al ingresar al sistema los menus de aplicaciones se mostraran abierto
sidemenu.selectRoomsVisibleIndica 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);
  }
}
9.2.1

4 years ago

9.2.0

4 years ago

9.1.0

4 years ago

9.0.3

4 years ago

9.0.2

4 years ago

9.0.1

4 years ago

9.0.0

4 years ago

8.1.11

4 years ago

8.1.10

4 years ago

8.1.9

4 years ago

8.1.8

4 years ago

8.1.7

4 years ago

8.1.6

4 years ago

8.1.5

4 years ago

8.1.4

4 years ago

8.1.3

4 years ago

8.1.2

4 years ago

8.1.1

4 years ago

8.1.0

4 years ago

8.0.7

5 years ago

8.0.6

5 years ago

8.0.5

5 years ago

8.0.4

5 years ago

8.0.3

5 years ago

8.0.2

5 years ago

8.0.1

5 years ago

8.0.0

5 years ago

0.1.1

5 years ago

0.1.0

5 years ago

0.0.9

5 years ago

0.0.8

5 years ago

0.0.7

5 years ago

0.0.6

5 years ago

0.0.5

5 years ago

0.0.4

5 years ago

0.0.3

5 years ago

0.0.2

5 years ago

0.0.1

5 years ago