@bitblit/ngx-acute-common 6.0.146-alpha → 6.0.148-alpha

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 (43) hide show
  1. package/package.json +26 -25
  2. package/src/acute-common-type-guards.ts +12 -0
  3. package/src/build/ngx-acute-common-info.ts +19 -0
  4. package/src/components/dialogs/alert/alert.component.ts +41 -0
  5. package/src/components/dynamic-404-helper/dynamic-404-helper.component.html +24 -0
  6. package/src/components/dynamic-404-helper/dynamic-404-helper.component.ts +47 -0
  7. package/src/components/log-display/log-display.component.html +27 -0
  8. package/src/components/log-display/log-display.component.ts +122 -0
  9. package/src/components/process-monitor-simple-display/process-monitor-simple-display.component.html +19 -0
  10. package/src/components/process-monitor-simple-display/process-monitor-simple-display.component.ts +41 -0
  11. package/src/components/process-monitor-simple-modal-display/process-monitor-simple-modal-display.component.html +21 -0
  12. package/src/components/process-monitor-simple-modal-display/process-monitor-simple-modal-display.component.ts +41 -0
  13. package/src/constants.ts +3 -0
  14. package/src/index.ts +41 -0
  15. package/src/model/google-analytics-config.ts +3 -0
  16. package/src/pipes/capitalize.pipe.ts +8 -0
  17. package/src/pipes/dollar-formatted.pipe.ts +10 -0
  18. package/src/pipes/duration-ms-formatted.pipe.ts +25 -0
  19. package/src/pipes/map-values.pipe.ts +19 -0
  20. package/src/pipes/number-with-commas.pipe.ts +8 -0
  21. package/src/pipes/order-by.pipe.ts +59 -0
  22. package/src/pipes/percent-formatted.pipe.ts +9 -0
  23. package/src/pipes/plural.pipe.ts +9 -0
  24. package/src/pipes/round.pipe.ts +8 -0
  25. package/src/pipes/time-ago-formatted.pipe.ts +10 -0
  26. package/src/pipes/timing.pipe.ts +18 -0
  27. package/src/services/css-theme.service.spec.ts +17 -0
  28. package/src/services/css-theme.service.ts +84 -0
  29. package/src/services/google-analytics.service.spec.ts +17 -0
  30. package/src/services/google-analytics.service.ts +65 -0
  31. package/src/services/graphql-query-execution-display-style.ts +5 -0
  32. package/src/services/graphql-query-execution-options.ts +10 -0
  33. package/src/services/graphql-query.service.spec.ts +17 -0
  34. package/src/services/graphql-query.service.ts +85 -0
  35. package/src/services/local-storage.service.spec.ts +17 -0
  36. package/src/services/local-storage.service.ts +114 -0
  37. package/src/services/process-monitor/monitored-processes.ts +5 -0
  38. package/src/services/process-monitor/process-holder.ts +10 -0
  39. package/src/services/process-monitor/process-monitor-display-mode.ts +6 -0
  40. package/src/services/process-monitor/process-monitor-service.ts +178 -0
  41. package/src/services/process-monitor/process-monitor-state.ts +7 -0
  42. package/src/services/window-ref.service.spec.ts +17 -0
  43. package/src/services/window-ref.service.ts +34 -0
