@bitblit/ngx-acute-common 5.0.512-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 (66) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/License.txt +13 -0
  3. package/README.md +7 -0
  4. package/artifacts/coverage/base.css +224 -0
  5. package/artifacts/coverage/block-navigation.js +87 -0
  6. package/artifacts/coverage/clover.xml +1565 -0
  7. package/artifacts/coverage/coverage-final.json +40 -0
  8. package/artifacts/coverage/favicon.png +0 -0
  9. package/artifacts/coverage/index.html +236 -0
  10. package/artifacts/coverage/modules/acute-common/src/build/index.html +116 -0
  11. package/artifacts/coverage/modules/acute-common/src/build/ngx-acute-common-info.ts.html +142 -0
  12. package/artifacts/coverage/modules/acute-common/src/components/dialogs/alert/alert.component.ts.html +184 -0
  13. package/artifacts/coverage/modules/acute-common/src/components/dialogs/alert/index.html +116 -0
  14. package/artifacts/coverage/modules/acute-common/src/components/dialogs/block-ui/block-ui.component.ts.html +271 -0
  15. package/artifacts/coverage/modules/acute-common/src/components/dialogs/block-ui/index.html +116 -0
  16. package/artifacts/coverage/modules/acute-common/src/pipes/capitalize.pipe.ts.html +118 -0
  17. package/artifacts/coverage/modules/acute-common/src/pipes/dollar-formatted.pipe.ts.html +124 -0
  18. package/artifacts/coverage/modules/acute-common/src/pipes/index.html +251 -0
  19. package/artifacts/coverage/modules/acute-common/src/pipes/map-values.pipe.ts.html +142 -0
  20. package/artifacts/coverage/modules/acute-common/src/pipes/number-with-commas.pipe.ts.html +112 -0
  21. package/artifacts/coverage/modules/acute-common/src/pipes/order-by.pipe.ts.html +259 -0
  22. package/artifacts/coverage/modules/acute-common/src/pipes/percent-formatted.pipe.ts.html +112 -0
  23. package/artifacts/coverage/modules/acute-common/src/pipes/plural.pipe.ts.html +127 -0
  24. package/artifacts/coverage/modules/acute-common/src/pipes/round.pipe.ts.html +112 -0
  25. package/artifacts/coverage/modules/acute-common/src/pipes/time-ago-formatted.pipe.ts.html +115 -0
  26. package/artifacts/coverage/modules/acute-common/src/pipes/timing.pipe.ts.html +139 -0
  27. package/artifacts/coverage/modules/acute-common/src/services/google-analytics.service.ts.html +280 -0
  28. package/artifacts/coverage/modules/acute-common/src/services/graphql-query.service.ts.html +394 -0
  29. package/artifacts/coverage/modules/acute-common/src/services/index.html +161 -0
  30. package/artifacts/coverage/modules/acute-common/src/services/local-storage.service.ts.html +235 -0
  31. package/artifacts/coverage/modules/acute-common/src/services/window-ref.service.ts.html +160 -0
  32. package/artifacts/coverage/prettify.css +1 -0
  33. package/artifacts/coverage/prettify.js +2 -0
  34. package/artifacts/coverage/sort-arrow-sprite.png +0 -0
  35. package/artifacts/coverage/sorter.js +196 -0
  36. package/lib/my-angular-library.cjs.js +7 -0
  37. package/lib/my-angular-library.esm.js +7 -0
  38. package/lib/my-angular-library.umd.js +7 -0
  39. package/package.json +56 -0
  40. package/rollup.config.mjs +58 -0
  41. package/src/build/ngx-acute-common-info.ts +19 -0
  42. package/src/components/dialogs/alert/alert.component.ts +33 -0
  43. package/src/components/dialogs/block-ui/block-ui.component.html +9 -0
  44. package/src/components/dialogs/block-ui/block-ui.component.spec.ts +24 -0
  45. package/src/components/dialogs/block-ui/block-ui.component.ts +62 -0
  46. package/src/index.ts +2 -0
  47. package/src/model/google-analytics-config.ts +3 -0
  48. package/src/pipes/capitalize.pipe.ts +11 -0
  49. package/src/pipes/dollar-formatted.pipe.ts +13 -0
  50. package/src/pipes/map-values.pipe.ts +19 -0
  51. package/src/pipes/number-with-commas.pipe.ts +9 -0
  52. package/src/pipes/order-by.pipe.ts +58 -0
  53. package/src/pipes/percent-formatted.pipe.ts +9 -0
  54. package/src/pipes/plural.pipe.ts +14 -0
  55. package/src/pipes/round.pipe.ts +9 -0
  56. package/src/pipes/time-ago-formatted.pipe.ts +10 -0
  57. package/src/pipes/timing.pipe.ts +18 -0
  58. package/src/services/google-analytics.service.spec.ts +17 -0
  59. package/src/services/google-analytics.service.ts +65 -0
  60. package/src/services/graphql-query.service.spec.ts +17 -0
  61. package/src/services/graphql-query.service.ts +103 -0
  62. package/src/services/local-storage.service.spec.ts +17 -0
  63. package/src/services/local-storage.service.ts +50 -0
  64. package/src/services/window-ref.service.spec.ts +17 -0
  65. package/src/services/window-ref.service.ts +25 -0
  66. package/tsconfig.json +10 -0
