@yomotech/view-toolkit 0.0.31 → 0.0.32
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/ng-package.json +7 -0
- package/package.json +38 -49
- package/src/lib/app-version.ts +2 -0
- package/src/lib/components/autocomplete/autocomplete.css +0 -0
- package/src/lib/components/autocomplete/autocomplete.html +23 -0
- package/src/lib/components/autocomplete/autocomplete.ts +71 -0
- package/src/lib/components/button/button.css +0 -0
- package/src/lib/components/button/button.html +1 -0
- package/src/lib/components/button/button.ts +11 -0
- package/src/lib/components/date/date.css +0 -0
- package/src/lib/components/date/date.html +1 -0
- package/src/lib/components/date/date.ts +11 -0
- package/src/lib/components/dropdown/dropdown.css +0 -0
- package/src/lib/components/dropdown/dropdown.html +1 -0
- package/src/lib/components/dropdown/dropdown.ts +11 -0
- package/src/lib/components/error-message/error-message.css +0 -0
- package/src/lib/components/error-message/error-message.html +1 -0
- package/src/lib/components/error-message/error-message.ts +11 -0
- package/src/lib/components/label/label.css +0 -0
- package/src/lib/components/label/label.html +7 -0
- package/src/lib/components/label/label.ts +33 -0
- package/src/lib/components/string/string.css +0 -0
- package/src/lib/components/string/string.html +4 -0
- package/src/lib/components/string/string.ts +22 -0
- package/src/lib/components/textbox/textbox.css +0 -0
- package/src/lib/components/textbox/textbox.html +7 -0
- package/src/lib/components/textbox/textbox.ts +33 -0
- package/src/lib/components/time/time.css +0 -0
- package/src/lib/components/time/time.html +1 -0
- package/src/lib/components/time/time.ts +11 -0
- package/src/lib/containers/card/card.component.css +0 -0
- package/src/lib/containers/card/card.component.html +450 -0
- package/src/lib/containers/card/card.component.ts +474 -0
- package/src/lib/containers/form/form.component.css +101 -0
- package/src/lib/containers/form/form.component.html +305 -0
- package/src/lib/containers/form/form.component.ts +333 -0
- package/src/lib/containers/grid/grid.component.css +0 -0
- package/src/lib/containers/grid/grid.component.html +212 -0
- package/src/lib/containers/grid/grid.component.ts +228 -0
- package/src/lib/containers/header-menu/header-menu.component.css +0 -0
- package/src/lib/containers/header-menu/header-menu.component.html +72 -0
- package/src/lib/containers/header-menu/header-menu.component.ts +105 -0
- package/src/lib/containers/logs/logs.component.css +160 -0
- package/src/lib/containers/logs/logs.component.html +89 -0
- package/src/lib/containers/logs/logs.component.ts +29 -0
- package/src/lib/containers/model/model.component.css +0 -0
- package/src/lib/containers/model/model.component.html +351 -0
- package/src/lib/containers/model/model.component.ts +436 -0
- package/src/lib/containers/pagination/pagination.component.css +0 -0
- package/src/lib/containers/pagination/pagination.component.html +41 -0
- package/src/lib/containers/pagination/pagination.component.ts +100 -0
- package/src/lib/containers/side-menu/side-menu.component.css +173 -0
- package/src/lib/containers/side-menu/side-menu.component.html +126 -0
- package/src/lib/containers/side-menu/side-menu.component.ts +458 -0
- package/src/lib/services/app-version-reset.service.ts +59 -0
- package/src/lib/services/config.service.ts +144 -0
- package/src/lib/services/couchdb.ts +275 -0
- package/src/lib/services/mobile-keycloak.service.ts +116 -0
- package/src/lib/services/network-log.service.ts +27 -0
- package/src/lib/services/notification.service.ts +26 -0
- package/src/lib/services/request.service.ts +125 -0
- package/src/lib/services/utility.service.ts +600 -0
- package/src/lib/view-toolkit.module.ts +57 -0
- package/src/lib/view-toolkit.spec.ts +23 -0
- package/src/lib/view-toolkit.ts +15 -0
- package/src/public-api.ts +25 -0
- package/tsconfig.lib.json +17 -0
- package/tsconfig.lib.prod.json +11 -0
- package/tsconfig.spec.json +15 -0
- package/fesm2022/yomotech-view-toolkit.mjs +0 -3597
- package/fesm2022/yomotech-view-toolkit.mjs.map +0 -1
- package/types/yomotech-view-toolkit.d.ts +0 -648
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
<div *ngIf="!tableitemInfo.data?.length" class="alert alert-warning col-md-12" role="alert">
|
|
2
|
+
{{ tableitemInfo.layoutSchema?.noRecordMessage}}
|
|
3
|
+
</div>
|
|
4
|
+
<div *ngIf="tableitemInfo.data?.length" class="reservation-container pt-5 px-3">
|
|
5
|
+
<nz-table #basicTable [nzData]="tableitemInfo.data" [nzBordered]="true"
|
|
6
|
+
[nzFrontPagination]="currenTableOptions?.pagination?.tabs"
|
|
7
|
+
[style]="getStyleWithoutClasses(currenTableOptions?.style).style" (scroll)="onScrollEvent($event)"
|
|
8
|
+
[nzLoading]="isTableDataLoad">
|
|
9
|
+
<thead>
|
|
10
|
+
<tr>
|
|
11
|
+
<th *ngFor="let column of tableitemInfo.layoutSchema.elements">{{ column?.label?.caption }}</th>
|
|
12
|
+
</tr>
|
|
13
|
+
</thead>
|
|
14
|
+
<tbody>
|
|
15
|
+
<tr *ngFor="let data of tableitemInfo.data; let i = index">
|
|
16
|
+
<td *ngFor="let col of tableitemInfo.layoutSchema.elements"
|
|
17
|
+
[style]="getStyleWithoutClasses(col?.scope?.style).style">
|
|
18
|
+
<ng-container
|
|
19
|
+
*ngIf="tableitemInfo.propertySchema[getScope(col.scope?.reference)] && tableitemInfo.propertySchema[getScope(col.scope?.reference)][col?.scope?.reference?.split('/').pop()]?.type === 'string'"
|
|
20
|
+
[class]="getStyleWithoutClasses(col?.scope?.style).classes"
|
|
21
|
+
[style]="getStyleWithoutClasses(col?.scope?.style).style">
|
|
22
|
+
<span *ngIf="col.option.protected">
|
|
23
|
+
<span *ngIf="col.option?.link" (click)="showLinkDetails(col.option, data)">
|
|
24
|
+
{{data[col.scope?.reference.split('/').pop()]}}
|
|
25
|
+
</span>
|
|
26
|
+
<span *ngIf="!col.option?.link">
|
|
27
|
+
<ng-container *ngIf="col?.option?.dateFormat; else string">
|
|
28
|
+
{{ data[col.scope?.reference.split('/').pop()] | date:'yyyy-MM-dd' }}
|
|
29
|
+
</ng-container>
|
|
30
|
+
<ng-template #string>
|
|
31
|
+
{{ data[col.scope?.reference.split('/').pop()] }}
|
|
32
|
+
</ng-template>
|
|
33
|
+
</span>
|
|
34
|
+
</span>
|
|
35
|
+
<span *ngIf="!col.option.protected">
|
|
36
|
+
<input [(ngModel)]="data[col.scope?.reference.split('/').pop()]"
|
|
37
|
+
class="p-inputtext p-component" />
|
|
38
|
+
</span>
|
|
39
|
+
</ng-container>
|
|
40
|
+
|
|
41
|
+
<ng-container
|
|
42
|
+
*ngIf="tableitemInfo.propertySchema[getScope(col.scope?.reference)] && tableitemInfo.propertySchema[getScope(col.scope?.reference)][col?.scope?.reference?.split('/').pop()]?.type === 'number'">
|
|
43
|
+
<span *ngIf="col.option.protected">
|
|
44
|
+
<span *ngIf="col.option?.innerAction?.action == 'multiply'">
|
|
45
|
+
{{
|
|
46
|
+
(data[col.option?.innerAction?.from] * data[col.option?.innerAction?.to])
|
|
47
|
+
| number:'1.2-2'
|
|
48
|
+
}}
|
|
49
|
+
</span>
|
|
50
|
+
<span *ngIf="!col.option?.innerAction">
|
|
51
|
+
{{data[col.scope?.reference.split('/').pop()] | currency:
|
|
52
|
+
tableitemInfo.propertySchema[getScope(col.scope?.reference)][col?.scope?.reference?.split('/').pop()]?.currency
|
|
53
|
+
:true }}
|
|
54
|
+
</span>
|
|
55
|
+
</span>
|
|
56
|
+
<span *ngIf="!col.option.protected">
|
|
57
|
+
<input [(ngModel)]="data[col.scope?.reference.split('/').pop()]" type="number"
|
|
58
|
+
class="p-inputtext p-component" />
|
|
59
|
+
</span>
|
|
60
|
+
</ng-container>
|
|
61
|
+
|
|
62
|
+
<ng-container
|
|
63
|
+
*ngIf="tableitemInfo.propertySchema[getScope(col.scope?.reference)] && tableitemInfo.propertySchema[getScope(col.scope?.reference)][col?.scope?.reference?.split('/').pop()]?.type === 'image'">
|
|
64
|
+
<img *ngIf="data[col.scope?.reference.split('/').pop()]"
|
|
65
|
+
[src]="data[col.scope?.reference.split('/').pop()]" alt="Image"
|
|
66
|
+
(click)="invokeTableImageClick(col, data)"
|
|
67
|
+
[style]="getStyleWithoutClasses(col?.scope?.style).style" />
|
|
68
|
+
</ng-container>
|
|
69
|
+
|
|
70
|
+
<ng-container *ngIf="!col?.scope?.reference">
|
|
71
|
+
<span *ngIf="col.option?.actionColumn">
|
|
72
|
+
<span nz-icon *ngIf="setActionColumn(col.option?.save, data)" [nzType]="col.option?.save?.icon" [nzTheme]="'twotone'"
|
|
73
|
+
[style]="col.option?.save?.style" [nzTwotoneColor]="'#52c41a'"
|
|
74
|
+
[class]="col.option?.save?.style?.classes[0]" (click)="upsertAction(col.option?.save, data)">
|
|
75
|
+
</span>
|
|
76
|
+
<span nz-icon *ngIf="setActionColumn(col.option?.delete, data)" [nzType]="col.option?.delete?.icon" [nzTheme]="'twotone'"
|
|
77
|
+
[style]="col.option?.delete?.style" [nzTwotoneColor]="'#FF0000'"
|
|
78
|
+
[class]="col.option?.delete?.style?.classes[0]"
|
|
79
|
+
(click)="upsertAction(col.option?.delete, data)"></span>
|
|
80
|
+
|
|
81
|
+
</span>
|
|
82
|
+
<span *ngIf="!col.option?.actionColumn">
|
|
83
|
+
<button type="submit" [style]="getStyleWithoutClasses(col?.label?.style).style"
|
|
84
|
+
(click)="invokeGridBtnClick(col.option, data)" [class]="col?.label?.style?.classes[0]">
|
|
85
|
+
{{ col.label?.caption }}
|
|
86
|
+
</button>
|
|
87
|
+
</span>
|
|
88
|
+
</ng-container>
|
|
89
|
+
|
|
90
|
+
<!-- For quantity column, display increment/decrement buttons -->
|
|
91
|
+
<ng-container
|
|
92
|
+
*ngIf="tableitemInfo.propertySchema[getScope(col.scope?.reference)] && tableitemInfo.propertySchema[getScope(col.scope?.reference)][col?.scope?.reference?.split('/').pop()]?.type === 'quantity'">
|
|
93
|
+
<div style="display: flex; align-items: center;">
|
|
94
|
+
<button pButton icon="pi pi-minus"
|
|
95
|
+
(click)="decrementQuantity(i,col.scope?.reference.split('/').pop(), col.option)"
|
|
96
|
+
[disabled]="data.quantity <= 0"
|
|
97
|
+
style="margin-right: 8px; height: 10px; width: 10px;"></button>
|
|
98
|
+
<span>{{ data[col.scope?.reference.split('/').pop()] }}</span>
|
|
99
|
+
<button pButton icon="pi pi-plus"
|
|
100
|
+
(click)="incrementQuantity(i, col.scope?.reference.split('/').pop(), col.option)"
|
|
101
|
+
style="margin-left: 8px; height: 10px; width: 10px;"></button>
|
|
102
|
+
</div>
|
|
103
|
+
</ng-container>
|
|
104
|
+
</td>
|
|
105
|
+
</tr>
|
|
106
|
+
</tbody>
|
|
107
|
+
</nz-table>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<!-- table footer -->
|
|
111
|
+
<div *ngIf="tableitemInfo?.footer?.formFields && tableitemInfo.data?.length"
|
|
112
|
+
class="table-footer flex flex-column align-items-end gap-2 pt-2 mx-4 border-top-1 border-cyan-500">
|
|
113
|
+
<div *ngFor="let tableField of tableitemInfo?.footer?.formFields">
|
|
114
|
+
<div
|
|
115
|
+
[ngSwitch]="tableField?.scope?.reference && tableitemInfo.propertySchema[getScope(tableField.scope?.reference)] && tableitemInfo.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()] ?
|
|
116
|
+
tableitemInfo.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()]?.type : 'default'">
|
|
117
|
+
|
|
118
|
+
<!-- string control -->
|
|
119
|
+
<div *ngSwitchCase="'string'" class="form-group">
|
|
120
|
+
<span *ngIf="tableField.option.protected">
|
|
121
|
+
<h5 style="display: flex; justify-content: space-between;">
|
|
122
|
+
<span [style]="getStyleWithoutClasses(tableField?.label?.style).style"
|
|
123
|
+
[class]="tableField?.label?.style?.classes[0]">
|
|
124
|
+
{{
|
|
125
|
+
tableitemInfo.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()]?.caption
|
|
126
|
+
}}
|
|
127
|
+
</span>
|
|
128
|
+
<span>
|
|
129
|
+
{{
|
|
130
|
+
tableitemInfo.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()]?.value
|
|
131
|
+
}}
|
|
132
|
+
</span>
|
|
133
|
+
</h5>
|
|
134
|
+
</span>
|
|
135
|
+
<div *ngIf="!tableField.option.protected">
|
|
136
|
+
<div [class]="tableField?.layout == 'horizontal' ? 'horizontal-layout' : 'row'">
|
|
137
|
+
<label [style]="getStyleWithoutClasses(tableField?.label?.style).style"
|
|
138
|
+
[class]="tableField?.label?.style?.classes[0]">{{ tableField.label?.value ?
|
|
139
|
+
tableField.label?.value :
|
|
140
|
+
tableitemInfo.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()]?.caption
|
|
141
|
+
}}</label>
|
|
142
|
+
<input type="text" #inputField="ngModel" [required]="tableField.option.required"
|
|
143
|
+
[email]="tableField.option.email" [class]="tableField.scope?.style?.classes[0]"
|
|
144
|
+
[style]="getStyleWithoutClasses(tableField?.scope?.style).style"
|
|
145
|
+
[(ngModel)]="tableitemInfo.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()].value"
|
|
146
|
+
[name]="tableField.scope?.reference"
|
|
147
|
+
[placeholder]="tableitemInfo.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()]?.placeholder" />
|
|
148
|
+
</div>
|
|
149
|
+
<!-- Error Message -->
|
|
150
|
+
<div *ngIf="inputField?.touched && inputField?.invalid"
|
|
151
|
+
[style]="getStyleWithoutClasses(tableField?.validation?.style).style">
|
|
152
|
+
<p class="text-danger" *ngIf="inputField?.errors?.['required']">{{tableField.label?.value ?
|
|
153
|
+
tableField.label?.value :
|
|
154
|
+
tableitemInfo.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()]?.caption
|
|
155
|
+
+
|
|
156
|
+
' ' + errorMessages.required}}</p>
|
|
157
|
+
<p class="text-danger" *ngIf="inputField?.errors?.['email']">{{(tableField.label?.value ?
|
|
158
|
+
tableField.label?.value :
|
|
159
|
+
tableitemInfo.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()]?.caption)
|
|
160
|
+
+
|
|
161
|
+
' ' + errorMessages.pattern}}</p>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<!-- number control -->
|
|
167
|
+
<div *ngSwitchCase="'number'" class="form-group">
|
|
168
|
+
<span *ngIf="tableField.option.protected"
|
|
169
|
+
[style]="getStyleWithoutClasses(tableField?.label?.style).style"
|
|
170
|
+
[class]="tableField?.label?.style?.classes[0]">
|
|
171
|
+
<h5>{{
|
|
172
|
+
form.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()]?.caption
|
|
173
|
+
}} {{
|
|
174
|
+
form.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()]?.value
|
|
175
|
+
|
|
|
176
|
+
currency:tableField.option.currency :true: tableField.option?.decimalPoint}}
|
|
177
|
+
</h5>
|
|
178
|
+
</span>
|
|
179
|
+
<span *ngIf="!tableField.option.protected">
|
|
180
|
+
<div [class]="tableField?.layout == 'horizontal' ? 'horizontal-layout' : 'row'">
|
|
181
|
+
<label [style]="getStyleWithoutClasses(tableField?.label?.style).style"
|
|
182
|
+
[class]="tableField?.label?.style?.classes[0]">{{ tableField.label?.value ?
|
|
183
|
+
tableField.label?.value :
|
|
184
|
+
form.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()]?.caption
|
|
185
|
+
}}</label>
|
|
186
|
+
<input type="number" [class]="tableField.scope?.style?.classes[0]"
|
|
187
|
+
[style]="getStyleWithoutClasses(tableField?.scope?.style).style"
|
|
188
|
+
[(ngModel)]="form.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()].value"
|
|
189
|
+
[name]="tableField.scope?.reference"
|
|
190
|
+
[placeholder]="form.propertySchema[getScope(tableField.scope?.reference)][tableField.scope?.reference.split('/').pop()]?.placeholder" />
|
|
191
|
+
</div>
|
|
192
|
+
</span>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<!-- button control -->
|
|
196
|
+
<div *ngSwitchCase="'default'">
|
|
197
|
+
<button type="submit" [style]="getStyleWithoutClasses(tableField.label.style).style"
|
|
198
|
+
(click)="invokeGridBtnClick(tableField.option, tableitemInfo.propertySchema)">
|
|
199
|
+
{{ tableField.label?.caption }}
|
|
200
|
+
</button>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
|
|
206
|
+
<!-- bottom pagination on grid -->
|
|
207
|
+
<div
|
|
208
|
+
*ngIf="tableitemInfo.data?.length && !tableitemInfo?.layoutSchema?.pagination?.top && tableitemInfo?.layoutSchema?.pagination?.bottom">
|
|
209
|
+
<vl-pagination [itemInfo]="tableitemInfo" [pageSize]="pageSize" [currentPage]="currentPage" [pages]="pages"
|
|
210
|
+
(pageSizeChange)="invokeOnPageSizeChange($event)" (onGoToPage)="invokeGoToPage($event)">
|
|
211
|
+
</vl-pagination>
|
|
212
|
+
</div>
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { AfterViewInit, Component, EventEmitter, Input, Output, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { RequestService } from '../../services/request.service';
|
|
3
|
+
import { UtilityService } from '../../services/utility.service';
|
|
4
|
+
import { OktaAuthStateService } from '@okta/okta-angular';
|
|
5
|
+
import { NotificationService } from '../../services/notification.service';
|
|
6
|
+
import { CommonModule } from '@angular/common';
|
|
7
|
+
import { FormsModule } from '@angular/forms';
|
|
8
|
+
import { NzTableModule } from 'ng-zorro-antd/table';
|
|
9
|
+
import { NzIconModule } from 'ng-zorro-antd/icon';
|
|
10
|
+
import { ButtonModule } from 'primeng/button';
|
|
11
|
+
import { PaginationComponent } from '../pagination/pagination.component';
|
|
12
|
+
|
|
13
|
+
@Component({
|
|
14
|
+
standalone: true,
|
|
15
|
+
imports: [
|
|
16
|
+
CommonModule,
|
|
17
|
+
FormsModule,
|
|
18
|
+
NzTableModule,
|
|
19
|
+
NzIconModule,
|
|
20
|
+
ButtonModule,
|
|
21
|
+
PaginationComponent
|
|
22
|
+
],
|
|
23
|
+
selector: 'vl-grid',
|
|
24
|
+
templateUrl: './grid.component.html',
|
|
25
|
+
styleUrl: './grid.component.css'
|
|
26
|
+
})
|
|
27
|
+
export class GridComponent implements AfterViewInit {
|
|
28
|
+
isLogined: boolean = false;
|
|
29
|
+
tableitemInfoCopy: any = {};
|
|
30
|
+
@Input() errorMessages: any = {};
|
|
31
|
+
@Input() environment: any;
|
|
32
|
+
@Input() selectedLanguageInfo: any = {};
|
|
33
|
+
@Input() tableitemInfo: any = {};
|
|
34
|
+
@Input() form: any = {};
|
|
35
|
+
@Input() isTableDataLoad: boolean = false;
|
|
36
|
+
@Input() currenTableOptions: any = {};
|
|
37
|
+
@Input() projectSeleted: any = '';
|
|
38
|
+
@Input() pageSize: number = 5;
|
|
39
|
+
@Input() currentPage: number = 0;
|
|
40
|
+
@Input() pages: number[] = [];
|
|
41
|
+
@Input() userInfo: any;
|
|
42
|
+
@Output() onPageChange: EventEmitter<any> = new EventEmitter();
|
|
43
|
+
@Output() onPageSizeChange: EventEmitter<any> = new EventEmitter();
|
|
44
|
+
@Output() onGridScroll: EventEmitter<any> = new EventEmitter();
|
|
45
|
+
@Output() showGridLink: EventEmitter<any> = new EventEmitter();
|
|
46
|
+
@Output() gridButtonClick: EventEmitter<any> = new EventEmitter();
|
|
47
|
+
@Output() gridIncreamentClick: EventEmitter<any> = new EventEmitter();
|
|
48
|
+
@Output() gridDecreamentClick: EventEmitter<any> = new EventEmitter();
|
|
49
|
+
@Output() gridImgClick: EventEmitter<any> = new EventEmitter();
|
|
50
|
+
|
|
51
|
+
constructor(private requestService: RequestService,
|
|
52
|
+
private utilityService: UtilityService,
|
|
53
|
+
private notificationService: NotificationService,
|
|
54
|
+
private oktaAuthService: OktaAuthStateService,) {
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
ngAfterViewInit(): void {
|
|
58
|
+
this.authenticating();
|
|
59
|
+
setTimeout(() => {
|
|
60
|
+
if (this.environment && this.environment?.login && this.environment?.login?.type == "oktaAuth") {
|
|
61
|
+
this.oktaAuthService.authState$.subscribe(
|
|
62
|
+
(result) => {
|
|
63
|
+
if (result.isAuthenticated) {
|
|
64
|
+
this.isLogined = true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}, 500);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
ngOnChanges(changes: SimpleChanges): void {
|
|
73
|
+
setTimeout(() => {
|
|
74
|
+
if (changes['tableitemInfo'] && this.tableitemInfo) {
|
|
75
|
+
console.log('this.tableitemInfo: ', this.tableitemInfo);
|
|
76
|
+
console.log('this.selectedLanguageInfo?: ', this.selectedLanguageInfo);
|
|
77
|
+
this.tableitemInfoCopy = JSON.parse(JSON.stringify(this.tableitemInfo));
|
|
78
|
+
}
|
|
79
|
+
if (changes['SelectedLanguage'] || this.selectedLanguageInfo?.selectedLanguage) {
|
|
80
|
+
if (this.tableitemInfoCopy?.layoutSchema && this.tableitemInfoCopy.layoutSchema?.elements?.length) {
|
|
81
|
+
this.tableitemInfo.propertySchema = JSON.parse(JSON.stringify(this.tableitemInfoCopy.propertySchema));
|
|
82
|
+
this.tableitemInfo.propertySchema = this.translateSchema(this.tableitemInfo.propertySchema, this.selectedLanguageInfo.selectedLanguage);
|
|
83
|
+
if (this.tableitemInfoCopy?.footer) {
|
|
84
|
+
this.tableitemInfo.footer = JSON.parse(JSON.stringify(this.tableitemInfoCopy.footer));
|
|
85
|
+
this.tableitemInfo.footer = this.translateSchema(this.tableitemInfo.footer, this.selectedLanguageInfo.selectedLanguage);
|
|
86
|
+
}
|
|
87
|
+
this.tableitemInfoCopy.layoutSchema.elements.forEach((column: any, index: any) => {
|
|
88
|
+
if (column.label && column.label.caption && this.selectedLanguageInfo.selectedLanguage[column.label.caption]) {
|
|
89
|
+
this.tableitemInfo.layoutSchema.elements[index].label.caption = this.selectedLanguageInfo.selectedLanguage[column.label.caption];
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}, 500);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
translateSchema(schema: any, SelectedLanguage: any): any {
|
|
98
|
+
if (schema && typeof schema === 'object') {
|
|
99
|
+
for (const key of Object.keys(schema)) {
|
|
100
|
+
const val = schema[key];
|
|
101
|
+
if (val && typeof val === 'object') {
|
|
102
|
+
this.translateSchema(val, SelectedLanguage);
|
|
103
|
+
}
|
|
104
|
+
if (val && val.caption !== undefined && typeof val.caption === 'string') {
|
|
105
|
+
const original = val.caption.trim();
|
|
106
|
+
if (original && SelectedLanguage[original]) {
|
|
107
|
+
val.caption = SelectedLanguage[original];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (val && val.value !== undefined && typeof val.value === 'string' && !val.value.includes("{{")) {
|
|
111
|
+
const originalVal = val.value.trim();
|
|
112
|
+
if (originalVal && SelectedLanguage[originalVal]) {
|
|
113
|
+
val.value = SelectedLanguage[originalVal];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return schema;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
getScope(scope: any) {
|
|
123
|
+
let propertyScope = "";
|
|
124
|
+
let start = scope?.indexOf("#/") + 2;
|
|
125
|
+
let end = scope?.indexOf("/", start);
|
|
126
|
+
if (start && end) {
|
|
127
|
+
propertyScope = scope.substring(start, end);
|
|
128
|
+
}
|
|
129
|
+
return propertyScope;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
getStyleWithoutClasses(styleObject: any) {
|
|
133
|
+
if (!styleObject) {
|
|
134
|
+
return { classes: '', style: {} };
|
|
135
|
+
}
|
|
136
|
+
const { classes, ...styleWithoutClasses } = styleObject;
|
|
137
|
+
return { classes: classes && classes.length > 0 ? classes[0] : '', style: styleWithoutClasses };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
onScrollEvent(event: any) {
|
|
141
|
+
this.onGridScroll.emit(event);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
showLinkDetails(option: any, data: any) {
|
|
145
|
+
this.showGridLink.emit({ option: option, data: data });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
invokeGridBtnClick(option: any, propertySchema: any) {
|
|
149
|
+
this.gridButtonClick.emit({ option: option, propertySchema: propertySchema });
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
upsertAction(option: any, data: any) {
|
|
153
|
+
let url = option?.data_url;
|
|
154
|
+
if (url && url?.includes("{{")) {
|
|
155
|
+
const regex = /{{(.*?)}}/g;
|
|
156
|
+
const matches = [...url.matchAll(regex)].map(m => m[1]);
|
|
157
|
+
if (matches && data && data[matches[0]]) {
|
|
158
|
+
option.data_url = url.replace(`{{${matches[0]}}}`, data[matches[0]])
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
let baseUrl = this.environment?.apiUrl + option.data_url;
|
|
162
|
+
this.requestService.dynamicCall(option.method, {}, baseUrl, option?.passToken, this.projectSeleted, this.userInfo).subscribe((res: any) => {
|
|
163
|
+
console.log('res: ', res);
|
|
164
|
+
if (option?.reload) {
|
|
165
|
+
window.location.reload();
|
|
166
|
+
} else if (option.notifcation) {
|
|
167
|
+
if(option.notifcation.success){
|
|
168
|
+
this.notificationService.success(option.notifcation.success);
|
|
169
|
+
let findObj: any = this.findDynamicKeyAndValue(option);
|
|
170
|
+
if(findObj.keyName){
|
|
171
|
+
data[findObj.keyName] = "APPROVED";
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
setActionColumn(option: any, data: any) {
|
|
179
|
+
let showAction: boolean = true;
|
|
180
|
+
let findCondiontionalKey: any = this.findDynamicKeyAndValue(option);
|
|
181
|
+
if (findCondiontionalKey.keyName) {
|
|
182
|
+
showAction = data[findCondiontionalKey.keyName] === findCondiontionalKey.value ? true : false;
|
|
183
|
+
}
|
|
184
|
+
return showAction;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
findDynamicKeyAndValue(object: Record<string, any>) {
|
|
188
|
+
const regex = /^\{\{(.*?)\}\}$/;
|
|
189
|
+
for (const key of Object.keys(object)) {
|
|
190
|
+
const match = key.match(regex);
|
|
191
|
+
if (match) {
|
|
192
|
+
return {
|
|
193
|
+
keyName: match[1].trim(),
|
|
194
|
+
value: object[key]
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
incrementQuantity(index: any, field: any, option: any) {
|
|
202
|
+
this.gridIncreamentClick.emit({ index: index, field: field, option: option });
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
invokeTableImageClick(column: any, data: any) {
|
|
206
|
+
this.gridImgClick.emit({ col: column, data: data });
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
decrementQuantity(index: any, field: any, option: any) {
|
|
210
|
+
this.gridDecreamentClick.emit({ index: index, field: field, option: option });
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
invokeOnPageSizeChange(pageSize: any) {
|
|
214
|
+
this.onPageSizeChange.emit(pageSize);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
invokeGoToPage(page: any) {
|
|
218
|
+
this.onPageChange.emit(page);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
authenticating() {
|
|
222
|
+
this.utilityService.getStorage(`${this.projectSeleted}Logined`).then((logined: any) => {
|
|
223
|
+
if (logined == "true") {
|
|
224
|
+
this.isLogined = true;
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
}
|
|
228
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<header *ngIf="headerItems.length > 0" [ngStyle]="getStyle(headerLayout?.style)">
|
|
2
|
+
|
|
3
|
+
<ng-container *ngFor="let header of headerItems"
|
|
4
|
+
[ngSwitch]="header.scope?.reference ? header.scope?.reference.split('/').pop() : 'default'">
|
|
5
|
+
|
|
6
|
+
<!-- Logo -->
|
|
7
|
+
<ng-container *ngSwitchCase="'logo'">
|
|
8
|
+
<div *ngIf="isVisible(header)" [ngStyle]="getStyle(header?.option?.style)">
|
|
9
|
+
|
|
10
|
+
<img [src]="header.option.src" [alt]="header.alt || 'Logo'"
|
|
11
|
+
[ngStyle]="getStyle(header?.scope?.style)" />
|
|
12
|
+
</div>
|
|
13
|
+
</ng-container>
|
|
14
|
+
|
|
15
|
+
<!-- Search -->
|
|
16
|
+
<ng-container *ngSwitchCase="'searchInput'">
|
|
17
|
+
<div *ngIf="isVisible(header)" [ngStyle]="getStyle(header?.option?.style)">
|
|
18
|
+
|
|
19
|
+
<input #search type="text" [placeholder]="header.option.placeholder"
|
|
20
|
+
(keyup.enter)="invokeSearchedItems(header.option, search)"
|
|
21
|
+
[ngStyle]="getStyle(header?.scope?.style)" />
|
|
22
|
+
|
|
23
|
+
<button *ngIf="header.option.button !== false" type="button"
|
|
24
|
+
(click)="invokeSearchedItems(header.option, search)" [ngStyle]="getStyle(header?.buttonStyle)">
|
|
25
|
+
<ng-container *ngIf="!header.caption; else searchTextContent">
|
|
26
|
+
<i nz-icon [nzType]="header.icon" nzTheme="outline"></i>
|
|
27
|
+
</ng-container>
|
|
28
|
+
|
|
29
|
+
<ng-template #searchTextContent>
|
|
30
|
+
{{ header.caption }}
|
|
31
|
+
</ng-template>
|
|
32
|
+
</button>
|
|
33
|
+
</div>
|
|
34
|
+
</ng-container>
|
|
35
|
+
|
|
36
|
+
<!-- Cart -->
|
|
37
|
+
<ng-container *ngSwitchCase="'cart'">
|
|
38
|
+
<div *ngIf="isVisible(header)" [ngStyle]="getStyle(header?.option?.style)"
|
|
39
|
+
(click)="invokeShowtableContent(header.option)">
|
|
40
|
+
|
|
41
|
+
<span [ngStyle]="getStyle(header?.priceStyle)">
|
|
42
|
+
{{ cartInfo.totalPrice | currency : header.option?.currency ? header.option.currency : 'USD' }}
|
|
43
|
+
</span>
|
|
44
|
+
|
|
45
|
+
<span [ngStyle]="getStyle(header?.quantityStyle)">
|
|
46
|
+
{{ cartInfo.quantity }}
|
|
47
|
+
</span>
|
|
48
|
+
|
|
49
|
+
<i [class]="header.icon" [ngStyle]="getStyle(header?.iconStyle)">
|
|
50
|
+
</i>
|
|
51
|
+
</div>
|
|
52
|
+
</ng-container>
|
|
53
|
+
|
|
54
|
+
<!-- Default Button -->
|
|
55
|
+
<ng-container *ngSwitchCase="'default'">
|
|
56
|
+
<div *ngIf="shouldShowDefaultButton(header)" [ngStyle]="getStyle(header?.option?.style)">
|
|
57
|
+
|
|
58
|
+
<button type="button" (click)="invokeHeaderButtonClick(header.option)"
|
|
59
|
+
[ngStyle]="getStyle(header?.buttonStyle)">
|
|
60
|
+
<ng-container *ngIf="!header.label; else buttonTextContent">
|
|
61
|
+
<i nz-icon [nzType]="header.icon" nzTheme="outline"></i>
|
|
62
|
+
</ng-container>
|
|
63
|
+
|
|
64
|
+
<ng-template #buttonTextContent>
|
|
65
|
+
{{ header.label }}
|
|
66
|
+
</ng-template>
|
|
67
|
+
</button>
|
|
68
|
+
</div>
|
|
69
|
+
</ng-container>
|
|
70
|
+
|
|
71
|
+
</ng-container>
|
|
72
|
+
</header>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import { OktaAuthStateService } from '@okta/okta-angular';
|
|
3
|
+
import { Platform } from '@angular/cdk/platform';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import { NzIconModule } from 'ng-zorro-antd/icon';
|
|
6
|
+
import { RequestService } from '../../services/request.service';
|
|
7
|
+
import { UtilityService } from '../../services/utility.service';
|
|
8
|
+
|
|
9
|
+
@Component({
|
|
10
|
+
standalone: true,
|
|
11
|
+
imports: [
|
|
12
|
+
CommonModule,
|
|
13
|
+
NzIconModule
|
|
14
|
+
],
|
|
15
|
+
selector: 'vl-header-menu',
|
|
16
|
+
templateUrl: './header-menu.component.html',
|
|
17
|
+
styleUrl: './header-menu.component.css'
|
|
18
|
+
})
|
|
19
|
+
export class HeaderMenuComponent implements AfterViewInit {
|
|
20
|
+
isLogined: boolean = false;
|
|
21
|
+
|
|
22
|
+
@Input() headerItems: any[] = [];
|
|
23
|
+
@Input() headerLayout: any = {};
|
|
24
|
+
@Input() environment: any;
|
|
25
|
+
@Input() projectSeleted: any;
|
|
26
|
+
@Input() cartInfo: any = {
|
|
27
|
+
items: [],
|
|
28
|
+
totalPrice: 0,
|
|
29
|
+
quantity: 0
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
@Output() buttonClick: EventEmitter<any> = new EventEmitter();
|
|
33
|
+
@Output() showTableContent: EventEmitter<any> = new EventEmitter();
|
|
34
|
+
@Output() searchItems: EventEmitter<any> = new EventEmitter();
|
|
35
|
+
|
|
36
|
+
constructor(
|
|
37
|
+
private oktaAuthService: OktaAuthStateService,
|
|
38
|
+
private requestService: RequestService,
|
|
39
|
+
private utilityService: UtilityService,
|
|
40
|
+
private platform: Platform
|
|
41
|
+
) {}
|
|
42
|
+
|
|
43
|
+
ngAfterViewInit(): void {
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
if (this.environment && this.environment?.login && this.environment?.login?.type == "oktaAuth") {
|
|
46
|
+
if (this.platform.ANDROID || this.platform.IOS) {
|
|
47
|
+
this.utilityService.getLocalStorage(`loginedUser`).then((logined: any) => {
|
|
48
|
+
if (logined && logined.token) {
|
|
49
|
+
this.requestService.getLoginUser(logined?.token).subscribe(() => {
|
|
50
|
+
this.isLogined = true;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this.oktaAuthService.authState$.subscribe((result) => {
|
|
57
|
+
if (result.isAuthenticated) {
|
|
58
|
+
this.isLogined = true;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}, 500);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
getStyle(styleObject: any): Record<string, any> {
|
|
66
|
+
if (!styleObject || typeof styleObject !== 'object') {
|
|
67
|
+
return {};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const { classes, ...styleWithoutClasses } = styleObject;
|
|
71
|
+
return styleWithoutClasses;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
isVisible(header: any): boolean {
|
|
75
|
+
return header?.option?.visible !== false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
shouldShowDefaultButton(header: any): boolean {
|
|
79
|
+
if (!this.isVisible(header)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (header?.option?.islogin === true) {
|
|
84
|
+
return this.isLogined;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (header?.option?.islogin === false) {
|
|
88
|
+
return !this.isLogined;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
invokeSearchedItems(option: any, search: any) {
|
|
95
|
+
this.searchItems.emit({ option: option, search: search });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
invokeHeaderButtonClick(option: any) {
|
|
99
|
+
this.buttonClick.emit(option);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
invokeShowtableContent(option: any) {
|
|
103
|
+
this.showTableContent.emit(option);
|
|
104
|
+
}
|
|
105
|
+
}
|