@@ -0,0 +1,178 @@
1
+ import { computed, Injectable, Signal, signal, WritableSignal } from "@angular/core";
2
+ import {RequireRatchet} from "@bitblit/ratchet-common/lang/require-ratchet";
3
+ import {ProcessMonitorState} from './process-monitor-state';
4
+ import {StringRatchet} from "@bitblit/ratchet-common/lang/string-ratchet";
5
+ import {No} from "@bitblit/ratchet-common/lang/no";
6
+ import {ProcessHolder} from "./process-holder";
7
+ import { MonitoredProcesses } from "./monitored-processes";
8
+ import { Logger } from "@bitblit/ratchet-common/logger/logger";
9
+ import { AcuteCommonTypeGuards } from "../../acute-common-type-guards";
10
+
11
+ // Service for providing visual feedback on an ongoing long-running process
12
+ @Injectable({providedIn: 'root'})
13
+ export class ProcessMonitorService {
14
+ public static readonly DEFAULT_GROUP: string = 'Long-Running Process';
15
+ private _defaultLabel: string = 'Processing...';
16
+
17
+ private processes: WritableSignal<MonitoredProcesses> = signal({processes:[]});
18
+
19
+ public hasModalProcesses(): Signal<boolean> {
20
+ return computed(
21
+ ()=>{
22
+ const rval: boolean = this.modalProcesses()().processes.length>0;
23
+ return rval;
24
+ });
25
+ }
26
+
27
+ public hasStandardProcesses(): Signal<boolean> {
28
+ return computed(
29
+ ()=>{
30
+ const rval: boolean = this.standardProcesses()().processes.length>0;
31
+ return rval;
32
+ });
33
+ }
34
+
35
+
36
+ public modalProcesses(): Signal<MonitoredProcesses> {
37
+ const rval: Signal<MonitoredProcesses> = computed(()=>{
38
+ const r: ProcessHolder<any>[] = this.processes().processes;
39
+ const modalOnly: ProcessHolder<any>[] = r.filter(s=>s.modal);
40
+ return {processes:modalOnly};
41
+ });
42
+ return rval;
43
+ }
44
+
45
+ public standardProcesses(): Signal<MonitoredProcesses> {
46
+ return computed(()=>{
47
+ const r: ProcessHolder<any>[] = this.processes().processes;
48
+ const modalOnly: ProcessHolder<any>[] = r.filter(s=>!s.modal);
49
+ return {processes:modalOnly};
50
+ });
51
+ }
52
+
53
+ public get defaultLabel(): string {
54
+ return this._defaultLabel;
55
+ }
56
+
57
+ public set defaultLabel(val: string) {
58
+ this._defaultLabel = val;
59
+ }
60
+
61
+ // Fire and forget - just so you don't get warnings about the promise not being handled
62
+ public fafMonitorProcessDefaultLabel<T>(promise: Promise<T>, modal?: boolean): void {
63
+ this.monitorProcessSimple(promise, this.defaultLabel, modal).then(No.op);
64
+ }
65
+
66
+ // Fire and forget - just so you don't get warnings about the promise not being handled
67
+ public fafMonitorProcessSimple<T>(promise: Promise<T>, label: string, modal?: boolean): void {
68
+ this.monitorProcessSimple(promise, label, modal).then(No.op);
69
+ }
70
+
71
+ public fafMonitorProcess<T>(promise: Promise<T>, descriptor: ProcessMonitorState | WritableSignal<ProcessMonitorState>, modal?: boolean): void {
72
+ this.monitorProcess(promise, descriptor, modal).then(No.op);
73
+ }
74
+
75
+ public monitorProcessDefaultLabel<T>(promise: Promise<T>, modal?: boolean): Promise<T> {
76
+ return this.monitorProcessSimple(promise, this.defaultLabel, modal);
77
+ }
78
+
79
+ public monitorProcessSimple<T>(promise: Promise<T>, label: string, modal?: boolean): Promise<T> {
80
+ return this.monitorProcess(promise, ProcessMonitorService.labelToProcessInput(label), modal);
81
+ }
82
+
83
+ public monitorProcess<T>(promise: Promise<T>, descriptor: ProcessMonitorState | WritableSignal<ProcessMonitorState>, modal?: boolean): Promise<T> {
84
+ const val:ProcessHolder<T> = this.innerMonitorProcess(promise, descriptor, modal);
85
+ return val.proc;
86
+ }
87
+
88
+ public monitorProcessWithUpdate<T>(promise: Promise<T>, descriptor: ProcessMonitorState | WritableSignal<ProcessMonitorState>, modal?: boolean): ProcessHolder<T> {
89
+ return this.innerMonitorProcess(promise, descriptor, modal);
90
+ }
91
+
92
+ public updatePercentCompleteByGuid(guid: string, pct:number): void {
93
+ const old: MonitoredProcesses = this.processes();
94
+ const tgt: ProcessHolder<any> = old.processes.find(s=>s.guid===guid);
95
+ if (tgt) {
96
+ ProcessMonitorService.updateSignalPercent(tgt.input, pct);
97
+ } else {
98
+ Logger.warn('Could not find process with guid %s to update', guid);
99
+ }
100
+ }
101
+
102
+ public updateLabelByGuid(guid: string, newLabel: string): void {
103
+ const old: MonitoredProcesses = this.processes();
104
+ const tgt: ProcessHolder<any> = old.processes.find(s=>s.guid===guid);
105
+ if (tgt) {
106
+ ProcessMonitorService.updateSignalLabel(tgt.input, newLabel);
107
+ } else {
108
+ Logger.warn('Could not find process with guid %s to update', guid);
109
+ }
110
+ }
111
+
112
+ public updateDetailByGuid(guid: string, newDetail: string): void {
113
+ const old: MonitoredProcesses = this.processes();
114
+ const tgt: ProcessHolder<any> = old.processes.find(s=>s.guid===guid);
115
+ if (tgt) {
116
+ ProcessMonitorService.updateSignalDetail(tgt.input, newDetail);
117
+ } else {
118
+ Logger.warn('Could not find process with guid %s to update', guid);
119
+ }
120
+ }
121
+
122
+
123
+ public static updateSignalPercent(inp: WritableSignal<ProcessMonitorState>, pct: number): void {
124
+ const old: ProcessMonitorState = inp();
125
+ old.percentComplete = pct;
126
+ inp.set(old);
127
+ }
128
+
129
+ public static updateSignalLabel(inp: WritableSignal<ProcessMonitorState>, newLabel: string): void {
130
+ const old: ProcessMonitorState = inp();
131
+ old.label = newLabel;
132
+ inp.set(old);
133
+ }
134
+
135
+ public static updateSignalDetail(inp: WritableSignal<ProcessMonitorState>, newDetail: string): void {
136
+ const old: ProcessMonitorState = inp();
137
+ old.detail = newDetail;
138
+ inp.set(old);
139
+ }
140
+
141
+ private innerMonitorProcess<T>(promise: Promise<T>, descriptor: ProcessMonitorState | WritableSignal<ProcessMonitorState>, modal: boolean = false): ProcessHolder<T> {
142
+ RequireRatchet.notNullOrUndefined(promise, 'promise');
143
+ RequireRatchet.notNullOrUndefined(descriptor, 'descriptor');
144
+
145
+ const guid: string = StringRatchet.createRandomHexString(10);
146
+ const descSig: WritableSignal<ProcessMonitorState> = AcuteCommonTypeGuards.isProcessMonitorState(descriptor) ? signal(descriptor) : descriptor;
147
+
148
+ const wrapped: Promise<T> = promise.finally(()=>{
149
+ Logger.info('Process %s finished - removing', holder.guid);
150
+ const newProc: ProcessHolder<any>[] = this.processes().processes.filter(s=>s.guid!==guid);
151
+ this.processes.set({processes: newProc});
152
+ });
153
+
154
+ const holder: ProcessHolder<T> = {
155
+ guid: guid,
156
+ proc: wrapped,
157
+ input: descSig,
158
+ group: ProcessMonitorService.DEFAULT_GROUP,
159
+ modal: modal
160
+ };
161
+
162
+ const oldProc: ProcessHolder<any>[] = this.processes().processes;
163
+ oldProc.push(holder);
164
+ this.processes.set({processes:oldProc});
165
+
166
+ return holder;
167
+ }
168
+
169
+
170
+ public static labelToProcessInput(label: string): ProcessMonitorState {
171
+ return {
172
+ label: label,
173
+ detail: null,
174
+ percentComplete: null
175
+ };
176
+ }
177
+
178
+ }
@@ -0,0 +1,7 @@
1
+
2
+ /** This is all the stuff that can be updated during a process */
3
+ export interface ProcessMonitorState {
4
+ label: string;
5
+ detail?: string;
6
+ percentComplete?: number;
7
+ }
@@ -0,0 +1,17 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+ import { beforeEach, describe, expect, test } from 'vitest';
3
+
4
+ import { WindowRefService } from './window-ref.service';
5
+
6
+ describe('WindowRefService', () => {
7
+ let service: WindowRefService;
8
+
9
+ beforeEach(() => {
10
+ TestBed.configureTestingModule({});
11
+ service = TestBed.inject(WindowRefService);
12
+ });
13
+
14
+ test.skip('should be created', () => {
15
+ expect(service).toBeTruthy();
16
+ });
17
+ });
@@ -0,0 +1,34 @@
1
+ import { Injectable } from '@angular/core';
2
+
3
+ // Taken from https://juristr.com/blog/2016/09/ng2-get-window-ref/
4
+ // Here to make transition to Angular Universal later easier
5
+
6
+ /* This interface is optional, showing how you can add strong typings for custom globals.
7
+ // Just use "Window" as the type if you don't have custom global stuff
8
+ export interface ICustomWindow extends Window {
9
+ __custom_global_stuff: string;
10
+ } */
11
+
12
+ function getWindow(): any {
13
+ if (typeof window !== 'undefined') {
14
+ return window;
15
+ } else {
16
+ throw new Error('Cannot find window object - running in SSR?');
17
+ }
18
+ }
19
+
20
+ @Injectable({ providedIn: 'root' })
21
+ export class WindowRefService {
22
+ public nativeWindow(): Window {
23
+ return getWindow();
24
+ }
25
+
26
+ public nativeWindowReload(): void {
27
+ getWindow().location.reload();
28
+ }
29
+
30
+ public nativeWindowNavigateTo(url: string): void {
31
+ getWindow().location.href = url;
32
+ }
33
+
34
+ }