@unopsitg/ux 21.0.5 → 21.0.19
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/assets/_card.scss +89 -2
- package/assets/_config.scss +3 -3
- package/assets/_content.scss +39 -5
- package/assets/_footer.scss +59 -3
- package/assets/_main.scss +6 -8
- package/assets/_responsive.scss +15 -3
- package/assets/_sass_variables.scss +8 -2
- package/assets/_search.scss +3 -3
- package/assets/_tabs.scss +44 -0
- package/assets/_tags.scss +1 -1
- package/assets/_topbar.scss +45 -17
- package/assets/_utils.scss +0 -12
- package/assets/layout.scss +1 -0
- package/assets/sidebar/_sidebar_compact.scss +1 -6
- package/assets/sidebar/_sidebar_horizontal.scss +97 -76
- package/assets/sidebar/_sidebar_slim.scss +1 -6
- package/assets/sidebar/_sidebar_theme_core.scss +19 -19
- package/assets/sidebar/themes/_dark.scss +5 -5
- package/assets/sidebar/themes/_light.scss +2 -2
- package/assets/sidebar/themes/_primary.scss +8 -8
- package/assets/tailwind.css +47 -18
- package/assets/variables/_common.scss +1 -0
- package/assets/variables/_light.scss +2 -2
- package/fesm2022/unopsitg-ux.mjs +1235 -292
- package/fesm2022/unopsitg-ux.mjs.map +1 -1
- package/package.json +1 -1
- package/types/unopsitg-ux.d.ts +205 -200
- package/assets/opp/AppLogo/AppLogo-onDark_V.svg +0 -55
- package/assets/opp/AppLogo/AppLogo-onLight_V.svg +0 -55
- package/assets/opp/AppLogo-dark-vertical.svg +0 -55
- package/assets/opp/drive-download-20260421T141232Z-3-001.zip +0 -0
- package/assets/opp/favicon/favicon.svg +0 -17
- package/assets/opp/logo-dark-horizontal.svg +0 -55
- package/assets/opp/logo-light-horizontal.svg +0 -55
package/fesm2022/unopsitg-ux.mjs
CHANGED
|
@@ -3,23 +3,23 @@ import SoftBase from '@primeuix/themes/aura';
|
|
|
3
3
|
import CrispBase from '@primeuix/themes/lara';
|
|
4
4
|
import ContrastBase from '@primeuix/themes/nora';
|
|
5
5
|
import * as i0 from '@angular/core';
|
|
6
|
-
import { InjectionToken, signal, inject, computed, effect, Injectable, Component, PLATFORM_ID, model, booleanAttribute, Input, input, HostListener, ViewChild, ElementRef,
|
|
6
|
+
import { InjectionToken, signal, inject, computed, effect, Injectable, Component, PLATFORM_ID, model, booleanAttribute, Input, input, ChangeDetectionStrategy, HostListener, ViewChild, ElementRef, output, DestroyRef, Directive, ContentChildren } from '@angular/core';
|
|
7
7
|
import * as i1 from '@angular/router';
|
|
8
8
|
import { Router, NavigationEnd, RouterModule } from '@angular/router';
|
|
9
9
|
import * as i1$1 from '@angular/common';
|
|
10
|
-
import { CommonModule, isPlatformBrowser, NgClass } from '@angular/common';
|
|
10
|
+
import { CommonModule, isPlatformBrowser, NgTemplateOutlet, NgClass } from '@angular/common';
|
|
11
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
11
12
|
import { BehaviorSubject, filter, Subject, takeUntil } from 'rxjs';
|
|
12
|
-
import * as
|
|
13
|
+
import * as i1$2 from '@angular/forms';
|
|
13
14
|
import { FormsModule } from '@angular/forms';
|
|
14
15
|
import { PrimeNG } from 'primeng/config';
|
|
15
16
|
import * as i4 from 'primeng/drawer';
|
|
16
17
|
import { DrawerModule } from 'primeng/drawer';
|
|
17
|
-
import * as i5
|
|
18
|
+
import * as i5 from 'primeng/radiobutton';
|
|
18
19
|
import { RadioButtonModule } from 'primeng/radiobutton';
|
|
19
20
|
import * as i3 from 'primeng/selectbutton';
|
|
20
21
|
import { SelectButtonModule } from 'primeng/selectbutton';
|
|
21
|
-
import
|
|
22
|
-
import * as i6 from 'primeng/button';
|
|
22
|
+
import * as i2$1 from 'primeng/button';
|
|
23
23
|
import { ButtonModule } from 'primeng/button';
|
|
24
24
|
import * as i2 from 'primeng/divider';
|
|
25
25
|
import { DividerModule } from 'primeng/divider';
|
|
@@ -29,7 +29,7 @@ import * as i3$1 from 'primeng/select';
|
|
|
29
29
|
import { SelectModule } from 'primeng/select';
|
|
30
30
|
import * as i3$2 from 'primeng/autofocus';
|
|
31
31
|
import { AutoFocusModule } from 'primeng/autofocus';
|
|
32
|
-
import * as i1$
|
|
32
|
+
import * as i1$3 from 'primeng/dialog';
|
|
33
33
|
import { DialogModule } from 'primeng/dialog';
|
|
34
34
|
import * as i4$2 from 'primeng/ripple';
|
|
35
35
|
import { RippleModule } from 'primeng/ripple';
|
|
@@ -39,18 +39,34 @@ import * as i10 from 'primeng/avatar';
|
|
|
39
39
|
import { AvatarModule } from 'primeng/avatar';
|
|
40
40
|
import * as i8 from 'primeng/badge';
|
|
41
41
|
import { BadgeModule } from 'primeng/badge';
|
|
42
|
-
import * as i5$
|
|
42
|
+
import * as i5$1 from 'primeng/iconfield';
|
|
43
43
|
import { IconFieldModule } from 'primeng/iconfield';
|
|
44
|
-
import * as i6
|
|
44
|
+
import * as i6 from 'primeng/inputicon';
|
|
45
45
|
import { InputIconModule } from 'primeng/inputicon';
|
|
46
46
|
import * as i9 from 'primeng/overlaybadge';
|
|
47
47
|
import { OverlayBadgeModule } from 'primeng/overlaybadge';
|
|
48
48
|
import * as i3$4 from 'primeng/styleclass';
|
|
49
49
|
import { StyleClassModule } from 'primeng/styleclass';
|
|
50
|
-
import * as i2$
|
|
50
|
+
import * as i2$2 from 'primeng/paginator';
|
|
51
51
|
import { PaginatorModule } from 'primeng/paginator';
|
|
52
|
-
import * as
|
|
52
|
+
import * as i4$3 from 'primeng/tabs';
|
|
53
53
|
import { TabsModule } from 'primeng/tabs';
|
|
54
|
+
import * as i3$5 from 'primeng/fileupload';
|
|
55
|
+
import { FileUploadModule } from 'primeng/fileupload';
|
|
56
|
+
import * as i7 from 'primeng/menu';
|
|
57
|
+
import { MenuModule } from 'primeng/menu';
|
|
58
|
+
import * as i10$1 from 'primeng/panel';
|
|
59
|
+
import { PanelModule } from 'primeng/panel';
|
|
60
|
+
import * as i8$1 from 'primeng/table';
|
|
61
|
+
import { TableModule } from 'primeng/table';
|
|
62
|
+
import * as i9$1 from 'primeng/tag';
|
|
63
|
+
import { TagModule } from 'primeng/tag';
|
|
64
|
+
import * as i8$2 from 'primeng/autocomplete';
|
|
65
|
+
import { AutoCompleteModule } from 'primeng/autocomplete';
|
|
66
|
+
import * as i7$1 from 'primeng/datepicker';
|
|
67
|
+
import { DatePickerModule } from 'primeng/datepicker';
|
|
68
|
+
import * as i5$2 from 'primeng/textarea';
|
|
69
|
+
import { TextareaModule } from 'primeng/textarea';
|
|
54
70
|
|
|
55
71
|
/**
|
|
56
72
|
* Brand theme presets built on top of PrimeUIX base presets.
|
|
@@ -61,8 +77,8 @@ import { TabsModule } from 'primeng/tabs';
|
|
|
61
77
|
* Contrast <- @primeuix/themes/nora
|
|
62
78
|
*/
|
|
63
79
|
const brandPrimitives = {
|
|
64
|
-
deepsea: { 50: '#
|
|
65
|
-
gray: { 50: '#
|
|
80
|
+
deepsea: { 50: '#c3c7cb', 100: '#9ea5ac', 200: '#7a838d', 300: '#56626d', 400: '#31404e', 500: '#0d1e2f', 600: '#0b1a28', 700: '#091521', 800: '#07111a', 900: '#050c13', 950: '#03080c' },
|
|
81
|
+
gray: { 50: '#f8fafc', 100: '#f1f5f9', 200: '#e2e8f0', 300: '#cbd5e1', 400: '#94a3b8', 500: '#64748b', 600: '#475569', 700: '#334155', 800: '#1e293b', 900: '#0f172a', 950: '#020617' },
|
|
66
82
|
red: { 50: '#f6cac6', 100: '#f0a9a4', 200: '#eb8982', 300: '#e56960', 400: '#e0493e', 500: '#da291c', 600: '#b92318', 700: '#991d14', 800: '#78170f', 900: '#57100b', 950: '#370a07' },
|
|
67
83
|
orange: { 50: '#f9d6c3', 100: '#f6be9f', 200: '#f2a57a', 300: '#ef8d56', 400: '#eb7432', 500: '#e85c0e', 600: '#c54e0c', 700: '#a2400a', 800: '#803308', 900: '#5d2506', 950: '#3a1704' },
|
|
68
84
|
yellow: { 50: '#fff0c5', 100: '#ffe7a1', 200: '#ffdd7e', 300: '#ffd45b', 400: '#ffcb38', 500: '#ffc215', 600: '#d9a512', 700: '#b3880f', 800: '#8c6b0c', 900: '#664e08', 950: '#403105' },
|
|
@@ -76,7 +92,8 @@ const brandPrimitives = {
|
|
|
76
92
|
blue: { 50: '#DEEFFF', 100: '#C9E8FF', 150: '#99D3ED', 200: '#73c3e6', 300: '#4db3df', 400: '#26a2d8', 500: '#0092d1', 600: '#007cb2', 700: '#006692', 800: '#005073', 900: '#003a54', 950: '#002534' },
|
|
77
93
|
darkblue: { 50: '#D0EEFF', 100: '#B7E2F9', 200: '#73abc7', 300: '#4d94b8', 400: '#267da9', 500: '#00669a', 600: '#005783', 700: '#00476c', 800: '#003855', 900: '#00293e', 950: '#001a27' },
|
|
78
94
|
midnight: { 50: '#bfd2dd', 100: '#99b6c8', 200: '#739bb4', 300: '#4d809f', 400: '#26648b', 500: '#004976', 600: '#003e64', 700: '#003353', 800: '#002841', 850: '#001E31', 900: '#001d2f', 950: '#00121e' },
|
|
79
|
-
cherry: { 50: '#e6c7d9', 100: '#d6a5c2', 200: '#c783ab', 300: '#b86294', 400: '#a8407d', 500: '#991e66', 600: '#821a57', 700: '#6b1547', 800: '#541138', 900: '#3d0c29', 950: '#26081a' }
|
|
95
|
+
cherry: { 50: '#e6c7d9', 100: '#d6a5c2', 200: '#c783ab', 300: '#b86294', 400: '#a8407d', 500: '#991e66', 600: '#821a57', 700: '#6b1547', 800: '#541138', 900: '#3d0c29', 950: '#26081a' },
|
|
96
|
+
ai: { 50: '#f0edff', 100: '#e4deff', 200: '#cdc2ff', 300: '#b0a0ff', 400: '#9378ff', 500: '#7c5cfc', 600: '#6a44f0', 700: '#5835d4', 800: '#482dac', 900: '#3b278a', 950: '#24185e' }
|
|
80
97
|
};
|
|
81
98
|
const brandOverrides = {
|
|
82
99
|
primitive: {
|
|
@@ -115,17 +132,17 @@ const brandOverrides = {
|
|
|
115
132
|
light: {
|
|
116
133
|
surface: {
|
|
117
134
|
0: '#ffffff',
|
|
118
|
-
50: '{
|
|
119
|
-
100: '{
|
|
120
|
-
200: '{
|
|
121
|
-
300: '{
|
|
122
|
-
400: '{
|
|
123
|
-
500: '{
|
|
124
|
-
600: '{
|
|
125
|
-
700: '{
|
|
126
|
-
800: '{
|
|
127
|
-
900: '{
|
|
128
|
-
950: '{
|
|
135
|
+
50: '{gray.50}',
|
|
136
|
+
100: '{gray.100}',
|
|
137
|
+
200: '{gray.200}',
|
|
138
|
+
300: '{gray.300}',
|
|
139
|
+
400: '{gray.400}',
|
|
140
|
+
500: '{gray.500}',
|
|
141
|
+
600: '{gray.600}',
|
|
142
|
+
700: '{gray.700}',
|
|
143
|
+
800: '{gray.800}',
|
|
144
|
+
900: '{gray.900}',
|
|
145
|
+
950: '{gray.950}'
|
|
129
146
|
}
|
|
130
147
|
},
|
|
131
148
|
dark: {
|
|
@@ -135,8 +152,8 @@ const brandOverrides = {
|
|
|
135
152
|
100: '{darkblue.100}',
|
|
136
153
|
200: '{darkblue.200}',
|
|
137
154
|
300: '{darkblue.300}',
|
|
138
|
-
400: '{
|
|
139
|
-
500: '{
|
|
155
|
+
400: '{blue.400}',
|
|
156
|
+
500: '{blue.500}',
|
|
140
157
|
600: '{darkblue.600}',
|
|
141
158
|
700: '{darkblue.700}',
|
|
142
159
|
800: '{darkblue.800}',
|
|
@@ -147,6 +164,12 @@ const brandOverrides = {
|
|
|
147
164
|
}
|
|
148
165
|
},
|
|
149
166
|
components: {
|
|
167
|
+
accordion: {
|
|
168
|
+
root: { transitionDuration: '{transition.duration}' },
|
|
169
|
+
panel: { borderWidth: '0' },
|
|
170
|
+
header: { background: 'transparent', padding: '0 0 0 0' },
|
|
171
|
+
content: { background: 'transparent' }
|
|
172
|
+
},
|
|
150
173
|
button: {
|
|
151
174
|
colorScheme: {
|
|
152
175
|
light: {
|
|
@@ -175,34 +198,36 @@ const brandOverrides = {
|
|
|
175
198
|
}
|
|
176
199
|
}
|
|
177
200
|
},
|
|
201
|
+
// Tab active/hover backgrounds are set in _tabs.scss via sidebar
|
|
202
|
+
// `--d-menuitem-*` tokens (not expressible in the preset). Only structural
|
|
203
|
+
// properties that _tabs.scss does NOT override belong here.
|
|
178
204
|
tabs: {
|
|
179
205
|
tablist: {
|
|
180
|
-
background: 'transparent'
|
|
206
|
+
background: 'transparent',
|
|
207
|
+
borderWidth: '0 0 1px 0'
|
|
181
208
|
},
|
|
182
209
|
tab: {
|
|
183
210
|
background: 'transparent',
|
|
184
|
-
hoverBackground: '{primary.50}',
|
|
185
|
-
hoverColor: '{primary.700}',
|
|
186
|
-
activeBackground: '{primary.100}',
|
|
187
|
-
activeColor: '{primary.900}',
|
|
188
211
|
borderColor: 'transparent',
|
|
189
|
-
activeBorderColor: '
|
|
190
|
-
|
|
212
|
+
activeBorderColor: 'transparent',
|
|
213
|
+
borderWidth: '0',
|
|
214
|
+
padding: '0.5rem 1rem',
|
|
215
|
+
margin: '0 0 0.5rem 0'
|
|
191
216
|
},
|
|
192
217
|
tabpanel: {
|
|
193
218
|
background: 'transparent',
|
|
194
219
|
padding: '0'
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
dataview: {
|
|
223
|
+
header: {
|
|
224
|
+
background: 'transparent',
|
|
225
|
+
borderWidth: '0',
|
|
226
|
+
padding: '0'
|
|
195
227
|
},
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
hoverBackground: '{primary.900}',
|
|
200
|
-
hoverColor: '{primary.200}',
|
|
201
|
-
activeBackground: '{surface.800}',
|
|
202
|
-
activeColor: '{primary.200}',
|
|
203
|
-
activeBorderColor: '{primary.400}'
|
|
204
|
-
}
|
|
205
|
-
}
|
|
228
|
+
content: {
|
|
229
|
+
background: 'transparent',
|
|
230
|
+
padding: '0'
|
|
206
231
|
}
|
|
207
232
|
},
|
|
208
233
|
paginator: {
|
|
@@ -215,6 +240,64 @@ const brandOverrides = {
|
|
|
215
240
|
background: 'transparent'
|
|
216
241
|
}
|
|
217
242
|
},
|
|
243
|
+
panel: {
|
|
244
|
+
root: {
|
|
245
|
+
background: 'transparent',
|
|
246
|
+
borderColor: 'transparent',
|
|
247
|
+
borderRadius: '0'
|
|
248
|
+
},
|
|
249
|
+
header: {
|
|
250
|
+
background: 'transparent',
|
|
251
|
+
padding: '0',
|
|
252
|
+
borderWidth: '0'
|
|
253
|
+
},
|
|
254
|
+
toggleableHeader: {
|
|
255
|
+
padding: '0'
|
|
256
|
+
},
|
|
257
|
+
title: {
|
|
258
|
+
fontWeight: '700'
|
|
259
|
+
},
|
|
260
|
+
content: {
|
|
261
|
+
padding: '0'
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
card: {
|
|
265
|
+
root: {
|
|
266
|
+
shadow: 'none',
|
|
267
|
+
borderRadius: '{border.radius.xl}'
|
|
268
|
+
},
|
|
269
|
+
body: {
|
|
270
|
+
padding: '1.25rem',
|
|
271
|
+
gap: '1rem'
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
avatar: {
|
|
275
|
+
root: {
|
|
276
|
+
borderRadius: '9999px',
|
|
277
|
+
fontSize: '0.875rem'
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
drawer: {
|
|
281
|
+
content: { padding: '1.25rem' }
|
|
282
|
+
},
|
|
283
|
+
inputtext: {
|
|
284
|
+
root: {
|
|
285
|
+
borderRadius: '{border.radius.xl}',
|
|
286
|
+
paddingY: '0.5rem'
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
divider: {
|
|
290
|
+
horizontal: {
|
|
291
|
+
margin: '0',
|
|
292
|
+
padding: '0',
|
|
293
|
+
content: { padding: '0 0.5rem' }
|
|
294
|
+
},
|
|
295
|
+
vertical: {
|
|
296
|
+
margin: '0',
|
|
297
|
+
padding: '0',
|
|
298
|
+
content: { padding: '0.5rem 0' }
|
|
299
|
+
}
|
|
300
|
+
},
|
|
218
301
|
tag: {
|
|
219
302
|
root: {
|
|
220
303
|
padding: '0.25rem 0.5rem',
|
|
@@ -224,22 +307,47 @@ const brandOverrides = {
|
|
|
224
307
|
light: {
|
|
225
308
|
secondary: { color: '{surface.800}' },
|
|
226
309
|
success: { color: '{green.800}' },
|
|
227
|
-
active: { color: '{green.800}' },
|
|
228
|
-
inactive: { color: '{gray.800}' },
|
|
229
310
|
info: { color: '{blue.800}' },
|
|
230
311
|
warn: { color: '{orange.800}' },
|
|
231
|
-
|
|
312
|
+
danger: { color: '{red.800}' }
|
|
232
313
|
},
|
|
233
314
|
dark: {
|
|
234
315
|
secondary: { color: '{surface.100}' },
|
|
235
316
|
success: { color: '{green.100}' },
|
|
236
|
-
active: { color: '{green.100}' },
|
|
237
317
|
info: { color: '{blue.100}' },
|
|
238
|
-
inactive: { color: '{gray.100}' },
|
|
239
318
|
warn: { color: '{orange.100}' },
|
|
240
|
-
|
|
319
|
+
danger: { color: '{red.100}' }
|
|
241
320
|
}
|
|
242
321
|
}
|
|
322
|
+
},
|
|
323
|
+
toolbar: {
|
|
324
|
+
root: {
|
|
325
|
+
background: 'transparent',
|
|
326
|
+
borderColor: 'transparent',
|
|
327
|
+
borderRadius: '0',
|
|
328
|
+
padding: '0',
|
|
329
|
+
gap: '0.5rem'
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
progressbar: {
|
|
333
|
+
root: {
|
|
334
|
+
borderRadius: '{border.radius.lg}',
|
|
335
|
+
height: '0.75rem'
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
message: {
|
|
339
|
+
root: {
|
|
340
|
+
borderRadius: '{border.radius.lg}',
|
|
341
|
+
borderWidth: '0 0 0 4px'
|
|
342
|
+
},
|
|
343
|
+
content: {
|
|
344
|
+
padding: '0.75rem 1rem',
|
|
345
|
+
gap: '0.5rem'
|
|
346
|
+
},
|
|
347
|
+
text: {
|
|
348
|
+
fontSize: '0.875rem',
|
|
349
|
+
fontWeight: '500'
|
|
350
|
+
}
|
|
243
351
|
}
|
|
244
352
|
}
|
|
245
353
|
};
|
|
@@ -429,6 +537,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
429
537
|
}]
|
|
430
538
|
}], ctorParameters: () => [] });
|
|
431
539
|
|
|
540
|
+
class FooterService {
|
|
541
|
+
content = signal(null, ...(ngDevMode ? [{ debugName: "content" }] : []));
|
|
542
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FooterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
543
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FooterService, providedIn: 'root' });
|
|
544
|
+
}
|
|
545
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FooterService, decorators: [{
|
|
546
|
+
type: Injectable,
|
|
547
|
+
args: [{ providedIn: 'root' }]
|
|
548
|
+
}] });
|
|
549
|
+
|
|
432
550
|
class AppBreadcrumb {
|
|
433
551
|
router;
|
|
434
552
|
_breadcrumbs$ = new BehaviorSubject([]);
|
|
@@ -501,11 +619,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
501
619
|
class AppConfigurator {
|
|
502
620
|
simple = false;
|
|
503
621
|
location = 'app';
|
|
504
|
-
router = inject(Router);
|
|
505
622
|
config = inject(PrimeNG);
|
|
506
623
|
layoutService = inject(LayoutService);
|
|
507
624
|
platformId = inject(PLATFORM_ID);
|
|
508
|
-
primeng = inject(PrimeNG);
|
|
509
625
|
presetKeys = Object.keys(brandPresets);
|
|
510
626
|
themeOptions = [
|
|
511
627
|
{ name: 'Light', value: false },
|
|
@@ -533,42 +649,10 @@ class AppConfigurator {
|
|
|
533
649
|
];
|
|
534
650
|
}
|
|
535
651
|
}
|
|
536
|
-
surfaces = [
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
0: '#ffffff',
|
|
541
|
-
50: '#e5e6e6',
|
|
542
|
-
100: '#d5d6d7',
|
|
543
|
-
200: '#c6c7c8',
|
|
544
|
-
300: '#b6b8b9',
|
|
545
|
-
400: '#a7a8aa',
|
|
546
|
-
500: '#97999b',
|
|
547
|
-
600: '#808284',
|
|
548
|
-
700: '#6a6b6d',
|
|
549
|
-
800: '#535455',
|
|
550
|
-
900: '#3c3d3e',
|
|
551
|
-
950: '#262627'
|
|
552
|
-
}
|
|
553
|
-
},
|
|
554
|
-
{
|
|
555
|
-
name: 'darkblue',
|
|
556
|
-
palette: {
|
|
557
|
-
0: '#ffffff',
|
|
558
|
-
50: '#D0EEFF',
|
|
559
|
-
100: '#B7E2F9',
|
|
560
|
-
200: '#73abc7',
|
|
561
|
-
300: '#73abc7',
|
|
562
|
-
400: '#4d94b8',
|
|
563
|
-
500: '#267da9',
|
|
564
|
-
600: '#00669a',
|
|
565
|
-
700: '#005783',
|
|
566
|
-
800: '#00476c',
|
|
567
|
-
900: '#00293e',
|
|
568
|
-
950: '#001a27'
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
];
|
|
652
|
+
surfaces = ['gray', 'darkblue'].map(name => ({
|
|
653
|
+
name,
|
|
654
|
+
palette: { 0: '#ffffff', ...brandPrimitives[name] }
|
|
655
|
+
}));
|
|
572
656
|
selectedPrimaryColor = computed(() => {
|
|
573
657
|
return this.layoutService.layoutConfig().primary;
|
|
574
658
|
}, ...(ngDevMode ? [{ debugName: "selectedPrimaryColor" }] : []));
|
|
@@ -834,12 +918,12 @@ class AppConfigurator {
|
|
|
834
918
|
</div>
|
|
835
919
|
<div *ngIf="!simple && location === 'app'" class="flex flex-col gap-2">
|
|
836
920
|
<span class="text-lg text-muted-color font-semibold">Card Style</span>
|
|
837
|
-
<p-selectbutton [ngModel]="cardStyle()" (ngModelChange)="onCardStyleChange($event)" [options]="cardStyleOptions" optionLabel="name" optionValue="value" [allowEmpty]="false"
|
|
921
|
+
<p-selectbutton [ngModel]="cardStyle()" (ngModelChange)="onCardStyleChange($event)" [options]="cardStyleOptions" optionLabel="name" optionValue="value" [allowEmpty]="false" />
|
|
838
922
|
</div>
|
|
839
923
|
|
|
840
924
|
<div *ngIf="!simple && location === 'app'" class="flex flex-col gap-2">
|
|
841
925
|
<span class="text-lg text-muted-color font-semibold">Menu Theme</span>
|
|
842
|
-
<p-selectbutton [ngModel]="menuTheme()" (ngModelChange)="onMenuThemeChange($event)" [options]="menuThemeOptions" optionLabel="name" optionValue="value" [allowEmpty]="false"
|
|
926
|
+
<p-selectbutton [ngModel]="menuTheme()" (ngModelChange)="onMenuThemeChange($event)" [options]="menuThemeOptions" optionLabel="name" optionValue="value" [allowEmpty]="false" />
|
|
843
927
|
</div>
|
|
844
928
|
|
|
845
929
|
<div *ngIf="!simple && location === 'app'">
|
|
@@ -857,30 +941,16 @@ class AppConfigurator {
|
|
|
857
941
|
</div>
|
|
858
942
|
</div>
|
|
859
943
|
<div class="flex">
|
|
860
|
-
<div class="flex items-center gap-2 w-6/12">
|
|
861
|
-
<p-radiobutton name="menuMode" value="overlay" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('overlay')" inputId="overlay"></p-radiobutton>
|
|
862
|
-
<label for="overlay">Overlay</label>
|
|
863
|
-
</div>
|
|
864
944
|
<div class="flex items-center gap-2 w-6/12">
|
|
865
945
|
<p-radiobutton name="menuMode" value="slim" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('slim')" inputId="slim"></p-radiobutton>
|
|
866
946
|
<label for="slim">Slim</label>
|
|
867
947
|
</div>
|
|
868
|
-
</div>
|
|
869
|
-
<div class="flex">
|
|
870
948
|
<div class="flex items-center gap-2 w-6/12">
|
|
871
949
|
<p-radiobutton name="menuMode" value="compact" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('compact')" inputId="compact"></p-radiobutton>
|
|
872
950
|
<label for="compact">Compact</label>
|
|
873
951
|
</div>
|
|
874
|
-
<div class="flex items-center gap-2 w-6/12">
|
|
875
|
-
<p-radiobutton name="menuMode" value="reveal" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('reveal')" inputId="reveal"></p-radiobutton>
|
|
876
|
-
<label for="reveal">Reveal</label>
|
|
877
|
-
</div>
|
|
878
952
|
</div>
|
|
879
953
|
<div class="flex">
|
|
880
|
-
<div class="flex items-center gap-2 w-6/12">
|
|
881
|
-
<p-radiobutton name="menuMode" value="drawer" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('drawer')" inputId="drawer"></p-radiobutton>
|
|
882
|
-
<label for="drawer">Drawer</label>
|
|
883
|
-
</div>
|
|
884
954
|
<div class="flex items-center gap-2 w-6/12">
|
|
885
955
|
<p-radiobutton name="menuMode" value="horizontal" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('horizontal')" inputId="horizontal"></p-radiobutton>
|
|
886
956
|
<label for="horizontal">Horizontal</label>
|
|
@@ -891,13 +961,13 @@ class AppConfigurator {
|
|
|
891
961
|
</div>
|
|
892
962
|
</div>
|
|
893
963
|
</p-drawer>
|
|
894
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type:
|
|
964
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SelectButtonModule }, { kind: "component", type: i3.SelectButton, selector: "p-selectButton, p-selectbutton, p-select-button", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "styleClass", "ariaLabelledBy", "dataKey", "autofocus", "size", "fluid"], outputs: ["onOptionClick", "onChange"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i4.Drawer, selector: "p-drawer", inputs: ["appendTo", "motionOptions", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i5.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "styleClass", "autofocus", "binary", "variant", "size"], outputs: ["onClick", "onFocus", "onBlur"] }] });
|
|
895
965
|
}
|
|
896
966
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppConfigurator, decorators: [{
|
|
897
967
|
type: Component,
|
|
898
968
|
args: [{
|
|
899
969
|
selector: 'app-configurator',
|
|
900
|
-
imports: [CommonModule, FormsModule, SelectButtonModule, DrawerModule,
|
|
970
|
+
imports: [CommonModule, FormsModule, SelectButtonModule, DrawerModule, RadioButtonModule],
|
|
901
971
|
template: `
|
|
902
972
|
<p-drawer [(visible)]="configSidebarVisible" position="right" [transitionOptions]="'.3s cubic-bezier(0, 0, 0.2, 1)'" styleClass="layout-config-sidebar w-80" header="Settings" appendTo="body">
|
|
903
973
|
<div class="flex flex-col gap-6">
|
|
@@ -952,12 +1022,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
952
1022
|
</div>
|
|
953
1023
|
<div *ngIf="!simple && location === 'app'" class="flex flex-col gap-2">
|
|
954
1024
|
<span class="text-lg text-muted-color font-semibold">Card Style</span>
|
|
955
|
-
<p-selectbutton [ngModel]="cardStyle()" (ngModelChange)="onCardStyleChange($event)" [options]="cardStyleOptions" optionLabel="name" optionValue="value" [allowEmpty]="false"
|
|
1025
|
+
<p-selectbutton [ngModel]="cardStyle()" (ngModelChange)="onCardStyleChange($event)" [options]="cardStyleOptions" optionLabel="name" optionValue="value" [allowEmpty]="false" />
|
|
956
1026
|
</div>
|
|
957
1027
|
|
|
958
1028
|
<div *ngIf="!simple && location === 'app'" class="flex flex-col gap-2">
|
|
959
1029
|
<span class="text-lg text-muted-color font-semibold">Menu Theme</span>
|
|
960
|
-
<p-selectbutton [ngModel]="menuTheme()" (ngModelChange)="onMenuThemeChange($event)" [options]="menuThemeOptions" optionLabel="name" optionValue="value" [allowEmpty]="false"
|
|
1030
|
+
<p-selectbutton [ngModel]="menuTheme()" (ngModelChange)="onMenuThemeChange($event)" [options]="menuThemeOptions" optionLabel="name" optionValue="value" [allowEmpty]="false" />
|
|
961
1031
|
</div>
|
|
962
1032
|
|
|
963
1033
|
<div *ngIf="!simple && location === 'app'">
|
|
@@ -975,30 +1045,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
975
1045
|
</div>
|
|
976
1046
|
</div>
|
|
977
1047
|
<div class="flex">
|
|
978
|
-
<div class="flex items-center gap-2 w-6/12">
|
|
979
|
-
<p-radiobutton name="menuMode" value="overlay" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('overlay')" inputId="overlay"></p-radiobutton>
|
|
980
|
-
<label for="overlay">Overlay</label>
|
|
981
|
-
</div>
|
|
982
1048
|
<div class="flex items-center gap-2 w-6/12">
|
|
983
1049
|
<p-radiobutton name="menuMode" value="slim" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('slim')" inputId="slim"></p-radiobutton>
|
|
984
1050
|
<label for="slim">Slim</label>
|
|
985
1051
|
</div>
|
|
986
|
-
</div>
|
|
987
|
-
<div class="flex">
|
|
988
1052
|
<div class="flex items-center gap-2 w-6/12">
|
|
989
1053
|
<p-radiobutton name="menuMode" value="compact" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('compact')" inputId="compact"></p-radiobutton>
|
|
990
1054
|
<label for="compact">Compact</label>
|
|
991
1055
|
</div>
|
|
992
|
-
<div class="flex items-center gap-2 w-6/12">
|
|
993
|
-
<p-radiobutton name="menuMode" value="reveal" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('reveal')" inputId="reveal"></p-radiobutton>
|
|
994
|
-
<label for="reveal">Reveal</label>
|
|
995
|
-
</div>
|
|
996
1056
|
</div>
|
|
997
1057
|
<div class="flex">
|
|
998
|
-
<div class="flex items-center gap-2 w-6/12">
|
|
999
|
-
<p-radiobutton name="menuMode" value="drawer" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('drawer')" inputId="drawer"></p-radiobutton>
|
|
1000
|
-
<label for="drawer">Drawer</label>
|
|
1001
|
-
</div>
|
|
1002
1058
|
<div class="flex items-center gap-2 w-6/12">
|
|
1003
1059
|
<p-radiobutton name="menuMode" value="horizontal" [ngModel]="menuMode()" (ngModelChange)="setMenuMode('horizontal')" inputId="horizontal"></p-radiobutton>
|
|
1004
1060
|
<label for="horizontal">Horizontal</label>
|
|
@@ -1018,26 +1074,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1018
1074
|
type: Input
|
|
1019
1075
|
}], cardStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardStyle", required: false }] }, { type: i0.Output, args: ["cardStyleChange"] }] } });
|
|
1020
1076
|
|
|
1021
|
-
class AppFooter {
|
|
1022
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppFooter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1023
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.8", type: AppFooter, isStandalone: true, selector: "[app-footer]", ngImport: i0, template: `
|
|
1024
|
-
<footer class="layout-footer">
|
|
1025
|
-
<span class="footer-copyright">© UNOPS 2026</span>
|
|
1026
|
-
</footer>
|
|
1027
|
-
`, isInline: true });
|
|
1028
|
-
}
|
|
1029
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppFooter, decorators: [{
|
|
1030
|
-
type: Component,
|
|
1031
|
-
args: [{
|
|
1032
|
-
selector: '[app-footer]',
|
|
1033
|
-
template: `
|
|
1034
|
-
<footer class="layout-footer">
|
|
1035
|
-
<span class="footer-copyright">© UNOPS 2026</span>
|
|
1036
|
-
</footer>
|
|
1037
|
-
`
|
|
1038
|
-
}]
|
|
1039
|
-
}] });
|
|
1040
|
-
|
|
1041
1077
|
class AppRightMenu {
|
|
1042
1078
|
layoutService = inject(LayoutService);
|
|
1043
1079
|
cards = [
|
|
@@ -1059,7 +1095,7 @@ class AppRightMenu {
|
|
|
1059
1095
|
<div class="flex flex-col mt-7">
|
|
1060
1096
|
<div class="flex gap-6">
|
|
1061
1097
|
<div class="flex flex-col items-center">
|
|
1062
|
-
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-
|
|
1098
|
+
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-subtle">
|
|
1063
1099
|
<i class="pi pi-dollar text-blue-600 text-2xl!"></i>
|
|
1064
1100
|
</span>
|
|
1065
1101
|
<span class="min-h-14 w-px bg-(--surface-border)"></span>
|
|
@@ -1071,7 +1107,7 @@ class AppRightMenu {
|
|
|
1071
1107
|
</div>
|
|
1072
1108
|
<div class="flex gap-6">
|
|
1073
1109
|
<div class="flex flex-col items-center">
|
|
1074
|
-
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-
|
|
1110
|
+
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-subtle">
|
|
1075
1111
|
<i class="pi pi-download text-orange-600 text-2xl!"></i>
|
|
1076
1112
|
</span>
|
|
1077
1113
|
<span class="min-h-14 w-px bg-(--surface-border)"></span>
|
|
@@ -1083,7 +1119,7 @@ class AppRightMenu {
|
|
|
1083
1119
|
</div>
|
|
1084
1120
|
<div class="flex gap-6">
|
|
1085
1121
|
<div class="flex flex-col items-center">
|
|
1086
|
-
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-
|
|
1122
|
+
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-subtle">
|
|
1087
1123
|
<i class="pi pi-question-circle text-violet-600 text-2xl!"></i>
|
|
1088
1124
|
</span>
|
|
1089
1125
|
<span class="min-h-14 w-px bg-(--surface-border)"></span>
|
|
@@ -1095,7 +1131,7 @@ class AppRightMenu {
|
|
|
1095
1131
|
</div>
|
|
1096
1132
|
<div class="flex gap-6">
|
|
1097
1133
|
<div class="flex flex-col items-center">
|
|
1098
|
-
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-
|
|
1134
|
+
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-subtle">
|
|
1099
1135
|
<i class="pi pi-comment text-blue-600 text-2xl!"></i>
|
|
1100
1136
|
</span>
|
|
1101
1137
|
</div>
|
|
@@ -1121,7 +1157,7 @@ class AppRightMenu {
|
|
|
1121
1157
|
<p class="body-small mt-1 text-left">Track your ongoing shipments to customers.</p>
|
|
1122
1158
|
<img class="w-full h-full max-h-60 object-cover border border-surface rounded-2xl mt-4" src="layout/images/sidebar-right/staticmap.png" alt="unops-ng_ux" />
|
|
1123
1159
|
</div>
|
|
1124
|
-
</p-drawer>`, isInline: true, dependencies: [{ kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i4.Drawer, selector: "p-drawer", inputs: ["appendTo", "motionOptions", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i2.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4$1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type:
|
|
1160
|
+
</p-drawer>`, isInline: true, dependencies: [{ kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i4.Drawer, selector: "p-drawer", inputs: ["appendTo", "motionOptions", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i2.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4$1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }] });
|
|
1125
1161
|
}
|
|
1126
1162
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppRightMenu, decorators: [{
|
|
1127
1163
|
type: Component,
|
|
@@ -1134,7 +1170,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1134
1170
|
<div class="flex flex-col mt-7">
|
|
1135
1171
|
<div class="flex gap-6">
|
|
1136
1172
|
<div class="flex flex-col items-center">
|
|
1137
|
-
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-
|
|
1173
|
+
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-subtle">
|
|
1138
1174
|
<i class="pi pi-dollar text-blue-600 text-2xl!"></i>
|
|
1139
1175
|
</span>
|
|
1140
1176
|
<span class="min-h-14 w-px bg-(--surface-border)"></span>
|
|
@@ -1146,7 +1182,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1146
1182
|
</div>
|
|
1147
1183
|
<div class="flex gap-6">
|
|
1148
1184
|
<div class="flex flex-col items-center">
|
|
1149
|
-
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-
|
|
1185
|
+
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-subtle">
|
|
1150
1186
|
<i class="pi pi-download text-orange-600 text-2xl!"></i>
|
|
1151
1187
|
</span>
|
|
1152
1188
|
<span class="min-h-14 w-px bg-(--surface-border)"></span>
|
|
@@ -1158,7 +1194,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1158
1194
|
</div>
|
|
1159
1195
|
<div class="flex gap-6">
|
|
1160
1196
|
<div class="flex flex-col items-center">
|
|
1161
|
-
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-
|
|
1197
|
+
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-subtle">
|
|
1162
1198
|
<i class="pi pi-question-circle text-violet-600 text-2xl!"></i>
|
|
1163
1199
|
</span>
|
|
1164
1200
|
<span class="min-h-14 w-px bg-(--surface-border)"></span>
|
|
@@ -1170,7 +1206,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1170
1206
|
</div>
|
|
1171
1207
|
<div class="flex gap-6">
|
|
1172
1208
|
<div class="flex flex-col items-center">
|
|
1173
|
-
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-
|
|
1209
|
+
<span class="w-14 h-14 flex items-center justify-center border border-surface rounded-xl shadow-subtle">
|
|
1174
1210
|
<i class="pi pi-comment text-blue-600 text-2xl!"></i>
|
|
1175
1211
|
</span>
|
|
1176
1212
|
</div>
|
|
@@ -1212,21 +1248,21 @@ class AppSearch {
|
|
|
1212
1248
|
this.layoutService.layoutState.update((prev) => ({ ...prev, searchBarActive: _val }));
|
|
1213
1249
|
}
|
|
1214
1250
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppSearch, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1215
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.8", type: AppSearch, isStandalone: true, selector: "[app-search]", ngImport: i0, template: ` <p-dialog [(visible)]="searchBarActive" [breakpoints]="{ '
|
|
1251
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.8", type: AppSearch, isStandalone: true, selector: "[app-search]", ngImport: i0, template: ` <p-dialog [(visible)]="searchBarActive" [breakpoints]="{ '1024px': '75vw', '780px': '90vw' }" modal dismissableMask styleClass="w-1/2 search-container">
|
|
1216
1252
|
<ng-template #headless>
|
|
1217
1253
|
<div class="w-full">
|
|
1218
1254
|
<i class="pi pi-search"></i>
|
|
1219
1255
|
<input pInputText type="text" [pAutoFocus]="true" class="p-inputtext search-input" placeholder="Search" (keydown.enter)="toggleSearchBar()" />
|
|
1220
1256
|
</div>
|
|
1221
1257
|
</ng-template>
|
|
1222
|
-
</p-dialog>`, isInline: true, dependencies: [{ kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1$
|
|
1258
|
+
</p-dialog>`, isInline: true, dependencies: [{ kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1$3.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4$1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: AutoFocusModule }, { kind: "directive", type: i3$2.AutoFocus, selector: "[pAutoFocus]", inputs: ["pAutoFocus"] }] });
|
|
1223
1259
|
}
|
|
1224
1260
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppSearch, decorators: [{
|
|
1225
1261
|
type: Component,
|
|
1226
1262
|
args: [{
|
|
1227
1263
|
selector: '[app-search]',
|
|
1228
1264
|
imports: [DialogModule, InputTextModule, AutoFocusModule],
|
|
1229
|
-
template: ` <p-dialog [(visible)]="searchBarActive" [breakpoints]="{ '
|
|
1265
|
+
template: ` <p-dialog [(visible)]="searchBarActive" [breakpoints]="{ '1024px': '75vw', '780px': '90vw' }" modal dismissableMask styleClass="w-1/2 search-container">
|
|
1230
1266
|
<ng-template #headless>
|
|
1231
1267
|
<div class="w-full">
|
|
1232
1268
|
<i class="pi pi-search"></i>
|
|
@@ -1237,6 +1273,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1237
1273
|
}]
|
|
1238
1274
|
}] });
|
|
1239
1275
|
|
|
1276
|
+
class FooterMainComponent {
|
|
1277
|
+
/** When true, always shows the default copyright — ignores FooterService content. */
|
|
1278
|
+
copyrightOnly = input(false, ...(ngDevMode ? [{ debugName: "copyrightOnly" }] : []));
|
|
1279
|
+
footerService = inject(FooterService);
|
|
1280
|
+
copyrightYear = new Date().getFullYear();
|
|
1281
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FooterMainComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1282
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: FooterMainComponent, isStandalone: true, selector: "ux-footer-main", inputs: { copyrightOnly: { classPropertyName: "copyrightOnly", publicName: "copyrightOnly", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ux-footer-main" }, ngImport: i0, template: `
|
|
1283
|
+
<div class="footer-inner">
|
|
1284
|
+
@if (copyrightOnly()) {
|
|
1285
|
+
<span>© UNOPS {{ copyrightYear }}</span>
|
|
1286
|
+
} @else if (footerService.content(); as tpl) {
|
|
1287
|
+
<ng-container [ngTemplateOutlet]="tpl" />
|
|
1288
|
+
}
|
|
1289
|
+
</div>
|
|
1290
|
+
`, isInline: true, styles: [":host{flex-shrink:0;display:flex;align-items:center;height:3rem;background:var(--p-primary-50);font-size:var(--font-size-xs, .75rem);line-height:1.2;color:var(--p-text-color)}:host-context(:root[class*=\"app-dark\"]){background:var(--p-primary-950);color:var(--p-surface-100)}:host(.footer-sticky){position:sticky;bottom:0;z-index:10}.footer-inner{width:100%;max-width:1540px;margin-inline:auto;padding:1rem}@media screen and (min-width:780px){.footer-inner{padding:1rem 3rem}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1291
|
+
}
|
|
1292
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FooterMainComponent, decorators: [{
|
|
1293
|
+
type: Component,
|
|
1294
|
+
args: [{ selector: 'ux-footer-main', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet], host: { class: 'ux-footer-main' }, template: `
|
|
1295
|
+
<div class="footer-inner">
|
|
1296
|
+
@if (copyrightOnly()) {
|
|
1297
|
+
<span>© UNOPS {{ copyrightYear }}</span>
|
|
1298
|
+
} @else if (footerService.content(); as tpl) {
|
|
1299
|
+
<ng-container [ngTemplateOutlet]="tpl" />
|
|
1300
|
+
}
|
|
1301
|
+
</div>
|
|
1302
|
+
`, styles: [":host{flex-shrink:0;display:flex;align-items:center;height:3rem;background:var(--p-primary-50);font-size:var(--font-size-xs, .75rem);line-height:1.2;color:var(--p-text-color)}:host-context(:root[class*=\"app-dark\"]){background:var(--p-primary-950);color:var(--p-surface-100)}:host(.footer-sticky){position:sticky;bottom:0;z-index:10}.footer-inner{width:100%;max-width:1540px;margin-inline:auto;padding:1rem}@media screen and (min-width:780px){.footer-inner{padding:1rem 3rem}}\n"] }]
|
|
1303
|
+
}], propDecorators: { copyrightOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "copyrightOnly", required: false }] }] } });
|
|
1304
|
+
|
|
1240
1305
|
class AppMenuitem {
|
|
1241
1306
|
layoutService = inject(LayoutService);
|
|
1242
1307
|
router = inject(Router);
|
|
@@ -1716,19 +1781,24 @@ class AppTopbar {
|
|
|
1716
1781
|
<i class="pi pi-bars"></i>
|
|
1717
1782
|
</button>
|
|
1718
1783
|
<div class="topbar-left">
|
|
1719
|
-
<
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
<
|
|
1730
|
-
|
|
1731
|
-
|
|
1784
|
+
<div class="topbar-sidebar-section">
|
|
1785
|
+
<button
|
|
1786
|
+
type="button"
|
|
1787
|
+
class="topbar-menu-toggle"
|
|
1788
|
+
[class.active]="isSidebarPinned()"
|
|
1789
|
+
[attr.aria-label]="isSidebarPinned() ? 'Collapse sidebar' : 'Expand sidebar'"
|
|
1790
|
+
(click)="toggleSidebarPin()"
|
|
1791
|
+
>
|
|
1792
|
+
<i class="pi pi-bars"></i>
|
|
1793
|
+
</button>
|
|
1794
|
+
<a class="topbar-logo" [routerLink]="['/']">
|
|
1795
|
+
<img [src]="desktopLogo()" [attr.alt]="mobileLogoConfig.alt" />
|
|
1796
|
+
</a>
|
|
1797
|
+
<span class="topbar-logo-separator"></span>
|
|
1798
|
+
</div>
|
|
1799
|
+
</div>
|
|
1800
|
+
|
|
1801
|
+
<div class="topbar-main">
|
|
1732
1802
|
<div app-breadcrumb></div>
|
|
1733
1803
|
@if (searchActive()) {
|
|
1734
1804
|
<div class="flex items-center gap-2 ml-auto">
|
|
@@ -1741,14 +1811,8 @@ class AppTopbar {
|
|
|
1741
1811
|
</button>
|
|
1742
1812
|
</div>
|
|
1743
1813
|
}
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
<a class="mobile-logo" [routerLink]="['/landing']">
|
|
1747
|
-
<img [src]="mobileLogo()" [attr.alt]="mobileLogoConfig.alt" />
|
|
1748
|
-
</a>
|
|
1749
|
-
|
|
1750
|
-
<div class="topbar-right">
|
|
1751
|
-
<ul class="topbar-menu">
|
|
1814
|
+
<div class="topbar-right">
|
|
1815
|
+
<ul class="topbar-menu">
|
|
1752
1816
|
<li class="right-sidebar-item" [class.hidden]="searchActive()">
|
|
1753
1817
|
<a class="right-sidebar-button" aria-label="Open search" (click)="openSearch()">
|
|
1754
1818
|
<i class="pi pi-search"></i>
|
|
@@ -1769,11 +1833,11 @@ class AppTopbar {
|
|
|
1769
1833
|
<i class="pi pi-bell"></i>
|
|
1770
1834
|
</a>
|
|
1771
1835
|
<div
|
|
1772
|
-
class="list-none m-0 rounded-2xl border border-surface fixed sm:absolute bg-surface-0 dark:bg-surface-900 overflow-hidden hidden origin-top w-[calc(100vw-2rem)] sm:w-88 mt-2 z-50 top-auto left-4 sm:left-auto sm:right-0 shadow-
|
|
1836
|
+
class="list-none m-0 rounded-2xl border border-surface fixed sm:absolute bg-surface-0 dark:bg-surface-900 overflow-hidden hidden origin-top w-[calc(100vw-2rem)] sm:w-88 mt-2 z-50 top-auto left-4 sm:left-auto sm:right-0 shadow-flyout"
|
|
1773
1837
|
>
|
|
1774
1838
|
<div class="p-4 flex items-center justify-between border-b border-surface">
|
|
1775
1839
|
<span class="label-small text-surface-950 dark:text-surface-0">Notifications</span>
|
|
1776
|
-
<button pRipple class="py-1 px-2 text-surface-950 dark:text-surface-0 label-x-small hover:bg-emphasis border border-surface rounded-lg shadow-
|
|
1840
|
+
<button pRipple class="py-1 px-2 text-surface-950 dark:text-surface-0 label-x-small hover:bg-emphasis border border-surface rounded-lg shadow-subtle transition-all">Mark all as read</button>
|
|
1777
1841
|
</div>
|
|
1778
1842
|
<div class="flex items-center border-b border-surface">
|
|
1779
1843
|
@for (item of notificationsBars(); track item.id; let i = $index) {
|
|
@@ -1823,7 +1887,7 @@ class AppTopbar {
|
|
|
1823
1887
|
</svg>
|
|
1824
1888
|
</a>
|
|
1825
1889
|
<div
|
|
1826
|
-
class="list-none p-2 m-0 rounded-2xl border border-surface overflow-hidden fixed sm:absolute bg-surface-0 dark:bg-surface-900 hidden origin-top w-44 mt-2 right-4 sm:right-0 z-999 top-auto shadow-
|
|
1890
|
+
class="list-none p-2 m-0 rounded-2xl border border-surface overflow-hidden fixed sm:absolute bg-surface-0 dark:bg-surface-900 hidden origin-top w-44 mt-2 right-4 sm:right-0 z-999 top-auto shadow-flyout"
|
|
1827
1891
|
>
|
|
1828
1892
|
<ul class="flex flex-col gap-1">
|
|
1829
1893
|
@for (lang of languages(); track lang.code) {
|
|
@@ -1849,7 +1913,7 @@ class AppTopbar {
|
|
|
1849
1913
|
</a>
|
|
1850
1914
|
<div
|
|
1851
1915
|
#profilePanel
|
|
1852
|
-
class="list-none p-2 m-0 rounded-2xl border border-surface overflow-hidden fixed sm:absolute bg-surface-0 dark:bg-surface-900 origin-top w-52 mt-2 right-4 sm:right-0 z-999 top-auto shadow-
|
|
1916
|
+
class="list-none p-2 m-0 rounded-2xl border border-surface overflow-hidden fixed sm:absolute bg-surface-0 dark:bg-surface-900 origin-top w-52 mt-2 right-4 sm:right-0 z-999 top-auto shadow-flyout"
|
|
1853
1917
|
[class.hidden]="!profileMenuOpen()"
|
|
1854
1918
|
[class.animate-scalein]="profileMenuOpen()"
|
|
1855
1919
|
>
|
|
@@ -1900,7 +1964,7 @@ class AppTopbar {
|
|
|
1900
1964
|
</a>
|
|
1901
1965
|
</li>
|
|
1902
1966
|
<li>
|
|
1903
|
-
<a class="label-small dark:text-surface-400 flex gap-2 py-2 px-2.5 rounded-lg items-center hover:bg-emphasis transition-colors duration-150 cursor-pointer" (click)="profileMenuOpen.set(false)">
|
|
1967
|
+
<a class="label-small dark:text-surface-400 flex gap-2 py-2 px-2.5 rounded-lg items-center hover:bg-emphasis transition-colors duration-150 cursor-pointer" (click)="profileMenuOpen.set(false); onConfigButtonClick()">
|
|
1904
1968
|
<i class="pi pi-cog"></i>
|
|
1905
1969
|
<span>Settings</span>
|
|
1906
1970
|
</a>
|
|
@@ -1926,9 +1990,14 @@ class AppTopbar {
|
|
|
1926
1990
|
</ul>
|
|
1927
1991
|
</div>
|
|
1928
1992
|
</li>
|
|
1929
|
-
|
|
1993
|
+
</ul>
|
|
1994
|
+
</div>
|
|
1930
1995
|
</div>
|
|
1931
|
-
|
|
1996
|
+
|
|
1997
|
+
<a class="mobile-logo" [routerLink]="['/']">
|
|
1998
|
+
<img [src]="mobileLogo()" [attr.alt]="mobileLogoConfig.alt" />
|
|
1999
|
+
</a>
|
|
2000
|
+
</div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: StyleClassModule }, { kind: "directive", type: i3$4.StyleClass, selector: "[pStyleClass]", inputs: ["pStyleClass", "enterFromClass", "enterActiveClass", "enterToClass", "leaveFromClass", "leaveActiveClass", "leaveToClass", "hideOnOutsideClick", "toggleClass", "hideOnEscape", "hideOnResize", "resizeSelector"] }, { kind: "component", type: AppBreadcrumb, selector: "[app-breadcrumb]" }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4$1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i5$1.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i6.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "ngmodule", type: RippleModule }, { kind: "directive", type: i4$2.Ripple, selector: "[pRipple]" }, { kind: "ngmodule", type: BadgeModule }, { kind: "component", type: i8.Badge, selector: "p-badge", inputs: ["styleClass", "badgeSize", "size", "severity", "value", "badgeDisabled"] }, { kind: "ngmodule", type: OverlayBadgeModule }, { kind: "component", type: i9.OverlayBadge, selector: "p-overlayBadge, p-overlay-badge, p-overlaybadge", inputs: ["styleClass", "style", "badgeSize", "severity", "value", "badgeDisabled", "size"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i10.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }] });
|
|
1932
2001
|
}
|
|
1933
2002
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppTopbar, decorators: [{
|
|
1934
2003
|
type: Component,
|
|
@@ -1940,19 +2009,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1940
2009
|
<i class="pi pi-bars"></i>
|
|
1941
2010
|
</button>
|
|
1942
2011
|
<div class="topbar-left">
|
|
1943
|
-
<
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
<
|
|
1954
|
-
|
|
1955
|
-
|
|
2012
|
+
<div class="topbar-sidebar-section">
|
|
2013
|
+
<button
|
|
2014
|
+
type="button"
|
|
2015
|
+
class="topbar-menu-toggle"
|
|
2016
|
+
[class.active]="isSidebarPinned()"
|
|
2017
|
+
[attr.aria-label]="isSidebarPinned() ? 'Collapse sidebar' : 'Expand sidebar'"
|
|
2018
|
+
(click)="toggleSidebarPin()"
|
|
2019
|
+
>
|
|
2020
|
+
<i class="pi pi-bars"></i>
|
|
2021
|
+
</button>
|
|
2022
|
+
<a class="topbar-logo" [routerLink]="['/']">
|
|
2023
|
+
<img [src]="desktopLogo()" [attr.alt]="mobileLogoConfig.alt" />
|
|
2024
|
+
</a>
|
|
2025
|
+
<span class="topbar-logo-separator"></span>
|
|
2026
|
+
</div>
|
|
2027
|
+
</div>
|
|
2028
|
+
|
|
2029
|
+
<div class="topbar-main">
|
|
1956
2030
|
<div app-breadcrumb></div>
|
|
1957
2031
|
@if (searchActive()) {
|
|
1958
2032
|
<div class="flex items-center gap-2 ml-auto">
|
|
@@ -1965,14 +2039,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1965
2039
|
</button>
|
|
1966
2040
|
</div>
|
|
1967
2041
|
}
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
<a class="mobile-logo" [routerLink]="['/landing']">
|
|
1971
|
-
<img [src]="mobileLogo()" [attr.alt]="mobileLogoConfig.alt" />
|
|
1972
|
-
</a>
|
|
1973
|
-
|
|
1974
|
-
<div class="topbar-right">
|
|
1975
|
-
<ul class="topbar-menu">
|
|
2042
|
+
<div class="topbar-right">
|
|
2043
|
+
<ul class="topbar-menu">
|
|
1976
2044
|
<li class="right-sidebar-item" [class.hidden]="searchActive()">
|
|
1977
2045
|
<a class="right-sidebar-button" aria-label="Open search" (click)="openSearch()">
|
|
1978
2046
|
<i class="pi pi-search"></i>
|
|
@@ -1993,11 +2061,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1993
2061
|
<i class="pi pi-bell"></i>
|
|
1994
2062
|
</a>
|
|
1995
2063
|
<div
|
|
1996
|
-
class="list-none m-0 rounded-2xl border border-surface fixed sm:absolute bg-surface-0 dark:bg-surface-900 overflow-hidden hidden origin-top w-[calc(100vw-2rem)] sm:w-88 mt-2 z-50 top-auto left-4 sm:left-auto sm:right-0 shadow-
|
|
2064
|
+
class="list-none m-0 rounded-2xl border border-surface fixed sm:absolute bg-surface-0 dark:bg-surface-900 overflow-hidden hidden origin-top w-[calc(100vw-2rem)] sm:w-88 mt-2 z-50 top-auto left-4 sm:left-auto sm:right-0 shadow-flyout"
|
|
1997
2065
|
>
|
|
1998
2066
|
<div class="p-4 flex items-center justify-between border-b border-surface">
|
|
1999
2067
|
<span class="label-small text-surface-950 dark:text-surface-0">Notifications</span>
|
|
2000
|
-
<button pRipple class="py-1 px-2 text-surface-950 dark:text-surface-0 label-x-small hover:bg-emphasis border border-surface rounded-lg shadow-
|
|
2068
|
+
<button pRipple class="py-1 px-2 text-surface-950 dark:text-surface-0 label-x-small hover:bg-emphasis border border-surface rounded-lg shadow-subtle transition-all">Mark all as read</button>
|
|
2001
2069
|
</div>
|
|
2002
2070
|
<div class="flex items-center border-b border-surface">
|
|
2003
2071
|
@for (item of notificationsBars(); track item.id; let i = $index) {
|
|
@@ -2047,7 +2115,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2047
2115
|
</svg>
|
|
2048
2116
|
</a>
|
|
2049
2117
|
<div
|
|
2050
|
-
class="list-none p-2 m-0 rounded-2xl border border-surface overflow-hidden fixed sm:absolute bg-surface-0 dark:bg-surface-900 hidden origin-top w-44 mt-2 right-4 sm:right-0 z-999 top-auto shadow-
|
|
2118
|
+
class="list-none p-2 m-0 rounded-2xl border border-surface overflow-hidden fixed sm:absolute bg-surface-0 dark:bg-surface-900 hidden origin-top w-44 mt-2 right-4 sm:right-0 z-999 top-auto shadow-flyout"
|
|
2051
2119
|
>
|
|
2052
2120
|
<ul class="flex flex-col gap-1">
|
|
2053
2121
|
@for (lang of languages(); track lang.code) {
|
|
@@ -2073,7 +2141,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2073
2141
|
</a>
|
|
2074
2142
|
<div
|
|
2075
2143
|
#profilePanel
|
|
2076
|
-
class="list-none p-2 m-0 rounded-2xl border border-surface overflow-hidden fixed sm:absolute bg-surface-0 dark:bg-surface-900 origin-top w-52 mt-2 right-4 sm:right-0 z-999 top-auto shadow-
|
|
2144
|
+
class="list-none p-2 m-0 rounded-2xl border border-surface overflow-hidden fixed sm:absolute bg-surface-0 dark:bg-surface-900 origin-top w-52 mt-2 right-4 sm:right-0 z-999 top-auto shadow-flyout"
|
|
2077
2145
|
[class.hidden]="!profileMenuOpen()"
|
|
2078
2146
|
[class.animate-scalein]="profileMenuOpen()"
|
|
2079
2147
|
>
|
|
@@ -2124,7 +2192,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2124
2192
|
</a>
|
|
2125
2193
|
</li>
|
|
2126
2194
|
<li>
|
|
2127
|
-
<a class="label-small dark:text-surface-400 flex gap-2 py-2 px-2.5 rounded-lg items-center hover:bg-emphasis transition-colors duration-150 cursor-pointer" (click)="profileMenuOpen.set(false)">
|
|
2195
|
+
<a class="label-small dark:text-surface-400 flex gap-2 py-2 px-2.5 rounded-lg items-center hover:bg-emphasis transition-colors duration-150 cursor-pointer" (click)="profileMenuOpen.set(false); onConfigButtonClick()">
|
|
2128
2196
|
<i class="pi pi-cog"></i>
|
|
2129
2197
|
<span>Settings</span>
|
|
2130
2198
|
</a>
|
|
@@ -2150,8 +2218,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2150
2218
|
</ul>
|
|
2151
2219
|
</div>
|
|
2152
2220
|
</li>
|
|
2153
|
-
|
|
2221
|
+
</ul>
|
|
2222
|
+
</div>
|
|
2154
2223
|
</div>
|
|
2224
|
+
|
|
2225
|
+
<a class="mobile-logo" [routerLink]="['/']">
|
|
2226
|
+
<img [src]="mobileLogo()" [attr.alt]="mobileLogoConfig.alt" />
|
|
2227
|
+
</a>
|
|
2155
2228
|
</div>`
|
|
2156
2229
|
}]
|
|
2157
2230
|
}], propDecorators: { menuButton: [{
|
|
@@ -2171,7 +2244,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2171
2244
|
args: ['document:click', ['$event']]
|
|
2172
2245
|
}] } });
|
|
2173
2246
|
|
|
2174
|
-
const BREAKPOINT =
|
|
2247
|
+
const BREAKPOINT = 1024;
|
|
2175
2248
|
class AppSidebar {
|
|
2176
2249
|
layoutService = inject(LayoutService);
|
|
2177
2250
|
router = inject(Router);
|
|
@@ -2378,22 +2451,28 @@ class AppSidebar {
|
|
|
2378
2451
|
}
|
|
2379
2452
|
}
|
|
2380
2453
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppSidebar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2381
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2382
|
-
<div #menuContainer class="layout-menu-container" (scroll)="onMenuScroll()">
|
|
2454
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: AppSidebar, isStandalone: true, selector: "[app-sidebar]", viewQueries: [{ propertyName: "menuContainer", first: true, predicate: ["menuContainer"], descendants: true }, { propertyName: "sidebarRef", first: true, predicate: ["sidebarRef"], descendants: true }], ngImport: i0, template: `<nav class="layout-sidebar" aria-label="Main navigation" (mouseleave)="onMouseLeave()">
|
|
2455
|
+
<div #menuContainer class="layout-menu-container min-h-0 grow" (scroll)="onMenuScroll()">
|
|
2383
2456
|
<div app-menu></div>
|
|
2384
2457
|
</div>
|
|
2458
|
+
@if (!isHorizontal()) {
|
|
2459
|
+
<ux-footer-main [copyrightOnly]="true" role="contentinfo" />
|
|
2460
|
+
}
|
|
2385
2461
|
<div app-topbar *ngIf="isHorizontal()"></div>
|
|
2386
|
-
</nav>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: AppMenu, selector: "[app-menu]" }, { kind: "ngmodule", type: RouterModule }, { kind: "component", type: AppTopbar, selector: "[app-topbar]", inputs: ["selectedNotificationBar"], outputs: ["selectedNotificationBarChange"] }] });
|
|
2462
|
+
</nav>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: AppMenu, selector: "[app-menu]" }, { kind: "ngmodule", type: RouterModule }, { kind: "component", type: AppTopbar, selector: "[app-topbar]", inputs: ["selectedNotificationBar"], outputs: ["selectedNotificationBarChange"] }, { kind: "component", type: FooterMainComponent, selector: "ux-footer-main", inputs: ["copyrightOnly"] }] });
|
|
2387
2463
|
}
|
|
2388
2464
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppSidebar, decorators: [{
|
|
2389
2465
|
type: Component,
|
|
2390
2466
|
args: [{
|
|
2391
2467
|
selector: '[app-sidebar]',
|
|
2392
|
-
imports: [CommonModule, AppMenu, RouterModule, AppTopbar],
|
|
2468
|
+
imports: [CommonModule, AppMenu, RouterModule, AppTopbar, FooterMainComponent],
|
|
2393
2469
|
template: `<nav class="layout-sidebar" aria-label="Main navigation" (mouseleave)="onMouseLeave()">
|
|
2394
|
-
<div #menuContainer class="layout-menu-container" (scroll)="onMenuScroll()">
|
|
2470
|
+
<div #menuContainer class="layout-menu-container min-h-0 grow" (scroll)="onMenuScroll()">
|
|
2395
2471
|
<div app-menu></div>
|
|
2396
2472
|
</div>
|
|
2473
|
+
@if (!isHorizontal()) {
|
|
2474
|
+
<ux-footer-main [copyrightOnly]="true" role="contentinfo" />
|
|
2475
|
+
}
|
|
2397
2476
|
<div app-topbar *ngIf="isHorizontal()"></div>
|
|
2398
2477
|
</nav>`
|
|
2399
2478
|
}]
|
|
@@ -2407,6 +2486,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2407
2486
|
|
|
2408
2487
|
class AppLayout {
|
|
2409
2488
|
layoutService = inject(LayoutService);
|
|
2489
|
+
elRef = inject(ElementRef);
|
|
2410
2490
|
constructor() {
|
|
2411
2491
|
effect(() => {
|
|
2412
2492
|
const state = this.layoutService.layoutState();
|
|
@@ -2417,6 +2497,11 @@ class AppLayout {
|
|
|
2417
2497
|
document.body.classList.remove('blocked-scroll');
|
|
2418
2498
|
}
|
|
2419
2499
|
});
|
|
2500
|
+
inject(Router).events.pipe(filter((e) => e instanceof NavigationEnd), takeUntilDestroyed()).subscribe(() => {
|
|
2501
|
+
const wrapper = this.elRef.nativeElement.querySelector('.layout-content-wrapper');
|
|
2502
|
+
if (wrapper)
|
|
2503
|
+
wrapper.scrollTop = 0;
|
|
2504
|
+
});
|
|
2420
2505
|
}
|
|
2421
2506
|
containerClass = computed(() => {
|
|
2422
2507
|
const layoutConfig = this.layoutService.layoutConfig();
|
|
@@ -2449,21 +2534,21 @@ class AppLayout {
|
|
|
2449
2534
|
<div app-breadcrumb></div>
|
|
2450
2535
|
<router-outlet></router-outlet>
|
|
2451
2536
|
</main>
|
|
2452
|
-
<div app-footer></div>
|
|
2453
2537
|
</div>
|
|
2538
|
+
<ux-footer-main class="footer-sticky" />
|
|
2454
2539
|
</div>
|
|
2455
2540
|
</div>
|
|
2456
2541
|
<app-configurator />
|
|
2457
2542
|
<div app-search></div>
|
|
2458
2543
|
<div app-rightmenu></div>
|
|
2459
2544
|
<div class="layout-mask"></div>
|
|
2460
|
-
</div> `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AppTopbar, selector: "[app-topbar]", inputs: ["selectedNotificationBar"], outputs: ["selectedNotificationBarChange"] }, { kind: "component", type: AppSidebar, selector: "[app-sidebar]" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: AppConfigurator, selector: "app-configurator", inputs: ["simple", "location", "cardStyle"], outputs: ["cardStyleChange"] }, { kind: "component", type: AppBreadcrumb, selector: "[app-breadcrumb]" }, { kind: "component", type:
|
|
2545
|
+
</div> `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AppTopbar, selector: "[app-topbar]", inputs: ["selectedNotificationBar"], outputs: ["selectedNotificationBarChange"] }, { kind: "component", type: AppSidebar, selector: "[app-sidebar]" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: AppConfigurator, selector: "app-configurator", inputs: ["simple", "location", "cardStyle"], outputs: ["cardStyleChange"] }, { kind: "component", type: AppBreadcrumb, selector: "[app-breadcrumb]" }, { kind: "component", type: FooterMainComponent, selector: "ux-footer-main", inputs: ["copyrightOnly"] }, { kind: "component", type: AppSearch, selector: "[app-search]" }, { kind: "component", type: AppRightMenu, selector: "[app-rightmenu]" }] });
|
|
2461
2546
|
}
|
|
2462
2547
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppLayout, decorators: [{
|
|
2463
2548
|
type: Component,
|
|
2464
2549
|
args: [{
|
|
2465
2550
|
selector: 'app-layout',
|
|
2466
|
-
imports: [CommonModule, AppTopbar, AppSidebar, RouterModule, AppConfigurator, AppBreadcrumb,
|
|
2551
|
+
imports: [CommonModule, AppTopbar, AppSidebar, RouterModule, AppConfigurator, AppBreadcrumb, FooterMainComponent, AppSearch, AppRightMenu],
|
|
2467
2552
|
template: `<div class="layout-wrapper" [ngClass]="containerClass()">
|
|
2468
2553
|
<div app-topbar></div>
|
|
2469
2554
|
<div class="layout-body">
|
|
@@ -2474,8 +2559,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2474
2559
|
<div app-breadcrumb></div>
|
|
2475
2560
|
<router-outlet></router-outlet>
|
|
2476
2561
|
</main>
|
|
2477
|
-
<div app-footer></div>
|
|
2478
2562
|
</div>
|
|
2563
|
+
<ux-footer-main class="footer-sticky" />
|
|
2479
2564
|
</div>
|
|
2480
2565
|
</div>
|
|
2481
2566
|
<app-configurator />
|
|
@@ -2486,6 +2571,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2486
2571
|
}]
|
|
2487
2572
|
}], ctorParameters: () => [] });
|
|
2488
2573
|
|
|
2574
|
+
class AppFooter {
|
|
2575
|
+
layoutService = inject(LayoutService);
|
|
2576
|
+
copyrightYear = new Date().getFullYear();
|
|
2577
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppFooter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2578
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: AppFooter, isStandalone: true, selector: "[app-footer]", ngImport: i0, template: `
|
|
2579
|
+
@if (layoutService.isHorizontal()) {
|
|
2580
|
+
<footer class="layout-footer">
|
|
2581
|
+
<span class="footer-copyright">© UNOPS {{ copyrightYear }}</span>
|
|
2582
|
+
</footer>
|
|
2583
|
+
}
|
|
2584
|
+
`, isInline: true });
|
|
2585
|
+
}
|
|
2586
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AppFooter, decorators: [{
|
|
2587
|
+
type: Component,
|
|
2588
|
+
args: [{
|
|
2589
|
+
selector: '[app-footer]',
|
|
2590
|
+
template: `
|
|
2591
|
+
@if (layoutService.isHorizontal()) {
|
|
2592
|
+
<footer class="layout-footer">
|
|
2593
|
+
<span class="footer-copyright">© UNOPS {{ copyrightYear }}</span>
|
|
2594
|
+
</footer>
|
|
2595
|
+
}
|
|
2596
|
+
`
|
|
2597
|
+
}]
|
|
2598
|
+
}] });
|
|
2599
|
+
|
|
2489
2600
|
class AuthLayout {
|
|
2490
2601
|
layoutService = inject(LayoutService);
|
|
2491
2602
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AuthLayout, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -2571,7 +2682,7 @@ class AiCardBgComponent {
|
|
|
2571
2682
|
/>
|
|
2572
2683
|
</svg>
|
|
2573
2684
|
<ng-content />
|
|
2574
|
-
`, isInline: true, styles: [":host{--ux-ai-bg-from:
|
|
2685
|
+
`, isInline: true, styles: [":host{--ux-ai-bg-from: var(--color-ai-50);--ux-ai-bg-to: var(--color-cherry-50);--ux-ai-fg-from: var(--color-ai-200);--ux-ai-fg-to: var(--color-cherry-100);position:relative;overflow:hidden;isolation:isolate;contain:paint;animation:ux-ai-bg-move 5s ease-in-out infinite;will-change:background-color}:host-context([class*=\"app-dark\"]){--ux-ai-bg-from: var(--color-ai-950);--ux-ai-bg-to: var(--color-cherry-950);--ux-ai-fg-from: var(--color-ai-900);--ux-ai-fg-to: var(--color-cherry-900)}:host>:not(svg){position:relative;z-index:1}:host svg.ux-ai-card-bg__svg{position:absolute;inset:0;z-index:0;height:100%;width:100%;max-height:100%;overflow:hidden;pointer-events:none}.ux-ai-fg{will-change:fill;animation:ux-ai-fg-move 6s ease-in-out infinite}.ux-ai-fg--1{animation-delay:0s}.ux-ai-fg--2{animation-delay:2s}.ux-ai-fg--3{animation-delay:4s}@keyframes ux-ai-bg-move{0%,to{background-color:var(--ux-ai-bg-from)}50%{background-color:var(--ux-ai-bg-to)}}@keyframes ux-ai-fg-move{0%,to{fill:var(--ux-ai-fg-from)}50%{fill:var(--ux-ai-fg-to)}}@media(prefers-reduced-motion:reduce){:host{animation:none;background-color:var(--ux-ai-bg-from)}.ux-ai-fg{animation:none;fill:var(--ux-ai-fg-from)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2575
2686
|
}
|
|
2576
2687
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AiCardBgComponent, decorators: [{
|
|
2577
2688
|
type: Component,
|
|
@@ -2620,7 +2731,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2620
2731
|
/>
|
|
2621
2732
|
</svg>
|
|
2622
2733
|
<ng-content />
|
|
2623
|
-
`, styles: [":host{--ux-ai-bg-from:
|
|
2734
|
+
`, styles: [":host{--ux-ai-bg-from: var(--color-ai-50);--ux-ai-bg-to: var(--color-cherry-50);--ux-ai-fg-from: var(--color-ai-200);--ux-ai-fg-to: var(--color-cherry-100);position:relative;overflow:hidden;isolation:isolate;contain:paint;animation:ux-ai-bg-move 5s ease-in-out infinite;will-change:background-color}:host-context([class*=\"app-dark\"]){--ux-ai-bg-from: var(--color-ai-950);--ux-ai-bg-to: var(--color-cherry-950);--ux-ai-fg-from: var(--color-ai-900);--ux-ai-fg-to: var(--color-cherry-900)}:host>:not(svg){position:relative;z-index:1}:host svg.ux-ai-card-bg__svg{position:absolute;inset:0;z-index:0;height:100%;width:100%;max-height:100%;overflow:hidden;pointer-events:none}.ux-ai-fg{will-change:fill;animation:ux-ai-fg-move 6s ease-in-out infinite}.ux-ai-fg--1{animation-delay:0s}.ux-ai-fg--2{animation-delay:2s}.ux-ai-fg--3{animation-delay:4s}@keyframes ux-ai-bg-move{0%,to{background-color:var(--ux-ai-bg-from)}50%{background-color:var(--ux-ai-bg-to)}}@keyframes ux-ai-fg-move{0%,to{fill:var(--ux-ai-fg-from)}50%{fill:var(--ux-ai-fg-to)}}@media(prefers-reduced-motion:reduce){:host{animation:none;background-color:var(--ux-ai-bg-from)}.ux-ai-fg{animation:none;fill:var(--ux-ai-fg-from)}}\n"] }]
|
|
2624
2735
|
}] });
|
|
2625
2736
|
|
|
2626
2737
|
class AiInsightsCardComponent {
|
|
@@ -2658,27 +2769,25 @@ class AiInsightsCardComponent {
|
|
|
2658
2769
|
return Math.max(1, Math.floor(available / insightCardHeight));
|
|
2659
2770
|
}
|
|
2660
2771
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AiInsightsCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2661
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: AiInsightsCardComponent, isStandalone: true, selector: "ux-ai-insights-card", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, insights: { classPropertyName: "insights", publicName: "insights", isSignal: true, isRequired: true, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionClick: "actionClick" }, host: { properties: { "class.
|
|
2662
|
-
<ux-ai-card-bg class="flex flex-col flex-1
|
|
2663
|
-
<div class="motion-safe:animate-enter-liquid [animation-delay:80ms] flex flex-col flex-1
|
|
2664
|
-
<div class="flex items-center justify-between cursor-pointer shrink-0" (click)="expanded.set(!expanded())">
|
|
2772
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: AiInsightsCardComponent, isStandalone: true, selector: "ux-ai-insights-card", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, insights: { classPropertyName: "insights", publicName: "insights", isSignal: true, isRequired: true, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionClick: "actionClick" }, host: { properties: { "class.ux-ai-expanded": "expanded()" }, classAttribute: "ux-ai-insights-card block border border-blue-100 dark:border-midnight-400 rounded-2xl shadow-sm overflow-hidden transition-all duration-300 flex flex-col" }, ngImport: i0, template: `
|
|
2773
|
+
<ux-ai-card-bg class="flex flex-col flex-1 p-4">
|
|
2774
|
+
<div class="motion-safe:animate-enter-liquid [animation-delay:80ms] flex flex-col flex-1">
|
|
2775
|
+
<div class="flex items-center justify-between cursor-pointer shrink-0 pr-2" (click)="expanded.set(!expanded())">
|
|
2665
2776
|
<div class="flex items-center gap-3">
|
|
2666
2777
|
<div class="w-[34px] h-[34px] rounded-[10px] flex items-center justify-center shrink-0">
|
|
2667
|
-
<i class="pi pi-sparkles text-
|
|
2778
|
+
<i class="pi pi-sparkles text-ai-600 dark:text-ai-300"></i>
|
|
2668
2779
|
</div>
|
|
2669
2780
|
<div class="flex flex-col">
|
|
2670
2781
|
<h4 class="title-h4 text-left text-deepsea-500 dark:text-surface-0">{{ title() }}</h4>
|
|
2671
2782
|
<span class="text-midnight-700 dark:text-surface-100 text-sm font-medium leading-tight">{{ insights().length }} insights available for your review</span>
|
|
2672
2783
|
</div>
|
|
2673
2784
|
</div>
|
|
2674
|
-
<
|
|
2675
|
-
<i class="pi text-xs text-darkblue-500 dark:text-surface-0" [ngClass]="expanded() ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
|
|
2676
|
-
</button>
|
|
2785
|
+
<i class="pi text-sm text-darkblue-500 dark:text-surface-0" [ngClass]="expanded() ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
|
|
2677
2786
|
</div>
|
|
2678
2787
|
|
|
2679
2788
|
<div class="expand-body" [class.expand-body--open]="expanded()">
|
|
2680
2789
|
<div class="expand-body__inner">
|
|
2681
|
-
<div class="flex flex-col gap-4 mt-4
|
|
2790
|
+
<div class="flex flex-col gap-4 mt-4">
|
|
2682
2791
|
<div class="bg-white/60 dark:bg-surface-800/60 border border-white dark:border-surface-700 rounded-[14px] shadow-sm flex items-center gap-4 px-4 py-2.5 shrink-0">
|
|
2683
2792
|
<i class="pi pi-search text-surface-500 dark:text-surface-300 text-sm"></i>
|
|
2684
2793
|
<input
|
|
@@ -2690,14 +2799,14 @@ class AiInsightsCardComponent {
|
|
|
2690
2799
|
/>
|
|
2691
2800
|
</div>
|
|
2692
2801
|
|
|
2693
|
-
<div class="flex flex-col gap-3
|
|
2802
|
+
<div class="flex flex-col gap-3">
|
|
2694
2803
|
@for (insight of paginatedInsights(); track insight.id) {
|
|
2695
2804
|
<div class="bg-white/70 dark:bg-surface-800/70 border border-white/50 dark:border-surface-700/50 rounded-[14px] shadow-sm p-4 flex gap-3 items-start shrink-0">
|
|
2696
2805
|
<i class="pi mt-0.5" [ngClass]="[insight.icon, insight.iconColor]"></i>
|
|
2697
2806
|
<div class="flex flex-col gap-2 flex-1 min-w-0">
|
|
2698
2807
|
<div class="flex flex-col gap-1">
|
|
2699
2808
|
<span class="text-midnight-500 dark:text-surface-0 text-sm font-bold leading-[21px]">{{ insight.title }}</span>
|
|
2700
|
-
<p class="text-
|
|
2809
|
+
<p class="text-midnight-400 dark:text-surface-300 text-sm leading-normal">{{ insight.description }}</p>
|
|
2701
2810
|
</div>
|
|
2702
2811
|
<button
|
|
2703
2812
|
class="flex items-center gap-1.5 text-darkblue-500 dark:text-primary-400 text-sm font-semibold cursor-pointer hover:underline bg-transparent border-none p-0 w-fit"
|
|
@@ -2718,8 +2827,8 @@ class AiInsightsCardComponent {
|
|
|
2718
2827
|
[first]="first()"
|
|
2719
2828
|
(onPageChange)="page.set($event.page ?? 0)"
|
|
2720
2829
|
[pageLinkSize]="3"
|
|
2721
|
-
styleClass="w-full
|
|
2722
|
-
[pt]="{ root: { class: '
|
|
2830
|
+
styleClass="w-full"
|
|
2831
|
+
[pt]="{ root: { class: 'justify-center' } }"
|
|
2723
2832
|
/>
|
|
2724
2833
|
</div>
|
|
2725
2834
|
</div>
|
|
@@ -2727,34 +2836,32 @@ class AiInsightsCardComponent {
|
|
|
2727
2836
|
</div>
|
|
2728
2837
|
</div>
|
|
2729
2838
|
</ux-ai-card-bg>
|
|
2730
|
-
`, isInline: true, styles: [":host{display:flex}\n"], dependencies: [{ kind: "component", type: AiCardBgComponent, selector: "ux-ai-card-bg" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type:
|
|
2839
|
+
`, isInline: true, styles: [":host{display:flex}\n"], dependencies: [{ kind: "component", type: AiCardBgComponent, selector: "ux-ai-card-bg" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i2$2.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first", "appendTo"], outputs: ["onPageChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2731
2840
|
}
|
|
2732
2841
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: AiInsightsCardComponent, decorators: [{
|
|
2733
2842
|
type: Component,
|
|
2734
2843
|
args: [{ selector: 'ux-ai-insights-card', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AiCardBgComponent, FormsModule, NgClass, PaginatorModule], host: {
|
|
2735
|
-
class: 'ux-ai-insights-card block border border-
|
|
2736
|
-
'[class.
|
|
2844
|
+
class: 'ux-ai-insights-card block border border-blue-100 dark:border-midnight-400 rounded-2xl shadow-sm overflow-hidden transition-all duration-300 flex flex-col',
|
|
2845
|
+
'[class.ux-ai-expanded]': 'expanded()'
|
|
2737
2846
|
}, template: `
|
|
2738
|
-
<ux-ai-card-bg class="flex flex-col flex-1
|
|
2739
|
-
<div class="motion-safe:animate-enter-liquid [animation-delay:80ms] flex flex-col flex-1
|
|
2740
|
-
<div class="flex items-center justify-between cursor-pointer shrink-0" (click)="expanded.set(!expanded())">
|
|
2847
|
+
<ux-ai-card-bg class="flex flex-col flex-1 p-4">
|
|
2848
|
+
<div class="motion-safe:animate-enter-liquid [animation-delay:80ms] flex flex-col flex-1">
|
|
2849
|
+
<div class="flex items-center justify-between cursor-pointer shrink-0 pr-2" (click)="expanded.set(!expanded())">
|
|
2741
2850
|
<div class="flex items-center gap-3">
|
|
2742
2851
|
<div class="w-[34px] h-[34px] rounded-[10px] flex items-center justify-center shrink-0">
|
|
2743
|
-
<i class="pi pi-sparkles text-
|
|
2852
|
+
<i class="pi pi-sparkles text-ai-600 dark:text-ai-300"></i>
|
|
2744
2853
|
</div>
|
|
2745
2854
|
<div class="flex flex-col">
|
|
2746
2855
|
<h4 class="title-h4 text-left text-deepsea-500 dark:text-surface-0">{{ title() }}</h4>
|
|
2747
2856
|
<span class="text-midnight-700 dark:text-surface-100 text-sm font-medium leading-tight">{{ insights().length }} insights available for your review</span>
|
|
2748
2857
|
</div>
|
|
2749
2858
|
</div>
|
|
2750
|
-
<
|
|
2751
|
-
<i class="pi text-xs text-darkblue-500 dark:text-surface-0" [ngClass]="expanded() ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
|
|
2752
|
-
</button>
|
|
2859
|
+
<i class="pi text-sm text-darkblue-500 dark:text-surface-0" [ngClass]="expanded() ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
|
|
2753
2860
|
</div>
|
|
2754
2861
|
|
|
2755
2862
|
<div class="expand-body" [class.expand-body--open]="expanded()">
|
|
2756
2863
|
<div class="expand-body__inner">
|
|
2757
|
-
<div class="flex flex-col gap-4 mt-4
|
|
2864
|
+
<div class="flex flex-col gap-4 mt-4">
|
|
2758
2865
|
<div class="bg-white/60 dark:bg-surface-800/60 border border-white dark:border-surface-700 rounded-[14px] shadow-sm flex items-center gap-4 px-4 py-2.5 shrink-0">
|
|
2759
2866
|
<i class="pi pi-search text-surface-500 dark:text-surface-300 text-sm"></i>
|
|
2760
2867
|
<input
|
|
@@ -2766,14 +2873,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2766
2873
|
/>
|
|
2767
2874
|
</div>
|
|
2768
2875
|
|
|
2769
|
-
<div class="flex flex-col gap-3
|
|
2876
|
+
<div class="flex flex-col gap-3">
|
|
2770
2877
|
@for (insight of paginatedInsights(); track insight.id) {
|
|
2771
2878
|
<div class="bg-white/70 dark:bg-surface-800/70 border border-white/50 dark:border-surface-700/50 rounded-[14px] shadow-sm p-4 flex gap-3 items-start shrink-0">
|
|
2772
2879
|
<i class="pi mt-0.5" [ngClass]="[insight.icon, insight.iconColor]"></i>
|
|
2773
2880
|
<div class="flex flex-col gap-2 flex-1 min-w-0">
|
|
2774
2881
|
<div class="flex flex-col gap-1">
|
|
2775
2882
|
<span class="text-midnight-500 dark:text-surface-0 text-sm font-bold leading-[21px]">{{ insight.title }}</span>
|
|
2776
|
-
<p class="text-
|
|
2883
|
+
<p class="text-midnight-400 dark:text-surface-300 text-sm leading-normal">{{ insight.description }}</p>
|
|
2777
2884
|
</div>
|
|
2778
2885
|
<button
|
|
2779
2886
|
class="flex items-center gap-1.5 text-darkblue-500 dark:text-primary-400 text-sm font-semibold cursor-pointer hover:underline bg-transparent border-none p-0 w-fit"
|
|
@@ -2794,8 +2901,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2794
2901
|
[first]="first()"
|
|
2795
2902
|
(onPageChange)="page.set($event.page ?? 0)"
|
|
2796
2903
|
[pageLinkSize]="3"
|
|
2797
|
-
styleClass="w-full
|
|
2798
|
-
[pt]="{ root: { class: '
|
|
2904
|
+
styleClass="w-full"
|
|
2905
|
+
[pt]="{ root: { class: 'justify-center' } }"
|
|
2799
2906
|
/>
|
|
2800
2907
|
</div>
|
|
2801
2908
|
</div>
|
|
@@ -2806,6 +2913,153 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2806
2913
|
`, styles: [":host{display:flex}\n"] }]
|
|
2807
2914
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], insights: [{ type: i0.Input, args: [{ isSignal: true, alias: "insights", required: true }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }] } });
|
|
2808
2915
|
|
|
2916
|
+
class CompletionStepsComponent {
|
|
2917
|
+
title = input('Completion Steps', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
2918
|
+
steps = input([], ...(ngDevMode ? [{ debugName: "steps" }] : []));
|
|
2919
|
+
mandatory = input({ filled: 0, total: 0 }, ...(ngDevMode ? [{ debugName: "mandatory" }] : []));
|
|
2920
|
+
optional = input({ filled: 0, total: 0 }, ...(ngDevMode ? [{ debugName: "optional" }] : []));
|
|
2921
|
+
totalRecords = input(0, ...(ngDevMode ? [{ debugName: "totalRecords" }] : []));
|
|
2922
|
+
interactive = input(false, ...(ngDevMode ? [{ debugName: "interactive" }] : []));
|
|
2923
|
+
emptyTitle = input('No progress tracked yet', ...(ngDevMode ? [{ debugName: "emptyTitle" }] : []));
|
|
2924
|
+
emptyDescription = input('Progress is calculated automatically as you fill in the opportunity sections. Each dot represents a required or optional field — mandatory fields (bordered red) must be completed before submission.', ...(ngDevMode ? [{ debugName: "emptyDescription" }] : []));
|
|
2925
|
+
stepClick = output();
|
|
2926
|
+
dotStyles = {
|
|
2927
|
+
mandatoryFilled: { bg: 'bg-green-200 dark:bg-green-700', text: 'text-green-800 dark:text-green-50', icon: 'pi', iconClass: 'pi-check' },
|
|
2928
|
+
optionalFilled: { bg: 'bg-blue-200 dark:bg-blue-700', text: 'text-blue-800 dark:text-blue-50', icon: 'material', iconClass: 'info_i' },
|
|
2929
|
+
mandatoryMissing: { bg: 'bg-transparent border-2 border-red-400 dark:border-red-500', text: 'text-red-500 dark:text-red-400', icon: 'pi', iconClass: 'pi-plus' },
|
|
2930
|
+
optionalMissing: { bg: 'bg-transparent border-2 border-surface-300 dark:border-surface-600', text: 'text-surface-500 dark:text-surface-400', icon: 'material', iconClass: 'info_i' }
|
|
2931
|
+
};
|
|
2932
|
+
filledTotal = computed(() => this.mandatory().filled + this.optional().filled, ...(ngDevMode ? [{ debugName: "filledTotal" }] : []));
|
|
2933
|
+
empty = computed(() => this.filledTotal() === 0, ...(ngDevMode ? [{ debugName: "empty" }] : []));
|
|
2934
|
+
legendMandatoryBg = computed(() => this.mandatory().filled > 0 ? this.dotStyles.mandatoryFilled.bg : this.dotStyles.mandatoryMissing.bg, ...(ngDevMode ? [{ debugName: "legendMandatoryBg" }] : []));
|
|
2935
|
+
legendOptionalBg = computed(() => this.optional().filled > 0 ? this.dotStyles.optionalFilled.bg : this.dotStyles.optionalMissing.bg, ...(ngDevMode ? [{ debugName: "legendOptionalBg" }] : []));
|
|
2936
|
+
getDotStyle(step) {
|
|
2937
|
+
if (step.filled)
|
|
2938
|
+
return step.type === 'mandatory' ? this.dotStyles.mandatoryFilled : this.dotStyles.optionalFilled;
|
|
2939
|
+
return step.type === 'mandatory' ? this.dotStyles.mandatoryMissing : this.dotStyles.optionalMissing;
|
|
2940
|
+
}
|
|
2941
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: CompletionStepsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2942
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: CompletionStepsComponent, isStandalone: true, selector: "ux-completion-steps", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: false, transformFunction: null }, mandatory: { classPropertyName: "mandatory", publicName: "mandatory", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, totalRecords: { classPropertyName: "totalRecords", publicName: "totalRecords", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, emptyTitle: { classPropertyName: "emptyTitle", publicName: "emptyTitle", isSignal: true, isRequired: false, transformFunction: null }, emptyDescription: { classPropertyName: "emptyDescription", publicName: "emptyDescription", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { stepClick: "stepClick" }, host: { classAttribute: "block" }, ngImport: i0, template: `
|
|
2943
|
+
<div class="card flex flex-col gap-4">
|
|
2944
|
+
<div class="flex items-center justify-between">
|
|
2945
|
+
<div class="flex items-center gap-3">
|
|
2946
|
+
<div class="flex flex-col">
|
|
2947
|
+
<span class="text-xs font-semibold text-surface-600 dark:text-surface-300 uppercase tracking-wide">{{ title() }}</span>
|
|
2948
|
+
</div>
|
|
2949
|
+
</div>
|
|
2950
|
+
<span class="text-2xl font-bold" [class]="filledTotal() > 0 ? 'text-surface-900 dark:text-surface-0' : 'text-surface-500 dark:text-surface-400'">{{ filledTotal() }}/{{ totalRecords() }}</span>
|
|
2951
|
+
</div>
|
|
2952
|
+
|
|
2953
|
+
<div class="flex items-center gap-1 flex-wrap">
|
|
2954
|
+
@for (step of steps(); track $index) {
|
|
2955
|
+
<span class="inline-flex items-center justify-center w-6 h-6 rounded-full"
|
|
2956
|
+
[class.cursor-pointer]="interactive()"
|
|
2957
|
+
[class]="getDotStyle(step).bg"
|
|
2958
|
+
[pTooltip]="step.name + (step.filled ? '' : ' (missing)')" tooltipPosition="top"
|
|
2959
|
+
(click)="interactive() && stepClick.emit($index)">
|
|
2960
|
+
@if (getDotStyle(step).icon === 'pi') {
|
|
2961
|
+
<i class="pi text-[3px]" [class]="getDotStyle(step).iconClass + ' ' + getDotStyle(step).text"></i>
|
|
2962
|
+
} @else if (getDotStyle(step).icon === 'material') {
|
|
2963
|
+
<span class="material-symbols-outlined leading-none" style="font-size:20px;transform:scale(0.9)" [class]="getDotStyle(step).text">{{ getDotStyle(step).iconClass }}</span>
|
|
2964
|
+
} @else {
|
|
2965
|
+
<span class="text-sm font-black leading-none" [class]="getDotStyle(step).text">!</span>
|
|
2966
|
+
}
|
|
2967
|
+
</span>
|
|
2968
|
+
}
|
|
2969
|
+
</div>
|
|
2970
|
+
|
|
2971
|
+
<div class="flex flex-wrap items-center gap-x-6 gap-y-2 mt-1">
|
|
2972
|
+
<div class="flex items-center gap-2">
|
|
2973
|
+
<span class="inline-block w-4 h-4 rounded-full shrink-0" [class]="legendMandatoryBg()"></span>
|
|
2974
|
+
<span class="text-sm text-surface-600 dark:text-surface-300">Mandatory:</span>
|
|
2975
|
+
<span class="text-sm font-semibold text-surface-900 dark:text-surface-0">{{ mandatory().filled }}/{{ mandatory().total }}</span>
|
|
2976
|
+
</div>
|
|
2977
|
+
<div class="flex items-center gap-2">
|
|
2978
|
+
<span class="inline-block w-4 h-4 rounded-full shrink-0" [class]="legendOptionalBg()"></span>
|
|
2979
|
+
<span class="text-sm text-surface-600 dark:text-surface-300">Optional:</span>
|
|
2980
|
+
<span class="text-sm font-semibold text-surface-900 dark:text-surface-0">{{ optional().filled }}/{{ optional().total }}</span>
|
|
2981
|
+
</div>
|
|
2982
|
+
<div class="flex items-center gap-2">
|
|
2983
|
+
<span class="text-sm text-surface-600 dark:text-surface-300">Total:</span>
|
|
2984
|
+
<span class="text-sm font-semibold text-surface-900 dark:text-surface-0">{{ totalRecords() }}</span>
|
|
2985
|
+
</div>
|
|
2986
|
+
</div>
|
|
2987
|
+
|
|
2988
|
+
@if (empty()) {
|
|
2989
|
+
<div class="empty-state">
|
|
2990
|
+
<i class="pi pi-chart-bar text-3xl text-surface-500 dark:text-surface-400"></i>
|
|
2991
|
+
<span class="empty-state-title">{{ emptyTitle() }}</span>
|
|
2992
|
+
<span class="empty-state-desc">{{ emptyDescription() }}</span>
|
|
2993
|
+
</div>
|
|
2994
|
+
}
|
|
2995
|
+
</div>
|
|
2996
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3$3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2997
|
+
}
|
|
2998
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: CompletionStepsComponent, decorators: [{
|
|
2999
|
+
type: Component,
|
|
3000
|
+
args: [{
|
|
3001
|
+
selector: 'ux-completion-steps',
|
|
3002
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3003
|
+
imports: [TooltipModule],
|
|
3004
|
+
host: { class: 'block' },
|
|
3005
|
+
template: `
|
|
3006
|
+
<div class="card flex flex-col gap-4">
|
|
3007
|
+
<div class="flex items-center justify-between">
|
|
3008
|
+
<div class="flex items-center gap-3">
|
|
3009
|
+
<div class="flex flex-col">
|
|
3010
|
+
<span class="text-xs font-semibold text-surface-600 dark:text-surface-300 uppercase tracking-wide">{{ title() }}</span>
|
|
3011
|
+
</div>
|
|
3012
|
+
</div>
|
|
3013
|
+
<span class="text-2xl font-bold" [class]="filledTotal() > 0 ? 'text-surface-900 dark:text-surface-0' : 'text-surface-500 dark:text-surface-400'">{{ filledTotal() }}/{{ totalRecords() }}</span>
|
|
3014
|
+
</div>
|
|
3015
|
+
|
|
3016
|
+
<div class="flex items-center gap-1 flex-wrap">
|
|
3017
|
+
@for (step of steps(); track $index) {
|
|
3018
|
+
<span class="inline-flex items-center justify-center w-6 h-6 rounded-full"
|
|
3019
|
+
[class.cursor-pointer]="interactive()"
|
|
3020
|
+
[class]="getDotStyle(step).bg"
|
|
3021
|
+
[pTooltip]="step.name + (step.filled ? '' : ' (missing)')" tooltipPosition="top"
|
|
3022
|
+
(click)="interactive() && stepClick.emit($index)">
|
|
3023
|
+
@if (getDotStyle(step).icon === 'pi') {
|
|
3024
|
+
<i class="pi text-[3px]" [class]="getDotStyle(step).iconClass + ' ' + getDotStyle(step).text"></i>
|
|
3025
|
+
} @else if (getDotStyle(step).icon === 'material') {
|
|
3026
|
+
<span class="material-symbols-outlined leading-none" style="font-size:20px;transform:scale(0.9)" [class]="getDotStyle(step).text">{{ getDotStyle(step).iconClass }}</span>
|
|
3027
|
+
} @else {
|
|
3028
|
+
<span class="text-sm font-black leading-none" [class]="getDotStyle(step).text">!</span>
|
|
3029
|
+
}
|
|
3030
|
+
</span>
|
|
3031
|
+
}
|
|
3032
|
+
</div>
|
|
3033
|
+
|
|
3034
|
+
<div class="flex flex-wrap items-center gap-x-6 gap-y-2 mt-1">
|
|
3035
|
+
<div class="flex items-center gap-2">
|
|
3036
|
+
<span class="inline-block w-4 h-4 rounded-full shrink-0" [class]="legendMandatoryBg()"></span>
|
|
3037
|
+
<span class="text-sm text-surface-600 dark:text-surface-300">Mandatory:</span>
|
|
3038
|
+
<span class="text-sm font-semibold text-surface-900 dark:text-surface-0">{{ mandatory().filled }}/{{ mandatory().total }}</span>
|
|
3039
|
+
</div>
|
|
3040
|
+
<div class="flex items-center gap-2">
|
|
3041
|
+
<span class="inline-block w-4 h-4 rounded-full shrink-0" [class]="legendOptionalBg()"></span>
|
|
3042
|
+
<span class="text-sm text-surface-600 dark:text-surface-300">Optional:</span>
|
|
3043
|
+
<span class="text-sm font-semibold text-surface-900 dark:text-surface-0">{{ optional().filled }}/{{ optional().total }}</span>
|
|
3044
|
+
</div>
|
|
3045
|
+
<div class="flex items-center gap-2">
|
|
3046
|
+
<span class="text-sm text-surface-600 dark:text-surface-300">Total:</span>
|
|
3047
|
+
<span class="text-sm font-semibold text-surface-900 dark:text-surface-0">{{ totalRecords() }}</span>
|
|
3048
|
+
</div>
|
|
3049
|
+
</div>
|
|
3050
|
+
|
|
3051
|
+
@if (empty()) {
|
|
3052
|
+
<div class="empty-state">
|
|
3053
|
+
<i class="pi pi-chart-bar text-3xl text-surface-500 dark:text-surface-400"></i>
|
|
3054
|
+
<span class="empty-state-title">{{ emptyTitle() }}</span>
|
|
3055
|
+
<span class="empty-state-desc">{{ emptyDescription() }}</span>
|
|
3056
|
+
</div>
|
|
3057
|
+
}
|
|
3058
|
+
</div>
|
|
3059
|
+
`
|
|
3060
|
+
}]
|
|
3061
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: false }] }], mandatory: [{ type: i0.Input, args: [{ isSignal: true, alias: "mandatory", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], totalRecords: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalRecords", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], emptyTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyTitle", required: false }] }], emptyDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyDescription", required: false }] }], stepClick: [{ type: i0.Output, args: ["stepClick"] }] } });
|
|
3062
|
+
|
|
2809
3063
|
/**
|
|
2810
3064
|
* Structural directive that marks a template as content for a specific tab
|
|
2811
3065
|
* inside `<ux-detail-layout>`.
|
|
@@ -2843,12 +3097,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2843
3097
|
* <ng-template uxDetailTab="scope">...tab 2...</ng-template>
|
|
2844
3098
|
*
|
|
2845
3099
|
* <ng-container ux-detail-sidebar>
|
|
3100
|
+
* <!-- Use ng-container so children become direct children of the
|
|
3101
|
+
* library's flex container and inherit the gap spacing. -->
|
|
2846
3102
|
* ...right sidebar (AI card, documents, etc.)...
|
|
2847
3103
|
* </ng-container>
|
|
2848
3104
|
*
|
|
2849
|
-
* <ng-container ux-detail-footer>
|
|
2850
|
-
* ...audit metadata row...
|
|
2851
|
-
* </ng-container>
|
|
2852
3105
|
* </ux-detail-layout>
|
|
2853
3106
|
* ```
|
|
2854
3107
|
*/
|
|
@@ -2857,8 +3110,23 @@ class DetailLayoutComponent {
|
|
|
2857
3110
|
tabs = input.required(...(ngDevMode ? [{ debugName: "tabs" }] : []));
|
|
2858
3111
|
/** Currently active tab value (two-way bindable). */
|
|
2859
3112
|
activeTab = model('', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
|
|
3113
|
+
/** Options for the mobile tab dropdown. */
|
|
3114
|
+
tabOptions = computed(() => this.tabs().map(t => ({ label: t.label, value: t.value })), ...(ngDevMode ? [{ debugName: "tabOptions" }] : []));
|
|
3115
|
+
/** True when there is only a single tab, making the tab bar redundant. */
|
|
3116
|
+
singleTab = computed(() => this.tabs().length <= 1, ...(ngDevMode ? [{ debugName: "singleTab" }] : []));
|
|
3117
|
+
/** True when viewport is below the lg breakpoint (1024px). */
|
|
3118
|
+
isMobile = signal(false, ...(ngDevMode ? [{ debugName: "isMobile" }] : []));
|
|
2860
3119
|
/** True once the scrollable body has been scrolled past the threshold. */
|
|
2861
3120
|
scrolled = signal(false, ...(ngDevMode ? [{ debugName: "scrolled" }] : []));
|
|
3121
|
+
constructor() {
|
|
3122
|
+
if (isPlatformBrowser(inject(PLATFORM_ID))) {
|
|
3123
|
+
const mql = window.matchMedia('(max-width: 1023px)');
|
|
3124
|
+
this.isMobile.set(mql.matches);
|
|
3125
|
+
const handler = (e) => this.isMobile.set(e.matches);
|
|
3126
|
+
mql.addEventListener('change', handler);
|
|
3127
|
+
inject(DestroyRef).onDestroy(() => mql.removeEventListener('change', handler));
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
2862
3130
|
/** Tab content templates provided by the consumer. */
|
|
2863
3131
|
tabTemplates;
|
|
2864
3132
|
getTabTemplate(value) {
|
|
@@ -2870,8 +3138,8 @@ class DetailLayoutComponent {
|
|
|
2870
3138
|
this.scrolled.set(el.scrollTop > 10);
|
|
2871
3139
|
}
|
|
2872
3140
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DetailLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2873
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: DetailLayoutComponent, isStandalone: true, selector: "ux-detail-layout", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeTab: "activeTabChange" }, host: { classAttribute: "ux-detail-layout
|
|
2874
|
-
<div class="flex flex-col
|
|
3141
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: DetailLayoutComponent, isStandalone: true, selector: "ux-detail-layout", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeTab: "activeTabChange" }, host: { classAttribute: "ux-detail-layout" }, queries: [{ propertyName: "tabTemplates", predicate: DetailTabDirective }], ngImport: i0, template: `
|
|
3142
|
+
<div class="flex flex-col flex-1 min-h-0">
|
|
2875
3143
|
|
|
2876
3144
|
<!-- Sticky header (projected) -->
|
|
2877
3145
|
<div class="ux-dl__header flex-shrink-0 z-10">
|
|
@@ -2883,15 +3151,32 @@ class DetailLayoutComponent {
|
|
|
2883
3151
|
</div>
|
|
2884
3152
|
</div>
|
|
2885
3153
|
|
|
2886
|
-
<!--
|
|
2887
|
-
<
|
|
2888
|
-
|
|
3154
|
+
<!-- p-tabs wraps tablist + scrollable panels for state binding -->
|
|
3155
|
+
<p-tabs class="flex flex-col flex-1 min-h-0" [value]="activeTab()" (valueChange)="activeTab.set($event + '')">
|
|
3156
|
+
|
|
3157
|
+
@if (!singleTab()) {
|
|
3158
|
+
<!-- Mobile: dropdown selector -->
|
|
3159
|
+
@if (isMobile()) {
|
|
3160
|
+
<div class="ux-dl__mobile-tabs">
|
|
3161
|
+
<p-select
|
|
3162
|
+
[options]="tabOptions()"
|
|
3163
|
+
[ngModel]="activeTab()"
|
|
3164
|
+
(ngModelChange)="activeTab.set($event)"
|
|
3165
|
+
optionLabel="label"
|
|
3166
|
+
optionValue="value"
|
|
3167
|
+
styleClass="w-full ux-dl__mobile-select"
|
|
3168
|
+
/>
|
|
3169
|
+
</div>
|
|
3170
|
+
}
|
|
2889
3171
|
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
3172
|
+
<!-- Desktop: horizontal tab bar (outside scroll → stays fixed below header) -->
|
|
3173
|
+
<p-tablist
|
|
3174
|
+
class="flex-shrink-0 ux-dl__tablist"
|
|
3175
|
+
[style.display]="isMobile() ? 'none' : null"
|
|
3176
|
+
[pt]="{ content: { class: 'w-full' }, tabList: { class: 'w-full pl-8 p-0' } }"
|
|
3177
|
+
>
|
|
2893
3178
|
@for (tab of tabs(); track tab.value) {
|
|
2894
|
-
<p-tab [value]="tab.value">
|
|
3179
|
+
<p-tab [value]="tab.value" [pt]="{ root: { class: 'flex-1 justify-center' } }">
|
|
2895
3180
|
@if (tab.icon) {
|
|
2896
3181
|
<i [class]="tab.icon" class="mr-2 text-sm"></i>
|
|
2897
3182
|
}
|
|
@@ -2899,12 +3184,17 @@ class DetailLayoutComponent {
|
|
|
2899
3184
|
</p-tab>
|
|
2900
3185
|
}
|
|
2901
3186
|
</p-tablist>
|
|
3187
|
+
}
|
|
3188
|
+
|
|
3189
|
+
<!-- Scrollable body (only content scrolls, tabs stay above) -->
|
|
3190
|
+
<div class="flex flex-col flex-1 min-h-0 overflow-y-auto overflow-x-hidden ux-dl__scroll"
|
|
3191
|
+
(scroll)="onScroll($event)">
|
|
2902
3192
|
|
|
2903
|
-
<!-- Content + Sidebar row
|
|
2904
|
-
<div class="flex flex-col lg:flex-row items-start gap-6 w-full py-4
|
|
3193
|
+
<!-- Content + Sidebar row -->
|
|
3194
|
+
<div class="flex flex-col lg:flex-row items-start gap-6 w-full py-4 lg:py-6">
|
|
2905
3195
|
|
|
2906
3196
|
<!-- Main column: tab panels -->
|
|
2907
|
-
<div class="flex-1 min-w-0 flex flex-col gap-6">
|
|
3197
|
+
<div class="w-full flex-1 min-w-0 flex flex-col gap-6">
|
|
2908
3198
|
<p-tabpanels>
|
|
2909
3199
|
@for (tab of tabs(); track tab.value) {
|
|
2910
3200
|
<p-tabpanel [value]="tab.value">
|
|
@@ -2916,27 +3206,27 @@ class DetailLayoutComponent {
|
|
|
2916
3206
|
</p-tabpanel>
|
|
2917
3207
|
}
|
|
2918
3208
|
</p-tabpanels>
|
|
2919
|
-
|
|
2920
|
-
<!-- Footer below tab content -->
|
|
2921
|
-
<ng-content select="[ux-detail-footer]" />
|
|
2922
3209
|
</div>
|
|
2923
3210
|
|
|
2924
3211
|
<!-- Sidebar -->
|
|
2925
|
-
<aside class="w-full lg:w-[380px] shrink-0 flex flex-col lg:sticky lg:top-4 lg:self-start pb-8">
|
|
3212
|
+
<aside class="w-full lg:w-[380px] shrink-0 flex flex-col lg:sticky lg:top-4 lg:self-start lg:pb-8">
|
|
2926
3213
|
<div class="ux-dl__sidebar-inner w-full">
|
|
2927
3214
|
<ng-content select="[ux-detail-sidebar]" />
|
|
2928
3215
|
</div>
|
|
2929
3216
|
</aside>
|
|
2930
3217
|
</div>
|
|
2931
|
-
|
|
2932
|
-
|
|
3218
|
+
|
|
3219
|
+
</div>
|
|
3220
|
+
|
|
3221
|
+
</p-tabs>
|
|
3222
|
+
|
|
2933
3223
|
</div>
|
|
2934
|
-
`, isInline: true, styles: [":host{display:
|
|
3224
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0;font-family:var(--p-font-family, \"Noto Sans\", sans-serif);background:transparent;color:var(--p-text-color)}.ux-dl__header{background:transparent}.ux-dl__scroll{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--p-primary-color) 25%,transparent) color-mix(in srgb,var(--p-surface-500) 8%,transparent)}.ux-dl__scroll::-webkit-scrollbar{width:10px;height:10px}.ux-dl__scroll::-webkit-scrollbar-track{background:color-mix(in srgb,var(--p-surface-500) 8%,transparent);border-radius:var(--p-content-border-radius, .375rem)}.ux-dl__scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--p-primary-color) 25%,transparent);border-radius:var(--p-content-border-radius, .375rem)}.ux-dl__scroll::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--p-primary-color) 45%,transparent)}.ux-dl__sidebar-inner{display:flex;flex-direction:column;gap:1.5rem}.ux-dl__header-meta{overflow:hidden;max-height:80px;opacity:1;transition:max-height .25s ease-out,opacity .2s ease-out}.ux-dl__header-meta--hidden{max-height:0;opacity:0}.ux-dl__tablist{display:flex;overflow:hidden;background:var(--p-surface-950);padding-inline:.75rem}@media screen and (min-width:640px){.ux-dl__tablist{padding-inline:1rem}}@media screen and (min-width:1024px){.ux-dl__tablist{padding-inline:1.5rem}}.ux-dl__mobile-tabs{position:sticky;top:0;z-index:5}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TabsModule }, { kind: "component", type: i4$3.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i4$3.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i4$3.TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "component", type: i4$3.TabList, selector: "p-tablist" }, { kind: "component", type: i4$3.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2935
3225
|
}
|
|
2936
3226
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DetailLayoutComponent, decorators: [{
|
|
2937
3227
|
type: Component,
|
|
2938
|
-
args: [{ selector: 'ux-detail-layout', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, TabsModule], host: { class: 'ux-detail-layout
|
|
2939
|
-
<div class="flex flex-col
|
|
3228
|
+
args: [{ selector: 'ux-detail-layout', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FormsModule, SelectModule, TabsModule], host: { class: 'ux-detail-layout' }, template: `
|
|
3229
|
+
<div class="flex flex-col flex-1 min-h-0">
|
|
2940
3230
|
|
|
2941
3231
|
<!-- Sticky header (projected) -->
|
|
2942
3232
|
<div class="ux-dl__header flex-shrink-0 z-10">
|
|
@@ -2948,15 +3238,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2948
3238
|
</div>
|
|
2949
3239
|
</div>
|
|
2950
3240
|
|
|
2951
|
-
<!--
|
|
2952
|
-
<
|
|
2953
|
-
|
|
3241
|
+
<!-- p-tabs wraps tablist + scrollable panels for state binding -->
|
|
3242
|
+
<p-tabs class="flex flex-col flex-1 min-h-0" [value]="activeTab()" (valueChange)="activeTab.set($event + '')">
|
|
3243
|
+
|
|
3244
|
+
@if (!singleTab()) {
|
|
3245
|
+
<!-- Mobile: dropdown selector -->
|
|
3246
|
+
@if (isMobile()) {
|
|
3247
|
+
<div class="ux-dl__mobile-tabs">
|
|
3248
|
+
<p-select
|
|
3249
|
+
[options]="tabOptions()"
|
|
3250
|
+
[ngModel]="activeTab()"
|
|
3251
|
+
(ngModelChange)="activeTab.set($event)"
|
|
3252
|
+
optionLabel="label"
|
|
3253
|
+
optionValue="value"
|
|
3254
|
+
styleClass="w-full ux-dl__mobile-select"
|
|
3255
|
+
/>
|
|
3256
|
+
</div>
|
|
3257
|
+
}
|
|
2954
3258
|
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
3259
|
+
<!-- Desktop: horizontal tab bar (outside scroll → stays fixed below header) -->
|
|
3260
|
+
<p-tablist
|
|
3261
|
+
class="flex-shrink-0 ux-dl__tablist"
|
|
3262
|
+
[style.display]="isMobile() ? 'none' : null"
|
|
3263
|
+
[pt]="{ content: { class: 'w-full' }, tabList: { class: 'w-full pl-8 p-0' } }"
|
|
3264
|
+
>
|
|
2958
3265
|
@for (tab of tabs(); track tab.value) {
|
|
2959
|
-
<p-tab [value]="tab.value">
|
|
3266
|
+
<p-tab [value]="tab.value" [pt]="{ root: { class: 'flex-1 justify-center' } }">
|
|
2960
3267
|
@if (tab.icon) {
|
|
2961
3268
|
<i [class]="tab.icon" class="mr-2 text-sm"></i>
|
|
2962
3269
|
}
|
|
@@ -2964,12 +3271,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2964
3271
|
</p-tab>
|
|
2965
3272
|
}
|
|
2966
3273
|
</p-tablist>
|
|
3274
|
+
}
|
|
3275
|
+
|
|
3276
|
+
<!-- Scrollable body (only content scrolls, tabs stay above) -->
|
|
3277
|
+
<div class="flex flex-col flex-1 min-h-0 overflow-y-auto overflow-x-hidden ux-dl__scroll"
|
|
3278
|
+
(scroll)="onScroll($event)">
|
|
2967
3279
|
|
|
2968
|
-
<!-- Content + Sidebar row
|
|
2969
|
-
<div class="flex flex-col lg:flex-row items-start gap-6 w-full py-4
|
|
3280
|
+
<!-- Content + Sidebar row -->
|
|
3281
|
+
<div class="flex flex-col lg:flex-row items-start gap-6 w-full py-4 lg:py-6">
|
|
2970
3282
|
|
|
2971
3283
|
<!-- Main column: tab panels -->
|
|
2972
|
-
<div class="flex-1 min-w-0 flex flex-col gap-6">
|
|
3284
|
+
<div class="w-full flex-1 min-w-0 flex flex-col gap-6">
|
|
2973
3285
|
<p-tabpanels>
|
|
2974
3286
|
@for (tab of tabs(); track tab.value) {
|
|
2975
3287
|
<p-tabpanel [value]="tab.value">
|
|
@@ -2981,27 +3293,658 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
2981
3293
|
</p-tabpanel>
|
|
2982
3294
|
}
|
|
2983
3295
|
</p-tabpanels>
|
|
2984
|
-
|
|
2985
|
-
<!-- Footer below tab content -->
|
|
2986
|
-
<ng-content select="[ux-detail-footer]" />
|
|
2987
3296
|
</div>
|
|
2988
3297
|
|
|
2989
3298
|
<!-- Sidebar -->
|
|
2990
|
-
<aside class="w-full lg:w-[380px] shrink-0 flex flex-col lg:sticky lg:top-4 lg:self-start pb-8">
|
|
3299
|
+
<aside class="w-full lg:w-[380px] shrink-0 flex flex-col lg:sticky lg:top-4 lg:self-start lg:pb-8">
|
|
2991
3300
|
<div class="ux-dl__sidebar-inner w-full">
|
|
2992
3301
|
<ng-content select="[ux-detail-sidebar]" />
|
|
2993
3302
|
</div>
|
|
2994
3303
|
</aside>
|
|
2995
3304
|
</div>
|
|
2996
|
-
|
|
2997
|
-
|
|
3305
|
+
|
|
3306
|
+
</div>
|
|
3307
|
+
|
|
3308
|
+
</p-tabs>
|
|
3309
|
+
|
|
2998
3310
|
</div>
|
|
2999
|
-
`, styles: [":host{display:
|
|
3000
|
-
}], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: false }] }, { type: i0.Output, args: ["activeTabChange"] }], tabTemplates: [{
|
|
3311
|
+
`, styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0;font-family:var(--p-font-family, \"Noto Sans\", sans-serif);background:transparent;color:var(--p-text-color)}.ux-dl__header{background:transparent}.ux-dl__scroll{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--p-primary-color) 25%,transparent) color-mix(in srgb,var(--p-surface-500) 8%,transparent)}.ux-dl__scroll::-webkit-scrollbar{width:10px;height:10px}.ux-dl__scroll::-webkit-scrollbar-track{background:color-mix(in srgb,var(--p-surface-500) 8%,transparent);border-radius:var(--p-content-border-radius, .375rem)}.ux-dl__scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--p-primary-color) 25%,transparent);border-radius:var(--p-content-border-radius, .375rem)}.ux-dl__scroll::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--p-primary-color) 45%,transparent)}.ux-dl__sidebar-inner{display:flex;flex-direction:column;gap:1.5rem}.ux-dl__header-meta{overflow:hidden;max-height:80px;opacity:1;transition:max-height .25s ease-out,opacity .2s ease-out}.ux-dl__header-meta--hidden{max-height:0;opacity:0}.ux-dl__tablist{display:flex;overflow:hidden;background:var(--p-surface-950);padding-inline:.75rem}@media screen and (min-width:640px){.ux-dl__tablist{padding-inline:1rem}}@media screen and (min-width:1024px){.ux-dl__tablist{padding-inline:1.5rem}}.ux-dl__mobile-tabs{position:sticky;top:0;z-index:5}\n"] }]
|
|
3312
|
+
}], ctorParameters: () => [], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: false }] }, { type: i0.Output, args: ["activeTabChange"] }], tabTemplates: [{
|
|
3001
3313
|
type: ContentChildren,
|
|
3002
3314
|
args: [DetailTabDirective]
|
|
3003
3315
|
}] } });
|
|
3004
3316
|
|
|
3317
|
+
/**
|
|
3318
|
+
* Horizontal row of pill-shaped sub-tab buttons. Styling aligns with sidebar menu item
|
|
3319
|
+
* hover/active tokens (`--d-menuitem-*`).
|
|
3320
|
+
*/
|
|
3321
|
+
class PillTabsComponent {
|
|
3322
|
+
items = input.required(...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
3323
|
+
activeValue = model('', ...(ngDevMode ? [{ debugName: "activeValue" }] : []));
|
|
3324
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: PillTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3325
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: PillTabsComponent, isStandalone: true, selector: "ux-pill-tabs", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, activeValue: { classPropertyName: "activeValue", publicName: "activeValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeValue: "activeValueChange" }, host: { classAttribute: "ux-pill-tabs block" }, ngImport: i0, template: `
|
|
3326
|
+
<div class="ux-pill-tabs__row" role="tablist">
|
|
3327
|
+
@for (item of items(); track item.value) {
|
|
3328
|
+
<button
|
|
3329
|
+
type="button"
|
|
3330
|
+
class="ux-pill-tabs__btn"
|
|
3331
|
+
role="tab"
|
|
3332
|
+
[attr.aria-selected]="activeValue() === item.value"
|
|
3333
|
+
[class.ux-pill-tabs__btn--active]="activeValue() === item.value"
|
|
3334
|
+
(click)="activeValue.set(item.value)"
|
|
3335
|
+
>
|
|
3336
|
+
{{ item.label }}
|
|
3337
|
+
</button>
|
|
3338
|
+
}
|
|
3339
|
+
</div>
|
|
3340
|
+
`, isInline: true, styles: [".ux-pill-tabs__row{display:flex;flex-wrap:wrap;gap:.5rem}.ux-pill-tabs__btn{border-radius:9999px;padding:.375rem .875rem;font-size:var(--p-font-size, .875rem);font-weight:600;font-family:inherit;cursor:pointer;transition:all .15s ease;border:1px solid var(--p-primary-800);background:transparent;color:var(--p-text-muted-color)}:host-context(.app-dark) .ux-pill-tabs__btn:not(.ux-pill-tabs__btn--active){border-color:var(--p-surface-700)}.ux-pill-tabs__btn:hover:not(.ux-pill-tabs__btn--active){background:var(--d-menuitem-hover-bg);color:var(--p-primary-950)}:host-context(.app-dark) .ux-pill-tabs__btn:hover:not(.ux-pill-tabs__btn--active){color:var(--p-primary-200)}.ux-pill-tabs__btn--active{background:var(--p-primary-200);border-color:transparent;color:var(--p-primary-950)}:host-context(.app-dark) .ux-pill-tabs__btn--active{color:var(--p-primary-950)}.ux-pill-tabs__btn:focus{outline:none;box-shadow:none}.ux-pill-tabs__btn:focus-visible{outline:none;box-shadow:var(--d-menuitem-focus-shadow)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3341
|
+
}
|
|
3342
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: PillTabsComponent, decorators: [{
|
|
3343
|
+
type: Component,
|
|
3344
|
+
args: [{ selector: 'ux-pill-tabs', changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'ux-pill-tabs block' }, template: `
|
|
3345
|
+
<div class="ux-pill-tabs__row" role="tablist">
|
|
3346
|
+
@for (item of items(); track item.value) {
|
|
3347
|
+
<button
|
|
3348
|
+
type="button"
|
|
3349
|
+
class="ux-pill-tabs__btn"
|
|
3350
|
+
role="tab"
|
|
3351
|
+
[attr.aria-selected]="activeValue() === item.value"
|
|
3352
|
+
[class.ux-pill-tabs__btn--active]="activeValue() === item.value"
|
|
3353
|
+
(click)="activeValue.set(item.value)"
|
|
3354
|
+
>
|
|
3355
|
+
{{ item.label }}
|
|
3356
|
+
</button>
|
|
3357
|
+
}
|
|
3358
|
+
</div>
|
|
3359
|
+
`, styles: [".ux-pill-tabs__row{display:flex;flex-wrap:wrap;gap:.5rem}.ux-pill-tabs__btn{border-radius:9999px;padding:.375rem .875rem;font-size:var(--p-font-size, .875rem);font-weight:600;font-family:inherit;cursor:pointer;transition:all .15s ease;border:1px solid var(--p-primary-800);background:transparent;color:var(--p-text-muted-color)}:host-context(.app-dark) .ux-pill-tabs__btn:not(.ux-pill-tabs__btn--active){border-color:var(--p-surface-700)}.ux-pill-tabs__btn:hover:not(.ux-pill-tabs__btn--active){background:var(--d-menuitem-hover-bg);color:var(--p-primary-950)}:host-context(.app-dark) .ux-pill-tabs__btn:hover:not(.ux-pill-tabs__btn--active){color:var(--p-primary-200)}.ux-pill-tabs__btn--active{background:var(--p-primary-200);border-color:transparent;color:var(--p-primary-950)}:host-context(.app-dark) .ux-pill-tabs__btn--active{color:var(--p-primary-950)}.ux-pill-tabs__btn:focus{outline:none;box-shadow:none}.ux-pill-tabs__btn:focus-visible{outline:none;box-shadow:var(--d-menuitem-focus-shadow)}\n"] }]
|
|
3360
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], activeValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeValue", required: false }] }, { type: i0.Output, args: ["activeValueChange"] }] } });
|
|
3361
|
+
|
|
3362
|
+
class DocumentsCardComponent {
|
|
3363
|
+
documents = input([], ...(ngDevMode ? [{ debugName: "documents" }] : []));
|
|
3364
|
+
rows = input(5, ...(ngDevMode ? [{ debugName: "rows" }] : []));
|
|
3365
|
+
expanded = signal(false, ...(ngDevMode ? [{ debugName: "expanded" }] : []));
|
|
3366
|
+
activeFilter = signal('All Files', ...(ngDevMode ? [{ debugName: "activeFilter" }] : []));
|
|
3367
|
+
searchQuery = model('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : []));
|
|
3368
|
+
fileTypes = computed(() => {
|
|
3369
|
+
const types = [...new Set(this.documents().map(d => d.type))];
|
|
3370
|
+
types.sort();
|
|
3371
|
+
return types;
|
|
3372
|
+
}, ...(ngDevMode ? [{ debugName: "fileTypes" }] : []));
|
|
3373
|
+
filterOptions = computed(() => ['All Files', ...this.fileTypes(), 'Other'], ...(ngDevMode ? [{ debugName: "filterOptions" }] : []));
|
|
3374
|
+
pillTabItems = computed(() => this.filterOptions().map(f => ({ value: f, label: f })), ...(ngDevMode ? [{ debugName: "pillTabItems" }] : []));
|
|
3375
|
+
summary = computed(() => {
|
|
3376
|
+
const docs = this.documents();
|
|
3377
|
+
const count = docs.length;
|
|
3378
|
+
if (count === 0)
|
|
3379
|
+
return 'No files attached';
|
|
3380
|
+
const types = this.fileTypes();
|
|
3381
|
+
const fileWord = count === 1 ? 'file' : 'files';
|
|
3382
|
+
if (types.length === 0)
|
|
3383
|
+
return `${count} ${fileWord} attached`;
|
|
3384
|
+
return `${count} ${fileWord} · ${types.join(', ')}`;
|
|
3385
|
+
}, ...(ngDevMode ? [{ debugName: "summary" }] : []));
|
|
3386
|
+
filtered = computed(() => {
|
|
3387
|
+
let docs = this.documents();
|
|
3388
|
+
const query = this.searchQuery().trim().toLowerCase();
|
|
3389
|
+
if (query) {
|
|
3390
|
+
docs = docs.filter(d => d.fileName.toLowerCase().includes(query) || d.owner.toLowerCase().includes(query));
|
|
3391
|
+
}
|
|
3392
|
+
const filter = this.activeFilter();
|
|
3393
|
+
if (filter === 'All Files')
|
|
3394
|
+
return docs;
|
|
3395
|
+
if (filter === 'Other') {
|
|
3396
|
+
const knownTypes = this.fileTypes();
|
|
3397
|
+
return docs.filter(d => !knownTypes.includes(d.type));
|
|
3398
|
+
}
|
|
3399
|
+
return docs.filter(d => d.type === filter);
|
|
3400
|
+
}, ...(ngDevMode ? [{ debugName: "filtered" }] : []));
|
|
3401
|
+
menuItems = [];
|
|
3402
|
+
onMenuToggle(event, _doc, menu) {
|
|
3403
|
+
this.menuItems = [
|
|
3404
|
+
{ label: 'Preview', icon: 'pi pi-eye' },
|
|
3405
|
+
{ label: 'Share', icon: 'pi pi-share-alt' },
|
|
3406
|
+
{ separator: true },
|
|
3407
|
+
{ label: 'Delete', icon: 'pi pi-trash', styleClass: 'text-red-500' }
|
|
3408
|
+
];
|
|
3409
|
+
menu.toggle(event);
|
|
3410
|
+
}
|
|
3411
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DocumentsCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3412
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: DocumentsCardComponent, isStandalone: true, selector: "ux-documents-card", inputs: { documents: { classPropertyName: "documents", publicName: "documents", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, searchQuery: { classPropertyName: "searchQuery", publicName: "searchQuery", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchQuery: "searchQueryChange" }, host: { classAttribute: "ux-documents-card block" }, ngImport: i0, template: `
|
|
3413
|
+
<div class="card flex flex-col overflow-hidden">
|
|
3414
|
+
<p-panel [toggleable]="true" [collapsed]="!expanded()" (collapsedChange)="expanded.set(!$event)" toggler="header">
|
|
3415
|
+
<ng-template #headericons let-collapsed>
|
|
3416
|
+
<i class="pi text-sm text-darkblue-500 dark:text-surface-0" [ngClass]="collapsed ? 'pi-chevron-down' : 'pi-chevron-up'"></i>
|
|
3417
|
+
</ng-template>
|
|
3418
|
+
<ng-template #header>
|
|
3419
|
+
<div class="flex items-center gap-3 flex-1">
|
|
3420
|
+
<div class="w-[34px] h-[34px] rounded-[10px] flex items-center justify-center shrink-0">
|
|
3421
|
+
<i class="pi pi-folder text-deepsea-500 dark:text-surface-0"></i>
|
|
3422
|
+
</div>
|
|
3423
|
+
<div class="flex flex-col">
|
|
3424
|
+
<h4 class="title-h4 text-left text-deepsea-500 dark:text-surface-0">Documents</h4>
|
|
3425
|
+
<span class="text-surface-500 dark:text-surface-300 text-sm font-medium leading-tight">{{ summary() }}</span>
|
|
3426
|
+
</div>
|
|
3427
|
+
</div>
|
|
3428
|
+
</ng-template>
|
|
3429
|
+
<div class="flex flex-col gap-4 pt-4">
|
|
3430
|
+
<ux-pill-tabs [items]="pillTabItems()" [(activeValue)]="activeFilter" />
|
|
3431
|
+
|
|
3432
|
+
<p-iconfield>
|
|
3433
|
+
<p-inputicon class="pi pi-search" />
|
|
3434
|
+
<input pInputText [(ngModel)]="searchQuery" placeholder="Search documents" class="w-full" />
|
|
3435
|
+
</p-iconfield>
|
|
3436
|
+
|
|
3437
|
+
@if (filtered().length > 0) {
|
|
3438
|
+
<p-table
|
|
3439
|
+
[value]="filtered()"
|
|
3440
|
+
[paginator]="true"
|
|
3441
|
+
[rows]="rows()"
|
|
3442
|
+
sortMode="multiple"
|
|
3443
|
+
styleClass="flex flex-col rounded-2xl overflow-hidden [&>[data-pc-section=paginatorcontainer]]:border-0! [&>[data-pc-section=paginatorcontainer]]:mt-auto [&_[data-pc-name=pcpaginator]]:rounded-none!"
|
|
3444
|
+
tableStyleClass="w-full table-fixed"
|
|
3445
|
+
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink"
|
|
3446
|
+
>
|
|
3447
|
+
<ng-template #header>
|
|
3448
|
+
<tr>
|
|
3449
|
+
<th pSortableColumn="fileName" class="w-1/2">File Name <p-sortIcon field="fileName" /></th>
|
|
3450
|
+
<th pSortableColumn="type" class="w-1/4">Type <p-sortIcon field="type" /></th>
|
|
3451
|
+
<th class="w-1/4">Actions</th>
|
|
3452
|
+
</tr>
|
|
3453
|
+
</ng-template>
|
|
3454
|
+
<ng-template #body let-doc>
|
|
3455
|
+
<tr>
|
|
3456
|
+
<td>
|
|
3457
|
+
<div class="flex items-center gap-3 py-1 min-w-0">
|
|
3458
|
+
<i class="pi text-xl text-surface-600 dark:text-surface-300 shrink-0" [ngClass]="doc.icon"></i>
|
|
3459
|
+
<span class="text-surface-700 dark:text-surface-100 text-sm truncate">{{ doc.fileName }}</span>
|
|
3460
|
+
</div>
|
|
3461
|
+
</td>
|
|
3462
|
+
<td>
|
|
3463
|
+
<p-tag [value]="doc.type" styleClass="px-2 py-1" />
|
|
3464
|
+
</td>
|
|
3465
|
+
<td>
|
|
3466
|
+
<div class="flex items-center gap-1">
|
|
3467
|
+
<p-button icon="pi pi-download" [rounded]="true" [text]="true" size="small" severity="secondary" styleClass="cursor-pointer" ariaLabel="Download" />
|
|
3468
|
+
<p-button icon="pi pi-ellipsis-h" [rounded]="true" [text]="true" size="small" severity="secondary" styleClass="cursor-pointer" ariaLabel="More options" (onClick)="onMenuToggle($event, doc, docMenu)" />
|
|
3469
|
+
<p-menu #docMenu [model]="menuItems" [popup]="true" styleClass="w-48" appendTo="body" />
|
|
3470
|
+
</div>
|
|
3471
|
+
</td>
|
|
3472
|
+
</tr>
|
|
3473
|
+
</ng-template>
|
|
3474
|
+
</p-table>
|
|
3475
|
+
} @else {
|
|
3476
|
+
<div class="flex flex-col items-center gap-3 py-8 text-center">
|
|
3477
|
+
<i class="pi pi-folder-open text-3xl text-surface-300 dark:text-surface-500"></i>
|
|
3478
|
+
<span class="text-surface-600 dark:text-surface-300 text-sm">No documents to show</span>
|
|
3479
|
+
</div>
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3482
|
+
<p-fileupload
|
|
3483
|
+
name="documents[]"
|
|
3484
|
+
[multiple]="true"
|
|
3485
|
+
maxFileSize="10000000"
|
|
3486
|
+
mode="advanced"
|
|
3487
|
+
[auto]="false"
|
|
3488
|
+
chooseLabel="Upload File"
|
|
3489
|
+
chooseIcon="pi pi-upload"
|
|
3490
|
+
[showUploadButton]="false"
|
|
3491
|
+
[showCancelButton]="false"
|
|
3492
|
+
[pt]="{ root: { class: 'bg-transparent' }, header: { class: 'bg-transparent' }, content: { class: 'bg-transparent' } }"
|
|
3493
|
+
>
|
|
3494
|
+
<ng-template #header let-chooseCallback="chooseCallback">
|
|
3495
|
+
<div class="flex items-center gap-2 w-full">
|
|
3496
|
+
<p-button icon="pi pi-upload" label="Upload File" (onClick)="chooseCallback()" />
|
|
3497
|
+
<p-button icon="pi pi-link" label="Share Link" [outlined]="true" styleClass="!text-primary-600 !border-primary-600" />
|
|
3498
|
+
</div>
|
|
3499
|
+
</ng-template>
|
|
3500
|
+
<ng-template #empty>
|
|
3501
|
+
<div class="flex flex-col items-center gap-2 py-4">
|
|
3502
|
+
<i class="pi pi-cloud-upload text-2xl text-surface-400 dark:text-surface-300"></i>
|
|
3503
|
+
<span class="text-surface-500 dark:text-surface-100 text-sm">Drag and drop files here</span>
|
|
3504
|
+
</div>
|
|
3505
|
+
</ng-template>
|
|
3506
|
+
</p-fileupload>
|
|
3507
|
+
</div>
|
|
3508
|
+
</p-panel>
|
|
3509
|
+
</div>
|
|
3510
|
+
`, isInline: true, styles: [""], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "component", type: i3$5.FileUpload, selector: "p-fileupload, p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "chooseButtonProps", "uploadButtonProps", "cancelButtonProps", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i5$1.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i6.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4$1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: MenuModule }, { kind: "component", type: i7.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "appendTo", "motionOptions"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i8$1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i8$1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "component", type: i8$1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i9$1.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: PillTabsComponent, selector: "ux-pill-tabs", inputs: ["items", "activeValue"], outputs: ["activeValueChange"] }, { kind: "ngmodule", type: PanelModule }, { kind: "component", type: i10$1.Panel, selector: "p-panel", inputs: ["id", "toggleable", "header", "collapsed", "styleClass", "iconPos", "showHeader", "toggler", "transitionOptions", "toggleButtonProps", "motionOptions"], outputs: ["collapsedChange", "onBeforeToggle", "onAfterToggle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3511
|
+
}
|
|
3512
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DocumentsCardComponent, decorators: [{
|
|
3513
|
+
type: Component,
|
|
3514
|
+
args: [{ selector: 'ux-documents-card', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass, FormsModule, ButtonModule, FileUploadModule, IconFieldModule, InputIconModule, InputTextModule, MenuModule, TableModule, TagModule, PillTabsComponent, PanelModule], host: { class: 'ux-documents-card block' }, template: `
|
|
3515
|
+
<div class="card flex flex-col overflow-hidden">
|
|
3516
|
+
<p-panel [toggleable]="true" [collapsed]="!expanded()" (collapsedChange)="expanded.set(!$event)" toggler="header">
|
|
3517
|
+
<ng-template #headericons let-collapsed>
|
|
3518
|
+
<i class="pi text-sm text-darkblue-500 dark:text-surface-0" [ngClass]="collapsed ? 'pi-chevron-down' : 'pi-chevron-up'"></i>
|
|
3519
|
+
</ng-template>
|
|
3520
|
+
<ng-template #header>
|
|
3521
|
+
<div class="flex items-center gap-3 flex-1">
|
|
3522
|
+
<div class="w-[34px] h-[34px] rounded-[10px] flex items-center justify-center shrink-0">
|
|
3523
|
+
<i class="pi pi-folder text-deepsea-500 dark:text-surface-0"></i>
|
|
3524
|
+
</div>
|
|
3525
|
+
<div class="flex flex-col">
|
|
3526
|
+
<h4 class="title-h4 text-left text-deepsea-500 dark:text-surface-0">Documents</h4>
|
|
3527
|
+
<span class="text-surface-500 dark:text-surface-300 text-sm font-medium leading-tight">{{ summary() }}</span>
|
|
3528
|
+
</div>
|
|
3529
|
+
</div>
|
|
3530
|
+
</ng-template>
|
|
3531
|
+
<div class="flex flex-col gap-4 pt-4">
|
|
3532
|
+
<ux-pill-tabs [items]="pillTabItems()" [(activeValue)]="activeFilter" />
|
|
3533
|
+
|
|
3534
|
+
<p-iconfield>
|
|
3535
|
+
<p-inputicon class="pi pi-search" />
|
|
3536
|
+
<input pInputText [(ngModel)]="searchQuery" placeholder="Search documents" class="w-full" />
|
|
3537
|
+
</p-iconfield>
|
|
3538
|
+
|
|
3539
|
+
@if (filtered().length > 0) {
|
|
3540
|
+
<p-table
|
|
3541
|
+
[value]="filtered()"
|
|
3542
|
+
[paginator]="true"
|
|
3543
|
+
[rows]="rows()"
|
|
3544
|
+
sortMode="multiple"
|
|
3545
|
+
styleClass="flex flex-col rounded-2xl overflow-hidden [&>[data-pc-section=paginatorcontainer]]:border-0! [&>[data-pc-section=paginatorcontainer]]:mt-auto [&_[data-pc-name=pcpaginator]]:rounded-none!"
|
|
3546
|
+
tableStyleClass="w-full table-fixed"
|
|
3547
|
+
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink"
|
|
3548
|
+
>
|
|
3549
|
+
<ng-template #header>
|
|
3550
|
+
<tr>
|
|
3551
|
+
<th pSortableColumn="fileName" class="w-1/2">File Name <p-sortIcon field="fileName" /></th>
|
|
3552
|
+
<th pSortableColumn="type" class="w-1/4">Type <p-sortIcon field="type" /></th>
|
|
3553
|
+
<th class="w-1/4">Actions</th>
|
|
3554
|
+
</tr>
|
|
3555
|
+
</ng-template>
|
|
3556
|
+
<ng-template #body let-doc>
|
|
3557
|
+
<tr>
|
|
3558
|
+
<td>
|
|
3559
|
+
<div class="flex items-center gap-3 py-1 min-w-0">
|
|
3560
|
+
<i class="pi text-xl text-surface-600 dark:text-surface-300 shrink-0" [ngClass]="doc.icon"></i>
|
|
3561
|
+
<span class="text-surface-700 dark:text-surface-100 text-sm truncate">{{ doc.fileName }}</span>
|
|
3562
|
+
</div>
|
|
3563
|
+
</td>
|
|
3564
|
+
<td>
|
|
3565
|
+
<p-tag [value]="doc.type" styleClass="px-2 py-1" />
|
|
3566
|
+
</td>
|
|
3567
|
+
<td>
|
|
3568
|
+
<div class="flex items-center gap-1">
|
|
3569
|
+
<p-button icon="pi pi-download" [rounded]="true" [text]="true" size="small" severity="secondary" styleClass="cursor-pointer" ariaLabel="Download" />
|
|
3570
|
+
<p-button icon="pi pi-ellipsis-h" [rounded]="true" [text]="true" size="small" severity="secondary" styleClass="cursor-pointer" ariaLabel="More options" (onClick)="onMenuToggle($event, doc, docMenu)" />
|
|
3571
|
+
<p-menu #docMenu [model]="menuItems" [popup]="true" styleClass="w-48" appendTo="body" />
|
|
3572
|
+
</div>
|
|
3573
|
+
</td>
|
|
3574
|
+
</tr>
|
|
3575
|
+
</ng-template>
|
|
3576
|
+
</p-table>
|
|
3577
|
+
} @else {
|
|
3578
|
+
<div class="flex flex-col items-center gap-3 py-8 text-center">
|
|
3579
|
+
<i class="pi pi-folder-open text-3xl text-surface-300 dark:text-surface-500"></i>
|
|
3580
|
+
<span class="text-surface-600 dark:text-surface-300 text-sm">No documents to show</span>
|
|
3581
|
+
</div>
|
|
3582
|
+
}
|
|
3583
|
+
|
|
3584
|
+
<p-fileupload
|
|
3585
|
+
name="documents[]"
|
|
3586
|
+
[multiple]="true"
|
|
3587
|
+
maxFileSize="10000000"
|
|
3588
|
+
mode="advanced"
|
|
3589
|
+
[auto]="false"
|
|
3590
|
+
chooseLabel="Upload File"
|
|
3591
|
+
chooseIcon="pi pi-upload"
|
|
3592
|
+
[showUploadButton]="false"
|
|
3593
|
+
[showCancelButton]="false"
|
|
3594
|
+
[pt]="{ root: { class: 'bg-transparent' }, header: { class: 'bg-transparent' }, content: { class: 'bg-transparent' } }"
|
|
3595
|
+
>
|
|
3596
|
+
<ng-template #header let-chooseCallback="chooseCallback">
|
|
3597
|
+
<div class="flex items-center gap-2 w-full">
|
|
3598
|
+
<p-button icon="pi pi-upload" label="Upload File" (onClick)="chooseCallback()" />
|
|
3599
|
+
<p-button icon="pi pi-link" label="Share Link" [outlined]="true" styleClass="!text-primary-600 !border-primary-600" />
|
|
3600
|
+
</div>
|
|
3601
|
+
</ng-template>
|
|
3602
|
+
<ng-template #empty>
|
|
3603
|
+
<div class="flex flex-col items-center gap-2 py-4">
|
|
3604
|
+
<i class="pi pi-cloud-upload text-2xl text-surface-400 dark:text-surface-300"></i>
|
|
3605
|
+
<span class="text-surface-500 dark:text-surface-100 text-sm">Drag and drop files here</span>
|
|
3606
|
+
</div>
|
|
3607
|
+
</ng-template>
|
|
3608
|
+
</p-fileupload>
|
|
3609
|
+
</div>
|
|
3610
|
+
</p-panel>
|
|
3611
|
+
</div>
|
|
3612
|
+
` }]
|
|
3613
|
+
}], propDecorators: { documents: [{ type: i0.Input, args: [{ isSignal: true, alias: "documents", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], searchQuery: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchQuery", required: false }] }, { type: i0.Output, args: ["searchQueryChange"] }] } });
|
|
3614
|
+
|
|
3615
|
+
class UxSelectComponent {
|
|
3616
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
3617
|
+
optionLabel = input('label', ...(ngDevMode ? [{ debugName: "optionLabel" }] : []));
|
|
3618
|
+
optionValue = input('value', ...(ngDevMode ? [{ debugName: "optionValue" }] : []));
|
|
3619
|
+
optionGroupLabel = input('label', ...(ngDevMode ? [{ debugName: "optionGroupLabel" }] : []));
|
|
3620
|
+
optionGroupChildren = input('items', ...(ngDevMode ? [{ debugName: "optionGroupChildren" }] : []));
|
|
3621
|
+
placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
3622
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
3623
|
+
filter = input(false, ...(ngDevMode ? [{ debugName: "filter" }] : []));
|
|
3624
|
+
showClear = input(false, ...(ngDevMode ? [{ debugName: "showClear" }] : []));
|
|
3625
|
+
emptyMessage = input('No results found', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : []));
|
|
3626
|
+
group = input(false, ...(ngDevMode ? [{ debugName: "group" }] : []));
|
|
3627
|
+
styleClass = input('', ...(ngDevMode ? [{ debugName: "styleClass" }] : []));
|
|
3628
|
+
value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
3629
|
+
onChange = output();
|
|
3630
|
+
onFilter = output();
|
|
3631
|
+
resolvedStyleClass = computed(() => {
|
|
3632
|
+
const base = 'ux-select__inner';
|
|
3633
|
+
const extra = this.styleClass();
|
|
3634
|
+
return extra ? `${base} ${extra}` : base;
|
|
3635
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedStyleClass" }] : []));
|
|
3636
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: UxSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3637
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.8", type: UxSelectComponent, isStandalone: true, selector: "ux-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, optionGroupLabel: { classPropertyName: "optionGroupLabel", publicName: "optionGroupLabel", isSignal: true, isRequired: false, transformFunction: null }, optionGroupChildren: { classPropertyName: "optionGroupChildren", publicName: "optionGroupChildren", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onChange: "onChange", onFilter: "onFilter" }, host: { classAttribute: "ux-select" }, ngImport: i0, template: `
|
|
3638
|
+
<p-select
|
|
3639
|
+
[options]="options()"
|
|
3640
|
+
[optionLabel]="optionLabel()"
|
|
3641
|
+
[optionValue]="optionValue()"
|
|
3642
|
+
[optionGroupLabel]="optionGroupLabel()"
|
|
3643
|
+
[optionGroupChildren]="optionGroupChildren()"
|
|
3644
|
+
[placeholder]="placeholder()"
|
|
3645
|
+
[disabled]="disabled()"
|
|
3646
|
+
[filter]="filter()"
|
|
3647
|
+
[showClear]="showClear()"
|
|
3648
|
+
[emptyMessage]="emptyMessage()"
|
|
3649
|
+
[group]="group()"
|
|
3650
|
+
[ngModel]="value()"
|
|
3651
|
+
(ngModelChange)="value.set($event)"
|
|
3652
|
+
(onChange)="onChange.emit($event)"
|
|
3653
|
+
(onFilter)="onFilter.emit($event)"
|
|
3654
|
+
[styleClass]="resolvedStyleClass()"
|
|
3655
|
+
/>
|
|
3656
|
+
`, isInline: true, styles: [":host :deep .p-select{border-radius:var(--p-content-border-radius, .375rem);font-family:var(--p-font-family, \"Noto Sans\", sans-serif);font-size:var(--font-size-sm, .875rem);transition:border-color .15s ease,box-shadow .15s ease;padding:.5rem 1.5rem}:host :deep .p-select:not(.p-disabled):hover{border-color:var(--p-primary-400)}:host :deep .p-select:not(.p-disabled).p-focus{border-color:var(--p-primary-500);box-shadow:0 0 0 2px color-mix(in srgb,var(--p-primary-500) 20%,transparent)}:host :deep .p-select-label{font-size:var(--font-size-sm, .875rem);color:var(--p-text-color)}:host :deep .p-select-label.p-placeholder{color:var(--p-text-muted-color)}:host :deep .p-select-dropdown{color:var(--p-text-muted-color)}:host-context(:root[class*=\"app-dark\"]) :deep .p-select:not(.p-disabled):hover{border-color:var(--p-primary-300)}:host-context(:root[class*=\"app-dark\"]) :deep .p-select:not(.p-disabled).p-focus{border-color:var(--p-primary-400);box-shadow:0 0 0 2px color-mix(in srgb,var(--p-primary-400) 25%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3657
|
+
}
|
|
3658
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: UxSelectComponent, decorators: [{
|
|
3659
|
+
type: Component,
|
|
3660
|
+
args: [{ selector: 'ux-select', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, SelectModule], host: { class: 'ux-select' }, template: `
|
|
3661
|
+
<p-select
|
|
3662
|
+
[options]="options()"
|
|
3663
|
+
[optionLabel]="optionLabel()"
|
|
3664
|
+
[optionValue]="optionValue()"
|
|
3665
|
+
[optionGroupLabel]="optionGroupLabel()"
|
|
3666
|
+
[optionGroupChildren]="optionGroupChildren()"
|
|
3667
|
+
[placeholder]="placeholder()"
|
|
3668
|
+
[disabled]="disabled()"
|
|
3669
|
+
[filter]="filter()"
|
|
3670
|
+
[showClear]="showClear()"
|
|
3671
|
+
[emptyMessage]="emptyMessage()"
|
|
3672
|
+
[group]="group()"
|
|
3673
|
+
[ngModel]="value()"
|
|
3674
|
+
(ngModelChange)="value.set($event)"
|
|
3675
|
+
(onChange)="onChange.emit($event)"
|
|
3676
|
+
(onFilter)="onFilter.emit($event)"
|
|
3677
|
+
[styleClass]="resolvedStyleClass()"
|
|
3678
|
+
/>
|
|
3679
|
+
`, styles: [":host :deep .p-select{border-radius:var(--p-content-border-radius, .375rem);font-family:var(--p-font-family, \"Noto Sans\", sans-serif);font-size:var(--font-size-sm, .875rem);transition:border-color .15s ease,box-shadow .15s ease;padding:.5rem 1.5rem}:host :deep .p-select:not(.p-disabled):hover{border-color:var(--p-primary-400)}:host :deep .p-select:not(.p-disabled).p-focus{border-color:var(--p-primary-500);box-shadow:0 0 0 2px color-mix(in srgb,var(--p-primary-500) 20%,transparent)}:host :deep .p-select-label{font-size:var(--font-size-sm, .875rem);color:var(--p-text-color)}:host :deep .p-select-label.p-placeholder{color:var(--p-text-muted-color)}:host :deep .p-select-dropdown{color:var(--p-text-muted-color)}:host-context(:root[class*=\"app-dark\"]) :deep .p-select:not(.p-disabled):hover{border-color:var(--p-primary-300)}:host-context(:root[class*=\"app-dark\"]) :deep .p-select:not(.p-disabled).p-focus{border-color:var(--p-primary-400);box-shadow:0 0 0 2px color-mix(in srgb,var(--p-primary-400) 25%,transparent)}\n"] }]
|
|
3680
|
+
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: false }] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], optionGroupLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionGroupLabel", required: false }] }], optionGroupChildren: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionGroupChildren", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], showClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClear", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: false }] }], styleClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleClass", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], onChange: [{ type: i0.Output, args: ["onChange"] }], onFilter: [{ type: i0.Output, args: ["onFilter"] }] } });
|
|
3681
|
+
|
|
3682
|
+
class TaskDrawerComponent {
|
|
3683
|
+
visible = model(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
|
|
3684
|
+
task = input(null, ...(ngDevMode ? [{ debugName: "task" }] : []));
|
|
3685
|
+
mode = input('create', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
3686
|
+
availableMembers = input([
|
|
3687
|
+
{ name: 'Amy Elsner', image: 'amyelsner.png' },
|
|
3688
|
+
{ name: 'Anna Fali', image: 'annafali.png' },
|
|
3689
|
+
{ name: 'Asiya Javayant', image: 'asiyajavayant.png' },
|
|
3690
|
+
{ name: 'Bernardo Dominic', image: 'bernardodominic.png' }
|
|
3691
|
+
], ...(ngDevMode ? [{ debugName: "availableMembers" }] : []));
|
|
3692
|
+
save = output();
|
|
3693
|
+
cancel = output();
|
|
3694
|
+
drawerTitle = computed(() => this.mode() === 'create' ? 'Create New Task' : 'Edit Task', ...(ngDevMode ? [{ debugName: "drawerTitle" }] : []));
|
|
3695
|
+
formData = {
|
|
3696
|
+
id: null,
|
|
3697
|
+
title: '',
|
|
3698
|
+
description: '',
|
|
3699
|
+
status: 'pending',
|
|
3700
|
+
completed: false,
|
|
3701
|
+
startDate: null,
|
|
3702
|
+
endDate: null,
|
|
3703
|
+
members: []
|
|
3704
|
+
};
|
|
3705
|
+
statusOptions = [
|
|
3706
|
+
{ label: 'Pending', value: 'pending' },
|
|
3707
|
+
{ label: 'In Progress', value: 'in-progress' },
|
|
3708
|
+
{ label: 'Completed', value: 'completed' }
|
|
3709
|
+
];
|
|
3710
|
+
filteredMembers = [];
|
|
3711
|
+
ngOnChanges(changes) {
|
|
3712
|
+
if (changes['task']) {
|
|
3713
|
+
const newTask = changes['task'].currentValue;
|
|
3714
|
+
if (newTask) {
|
|
3715
|
+
this.formData = {
|
|
3716
|
+
id: newTask.id,
|
|
3717
|
+
title: newTask.title || '',
|
|
3718
|
+
description: newTask.description || '',
|
|
3719
|
+
status: newTask.status || 'pending',
|
|
3720
|
+
completed: newTask.completed || false,
|
|
3721
|
+
startDate: newTask.startDate ? this.parseDate(newTask.startDate) : null,
|
|
3722
|
+
endDate: newTask.endDate ? this.parseDate(newTask.endDate) : null,
|
|
3723
|
+
members: newTask.members || []
|
|
3724
|
+
};
|
|
3725
|
+
}
|
|
3726
|
+
else {
|
|
3727
|
+
this.resetForm();
|
|
3728
|
+
}
|
|
3729
|
+
}
|
|
3730
|
+
}
|
|
3731
|
+
parseDate(dateStr) {
|
|
3732
|
+
if (!dateStr)
|
|
3733
|
+
return null;
|
|
3734
|
+
const parts = dateStr.split('.');
|
|
3735
|
+
if (parts.length === 3) {
|
|
3736
|
+
return new Date(parseInt(parts[2]), parseInt(parts[1]) - 1, parseInt(parts[0]));
|
|
3737
|
+
}
|
|
3738
|
+
return null;
|
|
3739
|
+
}
|
|
3740
|
+
resetForm() {
|
|
3741
|
+
this.formData = {
|
|
3742
|
+
id: null,
|
|
3743
|
+
title: '',
|
|
3744
|
+
description: '',
|
|
3745
|
+
status: 'pending',
|
|
3746
|
+
completed: false,
|
|
3747
|
+
startDate: null,
|
|
3748
|
+
endDate: null,
|
|
3749
|
+
members: []
|
|
3750
|
+
};
|
|
3751
|
+
}
|
|
3752
|
+
filterMembers(event) {
|
|
3753
|
+
const members = this.availableMembers();
|
|
3754
|
+
if (!event.query) {
|
|
3755
|
+
this.filteredMembers = members;
|
|
3756
|
+
return;
|
|
3757
|
+
}
|
|
3758
|
+
this.filteredMembers = members.filter(member => member.name?.toLowerCase().includes(event.query.toLowerCase()));
|
|
3759
|
+
}
|
|
3760
|
+
formatDateForSave(date) {
|
|
3761
|
+
if (!date)
|
|
3762
|
+
return null;
|
|
3763
|
+
const d = new Date(date);
|
|
3764
|
+
return `${String(d.getDate()).padStart(2, '0')}.${String(d.getMonth() + 1).padStart(2, '0')}.${d.getFullYear()}`;
|
|
3765
|
+
}
|
|
3766
|
+
handleSave() {
|
|
3767
|
+
const taskData = {
|
|
3768
|
+
id: this.formData.id,
|
|
3769
|
+
title: this.formData.title,
|
|
3770
|
+
description: this.formData.description || null,
|
|
3771
|
+
status: this.formData.status,
|
|
3772
|
+
completed: this.formData.status === 'completed',
|
|
3773
|
+
startDate: this.formatDateForSave(this.formData.startDate),
|
|
3774
|
+
endDate: this.formatDateForSave(this.formData.endDate),
|
|
3775
|
+
members: this.formData.members
|
|
3776
|
+
};
|
|
3777
|
+
this.save.emit(taskData);
|
|
3778
|
+
this.handleCancel();
|
|
3779
|
+
}
|
|
3780
|
+
handleCancel() {
|
|
3781
|
+
this.resetForm();
|
|
3782
|
+
this.cancel.emit();
|
|
3783
|
+
this.visible.set(false);
|
|
3784
|
+
}
|
|
3785
|
+
onHide() {
|
|
3786
|
+
this.handleCancel();
|
|
3787
|
+
}
|
|
3788
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: TaskDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3789
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.8", type: TaskDrawerComponent, isStandalone: true, selector: "ux-task-drawer", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, task: { classPropertyName: "task", publicName: "task", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, availableMembers: { classPropertyName: "availableMembers", publicName: "availableMembers", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", save: "save", cancel: "cancel" }, host: { classAttribute: "ux-task-drawer" }, usesOnChanges: true, ngImport: i0, template: `
|
|
3790
|
+
<p-drawer [visible]="visible()" position="right" styleClass="w-full! md:w-[420px]!" (onHide)="onHide()" (visibleChange)="visible.set($event)" appendTo="body">
|
|
3791
|
+
<ng-template #header>
|
|
3792
|
+
<div class="flex items-center gap-3">
|
|
3793
|
+
<i class="pi pi-list-check text-xl text-primary-500"></i>
|
|
3794
|
+
<span class="text-surface-900 dark:text-surface-0 font-semibold text-lg">{{ drawerTitle() }}</span>
|
|
3795
|
+
</div>
|
|
3796
|
+
</ng-template>
|
|
3797
|
+
|
|
3798
|
+
<div class="flex flex-col gap-6 p-1">
|
|
3799
|
+
<div class="flex flex-col gap-2">
|
|
3800
|
+
<label for="task-title" class="text-surface-900 dark:text-surface-0 font-medium text-sm">Task Title</label>
|
|
3801
|
+
<input pInputText id="task-title" [(ngModel)]="formData.title" placeholder="Enter task title..." class="w-full" />
|
|
3802
|
+
</div>
|
|
3803
|
+
|
|
3804
|
+
<div class="flex flex-col gap-2">
|
|
3805
|
+
<label for="task-description" class="text-surface-900 dark:text-surface-0 font-medium text-sm">Description</label>
|
|
3806
|
+
<textarea pTextarea id="task-description" [(ngModel)]="formData.description" placeholder="Enter task description..." [rows]="4" class="w-full"></textarea>
|
|
3807
|
+
</div>
|
|
3808
|
+
|
|
3809
|
+
<div class="flex flex-col gap-2">
|
|
3810
|
+
<label for="task-status" class="text-surface-900 dark:text-surface-0 font-medium text-sm">Status</label>
|
|
3811
|
+
<p-select id="task-status" [(ngModel)]="formData.status" [options]="statusOptions" optionLabel="label" optionValue="value" placeholder="Select status" styleClass="w-full" />
|
|
3812
|
+
</div>
|
|
3813
|
+
|
|
3814
|
+
<p-divider styleClass="my-2" />
|
|
3815
|
+
|
|
3816
|
+
<div class="flex flex-col gap-2">
|
|
3817
|
+
<label for="start-date" class="text-surface-900 dark:text-surface-0 font-medium text-sm">Start Date</label>
|
|
3818
|
+
<p-datepicker id="start-date" [(ngModel)]="formData.startDate" dateFormat="dd.mm.yy" placeholder="Select start date" inputStyleClass="w-full" />
|
|
3819
|
+
</div>
|
|
3820
|
+
|
|
3821
|
+
<div class="flex flex-col gap-2">
|
|
3822
|
+
<label for="end-date" class="text-surface-900 dark:text-surface-0 font-medium text-sm">End Date</label>
|
|
3823
|
+
<p-datepicker id="end-date" [(ngModel)]="formData.endDate" dateFormat="dd.mm.yy" placeholder="Select end date" inputStyleClass="w-full" />
|
|
3824
|
+
</div>
|
|
3825
|
+
|
|
3826
|
+
<p-divider styleClass="my-2" />
|
|
3827
|
+
|
|
3828
|
+
<div class="flex flex-col gap-2">
|
|
3829
|
+
<label for="team-members" class="text-surface-900 dark:text-surface-0 font-medium text-sm">Team Members</label>
|
|
3830
|
+
<p-autocomplete
|
|
3831
|
+
id="team-members"
|
|
3832
|
+
[(ngModel)]="formData.members"
|
|
3833
|
+
[suggestions]="filteredMembers"
|
|
3834
|
+
optionLabel="name"
|
|
3835
|
+
[multiple]="true"
|
|
3836
|
+
placeholder="Search team members..."
|
|
3837
|
+
(completeMethod)="filterMembers($event)"
|
|
3838
|
+
styleClass="w-full"
|
|
3839
|
+
>
|
|
3840
|
+
<ng-template #selecteditem let-value>
|
|
3841
|
+
<div class="flex items-center gap-2 bg-surface-50 dark:bg-surface-900 px-2 py-1 rounded">
|
|
3842
|
+
<p-avatar [image]="'demo/images/avatar/' + value.image" shape="circle" styleClass="w-5 h-5 border border-surface-200 dark:border-surface-700" />
|
|
3843
|
+
</div>
|
|
3844
|
+
</ng-template>
|
|
3845
|
+
<ng-template #item let-option>
|
|
3846
|
+
<div class="flex items-center gap-3">
|
|
3847
|
+
<p-avatar [image]="'demo/images/avatar/' + option.image" shape="circle" styleClass="w-8 h-8 border border-surface-200 dark:border-surface-700" />
|
|
3848
|
+
<span class="text-surface-900 dark:text-surface-0 font-medium">{{ option.name }}</span>
|
|
3849
|
+
</div>
|
|
3850
|
+
</ng-template>
|
|
3851
|
+
</p-autocomplete>
|
|
3852
|
+
</div>
|
|
3853
|
+
</div>
|
|
3854
|
+
|
|
3855
|
+
<ng-template #footer>
|
|
3856
|
+
<div class="flex justify-end gap-3 pt-4 border-t border-surface-200 dark:border-surface-700">
|
|
3857
|
+
<p-button label="Cancel" icon="pi pi-times" [outlined]="true" severity="secondary" (onClick)="handleCancel()" styleClass="flex-1" />
|
|
3858
|
+
<p-button [label]="mode() === 'create' ? 'Create Task' : 'Update Task'" [icon]="mode() === 'create' ? 'pi pi-plus' : 'pi pi-check'" (onClick)="handleSave()" styleClass="flex-1" />
|
|
3859
|
+
</div>
|
|
3860
|
+
</ng-template>
|
|
3861
|
+
</p-drawer>
|
|
3862
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i4.Drawer, selector: "p-drawer", inputs: ["appendTo", "motionOptions", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4$1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i5$2.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: DatePickerModule }, { kind: "component", type: i7$1.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "ngmodule", type: AutoCompleteModule }, { kind: "component", type: i8$2.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i2.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i10.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3863
|
+
}
|
|
3864
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: TaskDrawerComponent, decorators: [{
|
|
3865
|
+
type: Component,
|
|
3866
|
+
args: [{
|
|
3867
|
+
selector: 'ux-task-drawer',
|
|
3868
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3869
|
+
imports: [FormsModule, ButtonModule, DrawerModule, InputTextModule, TextareaModule, SelectModule, DatePickerModule, AutoCompleteModule, DividerModule, AvatarModule],
|
|
3870
|
+
host: { class: 'ux-task-drawer' },
|
|
3871
|
+
template: `
|
|
3872
|
+
<p-drawer [visible]="visible()" position="right" styleClass="w-full! md:w-[420px]!" (onHide)="onHide()" (visibleChange)="visible.set($event)" appendTo="body">
|
|
3873
|
+
<ng-template #header>
|
|
3874
|
+
<div class="flex items-center gap-3">
|
|
3875
|
+
<i class="pi pi-list-check text-xl text-primary-500"></i>
|
|
3876
|
+
<span class="text-surface-900 dark:text-surface-0 font-semibold text-lg">{{ drawerTitle() }}</span>
|
|
3877
|
+
</div>
|
|
3878
|
+
</ng-template>
|
|
3879
|
+
|
|
3880
|
+
<div class="flex flex-col gap-6 p-1">
|
|
3881
|
+
<div class="flex flex-col gap-2">
|
|
3882
|
+
<label for="task-title" class="text-surface-900 dark:text-surface-0 font-medium text-sm">Task Title</label>
|
|
3883
|
+
<input pInputText id="task-title" [(ngModel)]="formData.title" placeholder="Enter task title..." class="w-full" />
|
|
3884
|
+
</div>
|
|
3885
|
+
|
|
3886
|
+
<div class="flex flex-col gap-2">
|
|
3887
|
+
<label for="task-description" class="text-surface-900 dark:text-surface-0 font-medium text-sm">Description</label>
|
|
3888
|
+
<textarea pTextarea id="task-description" [(ngModel)]="formData.description" placeholder="Enter task description..." [rows]="4" class="w-full"></textarea>
|
|
3889
|
+
</div>
|
|
3890
|
+
|
|
3891
|
+
<div class="flex flex-col gap-2">
|
|
3892
|
+
<label for="task-status" class="text-surface-900 dark:text-surface-0 font-medium text-sm">Status</label>
|
|
3893
|
+
<p-select id="task-status" [(ngModel)]="formData.status" [options]="statusOptions" optionLabel="label" optionValue="value" placeholder="Select status" styleClass="w-full" />
|
|
3894
|
+
</div>
|
|
3895
|
+
|
|
3896
|
+
<p-divider styleClass="my-2" />
|
|
3897
|
+
|
|
3898
|
+
<div class="flex flex-col gap-2">
|
|
3899
|
+
<label for="start-date" class="text-surface-900 dark:text-surface-0 font-medium text-sm">Start Date</label>
|
|
3900
|
+
<p-datepicker id="start-date" [(ngModel)]="formData.startDate" dateFormat="dd.mm.yy" placeholder="Select start date" inputStyleClass="w-full" />
|
|
3901
|
+
</div>
|
|
3902
|
+
|
|
3903
|
+
<div class="flex flex-col gap-2">
|
|
3904
|
+
<label for="end-date" class="text-surface-900 dark:text-surface-0 font-medium text-sm">End Date</label>
|
|
3905
|
+
<p-datepicker id="end-date" [(ngModel)]="formData.endDate" dateFormat="dd.mm.yy" placeholder="Select end date" inputStyleClass="w-full" />
|
|
3906
|
+
</div>
|
|
3907
|
+
|
|
3908
|
+
<p-divider styleClass="my-2" />
|
|
3909
|
+
|
|
3910
|
+
<div class="flex flex-col gap-2">
|
|
3911
|
+
<label for="team-members" class="text-surface-900 dark:text-surface-0 font-medium text-sm">Team Members</label>
|
|
3912
|
+
<p-autocomplete
|
|
3913
|
+
id="team-members"
|
|
3914
|
+
[(ngModel)]="formData.members"
|
|
3915
|
+
[suggestions]="filteredMembers"
|
|
3916
|
+
optionLabel="name"
|
|
3917
|
+
[multiple]="true"
|
|
3918
|
+
placeholder="Search team members..."
|
|
3919
|
+
(completeMethod)="filterMembers($event)"
|
|
3920
|
+
styleClass="w-full"
|
|
3921
|
+
>
|
|
3922
|
+
<ng-template #selecteditem let-value>
|
|
3923
|
+
<div class="flex items-center gap-2 bg-surface-50 dark:bg-surface-900 px-2 py-1 rounded">
|
|
3924
|
+
<p-avatar [image]="'demo/images/avatar/' + value.image" shape="circle" styleClass="w-5 h-5 border border-surface-200 dark:border-surface-700" />
|
|
3925
|
+
</div>
|
|
3926
|
+
</ng-template>
|
|
3927
|
+
<ng-template #item let-option>
|
|
3928
|
+
<div class="flex items-center gap-3">
|
|
3929
|
+
<p-avatar [image]="'demo/images/avatar/' + option.image" shape="circle" styleClass="w-8 h-8 border border-surface-200 dark:border-surface-700" />
|
|
3930
|
+
<span class="text-surface-900 dark:text-surface-0 font-medium">{{ option.name }}</span>
|
|
3931
|
+
</div>
|
|
3932
|
+
</ng-template>
|
|
3933
|
+
</p-autocomplete>
|
|
3934
|
+
</div>
|
|
3935
|
+
</div>
|
|
3936
|
+
|
|
3937
|
+
<ng-template #footer>
|
|
3938
|
+
<div class="flex justify-end gap-3 pt-4 border-t border-surface-200 dark:border-surface-700">
|
|
3939
|
+
<p-button label="Cancel" icon="pi pi-times" [outlined]="true" severity="secondary" (onClick)="handleCancel()" styleClass="flex-1" />
|
|
3940
|
+
<p-button [label]="mode() === 'create' ? 'Create Task' : 'Update Task'" [icon]="mode() === 'create' ? 'pi pi-plus' : 'pi pi-check'" (onClick)="handleSave()" styleClass="flex-1" />
|
|
3941
|
+
</div>
|
|
3942
|
+
</ng-template>
|
|
3943
|
+
</p-drawer>
|
|
3944
|
+
`
|
|
3945
|
+
}]
|
|
3946
|
+
}], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], task: [{ type: i0.Input, args: [{ isSignal: true, alias: "task", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], availableMembers: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableMembers", required: false }] }], save: [{ type: i0.Output, args: ["save"] }], cancel: [{ type: i0.Output, args: ["cancel"] }] } });
|
|
3947
|
+
|
|
3005
3948
|
/*
|
|
3006
3949
|
* Public API Surface of @unopsitg/ux
|
|
3007
3950
|
*/
|
|
@@ -3010,5 +3953,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
3010
3953
|
* Generated bundle index. Do not edit.
|
|
3011
3954
|
*/
|
|
3012
3955
|
|
|
3013
|
-
export { AiCardBgComponent, AiInsightsCardComponent, AppBreadcrumb, AppConfigurator, AppFooter, AppLayout, AppMenu, AppMenuitem, AppRightMenu, AppSearch, AppSidebar, AppTopbar, AuthLayout, BrandContrast, BrandCrisp, BrandSoft, DetailLayoutComponent, DetailTabDirective, LayoutService, MENU_MODEL, SIDEBAR_LOGO, TOPBAR_MOBILE_LOGO, brandPresets, brandPrimitives };
|
|
3956
|
+
export { AiCardBgComponent, AiInsightsCardComponent, AppBreadcrumb, AppConfigurator, AppFooter, AppLayout, AppMenu, AppMenuitem, AppRightMenu, AppSearch, AppSidebar, AppTopbar, AuthLayout, BrandContrast, BrandCrisp, BrandSoft, CompletionStepsComponent, DetailLayoutComponent, DetailTabDirective, DocumentsCardComponent, FooterMainComponent, FooterService, LayoutService, MENU_MODEL, PillTabsComponent, SIDEBAR_LOGO, TOPBAR_MOBILE_LOGO, TaskDrawerComponent, UxSelectComponent, brandPresets, brandPrimitives };
|
|
3014
3957
|
//# sourceMappingURL=unopsitg-ux.mjs.map
|