Skip to content

Aplicación Web ElectroThings con Angular, Highcharts, Bootstrap, Spring Boot, Spring MVC, , Spring Security, JWT, SpringMongoDB, Lombok, Log4J, Git, MongoDB. y Otras Tecnologías

License

Notifications You must be signed in to change notification settings

andresWeitzel/AppElectroThings_Angular_SpringBoot_MongoDB

Repository files navigation

AppElectroThings_Angular_SpringBoot_MongoDB.

Aplicación ElectroThings para la Gestión de Productos Electrónicos implementada con HTML5, CSS3, SCSS, Angular, Bootstrap, Highchart, Spring-Boot, Spring Security, Spring MVC, Microservicios, SpringFox, Swagger UI, Git, DBeaver, PgAdmin, PostgreSQL y Otras Tecnologías.


Índice 📜

Ver

Sección 1) Descripción, Tecnologías y Dependencias

Sección 2) Endpoints y Recursos

Sección 3) Prueba de Funcionalidad y Referencias



Sección 1) Descripción, Tecnologías y Dependencias

1.0) Descripción 🔝

Ver
  • Esta aplicación ha sido desarrollada para la gestión de productos de electrónica general ( televisores, notebooks, accesorios, etc). También se ha pensado originalmente desarrollar una sección para la gestión de usuarios, pero esta funcionalidad se aplica desde el backend (Api), utilizando postman o swagger ui, al implementar un modelo de negocios únicamente para un MicroFrontEnd se deberá desarrollar otra app para la gestión de dichos usuarios.
  • Como sistema de seguridad para manejo de recursos de la app se usa Spring Security y JWT. Las Operaciones Transaccionales fueron modificadas para que solamente los administradores del sistema tengan acceso, los usuarios convencionales solamente podrán visualizar los productos y filtrar búsquedas acerca de estos según el requerimiento deseado.
  • Todos los formularios aplican validaciones de carácteres, longitudes, tamaños, valores numéricos, valores mal formados, email, contraseña, url de imágenes, etc.
  • Se implementa Paginación Completa.
  • Se aplican dos filtros de búsqueda, uno para productos de forma genérica y otro según el campo deseado, permitiendo coincidencias de carácteres y palabras.
  • Para la experiencia de usuario se utiliza Popupts, Loaders, Angular Material, Etc.
  • Es posible descargar el Listado de Productos Paginado en formato xlsx(excel), csv y pdf.
  • Todas las Páginas de la Aplicación poseen modals de Ayuda.
  • Entre Otros Recursos Disponibles.
  • Aclaración : Este Microfrontend no es responsive. El enfoque es la funcionalidad de la aplicación, la maquetación es totalmente aplicable en relación al tiempo de disponibilidad que se emplee.
  • Repositorio ApiRest_ElectroThingsV1
  • Repositorio db_ElectroThings_MongoDB
  • PlayList del Proyecto

1.1) Ejecución del Proyecto 🔝

Ver
  • Crear un entorno de trabajo a través de algún IDE
  • Clonar el Proyecto (git clone https://github.com/andresWeitzel/AppElectroThings_Angular_SpringBoot_MongoDB)
  • Posicionarnos sobre el proyecto
    • cd proyecto
  • Dentro del directorio instalar todos los plugins implementados
    • npm i
  • Ejecutar la base de datos
  • Ejecutar la api rest
  • Ejecutar el proyecto
    • ng serve

1.2) Tecnologías 🔝

Ver
Tecnologías FRONTEND Versión Finalidad
HTML 5.0 Lenguaje de Hipertexto
Css 3.0 Lenguaje de hojas de estilo para presentación de documentos.
Scss 1.57 Preprocesador de css.
Angular 13.3.0 FrameWork Web Desarrollo de Apps con TypeScript
Angular CLI 13.3.0 Herramienta de Angular para depurar, crear, publicar, etc Apps
Angular Material 13.3.9 UI librería de componentes
ng-angular-popup 0.1.2 Mensajes emergentes personalizados
ngx-ui-loader 13.0.0 Animaciones de carga
Highchart 13.3.9 Librería para la generación de gráficos
Bootstrap 5.1 FrameWork Web Diseño y Desarrollo de Apps
Visual Studio Code 1.51.1 Entorno de Desarrollo
Tecnologías BACKEND Versión Finalidad
Java 12.0.2 JDK
Spring Tool Suite 4 4.9.0 IDE
Spring Boot 2.6.4 Framework
Spring Boot Data JPA 2.6.3 Mapeo de objetos y persistencia en la db
Spring Security 2.6.7 Servicios de Seguridad
JSON Web Token 0.9.1 Creación de tokens de acceso
Maven 4.0.0 Gestor de Proyectos
Postman 9.4.1 Test de Apis
Lombok 1.18.22 Automatización de Código
Open-Api 1.6.4 Documentación de la Api
UI Swagger 1.6.4 Visualización y Gestión de la Api
GNU bash / Terminal 4.4.23 Bash / Terminal para el manejo e implementación de Git integrado al Spring Tool Suite
Git 2.29.1 Control de Versiones
Tecnologías DATABASE Versión Finalidad
MongoDB 5.0 Base de Datos
MongoDB Compass 1.31.2 Gestor para MongoDB


Sección 2) EndPoints y Recursos

2.0) EndPoints 🔝

Ver

Autenticación

Gestión de Productos

Administración de Usuarios


2.1) Recursos y Servicios 🔝

Ver

Login

Index app

Signin

Index app

Inicio

Index app

Listado de Productos Electrónicos Tabla

Index app

Index app

Listado de Productos Electrónicos Cards

Index app

Gráficos de Barra para Stock de Productos por Categoría.

Index app

Novedades de Productos

Index app

Acerca de Productos

Index app


Documentación Gráfica Acotada por razones de simplificación de documentación. Visualizar los videos desde la PlayList acerca de las Pruebas de Funcionalidad de la aplicación.



Sección 3) Prueba de Funcionalidad y Referencias

3.0) Prueba de Funcionalidad 🔝

Ver

Comprobación login de usuarios (Ver)

Alt text

Comprobación signin de usuarios (Ver)

