MATERIAL LOGIN CARD
1. Antes de agregar el componente login necesitaremos de crear 1
directiva, en la siguiente ruta src/app/core/directives con el siguiente
comando:
$ ng g d core/directives/responsive-rows --spec=false
Angular 9
$ ng g d core/directives/responsive-rows --skipTests
Angular 9
$ ng g d core/directives/responsive-rows --skipTests
A) responsive-rows.directive.ts
Esta directiva nos permitira crear grillas para
formularios similar al bootstrap.
Previamente a moficar el codigo necesitamos instalar
una libreria adicional:
$ npm install --save @angular/flex-layout@7.0.0-beta.24
Angular 9
$ npm install --save @angular/flex-layout@9.0.0-beta.29
Angular 9
$ npm install --save @angular/flex-layout@9.0.0-beta.29
import { Directive, OnInit, Input } from '@angular/core';
import { MatGridTile } from '@angular/material';
import { MediaObserver, MediaChange } from '@angular/flex-layout';
export interface IResponsiveRowsMap {
xs?: number;
sm?: number;
md?: number;
lg?: number;
xl?: number;
}
@Directive({
selector: '[ResponsiveRows]'
})
export class ResponsiveRowsDirective implements OnInit {
private countBySize: IResponsiveRowsMap = { xs: 2, sm: 2, md: 4, lg: 6, xl: 8 };
public get colspan(): IResponsiveRowsMap {
return this.countBySize;
}
@Input('ResponsiveRows')
public set colspan(map: IResponsiveRowsMap) {
if (map && ('object' === (typeof map))) {
this.countBySize = map;
}
}
public constructor(private grid: MatGridTile, private serviceMedia: MediaObserver) {
this.initializeRowsCount();
}
public ngOnInit(): void {
this.initializeRowsCount();
this.serviceMedia.media$.subscribe((changes: MediaChange) => {
this.grid.colspan = this.countBySize[changes.mqAlias]
});
}
private initializeRowsCount(): void {
Object.keys(this.countBySize).some(
(mqAlias: string): boolean => {
const isActive = this.serviceMedia.isActive(mqAlias);
if (isActive) {
this.grid.colspan = this.countBySize[mqAlias];
}
return isActive;
});
}
}
2. Seguido necesitaremos crear una clase, en la siguiente ruta
src/app/core/model con el siguiente comando:
$ ng g i core/model/usuario
A) usuario.model.ts
Esta clase nos permitira guardar los datos de
usuario y contraseña para la autenticacion.
export class Usuario {
usuario: string;
contrasenia: string;
}
3. Luego necesitaremos crear 2 servicios, en la siguiente ruta
src/app/core/services con el siguiente comando:
$ ng g s core/services/usuario --spec=false
$ ng g s core/services/validation --spec=false
A) usuario.service.ts
Este servicio nos permitira mantener los datos en
la sesion:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class UsuarioService {
id: number;
usuario: string;
contrasenia: string;
idCargo: number;
cargo: string;
idDependencia: number;
dependencia: string;
constructor() { }
set setId(id: number) { this.id = id; }
set setUsuario(usuario: string) { this.usuario = usuario; }
set setContrasenia(contrasenia: string) { this.contrasenia = contrasenia; }
set setIdCargo(idCargo: number) { this.idCargo = idCargo; }
set setCargo(cargo: string) { this.cargo = cargo; }
set setIdDependencia(idDependencia: number) { this.idDependencia = idDependencia; }
set setDependencia(dependencia: string) { this.dependencia = dependencia; }
get getId() { return this.id; }
get getUsuario() { return this.usuario; }
get getContrasenia() { return this.contrasenia; }
get getIdCargo() { return this.idCargo; }
get getCargo() { return this.cargo; }
get getIdDependencia() { return this.idDependencia; }
get getDependencia() { return this.dependencia; }
public limpiarRegistro(): void {
this.id = null;
this.usuario = null;
this.contrasenia = null;
this.idCargo = null;
this.cargo = null;
this.idDependencia = null;
this.dependencia = null;
return null;
}
}
B) validation.service.ts
Este servicio nos permitir hacer operaciones de
validacion de formularios.
import { Injectable } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Injectable({
providedIn: 'root'
})
export class ValidationService {
constructor() { }
getValidationErrors(group: FormGroup, messages: any, formErrors: any, type: boolean): void {
Object.keys(group.controls).forEach((key: string) => {
let abstractControl = group.get(key);
if (abstractControl instanceof FormGroup) {
this.getValidationErrors(abstractControl, messages[key], formErrors[key], type);
} else {
if (type) {
abstractControl.markAsTouched();
}
formErrors[key] = '';
if (abstractControl && abstractControl.invalid && (abstractControl.touched || abstractControl.dirty)) {
let msg = messages[key];
for (let errorKey in abstractControl.errors) {
if (errorKey) {
formErrors[key] += msg[errorKey] + ' ';
}
}
}
}
});
}
setAsUntoched(group: FormGroup, formErrors: any, exclusions?: string[]): void {
group.markAsUntouched();
Object.keys(group.controls).forEach((key: string) => {
let abstractControl = group.get(key);
if (abstractControl instanceof FormGroup) {
this.setAsUntoched(abstractControl, formErrors[key]);
} else {
if (typeof exclusions != 'undefined') {
let ex = exclusions.find(el => el == key);
if (!ex) {
abstractControl.setValue('');
abstractControl.markAsUntouched();
}
} else {
abstractControl.setValue('');
abstractControl.markAsUntouched();
}
formErrors[key] = '';
}
});
}
disableControls(group: FormGroup, exclusions?: [string]): void {
Object.keys(group.controls).forEach((key: string) => {
let abstractControl = group.get(key);
if (abstractControl instanceof FormGroup) {
this.disableControls(abstractControl, exclusions);
} else {
if (typeof exclusions != 'undefined') {
let ex = exclusions.find(el => el == key);
if (!ex) {
abstractControl.disable()
}
} else {
abstractControl.disable();
}
}
});
}
removeErrors(group: FormGroup, exclusions?: [string]): void {
Object.keys(group.controls).forEach((key: string) => {
let abstractControl = group.get(key);
if (abstractControl instanceof FormGroup) {
this.removeErrors(abstractControl, exclusions);
} else {
if (typeof exclusions != 'undefined') {
let ex = exclusions.find(el => el == key);
if (!ex) {
abstractControl.setErrors(null)
}
} else {
abstractControl.setErrors(null);
}
}
});
}
}
4. Para agregar un login es necesario crear un componente con nombre
login en la siguiente ruta src/app/modules/sesion/comonents/login
A) login.component.html
<mat-card class="login-card">
<mat-card-header>
<mat-card-title>
<div mat-card-avatar class="login-card-header-image"></div>
</mat-card-title>
</mat-card-header>
<mat-card-content>
<h3>Ingresa a tu cuenta</h3>
<form [formGroup]="formularioGrp">
<mat-grid-list cols="12" rowHeight="50px">
<mat-grid-tile [ResponsiveRows]="{xs:12, sm:12, md:12, lg:12, xl:12}">
<mat-form-field>
<input matInput formControlName="usuario" type="text" id="usuario" placeholder="Inserte su ID de usuario"
[ngClass]="{'is-invalid': formErrors.usuario}" (keyup.enter)="autenticar()">
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile [ResponsiveRows]="{xs:12, sm:12, md:12, lg:12, xl:12}">
<mat-form-field>
<input matInput formControlName="contrasenia" type="password" id="contrasenia"
placeholder="Inserte su contraseña" [ngClass]="{'is-invalid': formErrors.contrasenia}"
(keyup.enter)="autenticar()">
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile [ResponsiveRows]="{xs:12, sm:12, md:12, lg:12, xl:12}">
<mat-checkbox>Recordar</mat-checkbox>
</mat-grid-tile>
<mat-grid-tile [ResponsiveRows]="{xs:12, sm:12, md:12, lg:12, xl:12}">
<button mat-raised-button color="primary" (click)="autenticar()">Ingresar</button>
</mat-grid-tile>
</mat-grid-list>
</form>
</mat-card-content>
</mat-card>
B) login.component.ts
import { Component, OnInit, Inject } from '@angular/core';
import { Usuario } from 'src/app/core/model/usuario.model';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { UsuarioService } from 'src/app/core/services/usuario.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
usuario: Usuario = new Usuario();
formularioGrp: FormGroup;
messages = {
'usuario': {
'required': 'El campo es obligatorio'
},
'contrasenia': {
'required': 'El campo es obligatorio'
}
};
formErrors = {
'usuario': '',
'contrasenia': '',
};
constructor(private fb: FormBuilder, private router: Router, @Inject(UsuarioService) private user: UsuarioService) { }
ngOnInit() {
this.formularioGrp = this.fb.group({
usuario: ['', [Validators.required]],
contrasenia: ['', [Validators.required]],
});
this.formularioGrp.get('usuario').setValue('admin');
this.formularioGrp.get('contrasenia').setValue('1234');
}
autenticar() {
this.usuario.usuario = this.formularioGrp.get('usuario').value;
this.usuario.contrasenia = this.formularioGrp.get('contrasenia').value;
localStorage.setItem('user', JSON.stringify(this.usuario));
this.user.setId = 1;
this.user.setUsuario = this.usuario.usuario;
this.user.setContrasenia = this.usuario.contrasenia;
this.user.setCargo = 'TECNICO INFORMATICO';
this.user.setDependencia = 'UTI';
this.router.navigate(['/intranet/home']);
}
}
C) login.component.scss
.login-card {
margin: 10% auto 0%;
width: 300px;
max-width: 300px;
text-align: center;
box-shadow: 0px 0px 10px 2px #888888;
mat-card-header {
display: flex !important;
justify-content: center !important;
}
form {
mat-grid-tile {
button {
width: 90%;
}
}
}
}
::ng-deep .login-card-header-image {
background-image: url("../../../../../assets/images/icons/icono-perficon.png");
background-size: cover;
height: 60px !important;
width: 60px !important;
}
mat-checkbox {
padding-left: 10px;
}
5. Finalmente agregamos algunos componenentes necesarios en el archivo
material.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatButtonModule, MatToolbarModule, MatSidenavModule, MatMenuModule, MatCardModule, MatGridListModule, MatInputModule, MatListModule, MatCheckboxModule } from '@angular/material';
import { ResponsiveRowsDirective } from '../core/directives/responsive-rows.directive';
import { UppercasedDirective } from '../core/directives/uppercased.directive';
import { ReactiveFormsModule } from '@angular/forms';
import { LayoutModule } from '@angular/cdk/layout';
@NgModule({
declarations: [
ResponsiveRowsDirective,
UppercasedDirective,
],
imports: [
ReactiveFormsModule,
CommonModule,
LayoutModule,
MatButtonModule,
MatToolbarModule,
MatSidenavModule,
MatMenuModule,
MatCardModule,
MatGridListModule,
MatListModule,
MatInputModule,
MatCheckboxModule,
],
exports: [
ReactiveFormsModule,
LayoutModule,
MatButtonModule,
MatToolbarModule,
MatSidenavModule,
MatMenuModule,
MatCardModule,
MatGridListModule,
MatListModule,
MatInputModule,
MatCheckboxModule,
ResponsiveRowsDirective,
UppercasedDirective,
]
})
export class MaterialModule { }
0 Comentarios