tin-spa 20.14.99 → 20.14.113
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.
- package/core/index.d.ts +3033 -0
- package/fesm2022/tin-spa-accounting.module-Cg4vWaJE.mjs +2231 -0
- package/fesm2022/tin-spa-accounting.module-Cg4vWaJE.mjs.map +1 -0
- package/fesm2022/tin-spa-agent-page.component-DJvMPjCQ.mjs +39 -0
- package/fesm2022/tin-spa-agent-page.component-DJvMPjCQ.mjs.map +1 -0
- package/fesm2022/tin-spa-agent.component-D0CGGnGZ.mjs +1379 -0
- package/fesm2022/tin-spa-agent.component-D0CGGnGZ.mjs.map +1 -0
- package/fesm2022/tin-spa-assets.module-qIWNwJ2E.mjs +167 -0
- package/fesm2022/tin-spa-assets.module-qIWNwJ2E.mjs.map +1 -0
- package/fesm2022/tin-spa-core.mjs +13628 -0
- package/fesm2022/tin-spa-core.mjs.map +1 -0
- package/fesm2022/tin-spa-general-erp.module-CoYxceLj.mjs +138 -0
- package/fesm2022/tin-spa-general-erp.module-CoYxceLj.mjs.map +1 -0
- package/fesm2022/tin-spa-hr.module-CKPZ9ZOj.mjs +134 -0
- package/fesm2022/tin-spa-hr.module-CKPZ9ZOj.mjs.map +1 -0
- package/fesm2022/tin-spa-http.mjs +117 -0
- package/fesm2022/tin-spa-http.mjs.map +1 -0
- package/fesm2022/tin-spa-inventory.module-DRKAcNau.mjs +338 -0
- package/fesm2022/tin-spa-inventory.module-DRKAcNau.mjs.map +1 -0
- package/fesm2022/tin-spa-keys.mjs +14 -0
- package/fesm2022/tin-spa-keys.mjs.map +1 -0
- package/fesm2022/tin-spa-landing.mjs +189 -0
- package/fesm2022/tin-spa-landing.mjs.map +1 -0
- package/fesm2022/tin-spa-loans.module-BTDmgrWo.mjs +115 -0
- package/fesm2022/tin-spa-loans.module-BTDmgrWo.mjs.map +1 -0
- package/fesm2022/tin-spa-login.mjs +719 -0
- package/fesm2022/tin-spa-login.mjs.map +1 -0
- package/fesm2022/tin-spa-manufacturing.module-CHta6oV_.mjs +96 -0
- package/fesm2022/tin-spa-manufacturing.module-CHta6oV_.mjs.map +1 -0
- package/fesm2022/tin-spa-map.mjs +750 -0
- package/fesm2022/tin-spa-map.mjs.map +1 -0
- package/fesm2022/tin-spa-payroll.module-CZ_GO1jF.mjs +847 -0
- package/fesm2022/tin-spa-payroll.module-CZ_GO1jF.mjs.map +1 -0
- package/fesm2022/tin-spa-purchasing.module-NCdwquaF.mjs +161 -0
- package/fesm2022/tin-spa-purchasing.module-NCdwquaF.mjs.map +1 -0
- package/fesm2022/tin-spa-sales.module-D0uEGJW7.mjs +1346 -0
- package/fesm2022/tin-spa-sales.module-D0uEGJW7.mjs.map +1 -0
- package/fesm2022/tin-spa-tenancy-erp.module-GwIv8Wbc.mjs +932 -0
- package/fesm2022/tin-spa-tenancy-erp.module-GwIv8Wbc.mjs.map +1 -0
- package/fesm2022/tin-spa-tin-spa-Cqe5hYTr.mjs +22576 -0
- package/fesm2022/tin-spa-tin-spa-Cqe5hYTr.mjs.map +1 -0
- package/fesm2022/tin-spa.mjs +2 -42079
- package/fesm2022/tin-spa.mjs.map +1 -1
- package/http/index.d.ts +16 -0
- package/index.d.ts +588 -4687
- package/keys/index.d.ts +4 -0
- package/landing/index.d.ts +175 -0
- package/login/index.d.ts +141 -0
- package/map/index.d.ts +148 -0
- package/package.json +25 -1
- package/src/tin-styles.css +81 -2
package/keys/index.d.ts
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { OnInit, AfterViewInit, OnDestroy, Injector, ElementRef } from '@angular/core';
|
|
3
|
+
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
|
4
|
+
import { Router } from '@angular/router';
|
|
5
|
+
|
|
6
|
+
interface LandingColors {
|
|
7
|
+
primary: string;
|
|
8
|
+
primaryDark: string;
|
|
9
|
+
primaryLight: string;
|
|
10
|
+
secondary: string;
|
|
11
|
+
secondaryLight: string;
|
|
12
|
+
}
|
|
13
|
+
interface LandingBrandOverride {
|
|
14
|
+
svgMarkup: string;
|
|
15
|
+
wordmarkLine1?: string;
|
|
16
|
+
wordmarkLine2?: string;
|
|
17
|
+
}
|
|
18
|
+
interface LandingNavLink {
|
|
19
|
+
label: string;
|
|
20
|
+
target: string;
|
|
21
|
+
}
|
|
22
|
+
interface LandingFeature {
|
|
23
|
+
title: string;
|
|
24
|
+
description: string;
|
|
25
|
+
icon: string;
|
|
26
|
+
color: string;
|
|
27
|
+
}
|
|
28
|
+
interface LandingStep {
|
|
29
|
+
number: string;
|
|
30
|
+
title: string;
|
|
31
|
+
description: string;
|
|
32
|
+
icon: string;
|
|
33
|
+
}
|
|
34
|
+
interface LandingModuleTile {
|
|
35
|
+
name: string;
|
|
36
|
+
icon: string;
|
|
37
|
+
}
|
|
38
|
+
interface LandingModuleGroup {
|
|
39
|
+
category: string;
|
|
40
|
+
tiles: LandingModuleTile[];
|
|
41
|
+
}
|
|
42
|
+
interface LandingMetric {
|
|
43
|
+
value: string;
|
|
44
|
+
label: string;
|
|
45
|
+
}
|
|
46
|
+
interface LandingSecurityItem {
|
|
47
|
+
icon: string;
|
|
48
|
+
title: string;
|
|
49
|
+
description: string;
|
|
50
|
+
}
|
|
51
|
+
interface LandingTestimonial {
|
|
52
|
+
quote: string;
|
|
53
|
+
authorName: string;
|
|
54
|
+
authorRole: string;
|
|
55
|
+
authorInitials: string;
|
|
56
|
+
}
|
|
57
|
+
interface LandingPricingPlan {
|
|
58
|
+
name: string;
|
|
59
|
+
price: string;
|
|
60
|
+
period?: string;
|
|
61
|
+
description: string;
|
|
62
|
+
features: string[];
|
|
63
|
+
ctaLabel: string;
|
|
64
|
+
ctaRoute?: string;
|
|
65
|
+
ctaSection?: string;
|
|
66
|
+
popular?: boolean;
|
|
67
|
+
outline?: boolean;
|
|
68
|
+
}
|
|
69
|
+
interface LandingFooterLink {
|
|
70
|
+
label: string;
|
|
71
|
+
section?: string;
|
|
72
|
+
route?: string;
|
|
73
|
+
}
|
|
74
|
+
interface LandingFooterColumn {
|
|
75
|
+
title: string;
|
|
76
|
+
links: LandingFooterLink[];
|
|
77
|
+
}
|
|
78
|
+
interface LandingConfig {
|
|
79
|
+
appName: string;
|
|
80
|
+
logoSrc: string;
|
|
81
|
+
colors: LandingColors;
|
|
82
|
+
navBrand?: LandingBrandOverride;
|
|
83
|
+
navLinks: LandingNavLink[];
|
|
84
|
+
hero: {
|
|
85
|
+
badge?: string;
|
|
86
|
+
headline: string;
|
|
87
|
+
gradientText: string;
|
|
88
|
+
subtitle: string;
|
|
89
|
+
primaryCTA: string;
|
|
90
|
+
primaryCTARoute?: string;
|
|
91
|
+
secondaryCTA: string;
|
|
92
|
+
secondaryCTASection: string;
|
|
93
|
+
trustSignals: string[];
|
|
94
|
+
layout?: 'centered' | 'split';
|
|
95
|
+
watermarkSvg?: string;
|
|
96
|
+
};
|
|
97
|
+
features: {
|
|
98
|
+
title: string;
|
|
99
|
+
subtitle: string;
|
|
100
|
+
items: LandingFeature[];
|
|
101
|
+
};
|
|
102
|
+
workflow?: {
|
|
103
|
+
title: string;
|
|
104
|
+
subtitle?: string;
|
|
105
|
+
style?: 'steps' | 'road';
|
|
106
|
+
steps: LandingStep[];
|
|
107
|
+
};
|
|
108
|
+
modules?: {
|
|
109
|
+
title: string;
|
|
110
|
+
subtitle: string;
|
|
111
|
+
groups: LandingModuleGroup[];
|
|
112
|
+
};
|
|
113
|
+
metrics?: LandingMetric[];
|
|
114
|
+
security?: {
|
|
115
|
+
title: string;
|
|
116
|
+
subtitle: string;
|
|
117
|
+
items: LandingSecurityItem[];
|
|
118
|
+
};
|
|
119
|
+
testimonials?: {
|
|
120
|
+
title: string;
|
|
121
|
+
subtitle?: string;
|
|
122
|
+
items: LandingTestimonial[];
|
|
123
|
+
};
|
|
124
|
+
pricing?: {
|
|
125
|
+
title: string;
|
|
126
|
+
subtitle?: string;
|
|
127
|
+
plans: LandingPricingPlan[];
|
|
128
|
+
};
|
|
129
|
+
finalCta?: {
|
|
130
|
+
headline: string;
|
|
131
|
+
subtitle: string;
|
|
132
|
+
primaryCTA: string;
|
|
133
|
+
primaryCTARoute?: string;
|
|
134
|
+
secondaryCTA?: string;
|
|
135
|
+
secondaryCTASection?: string;
|
|
136
|
+
};
|
|
137
|
+
footerCompany?: string;
|
|
138
|
+
footerTagline?: string;
|
|
139
|
+
footerBrand?: LandingBrandOverride;
|
|
140
|
+
footerColumns?: LandingFooterColumn[];
|
|
141
|
+
}
|
|
142
|
+
declare const ALSQUARE_SVG_DARK = "<svg viewBox=\"0 0 80 80\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M32 62C17.6 62 6 50.4 6 36S17.6 10 32 10c9.2 0 17.3 4.9 21.8 12.2\" stroke=\"#1a3a7a\" stroke-width=\"9\" stroke-linecap=\"round\" fill=\"none\"/>\n <circle cx=\"32\" cy=\"36\" r=\"10\" fill=\"white\" stroke=\"#1a3a7a\" stroke-width=\"7\"/>\n <circle cx=\"32\" cy=\"36\" r=\"5.5\" fill=\"#e8a020\"/>\n <line x1=\"48\" y1=\"22\" x2=\"48\" y2=\"62\" stroke=\"#1a3a7a\" stroke-width=\"9\" stroke-linecap=\"round\"/>\n <rect x=\"56\" y=\"6\" width=\"7\" height=\"56\" rx=\"3.5\" fill=\"#e8a020\"/>\n <rect x=\"67\" y=\"0\" width=\"6\" height=\"6\" rx=\"1\" fill=\"#1a3a7a\"/>\n <rect x=\"67\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" fill=\"#1a3a7a\"/>\n <rect x=\"75\" y=\"0\" width=\"5\" height=\"5\" rx=\"1\" fill=\"#1a3a7a\" opacity=\"0.7\"/>\n <rect x=\"75\" y=\"8\" width=\"5\" height=\"5\" rx=\"1\" fill=\"#1a3a7a\" opacity=\"0.5\"/>\n</svg>";
|
|
143
|
+
declare const ALSQUARE_SVG_WHITE = "<svg viewBox=\"0 0 80 80\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M32 62C17.6 62 6 50.4 6 36S17.6 10 32 10c9.2 0 17.3 4.9 21.8 12.2\" stroke=\"#ffffff\" stroke-width=\"9\" stroke-linecap=\"round\" fill=\"none\"/>\n <circle cx=\"32\" cy=\"36\" r=\"10\" fill=\"#0f172a\" stroke=\"#ffffff\" stroke-width=\"7\"/>\n <circle cx=\"32\" cy=\"36\" r=\"5.5\" fill=\"#e8a020\"/>\n <line x1=\"48\" y1=\"22\" x2=\"48\" y2=\"62\" stroke=\"#ffffff\" stroke-width=\"9\" stroke-linecap=\"round\"/>\n <rect x=\"56\" y=\"6\" width=\"7\" height=\"56\" rx=\"3.5\" fill=\"#e8a020\"/>\n <rect x=\"67\" y=\"0\" width=\"6\" height=\"6\" rx=\"1\" fill=\"#ffffff\"/>\n <rect x=\"67\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" fill=\"#ffffff\"/>\n <rect x=\"75\" y=\"0\" width=\"5\" height=\"5\" rx=\"1\" fill=\"#ffffff\" opacity=\"0.7\"/>\n <rect x=\"75\" y=\"8\" width=\"5\" height=\"5\" rx=\"1\" fill=\"#ffffff\" opacity=\"0.5\"/>\n</svg>";
|
|
144
|
+
|
|
145
|
+
declare class SpaLandingComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
146
|
+
private router;
|
|
147
|
+
private injector;
|
|
148
|
+
private el;
|
|
149
|
+
private sanitizer;
|
|
150
|
+
config: LandingConfig;
|
|
151
|
+
mobileMenuOpen: boolean;
|
|
152
|
+
navScrolled: boolean;
|
|
153
|
+
restoring: boolean;
|
|
154
|
+
currentYear: number;
|
|
155
|
+
private observer;
|
|
156
|
+
constructor(router: Router, injector: Injector, // Changed (landing-first L1): the resume services are resolved AFTER a dynamic import, so this entry point names no primary symbol
|
|
157
|
+
el: ElementRef, sanitizer: DomSanitizer);
|
|
158
|
+
get safeNavBrandSvg(): SafeHtml | null;
|
|
159
|
+
get safeHeroWatermarkSvg(): SafeHtml | null;
|
|
160
|
+
get safeFooterBrandSvg(): SafeHtml | null;
|
|
161
|
+
ngOnInit(): void;
|
|
162
|
+
ngAfterViewInit(): void;
|
|
163
|
+
ngOnDestroy(): void;
|
|
164
|
+
onWindowScroll(): void;
|
|
165
|
+
scrollToSection(target: string): void;
|
|
166
|
+
toggleMobileMenu(): void;
|
|
167
|
+
navigateTo(path: string): void;
|
|
168
|
+
iconBg(hex: string): string;
|
|
169
|
+
private applyColors;
|
|
170
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SpaLandingComponent, never>;
|
|
171
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SpaLandingComponent, "spa-landing", never, { "config": { "alias": "config"; "required": false; }; }, {}, never, ["[lpHeroVisual]", "[lpCustomSection]"], true, never>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export { ALSQUARE_SVG_DARK, ALSQUARE_SVG_WHITE, SpaLandingComponent };
|
|
175
|
+
export type { LandingBrandOverride, LandingColors, LandingConfig, LandingFeature, LandingFooterColumn, LandingFooterLink, LandingMetric, LandingModuleGroup, LandingModuleTile, LandingNavLink, LandingPricingPlan, LandingSecurityItem, LandingStep, LandingTestimonial };
|
package/login/index.d.ts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { OnInit, ChangeDetectorRef } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/router';
|
|
4
|
+
import { Router, ActivatedRoute } from '@angular/router';
|
|
5
|
+
import * as i5 from '@angular/common';
|
|
6
|
+
import { Location } from '@angular/common';
|
|
7
|
+
import * as i6 from 'tin-spa/core';
|
|
8
|
+
import { DataServiceLib, AuthService, HttpService, StorageService, MessageService, LogService, NotificationsService, SignalRService, SetupService, LastRouteService, PreferencesService, TinSpaRuntimeConfig, ApiErrorService, User, AppConfig, SignupData, ApiResponse } from 'tin-spa/core';
|
|
9
|
+
import * as i7 from '@abacritt/angularx-social-login';
|
|
10
|
+
import { SocialAuthServiceConfig, SocialUser } from '@abacritt/angularx-social-login';
|
|
11
|
+
import { MsalService } from '@azure/msal-angular';
|
|
12
|
+
import { MatDialog } from '@angular/material/dialog';
|
|
13
|
+
import * as i4 from '@angular/forms';
|
|
14
|
+
|
|
15
|
+
declare class LoginRoutingModule {
|
|
16
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<LoginRoutingModule, never>;
|
|
17
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<LoginRoutingModule, never, [typeof i1.RouterModule], [typeof i1.RouterModule]>;
|
|
18
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<LoginRoutingModule>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare class LoginComponent implements OnInit {
|
|
22
|
+
private httpService;
|
|
23
|
+
private storageService;
|
|
24
|
+
router: Router;
|
|
25
|
+
private messageService;
|
|
26
|
+
dataService: DataServiceLib;
|
|
27
|
+
authService: AuthService;
|
|
28
|
+
private logService;
|
|
29
|
+
private route;
|
|
30
|
+
private notificationsService;
|
|
31
|
+
private signalRService;
|
|
32
|
+
private msalService;
|
|
33
|
+
private dialog;
|
|
34
|
+
private setupService;
|
|
35
|
+
private lastRouteService;
|
|
36
|
+
private preferencesService;
|
|
37
|
+
private runtimeConfig;
|
|
38
|
+
private apiErrorService;
|
|
39
|
+
private socialAuthConfig;
|
|
40
|
+
constructor(httpService: HttpService, storageService: StorageService, router: Router, messageService: MessageService, dataService: DataServiceLib, authService: AuthService, logService: LogService, route: ActivatedRoute, notificationsService: NotificationsService, signalRService: SignalRService, msalService: MsalService | null, dialog: MatDialog, // Changed: MsalService is now @Optional() — an app that never registers MSAL gets null here instead of a NullInjectorError; the Microsoft button hides itself (showMicrosoftAuth)
|
|
41
|
+
setupService: SetupService, lastRouteService: LastRouteService, preferencesService: PreferencesService, // Added (chunk C): the user's chosen landing page outranks the saved last route
|
|
42
|
+
runtimeConfig: TinSpaRuntimeConfig, apiErrorService: ApiErrorService, // Added: routes application-level (HTTP 200, success:false) failures through the shared classify + dedupe path
|
|
43
|
+
socialAuthConfig: SocialAuthServiceConfig | null);
|
|
44
|
+
private resumeTarget;
|
|
45
|
+
private resumeNavigate;
|
|
46
|
+
ngOnInit(): void;
|
|
47
|
+
get showMicrosoftAuth(): boolean;
|
|
48
|
+
loginWithMS(): void;
|
|
49
|
+
private doMsalLoginPopup;
|
|
50
|
+
autoLogin: boolean;
|
|
51
|
+
socialUser: SocialUser | null;
|
|
52
|
+
rememberMe: boolean;
|
|
53
|
+
style: string;
|
|
54
|
+
email: string;
|
|
55
|
+
password: string;
|
|
56
|
+
redirectPath: any;
|
|
57
|
+
user: User;
|
|
58
|
+
hide: boolean;
|
|
59
|
+
isProcessing: boolean;
|
|
60
|
+
restoring: boolean;
|
|
61
|
+
restoreOffline: boolean;
|
|
62
|
+
private manualLogin;
|
|
63
|
+
appConfig: AppConfig;
|
|
64
|
+
signup(): void;
|
|
65
|
+
recoverAccount(): void;
|
|
66
|
+
signInManually(): void;
|
|
67
|
+
private logSsoDiagnostics;
|
|
68
|
+
private setupForm;
|
|
69
|
+
login(): void;
|
|
70
|
+
notifications(): void;
|
|
71
|
+
openTerms(): void;
|
|
72
|
+
openPrivacy(): void;
|
|
73
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<LoginComponent, [null, null, null, null, null, null, null, null, null, null, { optional: true; }, null, null, null, null, null, null, { optional: true; }]>;
|
|
74
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<LoginComponent, "spa-login", never, {}, {}, never, never, false, never>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
declare class SignupComponent implements OnInit {
|
|
78
|
+
private httpService;
|
|
79
|
+
private messageService;
|
|
80
|
+
dataService: DataServiceLib;
|
|
81
|
+
authService: AuthService;
|
|
82
|
+
private storageService;
|
|
83
|
+
router: Router;
|
|
84
|
+
private msalService;
|
|
85
|
+
private notificationsService;
|
|
86
|
+
private setupService;
|
|
87
|
+
private dialog;
|
|
88
|
+
private cdr;
|
|
89
|
+
private apiErrorService;
|
|
90
|
+
constructor(httpService: HttpService, messageService: MessageService, dataService: DataServiceLib, authService: AuthService, storageService: StorageService, router: Router, msalService: MsalService | null, // Changed: @Optional() — an app that never registers MSAL gets null here instead of a NullInjectorError; the Microsoft button hides itself (showMicrosoftAuth)
|
|
91
|
+
notificationsService: NotificationsService, setupService: SetupService, // Added: SetupService for setup badge
|
|
92
|
+
dialog: MatDialog, cdr: ChangeDetectorRef, // Changed: Inject ChangeDetectorRef for invitation toggle
|
|
93
|
+
apiErrorService: ApiErrorService);
|
|
94
|
+
ngOnInit(): void;
|
|
95
|
+
appConfig: AppConfig;
|
|
96
|
+
style: string;
|
|
97
|
+
signupData: SignupData;
|
|
98
|
+
step: 'provider' | 'form' | 'invitations' | 'complete';
|
|
99
|
+
isProcessing: boolean;
|
|
100
|
+
handleProviderAuth(token: string, authType: string, userName: string): void;
|
|
101
|
+
get showMicrosoftAuth(): boolean;
|
|
102
|
+
loginWithMS(): void;
|
|
103
|
+
private doMsalLoginPopup;
|
|
104
|
+
toggleInvitation(invitation: any): void;
|
|
105
|
+
submit(): void;
|
|
106
|
+
completeLogin(apiResponse: ApiResponse): void;
|
|
107
|
+
goToDashboard(): void;
|
|
108
|
+
goToLogin(): void;
|
|
109
|
+
openTerms(): void;
|
|
110
|
+
openPrivacy(): void;
|
|
111
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SignupComponent, [null, null, null, null, null, null, { optional: true; }, null, null, null, null, null]>;
|
|
112
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SignupComponent, "spa-signup", never, {}, {}, never, never, false, never>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
declare class RecoverAccountComponent implements OnInit {
|
|
116
|
+
private location;
|
|
117
|
+
private dataService;
|
|
118
|
+
authService: AuthService;
|
|
119
|
+
private messageService;
|
|
120
|
+
private apiErrorService;
|
|
121
|
+
constructor(location: Location, dataService: DataServiceLib, authService: AuthService, messageService: MessageService, apiErrorService: ApiErrorService);
|
|
122
|
+
ngOnInit(): void;
|
|
123
|
+
userName: string;
|
|
124
|
+
recover(): void;
|
|
125
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RecoverAccountComponent, never>;
|
|
126
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RecoverAccountComponent, "spa-recover-account", never, {}, {}, never, never, false, never>;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
declare class SpaIndexModule {
|
|
130
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SpaIndexModule, never>;
|
|
131
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<SpaIndexModule, [typeof LoginComponent, typeof SignupComponent, typeof RecoverAccountComponent], [typeof i4.ReactiveFormsModule, typeof i5.CommonModule, typeof i4.FormsModule, typeof i4.ReactiveFormsModule, typeof i6.SpaCoreModule, typeof i7.SocialLoginModule], [typeof i5.CommonModule, typeof i4.FormsModule, typeof i6.SpaCoreModule, typeof LoginComponent, typeof SignupComponent, typeof RecoverAccountComponent]>;
|
|
132
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<SpaIndexModule>;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
declare class LoginModule {
|
|
136
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<LoginModule, never>;
|
|
137
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<LoginModule, never, [typeof i5.CommonModule, typeof LoginRoutingModule, typeof SpaIndexModule], never>;
|
|
138
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<LoginModule>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export { LoginComponent, LoginModule, LoginRoutingModule, RecoverAccountComponent, SignupComponent, SpaIndexModule };
|
package/map/index.d.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { OnChanges, OnDestroy, EventEmitter, ElementRef, NgZone, SimpleChanges } from '@angular/core';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
import { MatDialogRef, MatDialog } from '@angular/material/dialog';
|
|
5
|
+
|
|
6
|
+
declare class MapConfig {
|
|
7
|
+
position?: string | MapPoint | null;
|
|
8
|
+
title?: string;
|
|
9
|
+
subtitle?: string;
|
|
10
|
+
caption?: string;
|
|
11
|
+
zoom?: number;
|
|
12
|
+
mapTypeId?: MapTypeId;
|
|
13
|
+
showCoordinates?: boolean;
|
|
14
|
+
showMapTypeToggle?: boolean;
|
|
15
|
+
interactive?: boolean;
|
|
16
|
+
tileUrl?: string;
|
|
17
|
+
attribution?: string;
|
|
18
|
+
imageryTileUrl?: string;
|
|
19
|
+
imageryAttribution?: string;
|
|
20
|
+
apiKey?: string;
|
|
21
|
+
emptyMessage?: string;
|
|
22
|
+
emptyDetail?: string;
|
|
23
|
+
height?: string;
|
|
24
|
+
markers?: MapMarker[];
|
|
25
|
+
fitMarkers?: boolean;
|
|
26
|
+
fleetTitle?: string;
|
|
27
|
+
}
|
|
28
|
+
interface MapMarker {
|
|
29
|
+
id: string | number;
|
|
30
|
+
position: string | MapPoint | null | undefined;
|
|
31
|
+
title?: string;
|
|
32
|
+
subtitle?: string;
|
|
33
|
+
caption?: string;
|
|
34
|
+
heading?: number | null;
|
|
35
|
+
speed?: number | null;
|
|
36
|
+
speedUnit?: string;
|
|
37
|
+
at?: string | Date | null;
|
|
38
|
+
stale?: boolean;
|
|
39
|
+
}
|
|
40
|
+
interface MapPositionUpdate {
|
|
41
|
+
id: string | number;
|
|
42
|
+
position?: string | MapPoint | null;
|
|
43
|
+
lat?: number | null;
|
|
44
|
+
lng?: number | null;
|
|
45
|
+
at?: string | Date | null;
|
|
46
|
+
speed?: number | null;
|
|
47
|
+
heading?: number | null;
|
|
48
|
+
}
|
|
49
|
+
interface ResolvedMapMarker {
|
|
50
|
+
marker: MapMarker;
|
|
51
|
+
point: MapPoint;
|
|
52
|
+
key: string;
|
|
53
|
+
}
|
|
54
|
+
declare function normaliseMarkers(markers: MapMarker[] | null | undefined): ResolvedMapMarker[];
|
|
55
|
+
declare function markerKey(id: string | number | null | undefined): string | null;
|
|
56
|
+
declare function updatePoint(update: MapPositionUpdate | null | undefined): MapPoint | null;
|
|
57
|
+
interface MapPoint {
|
|
58
|
+
lat: number;
|
|
59
|
+
lng: number;
|
|
60
|
+
}
|
|
61
|
+
type MapTypeId = 'roadmap' | 'satellite' | 'hybrid' | 'terrain';
|
|
62
|
+
declare function parseMapPoint(value: string | MapPoint | null | undefined): MapPoint | null;
|
|
63
|
+
declare function formatMapPoint(point: MapPoint | null): string;
|
|
64
|
+
|
|
65
|
+
type MapState = 'loading' | 'ready' | 'empty' | 'unavailable';
|
|
66
|
+
declare class MapComponent implements OnChanges, OnDestroy {
|
|
67
|
+
private zone;
|
|
68
|
+
config: MapConfig;
|
|
69
|
+
positionStream: Observable<MapPositionUpdate> | null;
|
|
70
|
+
followSelected: boolean;
|
|
71
|
+
closed: EventEmitter<void>;
|
|
72
|
+
markerSelected: EventEmitter<MapMarker>;
|
|
73
|
+
markerMoved: EventEmitter<MapMarker>;
|
|
74
|
+
surface: ElementRef<HTMLDivElement>;
|
|
75
|
+
beacon: ElementRef<HTMLDivElement>;
|
|
76
|
+
state: MapState;
|
|
77
|
+
point: MapPoint | null;
|
|
78
|
+
coordinates: string;
|
|
79
|
+
mapType: MapTypeId;
|
|
80
|
+
offCentre: boolean;
|
|
81
|
+
fleet: boolean;
|
|
82
|
+
resolved: ResolvedMapMarker[];
|
|
83
|
+
selected: MapMarker | null;
|
|
84
|
+
selectedCoordinates: string;
|
|
85
|
+
dropped: number;
|
|
86
|
+
private map;
|
|
87
|
+
private marker;
|
|
88
|
+
private layers;
|
|
89
|
+
private streamSub;
|
|
90
|
+
private base;
|
|
91
|
+
private imagery;
|
|
92
|
+
private tilesSeen;
|
|
93
|
+
private settleTimer;
|
|
94
|
+
constructor(zone: NgZone);
|
|
95
|
+
get title(): string;
|
|
96
|
+
get subtitle(): string;
|
|
97
|
+
get caption(): string;
|
|
98
|
+
get showCoordinates(): boolean;
|
|
99
|
+
get emptyMessage(): string;
|
|
100
|
+
get emptyDetail(): string;
|
|
101
|
+
get fleetTitle(): string;
|
|
102
|
+
get reportingCount(): number;
|
|
103
|
+
get fleetSummary(): string;
|
|
104
|
+
get showMapTypeToggle(): boolean;
|
|
105
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
106
|
+
ngOnDestroy(): void;
|
|
107
|
+
refreshMarkers(): void;
|
|
108
|
+
private start;
|
|
109
|
+
private draw;
|
|
110
|
+
private watchTiles;
|
|
111
|
+
private attachBeacon;
|
|
112
|
+
private drawMarkers;
|
|
113
|
+
private addMarker;
|
|
114
|
+
private beaconHtml;
|
|
115
|
+
private applyMarkers;
|
|
116
|
+
private restyleMarker;
|
|
117
|
+
applyPositionUpdate(update: MapPositionUpdate | null | undefined): boolean;
|
|
118
|
+
markerPosition(id: string | number): MapPoint | null;
|
|
119
|
+
select(marker: MapMarker | null): void;
|
|
120
|
+
clearSelection(): void;
|
|
121
|
+
private fitToMarkers;
|
|
122
|
+
private dropLayers;
|
|
123
|
+
private subscribeStream;
|
|
124
|
+
setPosition(value: string | MapPoint | null | undefined, follow?: boolean): boolean;
|
|
125
|
+
recenter(): void;
|
|
126
|
+
zoomBy(delta: number): void;
|
|
127
|
+
toggleMapType(): void;
|
|
128
|
+
copyCoordinates(): void;
|
|
129
|
+
close(): void;
|
|
130
|
+
private teardown;
|
|
131
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MapComponent, never>;
|
|
132
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MapComponent, "spa-map", never, { "config": { "alias": "config"; "required": false; }; "positionStream": { "alias": "positionStream"; "required": false; }; "followSelected": { "alias": "followSelected"; "required": false; }; }, { "closed": "closed"; "markerSelected": "markerSelected"; "markerMoved": "markerMoved"; }, never, never, true, never>;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
declare class MapDialogComponent {
|
|
136
|
+
dialogRef: MatDialogRef<MapDialogComponent>;
|
|
137
|
+
data: any;
|
|
138
|
+
config: MapConfig;
|
|
139
|
+
constructor(dialogRef: MatDialogRef<MapDialogComponent>, data: any);
|
|
140
|
+
close(): void;
|
|
141
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MapDialogComponent, never>;
|
|
142
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MapDialogComponent, "spa-map-dialog", never, {}, {}, never, never, true, never>;
|
|
143
|
+
}
|
|
144
|
+
declare function normaliseMapData(data: any): MapConfig;
|
|
145
|
+
declare function openMapDialog(dialog: MatDialog, data: MapConfig | string): MatDialogRef<MapDialogComponent, any>;
|
|
146
|
+
|
|
147
|
+
export { MapComponent, MapConfig, MapDialogComponent, formatMapPoint, markerKey, normaliseMapData, normaliseMarkers, openMapDialog, parseMapPoint, updatePoint };
|
|
148
|
+
export type { MapMarker, MapPoint, MapPositionUpdate, MapTypeId, ResolvedMapMarker };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tin-spa",
|
|
3
|
-
"version": "20.14.
|
|
3
|
+
"version": "20.14.113",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/tnyagato/ng-space.git"
|
|
@@ -42,6 +42,30 @@
|
|
|
42
42
|
".": {
|
|
43
43
|
"types": "./index.d.ts",
|
|
44
44
|
"default": "./fesm2022/tin-spa.mjs"
|
|
45
|
+
},
|
|
46
|
+
"./core": {
|
|
47
|
+
"types": "./core/index.d.ts",
|
|
48
|
+
"default": "./fesm2022/tin-spa-core.mjs"
|
|
49
|
+
},
|
|
50
|
+
"./http": {
|
|
51
|
+
"types": "./http/index.d.ts",
|
|
52
|
+
"default": "./fesm2022/tin-spa-http.mjs"
|
|
53
|
+
},
|
|
54
|
+
"./keys": {
|
|
55
|
+
"types": "./keys/index.d.ts",
|
|
56
|
+
"default": "./fesm2022/tin-spa-keys.mjs"
|
|
57
|
+
},
|
|
58
|
+
"./landing": {
|
|
59
|
+
"types": "./landing/index.d.ts",
|
|
60
|
+
"default": "./fesm2022/tin-spa-landing.mjs"
|
|
61
|
+
},
|
|
62
|
+
"./login": {
|
|
63
|
+
"types": "./login/index.d.ts",
|
|
64
|
+
"default": "./fesm2022/tin-spa-login.mjs"
|
|
65
|
+
},
|
|
66
|
+
"./map": {
|
|
67
|
+
"types": "./map/index.d.ts",
|
|
68
|
+
"default": "./fesm2022/tin-spa-map.mjs"
|
|
45
69
|
}
|
|
46
70
|
},
|
|
47
71
|
"sideEffects": false
|
package/src/tin-styles.css
CHANGED
|
@@ -384,6 +384,20 @@ table {
|
|
|
384
384
|
.tin-grid-auto button {
|
|
385
385
|
width: 100%;
|
|
386
386
|
}
|
|
387
|
+
|
|
388
|
+
/* Added (A-0901-11, 2026-09-01): a blank field exists ONLY to reserve an empty CELL in the two-column
|
|
389
|
+
desktop grid. At this breakpoint .tin-grid is a single flex COLUMN, so there is no cell to hold open —
|
|
390
|
+
but the empty wrapper is still a flex item and still costs the full 0.5rem (8px) gap above, which is why
|
|
391
|
+
mobile dialogs showed a mystery double gap with no visible control in it. display:none removes it from
|
|
392
|
+
flex layout entirely; nothing short of that reclaims the gap (a zero-HEIGHT div still gets one, and
|
|
393
|
+
hiding the inner <label> leaves the wrapper behind).
|
|
394
|
+
🔴 `:not(.span-col)` IS LOAD-BEARING — DO NOT SIMPLIFY IT AWAY. A blank that SPANS the row is a
|
|
395
|
+
deliberate vertical SPACER, not a grid filler: datalib.service.ts:1850 uses one as the top spacer of the
|
|
396
|
+
estate-wide Approval form, where it must keep working at every width. Only the non-spanning
|
|
397
|
+
cell-filler kind is meaningless here. blank-mobile-collapse.spec.ts pins both halves. */
|
|
398
|
+
.tin-grid > .tin-blank-field:not(.span-col) {
|
|
399
|
+
display: none;
|
|
400
|
+
}
|
|
387
401
|
}
|
|
388
402
|
|
|
389
403
|
.tin-cluster {
|
|
@@ -672,9 +686,12 @@ spa-form spa-check {
|
|
|
672
686
|
padding-bottom: var(--tin-field-subscript-reserve);
|
|
673
687
|
}
|
|
674
688
|
|
|
675
|
-
/* Composite subfields share a row
|
|
689
|
+
/* Composite subfields share a row, and a row layout defaults to align-items:stretch —
|
|
676
690
|
a checkbox or label among boxed inputs would stretch instead of sitting on the
|
|
677
|
-
band. Match the grid's top alignment so composites align by the same rule.
|
|
691
|
+
band. Match the grid's top alignment so composites align by the same rule.
|
|
692
|
+
Changed (composite redesign, 2026-08-31): the row is now a CSS Grid rather than a
|
|
693
|
+
flex row (form.component.css) — `flex-start` is still the correct value for grid,
|
|
694
|
+
but the sizing rules that make the children divide the slot live with the component. */
|
|
678
695
|
.composite-field-group {
|
|
679
696
|
align-items: flex-start;
|
|
680
697
|
}
|
|
@@ -908,6 +925,12 @@ spa-groups mat-chip .mat-icon {
|
|
|
908
925
|
color: rgba(0, 0, 0, 0.55) !important; /* dimmed value text — still legible but clearly not editable */
|
|
909
926
|
cursor: default;
|
|
910
927
|
}
|
|
928
|
+
/* Added: a readonly textarea kept the browser's default resize gripper in its bottom-right corner — the one
|
|
929
|
+
affordance on the field that still looked draggable, promising an interaction the field does not offer.
|
|
930
|
+
Scoped to .spa-readonly, so an editable textarea keeps its gripper untouched. */
|
|
931
|
+
.mat-mdc-form-field.spa-readonly textarea.mat-mdc-input-element {
|
|
932
|
+
resize: none;
|
|
933
|
+
}
|
|
911
934
|
.mat-mdc-form-field.spa-readonly .mat-mdc-floating-label,
|
|
912
935
|
.mat-mdc-form-field.spa-readonly .mdc-floating-label {
|
|
913
936
|
color: rgba(0, 0, 0, 0.38) !important; /* MDC disabled label color */
|
|
@@ -1582,3 +1605,59 @@ spa-groups mat-chip .mat-icon {
|
|
|
1582
1605
|
--tin-grip-color-hover: rgba(144, 202, 249, 1);
|
|
1583
1606
|
--tin-grip-disabled-color: rgba(176, 182, 192, 0.42);
|
|
1584
1607
|
}
|
|
1608
|
+
|
|
1609
|
+
/* ------------------------------------------------------------------ A PAGE CLAIMING THE BOTTOM-RIGHT CORNER
|
|
1610
|
+
Added 2026-08-31. Library chrome is pinned to the bottom of the viewport and does not know what the page
|
|
1611
|
+
underneath it has put there.
|
|
1612
|
+
|
|
1613
|
+
The agent FAB is fixed bottom-right, which is also where a page may put its primary action — on the desktop
|
|
1614
|
+
POS till it sat on top of the full-bleed 88px CHARGE button. A page that owns that corner adds this class to
|
|
1615
|
+
<body> for as long as it is mounted (spa-pos does it in ngOnInit/ngOnDestroy), the same mechanism
|
|
1616
|
+
update.service.ts uses for `spa-update-prompt-open`. It must be on BODY, not on the page host: spa-agent is
|
|
1617
|
+
mounted by nav-menu, so it is not a descendant of the routed page and inherits nothing from it.
|
|
1618
|
+
|
|
1619
|
+
104px = the 88px CHARGE button plus a 16px breathing gap, so the FAB clears the whole plinth button rather
|
|
1620
|
+
than resting on its edge.
|
|
1621
|
+
|
|
1622
|
+
🔴 Changed 2026-08-31 (Arbiter B.1): lifting the FAB was the RIGHT fix on a PHONE and the WRONG one on a
|
|
1623
|
+
DESKTOP, and the difference is which way the till's primary action runs.
|
|
1624
|
+
On the phone presentation (spa-pos-compact) the CHARGE bar is full-bleed and IS the last 88px of the screen
|
|
1625
|
+
(pos-compact.component.css:204), so the collision is VERTICAL and 104px clears it.
|
|
1626
|
+
On the wide presentation the till is a two-column grid — catalogue plus a full-height TICKET RAIL down the
|
|
1627
|
+
right edge (pos-wide.component.css:85) — and CHARGE is the foot of that rail. Lifting the FAB by 104px moved
|
|
1628
|
+
it off the CHARGE button and straight onto the TOTAL, the single most-read value on a till. Every further
|
|
1629
|
+
pixel up lands on more of the rail: the rail is full-height, so there is NO vertical position on that column
|
|
1630
|
+
that is not somebody's content. THE COLLISION THERE IS HORIZONTAL, and so is the fix — the FAB moves LEFT of
|
|
1631
|
+
the rail and sits back down in its natural corner over the catalogue.
|
|
1632
|
+
|
|
1633
|
+
The widths are the rail's own, read from pos-wide.component.css, plus a 24px gutter:
|
|
1634
|
+
rail 380px (.pw-body grid-template-columns) -> 404px
|
|
1635
|
+
rail 320px (its own max-width:1100px block, same file:236) -> 344px
|
|
1636
|
+
The breakpoint is the library's existing 600px line — the same literal the POS shell swaps presentations on
|
|
1637
|
+
(pos.component.ts:68) and the same one agent.component.css:545 changes the FAB's own defaults at. No new
|
|
1638
|
+
breakpoint is introduced; 600.02px is just the exact complement of `max-width: 600px`.
|
|
1639
|
+
|
|
1640
|
+
🔑 The vertical lift is now PHONE-ONLY, and on this library it is currently INERT: `showFab` stands the FAB
|
|
1641
|
+
DOWN below 600px because the bottom tab bar's Chat tab replaces it (agent.component.html:5-7), so no FAB
|
|
1642
|
+
exists at that width to collide with anything. It is kept, scoped, so that IF the FAB ever returns on the
|
|
1643
|
+
phone it clears the compact till's full-bleed 88px bar instead of sitting on it — but it no longer reaches
|
|
1644
|
+
the desktop, where it was doing the damage. */
|
|
1645
|
+
@media (max-width: 600px) {
|
|
1646
|
+
body.spa-page-owns-fab-corner {
|
|
1647
|
+
--tin-fab-bottom: 104px;
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
/* Above that line is the ONLY width where the FAB and the till actually coexist, and there the answer is
|
|
1652
|
+
purely horizontal: the FAB keeps its natural 24px bottom corner and steps left of the rail. */
|
|
1653
|
+
@media (min-width: 600.02px) {
|
|
1654
|
+
body.spa-page-owns-fab-corner {
|
|
1655
|
+
--tin-fab-right: 404px;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
@media (min-width: 600.02px) and (max-width: 1100px) {
|
|
1660
|
+
body.spa-page-owns-fab-corner {
|
|
1661
|
+
--tin-fab-right: 344px;
|
|
1662
|
+
}
|
|
1663
|
+
}
|