@dragonworks/ngx-dashboard-widgets 20.0.6 → 20.1.1

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 (34) hide show
  1. package/fesm2022/dragonworks-ngx-dashboard-widgets.mjs +2251 -0
  2. package/fesm2022/dragonworks-ngx-dashboard-widgets.mjs.map +1 -0
  3. package/index.d.ts +532 -0
  4. package/package.json +42 -31
  5. package/ng-package.json +0 -7
  6. package/src/lib/arrow-widget/arrow-state-dialog.component.ts +0 -187
  7. package/src/lib/arrow-widget/arrow-widget.component.html +0 -9
  8. package/src/lib/arrow-widget/arrow-widget.component.scss +0 -52
  9. package/src/lib/arrow-widget/arrow-widget.component.ts +0 -78
  10. package/src/lib/arrow-widget/arrow-widget.metadata.ts +0 -3
  11. package/src/lib/clock-widget/analog-clock/analog-clock.component.html +0 -66
  12. package/src/lib/clock-widget/analog-clock/analog-clock.component.scss +0 -103
  13. package/src/lib/clock-widget/analog-clock/analog-clock.component.ts +0 -120
  14. package/src/lib/clock-widget/clock-state-dialog.component.ts +0 -170
  15. package/src/lib/clock-widget/clock-widget.component.html +0 -16
  16. package/src/lib/clock-widget/clock-widget.component.scss +0 -160
  17. package/src/lib/clock-widget/clock-widget.component.ts +0 -87
  18. package/src/lib/clock-widget/clock-widget.metadata.ts +0 -42
  19. package/src/lib/clock-widget/digital-clock/__tests__/digital-clock.component.spec.ts +0 -276
  20. package/src/lib/clock-widget/digital-clock/digital-clock.component.html +0 -1
  21. package/src/lib/clock-widget/digital-clock/digital-clock.component.scss +0 -43
  22. package/src/lib/clock-widget/digital-clock/digital-clock.component.ts +0 -105
  23. package/src/lib/directives/__tests__/responsive-text.directive.spec.ts +0 -906
  24. package/src/lib/directives/responsive-text.directive.ts +0 -334
  25. package/src/lib/label-widget/__tests__/label-widget.component.spec.ts +0 -539
  26. package/src/lib/label-widget/label-state-dialog.component.ts +0 -385
  27. package/src/lib/label-widget/label-widget.component.html +0 -21
  28. package/src/lib/label-widget/label-widget.component.scss +0 -112
  29. package/src/lib/label-widget/label-widget.component.ts +0 -96
  30. package/src/lib/label-widget/label-widget.metadata.ts +0 -3
  31. package/src/public-api.ts +0 -7
  32. package/tsconfig.lib.json +0 -15
  33. package/tsconfig.lib.prod.json +0 -11
  34. package/tsconfig.spec.json +0 -14
