newportsite 1.1.3
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/newportsite-1.1.3.tgz +0 -0
- package/ng-package.json +7 -0
- package/obfuscate.js +70 -0
- package/package.json +15 -0
- package/src/lib/app.component.ts +47 -0
- package/src/lib/app.routing.ts +38 -0
- package/src/lib/auth/alert.component.html +5 -0
- package/src/lib/auth/alert.component.ts +24 -0
- package/src/lib/auth/auth.component.html +1 -0
- package/src/lib/auth/auth.component.ts +10 -0
- package/src/lib/auth/auth.routes.ts +16 -0
- package/src/lib/auth/index.ts +4 -0
- package/src/lib/auth/login.component.html +87 -0
- package/src/lib/auth/login.component.ts +158 -0
- package/src/lib/auth/models/index.ts +1 -0
- package/src/lib/auth/models/user.ts +25 -0
- package/src/lib/auth/register.component.html +157 -0
- package/src/lib/auth/register.component.ts +219 -0
- package/src/lib/auth/services/alert.service.ts +47 -0
- package/src/lib/auth/services/auth.service.ts +28 -0
- package/src/lib/auth/services/index.ts +3 -0
- package/src/lib/auth/services/user.service.spec.ts +112 -0
- package/src/lib/auth/services/user.service.ts +47 -0
- package/src/lib/common/card.component.html +72 -0
- package/src/lib/common/card.component.ts +102 -0
- package/src/lib/common/commands.component.html +8 -0
- package/src/lib/common/commands.component.ts +42 -0
- package/src/lib/common/context.component.html +9 -0
- package/src/lib/common/context.component.ts +38 -0
- package/src/lib/common/grid.component.html +20 -0
- package/src/lib/common/grid.component.ts +747 -0
- package/src/lib/common/index.ts +9 -0
- package/src/lib/common/loader.component.html +5 -0
- package/src/lib/common/loader.component.ts +27 -0
- package/src/lib/common/lookup.component.html +29 -0
- package/src/lib/common/lookup.component.ts +115 -0
- package/src/lib/common/messagebox.component.html +39 -0
- package/src/lib/common/messagebox.component.ts +74 -0
- package/src/lib/common/theme-toggle.component.ts +139 -0
- package/src/lib/config.ts +62 -0
- package/src/lib/containers/default-layout/default-layout.component.html +191 -0
- package/src/lib/containers/default-layout/default-layout.component.ts +158 -0
- package/src/lib/containers/default-layout/index.ts +1 -0
- package/src/lib/containers/index.ts +1 -0
- package/src/lib/directives/component.draggable.ts +80 -0
- package/src/lib/directives/index.ts +2 -0
- package/src/lib/directives/input.directive.spec.ts +158 -0
- package/src/lib/directives/input.directive.ts +210 -0
- package/src/lib/home/dashboard/dashboard.component.html +38 -0
- package/src/lib/home/dashboard/dashboard.component.ts +50 -0
- package/src/lib/home/dashboard/index.ts +1 -0
- package/src/lib/home/index.component.html +1 -0
- package/src/lib/home/index.component.ts +10 -0
- package/src/lib/home/index.routes.ts +29 -0
- package/src/lib/home/index.ts +1 -0
- package/src/lib/home/info/index.ts +1 -0
- package/src/lib/home/info/info.component.css +476 -0
- package/src/lib/home/info/info.component.html +174 -0
- package/src/lib/home/info/info.component.ts +287 -0
- package/src/lib/home/model/article.component.html +10 -0
- package/src/lib/home/model/article.component.ts +50 -0
- package/src/lib/home/model/barchart.component.html +8 -0
- package/src/lib/home/model/barchart.component.ts +59 -0
- package/src/lib/home/model/index.ts +7 -0
- package/src/lib/home/model/itemdetail.component.html +25 -0
- package/src/lib/home/model/itemdetail.component.ts +93 -0
- package/src/lib/home/model/itemtab.component.html +25 -0
- package/src/lib/home/model/itemtab.component.ts +105 -0
- package/src/lib/home/model/model.component.html +121 -0
- package/src/lib/home/model/model.component.ts +510 -0
- package/src/lib/home/model/modeltoolbar.component.html +111 -0
- package/src/lib/home/model/modeltoolbar.component.ts +157 -0
- package/src/lib/home/model/navigation.component.html +86 -0
- package/src/lib/home/model/navigation.component.ts +247 -0
- package/src/lib/home/model/services/index.ts +1 -0
- package/src/lib/home/model/services/model.service.spec.ts +423 -0
- package/src/lib/home/model/services/model.service.ts +319 -0
- package/src/lib/home/modelsearch/index.ts +1 -0
- package/src/lib/home/modelsearch/modelsearch.component.html +124 -0
- package/src/lib/home/modelsearch/modelsearch.component.ts +453 -0
- package/src/lib/interfaces/data.interface.ts +131 -0
- package/src/lib/interfaces/index.ts +2 -0
- package/src/lib/interfaces/item.interface.ts +438 -0
- package/src/lib/players/lookup/lookup.directive.ts +6 -0
- package/src/lib/players/lookup/lookup.item.component.ts +37 -0
- package/src/lib/players/lookup/lookup.item.ts +9 -0
- package/src/lib/players/lookup/lookup.player.component.ts +59 -0
- package/src/lib/players/lookup/lookup.selector.component.ts +41 -0
- package/src/lib/players/model/model.directive.ts +6 -0
- package/src/lib/players/model/model.item.component.spec.ts +311 -0
- package/src/lib/players/model/model.item.component.ts +3457 -0
- package/src/lib/players/model/model.item.ts +9 -0
- package/src/lib/players/model/model.player.component.ts +109 -0
- package/src/lib/players/model/model.selector.component.ts +59 -0
- package/src/lib/scheduler/scheduler.component.html +13 -0
- package/src/lib/scheduler/scheduler.component.scss +6 -0
- package/src/lib/scheduler/scheduler.component.ts +296 -0
- package/src/lib/scheduler/scheduler.routes.ts +15 -0
- package/src/lib/scheduler/schedulerdialog.component.html +72 -0
- package/src/lib/scheduler/schedulerdialog.component.ts +208 -0
- package/src/lib/scheduler/services/scheduler.service.ts +133 -0
- package/src/lib/services/auth-state.service.ts +129 -0
- package/src/lib/services/auth.interceptor.spec.ts +144 -0
- package/src/lib/services/auth.interceptor.ts +44 -0
- package/src/lib/services/cache.service.spec.ts +143 -0
- package/src/lib/services/cache.service.ts +71 -0
- package/src/lib/services/global-error-handler.spec.ts +39 -0
- package/src/lib/services/global-error-handler.ts +28 -0
- package/src/lib/services/global.service.spec.ts +801 -0
- package/src/lib/services/global.service.ts +724 -0
- package/src/lib/services/message.service.ts +556 -0
- package/src/lib/services/theme.service.ts +96 -0
- package/src/lib/template/authtemplate.component.html +6 -0
- package/src/lib/template/authtemplate.component.ts +13 -0
- package/src/lib/template/basetemplate.component.html +7 -0
- package/src/lib/template/basetemplate.component.ts +13 -0
- package/src/lib/template/index.ts +3 -0
- package/src/lib/template/modeltemplate.component.html +7 -0
- package/src/lib/template/modeltemplate.component.ts +21 -0
- package/src/lib/utils/piva.spec.ts +56 -0
- package/src/lib/utils/piva.ts +29 -0
- package/src/lib/validators/email.validator.spec.ts +57 -0
- package/src/lib/validators/email.validator.ts +17 -0
- package/src/lib/validators/equalPasswords.validator.spec.ts +54 -0
- package/src/lib/validators/equalPasswords.validator.ts +17 -0
- package/src/lib/validators/index.ts +2 -0
- package/src/lib/version.ts +1 -0
- package/src/public-api.ts +64 -0
- package/src/typings.d.ts +2 -0
- package/tsconfig.lib.json +18 -0
- package/tsconfig.lib.prod.json +9 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { Directive, ElementRef, HostListener, inject } from '@angular/core';
|
|
2
|
+
import { FieldType, FieldState, FieldAttr, FieldFontSize } from '../interfaces/index';
|
|
3
|
+
|
|
4
|
+
import { GlobalService } from '../services/global.service';
|
|
5
|
+
|
|
6
|
+
import { AppMessageService } from '../services/message.service';
|
|
7
|
+
|
|
8
|
+
@Directive({ selector: '[nvg]', standalone: true })
|
|
9
|
+
export class InputDirective {
|
|
10
|
+
el = inject(ElementRef);
|
|
11
|
+
gsv = inject(GlobalService);
|
|
12
|
+
msg = inject(AppMessageService);
|
|
13
|
+
|
|
14
|
+
/** Returns the named HTML attribute from the host element, or undefined if absent. */
|
|
15
|
+
private attr(key: string): Attr | undefined {
|
|
16
|
+
return (this.el.nativeElement as any).attributes[FieldAttr.get(key)!];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Parses the named HTML attribute as an integer (defaults to 0 if absent). */
|
|
20
|
+
private attrInt(key: string): number {
|
|
21
|
+
return parseInt(this.attr(key)?.value ?? '0', 10);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@HostListener('keydown', ['$event']) onKeyDown(event: KeyboardEvent) {
|
|
25
|
+
if (event.key === 'Enter' && !this.gsv.getDialog()?.state) {
|
|
26
|
+
this.navigateEnter(event.shiftKey);
|
|
27
|
+
} else {
|
|
28
|
+
if (this.isReadOnlyField(event)) return false;
|
|
29
|
+
if (!this.isControlKey(event)) return this.handleTypedKey(event);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Moves focus to the previous or next focusable element based on the Shift key state. */
|
|
34
|
+
private navigateEnter(backward: boolean): void {
|
|
35
|
+
const tbidx = this.el.nativeElement.tabIndex;
|
|
36
|
+
const element = backward ? this.findPrevFocusable(tbidx) : this.findNextFocusable(tbidx);
|
|
37
|
+
element?.focus();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Scans forward through tabindex values to find the next enabled, visible input or select. */
|
|
41
|
+
private findNextFocusable(tbidx: number): HTMLElement | null {
|
|
42
|
+
let element: HTMLElement | null = null;
|
|
43
|
+
do {
|
|
44
|
+
tbidx++;
|
|
45
|
+
element = document.querySelector<HTMLElement>(
|
|
46
|
+
`input[tabindex="${tbidx}"], select[tabindex="${tbidx}"]`
|
|
47
|
+
);
|
|
48
|
+
} while (
|
|
49
|
+
(!element || element.hidden || element.getAttribute('disabled') !== null) &&
|
|
50
|
+
tbidx < 1024
|
|
51
|
+
);
|
|
52
|
+
return element;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Scans backward through tabindex values to find the previous enabled, visible input or select. */
|
|
56
|
+
private findPrevFocusable(tbidx: number): HTMLElement | null {
|
|
57
|
+
if (tbidx <= 0) return null;
|
|
58
|
+
let element: HTMLElement | null = null;
|
|
59
|
+
do {
|
|
60
|
+
tbidx--;
|
|
61
|
+
const inputs = document.querySelectorAll<HTMLElement>(`input[tabindex="${tbidx}"]`);
|
|
62
|
+
const selects = document.querySelectorAll<HTMLElement>(`select[tabindex="${tbidx}"]`);
|
|
63
|
+
element = inputs.length > 0 ? inputs[inputs.length - 1]
|
|
64
|
+
: selects.length > 0 ? selects[selects.length - 1] : null;
|
|
65
|
+
} while (
|
|
66
|
+
(!element || element.hidden || element.getAttribute('disabled') !== null) &&
|
|
67
|
+
tbidx >= 0
|
|
68
|
+
);
|
|
69
|
+
return element;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Returns true when the host field is in a state that should block typed input. */
|
|
73
|
+
private isReadOnlyField(event: KeyboardEvent): boolean {
|
|
74
|
+
return (
|
|
75
|
+
this.el.nativeElement.value === undefined ||
|
|
76
|
+
!!this.el.nativeElement.attributes['disabled'] ||
|
|
77
|
+
this.attrInt('state') === FieldState.ReadOnly ||
|
|
78
|
+
this.el.nativeElement.readOnly ||
|
|
79
|
+
(((event.ctrlKey && event.key === '@') || event.shiftKey || event.altKey) &&
|
|
80
|
+
this.attr('type') !== undefined &&
|
|
81
|
+
this.attrInt('type') === FieldType.Number)
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Clears a multi-char selection if present, adjusts font size, then delegates to the type-specific handler. */
|
|
86
|
+
private handleTypedKey(event: KeyboardEvent): boolean | void {
|
|
87
|
+
const native = this.el.nativeElement;
|
|
88
|
+
if (native.selectionEnd - native.selectionStart > 1) native.value = '';
|
|
89
|
+
if (this.attr('type') === undefined) return;
|
|
90
|
+
|
|
91
|
+
const inputLen = native.value.length * FieldFontSize.compactPx;
|
|
92
|
+
native.style.fontSize =
|
|
93
|
+
inputLen > parseFloat(native.style.width) ? FieldFontSize.compact : FieldFontSize.default;
|
|
94
|
+
|
|
95
|
+
switch (this.attrInt('type')) {
|
|
96
|
+
case FieldType.Text: return this.handleTextKey(event);
|
|
97
|
+
case FieldType.Number: return this.handleNumberKey(event);
|
|
98
|
+
case FieldType.TextualCheck: return this.handleTextualCheckKey(event);
|
|
99
|
+
case FieldType.Date: return this.handleDateKey(event);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Validates a keystroke for Text fields: checks allowedchars and maxLength regex. */
|
|
104
|
+
private handleTextKey(event: KeyboardEvent): boolean {
|
|
105
|
+
const ac = this.attr('allowchar');
|
|
106
|
+
if (ac?.value && !this.regExpressionMatch(ac.value, event.key.toUpperCase())) return false;
|
|
107
|
+
const value = this.el.nativeElement.value + event.key.toUpperCase();
|
|
108
|
+
const maxLen = parseInt(this.el.nativeElement.getAttribute(FieldAttr.get('length')!) ?? '0', 10);
|
|
109
|
+
return value.match(`^[A-Za-z0-9, %/@\\-+().']{0,${maxLen}}$`) !== null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Validates a keystroke for Number fields: enforces precision, scale, sign, and locale decimal separator. */
|
|
113
|
+
private handleNumberKey(event: KeyboardEvent): boolean {
|
|
114
|
+
const nmv = this.el.nativeElement.value + event.key;
|
|
115
|
+
const prc = this.attrInt('length');
|
|
116
|
+
const scl = this.attrInt('decimal');
|
|
117
|
+
const dec = this.gsv.getDecimalChar();
|
|
118
|
+
const intPart = this.attr('sign')?.value === 'true' ? `^+?[-0-9]{0,${prc}}` : `^[0-9]{0,${prc}}`;
|
|
119
|
+
const regExp = scl === 0 ? `${intPart}$` : `${intPart}(\\${dec}\\d{0,${scl}})?$`;
|
|
120
|
+
return nmv.match(regExp) !== null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Handles Space (toggle) and 'X' entry for TextualCheck fields; blocks all other keys. */
|
|
124
|
+
private handleTextualCheckKey(event: KeyboardEvent): boolean | void {
|
|
125
|
+
if (event.key === ' ') { this.invertTextualCheck(); return false; }
|
|
126
|
+
if (event.key.toUpperCase() !== 'X' || this.el.nativeElement.value.length > 0) return false;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Validates a keystroke for Date fields: allows only digits, auto-inserts slashes at positions 3 and 6. */
|
|
130
|
+
private handleDateKey(event: KeyboardEvent): boolean | void {
|
|
131
|
+
const dtv = this.el.nativeElement.value + event.key;
|
|
132
|
+
if (dtv.length > 10) return false;
|
|
133
|
+
if (dtv.length === 3 || dtv.length === 6) this.el.nativeElement.value += '/';
|
|
134
|
+
if (!(event.key >= '0' && event.key <= '9')) return false;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@HostListener('click', ['$event']) onClick(_event: MouseEvent) {
|
|
138
|
+
if (
|
|
139
|
+
this.attr('type') !== undefined &&
|
|
140
|
+
this.attrInt('type') === FieldType.TextualCheck
|
|
141
|
+
) {
|
|
142
|
+
this.invertTextualCheck();
|
|
143
|
+
this.sendChanged();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@HostListener('dblclick', ['$event']) dblClick(_event: MouseEvent) {
|
|
148
|
+
this.sendChanged('setForced');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@HostListener('focus') onFocus() {
|
|
152
|
+
if (this.el.nativeElement.id && this.attr('type') !== undefined) {
|
|
153
|
+
const typeComponent = this.attrInt('type');
|
|
154
|
+
if (
|
|
155
|
+
typeComponent !== FieldType.Label &&
|
|
156
|
+
typeComponent !== FieldType.Combo
|
|
157
|
+
) {
|
|
158
|
+
this.gsv.setCurrentField(this.el.nativeElement);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@HostListener('blur') onBlur() {
|
|
164
|
+
if (!this.gsv.getDialog()?.state) {
|
|
165
|
+
this.sendChanged();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Returns true for modifier keys, arrows, Escape, Enter, Backspace, Tab, and function keys. */
|
|
170
|
+
isControlKey(event: KeyboardEvent): boolean {
|
|
171
|
+
return (
|
|
172
|
+
event.altKey ||
|
|
173
|
+
event.shiftKey ||
|
|
174
|
+
event.ctrlKey ||
|
|
175
|
+
event.key?.indexOf('Arrow') >= 0 ||
|
|
176
|
+
event.key === 'Escape' ||
|
|
177
|
+
event.key === 'Enter' ||
|
|
178
|
+
event.key === 'Backspace' ||
|
|
179
|
+
event.key === 'Tab' ||
|
|
180
|
+
/^F(1[0-2]|[1-9])$/.test(event.key)
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** Toggles a TextualCheck field between 'X' (checked) and '' (unchecked). */
|
|
185
|
+
invertTextualCheck(): void {
|
|
186
|
+
if (this.attrInt('state') !== FieldState.ReadOnly) {
|
|
187
|
+
if (this.el.nativeElement.value === 'X') {
|
|
188
|
+
this.el.nativeElement.value = '';
|
|
189
|
+
this.el.nativeElement.checked = false;
|
|
190
|
+
} else {
|
|
191
|
+
this.el.nativeElement.value = 'X';
|
|
192
|
+
this.el.nativeElement.checked = true;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** Tests whether the given key matches the provided regular expression string. */
|
|
198
|
+
regExpressionMatch(rem: string, key: string): boolean {
|
|
199
|
+
return new RegExp(rem.toUpperCase()).test(key);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Notifies GlobalService that the field value has changed, carrying the field id, value, and function name. */
|
|
203
|
+
sendChanged(functionName = 'sendChanged') {
|
|
204
|
+
this.gsv.setFieldChanged({
|
|
205
|
+
id: this.el.nativeElement.getAttribute('id') ?? '',
|
|
206
|
+
value: this.el.nativeElement.value.toUpperCase(),
|
|
207
|
+
function: functionName,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<basetemplate>
|
|
2
|
+
<div class="container-fluid">
|
|
3
|
+
<div>
|
|
4
|
+
<div class="row align-items-start">
|
|
5
|
+
@for (project of currentProjects; track project) {
|
|
6
|
+
<div class="p-1 col-sm-6 col-md-4">
|
|
7
|
+
<div class="card">
|
|
8
|
+
<div class="card-body">
|
|
9
|
+
<h5 class="card-title">
|
|
10
|
+
<h1 class="bg-transparent truncate">
|
|
11
|
+
{{ msg?.getProjectInfo(project, 'description') }}
|
|
12
|
+
</h1>
|
|
13
|
+
</h5>
|
|
14
|
+
<div
|
|
15
|
+
class="truncate"
|
|
16
|
+
title="{{
|
|
17
|
+
msg?.getProjectInfo(project, 'extendeddescription')
|
|
18
|
+
}}">
|
|
19
|
+
{{ msg?.getProjectInfo(project, 'extendeddescription') }}
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="nopaddingtae">
|
|
23
|
+
<button
|
|
24
|
+
title="{{ msg?.get('app.dashboard.module.start') }}"
|
|
25
|
+
class="btn bi bi-box-arrow-right"
|
|
26
|
+
(click)="activate(project)"
|
|
27
|
+
[hidden]="!project.active"></button>
|
|
28
|
+
<h1 class="bg-transparent truncate" [hidden]="project.active">
|
|
29
|
+
{{ msg?.get('app.dashboard.module.inactive') }}
|
|
30
|
+
</h1>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
}
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</basetemplate>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Component,
|
|
3
|
+
ChangeDetectionStrategy,
|
|
4
|
+
ChangeDetectorRef,
|
|
5
|
+
DestroyRef,
|
|
6
|
+
inject,
|
|
7
|
+
} from '@angular/core';
|
|
8
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
9
|
+
|
|
10
|
+
import { GlobalService } from '../../services/global.service';
|
|
11
|
+
|
|
12
|
+
import { AppMessageService } from '../../services/message.service';
|
|
13
|
+
|
|
14
|
+
import { UserLicenses } from '../../interfaces/index';
|
|
15
|
+
|
|
16
|
+
import { BaseTemplateComponent } from '../../template/basetemplate.component';
|
|
17
|
+
|
|
18
|
+
@Component({
|
|
19
|
+
selector: 'dashboard',
|
|
20
|
+
templateUrl: 'dashboard.component.html',
|
|
21
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
22
|
+
imports: [BaseTemplateComponent],
|
|
23
|
+
})
|
|
24
|
+
export class DashboardComponent {
|
|
25
|
+
gsv = inject(GlobalService);
|
|
26
|
+
msg = inject(AppMessageService);
|
|
27
|
+
private cdr = inject(ChangeDetectorRef);
|
|
28
|
+
private destroyRef = inject(DestroyRef);
|
|
29
|
+
|
|
30
|
+
constructor() {
|
|
31
|
+
this.gsv
|
|
32
|
+
.getStateChanged()
|
|
33
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
34
|
+
.subscribe(() => this.cdr.markForCheck());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get currentProjects() {
|
|
38
|
+
return this.gsv?.getProjects()[this.gsv.getYear()];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Activates the selected project license and navigates to its home view. */
|
|
42
|
+
public activate(prj: UserLicenses) {
|
|
43
|
+
this.gsv.activateProject(prj);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Opens the given help URL in an external browser tab. */
|
|
47
|
+
public help(url: string) {
|
|
48
|
+
this.gsv.externalnavigate(url);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dashboard.component';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<router-outlet></router-outlet>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
|
2
|
+
import { RouterOutlet } from '@angular/router';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'index',
|
|
6
|
+
templateUrl: 'index.component.html',
|
|
7
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
8
|
+
imports: [RouterOutlet],
|
|
9
|
+
})
|
|
10
|
+
export class IndexComponent {}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Routes } from '@angular/router';
|
|
2
|
+
import { IndexComponent } from './index';
|
|
3
|
+
import { ModelComponent } from './model/index';
|
|
4
|
+
import { ModelSearchComponent } from './modelsearch/index';
|
|
5
|
+
import { authGuard } from '../auth/services/auth.service';
|
|
6
|
+
import { DashboardComponent } from './dashboard/index';
|
|
7
|
+
import { InfoComponent } from './info/index';
|
|
8
|
+
|
|
9
|
+
export const INDEX_ROUTES: Routes = [
|
|
10
|
+
{
|
|
11
|
+
path: '',
|
|
12
|
+
component: IndexComponent,
|
|
13
|
+
children: [
|
|
14
|
+
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
|
|
15
|
+
{
|
|
16
|
+
path: 'dashboard',
|
|
17
|
+
component: DashboardComponent,
|
|
18
|
+
canActivate: [authGuard],
|
|
19
|
+
},
|
|
20
|
+
{ path: 'model', component: ModelComponent, canActivate: [authGuard] },
|
|
21
|
+
{
|
|
22
|
+
path: 'modelsearch',
|
|
23
|
+
component: ModelSearchComponent,
|
|
24
|
+
canActivate: [authGuard],
|
|
25
|
+
},
|
|
26
|
+
{ path: 'info', component: InfoComponent },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index.component';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './info.component';
|