{"id":4448,"date":"2024-11-18T00:36:33","date_gmt":"2024-11-18T06:36:33","guid":{"rendered":"https:\/\/linuxitos.com\/main\/?p=4448"},"modified":"2024-11-18T00:37:57","modified_gmt":"2024-11-18T06:37:57","slug":"notificaciones-bootstrap-angular-18","status":"publish","type":"post","link":"https:\/\/linuxitos.com\/main\/notificaciones-bootstrap-angular-18\/","title":{"rendered":"Notificaciones Bootstrap Angular 18"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-35-49.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"738\" src=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-35-49-1024x738.png\" alt=\"\" class=\"wp-image-4451\" srcset=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-35-49-1024x738.png 1024w, https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-35-49-300x216.png 300w, https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-35-49-768x553.png 768w, https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-35-49.png 1094w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">Contexto<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Estoy realizando una migraci\u00f3n de de front a angular de un proyecto algo ampl\u00edo, y dentro de las migraciones, se requiere enviar notificaciones a pantalla. Pero las notificaciones deben ser no intrusivas que necesiten forzosamente la intervenci\u00f3n del usuario, ya sea mediante click o esc. En la anterior plataforma se us\u00f3 un sistema de notificaciones de desarrollado con jquery y bootstrap, por lo que se migr\u00f3 de una manera similar a \u00e9ste nuevo proyecto.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Y me dispuse a compartir dichas notificaciones, por si alguno requiere notificaciones poco invasivas en la pantalla para el usuario.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Requerimientos<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Angular v18<\/li>\n\n\n\n<li>Node v22<\/li>\n\n\n\n<li>Bootstrap v5<\/li>\n\n\n\n<li>Bootstrap Icons v1<\/li>\n\n\n\n<li>VsCode<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Proyecto Angular<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">El proyecto a crear y desarrollar se llamar\u00e1 <strong>ng-bs-notify<\/strong> si no desean realizar el paso a paso, pueden clonarlo de: <a href=\"https:\/\/gitlab.com\/linuxitos\/notify-bootstrap-angular\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/gitlab.com\/linuxitos\/notify-bootstrap-angular<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Crear proyecto y a\u00f1adir dependencias<\/h2>\n\n\n\n<pre style=\"background: rgb(54, 63, 72); border-radius: 6px; border: 0px; box-sizing: border-box; color: white; font-family: menlo, monaco, monospace; font-style: inherit; font-weight: inherit; line-height: 15.68px; margin-bottom: 1.1em; max-width: 100%; outline: 0px; overflow: auto; padding: 13.125px 16.4062px; vertical-align: baseline; white-space: pre-wrap; word-wrap: break-word;\">ng new ng-bs-notify<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Elegir las opciones por defecto que muestre en pantalla:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-51-27.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"394\" src=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-51-27-1024x394.png\" alt=\"\" class=\"wp-image-4453\" srcset=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-51-27-1024x394.png 1024w, https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-51-27-300x115.png 300w, https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-51-27-768x296.png 768w, https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/Screenshot-From-2024-11-17-12-51-27.png 1026w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Una vez que termine, instalar las dependencias, pueden cambiarlo, y usar tailwind, o css puro:<\/p>\n\n\n\n<pre style=\"background: rgb(54, 63, 72); border-radius: 6px; border: 0px; box-sizing: border-box; color: white; font-family: menlo, monaco, monospace; font-style: inherit; font-weight: inherit; line-height: 15.68px; margin-bottom: 1.1em; max-width: 100%; outline: 0px; overflow: auto; padding: 13.125px 16.4062px; vertical-align: baseline; white-space: pre-wrap; word-wrap: break-word;\">npm install bootstrap bootstrap-icons<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A\u00f1adir las rutas de los css de bootstrap, en el archivo angular.json<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Buscar la secci\u00f3n de style, para los css:<\/p>\n\n\n\n<pre style=\"background: rgb(245, 245, 245); border-radius: 6px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; color: #333; font-family: menlo, monaco, monospace; font-style: inherit; font-weight: inherit; line-height: 15.68px; margin-bottom: 1.1em; max-width: 100%; outline: 0px; overflow: auto; padding: 13.125px 16.4062px; vertical-align: baseline; white-space: pre-wrap; word-wrap: break-word;\">\"styles\": [\n     \"node_modules\/bootstrap\/dist\/css\/bootstrap.min.css\",\n     \"node_modules\/bootstrap-icons\/font\/bootstrap-icons.css\",\n     \"src\/styles.css\"\n]<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Los archivos js en:<\/p>\n\n\n\n<pre style=\"background: rgb(245, 245, 245); border-radius: 6px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; color: #333; font-family: menlo, monaco, monospace; font-style: inherit; font-weight: inherit; line-height: 15.68px; margin-bottom: 1.1em; max-width: 100%; outline: 0px; overflow: auto; padding: 13.125px 16.4062px; vertical-align: baseline; white-space: pre-wrap; word-wrap: break-word;\">\"scripts\": [\n      \"node_modules\/bootstrap\/dist\/js\/bootstrap.bundle.min.js\"\n]<\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Crear servicio Alert<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">El servicio <strong>alert.service.ts<\/strong> se encargar\u00e1 de procesar las notificaciones desde cualquier parte del proyecto y mostrarlas en pantalla.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para crear el servicio, se usa el siguiente comando, dentro directo de app, y dentro del directorio services, usar el siguiente comando:<\/p>\n\n\n\n<pre style=\"background: rgb(54, 63, 72); border-radius: 6px; border: 0px; box-sizing: border-box; color: white; font-family: menlo, monaco, monospace; font-style: inherit; font-weight: inherit; line-height: 15.68px; margin-bottom: 1.1em; max-width: 100%; outline: 0px; overflow: auto; padding: 13.125px 16.4062px; vertical-align: baseline; white-space: pre-wrap; word-wrap: break-word;\">ng g service services\/alert<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Una vez creado deber\u00e1 aparecer de la siguiente manera:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"856\" height=\"96\" src=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/image.png\" alt=\"\" class=\"wp-image-4455\" srcset=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/image.png 856w, https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/image-300x34.png 300w, https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/image-768x86.png 768w\" sizes=\"auto, (max-width: 856px) 100vw, 856px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Editar el servicio alert.service.ts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Abrir el archivo alert.service.ts y a\u00f1adir el siguiente c\u00f3digo. Guardar los cambios y listo.<\/p>\n\n\n\n<pre style=\"background: rgb(245, 245, 245); border-radius: 6px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; color: #333; font-family: menlo, monaco, monospace; font-style: inherit; font-weight: inherit; line-height: 15.68px; margin-bottom: 1.1em; max-width: 100%; outline: 0px; overflow: auto; padding: 13.125px 16.4062px; vertical-align: baseline; white-space: pre-wrap; word-wrap: break-word;\">import { Injectable } from '@angular\/core'\nimport { Subject } from 'rxjs'\n\nexport type AlertType = 'success' | 'danger' | 'info' | 'warning'\n\nexport interface Alert {\n\tmessage: string\n\ttype: AlertType\n\tid: number\n\tshow: boolean\n}\n\n@Injectable({\n\tprovidedIn: 'root'\n})\n\nexport class AlertService {\n\tprivate alertsSubject = new Subject<Alert[]>();\n\talerts$ = this.alertsSubject.asObservable();\n\tprivate alerts: Alert[] = [];\n\tprivate idCounter = 0;\n\n\tshowAlert(message: string, type: AlertType) {\n\t\tconst alert: Alert = { message, type, id: this.idCounter++, show: false }\n\t\tthis.alerts = [alert, ...this.alerts]\n\t\tthis.alertsSubject.next(this.alerts)\n\n\t\tsetTimeout(() => {\n\t\t\talert.show = true\n\t\t\tthis.alertsSubject.next(this.alerts)\n\t\t}, 10) \/\/ Peque\u00f1o retraso para activar la animaci\u00f3n de fade-in\n\n\t\tsetTimeout(() => {\n\t\t\tthis.fadeOutAlert(alert.id)\n\t\t}, 4000) \/\/ Iniciar desvanecimiento despu\u00e9s de 3 segundos\n\t}\n\n\tfadeOutAlert(id: number) {\n\t\tconst alert = this.alerts.find(alert => alert.id === id)\n\t\tif (alert) {\n\t\t\talert.show = false\n\t\t\tthis.alertsSubject.next(this.alerts)\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.removeAlert(id)\n\t\t\t}, 500) \/\/ Tiempo para la animaci\u00f3n de desvanecimiento\n\t\t}\n\t}\n\n\tremoveAlert(id: number) {\n\t\tthis.alerts = this.alerts.filter(alert => alert.id !== id)\n\t\tthis.alertsSubject.next(this.alerts)\n\t}\n}<\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Crear component alert.component.ts<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">El componente alert.coponent.ts contiene el c\u00f3digo, y vistas que se usar\u00e1 para las notificaciones, \u00e9sta a su vez los tomar\u00e1 el servicio alert.service.ts<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Usar el comando siguiente para crear el componente, y se crear\u00e1 en la ruta app\/components<\/p>\n\n\n\n<pre style=\"background: rgb(54, 63, 72); border-radius: 6px; border: 0px; box-sizing: border-box; color: white; font-family: menlo, monaco, monospace; font-style: inherit; font-weight: inherit; line-height: 15.68px; margin-bottom: 1.1em; max-width: 100%; outline: 0px; overflow: auto; padding: 13.125px 16.4062px; vertical-align: baseline; white-space: pre-wrap; word-wrap: break-word;\">ng g component components\/alert<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Y se generar\u00e1 de la siguiente manera:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"856\" height=\"131\" src=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/image-1.png\" alt=\"\" class=\"wp-image-4456\" srcset=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/image-1.png 856w, https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/image-1-300x46.png 300w, https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/image-1-768x118.png 768w\" sizes=\"auto, (max-width: 856px) 100vw, 856px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Editar el component Alert<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Abrir el archivo alert.component.ts y a\u00f1adir el siguiente c\u00f3digo:<\/p>\n\n\n\n<pre style=\"background: rgb(245, 245, 245); border-radius: 6px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; color: #333; font-family: menlo, monaco, monospace; font-style: inherit; font-weight: inherit; line-height: 15.68px; margin-bottom: 1.1em; max-width: 100%; outline: 0px; overflow: auto; padding: 13.125px 16.4062px; vertical-align: baseline; white-space: pre-wrap; word-wrap: break-word;\">import { Component } from '@angular\/core';\nimport { RouterOutlet } from '@angular\/router';\nimport { AlertService, Alert } from '..\/..\/services\/alert.service'\nimport { CommonModule } from '@angular\/common';\n\n@Component({\n\tselector: 'app-alert',\n\tstandalone: true,\n\timports: [RouterOutlet, AlertComponent,CommonModule],\n\ttemplateUrl: '.\/alert.component.html',\n\tstyleUrl: '.\/alert.component.css'\n})\n\nexport class AlertComponent {\n\talerts: Alert[] = [];\n\tshow: boolean = false;\n\n\tconstructor(private alertService: AlertService) { }\n\n\tngOnInit(): void {\n\t\tthis.alertService.alerts$.subscribe(alerts => {\n\t\t\tthis.alerts = alerts\n\t\t})\n\t}\n\n\tgetIcon(type: string): string {\n\t\tswitch (type) {\n\t\t\tcase 'danger':\n\t\t\t\treturn 'bi bi-x-circle'\n\t\t\tcase 'info':\n\t\t\t\treturn 'bi bi-info-circle'\n\t\t\tcase 'success':\n\t\t\t\treturn 'bi bi-check-circle'\n\t\t\tcase 'warning':\n\t\t\t\treturn 'bi bi-exclamation-circle'\n\t\t\tdefault:\n\t\t\t\treturn ''\n\t\t}\n\t}\n\n\tcloseAlert(id: number) {\n\t\tthis.alertService.removeAlert(id)\n\t}\n}\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Abrir el archivo alert.component.html<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@for (alert of alerts; track alert) {\n\t&lt;div &#91;className]=\"'alert alert-notify alert-dismissible fade show col-xl-8 col-lg-8 col-md-7 col-sm-8 col-10 alert-'+alert.type\"\n\t\trole=\"alert\" &#91;class]=\"{'show': alert.show, 'fade-out': !alert.show}\"&gt;\n\t\t&lt;div class=\"w-100\"&gt;\n\t\t\t&lt;i &#91;class]=\"getIcon(alert.type)\"&gt;&lt;\/i&gt; {{alert.message }}\n\t\t&lt;\/div&gt;\n\t\t&lt;button type=\"button\" class=\"btn-close\" (click)=\"closeAlert(alert.id)\" aria-label=\"Close\"&gt;&lt;\/button&gt;\n\t&lt;\/div&gt;\n\t}\n&lt;\/div&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Abrir el archivo alert.component.css<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.alert-container {\n\tposition: fixed;\n\ttop: 20px;\n\tright: 20px;\n\tz-index: 1050;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: flex-end;\n\tgap: 0px;\n}\n.alert {\n\topacity: 0;\n\ttransform: translateY(-20px);\n\ttransition: opacity 0.5s ease-out, transform 0.5s ease-out;\n}\n\n.alert.show {\n\topacity: 1;\n\ttransform: translateY(0);\n}\n\n.alert.fade-out {\n\topacity: 0;\n\ttransform: translateY(-20px);\n}\n\n.alert-notify{\n\tpadding: 6px 30px 6px 6px;\n}\n\n.alert-notify .btn-close{\n\tmargin-top: 5px;\n\tpadding: 6px;\n}<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Configurar app.component<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Buscar el archivo app.component.ts y modificarlo de la siguiente manera:<\/p>\n\n\n\nimport { Component } from &#8216;@angular\/core&#8217;;\nimport { AlertService, AlertType } from &#8216;.\/services\/alert.service&#8217;\nimport { AlertComponent } from &#8216;.\/components\/alert\/alert.component&#8217;;\nimport { CommonModule } from &#8216;@angular\/common&#8217;;\n\n@Component({\n\tselector: &#8216;app-root&#8217;,\n\tstandalone: true,\n\timports: [AlertComponent,CommonModule],\n\ttemplateUrl: &#8216;.\/app.component.html&#8217;,\n\tstyleUrl: &#8216;.\/app.component.css&#8217;\n})\n\nexport class AppComponent {\n\ttitle = &#8216;Notify Bootstrap Style&#8217;;\n\n\tmessage: string = \u00bb;\n\tshow: boolean = false;\n\n\tconstructor(\n\t\tprivate alertService: AlertService\n\t) {\n\n\t}\n\n\ttriggerAlert(message: string, type: AlertType) {\n\t\tthis.alertService.showAlert(message, type)\n\t}\n}\n\n\n\n<p class=\"wp-block-paragraph\">El archivo app.component.html modificarlo de la siguiente manera:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;div class=\"container\">\n\t&lt;div class=\"row justify-content-center\">\n\t\t&lt;div class=\"col-md-12\">\n\t\t\t&lt;app-alert>&lt;\/app-alert>\n\t\t&lt;\/div>\n\t\t&lt;div class=\"col-lg-9 col-md-8 col-12\">\n\t\t\t&lt;div class=\"row\">\n\t\t\t\t&lt;div class=\"col-md-12 justify-content-center text-center\">\n\t\t\t\t\t&lt;img class=\"img-fluid\" src=\"..\/assets\/images\/logo.svg\" alt width=\"72\" height=\"72\" \/>\n\t\t\t\t\t&lt;h1 class=\"h3 mb-3 fw-normal\">Alertas&lt;\/h1>\n\t\t\t\t&lt;\/div>\n\t\t\t&lt;\/div>\n\t\t\t&lt;div class=\"row\">\n\t\t\t\t&lt;div class=\"col-md-12 d-flex justify-content-center\">\n\t\t\t\t\t&lt;button type=\"button\" (click)=\"triggerAlert('Un tipo de alerta informativa!', 'info')\"\n\t\t\t\t\t\tclass=\"btn btn-primary\">\n\t\t\t\t\t\tAlerta &lt;i class=\"bi bi-eye\">&lt;\/i>\n\t\t\t\t\t&lt;\/button>\n\t\t\t\t\t&lt;button type=\"button\" (click)=\"triggerAlert('Tipo de alerta o notificaci\u00f3n de error', 'danger')\"\n\t\t\t\t\t\tclass=\"btn btn-danger mx-2\">\n\t\t\t\t\t\tAlerta &lt;i class=\"bi bi-eye\">&lt;\/i>\n\t\t\t\t\t&lt;\/button>\n\t\t\t\t\t&lt;button type=\"button\" (click)=\"triggerAlert('Tipo de alerta de existosa!', 'success')\"\n\t\t\t\t\t\tclass=\"btn btn-success mx-2\">\n\t\t\t\t\t\tAlerta &lt;i class=\"bi bi-eye\">&lt;\/i>\n\t\t\t\t\t&lt;\/button>\n\t\t\t\t\t&lt;button type=\"button\"\n\t\t\t\t\t\t(click)=\"triggerAlert('Tipo de alerta de que algo requiere atenci\u00f3n, no a nivel de error!', 'warning')\"\n\t\t\t\t\t\tclass=\"btn btn-warning\">\n\t\t\t\t\t\tAlerta &lt;i class=\"bi bi-eye\">&lt;\/i>\n\t\t\t\t\t&lt;\/button>\n\t\t\t\t&lt;\/div>\n\t\t\t&lt;\/div>\n\n\t\t\t&lt;div class=\"row\">\n\t\t\t\t&lt;div class=\"col-md-12\">\n\t\t\t\t\t&lt;p class=\"mt-5 mb-3 text-body-secondary text-center\">&lt;a href=\"https:\/\/linuxitos.com\/\"\n\t\t\t\t\t\t\ttarget=\"_blank\">linuxitos&lt;\/a> \u00a9 2017-2024&lt;\/p>\n\t\t\t\t&lt;\/div>\n\t\t\t&lt;\/div>\n\t\t&lt;\/div>\n\t&lt;\/div>\n&lt;\/div><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Archivo style.css el cu\u00e1l corresponde al archivo principal de todo el proyecto:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.menu-card {\n    width: 100%;\n    height: 37px;\n    background-color: rgba(0, 0, 0, 0.03);\n    padding-inline: 20px 0px;\n}\n\n.btnMenu {\n    cursor: pointer;\n    line-height: 35px;\n    border: 0;\n    font-size: 0.9rem;\n}\n\n.btnMenu:hover {\n    background-color: white;\n}\n\n.active {\n    color: #CC3333;\n    background-color: #fff;\n    font-weight: 700;\n    border-bottom: 1px solid #CC3333;\n}\n\n.active {\n    color: #CC3333;\n    background-color: #fff;\n    font-weight: 700;\n    border-bottom: 1px solid #CC3333;\n}\n\ndiv.centerTable {\n    text-align: center;\n    padding: 10px;\n    overflow-x:auto;\n}\n\ndiv.centerTable table {\n    margin: 0 auto;\n    text-align: left;\n}\n\n.color_White {\n    color: white;\n}\n\n.contenedor {\n    height: 400px;\n    border-radius: 10px;\n    border: 1px solid #ced4da;\n    margin-top: 25px;\n    margin-bottom: 25px;\n}\n\n.prueba1 {\n    color: white;\n}\n\n.colorgenerate, #tablaListado2 thead{\n    color: white;\n    background-color: #CC3333;\n}\n\n#divCabezero {\n    background-color: #CC3333;\n    margin: 0px 0px 20px 0px;\n    width: 100%;\n    color: white;\n    display: flex;\n}\n\n#Sucursal {\n    float:right;\n}\n\n#btnNuevo {\n    cursor: pointer;\n}\n\n#ddlConceptos {\n    cursor: pointer;\n}\n\n#add-sku-ubi {\n    cursor: pointer;\n}\n\n.table-responsivee {\n    height: 400px;\n    overflow-y: auto;\n}\n\n.list-sku {\n    cursor: pointer;\n}\n\n.list-sku:hover {\n    color: #FFFFFF;\n    background-color: #000000;\n}\n\n#label-nc {\n    border: 1px solid gray;\n    height: 221px;\n    padding: 10px;\n}\n\n#label-ne {\n    border: 1px solid gray;\n    height: 221px;\n    padding: 10px;\n}\n\n#txtUsuario {\n    width: 25%;\n}\n\n#txtObservaciones {\n    width: 50%;\n}\n\n#rowCargo {\n    margin-top: 2px;\n}\n\nbody {\n    margin-top: 1%;\n}\n\n.panel-heading {\n    padding: 15px 15px;\n}\n\n#loadImg {\n    margin-top: 10%;\n    margin-left: 42%;\n}\n\n#tdetalle {\n    overflow-y: auto;\n    height: 100px;\n}\n\n.disabledbutton {\n    pointer-events: none;\n    opacity: 0.4;\n}\n\n.mover-mensajes-info {\n    transform: translate(0px, 49px);\n}\n\n.hidden {\n    visibility: hidden;\n}\n\n.loading {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    top: 0;\n    left: 0;\n    position: fixed;\n    z-index: 10000 !important;\n    padding: 0;\n    margin: 0;\n    width: 100%;\n    height: 100vh;\n    opacity: 0.2;\n    background-color: #999988;\n}\n\n.imgLoading {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    top: 0;\n    left: 0;\n    position: fixed;\n    z-index: 10000 !important;\n    padding: 0;\n    margin: 0;\n    width: 100%;\n    height: 100vh;\n}\n\n.Listado tbody {\n    display: block;\n    height: calc(50vh - 1px);\n    min-height: calc(200px + 1 px);\n    overflow-Y: scroll;\n    color: #000;\n}\n\n.Listado tr {\n    display: block;\n    overflow: hidden;\n    cursor: pointer;\n}\n\n.Listado tbody tr:nth-child(odd) {\n    background: rgba(0,0,0,.1);\n}\n\n.Listado td {\n    width: 30%;\n    float: left;\n}\n\n.Listado th {\n    width: 30%;\n    float: left;\n}\n\n.Listado td {\n    padding: .1rem 0 .1em 1rem;\n    border-right: 2px solid rgba(0,0,0,.2);\n}\n\n.Listado th:last-child {\n    width: 70%;\n    text-align: center;\n    border-right: 0 none;\n    padding-left: 0;\n}\n\n.Listado td:last-child {\n    width: 70%;\n    text-align: center;\n    border-right: 0 none;\n    padding-left: 0;\n}\n\n.spin-10x {\n    width: 10rem;\n    height: 10rem;\n}\n\n.spin-10x {\n    width: 10rem;\n    height: 10rem;\n}\n\n.spin-10x {\n    width: 10rem;\n    height: 10rem;\n}\n.spin-13x {\n    width: 13rem;\n    height: 13rem;\n}\n\n.bg-ekt {\n    background-color: #CC3333;\n}\n\n&#91;class*=\"swal-button--\"] {\n    background-color: #0d6efd;\n    border: 1px solid #0d6efd;\n    text-shadow: none;\n    font-size: 1rem;\n    font-weight: 400;\n    line-height: 1.5;\n}\n\n&#91;class*=\"swal-button--\"]:hover, &#91;class*=\"swal-button--\"]:active {\n    background-color: #0b5ed7 !important;\n    border: 1px solid #0b5ed7;\n    text-shadow: none;\n    color: #fff;\n}\n\n.swal-button {\n    box-shadow: none;\n    text-shadow: none;\n}\n\n.swal-text {\n    color:#212529;\n}\n\n.swal-button--confirm {\n    background-color: #0d6efd;\n    border: 1px solid #0d6efd;\n    text-shadow: none;\n}\n\n.swal-button--cancel {\n    background-color: #dc3545;\n    border: 1px solid #dc3545;\n    text-shadow: none;\n    color: #fff;\n}\n\n.swal-button--defeat {\n    background-color: #6c757d;\n    border: 1px solid #6c757d;\n    text-shadow: none;\n    color: #fff;\n}\n\n.swal-button--catch {\n    background-color: #198754;\n    border: 1px solid #198754;\n    text-shadow: none;\n    color: #fff;\n}\n\n.swal-button--catch:hover, .swal-button--catch:active {\n    background-color: #157347 !important;\n    border: 1px solid #157347;\n    text-shadow: none;\n    color: #fff;\n}\n\n.swal-button--cancel:hover, .swal-button--cancel:active {\n    background-color: #bb2d3b !important;\n    border: 1px solid #bb2d3b;\n    text-shadow: none;\n    color: #fff;\n}\n\n.swal-button--defeat:hover, .swal-button--defeat:active {\n    background-color: #5c636a !important;\n    border: 1px solid #5c636a;\n    text-shadow: none;\n    color: #fff;\n}\n\n.swal-button--confirm:hover, .swal-button--confirm:active {\n    background-color: #0b5ed7 !important;\n    border: 1px solid #0b5ed7;\n    text-shadow: none;\n    color: #fff;\n}\n\n.btn-block {\n    display: block;\n    width: 100%;\n}\n\n.swal-modal-md {\n    width: 700px;\n}\n\n.form-control:focus {\n    box-shadow: none;\n}\n\n\/** float label inputs **\/\n.has-float-label {\n    position: relative;\n    width: 100%;\n    display:inline;\n}\n\n.has-float-label label {\n    position: absolute;\n    left: 0;\n    top: 0;\n    cursor: text;\n    font-size: 75%;\n    opacity: 1;\n    -webkit-transition: all .2s;\n    transition: all .2s;\n    top: -.5em;\n    left: 12px;\n    z-index: 3;\n    line-height: 1;\n    padding: 0 1px;\n}\n\n.has-float-label label::after {\n    content: \" \";\n    display: block;\n    position: absolute;\n    background: white;\n    height: 2px;\n    top: 50%;\n    left: -.2em;\n    right: -.2em;\n    z-index: -1;\n}\n\n.has-float-label .form-control::-webkit-input-placeholder {\n    opacity: 1;\n    -webkit-transition: all .2s;\n    transition: all .2s;\n}\n\n.has-float-label .form-control:placeholder-shown:not(:focus)::-webkit-input-placeholder {\n    opacity: 0;\n}\n\n.has-float-label .form-control:placeholder-shown:not(:focus) + label {\n    opacity: .5;\n    top: .3em;\n    font-weight: normal;\n}\n\n.input-group .has-float-label {\n    display: table-cell;\n}\n\n.input-group .has-float-label .form-control {\n    border-radius: 4px;\n}\n\n.input-group .has-float-label:not(:last-child) .form-control {\n    border-bottom-right-radius: 0;\n    border-top-right-radius: 0;\n}\n\n.input-group .has-float-label:not(:first-child) .form-control {\n    border-bottom-left-radius: 0;\n    border-top-left-radius: 0;\n    margin-left: -1px;\n}\n\n.has-float-label input:focus, .has-float-label textarea:focus, .has-float-label select:focus {\n    border-color: #0d47a1;\n    box-shadow: none;\n}\n\n.has-float-label .form-control:placeholder-shown:not(:focus) + * {\n    font-size: 100%;\n    margin-top: 4px;\n}\n\n.form-icon {\n    position: absolute;\n    top: 0;\n    right: 0;\n    z-index: 2;\n    display: block;\n    width: 34px;\n    height: 34px;\n    line-height: 34px;\n    text-align: center;\n    pointer-events: none;\n    margin-right: 5px;\n}\n\n.table > tbody > tr > td {\n    vertical-align: middle;\n}\n\n.selectores-format{\n    text-align: center !important;\n}\n\n.txtPedidoGuia {\n    text-transform: uppercase;\n}\n\n.w-5 {\n    width: 5%;\n}\n\n.w-10 {\n    width: 10%;\n}\n\n.w-15 {\n    width: 15%;\n}\n\n.w-20 {\n    width: 20% !important;\n}\n\n.w-30 {\n    width: 30% !important;\n}\n\n.w-40 {\n    width: 40% !important;\n}\n\n.w-50 {\n    width: 50% !important;\n}\n\n.w-60 {\n    width: 60% !important;\n}\n\n.w-70 {\n    width: 70% !important;\n}\n\n.w-80 {\n    width: 80% !important;\n}\n\n.bi-enter {\n    background: url('data:image\/svg+xml;charset=UTF-8,%3Csvg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"30\" height=\"30\" aria-label=\"Enter key\" class=\"bi bi-enter\" viewBox=\"0 0 16 16\"%3E%3Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.2\"%3E%3Cpath d=\"M12 3.53088v3c0 1-1 2-2 2H4M7 11.53088l-3-3 3-3\"%3E%3C\/path%3E%3C\/g%3E%3C\/svg%3E') no-repeat;\n}\n\n.bi {\n    display: inline-block;\n    vertical-align: -0.125em !important;\n    fill: currentcolor;\n}\n\n.form-icon {\n    margin-top:2px;\n    position: absolute;\n    top: 0;\n    right: 0;\n    z-index: 0;\n    display: block;\n    width: 34px;\n    height: 34px;\n    line-height: 34px;\n    text-align: center;\n    pointer-events: none;\n    margin-right: 5px;\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Ejecuci\u00f3n del proyecto<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Finalmente ejecutar el siguiente comando para lanzar la aplicaci\u00f3n y luego abrir desde el navegador con la url <a href=\"http:\/\/localhost:4200\/\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/localhost:4200\/<\/a>.<\/p>\n\n\n\n<pre style=\"background: rgb(54, 63, 72); border-radius: 6px; border: 0px; box-sizing: border-box; color: white; font-family: menlo, monaco, monospace; font-style: inherit; font-weight: inherit; line-height: 15.68px; margin-bottom: 1.1em; max-width: 100%; outline: 0px; overflow: auto; padding: 13.125px 16.4062px; vertical-align: baseline; white-space: pre-wrap; word-wrap: break-word;\">ng serve<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Deber\u00e1 mostrar algo similar:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/a.gif\"><img loading=\"lazy\" decoding=\"async\" width=\"969\" height=\"664\" src=\"https:\/\/linuxitos.com\/main\/wp-content\/uploads\/2024\/11\/a.gif\" alt=\"\" class=\"wp-image-4462\"\/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Si por alguna raz\u00f3n no les funciona, pueden dejar su comentario, o bien clonar el proyecto desde aqu\u00ed: <a href=\"https:\/\/gitlab.com\/linuxitos\/notify-bootstrap-angular\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/gitlab.com\/linuxitos\/notify-bootstrap-angular<\/a> aqu\u00ed solo basta clonarlo, instalar dependencias y el comando.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Contexto Estoy realizando una migraci\u00f3n de de front a angular de un proyecto algo ampl\u00edo, y dentro de las migraciones, se requiere enviar notificaciones a pantalla. Pero las notificaciones deben ser no intrusivas que necesiten forzosamente la intervenci\u00f3n del usuario, ya sea mediante click o esc. En la anterior plataforma se us\u00f3 un sistema de [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":4451,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1540,1543,1092],"tags":[2020,1634,2021,2022],"class_list":["post-4448","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-develepmet","category-developer","category-nodev","tag-angular","tag-bootstrap","tag-node","tag-notifications"],"_links":{"self":[{"href":"https:\/\/linuxitos.com\/main\/wp-json\/wp\/v2\/posts\/4448","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/linuxitos.com\/main\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/linuxitos.com\/main\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/linuxitos.com\/main\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/linuxitos.com\/main\/wp-json\/wp\/v2\/comments?post=4448"}],"version-history":[{"count":9,"href":"https:\/\/linuxitos.com\/main\/wp-json\/wp\/v2\/posts\/4448\/revisions"}],"predecessor-version":[{"id":4464,"href":"https:\/\/linuxitos.com\/main\/wp-json\/wp\/v2\/posts\/4448\/revisions\/4464"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/linuxitos.com\/main\/wp-json\/wp\/v2\/media\/4451"}],"wp:attachment":[{"href":"https:\/\/linuxitos.com\/main\/wp-json\/wp\/v2\/media?parent=4448"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/linuxitos.com\/main\/wp-json\/wp\/v2\/categories?post=4448"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/linuxitos.com\/main\/wp-json\/wp\/v2\/tags?post=4448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}