@@ -1,276 +0,0 @@
1
- import { ComponentFixture, TestBed } from '@angular/core/testing';
2
- import { DigitalClockComponent } from '../digital-clock.component';
3
-
4
- describe('DigitalClockComponent', () => {
5
- let component: DigitalClockComponent;
6
- let fixture: ComponentFixture<DigitalClockComponent>;
7
-
8
- beforeEach(async () => {
9
- await TestBed.configureTestingModule({
10
- imports: [DigitalClockComponent]
11
- })
12
- .compileComponents();
13
-
14
- fixture = TestBed.createComponent(DigitalClockComponent);
15
- component = fixture.componentInstance;
16
- });
17
-
18
- afterEach(() => {
19
- // Ensure proper cleanup after each test
20
- fixture.destroy();
21
- });
22
-
23
- it('should create', () => {
24
- expect(component).toBeTruthy();
25
- });
26
-
27
- describe('Component Initialization', () => {
28
- it('should display current time immediately after initialization', () => {
29
- fixture.detectChanges();
30
-
31
- const timeElement = fixture.nativeElement.querySelector('.digital-time');
32
- expect(timeElement?.textContent?.trim()).toBeTruthy();
33
- expect(timeElement?.textContent?.trim()).toMatch(/^\d{2}:\d{2}:\d{2}$/);
34
- });
35
-
36
- it('should display current time within reasonable bounds', () => {
37
- fixture.detectChanges();
38
-
39
- const timeElement = fixture.nativeElement.querySelector('.digital-time');
40
- const displayedTime = timeElement?.textContent?.trim();
41
-
42
- expect(displayedTime).toBeTruthy();
43
- expect(displayedTime).toMatch(/^\d{2}:\d{2}:\d{2}$/);
44
-
45
- // The displayed time should be within reasonable bounds of current time
46
- const displayedHour = parseInt(displayedTime!.substring(0, 2));
47
- const currentHour = new Date().getHours();
48
- expect(Math.abs(displayedHour - currentHour)).toBeLessThanOrEqual(1);
49
- });
50
- });
51
-
52
- describe('User Configuration Options', () => {
53
- it('should display time in 24h format without seconds when configured', () => {
54
- fixture.componentRef.setInput('timeFormat', '24h');
55
- fixture.componentRef.setInput('showSeconds', false);
56
- fixture.detectChanges();
57
-
58
- const formattedTime = component.formattedTime();
59
- expect(formattedTime).toMatch(/^\d{2}:\d{2}$/);
60
- expect(formattedTime).not.toContain('AM');
61
- expect(formattedTime).not.toContain('PM');
62
- });
63
-
64
- it('should display time in 24h format with seconds when configured', () => {
65
- fixture.componentRef.setInput('timeFormat', '24h');
66
- fixture.componentRef.setInput('showSeconds', true);
67
- fixture.detectChanges();
68
-
69
- const formattedTime = component.formattedTime();
70
- expect(formattedTime).toMatch(/^\d{2}:\d{2}:\d{2}$/);
71
- expect(formattedTime).not.toContain('AM');
72
- expect(formattedTime).not.toContain('PM');
73
- });
74
-
75
- it('should display time in 12h format without seconds when configured', () => {
76
- fixture.componentRef.setInput('timeFormat', '12h');
77
- fixture.componentRef.setInput('showSeconds', false);
78
- fixture.detectChanges();
79
-
80
- const formattedTime = component.formattedTime();
81
- expect(formattedTime).toMatch(/^\d{2}:\d{2} (AM|PM)$/);
82
- });
83
-
84
- it('should display time in 12h format with seconds when configured', () => {
85
- fixture.componentRef.setInput('timeFormat', '12h');
86
- fixture.componentRef.setInput('showSeconds', true);
87
- fixture.detectChanges();
88
-
89
- const formattedTime = component.formattedTime();
90
- expect(formattedTime).toMatch(/^\d{2}:\d{2}:\d{2} (AM|PM)$/);
91
- });
92
-
93
- it('should update display format when switching between 24h and 12h', () => {
94
- // Start with 24h format
95
- fixture.componentRef.setInput('timeFormat', '24h');
96
- fixture.componentRef.setInput('showSeconds', false);
97
- fixture.detectChanges();
98
-
99
- const time24h = component.formattedTime();
100
- expect(time24h).toMatch(/^\d{2}:\d{2}$/);
101
-
102
- // Switch to 12h format
103
- fixture.componentRef.setInput('timeFormat', '12h');
104
- fixture.detectChanges();
105
-
106
- const time12h = component.formattedTime();
107
- expect(time12h).toMatch(/^\d{2}:\d{2} (AM|PM)$/);
108
-
109
- // Times should be different formats
110
- expect(time24h).not.toBe(time12h);
111
- });
112
-
113
- it('should update display when toggling seconds visibility', () => {
114
- fixture.componentRef.setInput('timeFormat', '24h');
115
- fixture.componentRef.setInput('showSeconds', false);
116
- fixture.detectChanges();
117
-
118
- const timeWithoutSeconds = component.formattedTime();
119
- expect(timeWithoutSeconds).toMatch(/^\d{2}:\d{2}$/);
120
-
121
- // Enable seconds
122
- fixture.componentRef.setInput('showSeconds', true);
123
- fixture.detectChanges();
124
-
125
- const timeWithSeconds = component.formattedTime();
126
- expect(timeWithSeconds).toMatch(/^\d{2}:\d{2}:\d{2}$/);
127
-
128
- // Should be different lengths
129
- expect(timeWithSeconds.length).toBeGreaterThan(timeWithoutSeconds.length);
130
- });
131
- });
132
-
133
- describe('Template Integration', () => {
134
- it('should display formatted time in template element', () => {
135
- fixture.componentRef.setInput('timeFormat', '24h');
136
- fixture.componentRef.setInput('showSeconds', true);
137
- fixture.detectChanges();
138
-
139
- const timeElement = fixture.nativeElement.querySelector('.digital-time');
140
- const templateTime = timeElement?.textContent?.trim();
141
- const componentTime = component.formattedTime();
142
-
143
- expect(templateTime).toBe(componentTime);
144
- expect(templateTime).toMatch(/^\d{2}:\d{2}:\d{2}$/);
145
- });
146
-
147
- it('should update template when time format changes', () => {
148
- fixture.componentRef.setInput('timeFormat', '24h');
149
- fixture.componentRef.setInput('showSeconds', false);
150
- fixture.detectChanges();
151
-
152
- let timeElement = fixture.nativeElement.querySelector('.digital-time');
153
- let templateTime = timeElement?.textContent?.trim();
154
- expect(templateTime).toMatch(/^\d{2}:\d{2}$/);
155
-
156
- // Change to 12h format
157
- fixture.componentRef.setInput('timeFormat', '12h');
158
- fixture.detectChanges();
159
-
160
- timeElement = fixture.nativeElement.querySelector('.digital-time');
161
- templateTime = timeElement?.textContent?.trim();
162
- expect(templateTime).toMatch(/^\d{2}:\d{2} (AM|PM)$/);
163
- });
164
-
165
- it('should reflect input changes in host element classes', () => {
166
- fixture.componentRef.setInput('hasBackground', true);
167
- fixture.componentRef.setInput('timeFormat', '12h');
168
- fixture.componentRef.setInput('showSeconds', true);
169
- fixture.detectChanges();
170
-
171
- const hostElement = fixture.nativeElement;
172
- expect(hostElement.classList.contains('has-background')).toBe(true);
173
- expect(hostElement.classList.contains('show-pm')).toBe(true);
174
- expect(hostElement.classList.contains('show-seconds')).toBe(true);
175
- expect(hostElement.classList.contains('clock-widget')).toBe(true);
176
- expect(hostElement.classList.contains('digital')).toBe(true);
177
- });
178
-
179
- it('should update host classes when inputs change', () => {
180
- fixture.componentRef.setInput('hasBackground', false);
181
- fixture.componentRef.setInput('timeFormat', '24h');
182
- fixture.componentRef.setInput('showSeconds', false);
183
- fixture.detectChanges();
184
-
185
- const hostElement = fixture.nativeElement;
186
- expect(hostElement.classList.contains('has-background')).toBe(false);
187
- expect(hostElement.classList.contains('show-pm')).toBe(false);
188
- expect(hostElement.classList.contains('show-seconds')).toBe(false);
189
- });
190
- });
191
-
192
- describe('Input Validation', () => {
193
- it('should handle rapid input changes without errors', () => {
194
- fixture.detectChanges();
195
-
196
- // Rapidly change inputs multiple times
197
- for (let i = 0; i < 10; i++) {
198
- fixture.componentRef.setInput('timeFormat', i % 2 === 0 ? '24h' : '12h');
199
- fixture.componentRef.setInput('showSeconds', i % 2 === 0);
200
- fixture.componentRef.setInput('hasBackground', i % 3 === 0);
201
- fixture.detectChanges();
202
-
203
- // Should still display valid time format
204
- const formattedTime = component.formattedTime();
205
- expect(formattedTime).toMatch(/^\d{2}:\d{2}(:\d{2})?( (AM|PM))?$/);
206
- }
207
- });
208
-
209
- it('should maintain consistent formatting patterns', () => {
210
- fixture.detectChanges();
211
-
212
- // Test all combinations of inputs
213
- const timeFormats: Array<'12h' | '24h'> = ['12h', '24h'];
214
- const showSecondsOptions = [true, false];
215
- const hasBackgroundOptions = [true, false];
216
-
217
- timeFormats.forEach(timeFormat => {
218
- showSecondsOptions.forEach(showSeconds => {
219
- hasBackgroundOptions.forEach(hasBackground => {
220
- fixture.componentRef.setInput('timeFormat', timeFormat);
221
- fixture.componentRef.setInput('showSeconds', showSeconds);
222
- fixture.componentRef.setInput('hasBackground', hasBackground);
223
- fixture.detectChanges();
224
-
225
- const formattedTime = component.formattedTime();
226
-
227
- if (timeFormat === '24h') {
228
- if (showSeconds) {
229
- expect(formattedTime).toMatch(/^\d{2}:\d{2}:\d{2}$/);
230
- } else {
231
- expect(formattedTime).toMatch(/^\d{2}:\d{2}$/);
232
- }
233
- expect(formattedTime).not.toContain('AM');
234
- expect(formattedTime).not.toContain('PM');
235
- } else {
236
- if (showSeconds) {
237
- expect(formattedTime).toMatch(/^\d{2}:\d{2}:\d{2} (AM|PM)$/);
238
- } else {
239
- expect(formattedTime).toMatch(/^\d{2}:\d{2} (AM|PM)$/);
240
- }
241
- }
242
- });
243
- });
244
- });
245
- });
246
- });
247
-
248
- describe('Component Lifecycle', () => {
249
- it('should handle component destruction cleanly', () => {
250
- fixture.detectChanges();
251
-
252
- // Destroy should not throw errors
253
- expect(() => {
254
- fixture.destroy();
255
- }).not.toThrow();
256
- });
257
-
258
- it('should provide consistent output across multiple initialization cycles', () => {
259
- // Initialize and get initial time format
260
- fixture.detectChanges();
261
- const firstTime = component.formattedTime();
262
-
263
- // Destroy and recreate
264
- fixture.destroy();
265
- fixture = TestBed.createComponent(DigitalClockComponent);
266
- component = fixture.componentInstance;
267
- fixture.detectChanges();
268
-
269
- const secondTime = component.formattedTime();
270
-
271
- // Both should be valid time formats (though potentially different times)
272
- expect(firstTime).toMatch(/^\d{2}:\d{2}:\d{2}$/);
273
- expect(secondTime).toMatch(/^\d{2}:\d{2}:\d{2}$/);
274
- });
275
- });
276
- });
@@ -1 +0,0 @@
1
- <div responsiveText class="digital-time">{{ formattedTime() }}</div>
@@ -1,43 +0,0 @@
1
- // Digital Clock Component Styles
2
-
3
- :host {
4
- // Base widget styles
5
- display: flex;
6
- align-items: center;
7
- justify-content: center;
8
- height: 100%;
9
- width: 100%;
10
- box-sizing: border-box;
11
- transition: background-color var(--mat-sys-motion-duration-medium2)
12
- var(--mat-sys-motion-easing-standard);
13
-
14
- // Clock widget padding and colors
15
- padding: var(--mat-sys-spacing-4);
16
- color: var(--mat-sys-on-surface-variant, #6c757d);
17
-
18
- &.has-background {
19
- background-color: var(--mat-sys-surface-container-high);
20
- border-radius: 4px;
21
- color: var(--mat-sys-on-surface, #1f1f1f);
22
- }
23
-
24
- &:hover {
25
- opacity: 0.8;
26
- color: var(--mat-sys-primary, #6750a4);
27
- }
28
- }
29
-
30
- // Digital time display
31
- .digital-time {
32
- // Default: when NO PM is shown (regardless of seconds)
33
- font-size: clamp(8px, min(20cqw, 50cqh), 200px);
34
- font-family: monospace;
35
- font-weight: 500;
36
- letter-spacing: 0.05em;
37
- transition: color 0.2s ease;
38
- }
39
-
40
- // Smaller font when showing both PM AND seconds
41
- :host.show-pm.show-seconds .digital-time {
42
- font-size: clamp(8px, min(15cqw, 50cqh), 200px);
43
- }
@@ -1,105 +0,0 @@
1
- import {
2
- Component,
3
- inject,
4
- signal,
5
- computed,
6
- DestroyRef,
7
- input,
8
- ChangeDetectionStrategy,
9
- } from '@angular/core';
10
-
11
- export interface DigitalClockConfig {
12
- timeFormat: '12h' | '24h';
13
- showSeconds: boolean;
14
- hasBackground: boolean;
15
- }
16
-
17
- @Component({
18
- selector: 'ngx-digital-clock',
19
- standalone: true,
20
- changeDetection: ChangeDetectionStrategy.OnPush,
21
- templateUrl: './digital-clock.component.html',
22
- styleUrl: './digital-clock.component.scss',
23
- host: {
24
- '[class.has-background]': 'hasBackground()',
25
- '[class.show-pm]': 'timeFormat() === "12h"',
26
- '[class.show-seconds]': 'showSeconds()',
27
- class: 'clock-widget digital',
28
- },
29
- })
30
- export class DigitalClockComponent {
31
- readonly #destroyRef = inject(DestroyRef);
32
-
33
- // Inputs
34
- timeFormat = input<'12h' | '24h'>('24h');
35
- showSeconds = input<boolean>(true);
36
- hasBackground = input<boolean>(false);
37
-
38
- // Time tracking
39
- currentTime = signal(new Date());
40
-
41
- formattedTime = computed(() => {
42
- const time = this.currentTime();
43
- const format = this.timeFormat();
44
- const showSecs = this.showSeconds();
45
- return this.#formatTime(time, format, showSecs);
46
- });
47
-
48
- #intervalId: number | null = null;
49
-
50
- #formatTime(time: Date, format: '12h' | '24h', showSecs: boolean): string {
51
- let hours = time.getHours();
52
- const minutes = time.getMinutes();
53
- const seconds = time.getSeconds();
54
-
55
- // Pad with leading zeros
56
- const mm = minutes.toString().padStart(2, '0');
57
- const ss = seconds.toString().padStart(2, '0');
58
-
59
- if (format === '12h') {
60
- // 12-hour format with AM/PM
61
- const ampm = hours >= 12 ? 'PM' : 'AM';
62
- hours = hours % 12;
63
- if (hours === 0) hours = 12; // Convert 0 to 12 for 12 AM/PM
64
-
65
- const hh = hours.toString().padStart(2, '0');
66
- return showSecs ? `${hh}:${mm}:${ss} ${ampm}` : `${hh}:${mm} ${ampm}`;
67
- } else {
68
- // 24-hour format
69
- const hh = hours.toString().padStart(2, '0');
70
- return showSecs ? `${hh}:${mm}:${ss}` : `${hh}:${mm}`;
71
- }
72
- }
73
-
74
- constructor() {
75
- // Set up time update timer
76
- this.#startTimer();
77
-
78
- // Clean up timer on component destruction
79
- this.#destroyRef.onDestroy(() => {
80
- this.#stopTimer();
81
- });
82
- }
83
-
84
- #startTimer(): void {
85
- // Sync to the next second boundary for smooth start
86
- const now = new Date();
87
- const msUntilNextSecond = 1000 - now.getMilliseconds();
88
-
89
- setTimeout(() => {
90
- this.currentTime.set(new Date());
91
-
92
- // Start the regular 1-second interval
93
- this.#intervalId = window.setInterval(() => {
94
- this.currentTime.set(new Date());
95
- }, 1000);
96
- }, msUntilNextSecond);
97
- }
98
-
99
- #stopTimer(): void {
100
- if (this.#intervalId !== null) {
101
- clearInterval(this.#intervalId);
102
- this.#intervalId = null;
103
- }
104
- }
105
- }