Alt text

Comprobación token y refresh token (Ver)

Alt text

Comprobación listado de productos (Ver)

Alt text

Comprobación búsqueda de productos con filtro (Ver)

Alt text


Se resume documentación gráfica. Visualizar Playlist del proyecto para más funcionalidades


3.1) Referencias 🔝

Ver

Documentación No Oficial Recomendada


Documentación Oficial/No Oficial Librerías Frontend





Siguiente sección en proceso de actualización

Ver

Documentación y Guía del Proyecto

(Esta Documentación que Desarrollé es para la Creación, Configuración, Posibles Errores, Despliegue, etc de la Aplicación con Angular, Firebase y Bootstrap. Recomiendo Leerla y Realizar todo paso a paso como se indica en la misma).


Indice

Sección 1) Configurar el Ambiente y el Espacio de Trabajo Local

Sección 2) Manejo e Implementación de Bootstrap

Sección 3) Módulos y Componentes de Angular

Sección 4) Creación y Configuración de Páginas Web y Servicios

Sección 5) Desarrollo de las Páginas Web


Sección 1) Configurar el Ambiente y el Espacio de Trabajo Local


Paso 1) Instalación de Angular

(Primeramente deberás tener instalado VS Code, configurado a gusto y saber/manejar de Forma Básica una CLI(Terminal-Interfaz de Línea de Comandos o como se le quiera decir. Te recomiendo que consideres la CLI Bash/Shell de Linux)).


  • Para usar angular se necesita instalar Node.js.
  • Abrír el Archivo Descargado e Instalar(Siguiente y Siguiente...).
  • Angular Depende del 'npm package manager' de Node.js, cuando se descarga este, viene todo incluido.
  • Comprobamos la Instalación de Angular desde una CLI.
    • --> Abrir el cmd en Windows, bash-shell en Linux, o terminal en VS Code
    • --> escribir npm -v.
    • --> Si no surgió ningún error te debería aparecer la Versión de Node.js, ya está instalado Node.js

Paso 2) Instalación de la CLI de Angular

(La CLI de Angular nos ayudará a Crear Proyectos, generar Código, depurar, etc).


  • Teniendo Instalado el Sistema de Gestión de Angular en Nuestra Computadora, trabajaremos todo desde la CLI
  • Abrir el cmd en Windows, bash-shell en Linux, o terminal en VS Code y escribir npm install -g @angular/cli.
  • Si se instalo correctamente la cli de Angular, escribiendo ng help se debería poder visualizar la lista de comandos y la versión.(Paciencia porque las ejecuciones de angular son lerdas).

Paso 3) Creación de una Aplicación Web con Angular.

(Este es uno de los pasos más tediosos ya que para la creación de una App en Angular viene intrínsico el proceso de construcción de Paquetes, creación de Módulos, Deploy de la App en el Servidor de Angular, etc).


  • Primeramente deberás ubicarte en la carpeta que deseas construir la app con Angular.
    • --> En mi caso crearé la app en mi ruta ANGULAR/Proyectos2021
    • --> Abrimos una Nueva Terminal en VS Code y
    • --> Escribimos ng new 'nombreDelProyectoSinComillasTodoSeguido' en mi caso ng new 'crudAngularFirebaseBootstrap'
    • --> Seguidamente nos pregunta si queremos agregar una routing, escribimos yes o y
    • --> Ahora cual Lenguaje de Maquetación queremos, elegimos CSS.
    • --> Esperamos a que se cree el Proyecto(este paso lleva tiempo).

Paso 4) Deployar la Aplicación con Angular

(La CLI de Angular incluye un Servidor Local )


  • Nos posicionamos sobre la carpeta creada cd crudAngularFirebaseBootstrap
    • --> Escribimos por consola ng serve --open
    • --> Si nos preguntan algo escribimos yes o y
    • --> El último paso suele tardar un poco
    • --> Si se abre el navegador con la página de inicio de Angular está todo Correcto.


Sección 2) Manejo e Implementación de Bootstrap


Paso 5) Implementar Bootstrap con Angular

( Bootstrap es un Framework Web que nos permite realizar aplicaciones de forma más rápidas y con estructuras modernas. Para este caso no vamos a instalar los paquetes de bootstrap, sino incluir CDN's, osea linkear servidores de boostrap para trabajar con sus librerías )


5.1) Incluir el CSS desde el CDN de Bootstrap en el index.html

<!--CSS BOOTSTRAP-->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  • Guardamos cambios (Ctrl+s)

5.2) Incluir JS desde el CDN de Bootstrap en el index.html

<!--JS Bootstrap-->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
  • Guardamos cambios (Ctrl+s)
  • Si visualizas nuevamente la aplicación se podrá notar la diferencia de tamaños y colores, tenemos implementado Bootstrap

Sección 3) Módulos y Componentes de Angular


Paso 6) Generación y Configuración de Componentes y Módulos con Angular

(Todos los componentes y Módulos de Angular están dentro de sus respectivos directorios o carpetas(en este caso el directorio es app, que a su vez es el módulo padre), vamos a realizar lo mismo con Boostrap , crearemos los componentes y módulos y trabajaremos de forma modularizada, respetando el Patrón de Angular)

6.1) Creación del componente y módulo Navbar

  • Abrimos una nueva terminal
    • --> View -> Terminal
  • Nos posicionamos sobre el proyecto
    • --> Escribimos cd crud AngularFirebaseBootstrap
  • Creamos el Nuevo Componente modularizado
    • --> Escribimos ng generate component components/navbar --module app o ng g c components/navbar --module app
  • Si desplegas componentes, se debería haber generado el componente, junto con sus archivos
  • Ahora creamos el módulo interno de configuración del navbar
    • --> Escribimos ng generate module components/navbar --module app o ng g m components/navbar --module app

6.2) Configuración del componente html Navbar

  • Vamos a incluir el código html de ejemplo de la página de bootstrap en el navbar.component.html(app/navbar/navbar.component.html)
  • Voy a implementar un Navbar de tipo Offcanvas que se despliegua al costado de la pantalla.
  • Código https://getbootstrap.com/docs/5.1/components/navbar/
