Skip to content

Commit

Permalink
refactor: system-alert component updates
Browse files Browse the repository at this point in the history
* Updated dom/styling to use flexbox vs table.
* Removed system-alert-icon component.
* No longer using ngx-bootstrap alert component.  It was a thin wrapper around the bootstrap alert component styling.
* Added animation when adding/remove alerts
* Alert types (color/icon) are now defined in scss maps.  These can be overridden to easily add additional alert types.
  • Loading branch information
jrassa committed Aug 9, 2023
1 parent 258f0f2 commit 8bd502b
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 122 deletions.
6 changes: 0 additions & 6 deletions src/app/common/system-alert/system-alert-icon.component.html

This file was deleted.

12 changes: 0 additions & 12 deletions src/app/common/system-alert/system-alert-icon.component.ts

This file was deleted.

33 changes: 13 additions & 20 deletions src/app/common/system-alert/system-alert.component.html
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
<alert
[type]="alert.type"
<div
class="alert alert-{{ alert.type }} d-flex"
role="alert"
*ngFor="let alert of alertService.alerts$ | async; let i = index"
[dismissible]="true"
(close)="alertService.clear(i)"
@animateAddRemove
>
<table aria-describedby="System alerts">
<tbody>
<tr>
<th class="align-middle" scope="row">
<system-alert-icon [icon]="alert.type"></system-alert-icon>
</th>
<td class="align-middle">
<div class="system-alert-message">{{ alert.msg }}</div>
<div class="system-alert-subtext" *ngIf="alert.subtext">
{{ alert.subtext }}
</div>
</td>
</tr>
</tbody>
</table>
</alert>
<span class="fa-solid fa-fw system-alert-icon system-alert-icon-{{ alert.type }}"></span>
<div class="system-alert-content">
<div class="system-alert-message">{{ alert.msg }}</div>
<small *ngIf="alert.subtext">{{ alert.subtext }}</small>
</div>
<button class="close" type="button" aria-label="Close" (click)="clearAlert(i)">
<span aria-hidden="true">×</span>
</button>
</div>
105 changes: 49 additions & 56 deletions src/app/common/system-alert/system-alert.component.scss
Original file line number Diff line number Diff line change
@@ -1,74 +1,67 @@
@use 'sass:map';
@import '../../../styles/shared';
@import '../../../styles/ngx-bootstrap/shared';

