ngx-beacon-notify 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/beacon/beacon.component.css +175 -0
  2. package/beacon/beacon.component.html +46 -0
  3. package/beacon/beacon.component.spec.ts +21 -0
  4. package/beacon/beacon.component.ts +142 -0
  5. package/beacon-notify.module.ts +43 -0
  6. package/beacon-notify.service.ts +634 -0
  7. package/container/container.component.css +10 -0
  8. package/container/container.component.html +3 -0
  9. package/container/container.component.spec.ts +21 -0
  10. package/container/container.component.ts +62 -0
  11. package/icons/beacon-icon-alert/beacon-icon-alert.component.css +6 -0
  12. package/icons/beacon-icon-alert/beacon-icon-alert.component.html +10 -0
  13. package/icons/beacon-icon-alert/beacon-icon-alert.component.spec.ts +21 -0
  14. package/icons/beacon-icon-alert/beacon-icon-alert.component.ts +10 -0
  15. package/icons/beacon-icon-error/beacon-icon-error.component.css +6 -0
  16. package/icons/beacon-icon-error/beacon-icon-error.component.html +13 -0
  17. package/icons/beacon-icon-error/beacon-icon-error.component.spec.ts +21 -0
  18. package/icons/beacon-icon-error/beacon-icon-error.component.ts +10 -0
  19. package/icons/beacon-icon-info/beacon-icon-info.component.css +6 -0
  20. package/icons/beacon-icon-info/beacon-icon-info.component.html +14 -0
  21. package/icons/beacon-icon-info/beacon-icon-info.component.spec.ts +21 -0
  22. package/icons/beacon-icon-info/beacon-icon-info.component.ts +10 -0
  23. package/icons/beacon-icon-success/beacon-icon-success.component.css +6 -0
  24. package/icons/beacon-icon-success/beacon-icon-success.component.html +13 -0
  25. package/icons/beacon-icon-success/beacon-icon-success.component.spec.ts +21 -0
  26. package/icons/beacon-icon-success/beacon-icon-success.component.ts +9 -0
  27. package/icons/beacon-icon-warning/beacon-icon-warning.component.css +6 -0
  28. package/icons/beacon-icon-warning/beacon-icon-warning.component.html +15 -0
  29. package/icons/beacon-icon-warning/beacon-icon-warning.component.spec.ts +21 -0
  30. package/icons/beacon-icon-warning/beacon-icon-warning.component.ts +10 -0
  31. package/index.d.ts +1 -0
  32. package/index.ts +2 -0
  33. package/package.json +16 -0
  34. package/pipes/beacon-type-resolve.pipe.spec.ts +8 -0
  35. package/pipes/beacon-type-resolve.pipe.ts +33 -0
  36. package/types/constants/index.ts +8 -0
  37. package/types/index.ts +3 -0
  38. package/types/interfaces/index.ts +110 -0