<nav class="navbar navbar-light bg-light fixed-top">
  <div class="container-fluid">
    <a class="navbar-brand" href="#">Offcanvas navbar</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbar" aria-controls="offcanvasNavbar">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasNavbar" aria-labelledby="offcanvasNavbarLabel">
      <div class="offcanvas-header">
        <h5 class="offcanvas-title" id="offcanvasNavbarLabel">Offcanvas</h5>
        <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
      </div>
      <div class="offcanvas-body">
        <ul class="navbar-nav justify-content-end flex-grow-1 pe-3">
          <li class="nav-item">
            <a class="nav-link active" aria-current="page" href="#">Home</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Link</a>
          </li>
          <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle" href="#" id="offcanvasNavbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
              Dropdown
            </a>
            <ul class="dropdown-menu" aria-labelledby="offcanvasNavbarDropdown">
              <li><a class="dropdown-item" href="#">Action</a></li>
              <li><a class="dropdown-item" href="#">Another action</a></li>
              <li>
                <hr class="dropdown-divider">
              </li>
              <li><a class="dropdown-item" href="#">Something else here</a></li>
            </ul>
          </li>
        </ul>
        <form class="d-flex">
          <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
          <button class="btn btn-outline-success" type="submit">Search</button>
        </form>
      </div>
    </div>
  </div>
</nav>
  • Seguidamente vamos a comprobar si el componente creado se ha importado dentro de app.module.ts
  • Nos dirigimos al archivo (app/app.module.ts)
  • Deberías tener el siguiente código indicando que tenemos el componente importado correctamente
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { NavbarModule } from './components/navbar/navbar.module';


@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    NavbarModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
  • Seguidamente vamos a incluir el código html del componente navbar dentro del componente app, especificamente dentro de app.component.html
  • Nos dirijimos a app.component.html(app/app.component.html) y escribimos
<div>

    <app-navbar></app-navbar>

</div>
  • Guardamos (Ctrl + s )
  • Levantamos el Servidor ng server desde terminal
  • Visualizamos el contenido.

6.3) Creación del componente y módulo Carousel

  • Abrimos una nueva terminal
  • Nos posicionamos sobre el proyecto
  • Creamos el Nuevo Componente modularizado
    • --> Escribimos ng generate component components/carousel --module app o ng g c components/carousel --module app
  • Si desplegas componentes, se debería haber generado el componente, junto con sus archivos
  • Ahora creamos el módulo interno de configuración del carousel
    • --> Escribimos ng generate module components/carousel --module app o ng g m components/carousel --module app

6.4) Configuración del componente html Carousel

  • Vamos a incluir el código html de ejemplo de la página de bootstrap en el carousel.component.html(app/carousel/carousel.component.html)
  • Voy a implementar un Carousel de tipo Dark variant
  • Voy a incluir algunas rutas a imagenes de internet y cambiar algunos colores para que se visualize correctamente el carousel
  • Código https://getbootstrap.com/docs/5.1/components/carousel/
<section>

    <div id="carouselExampleDark" class="carousel carousel-ligth slide" data-bs-ride="carousel">
        <div class="carousel-indicators">
            <button type="button" data-bs-target="#carouselExampleDark" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
            <button type="button" data-bs-target="#carouselExampleDark" data-bs-slide-to="1" aria-label="Slide 2"></button>
            <button type="button" data-bs-target="#carouselExampleDark" data-bs-slide-to="2" aria-label="Slide 3"></button>
        </div>
        <div class="carousel-inner text-white">
            <div class="carousel-item active" data-bs-interval="10000">
                <img src="https://www.aawishkar.tech/images/banner.jpg" class="d-block w-100" alt="...">
                <div class="carousel-caption d-none d-md-block">
                    <h5>First slide label</h5>
                    <p>Some representative placeholder content for the first slide.</p>
                </div>
            </div>
            <div class="carousel-item" data-bs-interval="2000">
                <img src="https://images7.alphacoders.com/447/447880.jpg" class="d-block w-100" alt="...">
                <div class="carousel-caption d-none d-md-block">
                    <h5>Second slide label</h5>
                    <p>Some representative placeholder content for the second slide.</p>
                </div>
            </div>
            <div class="carousel-item">
                <img src="https://www.wallpapertip.com/wmimgs/16-165025_electronics-electronics-wallpaper-hd.jpg" class="d-block w-100" alt="...">
                <div class="carousel-caption d-none d-md-block">
                    <h5>Third slide label</h5>
                    <p>Some representative placeholder content for the third slide.</p>
                </div>
            </div>
        </div>
        <button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleDark" data-bs-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </button>
        <button class="carousel-control-next" type="button" data-bs-target="#carouselExampleDark" data-bs-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </button>
    </div>
</section>

  • Seguidamente vamos a comprobar si el componente creado se ha importado dentro de app.module.ts
  • Nos dirigimos al archivo (app/app.module.ts)
  • Deberías tener el siguiente código indicando que tenemos el componente importado correctamente
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { NavbarModule } from './components/navbar/navbar.module';
import { CarouselComponent } from './components/carousel/carousel.component';
import { CarouselModule } from './components/carousel/carousel.module';


@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent,
    CarouselComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    NavbarModule,
    CarouselModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
  • Seguidamente vamos a incluir el código html del componente carousel dentro del componente app, especificamente dentro de app.component.html
  • Nos dirijimos a app.component.html(app/app.component.html) y escribimos
<div>

     <app-carousel></app-carousel>

</div>
  • Guardamos (Ctrl + s )
  • Levantamos el Servidor ng server desde terminal
  • Visualizamos el contenido.

Paso 7) Imágenes de la Aplicación

(Por convención las imágenes locales, iconos web, etc, las guardamos dentro de la carpeta assets).


7.1) Descarga de Imágenes e Íconos

  • Descargar imágenes e iconos a gusto, en mi caso de electrónica
  • Ted recomiendo la página https://www.flaticon.es/iconos-gratis/electronica
  • Creamos un directorio raiz dentro de assets llamado images(src/assets/images)
  • Copiamos todas las imágenes descargadas al directorio images
  • Incluimos el icono deseado como representación de la tienda y nombre dentro de navbar.component.html
  • Porción de Código