@@ -0,0 +1,58 @@
1
+ import { Pipe, PipeTransform } from '@angular/core';
2
+
3
+ @Pipe({ name: 'acuteOrderBy', pure: false, standalone: true })
4
+ export class OrderByPipe implements PipeTransform {
5
+ static _orderByComparator(a: any, b: any): number {
6
+ if (isNaN(parseFloat(a)) || !isFinite(a) || isNaN(parseFloat(b)) || !isFinite(b)) {
7
+ //Isn't a number so lowercase the string to properly compare
8
+ if (String(a).toLowerCase() < String(b).toLowerCase()) return -1;
9
+ if (String(a).toLowerCase() > String(b).toLowerCase()) return 1;
10
+ } else {
11
+ //Parse strings as numbers to compare properly
12
+ if (parseFloat(a) < parseFloat(b)) return -1;
13
+ if (parseFloat(a) > parseFloat(b)) return 1;
14
+ }
15
+
16
+ return 0; //equal each other
17
+ }
18
+
19
+ transform(input: any, [config = '+']): any {
20
+ if (!Array.isArray(input)) return input;
21
+
22
+ if (!Array.isArray(config) || (Array.isArray(config) && config.length == 1)) {
23
+ const propertyToCheck: string = !Array.isArray(config) ? config : config[0];
24
+ const desc = propertyToCheck.substr(0, 1) == '-';
25
+
26
+ //Basic array
27
+ if (!propertyToCheck || propertyToCheck == '-' || propertyToCheck == '+') {
28
+ return !desc ? input.sort() : input.sort().reverse();
29
+ } else {
30
+ const property: string =
31
+ propertyToCheck.substr(0, 1) == '+' || propertyToCheck.substr(0, 1) == '-' ? propertyToCheck.substr(1) : propertyToCheck;
32
+
33
+ return input.sort(function (a: any, b: any) {
34
+ return !desc
35
+ ? OrderByPipe._orderByComparator(a[property], b[property])
36
+ : -OrderByPipe._orderByComparator(a[property], b[property]);
37
+ });
38
+ }
39
+ } else {
40
+ //Loop over property of the array in order and sort
41
+ return input.sort(function (a: any, b: any) {
42
+ for (let i: number = 0; i < config.length; i++) {
43
+ const desc = config[i].substr(0, 1) == '-';
44
+ const property = config[i].substr(0, 1) == '+' || config[i].substr(0, 1) == '-' ? config[i].substr(1) : config[i];
45
+
46
+ const comparison = !desc
47
+ ? OrderByPipe._orderByComparator(a[property], b[property])
48
+ : -OrderByPipe._orderByComparator(a[property], b[property]);
49
+
50
+ //Don't return 0 yet in case of needing to sort by next property
51
+ if (comparison != 0) return comparison;
52
+ }
53
+
54
+ return 0; //equal each other
55
+ });
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,9 @@
1
+ import { Pipe, PipeTransform } from '@angular/core';
2
+ import {NumberRatchet} from "@bitblit/ratchet-common/lang/number-ratchet";
3
+
4
+ @Pipe({ name: 'acutePercent' , standalone: true })
5
+ export class PercentFormattedPipe implements PipeTransform {
6
+ transform(input: number): string {
7
+ return NumberRatchet.pctFormatted(input);
8
+ }
9
+ }
@@ -0,0 +1,14 @@
1
+ import { Pipe, PipeTransform } from '@angular/core';
2
+
3
+ @Pipe({ name: 'acutePlural' , standalone: true})
4
+ export class PluralPipe implements PipeTransform {
5
+
6
+ transform(input: number, label: string, pluralLabel: string = ''): string {
7
+ input = input || 0;
8
+ return input === 1
9
+ ? `${input} ${label}`
10
+ : pluralLabel
11
+ ? `${input} ${pluralLabel}`
12
+ : `${input} ${label}s`;
13
+ }
14
+ }
@@ -0,0 +1,9 @@
1
+ import { Pipe, PipeTransform } from '@angular/core';
2
+
3
+ @Pipe({ name: 'acuteRound' , standalone: true})
4
+ export class RoundPipe implements PipeTransform {
5
+
6
+ transform(input: number): number {
7
+ return Math.round(input);
8
+ }
9
+ }
@@ -0,0 +1,10 @@
1
+ import {Pipe, PipeTransform} from '@angular/core';
2
+ import {DurationRatchet} from "@bitblit/ratchet-common/lang/duration-ratchet";
3
+ import {NumberRatchet} from "@bitblit/ratchet-common/lang/number-ratchet";
4
+
5
+ @Pipe({ name: 'acuteTimeAgo' , standalone: true})
6
+ export class TimeAgoFormattedPipe implements PipeTransform {
7
+ transform(input: number): string {
8
+ return DurationRatchet.formatMsDuration(new Date().getTime() - NumberRatchet.safeNumber(input));
9
+ }
10
+ }
@@ -0,0 +1,18 @@
1
+ import { Pipe, PipeTransform } from '@angular/core';
2
+
3
+ @Pipe({ name: 'acuteTiming' , standalone: true})
4
+ export class TimingPipe implements PipeTransform {
5
+ transform(time: number): string {
6
+ if (time) {
7
+ const minutes = Math.floor(time / 60);
8
+ const seconds = Math.floor(time % 60);
9
+ return `${this.initZero(minutes)}${minutes}:${this.initZero(seconds)}${seconds}`;
10
+ }
11
+
12
+ return '00:00';
13
+ }
14
+
15
+ private initZero(time: number): string {
16
+ return time < 10 ? '0' : '';
17
+ }
18
+ }
@@ -0,0 +1,17 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+ import { beforeEach, describe, expect, test } from 'vitest';
3
+
4
+ import {GraphqlQueryService} from "./graphql-query.service";
5
+
6
+ describe('GraphqlQueryService', () => {
7
+ let service: GraphqlQueryService;
8
+
9
+ beforeEach(() => {
10
+ TestBed.configureTestingModule({});
11
+ service = TestBed.inject(GraphqlQueryService);
12
+ });
13
+
14
+ test.skip('should be created', () => {
15
+ expect(service).toBeTruthy();
16
+ });
17
+ });
@@ -0,0 +1,65 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { NavigationEnd, Router } from '@angular/router';
3
+ import { Logger } from '@bitblit/ratchet-common/logger/logger';
4
+
5
+ // eslint-disable-next-line @typescript-eslint/ban-types
6
+ declare let gtag: Function;
7
+
8
+ @Injectable({
9
+ providedIn: 'root',
10
+ })
11
+ // See : https://lumin8media.com/blog/add-google-analytics-angular
12
+ export class GoogleAnalyticsService {
13
+ private static readonly IS_PROD: boolean = true;
14
+
15
+ constructor(private router: Router) {}
16
+
17
+ public initialize() {
18
+ this.onRouteChange();
19
+
20
+ // dynamically add analytics scripts to document head
21
+ try {
22
+ const url:string = 'https://www.googletagmanager.com/gtag/js?id=';
23
+ const gTagScript = document.createElement('script');
24
+ gTagScript.async = true;
25
+ const tagId: string = GoogleAnalyticsService.IS_PROD ? 'G-7D5BBK4K8X' : null;
26
+ gTagScript.src = `${url}${tagId}`;
27
+ document.head.appendChild(gTagScript);
28
+
29
+ const dataLayerScript = document.createElement('script');
30
+ dataLayerScript.innerHTML = `
31
+ window.dataLayer = window.dataLayer || [];
32
+ function gtag(){dataLayer.push(arguments);}
33
+ gtag('js', new Date());
34
+ gtag('config', '${tagId}', {'send_page_view': false});`;
35
+ document.head.appendChild(dataLayerScript);
36
+ } catch (e) {
37
+ Logger.error('Error adding Google Analytics', e, e);
38
+ }
39
+ }
40
+
41
+ // track visited routes
42
+ private onRouteChange() {
43
+ const tagId: string = GoogleAnalyticsService.IS_PROD ? 'G-7D5BBK4K8X' : null;
44
+
45
+ this.router.events.subscribe((event) => {
46
+ if (event instanceof NavigationEnd) {
47
+ gtag('config', tagId, {
48
+ page_path: event.urlAfterRedirects,
49
+ });
50
+
51
+ Logger.info('Sending Google Analytics tracking for: ', event.urlAfterRedirects);
52
+ Logger.info('Google Analytics property ID: ', tagId);
53
+ }
54
+ });
55
+ }
56
+
57
+ // use gtag.js to send Google Analytics Events
58
+ public event(action: string, eventCategory?: string, eventLabel?: string, value?: string) {
59
+ gtag('event', action, {
60
+ ...(eventCategory && { event_category: eventCategory }),
61
+ ...(eventLabel && { event_label: eventLabel }),
62
+ ...(value && { value: value }),
63
+ });
64
+ }
65
+ }
@@ -0,0 +1,17 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+ import { beforeEach, describe, expect, test } from 'vitest';
3
+
4
+ import {GraphqlQueryService} from "./graphql-query.service";
5
+
6
+ describe('GraphqlQueryService', () => {
7
+ let service: GraphqlQueryService;
8
+
9
+ beforeEach(() => {
10
+ TestBed.configureTestingModule({});
11
+ service = TestBed.inject(GraphqlQueryService);
12
+ });
13
+
14
+ test.skip('should be created', () => {
15
+ expect(service).toBeTruthy();
16
+ });
17
+ });
@@ -0,0 +1,103 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { DialogService } from 'primeng/dynamicdialog';
3
+ import { MessageService } from 'primeng/api';
4
+ import { Logger } from '@bitblit/ratchet-common/logger/logger';
5
+ import { GraphqlRatchet } from '@bitblit/ratchet-graphql/graphql/graphql-ratchet';
6
+ import { BlockUiComponent } from "../components/dialogs/block-ui/block-ui.component";
7
+ import {AuthorizationStyle} from "@bitblit/ratchet-graphql/graphql/authorization-style";
8
+
9
+ @Injectable({providedIn: 'root'})
10
+ export class GraphqlQueryService {
11
+ constructor(
12
+ private graphqlRatchet: GraphqlRatchet,
13
+ private dialogService: DialogService,
14
+ private messageService: MessageService,
15
+ ) {}
16
+
17
+ public async executeQuery<T>(queryName: string, variables: any, authStyle: AuthorizationStyle = AuthorizationStyle.TokenRequired
18
+ ): Promise<T | null> {
19
+ let rval: T | null = null;
20
+ this.messageService.add({ severity: 'info', summary: 'Running query', detail: queryName, life: 3000 });
21
+
22
+ Logger.info('eq: %j -: %s --: %s ---: %j', queryName, variables);
23
+
24
+ try {
25
+ rval = await this.graphqlRatchet.executeQuery<T>(queryName, variables, authStyle);
26
+ } catch (err) {
27
+ Logger.error('Fail : %s', err);
28
+ } finally {
29
+ this.messageService.clear();
30
+ }
31
+ return rval;
32
+ }
33
+
34
+ public async executeQueryWithBlock<T>(
35
+ blockMessage: string,
36
+ queryName: string,
37
+ variables: any,
38
+ authStyle: AuthorizationStyle = AuthorizationStyle.TokenRequired
39
+ ): Promise<T | null> {
40
+ let rval: T | null = null;
41
+ this.messageService.add({ severity: 'info', summary: 'Running query', detail: queryName, life: 3000 });
42
+
43
+ Logger.info('eqb: %j -: %s --: %s ---: %j', blockMessage, queryName, variables);
44
+
45
+ try {
46
+ rval = await BlockUiComponent.runPromiseWithUiBlock<T>(
47
+ this.dialogService,
48
+ this.graphqlRatchet.executeQuery<T>(queryName, variables, authStyle),
49
+ blockMessage,
50
+ );
51
+ } catch (err) {
52
+ Logger.error('Fail : %s', err);
53
+ } finally {
54
+ this.messageService.clear();
55
+ }
56
+
57
+ return rval;
58
+ }
59
+
60
+
61
+ public async executeMutate<T>(queryName: string, variables: any, authStyle: AuthorizationStyle = AuthorizationStyle.TokenRequired
62
+ ): Promise<T | null> {
63
+ let rval: T | null = null;
64
+ this.messageService.add({ severity: 'info', summary: 'Running query', detail: queryName, life: 3000 });
65
+
66
+ Logger.info('eq: %j -: %s --: %s ---: %j', queryName, variables);
67
+
68
+ try {
69
+ rval = await this.graphqlRatchet.executeMutate<T>(queryName, variables, authStyle);
70
+ } catch (err) {
71
+ Logger.error('Fail : %s', err);
72
+ } finally {
73
+ this.messageService.clear();
74
+ }
75
+
76
+ return rval;
77
+ }
78
+
79
+ public async executeMutateWithBlock<T>(
80
+ blockMessage: string,
81
+ queryName: string,
82
+ variables: any,
83
+ authStyle: AuthorizationStyle = AuthorizationStyle.TokenRequired
84
+
85
+ ): Promise<T | null> {
86
+ let rval: T | null = null;
87
+ this.messageService.add({ severity: 'info', summary: 'Running query', detail: queryName, life: 3000 });
88
+
89
+ try {
90
+ rval = await BlockUiComponent.runPromiseWithUiBlock<T>(
91
+ this.dialogService,
92
+ this.graphqlRatchet.executeMutate<T>(queryName, variables, authStyle),
93
+ blockMessage,
94
+ );
95
+ } catch (err) {
96
+ Logger.error('Fail : %s', err);
97
+ } finally {
98
+ this.messageService.clear();
99
+ }
100
+
101
+ return rval;
102
+ }
103
+ }
@@ -0,0 +1,17 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+ import { beforeEach, describe, expect, test } from 'vitest';
3
+
4
+ import {LocalStorageService} from "./local-storage.service";
5
+
6
+ describe('LocalStorageService', () => {
7
+ let service: LocalStorageService<any>;
8
+
9
+ beforeEach(() => {
10
+ TestBed.configureTestingModule({});
11
+ service = TestBed.inject(LocalStorageService);
12
+ });
13
+
14
+ test.skip('should be created', () => {
15
+ expect(service).toBeTruthy();
16
+ });
17
+ });
@@ -0,0 +1,50 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { Logger } from '@bitblit/ratchet-common/logger/logger';
3
+
4
+
5
+ export function storageFinder(): Storage | null {
6
+ if (typeof window !== 'undefined') {
7
+ if (typeof window.localStorage !=='undefined') {
8
+ return window.localStorage;
9
+ }
10
+ }
11
+ return null;
12
+ }
13
+
14
+ @Injectable({providedIn: 'root'})
15
+ export class LocalStorageService<T> {
16
+ private static readonly APP_NAME: string = 'Scribe';
17
+
18
+ public get storageReady(): boolean {
19
+ return !!storageFinder();
20
+ }
21
+
22
+ public clear(): void {
23
+ this.update({ } as T );
24
+ }
25
+
26
+ public update(value: T): T {
27
+ if (this.storageReady) {
28
+ const toSave: T = value || ({} as T);
29
+ const saveString: string = JSON.stringify(toSave);
30
+ Logger.info('Updating storage to %s', saveString);
31
+ localStorage.setItem(LocalStorageService.APP_NAME, saveString);
32
+ return toSave;
33
+ } else {
34
+ Logger.info('Skipping update - storage not ready : %j', value);
35
+ return {} as T;
36
+ }
37
+ }
38
+
39
+ fetch(): T {
40
+ if (this.storageReady) {
41
+ const loadString: string = localStorage.getItem(LocalStorageService.APP_NAME) || '{}';
42
+ const rval: T = JSON.parse(loadString) as T;
43
+ return rval;
44
+ } else {
45
+ Logger.info('Skipping fetch - storage not ready');
46
+ return {} as T;
47
+ }
48
+ }
49
+
50
+ }
@@ -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,25 @@
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
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": ".",
4
+ "outDir": "lib",
5
+ "rootDir": "src",
6
+ "stripInternal": true
7
+ },
8
+ "extends": "../../tsconfig.json",
9
+ "include": ["src/"]
10
+ }