@@ -0,0 +1,175 @@
1
+ .beacon-message-control {
2
+ width: 270px;
3
+ height: auto;
4
+ background: #eeeeee;
5
+ margin: 6px;
6
+ border-radius: 4px;
7
+ position: relative;
8
+ z-index: 4000;
9
+ cursor: pointer;
10
+ }
11
+ .beacon-message-control:hover {
12
+ box-shadow: 0 0 20px #44444433;
13
+ }
14
+ .beacon-message-control-no-hover-effect {
15
+ box-shadow: none !important;
16
+ }
17
+ .beacon-message-control-animate {
18
+ -webkit-animation: beacon-fade-out .5s 7s linear forwards;
19
+ animation: beacon-fade-out .5s 7s linear forwards;
20
+ }
21
+ .beacon-message-header,
22
+ .beacon-message-body,
23
+ .beacon-message-footer {
24
+ padding: 8px;
25
+ font-size: 14px;
26
+ }
27
+ .beacon-message-header {
28
+ font-weight: bold;
29
+ display: flex;
30
+ font-size: 15px;
31
+ }
32
+ .beacon-message-header > div:first-child {
33
+ flex-grow: 1;
34
+ display: flex;
35
+ place-items: flex-start;
36
+ word-break: break-all;
37
+ }
38
+ .beacon-message-header > div:first-child i {
39
+ font-size: 20px;
40
+ margin-right: 7px;
41
+ margin-top: 2px;
42
+ }
43
+ .beacon-message-header > div:last-child {
44
+ flex-grow: 0;
45
+ }
46
+ .beacon-message-divider {
47
+ border-top: 1px solid #44444433;
48
+ }
49
+ .beacon-message-close {
50
+ height: 22px;
51
+ width: 22px;
52
+ border: 1px solid #444444;
53
+ display: flex;
54
+ place-items: center;
55
+ place-content: center;
56
+ border-radius: 100%;
57
+ cursor: pointer;
58
+ opacity: .3;
59
+ }
60
+ .beacon-message-close svg rect {
61
+ fill: #444444;
62
+ }
63
+ .beacon-message-close:hover {
64
+ opacity: .7;
65
+ }
66
+ .beacon-message-alert {
67
+ background: #eeeeee;
68
+ color: #5E5E5E;
69
+ }
70
+ .beacon-message-alert .beacon-message-footer button {
71
+ border: 1px solid #5E5E5E;
72
+ color: #5E5E5E;
73
+ }
74
+ .beacon-message-alert .beacon-message-footer button:hover {
75
+ background: #5E5E5E;
76
+ color: #fff;
77
+ }
78
+ .beacon-message-success {
79
+ background: #F0FFF0;
80
+ color: #698B69;
81
+ }
82
+ .beacon-message-success .beacon-message-divider {
83
+ border-color: #698B6933;
84
+ }
85
+ .beacon-message-success .beacon-message-footer button {
86
+ border: 1px solid #698B69;
87
+ color: #698B69;
88
+ }
89
+ .beacon-message-success .beacon-message-footer button:hover {
90
+ background: #698B69;
91
+ color: #fff;
92
+ }
93
+ .beacon-message-error {
94
+ background: #FFE4E1;
95
+ color: #B22222;
96
+ }
97
+ .beacon-message-error .beacon-message-divider {
98
+ border-color: #EE3B3B33;
99
+ }
100
+ .beacon-message-error .beacon-message-footer button {
101
+ border: 1px solid #B22222;
102
+ color: #B22222;
103
+ }
104
+ .beacon-message-error .beacon-message-footer button:hover {
105
+ background: #B22222;
106
+ color: #fff;
107
+ }
108
+ .beacon-message-warning {
109
+ background: #FFFACD;
110
+ color: #B8860B;
111
+ }
112
+ .beacon-message-warning .beacon-message-divider {
113
+ border-color: #FFD70088;
114
+ }
115
+ .beacon-message-warning .beacon-message-footer button {
116
+ border: 1px solid #B8860B;
117
+ color: #B8860B;
118
+ }
119
+ .beacon-message-warning .beacon-message-footer button:hover {
120
+ background: #B8860B;
121
+ color: #fff;
122
+ }
123
+ .beacon-message-info {
124
+ background: #BFEFFF;
125
+ color: #4A708B;
126
+ }
127
+ .beacon-message-info .beacon-message-divider {
128
+ border-color: #5CACEE33;
129
+ }
130
+ .beacon-message-info .beacon-message-footer button {
131
+ border: 1px solid #4A708B;
132
+ color: #4A708B;
133
+ }
134
+ .beacon-message-info .beacon-message-footer button:hover {
135
+ background: #4A708B;
136
+ color: #fff;
137
+ }
138
+ .beacon-message-footer {
139
+ display: flex;
140
+ }
141
+ .beacon-message-footer > div:first-child {
142
+ flex-grow: 1;
143
+ }
144
+ .beacon-message-footer > div:last-child {
145
+ flex-grow: 1;
146
+ text-align: right;
147
+ }
148
+ .beacon-message-footer button {
149
+ padding: 4px 7px;
150
+ border-radius: 5px;
151
+ -webkit-border-radius: 5px;
152
+ -moz-border-radius: 5px;
153
+ background: transparent;
154
+ cursor: pointer;
155
+ }
156
+ .beacon-message-footer .beacon-message-button-container-left {
157
+ text-align: left !important;
158
+ }
159
+ .beacon-message-footer .beacon-message-button-container-center {
160
+ text-align: center !important;
161
+ }
162
+ .beacon-message-footer .beacon-message-button-container-right {
163
+ text-align: right !important;
164
+ }
165
+
166
+ @keyframes beacon-fade-out {
167
+ 90% {
168
+ opacity: 0;
169
+ display: none;
170
+ }
171
+ 100% {
172
+ opacity: 0;
173
+ display: none;
174
+ }
175
+ }
@@ -0,0 +1,46 @@
1
+ <div #beaconControl
2
+ [id]="'bc_' + beacon.bid"
3
+ (mouseenter)="autoClose(false, beaconControl)"
4
+ (mouseleave)="autoClose(true, beaconControl)"
5
+ (click)="beacon.preventClickClose ? null : closeBeacon(beaconControl, beacon)"
6
+ [attr.data-beacon-static]="beacon.static"
7
+ class="beacon-message-control {{ (beacon.static !== true && beacon.fixed !== true) ? beacon.animationClass : '' }} {{ beacon.replacementClass || beacon.type }} {{ beacon.styleClass }}"
8
+ [class.beacon-message-control-no-hover-effect]="beacon.noHoverEffect">
9
+ <div class="beacon-message-header">
10
+ <div>
11
+ <span *ngIf="beacon.fontIcon"><i [class]="beacon.icon"></i></span>
12
+ <span *ngIf="!beacon.fontIcon && beaconDefaultIconKeys.includes(beacon.icon)" class="beacon-message-svg-control">
13
+ <app-beacon-icon-alert *ngIf="beacon.icon | beaconTypeResolve:'alert'"></app-beacon-icon-alert>
14
+ <app-beacon-icon-error *ngIf="beacon.icon | beaconTypeResolve:'error'"></app-beacon-icon-error>
15
+ <app-beacon-icon-info *ngIf="beacon.icon | beaconTypeResolve:'info'"></app-beacon-icon-info>
16
+ <app-beacon-icon-success *ngIf="beacon.icon | beaconTypeResolve:'success'"></app-beacon-icon-success>
17
+ <app-beacon-icon-warning *ngIf="beacon.icon | beaconTypeResolve:'warning'"></app-beacon-icon-warning>
18
+ </span>
19
+ <span *ngIf="!beacon.fontIcon && beacon.icon && !beaconDefaultIconKeys.includes(beacon.icon)" class="beacon-message-svg-control" [innerHTML]="beacon.svgIcon"></span>
20
+ {{ beacon.title }}
21
+ </div>
22
+ <div>
23
+ <div *ngIf="!beacon.fixed" class="beacon-message-close" (click)="closeBeacon(beaconControl, beacon)">
24
+ <svg width="10" height="10" viewBox="0 0 78 78" fill="none" xmlns="http://www.w3.org/2000/svg">
25
+ <rect y="7.07104" width="10" height="100" rx="5" transform="rotate(-45 0 7.07104)" />
26
+ <rect x="70.7109" width="10" height="100" rx="5" transform="rotate(45 70.7109 0)" />
27
+ </svg>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ <div class="beacon-message-divider"></div>
32
+ <div class="beacon-message-body" [innerHTML]="beacon.bodyHtml"></div>
33
+ <div class="beacon-message-divider" *ngIf="beacon.buttons?.one || beacon.buttons?.two"></div>
34
+
35
+ <div class="beacon-message-footer" *ngIf="beacon.buttons && beacon.buttons.one && beacon.buttons.two">
36
+ <div><button (click)="beaconButtonClick($event, 1)">{{ beacon.buttons.one.text }}</button></div>
37
+ <div><button (click)="beaconButtonClick($event, 2)">{{ beacon.buttons.two.text }}</button></div>
38
+ </div>
39
+
40
+ <div class="beacon-message-footer" *ngIf="beacon.buttons && beacon.buttons.one && !beacon.buttons.two">
41
+ <div [class]="beacon.buttons.one.position ? ('beacon-message-button-container-' + beacon.buttons.one.position) : ''">
42
+ <button (click)="beaconButtonClick($event, 1)">{{ beacon.buttons.one.text }}</button>
43
+ </div>
44
+ </div>
45
+
46
+ </div>
@@ -0,0 +1,21 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { BeaconNotifyComponent } from './beacon.component';
4
+
5
+ describe('BeaconNotifyComponent', () => {
6
+ let component: BeaconNotifyComponent;
7
+ let fixture: ComponentFixture<BeaconNotifyComponent>;
8
+
9
+ beforeEach(() => {
10
+ TestBed.configureTestingModule({
11
+ declarations: [BeaconNotifyComponent]
12
+ });
13
+ fixture = TestBed.createComponent(BeaconNotifyComponent);
14
+ component = fixture.componentInstance;
15
+ fixture.detectChanges();
16
+ });
17
+
18
+ it('should create', () => {
19
+ expect(component).toBeTruthy();
20
+ });
21
+ });
@@ -0,0 +1,142 @@
1
+ import { Component, Input, AfterViewInit } from '@angular/core';
2
+ import { BeaconNotifyService } from '../beacon-notify.service';
3
+ import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
4
+ import { IBeaconConfig, IBeaconEventMessage } from '../types';
5
+
6
+ @Component({
7
+ selector: 'app-beacon',
8
+ templateUrl: './beacon.component.html',
9
+ styleUrls: ['./beacon.component.css']
10
+ })
11
+ export class BeaconNotifyComponent {
12
+ @Input() beacon!: IBeaconConfig
13
+ private beaconDOM!: HTMLElement
14
+ public beaconDefaultIconKeys!: string[]
15
+
16
+ constructor(private beaconService: BeaconNotifyService,
17
+ private sanitizer: DomSanitizer){
18
+ this.beaconDefaultIconKeys = this.beaconService.getBeaconDefaultIconKeys
19
+ }
20
+
21
+ ngOnInit(): void {
22
+ // Fire mount event
23
+ this.beaconService.beaconEventTaskMaster.emit({
24
+ mount: true,
25
+ id: this.beacon.bid
26
+ })
27
+ }
28
+
29
+ ngAfterViewInit(): void {
30
+ // Get beacon
31
+ const beacon = this.beaconDOM = this.beaconService.getBeaconContainer.nativeElement.querySelector(`#bc_${this.beacon.bid}`)
32
+ // Resolve possible focus for beacon
33
+ this.resolvePossibleFocusForBeacon(beacon)
34
+ setTimeout(() => {
35
+ // Resolve delay setting
36
+ this.resolveDelayForBeacon(beacon, true)
37
+ // Set beacon listener
38
+ this.setListenerForBeacon(beacon, this.beacon)
39
+
40
+ // Sanitize svg content if not font icon
41
+ if (this.beacon.svgIcon) {
42
+ const beaconSvgIcon = beacon.querySelector('span.beacon-message-svg-control svg')
43
+ beaconSvgIcon.style.width = '20px'
44
+ beaconSvgIcon.style.height = '20px'
45
+ beaconSvgIcon.style.marginRight = '7px'
46
+ beaconSvgIcon.style.marginTop = '-2px'
47
+ }
48
+ }, 0)
49
+
50
+ // Listen for event
51
+ this.beaconService.beaconEventTaskMaster.subscribe((message: IBeaconEventMessage) => {
52
+ // Check for next for focus event
53
+ if (message.autoDetectNextFocusBeacon)
54
+ this.resolvePossibleFocusForBeacon(this.beaconDOM, false)
55
+ })
56
+ }
57
+
58
+ // When beacon button is clicked
59
+ beaconButtonClick(e: Event, no: number): void {
60
+ e.stopPropagation()
61
+ switch (no) {
62
+ case 1:
63
+ // Check for callback
64
+ if (this.beacon?.buttons?.one?.callback)
65
+ this.beacon?.buttons?.one?.callback(this.beacon?.buttons?.one?.callbackArgs)
66
+
67
+ // Check if can dismiss
68
+ if (this.beacon?.buttons?.one?.canDismiss)
69
+ this.closeBeacon(this.beaconDOM, this.beacon)
70
+ break
71
+ case 2:
72
+ // Check for callback
73
+ if (this.beacon?.buttons?.two?.callback)
74
+ this.beacon?.buttons?.two?.callback(this.beacon?.buttons?.two?.callbackArgs)
75
+
76
+ // Check if can dismiss
77
+ if (this.beacon?.buttons?.two?.canDismiss)
78
+ this.closeBeacon(this.beaconDOM, this.beacon)
79
+ break
80
+ }
81
+ }
82
+
83
+ // Set listener for beacon changes
84
+ setListenerForBeacon(beacon: Element, beaconData: IBeaconConfig): void {
85
+ ((b, d) => {
86
+ beacon?.addEventListener('animationend', (e) => this.closeBeacon(b, d))
87
+ beacon?.addEventListener('webkitAnimationEnd', (e) => this.closeBeacon(b, d))
88
+ beacon?.addEventListener('oAnimationEnd', (e) => this.closeBeacon(b, d))
89
+ })(beacon, beaconData)
90
+ }
91
+
92
+ // Toggle auto-close
93
+ autoClose(status: boolean, control: HTMLElement): void {
94
+ status
95
+ ? (control.getAttribute('data-beacon-static') != 'true' && this.resolveDelayForBeacon(control, false))
96
+ : control.classList.remove(String(this.beacon.animationClass))
97
+ }
98
+
99
+ // Resolve delay for beacon
100
+ resolveDelayForBeacon(beacon: HTMLElement, onLoad?: boolean): void {
101
+ // Check if delay set
102
+ if (this.beacon.static && typeof this.beacon.static == 'number') {
103
+ beacon && (beacon.style.animationDelay = this.beacon.static + 's')
104
+ } else {
105
+ if (onLoad == !1 && this.beacon?.fixed != true)
106
+ beacon.classList.add(String(this.beacon.animationClass))
107
+ }
108
+ }
109
+
110
+ // Resolve focus beacon
111
+ resolvePossibleFocusForBeacon(beacon: HTMLElement, createOverlay: boolean = true): void {
112
+ const activeFocusBeaconId = this.beaconService.getActiveFocusBeaconId
113
+ if (activeFocusBeaconId == this.beacon.bid) {
114
+ beacon.style.zIndex = '9003'
115
+
116
+ // Check if beacon should be centered
117
+ if (this.beacon.shine) {
118
+ beacon.style.position = 'fixed'
119
+ beacon.style.right = '0'
120
+ beacon.style.left = '0'
121
+ beacon.style.bottom = '50%'
122
+ beacon.style.margin = 'auto'
123
+ beacon.style.transform = 'scale(1.6)'
124
+ }
125
+
126
+ // Create overlay
127
+ if (createOverlay)
128
+ this.beaconService.createBeaconFocusOverlay(this.beacon.overlayColor)
129
+ else this.beaconService.repaintBeaconFocusOverlay(this.beacon.overlayColor)
130
+ }
131
+ }
132
+
133
+ // Trigger close beacon
134
+ closeBeacon(beaconControl: any, beaconData: IBeaconConfig): void {
135
+ if (!this.beacon?.fixed) {
136
+ this.beaconService.beaconEventTaskMaster.emit({
137
+ delete: true,
138
+ id: beaconControl.getAttribute('id').replace(/bc_/, '')
139
+ })
140
+ }
141
+ }
142
+ }
@@ -0,0 +1,43 @@
1
+ import { NgModule, ModuleWithProviders } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { BeaconNotifyContainerComponent } from './container/container.component';
4
+ import { BeaconNotifyComponent } from './beacon/beacon.component';
5
+ import { IBeaconGlobalConfig, BEACON_GLOBAL_CONFIG } from './types';
6
+ import { BeaconNotifyService } from './beacon-notify.service';
7
+ import { BeaconIconSuccessComponent } from './icons/beacon-icon-success/beacon-icon-success.component';
8
+ import { BeaconIconAlertComponent } from './icons/beacon-icon-alert/beacon-icon-alert.component';
9
+ import { BeaconIconErrorComponent } from './icons/beacon-icon-error/beacon-icon-error.component';
10
+ import { BeaconIconInfoComponent } from './icons/beacon-icon-info/beacon-icon-info.component';
11
+ import { BeaconIconWarningComponent } from './icons/beacon-icon-warning/beacon-icon-warning.component';
12
+ import { BeaconTypeResolvePipe } from './pipes/beacon-type-resolve.pipe';
13
+
14
+ @NgModule({
15
+ declarations: [
16
+ BeaconNotifyComponent,
17
+ BeaconNotifyContainerComponent,
18
+ BeaconIconAlertComponent,
19
+ BeaconIconErrorComponent,
20
+ BeaconIconInfoComponent,
21
+ BeaconIconSuccessComponent,
22
+ BeaconIconWarningComponent,
23
+ BeaconTypeResolvePipe
24
+ ],
25
+ imports: [
26
+ CommonModule
27
+ ],
28
+ exports: [
29
+ BeaconNotifyComponent,
30
+ BeaconNotifyContainerComponent
31
+ ]
32
+ })
33
+ export class BeaconNotifyModule {
34
+ static forRoot(config?: IBeaconGlobalConfig): ModuleWithProviders<BeaconNotifyModule> {
35
+ return {
36
+ ngModule: BeaconNotifyModule,
37
+ providers: [
38
+ { provide: BEACON_GLOBAL_CONFIG, useValue: config },
39
+ BeaconNotifyService
40
+ ]
41
+ }
42
+ }
43
+ }