<header>

     <div>
                <img src="assets/images/elect02.png" alt="" width="40" height="40" class="d-inline-block align-text-top "> ElectroThings
            </div>

</header>

7.2) Cambio de Título e Ícono de la app

  • Nos dirigimos al index.html y en title cambiamos el titulo de la app
  • Para cambiar el icono de la app, linkear la imagen descargada desde el <link rel="icon">
  • Porción de Código
<head>
    <meta charset="utf-8">
    <title>ElectroThings</title>
    <base href="/">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/x-icon" href="assets/images/elect02.png">


</head>

Paso 8) Maquetado del Componente Navbar con css

(Mas allá que implementemos un esplendido framework como bootstrap, no podemos dejar de lado css, ya que nos ayuda a ahorrar lineas spaghettis en el html).

  • Dentro del navbar.component.css vamos a implementar el maquetado para este componente.
  • Por ahora establecemos el color de texto en blanco y cambiamos el light por el dark dentro del navbar
  • Código
header {
    color: white;
}

img {
    padding-right: 2px;
}

div.collapse {
    margin-left: 15px;
    padding: 5px;
}

Sección 4) Creación-Configuración de Páginas Web y Servicios


Paso 9) Generación de Módulos y Componentes para otras páginas

(Nuestra Aplicación tendrá diversas páginas en las cuáles crearemos para el listado de los componentes electrónicos, agregar, modificar, etc).


9.1) Página listado-componentes

  • Vamos a generar un módulo con sus componentes indicando también la ruta del mismo que utilizaremos para la página web deseada. El mismo lo vamos a crear dentro de una nueva ruta (pages/electronica/listado-componentes).
  • El comando completo sería ng g m pages/electronica/listado-componentes --module app --route listado-componentes
  • Abris una nueva terminal y escribir el comando anterior (en mi caso)

9.2) Página detalles-componentes

  • Vamos a generar un módulo con sus componentes indicando también la ruta del mismo que utilizaremos para la página web deseada. El mismo lo vamos a crear dentro de una nueva ruta (pages/electronica/detalles-componentes).
  • El comando completo sería ng g m pages/electronica/detalles-componentes --module app --route detalles-componentes
  • Abris una nueva terminal y escribir el comando anterior (en mi caso)

9.3) Página agregar-componentes

  • Vamos a generar un módulo con sus componentes indicando también la ruta del mismo que utilizaremos para la página web deseada. El mismo lo vamos a crear dentro de una nueva ruta (pages/electronica/agregar-componentes).
  • El comando completo sería ng g m pages/electronica/agregar-componentes --module app --route agregar-componentes
  • Abris una nueva terminal y escribir el comando anterior (en mi caso)

9.4) Página editar-componentes

  • Vamos a generar un módulo con sus componentes indicando también la ruta del mismo que utilizaremos para la página web deseada. El mismo lo vamos a crear dentro de una nueva ruta (pages/electronica/editar-componentes).
  • El comando completo sería ng g m pages/electronica/editar-componentes --module app --route editar-componentes
  • Abris una nueva terminal y escribir el comando anterior (en mi caso)

9.5) Página para Ayuda

  • Vamos a generar un módulo con sus componentes indicando también la ruta del mismo que utilizaremos para la página web deseada. El mismo lo vamos a crear dentro de una nueva ruta (pages/utilidades/ayuda).
  • El comando completo sería ng g m pages/utilidades/ayuda --module app --route ayuda
  • Abris una nueva terminal y escribir el comando anterior (en mi caso)

Paso 10) Ruteo de las Páginas Web

(Declarar las rutas con directivas en angular se consideran buenas prácticas, ya que podremos controlar los errores que pudiesen surgir).

  • Primeramente hay que incluir la Directiva <router-outlet></router-outlet> dentro de app.component.html, por qué sino no se establece el ruteo de forma dinámica, osea no se van a mostrar las páginas creadas.
<div>

    <app-navbar></app-navbar>

    <router-outlet></router-outlet>

</div>
  • Ahora nos dirigimos al navbar.component.html y allí modificamos los nav-item agregando las directivas de enlaces [routerLink] = "['/nombrePagina']" indicando las páginas de redireccionamiento
  • Vamos a modificar nuestro Offcanvas navbar a gusto, cambiamos los fondos, agregamos iconos, cambiamos los nombres, etc
  • Código
<header>

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
        <div class="container-fluid">
            <!--Icono-->
            <div>
                <img src="assets/images/elect02.png" alt="" width="40" height="40" class="d-inline-block align-text-top "> ElectroThings
            </div>
            <!--Fin Icono-->
            <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbar" aria-controls="offcanvasNavbar">
        <span class="navbar-toggler-icon"></span>
      </button>
            <div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasNavbar" aria-labelledby="offcanvasNavbarLabel">
                <!--Boton Close-->
                <div class="offcanvas-header bg-dark">
                    <h5 class="offcanvas-title" id="offcanvasNavbarLabel"><img src="assets/images/elect02.png" alt="" width="40" height="40" class="d-inline-block align-text-top "> ElectroThings</h5>

                    <button type="button" class="btn-close bg-white text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
                </div>
                <!--Fin Boton Close-->
                <div class="offcanvas-body bg-dark">
                    <ul class="navbar-nav">
                        <li class="nav-item" routerLinkActive="active">
                            <a class="nav-link" [routerLink]="['/']">Inicio</a>
                        </li>
                        <li class="nav-item" routerLinkActive="active">
                            <a class="nav-link" [routerLink]="['/listado-componentes']">Listado de Componentes</a>
                        </li>
                        <li class="nav-item" routerLinkActive="active">
                            <a class="nav-link" [routerLink]="['/agregar-componentes']">Agregar Componentes</a>
                        </li>
                        <li class="nav-item" routerLinkActive="active">
                            <a class="nav-link" [routerLink]="['/editar-componentes']">Editar Componentes</a>
                        </li>
                        <li class="nav-item" routerLinkActive="active">
                            <a class="nav-link" [routerLink]="['/ayuda']">Ayuda</a>
                        </li>
                    </ul>

                </div>
            </div>
        </div>
    </nav>