:host ::ng-deep .alert {
.alert-icon {
margin-left: -5px;
margin-right: 5px;
$system-alert-colors: () !default;
$system-alert-colors: map.merge(
(
'success': $ux-color-alert-success,
'info': $ux-color-alert-notification,
'warning': $ux-color-alert-warning,
'danger': $ux-color-alert-error
),
$system-alert-colors
);

.fa-fw {
font-size: 30px;
}
}

.system-alert-message {
@include font-normal(16px);
color: $ux-color-body-text;
}
$system-alert-icons: () !default;
$system-alert-icons: map.merge(
(
'success': '\f058',
'info': '\f05a',
'warning': '\f06a',
'danger': '\f071'
),
$system-alert-icons
);

.system-alert-subtext {
@include font-normal(12px);
color: $ux-color-body-text;
}

&.alert-success {
@include border($ux-color-alert-success, 2px, 3px);
background: $ux-color-white;
.alert {
@include border($ux-color-alert-success, 2px, 3px);
background: $ux-color-white;
display: flex;
align-items: center;
padding: 0 $alert-padding-x;
overflow: hidden;

.alert-icon {
.fa-fw {
color: $ux-color-alert-success;
}
@each $type, $color in $system-alert-colors {
&.alert-#{$type} {
border-color: $color;
}
}

&.alert-danger {
@include border($ux-color-alert-error, 2px, 3px);
background: $ux-color-white;
.system-alert-icon-#{$type} {
color: $color;

.alert-icon {
.fa-fw {
color: $ux-color-alert-error;
&:before {
content: map.get($system-alert-icons, $type);
}
}
}

&.alert-warning {
@include border($ux-color-alert-warning, 2px, 3px);
background: $ux-color-white;

.alert-icon {
.fa-fw {
color: $ux-color-alert-warning;
}
}
.system-alert-icon {
font-size: 30px;
margin-right: $spacer;
}

&.alert-info {
@include border($ux-color-alert-notification, 2px, 3px);
background: $ux-color-white;

.alert-icon {
.fa-fw {
color: $ux-color-alert-notification;
}
}
.system-alert-content {
color: $ux-color-body-text;
font-size: 16px;
flex-grow: 1;
padding: 1rem 0;
}

button {
&.close {
color: $ux-color-body-text;
opacity: 1;
padding: 1rem 1.25rem;
}
button.close {
color: $ux-color-body-text;
opacity: 1;
padding: 1rem 0 1rem 1.25rem;
align-self: flex-start;
}
}
25 changes: 21 additions & 4 deletions src/app/common/system-alert/system-alert.component.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
import { animate, style, transition, trigger } from '@angular/animations';
import { AsyncPipe, NgFor, NgIf } from '@angular/common';
import { Component } from '@angular/core';
import { Component, inject } from '@angular/core';

import { AlertModule } from 'ngx-bootstrap/alert';

import { SystemAlertIconComponent } from './system-alert-icon.component';
import { SystemAlertService } from './system-alert.service';

@Component({
selector: 'system-alert',
templateUrl: 'system-alert.component.html',
styleUrls: ['system-alert.component.scss'],
animations: [
trigger('animateAddRemove', [
transition(':enter', [
style({ border: 0, height: 0, margin: 0, opacity: 0, overflow: 'hidden' }),
animate('200ms ease-in-out', style({ height: '*', margin: '*', opacity: 1 })),
style({ overflow: 'auto' })
]),
transition(':leave', [
style({ overflow: 'hidden' }),
animate('200ms ease-in-out', style({ border: 0, height: 0, margin: 0, opacity: 0 }))
])
])
],
standalone: true,
imports: [NgFor, AlertModule, SystemAlertIconComponent, NgIf, AsyncPipe]
imports: [NgFor, AlertModule, NgIf, AsyncPipe]
})
export class SystemAlertComponent {
constructor(public alertService: SystemAlertService) {}
alertService = inject(SystemAlertService);

clearAlert(index: number) {
this.alertService.clear(index);
}
}
2 changes: 1 addition & 1 deletion src/app/common/system-alert/system-alert.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class SystemAlertService {
this.alerts.push(alert);

// If they passed in a ttl parameter, age off the alert after said timeout
if (null != ttl) {
if (ttl && ttl > 0) {
setTimeout(() => this.clearAlertById(alert.id), ttl);
}
this.alerts$.next(this.alerts);
Expand Down
62 changes: 43 additions & 19 deletions src/app/site/example/alerts/alerts.component.html
Original file line number Diff line number Diff line change
@@ -1,28 +1,52 @@
<div class="container">
<h1>System Alerts</h1>
<div class="row">
<div class="col-md-3">
<button class="mr-3 btn btn-primary" (click)="addAlert('Success', 'success')">
Success
</button>
</div>
<div class="col-md-3">
<button class="mr-3 btn btn-primary" (click)="addAlert('Danger', 'danger')">
Danger
</button>
<div class="row mt-3">
<div class="col-md-12">
<system-alert></system-alert>
</div>
<div class="col-md-3">
<button class="mr-3 btn btn-primary" (click)="addAlert('Warning', 'warning')">
Warning
</button>
</div>

<h2 class="mt-3">Add Alert</h2>

<div class="form-row">
<div class="form-group col">
<label for="type">Type</label>
<ng-select
id="type"
[(ngModel)]="type"
[items]="['success', 'danger', 'warning', 'info']"
>
<ng-template let-item="item" ng-label-tmp ng-option-tmp>
{{ item | titlecase }}
</ng-template>
</ng-select>
</div>
<div class="col-md-3">
<button class="mr-3 btn btn-primary" (click)="addAlert('Info', 'info')">Info</button>
<div class="form-group col">
<label for="message">TTL <small>(milliseconds)</small></label>
<input class="form-control" id="ttl" type="number" [(ngModel)]="ttl" />
</div>
</div>
<div class="row mt-3">
<div class="col-md-12">
<system-alert></system-alert>

<div class="form-row">
<div class="form-group col">
<label for="message">Message</label>
<textarea
class="form-control"
id="message"
type="text"
[(ngModel)]="message"
></textarea>
</div>
<div class="form-group col">
<label for="message">Subtext</label>
<textarea
class="form-control"
id="subtext"
type="text"
[(ngModel)]="subtext"
></textarea>
</div>
</div>

<button class="btn btn-primary" (click)="addAlert()">Add Alert</button>
</div>
16 changes: 12 additions & 4 deletions src/app/site/example/alerts/alerts.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { TitleCasePipe } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { NgSelectModule } from '@ng-select/ng-select';
import { UntilDestroy } from '@ngneat/until-destroy';

import { SystemAlertComponent } from '../../../common/system-alert/system-alert.component';
Expand All @@ -9,19 +12,24 @@ import { SystemAlertService } from '../../../common/system-alert/system-alert.se
@Component({
templateUrl: './alerts.component.html',
standalone: true,
imports: [SystemAlertComponent]
imports: [SystemAlertComponent, FormsModule, NgSelectModule, TitleCasePipe]
})
export class AlertsComponent implements OnInit {
message = '';
type = 'success';
subtext = '';
ttl = 0;

constructor(public alertService: SystemAlertService) {}
ngOnInit(): void {
this.alertService.clearAllAlerts();
this.alertService.addAlert('Success', 'success');
this.alertService.addAlert('Success', 'success', 0, 'subtext');
this.alertService.addAlert('Danger', 'danger');
this.alertService.addAlert('Warning', 'warning');
this.alertService.addAlert('Info', 'info');
}

addAlert(msg: string, type: string): void {
this.alertService.addAlert(msg, type);
addAlert(): void {
this.alertService.addAlert(this.message, this.type, this.ttl, this.subtext);
}
}

0 comments on commit 8bd502b

Please sign in to comment.