</header>

Paso 11) Creación de Servicios

(Un servicio Angular es un objeto sin estado y proporciona algunas funciones muy útiles. Estas funciones se pueden invocar desde cualquier componente de Angular, como Controladores, Directivas, etc. Esto ayuda a dividir la aplicación web en unidades lógicas pequeñas y diferentes que se pueden reutilizar.).


  • Vamos a generar el servicio dentro de la carpeta de electronica y el mismo se llamara electronica.service (pages/electronica/electronica.service).
  • El comando completo sería ng g s pages/electronica/electronica
  • Abris una nueva terminal y escribir el comando anterior (en mi caso)
  • Se tendria que haber generado el archivo electronica.service.ts

Sección 5) Desarrollo de las Páginas Web


Paso 12) Página Listado de Componentes de Electrónica

(Como se explico anteriormente esta página contendra la lista de componentes de eletrónica)


12.1) Creación de una Tabla

  • Copiamos la estructura base de la tabla de bootstrap https://getbootstrap.com/docs/5.1/content/tables/ y la pegamos en el listado-componentes.component.html dentro del modulo listado-componentes.
  • Voy a cambiar la variante de la tabla a tipo hover, también los nombres, columnas, agregar botones, colores, etc.
  • También voy a agregar iconos de bootstrap (https://icons.getbootstrap.com/) para la visualizacion, la edición y la eliminación de los productos del listado

12.2) Uso de la Directiva *ngFor

  • Vamos a replicar el listado de productos 4 veces, usando la directiva de angular *ngFor, esta directiva nos permite generar muchos elementos HTML repetidos a partir de un recorrido de un arreglo de datos.
<!--Replicamos 4 veces los productos e iconos-->
            <tr *ngFor=" let producto of [0,1,2,3,4]">
                <th scope="row">1</th>
                <td>Módulo WIFI MCU-ESP32</td>
                <td>MCU-65788</td>
                <td>1600</td>

12.3) Creación de Funciones CRUD (editar, eliminar y ver )

  • Necesitamos funciones que nos permitan eliminar, mostrar y modificar los PRODUCTOS que se muestran en el listado, estas funciones las vamos a usar con eventos posteriormente.
  • Nos dirigimos a listado-componentes.component.ts
  • Vamos a pasarle la clase Route en el constructor, esta clase es la encargada de gestionar las rutas de nuestras paginas web creadas. Importar dichos módulos
  • Vamos a utilizar la propiedad llamada state dentro y fuera de los métodos que desarrollemos, esta propiedad nos permite trabajar con el objeto completo, dicha propiedad deberá ser implementada en cada una de las siguientes funciones.
  • Para usar dicha propiedad debemos declarar un objeto de tipo NavigationExtras importando la interfaz correspondiente y pasandole un estado
  • Código de la Propiedad..
  navigationExtras : NavigationExtras = {

    state : {
      value:null
    };
  • ATENTI, si se tiene una configuración estricta de TypeScript surgirá un error en este paso, ya que se está declarando la propiedad como nula, hay que dirigirnos al archivo tsconfig.json y dentro del compilerOptions cambiar el paramnetro "strict":true a "strict":false
  • Por Último vamos a crear las funciones. Las mismas se llamaran editarProducto, eliminarProducto y mostrarProducto.

12.3.1) Función eliminarProducto

  • Este Método va a recibir un producto en su argumento
  • Luego, por el momento , en el cuerpo del método vamos a indicar con un alert que simplemente nos diga que el producto ha sido borrado..
  • Código Snippet..
  // Eliminar Productos
  eliminarProducto(producto : any): void{
    alert('El Producto ha sido Eliminado');
  }

12.3.2) Función editarProducto

  • Este Método va a recibir un producto en su argumento
  • En el cuerpo del método vamos a pasarle la ruta definida cuando creamos los componentes de las paginas creadas anteriormente que va a mostrar en detalle dicho producto. Además vamos a usar la propiedad creada navigationExtras haciendo referencia al valor del state para trabajar con el objeto en sí. En el segundo parametro del router.navigate vamos a pasarle además el estado de la propiedad creada
  • Código Snippet..
  // Editar Productos
  editarProducto(producto : any): void{
    this.navigationExtras.state.value = producto;
    this.router.navigate(['editar-componentes'] , this.navigationExtras);
  }

12.3.3) Función detallesProducto

  • Este Método va a recibir un producto en su argumento
  • En el cuerpo del método vamos a pasarle la ruta definida cuando creamos los componentes de las paginas creadas anteriormente que va a mostrar en detalle dicho producto. Además vamos a usar la propiedad creada navigationExtras haciendo referencia al valor del state para trabajar con el objeto en sí. En el segundo parametro del router.navigate vamos a pasarle además el estado de la propiedad creada
  • Código Snippet..
  // Mostrar Productos
  detallesProducto(producto : any): void{
    this.navigationExtras.state.value = producto;
    this.router.navigate(['detalles-componentes'] , this.navigationExtras);
  }

  • Código Completo para listado-componentes.component.ts..
import { Component, OnInit } from '@angular/core';
import { NavigationExtras, Router } from '@angular/router';

@Component({
  selector: 'app-listado-componentes',
  templateUrl: './listado-componentes.component.html',
  styleUrls: ['./listado-componentes.component.css']
})
export class ListadoComponentesComponent implements OnInit {

  navigationExtras : NavigationExtras = {

      state : {
        value :null
      }
  };

  constructor(private router: Router) { }

  ngOnInit(): void {

  }

  // Métodos CRUD para los Componentes Electrónicos

  // Mostrar Productos
  detallesProducto(producto : any): void{
    this.navigationExtras.state.value = producto;
    this.router.navigate(['detalles-componentes'] , this.navigationExtras);
  }

  // Editar Productos
  editarProducto(producto : any): void{
    this.navigationExtras.state.value = producto;
    this.router.navigate(['editar-componentes'] , this.navigationExtras);
  }

  // Eliminar Productos
  eliminarProducto(producto : any): void{
    alert('El Producto ha sido Eliminado');
  }
}

12.4) Uso de Enlaces a Eventos (click)

  • El enlace de Eventos escucha los eventos de click en el botón y llama al método indicado cada vez que se produce un click

  • Para poder implementar este evento se deben haber creado previamente las funciones correspondientes para que realizen las acciones de tipo CRUD básicas (editar, eliminar, agregar elementos), como se indica paso a paso en los items anteriores.

  • Estas funciones se van a agregar dentro de cada boton correspondiente para que realice la acción deseada.

  • Código..

<div class="table-responsive">

    <table class="table table-hover">
        <thead>
            <tr>
                <th scope="col">ID</th>
                <th scope="col">Nombre</th>
                <th scope="col">Código</th>
                <th scope="col">Precio</th>
                <th class="d-none d-sm-block" scope="col">Opciones</th>
            </tr>
        </thead>
        <tbody>
            <!--Replicamos 4 veces los productos e iconos-->
            <tr *ngFor=" let producto of [0,1,2,3,4]">
                <th scope="row">1</th>
                <td>Módulo WIFI MCU-ESP32</td>
                <td>MCU-65788</td>
                <td>1600</td>
                <!--En caso de moviles ocultamos -->
                <td class="btn-group d-none d-sm-block" role="group">

                    <button class="btn btn-primary border-light alert-link m-1" (click)="detallesProducto(producto)">
                    <!--Icono Visualizar Producto-->
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrows-fullscreen" viewBox="0 0 16 16">
                      <path fill-rule="evenodd" d="M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707zm4.344 0a.5.5 0 0 1 .707 0l4.096 4.096V11.5a.5.5 0 1 1 1 0v3.975a.5.5 0 0 1-.5.5H11.5a.5.5 0 0 1 0-1h2.768l-4.096-4.096a.5.5 0 0 1 0-.707zm0-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707zm-4.344 0a.5.5 0 0 1-.707 0L1.025 1.732V4.5a.5.5 0 0 1-1 0V.525a.5.5 0 0 1 .5-.5H4.5a.5.5 0 0 1 0 1H1.732l4.096 4.096a.5.5 0 0 1 0 .707z"/>
                    </svg>
                      <!--Fin Icono Visualizar Producto-->
                        </button>

                    <button class="btn btn-warning border-light alert-link m-1 " (click)="editarProducto(producto)">
                          <!--Icono Editar Producto-->
                          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil" viewBox="0 0 16 16">
                            <path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
                          </svg>
                            <!--Fin Icono Editar Producto-->
              </button>

                    <button class="btn btn-danger border-light alert-link m-1 " (click)="eliminarProducto(producto)">
                                <!--Icono Eliminar Producto-->
                                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
                                  <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/>
                                  <path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/>
                                </svg>
                                  <!--Fin Icono Eliminar Producto-->
                                    </button>
                </td>
            </tr>

        </tbody>

    </table>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-2">
                <button class="btn btn-outline-dark  border-dark alert-link m-2 ">Regresar
                <!--Icono Regresar Inicio-->
                <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-reply-fill" viewBox="0 0 16 16">
                  <path d="M5.921 11.9 1.353 8.62a.719.719 0 0 1 0-1.238L5.921 4.1A.716.716 0 0 1 7 4.719V6c1.5 0 6 0 7 8-2.5-4.5-7-4-7-4v1.281c0 .56-.606.898-1.079.62z"/>
                </svg>
                  <!--Fin Icono Regresar Inicio-->
                    </button>
            </div>
            <div class="col-2">
                <button class="btn btn-outline-dark  border-dark alert-link m-2 ">Actualizar
                <!--Icono Actualizar Listado-->
                <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-repeat" viewBox="0 0 16 16">
                  <path d="M11.534 7h3.932a.25.25 0 0 1 .192.41l-1.966 2.36a.25.25 0 0 1-.384 0l-1.966-2.36a.25.25 0 0 1 .192-.41zm-11 2h3.932a.25.25 0 0 0 .192-.41L2.692 6.23a.25.25 0 0 0-.384 0L.342 8.59A.25.25 0 0 0 .534 9z"/>
                  <path fill-rule="evenodd" d="M8 3c-1.552 0-2.94.707-3.857 1.818a.5.5 0 1 1-.771-.636A6.002 6.002 0 0 1 13.917 7H12.9A5.002 5.002 0 0 0 8 3zM3.1 9a5.002 5.002 0 0 0 8.757 2.182.5.5 0 1 1 .771.636A6.002 6.002 0 0 1 2.083 9H3.1z"/>
                </svg>
                  <!--Fin Icono Actualizar Listado-->
                    </button>

            </div>
        </div>
    </div>

</div>

12.5) Capturando el objeto Producto en la Página editar-componente


  • Una vez definidos los métodos CRUD vamos a capturar los objetos que se pasen al state cuando se haga click en el icono de editar.

  • Vamos a trabajar las Navegaciones y estados en editar-componentes.component.ts

  • Nos dirigimos a editar-componentes.component.ts

  • Dentro de la clase EditarComponentesComponent, fuera del constructor declaramos una variable llmada valorProducto del objeto como nulo. Dentro del constructor indicamos que la variable-propiedad valorProducto tendrá la propiedad de tomar el estado actual del objeto. Osea que nos muestre el valor de ese objeto .

  • Una vez allí, dentro del constructor, inyectamos el router definiendolo en su argumento, dentro de este creamos una variable-propiedad (const navigacionActual) que nos traiga ese objeto con el método getCurrentNavidation() a través de la ruta pasada.

  • Los signos de interrogación se indican ya que no es necesario pasarle sus valores.

  • Código Completo..

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

@Component({
selector: 'app-editar-componentes',
templateUrl: './editar-componentes.component.html',
styleUrls: ['./editar-componentes.component.css']
})
export class EditarComponentesComponent implements OnInit {

valorProducto = null

constructor(private router : Router) {
 
  const navigacionActual = this.router.getCurrentNavigation();

  this.valorProducto = navigacionActual?.extras?.state;
}



ngOnInit(): void {
}

}
  • Por Último testeamos el valor del objeto que se obtiene al hacer click sobre el boton de editar.
  • Nos dirigimos a editar-componentes.component.html e indicamos con interpolación el valor del producto, trabajamos con json.
  • Código Snippet..
<p>editar-componentes works!</p>

{{ valorProducto | json }}

12.6) Capturando el objeto Producto en la Página detalles-componente


  • Una vez definidos los métodos CRUD vamos a capturar los objetos que se pasen al state cuando se haga click en el icono de detalles.
  • Vamos a trabajar las Navegaciones y estados en detalles-componentes.component.ts
  • Nos dirigimos a detalles-componentes.component.ts
  • Dentro de la clase DetallesComponentesComponent, fuera del constructor declaramos una variable llamada valorProducto del objeto como nulo. Dentro del constructor indicamos que la variable-propiedad valorProducto tendrá la propiedad de tomar el estado actual del objeto. Osea que nos muestre el valor de ese objeto .
  • Una vez allí, dentro del constructor, inyectamos el router definiendolo en el argumento del constructor, dentro de este creamos una variable-propiedad (const navigacionActual) que nos traiga ese objeto con el método getCurrentNavidation() a través de la ruta pasada.
  • Los signos de interrogación se indican ya que no es necesario pasarle sus valores.
  • Vamos a crear una funcion para que nos regrese al listado de componentes cuando estemos en el detalle de un solo componente, la funcion se va a llamar regresarListadoComponentes()
  • Vamos a reutilizar las funciones editarProducto() y eliminarProducto() que declaramos en el listado-componentes.component.ts, para las operaciones de este producto. La diferencia acá es que no necesitamos pasarle el producto clickeado en el argumento de la funcion ya que lo recuperamos con el getCurrentNavigation , por ende en los estados de la funcion le pasamos la variable declarada valorProducto
  • Importante declarar el navigationExtras e importar su módulo
  • Código Completo..
import { Component, OnInit } from '@angular/core';
import { NavigationExtras, Router } from '@angular/router';

@Component({
selector: 'app-detalles-componentes',
templateUrl: './detalles-componentes.component.html',
styleUrls: ['./detalles-componentes.component.css']
})
export class DetallesComponentesComponent implements OnInit {

navigationExtras : NavigationExtras = {

  state : {
    value :null
  }
};




valorProducto = null;

constructor(private router: Router) {

  const navegacionActual = this.router.getCurrentNavigation();

  this.valorProducto = navegacionActual?.extras?.state;


}

ngOnInit(): void {
}

  //Regresar Listado Productos
regresarListadoProductos():void{
  this.router.navigate(['listado-componentes']);
}


// Editar Productos
editarProducto(): void{
  this.navigationExtras.state.value = this.valorProducto;
  this.router.navigate(['editar-componentes'] , this.navigationExtras);
}

// Eliminar Productos
eliminarProducto(): void{
  alert('El Producto ha sido Eliminado');
}




}

  • Por Último testeamos el valor del objeto que se obtiene al hacer click sobre el boton de detalles.
  • Nos dirigimos a detalles-componentes.component.html e indicamos con interpolación el valor del producto, trabajamos con json.
  • Código Snippet..
<p>detalles-componentes works!</p>

{{ valorProducto | json }}

Paso 13) Página Detalles Componentes de Electrónica

(Esta Página contendrá los Detalles Específicos de cada Producto o Componente de Electrónica)


13.1) Maquetación Página Detalles de Componentes

  • En esta página se alojará el detalle de cada componente una vez que el usuario haga click sobre el icono de detalles.
  • La Maquetación de la Página es detalles-componentes.component.html
  • Voy a crear un Card para el Producto con su foto, detalle, etc y otro Card para el detalle del producto con sus botones y descripcion. La idea es que ambas cards sean responsives.
  • Una vez que hemos declarado las funciones en el detalles-componentes.component.ts, vamos a pasarles los eventos a los botones y cuando se haga click se dispare las funciones realizadas anteriormente. * En el boton de regresar declaramos la funcion click para que se dispare dicho evento y nos muestre el alert..
 <button class="btn btn-danger border-dark alert-link m-1 " (click)="regresarListadoProductos()">
  • En el boton de eliminar declaramos la funcion click para que se dispare dicho evento y nos muestre el alert..
 <button class="btn btn-danger border-dark alert-link m-1 " (click)="eliminarProducto()">
  • En el boton de editar declaramos la funcion click para que se dispare dicho evento
 <button class="btn btn-danger border-dark alert-link m-1 " (click)="editarProducto()">
  • Código completo de detalles-componentes.component.html..
<div class="container m-2">
    <div class="row justify-content-start">



        <!--CARD PRODUCTO-->
        <div class="col-md-5 col-sm-12">

            <div class="card bg-opacity-10 bg-secondary" style="max-width: 540px;">
                <div class="row g-0  ">
                    <div class="col-md-4">
                        <img src="assets/images/esp32.jpg" class="card-img-top " alt="...">
                    </div>
                    <div class="col-md-8 ">
                        <div class="card-body ">
                            <h5 class="card-title bg-gradient bg-opacity-10 bg-dark text-center">Módulo Wifi Mcu Esp32</h5>
                            <p class="card-text">Incluyen puerto de conexión microUSB para alimentación y conector JST para alimentación de la placa. Y se pueden programar desde el IDE de Arduino..</p>
                        </div>
                        <div class="card-body  ">
                            <a href="https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf" class="card-link text-dark">Datasheet</a>
                            <a href="https://www.espressif.com/sitproyectos%20esp32es/default/files/documentation/esp32_datasheet_en.pdf" class="card-link text-dark">Proyectos</a>
                            <a href="https://www.espressif.com/sitproyectos%20esp32es/default/files/documentation/esp32_datasheet_en.pdf" class="card-link text-dark">Más Info</a>
                        </div>
                    </div>
                </div>
            </div>
        </div>


        <!--FIN CARD PRODUCTO-->

        <!--CARD DETALLES PRODUCTO-->

        <div class="col-md-7 col-sm-12">

            <div class="bg-opacity-10 bg-dark ">
                <hr>
                <div class="card-body text-center">
                    <div class="text-center ">
                        <h5 class="text-underline">DETALLES PRODUCTO</h5>
                    </div>
                    <hr>
                    <ul class=" m-2 p-2 text-center list-group list-group-flush list-group-horizontal-lg list-group-horizontal-md input-group ">

                        <li class="list-group-item "><strong>ID</strong>
                            <p>1</p>
                        </li>
                        <li class="list-group-item "><strong>Nombre</strong>
                            <p>Módulo Wifi Mcu Esp32
                            </p>
                        </li>
                        <li class="list-group-item"><strong>Código</strong>
                            <p>MCU-65788</p>
                        </li>
                        <li class="list-group-item"><strong>Precio</strong>
                            <p>1600</p>
                        </li>

                    </ul>
                </div>
            </div>


            <!--BOTONES-->
            <div class="container col-sm-12 bg-opacity-75 bg-dark p-1">
                <div class="row justify-content-center">

                    <div class="col-md-2 col-sm-2">
                        <button class="btn btn-primary border-dark alert-link m-1 " (click)="regresarListadoProductos()">
                      <!--Icono Regresar-->
                      <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-return-left" viewBox="0 0 16 16">
                        <path fill-rule="evenodd" d="M14.5 1.5a.5.5 0 0 1 .5.5v4.8a2.5 2.5 0 0 1-2.5 2.5H2.707l3.347 3.346a.5.5 0 0 1-.708.708l-4.2-4.2a.5.5 0 0 1 0-.708l4-4a.5.5 0 1 1 .708.708L2.707 8.3H12.5A1.5 1.5 0 0 0 14 6.8V2a.5.5 0 0 1 .5-.5z"/>
                      </svg>
                        <!--FIN Icono Regresar-->
                    </button>
                    </div>

                    <div class="col-md-2 col-sm-2">
                        <button class="btn btn-warning border-dark alert-link m-1 " (click)="editarProducto()">
                          <!--Icono Editar Producto-->
                          <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-pencil" viewBox="0 0 16 16">
                            <path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
                          </svg>
                            <!--Fin Icono Editar Producto-->
                        </button>
                    </div>
                    <div class="col-md-2 col-sm-2">
                        <button class="btn btn-danger border-dark alert-link m-1 " (click)="eliminarProducto()">
                <!--Icono Eliminar Producto-->
                <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
                  <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/>
                  <path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/>
                </svg>
                <!--Fin Icono Eliminar Producto-->
                  </button>
                    </div>

                    <div class="col-md-2 col-sm-2">

                        <button onClick="window.location.reload()" class="btn btn-secondary border-dark alert-link m-1  ">
                <!--Icono Actualizar Listado-->
                <svg xmlns="http://www.w3.org/2000/svg " width="20 " height="20 " fill="currentColor " class="bi bi-arrow-repeat " viewBox="0 0 16 16 ">
                  <path d="M11.534 7h3.932a.25.25 0 0 1 .192.41l-1.966 2.36a.25.25 0 0 1-.384 0l-1.966-2.36a.25.25 0 0 1 .192-.41zm-11 2h3.932a.25.25 0 0 0 .192-.41L2.692 6.23a.25.25 0 0 0-.384 0L.342 8.59A.25.25 0 0 0 .534 9z "/>
                  <path fill-rule="evenodd " d="M8 3c-1.552 0-2.94.707-3.857 1.818a.5.5 0 1 1-.771-.636A6.002 6.002 0 0 1 13.917 7H12.9A5.002 5.002 0 0 0 8 3zM3.1 9a5.002 5.002 0 0 0 8.757 2.182.5.5 0 1 1 .771.636A6.002 6.002 0 0 1 2.083 9H3.1z "/>
                </svg>
                  <!--Fin Icono Actualizar Listado-->
                  </button>

                    </div>

                </div>
            </div>
            <!--FIN BOTONES-->

            {{valorProducto | json}}

        </div>

        <!-- CARD FIN DETALLES PRODUCTO-->






    </div>

Paso 14) Página Editar Componentes de Electrónica

(Esta Página contendrá el formulario para editar el componente seleccionado de la lista de componentes de Electrónica)


14.1) Maquetación Página Editar Componentes de Electrónica


Paso 15) Página Agregar Componentes de Electrónica

(Esta Página contendrá el formulario para agregar componentes de Electrónica)


15.1) Maquetación Página Editar Componentes de Electrónica


Paso 16) Página de Inicio

(Esta Página será la página de Inicio de la Aplicación)


16.1) Maquetación Página de Inicio






Subir el proyecto al repositorio con git desde el bash de visual studio Code

1)Creamos un nuevo repositorio en GitHub

2)Inicializamos nuestro repositorio local .git

  • git init

3)Agregamos lo desarrollado a nuestro repo local

  • git add *

4)Agregamos lo que tenemos en nuestro repo local al área de Trabajo.

  • git commit -m "agrega un comentario entre comillas"

5)Le indicamos a git donde se va a almacenar nuestro proyecto(fijate en tu repositorio de github cual es el enlace de tu proyecto(esta en code)).

6)Subimos nuestro proyecto.

  • git push -u origin master

Actualización del repositorio del proyecto con git desde el bash de visual studio code

1)Visualizamos las modificaciones realizadas en local

  • git status

2)Agregamos lo modificado al area de trabajo

  • git add *

3)Confirmamos las modificaciones realizadas

  • git commit -m "Tu commit entre comillas"

4)Sincronizamos y traemos todos los cambios del repositorio remoto a la rama en la que estemos trabajando actualmente.

Desconozco porqué tengo que ejecutar este comando, supongo que será porque no estoy trabajando con branchs en mi proyecto, el main por defecto de gitHub ahora es mi master(Yo realicé esa modificación para mejor visualización)).

5)Enviamos todos los cambios al repo en github


Deploy de la app desde el bash de visual studio code

1) Instalar el cli global

  • npm i netlify-cli
  • netlify login
  • netlify status
  • netlify --version

2) Build

  • ng build --prod

3) Deploy

  • netlify deploy --prod

IMPORTANTE: Luego de ingresar este comando, asegurarse de colocar correctamente el Publish directory , sino no se va a deployar correctamente, en general es dist/'nombre de tu proyecto sin comillas'