@seniorsistemas/components-ai 2.0.0 → 2.0.2-master-c019cc99
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/esm2022/lib/components/dynamic-form/dynamic-form.component.mjs +9 -18
- package/esm2022/lib/components/dynamic-form/fields/dynamic-field-lookup.component.mjs +15 -6
- package/esm2022/lib/services/auth.service.mjs +24 -118
- package/esm2022/lib/utils/utils.mjs +2 -2
- package/fesm2022/seniorsistemas-components-ai.mjs +47 -140
- package/fesm2022/seniorsistemas-components-ai.mjs.map +1 -1
- package/lib/services/auth.service.d.ts +2 -45
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import * as i2 from '@angular/common';
|
|
|
4
4
|
import { CommonModule, DOCUMENT } from '@angular/common';
|
|
5
5
|
import * as i1 from '@angular/common/http';
|
|
6
6
|
import { HttpParams } from '@angular/common/http';
|
|
7
|
-
import { throwError,
|
|
7
|
+
import { throwError, of, BehaviorSubject, Subject, filter, takeUntil, share, from, concatMap, catchError as catchError$1 } from 'rxjs';
|
|
8
8
|
import { map, catchError, filter as filter$1, debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
9
9
|
import * as i1$1 from 'primeng/config';
|
|
10
10
|
import { providePrimeNG } from 'primeng/config';
|
|
@@ -392,155 +392,62 @@ class AuthService {
|
|
|
392
392
|
TOKEN_COOKIE_NAME = 'com.senior.token';
|
|
393
393
|
API_URL_COOKIE_NAME = 'com.senior.base.url';
|
|
394
394
|
API_PATH_SUFFIX = '/t/senior.com.br/bridge/1.0/rest';
|
|
395
|
-
currentUserSubject = new BehaviorSubject(null);
|
|
396
|
-
currentUser$ = this.currentUserSubject.asObservable();
|
|
397
395
|
constructor(cookieService) {
|
|
398
396
|
this.cookieService = cookieService;
|
|
399
|
-
this.loadUserFromCookie();
|
|
400
397
|
}
|
|
401
398
|
/**
|
|
402
|
-
*
|
|
399
|
+
* Parse token from cookie. Always reads fresh from cookie, no cache.
|
|
403
400
|
*/
|
|
404
|
-
|
|
401
|
+
parseTokenFromCookie() {
|
|
405
402
|
const tokenString = this.cookieService.getCookie(this.TOKEN_COOKIE_NAME);
|
|
406
|
-
if (tokenString)
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
catch (error) {
|
|
417
|
-
console.error('[AuthService] Error parsing token from cookie:', error);
|
|
418
|
-
this.currentUserSubject.next(null);
|
|
419
|
-
}
|
|
403
|
+
if (!tokenString)
|
|
404
|
+
return null;
|
|
405
|
+
try {
|
|
406
|
+
const token = JSON.parse(tokenString);
|
|
407
|
+
return token?.access_token ? token : null;
|
|
408
|
+
}
|
|
409
|
+
catch {
|
|
410
|
+
return null;
|
|
420
411
|
}
|
|
421
412
|
}
|
|
422
|
-
/**
|
|
423
|
-
* Get current user token
|
|
424
|
-
*/
|
|
425
413
|
getCurrentUser() {
|
|
426
|
-
return this.
|
|
414
|
+
return this.parseTokenFromCookie();
|
|
427
415
|
}
|
|
428
|
-
/**
|
|
429
|
-
* Get access token
|
|
430
|
-
*/
|
|
431
416
|
getAccessToken() {
|
|
432
|
-
|
|
433
|
-
return user?.access_token || null;
|
|
417
|
+
return this.parseTokenFromCookie()?.access_token || null;
|
|
434
418
|
}
|
|
435
|
-
/**
|
|
436
|
-
* Get token type (e.g., "Bearer")
|
|
437
|
-
*/
|
|
438
419
|
getTokenType() {
|
|
439
|
-
|
|
440
|
-
return user?.token_type || 'Bearer';
|
|
420
|
+
return this.parseTokenFromCookie()?.token_type || 'Bearer';
|
|
441
421
|
}
|
|
442
|
-
/**
|
|
443
|
-
* Get refresh token
|
|
444
|
-
*/
|
|
445
422
|
getRefreshToken() {
|
|
446
|
-
|
|
447
|
-
return user?.refresh_token || null;
|
|
423
|
+
return this.parseTokenFromCookie()?.refresh_token || null;
|
|
448
424
|
}
|
|
449
|
-
/**
|
|
450
|
-
* Get API base URL from cookie
|
|
451
|
-
*/
|
|
452
425
|
getApiBaseUrl() {
|
|
453
426
|
const baseUrl = this.cookieService.getCookie(this.API_URL_COOKIE_NAME);
|
|
454
|
-
// In development, use proxy
|
|
455
427
|
if (!baseUrl) {
|
|
456
|
-
// Check if we're in development mode
|
|
457
428
|
const isDevelopment = !window.location.hostname.includes('senior.com.br');
|
|
458
|
-
|
|
459
|
-
return '/api';
|
|
460
|
-
}
|
|
461
|
-
return null;
|
|
429
|
+
return isDevelopment ? '/api' : null;
|
|
462
430
|
}
|
|
463
|
-
|
|
464
|
-
const cleanBaseUrl = baseUrl.replace(/\/$/, '');
|
|
465
|
-
// Combine with API path suffix
|
|
466
|
-
return `${cleanBaseUrl}${this.API_PATH_SUFFIX}`;
|
|
431
|
+
return `${baseUrl.replace(/\/$/, '')}${this.API_PATH_SUFFIX}`;
|
|
467
432
|
}
|
|
468
|
-
/**
|
|
469
|
-
* Check if user is authenticated
|
|
470
|
-
*/
|
|
471
433
|
isAuthenticated() {
|
|
472
|
-
const user = this.
|
|
473
|
-
return user !== null
|
|
434
|
+
const user = this.parseTokenFromCookie();
|
|
435
|
+
return user !== null;
|
|
474
436
|
}
|
|
475
|
-
/**
|
|
476
|
-
* Check if token is valid (not expired)
|
|
477
|
-
*/
|
|
478
|
-
isTokenValid(token) {
|
|
479
|
-
if (!token || !token.access_token) {
|
|
480
|
-
return false;
|
|
481
|
-
}
|
|
482
|
-
// Check if token is expired
|
|
483
|
-
const now = Math.floor(Date.now() / 1000);
|
|
484
|
-
const tokenExpiry = token.expires_in;
|
|
485
|
-
// If expires_in is a timestamp, compare directly
|
|
486
|
-
// If it's a duration, we'd need the token creation time
|
|
487
|
-
// For now, assume it's a timestamp
|
|
488
|
-
// If expires_in is very large (like a duration in seconds), skip expiry check
|
|
489
|
-
if (tokenExpiry > 1000000000) {
|
|
490
|
-
// Looks like a timestamp
|
|
491
|
-
return tokenExpiry > now;
|
|
492
|
-
}
|
|
493
|
-
else {
|
|
494
|
-
// Looks like a duration, assume token is valid
|
|
495
|
-
return true;
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
/**
|
|
499
|
-
* Check if refresh token is valid
|
|
500
|
-
*/
|
|
501
|
-
isRefreshTokenValid() {
|
|
502
|
-
const user = this.getCurrentUser();
|
|
503
|
-
if (!user || !user.refresh_token) {
|
|
504
|
-
return false;
|
|
505
|
-
}
|
|
506
|
-
const now = Math.floor(Date.now() / 1000);
|
|
507
|
-
const refreshExpiry = user.refresh_expires_in;
|
|
508
|
-
return refreshExpiry > now;
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* Get user locale
|
|
512
|
-
*/
|
|
513
437
|
getUserLocale() {
|
|
514
|
-
|
|
515
|
-
return user?.locale || 'pt-BR';
|
|
438
|
+
return this.parseTokenFromCookie()?.locale || 'pt-BR';
|
|
516
439
|
}
|
|
517
|
-
/**
|
|
518
|
-
* Get user full name
|
|
519
|
-
*/
|
|
520
440
|
getUserFullName() {
|
|
521
|
-
|
|
522
|
-
return user?.fullName || '';
|
|
441
|
+
return this.parseTokenFromCookie()?.fullName || '';
|
|
523
442
|
}
|
|
524
|
-
/**
|
|
525
|
-
* Get user email
|
|
526
|
-
*/
|
|
527
443
|
getUserEmail() {
|
|
528
|
-
|
|
529
|
-
return user?.email || '';
|
|
444
|
+
return this.parseTokenFromCookie()?.email || '';
|
|
530
445
|
}
|
|
531
|
-
/**
|
|
532
|
-
* Get tenant name
|
|
533
|
-
*/
|
|
534
446
|
getTenantName() {
|
|
535
|
-
|
|
536
|
-
return user?.tenantName || '';
|
|
447
|
+
return this.parseTokenFromCookie()?.tenantName || '';
|
|
537
448
|
}
|
|
538
|
-
/**
|
|
539
|
-
* Get username
|
|
540
|
-
*/
|
|
541
449
|
getUsername() {
|
|
542
|
-
|
|
543
|
-
return user?.username || '';
|
|
450
|
+
return this.parseTokenFromCookie()?.username || '';
|
|
544
451
|
}
|
|
545
452
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthService, deps: [{ token: CookieService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
546
453
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthService, providedIn: 'root' });
|
|
@@ -4406,7 +4313,7 @@ class DynamicFieldLookupComponent {
|
|
|
4406
4313
|
}
|
|
4407
4314
|
else {
|
|
4408
4315
|
const upperTerm = term.toUpperCase();
|
|
4409
|
-
filterConditions.push(`UPPER(${field})
|
|
4316
|
+
filterConditions.push(`containing(UPPER(${field}), '${upperTerm}')`);
|
|
4410
4317
|
}
|
|
4411
4318
|
});
|
|
4412
4319
|
if (filterConditions.length > 0) {
|
|
@@ -4575,7 +4482,7 @@ class DynamicFieldLookupComponent {
|
|
|
4575
4482
|
}
|
|
4576
4483
|
else {
|
|
4577
4484
|
const upperTerm = term.toUpperCase();
|
|
4578
|
-
filterConditions.push(`UPPER(${field})
|
|
4485
|
+
filterConditions.push(`containing(UPPER(${field}), '${upperTerm}')`);
|
|
4579
4486
|
}
|
|
4580
4487
|
});
|
|
4581
4488
|
if (filterConditions.length > 0) {
|
|
@@ -4652,12 +4559,21 @@ class DynamicFieldLookupComponent {
|
|
|
4652
4559
|
this.loadData();
|
|
4653
4560
|
}
|
|
4654
4561
|
selectItem(item) {
|
|
4655
|
-
//
|
|
4656
|
-
|
|
4657
|
-
this.displayValue = this.formatDisplayValue(item);
|
|
4562
|
+
// Close dialog first, then set value in next tick to prevent
|
|
4563
|
+
// click event from propagating to elements behind the dialog
|
|
4658
4564
|
this.showLookupDialog = false;
|
|
4565
|
+
setTimeout(() => {
|
|
4566
|
+
this.setValue(item);
|
|
4567
|
+
this.displayValue = this.formatDisplayValue(item);
|
|
4568
|
+
});
|
|
4659
4569
|
}
|
|
4660
4570
|
onRowSelect(event) {
|
|
4571
|
+
// Prevent the click event from propagating after the dialog closes,
|
|
4572
|
+
// which could trigger buttons behind the dialog (e.g. inline-edit save button)
|
|
4573
|
+
if (event.originalEvent) {
|
|
4574
|
+
event.originalEvent.stopPropagation();
|
|
4575
|
+
event.originalEvent.preventDefault();
|
|
4576
|
+
}
|
|
4661
4577
|
this.selectItem(event.data);
|
|
4662
4578
|
}
|
|
4663
4579
|
clearValue() {
|
|
@@ -5709,7 +5625,7 @@ class DynamicFormComponent {
|
|
|
5709
5625
|
if (control) {
|
|
5710
5626
|
const shouldDisable = this.isFieldDisabled(field);
|
|
5711
5627
|
if (shouldDisable && control.enabled) {
|
|
5712
|
-
control.setValue(null);
|
|
5628
|
+
control.setValue(null, { emitEvent: false });
|
|
5713
5629
|
control.disable({ emitEvent: false });
|
|
5714
5630
|
}
|
|
5715
5631
|
else if (!shouldDisable && control.disabled && !field.disabled) {
|
|
@@ -5767,9 +5683,11 @@ class DynamicFormComponent {
|
|
|
5767
5683
|
if (target.tagName === 'TEXTAREA')
|
|
5768
5684
|
return;
|
|
5769
5685
|
event.preventDefault();
|
|
5770
|
-
// In inline-edit mode, Enter saves the current field
|
|
5771
|
-
if (this.isInlineEditMode
|
|
5772
|
-
|
|
5686
|
+
// In inline-edit mode, Enter saves the current field but never triggers form submit
|
|
5687
|
+
if (this.isInlineEditMode) {
|
|
5688
|
+
if (this.editingField) {
|
|
5689
|
+
this.saveInlineField(this.editingField);
|
|
5690
|
+
}
|
|
5773
5691
|
}
|
|
5774
5692
|
else {
|
|
5775
5693
|
this.handleSubmit();
|
|
@@ -5815,17 +5733,6 @@ class DynamicFormComponent {
|
|
|
5815
5733
|
const el = document.querySelector(`.inline-edit-field input[id="${fieldName}"], .inline-edit-field textarea[id="${fieldName}"]`);
|
|
5816
5734
|
el?.focus();
|
|
5817
5735
|
});
|
|
5818
|
-
// For lookup fields, auto-save when value changes (user selects from dialog)
|
|
5819
|
-
const field = this.allFields.find(f => f.field === fieldName);
|
|
5820
|
-
if (field?.type === 'lookup') {
|
|
5821
|
-
const control = this.form.get(fieldName);
|
|
5822
|
-
const sub = control?.valueChanges.subscribe(val => {
|
|
5823
|
-
if (val && typeof val === 'object') {
|
|
5824
|
-
sub?.unsubscribe();
|
|
5825
|
-
this.saveInlineField(fieldName);
|
|
5826
|
-
}
|
|
5827
|
-
});
|
|
5828
|
-
}
|
|
5829
5736
|
}
|
|
5830
5737
|
isFieldEditing(fieldName) { return this.editingField === fieldName; }
|
|
5831
5738
|
saveInlineField(fieldName) {
|
|
@@ -5929,7 +5836,7 @@ class DynamicFormComponent {
|
|
|
5929
5836
|
return String(value);
|
|
5930
5837
|
}
|
|
5931
5838
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFormComponent, deps: [{ token: i2$1.FormBuilder }, { token: TranslationService }, { token: MaskService }, { token: LocaleService }], target: i0.ɵɵFactoryTarget.Component });
|
|
5932
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DynamicFormComponent, isStandalone: true, selector: "sia-dynamic-form", inputs: { sections: "sections", entityData: "entityData", mode: "mode", displayMode: "displayMode", visible: "visible", dialogConfig: "dialogConfig", drawerConfig: "drawerConfig", showSubmitButton: "showSubmitButton", showCancelButton: "showCancelButton", submitButtonLabel: "submitButtonLabel", cancelButtonLabel: "cancelButtonLabel", submitButtonIcon: "submitButtonIcon", cancelButtonIcon: "cancelButtonIcon" }, outputs: { formReady: "formReady", formSubmit: "formSubmit", visibleChange: "visibleChange", onCancel: "onCancel", fieldSave: "fieldSave" }, usesOnChanges: true, ngImport: i0, template: "<!-- Inline Mode (no displayMode set) -->\n<ng-container *ngIf=\"isInlineMode\">\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n</ng-container>\n\n<!-- Dialog Mode -->\n<p-dialog\n *ngIf=\"isDialogMode\"\n [(visible)]=\"visible\"\n [header]=\"dialogHeader | translate\"\n [modal]=\"true\"\n [style]=\"{ width: dialogWidth }\"\n [draggable]=\"dialogDraggable\"\n [resizable]=\"dialogResizable\"\n [maximizable]=\"dialogMaximizable\"\n [closeOnEscape]=\"dialogCloseOnEscape\"\n [dismissableMask]=\"dialogDismissableMask\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"dialog-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n\n<!-- Drawer Mode -->\n<p-drawer\n *ngIf=\"isDrawerMode\"\n [(visible)]=\"visible\"\n [header]=\"drawerHeader | translate\"\n [position]=\"drawerPosition\"\n [style]=\"drawerStyle\"\n [showCloseIcon]=\"drawerShowCloseIcon\"\n [closeOnEscape]=\"drawerCloseOnEscape\"\n [modal]=\"drawerDismissable\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"drawer-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-drawer>\n\n<!-- Form Content Template -->\n<ng-template #formContent>\n <form [formGroup]=\"form\" class=\"dynamic-form\" (keydown)=\"onFormKeydown($event)\">\n\n <ng-container *ngFor=\"let section of sections\">\n <!-- No title = bare fields -->\n <ng-container *ngIf=\"!section.title\">\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Bordered section -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'bordered'\" class=\"bordered-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Panel section -->\n <p-panel\n *ngIf=\"section.title && getSectionStyle(section) === 'panel'\"\n [toggleable]=\"true\"\n [collapsed]=\"section.collapsed || false\"\n styleClass=\"section-panel\">\n <ng-template pTemplate=\"header\">\n <div class=\"section-header\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n <span class=\"section-title\">{{ section.title }}</span>\n </div>\n </ng-template>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n\n <!-- Heading-only section (title present, style='none' or omitted) -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'none'\" class=\"heading-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- Custom content projection -->\n <ng-content></ng-content>\n </form>\n</ng-template>\n\n<!-- Field Template -->\n<ng-template #fieldTemplate let-field=\"field\">\n <sia-dynamic-field-text *ngIf=\"field.type === 'text'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-text>\n <sia-dynamic-field-textarea *ngIf=\"field.type === 'textarea'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-textarea>\n <sia-dynamic-field-number *ngIf=\"field.type === 'number' || field.type === 'currency'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-number>\n <sia-dynamic-field-date *ngIf=\"field.type === 'date'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-date>\n <sia-dynamic-field-datetime *ngIf=\"field.type === 'datetime'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-datetime>\n <sia-dynamic-field-dropdown *ngIf=\"field.type === 'dropdown' || field.type === 'enum'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-dropdown>\n <sia-dynamic-field-lookup *ngIf=\"field.type === 'lookup'\" [field]=\"field\" [form]=\"form\" [formGroup]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-lookup>\n <sia-dynamic-field-time *ngIf=\"field.type === 'time'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-time>\n <sia-dynamic-field-checkbox *ngIf=\"field.type === 'checkbox'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-checkbox>\n <sia-dynamic-field-multiselect *ngIf=\"field.type === 'multiselect'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-multiselect>\n <sia-dynamic-field-image *ngIf=\"field.type === 'image'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-image>\n</ng-template>\n\n<!-- Inline Edit Field Template -->\n<ng-template #inlineEditFieldTemplate let-field=\"field\">\n <label class=\"field-label\">{{ field.label | translate }}</label>\n <div class=\"field-display\" *ngIf=\"!isFieldEditing(field.field)\" (click)=\"startEditField(field.field)\" [class.disabled]=\"field.disabled\">\n <span class=\"display-value\" [attr.data-placeholder]=\"field.placeholder || ('design.components_ai.not_informed' | translate)\">{{ getFieldDisplayValue(field.field) }}</span>\n <i class=\"pi pi-pencil edit-icon\" *ngIf=\"!field.disabled\"></i>\n </div>\n <div class=\"field-edit\" *ngIf=\"isFieldEditing(field.field)\">\n <div class=\"input-container\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n <div class=\"edit-actions\">\n <p-button type=\"button\" icon=\"pi pi-check\" [rounded]=\"true\" [text]=\"true\" severity=\"success\" (onClick)=\"saveInlineField(field.field)\" [loading]=\"savingField\" [disabled]=\"form.get(field.field)?.invalid\" size=\"small\"></p-button>\n <p-button type=\"button\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" (onClick)=\"cancelInlineEdit()\" [disabled]=\"savingField\" size=\"small\"></p-button>\n </div>\n </div>\n</ng-template>\n", styles: [".dynamic-form{width:100%;display:flex;flex-direction:column;gap:1.5rem}.dynamic-form .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}.dynamic-form .grid>div.col-1{grid-column:span 1}.dynamic-form .grid>div.col-2{grid-column:span 2}.dynamic-form .grid>div.col-3{grid-column:span 3}.dynamic-form .grid>div.col-4{grid-column:span 4}.dynamic-form .grid>div.col-5{grid-column:span 5}.dynamic-form .grid>div.col-6{grid-column:span 6}.dynamic-form .grid>div.col-7{grid-column:span 7}.dynamic-form .grid>div.col-8{grid-column:span 8}.dynamic-form .grid>div.col-9{grid-column:span 9}.dynamic-form .grid>div.col-10{grid-column:span 10}.dynamic-form .grid>div.col-11{grid-column:span 11}.dynamic-form .grid>div.col-12{grid-column:span 12}@media (max-width: 575.98px){.dynamic-form .grid>div.col-xs-1{grid-column:span 1}.dynamic-form .grid>div.col-xs-2{grid-column:span 2}.dynamic-form .grid>div.col-xs-3{grid-column:span 3}.dynamic-form .grid>div.col-xs-4{grid-column:span 4}.dynamic-form .grid>div.col-xs-5{grid-column:span 5}.dynamic-form .grid>div.col-xs-6{grid-column:span 6}.dynamic-form .grid>div.col-xs-7{grid-column:span 7}.dynamic-form .grid>div.col-xs-8{grid-column:span 8}.dynamic-form .grid>div.col-xs-9{grid-column:span 9}.dynamic-form .grid>div.col-xs-10{grid-column:span 10}.dynamic-form .grid>div.col-xs-11{grid-column:span 11}.dynamic-form .grid>div.col-xs-12{grid-column:span 12}}@media (min-width: 576px){.dynamic-form .grid>div.col-sm-1{grid-column:span 1}.dynamic-form .grid>div.col-sm-2{grid-column:span 2}.dynamic-form .grid>div.col-sm-3{grid-column:span 3}.dynamic-form .grid>div.col-sm-4{grid-column:span 4}.dynamic-form .grid>div.col-sm-5{grid-column:span 5}.dynamic-form .grid>div.col-sm-6{grid-column:span 6}.dynamic-form .grid>div.col-sm-7{grid-column:span 7}.dynamic-form .grid>div.col-sm-8{grid-column:span 8}.dynamic-form .grid>div.col-sm-9{grid-column:span 9}.dynamic-form .grid>div.col-sm-10{grid-column:span 10}.dynamic-form .grid>div.col-sm-11{grid-column:span 11}.dynamic-form .grid>div.col-sm-12{grid-column:span 12}}@media (min-width: 768px){.dynamic-form .grid>div.col-md-1{grid-column:span 1}.dynamic-form .grid>div.col-md-2{grid-column:span 2}.dynamic-form .grid>div.col-md-3{grid-column:span 3}.dynamic-form .grid>div.col-md-4{grid-column:span 4}.dynamic-form .grid>div.col-md-5{grid-column:span 5}.dynamic-form .grid>div.col-md-6{grid-column:span 6}.dynamic-form .grid>div.col-md-7{grid-column:span 7}.dynamic-form .grid>div.col-md-8{grid-column:span 8}.dynamic-form .grid>div.col-md-9{grid-column:span 9}.dynamic-form .grid>div.col-md-10{grid-column:span 10}.dynamic-form .grid>div.col-md-11{grid-column:span 11}.dynamic-form .grid>div.col-md-12{grid-column:span 12}}@media (min-width: 992px){.dynamic-form .grid>div.col-lg-1{grid-column:span 1}.dynamic-form .grid>div.col-lg-2{grid-column:span 2}.dynamic-form .grid>div.col-lg-3{grid-column:span 3}.dynamic-form .grid>div.col-lg-4{grid-column:span 4}.dynamic-form .grid>div.col-lg-5{grid-column:span 5}.dynamic-form .grid>div.col-lg-6{grid-column:span 6}.dynamic-form .grid>div.col-lg-7{grid-column:span 7}.dynamic-form .grid>div.col-lg-8{grid-column:span 8}.dynamic-form .grid>div.col-lg-9{grid-column:span 9}.dynamic-form .grid>div.col-lg-10{grid-column:span 10}.dynamic-form .grid>div.col-lg-11{grid-column:span 11}.dynamic-form .grid>div.col-lg-12{grid-column:span 12}}@media (min-width: 1200px){.dynamic-form .grid>div.col-xl-1{grid-column:span 1}.dynamic-form .grid>div.col-xl-2{grid-column:span 2}.dynamic-form .grid>div.col-xl-3{grid-column:span 3}.dynamic-form .grid>div.col-xl-4{grid-column:span 4}.dynamic-form .grid>div.col-xl-5{grid-column:span 5}.dynamic-form .grid>div.col-xl-6{grid-column:span 6}.dynamic-form .grid>div.col-xl-7{grid-column:span 7}.dynamic-form .grid>div.col-xl-8{grid-column:span 8}.dynamic-form .grid>div.col-xl-9{grid-column:span 9}.dynamic-form .grid>div.col-xl-10{grid-column:span 10}.dynamic-form .grid>div.col-xl-11{grid-column:span 11}.dynamic-form .grid>div.col-xl-12{grid-column:span 12}}.dynamic-form .bordered-section{border:1px solid var(--p-surface-200, var(--surface-200, #e5e7eb));border-radius:var(--p-border-radius, var(--border-radius, 6px));padding:1.5rem}.dynamic-form .bordered-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .bordered-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form .heading-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .heading-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header{background-color:var(--surface-50)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header{display:flex;align-items:center;gap:.5rem;width:100%}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-icon{font-size:1.1rem;color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-title{font-weight:600;color:var(--text-color)}.dynamic-form ::ng-deep .section-panel .p-panel-content{padding:1.5rem}.dynamic-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--surface-200)}.dialog-footer{display:flex;justify-content:flex-end;gap:.5rem}.drawer-footer{display:flex;justify-content:flex-end;gap:.5rem;padding:1rem;border-top:1px solid var(--surface-200)}.inline-edit-fields{display:flex;flex-direction:column;gap:1rem}.inline-edit-fields .inline-edit-field{display:flex;flex-direction:column;gap:.5rem}.inline-edit-fields .inline-edit-field .field-label{font-weight:500;font-size:.875rem;color:var(--text-color-secondary)}.inline-edit-fields .inline-edit-field .field-display{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background-color:transparent;border:1px solid var(--p-surface-300, var(--surface-300, #d1d5db));border-radius:var(--p-border-radius, var(--border-radius, 6px));cursor:pointer;transition:all .2s ease;min-height:42px}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled){border-color:var(--p-primary-color, var(--primary-color))}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled) .edit-icon{opacity:1}.inline-edit-fields .inline-edit-field .field-display.disabled{cursor:not-allowed;opacity:.6;background-color:var(--p-surface-50, var(--surface-50, #f9fafb))}.inline-edit-fields .inline-edit-field .field-display .display-value{flex:1;color:var(--text-color)}.inline-edit-fields .inline-edit-field .field-display .display-value:empty:before{content:attr(data-placeholder);color:var(--text-color-secondary);font-style:italic}.inline-edit-fields .inline-edit-field .field-display .edit-icon{color:var(--p-primary-color, var(--primary-color));font-size:.875rem;opacity:0;transition:opacity .2s ease}.inline-edit-fields .inline-edit-field .field-edit{display:flex;align-items:center;gap:.5rem}.inline-edit-fields .inline-edit-field .field-edit .input-container{flex:1}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field{gap:0}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field label{display:none}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field small.p-error{display:none}.inline-edit-fields .inline-edit-field .field-edit .edit-actions{display:flex;gap:0;flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PanelModule }, { kind: "component", type: i6$1.Panel, selector: "p-panel", inputs: ["toggleable", "header", "collapsed", "style", "styleClass", "iconPos", "expandIcon", "collapseIcon", "showHeader", "toggler", "transitionOptions", "toggleButtonProps"], outputs: ["collapsedChange", "onBeforeToggle", "onAfterToggle"] }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i9$1.Drawer, selector: "p-drawer", inputs: ["appendTo", "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: ButtonModule }, { kind: "component", type: i4$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: DynamicFieldTextComponent, selector: "sia-dynamic-field-text" }, { kind: "component", type: DynamicFieldNumberComponent, selector: "sia-dynamic-field-number" }, { kind: "component", type: DynamicFieldDateComponent, selector: "sia-dynamic-field-date" }, { kind: "component", type: DynamicFieldDatetimeComponent, selector: "sia-dynamic-field-datetime" }, { kind: "component", type: DynamicFieldDropdownComponent, selector: "sia-dynamic-field-dropdown" }, { kind: "component", type: DynamicFieldLookupComponent, selector: "sia-dynamic-field-lookup", inputs: ["field", "form", "formGroup", "mode"] }, { kind: "component", type: DynamicFieldTextareaComponent, selector: "sia-dynamic-field-textarea" }, { kind: "component", type: DynamicFieldTimeComponent, selector: "sia-dynamic-field-time" }, { kind: "component", type: DynamicFieldCheckboxComponent, selector: "sia-dynamic-field-checkbox" }, { kind: "component", type: DynamicFieldMultiselectComponent, selector: "sia-dynamic-field-multiselect" }, { kind: "component", type: DynamicFieldImageComponent, selector: "sia-dynamic-field-image" }] });
|
|
5839
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DynamicFormComponent, isStandalone: true, selector: "sia-dynamic-form", inputs: { sections: "sections", entityData: "entityData", mode: "mode", displayMode: "displayMode", visible: "visible", dialogConfig: "dialogConfig", drawerConfig: "drawerConfig", showSubmitButton: "showSubmitButton", showCancelButton: "showCancelButton", submitButtonLabel: "submitButtonLabel", cancelButtonLabel: "cancelButtonLabel", submitButtonIcon: "submitButtonIcon", cancelButtonIcon: "cancelButtonIcon" }, outputs: { formReady: "formReady", formSubmit: "formSubmit", visibleChange: "visibleChange", onCancel: "onCancel", fieldSave: "fieldSave" }, usesOnChanges: true, ngImport: i0, template: "<!-- Inline Mode (no displayMode set) -->\n<ng-container *ngIf=\"isInlineMode\">\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n</ng-container>\n\n<!-- Dialog Mode -->\n<p-dialog\n *ngIf=\"isDialogMode\"\n [(visible)]=\"visible\"\n [header]=\"dialogHeader | translate\"\n [modal]=\"true\"\n [style]=\"{ width: dialogWidth }\"\n [draggable]=\"dialogDraggable\"\n [resizable]=\"dialogResizable\"\n [maximizable]=\"dialogMaximizable\"\n [closeOnEscape]=\"dialogCloseOnEscape\"\n [dismissableMask]=\"dialogDismissableMask\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"dialog-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n\n<!-- Drawer Mode -->\n<p-drawer\n *ngIf=\"isDrawerMode\"\n [(visible)]=\"visible\"\n [header]=\"drawerHeader | translate\"\n [position]=\"drawerPosition\"\n [style]=\"drawerStyle\"\n [showCloseIcon]=\"drawerShowCloseIcon\"\n [closeOnEscape]=\"drawerCloseOnEscape\"\n [modal]=\"drawerDismissable\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"drawer-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-drawer>\n\n<!-- Form Content Template -->\n<ng-template #formContent>\n <form [formGroup]=\"form\" class=\"dynamic-form\" (keydown)=\"onFormKeydown($event)\" (submit)=\"$event.preventDefault()\">\n\n <ng-container *ngFor=\"let section of sections\">\n <!-- No title = bare fields -->\n <ng-container *ngIf=\"!section.title\">\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Bordered section -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'bordered'\" class=\"bordered-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Panel section -->\n <p-panel\n *ngIf=\"section.title && getSectionStyle(section) === 'panel'\"\n [toggleable]=\"true\"\n [collapsed]=\"section.collapsed || false\"\n styleClass=\"section-panel\">\n <ng-template pTemplate=\"header\">\n <div class=\"section-header\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n <span class=\"section-title\">{{ section.title }}</span>\n </div>\n </ng-template>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n\n <!-- Heading-only section (title present, style='none' or omitted) -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'none'\" class=\"heading-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- Custom content projection -->\n <ng-content></ng-content>\n </form>\n</ng-template>\n\n<!-- Field Template -->\n<ng-template #fieldTemplate let-field=\"field\">\n <sia-dynamic-field-text *ngIf=\"field.type === 'text'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-text>\n <sia-dynamic-field-textarea *ngIf=\"field.type === 'textarea'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-textarea>\n <sia-dynamic-field-number *ngIf=\"field.type === 'number' || field.type === 'currency'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-number>\n <sia-dynamic-field-date *ngIf=\"field.type === 'date'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-date>\n <sia-dynamic-field-datetime *ngIf=\"field.type === 'datetime'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-datetime>\n <sia-dynamic-field-dropdown *ngIf=\"field.type === 'dropdown' || field.type === 'enum'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-dropdown>\n <sia-dynamic-field-lookup *ngIf=\"field.type === 'lookup'\" [field]=\"field\" [form]=\"form\" [formGroup]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-lookup>\n <sia-dynamic-field-time *ngIf=\"field.type === 'time'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-time>\n <sia-dynamic-field-checkbox *ngIf=\"field.type === 'checkbox'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-checkbox>\n <sia-dynamic-field-multiselect *ngIf=\"field.type === 'multiselect'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-multiselect>\n <sia-dynamic-field-image *ngIf=\"field.type === 'image'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-image>\n</ng-template>\n\n<!-- Inline Edit Field Template -->\n<ng-template #inlineEditFieldTemplate let-field=\"field\">\n <label class=\"field-label\">{{ field.label | translate }}</label>\n <div class=\"field-display\" *ngIf=\"!isFieldEditing(field.field)\" (click)=\"startEditField(field.field)\" [class.disabled]=\"field.disabled\">\n <span class=\"display-value\" [attr.data-placeholder]=\"field.placeholder || ('design.components_ai.not_informed' | translate)\">{{ getFieldDisplayValue(field.field) }}</span>\n <i class=\"pi pi-pencil edit-icon\" *ngIf=\"!field.disabled\"></i>\n </div>\n <div class=\"field-edit\" *ngIf=\"isFieldEditing(field.field)\">\n <div class=\"input-container\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n <div class=\"edit-actions\">\n <p-button type=\"button\" icon=\"pi pi-check\" [rounded]=\"true\" [text]=\"true\" severity=\"success\" (onClick)=\"saveInlineField(field.field)\" [loading]=\"savingField\" [disabled]=\"form.get(field.field)?.invalid\" size=\"small\"></p-button>\n <p-button type=\"button\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" (onClick)=\"cancelInlineEdit()\" [disabled]=\"savingField\" size=\"small\"></p-button>\n </div>\n </div>\n</ng-template>\n", styles: [".dynamic-form{width:100%;display:flex;flex-direction:column;gap:1.5rem}.dynamic-form .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}.dynamic-form .grid>div.col-1{grid-column:span 1}.dynamic-form .grid>div.col-2{grid-column:span 2}.dynamic-form .grid>div.col-3{grid-column:span 3}.dynamic-form .grid>div.col-4{grid-column:span 4}.dynamic-form .grid>div.col-5{grid-column:span 5}.dynamic-form .grid>div.col-6{grid-column:span 6}.dynamic-form .grid>div.col-7{grid-column:span 7}.dynamic-form .grid>div.col-8{grid-column:span 8}.dynamic-form .grid>div.col-9{grid-column:span 9}.dynamic-form .grid>div.col-10{grid-column:span 10}.dynamic-form .grid>div.col-11{grid-column:span 11}.dynamic-form .grid>div.col-12{grid-column:span 12}@media (max-width: 575.98px){.dynamic-form .grid>div.col-xs-1{grid-column:span 1}.dynamic-form .grid>div.col-xs-2{grid-column:span 2}.dynamic-form .grid>div.col-xs-3{grid-column:span 3}.dynamic-form .grid>div.col-xs-4{grid-column:span 4}.dynamic-form .grid>div.col-xs-5{grid-column:span 5}.dynamic-form .grid>div.col-xs-6{grid-column:span 6}.dynamic-form .grid>div.col-xs-7{grid-column:span 7}.dynamic-form .grid>div.col-xs-8{grid-column:span 8}.dynamic-form .grid>div.col-xs-9{grid-column:span 9}.dynamic-form .grid>div.col-xs-10{grid-column:span 10}.dynamic-form .grid>div.col-xs-11{grid-column:span 11}.dynamic-form .grid>div.col-xs-12{grid-column:span 12}}@media (min-width: 576px){.dynamic-form .grid>div.col-sm-1{grid-column:span 1}.dynamic-form .grid>div.col-sm-2{grid-column:span 2}.dynamic-form .grid>div.col-sm-3{grid-column:span 3}.dynamic-form .grid>div.col-sm-4{grid-column:span 4}.dynamic-form .grid>div.col-sm-5{grid-column:span 5}.dynamic-form .grid>div.col-sm-6{grid-column:span 6}.dynamic-form .grid>div.col-sm-7{grid-column:span 7}.dynamic-form .grid>div.col-sm-8{grid-column:span 8}.dynamic-form .grid>div.col-sm-9{grid-column:span 9}.dynamic-form .grid>div.col-sm-10{grid-column:span 10}.dynamic-form .grid>div.col-sm-11{grid-column:span 11}.dynamic-form .grid>div.col-sm-12{grid-column:span 12}}@media (min-width: 768px){.dynamic-form .grid>div.col-md-1{grid-column:span 1}.dynamic-form .grid>div.col-md-2{grid-column:span 2}.dynamic-form .grid>div.col-md-3{grid-column:span 3}.dynamic-form .grid>div.col-md-4{grid-column:span 4}.dynamic-form .grid>div.col-md-5{grid-column:span 5}.dynamic-form .grid>div.col-md-6{grid-column:span 6}.dynamic-form .grid>div.col-md-7{grid-column:span 7}.dynamic-form .grid>div.col-md-8{grid-column:span 8}.dynamic-form .grid>div.col-md-9{grid-column:span 9}.dynamic-form .grid>div.col-md-10{grid-column:span 10}.dynamic-form .grid>div.col-md-11{grid-column:span 11}.dynamic-form .grid>div.col-md-12{grid-column:span 12}}@media (min-width: 992px){.dynamic-form .grid>div.col-lg-1{grid-column:span 1}.dynamic-form .grid>div.col-lg-2{grid-column:span 2}.dynamic-form .grid>div.col-lg-3{grid-column:span 3}.dynamic-form .grid>div.col-lg-4{grid-column:span 4}.dynamic-form .grid>div.col-lg-5{grid-column:span 5}.dynamic-form .grid>div.col-lg-6{grid-column:span 6}.dynamic-form .grid>div.col-lg-7{grid-column:span 7}.dynamic-form .grid>div.col-lg-8{grid-column:span 8}.dynamic-form .grid>div.col-lg-9{grid-column:span 9}.dynamic-form .grid>div.col-lg-10{grid-column:span 10}.dynamic-form .grid>div.col-lg-11{grid-column:span 11}.dynamic-form .grid>div.col-lg-12{grid-column:span 12}}@media (min-width: 1200px){.dynamic-form .grid>div.col-xl-1{grid-column:span 1}.dynamic-form .grid>div.col-xl-2{grid-column:span 2}.dynamic-form .grid>div.col-xl-3{grid-column:span 3}.dynamic-form .grid>div.col-xl-4{grid-column:span 4}.dynamic-form .grid>div.col-xl-5{grid-column:span 5}.dynamic-form .grid>div.col-xl-6{grid-column:span 6}.dynamic-form .grid>div.col-xl-7{grid-column:span 7}.dynamic-form .grid>div.col-xl-8{grid-column:span 8}.dynamic-form .grid>div.col-xl-9{grid-column:span 9}.dynamic-form .grid>div.col-xl-10{grid-column:span 10}.dynamic-form .grid>div.col-xl-11{grid-column:span 11}.dynamic-form .grid>div.col-xl-12{grid-column:span 12}}.dynamic-form .bordered-section{border:1px solid var(--p-surface-200, var(--surface-200, #e5e7eb));border-radius:var(--p-border-radius, var(--border-radius, 6px));padding:1.5rem}.dynamic-form .bordered-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .bordered-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form .heading-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .heading-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header{background-color:var(--surface-50)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header{display:flex;align-items:center;gap:.5rem;width:100%}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-icon{font-size:1.1rem;color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-title{font-weight:600;color:var(--text-color)}.dynamic-form ::ng-deep .section-panel .p-panel-content{padding:1.5rem}.dynamic-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--surface-200)}.dialog-footer{display:flex;justify-content:flex-end;gap:.5rem}.drawer-footer{display:flex;justify-content:flex-end;gap:.5rem;padding:1rem;border-top:1px solid var(--surface-200)}.inline-edit-fields{display:flex;flex-direction:column;gap:1rem}.inline-edit-fields .inline-edit-field{display:flex;flex-direction:column;gap:.5rem}.inline-edit-fields .inline-edit-field .field-label{font-weight:500;font-size:.875rem;color:var(--text-color-secondary)}.inline-edit-fields .inline-edit-field .field-display{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background-color:transparent;border:1px solid var(--p-surface-300, var(--surface-300, #d1d5db));border-radius:var(--p-border-radius, var(--border-radius, 6px));cursor:pointer;transition:all .2s ease;min-height:42px}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled){border-color:var(--p-primary-color, var(--primary-color))}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled) .edit-icon{opacity:1}.inline-edit-fields .inline-edit-field .field-display.disabled{cursor:not-allowed;opacity:.6;background-color:var(--p-surface-50, var(--surface-50, #f9fafb))}.inline-edit-fields .inline-edit-field .field-display .display-value{flex:1;color:var(--text-color)}.inline-edit-fields .inline-edit-field .field-display .display-value:empty:before{content:attr(data-placeholder);color:var(--text-color-secondary);font-style:italic}.inline-edit-fields .inline-edit-field .field-display .edit-icon{color:var(--p-primary-color, var(--primary-color));font-size:.875rem;opacity:0;transition:opacity .2s ease}.inline-edit-fields .inline-edit-field .field-edit{display:flex;align-items:center;gap:.5rem}.inline-edit-fields .inline-edit-field .field-edit .input-container{flex:1}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field{gap:0}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field label{display:none}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field small.p-error{display:none}.inline-edit-fields .inline-edit-field .field-edit .edit-actions{display:flex;gap:0;flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PanelModule }, { kind: "component", type: i6$1.Panel, selector: "p-panel", inputs: ["toggleable", "header", "collapsed", "style", "styleClass", "iconPos", "expandIcon", "collapseIcon", "showHeader", "toggler", "transitionOptions", "toggleButtonProps"], outputs: ["collapsedChange", "onBeforeToggle", "onAfterToggle"] }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i9$1.Drawer, selector: "p-drawer", inputs: ["appendTo", "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: ButtonModule }, { kind: "component", type: i4$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: DynamicFieldTextComponent, selector: "sia-dynamic-field-text" }, { kind: "component", type: DynamicFieldNumberComponent, selector: "sia-dynamic-field-number" }, { kind: "component", type: DynamicFieldDateComponent, selector: "sia-dynamic-field-date" }, { kind: "component", type: DynamicFieldDatetimeComponent, selector: "sia-dynamic-field-datetime" }, { kind: "component", type: DynamicFieldDropdownComponent, selector: "sia-dynamic-field-dropdown" }, { kind: "component", type: DynamicFieldLookupComponent, selector: "sia-dynamic-field-lookup", inputs: ["field", "form", "formGroup", "mode"] }, { kind: "component", type: DynamicFieldTextareaComponent, selector: "sia-dynamic-field-textarea" }, { kind: "component", type: DynamicFieldTimeComponent, selector: "sia-dynamic-field-time" }, { kind: "component", type: DynamicFieldCheckboxComponent, selector: "sia-dynamic-field-checkbox" }, { kind: "component", type: DynamicFieldMultiselectComponent, selector: "sia-dynamic-field-multiselect" }, { kind: "component", type: DynamicFieldImageComponent, selector: "sia-dynamic-field-image" }] });
|
|
5933
5840
|
}
|
|
5934
5841
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DynamicFormComponent, decorators: [{
|
|
5935
5842
|
type: Component,
|
|
@@ -5952,7 +5859,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5952
5859
|
DynamicFieldCheckboxComponent,
|
|
5953
5860
|
DynamicFieldMultiselectComponent,
|
|
5954
5861
|
DynamicFieldImageComponent
|
|
5955
|
-
], template: "<!-- Inline Mode (no displayMode set) -->\n<ng-container *ngIf=\"isInlineMode\">\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n</ng-container>\n\n<!-- Dialog Mode -->\n<p-dialog\n *ngIf=\"isDialogMode\"\n [(visible)]=\"visible\"\n [header]=\"dialogHeader | translate\"\n [modal]=\"true\"\n [style]=\"{ width: dialogWidth }\"\n [draggable]=\"dialogDraggable\"\n [resizable]=\"dialogResizable\"\n [maximizable]=\"dialogMaximizable\"\n [closeOnEscape]=\"dialogCloseOnEscape\"\n [dismissableMask]=\"dialogDismissableMask\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"dialog-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n\n<!-- Drawer Mode -->\n<p-drawer\n *ngIf=\"isDrawerMode\"\n [(visible)]=\"visible\"\n [header]=\"drawerHeader | translate\"\n [position]=\"drawerPosition\"\n [style]=\"drawerStyle\"\n [showCloseIcon]=\"drawerShowCloseIcon\"\n [closeOnEscape]=\"drawerCloseOnEscape\"\n [modal]=\"drawerDismissable\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"drawer-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-drawer>\n\n<!-- Form Content Template -->\n<ng-template #formContent>\n <form [formGroup]=\"form\" class=\"dynamic-form\" (keydown)=\"onFormKeydown($event)\">\n\n <ng-container *ngFor=\"let section of sections\">\n <!-- No title = bare fields -->\n <ng-container *ngIf=\"!section.title\">\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Bordered section -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'bordered'\" class=\"bordered-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Panel section -->\n <p-panel\n *ngIf=\"section.title && getSectionStyle(section) === 'panel'\"\n [toggleable]=\"true\"\n [collapsed]=\"section.collapsed || false\"\n styleClass=\"section-panel\">\n <ng-template pTemplate=\"header\">\n <div class=\"section-header\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n <span class=\"section-title\">{{ section.title }}</span>\n </div>\n </ng-template>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n\n <!-- Heading-only section (title present, style='none' or omitted) -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'none'\" class=\"heading-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- Custom content projection -->\n <ng-content></ng-content>\n </form>\n</ng-template>\n\n<!-- Field Template -->\n<ng-template #fieldTemplate let-field=\"field\">\n <sia-dynamic-field-text *ngIf=\"field.type === 'text'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-text>\n <sia-dynamic-field-textarea *ngIf=\"field.type === 'textarea'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-textarea>\n <sia-dynamic-field-number *ngIf=\"field.type === 'number' || field.type === 'currency'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-number>\n <sia-dynamic-field-date *ngIf=\"field.type === 'date'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-date>\n <sia-dynamic-field-datetime *ngIf=\"field.type === 'datetime'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-datetime>\n <sia-dynamic-field-dropdown *ngIf=\"field.type === 'dropdown' || field.type === 'enum'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-dropdown>\n <sia-dynamic-field-lookup *ngIf=\"field.type === 'lookup'\" [field]=\"field\" [form]=\"form\" [formGroup]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-lookup>\n <sia-dynamic-field-time *ngIf=\"field.type === 'time'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-time>\n <sia-dynamic-field-checkbox *ngIf=\"field.type === 'checkbox'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-checkbox>\n <sia-dynamic-field-multiselect *ngIf=\"field.type === 'multiselect'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-multiselect>\n <sia-dynamic-field-image *ngIf=\"field.type === 'image'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-image>\n</ng-template>\n\n<!-- Inline Edit Field Template -->\n<ng-template #inlineEditFieldTemplate let-field=\"field\">\n <label class=\"field-label\">{{ field.label | translate }}</label>\n <div class=\"field-display\" *ngIf=\"!isFieldEditing(field.field)\" (click)=\"startEditField(field.field)\" [class.disabled]=\"field.disabled\">\n <span class=\"display-value\" [attr.data-placeholder]=\"field.placeholder || ('design.components_ai.not_informed' | translate)\">{{ getFieldDisplayValue(field.field) }}</span>\n <i class=\"pi pi-pencil edit-icon\" *ngIf=\"!field.disabled\"></i>\n </div>\n <div class=\"field-edit\" *ngIf=\"isFieldEditing(field.field)\">\n <div class=\"input-container\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n <div class=\"edit-actions\">\n <p-button type=\"button\" icon=\"pi pi-check\" [rounded]=\"true\" [text]=\"true\" severity=\"success\" (onClick)=\"saveInlineField(field.field)\" [loading]=\"savingField\" [disabled]=\"form.get(field.field)?.invalid\" size=\"small\"></p-button>\n <p-button type=\"button\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" (onClick)=\"cancelInlineEdit()\" [disabled]=\"savingField\" size=\"small\"></p-button>\n </div>\n </div>\n</ng-template>\n", styles: [".dynamic-form{width:100%;display:flex;flex-direction:column;gap:1.5rem}.dynamic-form .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}.dynamic-form .grid>div.col-1{grid-column:span 1}.dynamic-form .grid>div.col-2{grid-column:span 2}.dynamic-form .grid>div.col-3{grid-column:span 3}.dynamic-form .grid>div.col-4{grid-column:span 4}.dynamic-form .grid>div.col-5{grid-column:span 5}.dynamic-form .grid>div.col-6{grid-column:span 6}.dynamic-form .grid>div.col-7{grid-column:span 7}.dynamic-form .grid>div.col-8{grid-column:span 8}.dynamic-form .grid>div.col-9{grid-column:span 9}.dynamic-form .grid>div.col-10{grid-column:span 10}.dynamic-form .grid>div.col-11{grid-column:span 11}.dynamic-form .grid>div.col-12{grid-column:span 12}@media (max-width: 575.98px){.dynamic-form .grid>div.col-xs-1{grid-column:span 1}.dynamic-form .grid>div.col-xs-2{grid-column:span 2}.dynamic-form .grid>div.col-xs-3{grid-column:span 3}.dynamic-form .grid>div.col-xs-4{grid-column:span 4}.dynamic-form .grid>div.col-xs-5{grid-column:span 5}.dynamic-form .grid>div.col-xs-6{grid-column:span 6}.dynamic-form .grid>div.col-xs-7{grid-column:span 7}.dynamic-form .grid>div.col-xs-8{grid-column:span 8}.dynamic-form .grid>div.col-xs-9{grid-column:span 9}.dynamic-form .grid>div.col-xs-10{grid-column:span 10}.dynamic-form .grid>div.col-xs-11{grid-column:span 11}.dynamic-form .grid>div.col-xs-12{grid-column:span 12}}@media (min-width: 576px){.dynamic-form .grid>div.col-sm-1{grid-column:span 1}.dynamic-form .grid>div.col-sm-2{grid-column:span 2}.dynamic-form .grid>div.col-sm-3{grid-column:span 3}.dynamic-form .grid>div.col-sm-4{grid-column:span 4}.dynamic-form .grid>div.col-sm-5{grid-column:span 5}.dynamic-form .grid>div.col-sm-6{grid-column:span 6}.dynamic-form .grid>div.col-sm-7{grid-column:span 7}.dynamic-form .grid>div.col-sm-8{grid-column:span 8}.dynamic-form .grid>div.col-sm-9{grid-column:span 9}.dynamic-form .grid>div.col-sm-10{grid-column:span 10}.dynamic-form .grid>div.col-sm-11{grid-column:span 11}.dynamic-form .grid>div.col-sm-12{grid-column:span 12}}@media (min-width: 768px){.dynamic-form .grid>div.col-md-1{grid-column:span 1}.dynamic-form .grid>div.col-md-2{grid-column:span 2}.dynamic-form .grid>div.col-md-3{grid-column:span 3}.dynamic-form .grid>div.col-md-4{grid-column:span 4}.dynamic-form .grid>div.col-md-5{grid-column:span 5}.dynamic-form .grid>div.col-md-6{grid-column:span 6}.dynamic-form .grid>div.col-md-7{grid-column:span 7}.dynamic-form .grid>div.col-md-8{grid-column:span 8}.dynamic-form .grid>div.col-md-9{grid-column:span 9}.dynamic-form .grid>div.col-md-10{grid-column:span 10}.dynamic-form .grid>div.col-md-11{grid-column:span 11}.dynamic-form .grid>div.col-md-12{grid-column:span 12}}@media (min-width: 992px){.dynamic-form .grid>div.col-lg-1{grid-column:span 1}.dynamic-form .grid>div.col-lg-2{grid-column:span 2}.dynamic-form .grid>div.col-lg-3{grid-column:span 3}.dynamic-form .grid>div.col-lg-4{grid-column:span 4}.dynamic-form .grid>div.col-lg-5{grid-column:span 5}.dynamic-form .grid>div.col-lg-6{grid-column:span 6}.dynamic-form .grid>div.col-lg-7{grid-column:span 7}.dynamic-form .grid>div.col-lg-8{grid-column:span 8}.dynamic-form .grid>div.col-lg-9{grid-column:span 9}.dynamic-form .grid>div.col-lg-10{grid-column:span 10}.dynamic-form .grid>div.col-lg-11{grid-column:span 11}.dynamic-form .grid>div.col-lg-12{grid-column:span 12}}@media (min-width: 1200px){.dynamic-form .grid>div.col-xl-1{grid-column:span 1}.dynamic-form .grid>div.col-xl-2{grid-column:span 2}.dynamic-form .grid>div.col-xl-3{grid-column:span 3}.dynamic-form .grid>div.col-xl-4{grid-column:span 4}.dynamic-form .grid>div.col-xl-5{grid-column:span 5}.dynamic-form .grid>div.col-xl-6{grid-column:span 6}.dynamic-form .grid>div.col-xl-7{grid-column:span 7}.dynamic-form .grid>div.col-xl-8{grid-column:span 8}.dynamic-form .grid>div.col-xl-9{grid-column:span 9}.dynamic-form .grid>div.col-xl-10{grid-column:span 10}.dynamic-form .grid>div.col-xl-11{grid-column:span 11}.dynamic-form .grid>div.col-xl-12{grid-column:span 12}}.dynamic-form .bordered-section{border:1px solid var(--p-surface-200, var(--surface-200, #e5e7eb));border-radius:var(--p-border-radius, var(--border-radius, 6px));padding:1.5rem}.dynamic-form .bordered-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .bordered-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form .heading-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .heading-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header{background-color:var(--surface-50)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header{display:flex;align-items:center;gap:.5rem;width:100%}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-icon{font-size:1.1rem;color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-title{font-weight:600;color:var(--text-color)}.dynamic-form ::ng-deep .section-panel .p-panel-content{padding:1.5rem}.dynamic-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--surface-200)}.dialog-footer{display:flex;justify-content:flex-end;gap:.5rem}.drawer-footer{display:flex;justify-content:flex-end;gap:.5rem;padding:1rem;border-top:1px solid var(--surface-200)}.inline-edit-fields{display:flex;flex-direction:column;gap:1rem}.inline-edit-fields .inline-edit-field{display:flex;flex-direction:column;gap:.5rem}.inline-edit-fields .inline-edit-field .field-label{font-weight:500;font-size:.875rem;color:var(--text-color-secondary)}.inline-edit-fields .inline-edit-field .field-display{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background-color:transparent;border:1px solid var(--p-surface-300, var(--surface-300, #d1d5db));border-radius:var(--p-border-radius, var(--border-radius, 6px));cursor:pointer;transition:all .2s ease;min-height:42px}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled){border-color:var(--p-primary-color, var(--primary-color))}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled) .edit-icon{opacity:1}.inline-edit-fields .inline-edit-field .field-display.disabled{cursor:not-allowed;opacity:.6;background-color:var(--p-surface-50, var(--surface-50, #f9fafb))}.inline-edit-fields .inline-edit-field .field-display .display-value{flex:1;color:var(--text-color)}.inline-edit-fields .inline-edit-field .field-display .display-value:empty:before{content:attr(data-placeholder);color:var(--text-color-secondary);font-style:italic}.inline-edit-fields .inline-edit-field .field-display .edit-icon{color:var(--p-primary-color, var(--primary-color));font-size:.875rem;opacity:0;transition:opacity .2s ease}.inline-edit-fields .inline-edit-field .field-edit{display:flex;align-items:center;gap:.5rem}.inline-edit-fields .inline-edit-field .field-edit .input-container{flex:1}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field{gap:0}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field label{display:none}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field small.p-error{display:none}.inline-edit-fields .inline-edit-field .field-edit .edit-actions{display:flex;gap:0;flex-shrink:0}\n"] }]
|
|
5862
|
+
], template: "<!-- Inline Mode (no displayMode set) -->\n<ng-container *ngIf=\"isInlineMode\">\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n</ng-container>\n\n<!-- Dialog Mode -->\n<p-dialog\n *ngIf=\"isDialogMode\"\n [(visible)]=\"visible\"\n [header]=\"dialogHeader | translate\"\n [modal]=\"true\"\n [style]=\"{ width: dialogWidth }\"\n [draggable]=\"dialogDraggable\"\n [resizable]=\"dialogResizable\"\n [maximizable]=\"dialogMaximizable\"\n [closeOnEscape]=\"dialogCloseOnEscape\"\n [dismissableMask]=\"dialogDismissableMask\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"dialog-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n\n<!-- Drawer Mode -->\n<p-drawer\n *ngIf=\"isDrawerMode\"\n [(visible)]=\"visible\"\n [header]=\"drawerHeader | translate\"\n [position]=\"drawerPosition\"\n [style]=\"drawerStyle\"\n [showCloseIcon]=\"drawerShowCloseIcon\"\n [closeOnEscape]=\"drawerCloseOnEscape\"\n [modal]=\"drawerDismissable\"\n (onHide)=\"close()\">\n\n <ng-container *ngTemplateOutlet=\"formContent\"></ng-container>\n\n <ng-template pTemplate=\"footer\" *ngIf=\"showSubmitButton || showCancelButton\">\n <div class=\"drawer-footer\">\n <p-button *ngIf=\"showCancelButton\" [label]=\"cancelLabel | translate\" [icon]=\"cancelButtonIcon\" severity=\"secondary\" (onClick)=\"handleCancel()\" [disabled]=\"loading\"></p-button>\n <p-button *ngIf=\"showSubmitButton\" [label]=\"submitLabel | translate\" [icon]=\"submitButtonIcon\" (onClick)=\"handleSubmit()\" [loading]=\"loading\" [disabled]=\"form.invalid\"></p-button>\n </div>\n </ng-template>\n</p-drawer>\n\n<!-- Form Content Template -->\n<ng-template #formContent>\n <form [formGroup]=\"form\" class=\"dynamic-form\" (keydown)=\"onFormKeydown($event)\" (submit)=\"$event.preventDefault()\">\n\n <ng-container *ngFor=\"let section of sections\">\n <!-- No title = bare fields -->\n <ng-container *ngIf=\"!section.title\">\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Bordered section -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'bordered'\" class=\"bordered-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Panel section -->\n <p-panel\n *ngIf=\"section.title && getSectionStyle(section) === 'panel'\"\n [toggleable]=\"true\"\n [collapsed]=\"section.collapsed || false\"\n styleClass=\"section-panel\">\n <ng-template pTemplate=\"header\">\n <div class=\"section-header\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n <span class=\"section-title\">{{ section.title }}</span>\n </div>\n </ng-template>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </p-panel>\n\n <!-- Heading-only section (title present, style='none' or omitted) -->\n <div *ngIf=\"section.title && getSectionStyle(section) === 'none'\" class=\"heading-section\">\n <h3 class=\"section-heading\">\n <i *ngIf=\"section.icon\" [class]=\"section.icon + ' section-icon'\"></i>\n {{ section.title }}\n </h3>\n <div *ngIf=\"!isInlineEditMode\" class=\"grid\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" [ngClass]=\"getFieldGridClass(field)\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n <div *ngIf=\"isInlineEditMode\" class=\"inline-edit-fields\">\n <ng-container *ngFor=\"let field of section.fields\">\n <div *ngIf=\"isFieldVisible(field)\" class=\"inline-edit-field\">\n <ng-container *ngTemplateOutlet=\"inlineEditFieldTemplate; context: { field: field }\"></ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- Custom content projection -->\n <ng-content></ng-content>\n </form>\n</ng-template>\n\n<!-- Field Template -->\n<ng-template #fieldTemplate let-field=\"field\">\n <sia-dynamic-field-text *ngIf=\"field.type === 'text'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-text>\n <sia-dynamic-field-textarea *ngIf=\"field.type === 'textarea'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-textarea>\n <sia-dynamic-field-number *ngIf=\"field.type === 'number' || field.type === 'currency'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-number>\n <sia-dynamic-field-date *ngIf=\"field.type === 'date'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-date>\n <sia-dynamic-field-datetime *ngIf=\"field.type === 'datetime'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-datetime>\n <sia-dynamic-field-dropdown *ngIf=\"field.type === 'dropdown' || field.type === 'enum'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-dropdown>\n <sia-dynamic-field-lookup *ngIf=\"field.type === 'lookup'\" [field]=\"field\" [form]=\"form\" [formGroup]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-lookup>\n <sia-dynamic-field-time *ngIf=\"field.type === 'time'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-time>\n <sia-dynamic-field-checkbox *ngIf=\"field.type === 'checkbox'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-checkbox>\n <sia-dynamic-field-multiselect *ngIf=\"field.type === 'multiselect'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-multiselect>\n <sia-dynamic-field-image *ngIf=\"field.type === 'image'\" [field]=\"field\" [form]=\"form\" [mode]=\"'form'\"></sia-dynamic-field-image>\n</ng-template>\n\n<!-- Inline Edit Field Template -->\n<ng-template #inlineEditFieldTemplate let-field=\"field\">\n <label class=\"field-label\">{{ field.label | translate }}</label>\n <div class=\"field-display\" *ngIf=\"!isFieldEditing(field.field)\" (click)=\"startEditField(field.field)\" [class.disabled]=\"field.disabled\">\n <span class=\"display-value\" [attr.data-placeholder]=\"field.placeholder || ('design.components_ai.not_informed' | translate)\">{{ getFieldDisplayValue(field.field) }}</span>\n <i class=\"pi pi-pencil edit-icon\" *ngIf=\"!field.disabled\"></i>\n </div>\n <div class=\"field-edit\" *ngIf=\"isFieldEditing(field.field)\">\n <div class=\"input-container\">\n <ng-container *ngTemplateOutlet=\"fieldTemplate; context: { field: field }\"></ng-container>\n </div>\n <div class=\"edit-actions\">\n <p-button type=\"button\" icon=\"pi pi-check\" [rounded]=\"true\" [text]=\"true\" severity=\"success\" (onClick)=\"saveInlineField(field.field)\" [loading]=\"savingField\" [disabled]=\"form.get(field.field)?.invalid\" size=\"small\"></p-button>\n <p-button type=\"button\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" (onClick)=\"cancelInlineEdit()\" [disabled]=\"savingField\" size=\"small\"></p-button>\n </div>\n </div>\n</ng-template>\n", styles: [".dynamic-form{width:100%;display:flex;flex-direction:column;gap:1.5rem}.dynamic-form .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}.dynamic-form .grid>div.col-1{grid-column:span 1}.dynamic-form .grid>div.col-2{grid-column:span 2}.dynamic-form .grid>div.col-3{grid-column:span 3}.dynamic-form .grid>div.col-4{grid-column:span 4}.dynamic-form .grid>div.col-5{grid-column:span 5}.dynamic-form .grid>div.col-6{grid-column:span 6}.dynamic-form .grid>div.col-7{grid-column:span 7}.dynamic-form .grid>div.col-8{grid-column:span 8}.dynamic-form .grid>div.col-9{grid-column:span 9}.dynamic-form .grid>div.col-10{grid-column:span 10}.dynamic-form .grid>div.col-11{grid-column:span 11}.dynamic-form .grid>div.col-12{grid-column:span 12}@media (max-width: 575.98px){.dynamic-form .grid>div.col-xs-1{grid-column:span 1}.dynamic-form .grid>div.col-xs-2{grid-column:span 2}.dynamic-form .grid>div.col-xs-3{grid-column:span 3}.dynamic-form .grid>div.col-xs-4{grid-column:span 4}.dynamic-form .grid>div.col-xs-5{grid-column:span 5}.dynamic-form .grid>div.col-xs-6{grid-column:span 6}.dynamic-form .grid>div.col-xs-7{grid-column:span 7}.dynamic-form .grid>div.col-xs-8{grid-column:span 8}.dynamic-form .grid>div.col-xs-9{grid-column:span 9}.dynamic-form .grid>div.col-xs-10{grid-column:span 10}.dynamic-form .grid>div.col-xs-11{grid-column:span 11}.dynamic-form .grid>div.col-xs-12{grid-column:span 12}}@media (min-width: 576px){.dynamic-form .grid>div.col-sm-1{grid-column:span 1}.dynamic-form .grid>div.col-sm-2{grid-column:span 2}.dynamic-form .grid>div.col-sm-3{grid-column:span 3}.dynamic-form .grid>div.col-sm-4{grid-column:span 4}.dynamic-form .grid>div.col-sm-5{grid-column:span 5}.dynamic-form .grid>div.col-sm-6{grid-column:span 6}.dynamic-form .grid>div.col-sm-7{grid-column:span 7}.dynamic-form .grid>div.col-sm-8{grid-column:span 8}.dynamic-form .grid>div.col-sm-9{grid-column:span 9}.dynamic-form .grid>div.col-sm-10{grid-column:span 10}.dynamic-form .grid>div.col-sm-11{grid-column:span 11}.dynamic-form .grid>div.col-sm-12{grid-column:span 12}}@media (min-width: 768px){.dynamic-form .grid>div.col-md-1{grid-column:span 1}.dynamic-form .grid>div.col-md-2{grid-column:span 2}.dynamic-form .grid>div.col-md-3{grid-column:span 3}.dynamic-form .grid>div.col-md-4{grid-column:span 4}.dynamic-form .grid>div.col-md-5{grid-column:span 5}.dynamic-form .grid>div.col-md-6{grid-column:span 6}.dynamic-form .grid>div.col-md-7{grid-column:span 7}.dynamic-form .grid>div.col-md-8{grid-column:span 8}.dynamic-form .grid>div.col-md-9{grid-column:span 9}.dynamic-form .grid>div.col-md-10{grid-column:span 10}.dynamic-form .grid>div.col-md-11{grid-column:span 11}.dynamic-form .grid>div.col-md-12{grid-column:span 12}}@media (min-width: 992px){.dynamic-form .grid>div.col-lg-1{grid-column:span 1}.dynamic-form .grid>div.col-lg-2{grid-column:span 2}.dynamic-form .grid>div.col-lg-3{grid-column:span 3}.dynamic-form .grid>div.col-lg-4{grid-column:span 4}.dynamic-form .grid>div.col-lg-5{grid-column:span 5}.dynamic-form .grid>div.col-lg-6{grid-column:span 6}.dynamic-form .grid>div.col-lg-7{grid-column:span 7}.dynamic-form .grid>div.col-lg-8{grid-column:span 8}.dynamic-form .grid>div.col-lg-9{grid-column:span 9}.dynamic-form .grid>div.col-lg-10{grid-column:span 10}.dynamic-form .grid>div.col-lg-11{grid-column:span 11}.dynamic-form .grid>div.col-lg-12{grid-column:span 12}}@media (min-width: 1200px){.dynamic-form .grid>div.col-xl-1{grid-column:span 1}.dynamic-form .grid>div.col-xl-2{grid-column:span 2}.dynamic-form .grid>div.col-xl-3{grid-column:span 3}.dynamic-form .grid>div.col-xl-4{grid-column:span 4}.dynamic-form .grid>div.col-xl-5{grid-column:span 5}.dynamic-form .grid>div.col-xl-6{grid-column:span 6}.dynamic-form .grid>div.col-xl-7{grid-column:span 7}.dynamic-form .grid>div.col-xl-8{grid-column:span 8}.dynamic-form .grid>div.col-xl-9{grid-column:span 9}.dynamic-form .grid>div.col-xl-10{grid-column:span 10}.dynamic-form .grid>div.col-xl-11{grid-column:span 11}.dynamic-form .grid>div.col-xl-12{grid-column:span 12}}.dynamic-form .bordered-section{border:1px solid var(--p-surface-200, var(--surface-200, #e5e7eb));border-radius:var(--p-border-radius, var(--border-radius, 6px));padding:1.5rem}.dynamic-form .bordered-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .bordered-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form .heading-section .section-heading{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--text-color);display:flex;align-items:center;gap:.5rem}.dynamic-form .heading-section .section-heading .section-icon{color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header{background-color:var(--surface-50)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header{display:flex;align-items:center;gap:.5rem;width:100%}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-icon{font-size:1.1rem;color:var(--primary-color)}.dynamic-form ::ng-deep .section-panel .p-panel-header .section-header .section-title{font-weight:600;color:var(--text-color)}.dynamic-form ::ng-deep .section-panel .p-panel-content{padding:1.5rem}.dynamic-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--surface-200)}.dialog-footer{display:flex;justify-content:flex-end;gap:.5rem}.drawer-footer{display:flex;justify-content:flex-end;gap:.5rem;padding:1rem;border-top:1px solid var(--surface-200)}.inline-edit-fields{display:flex;flex-direction:column;gap:1rem}.inline-edit-fields .inline-edit-field{display:flex;flex-direction:column;gap:.5rem}.inline-edit-fields .inline-edit-field .field-label{font-weight:500;font-size:.875rem;color:var(--text-color-secondary)}.inline-edit-fields .inline-edit-field .field-display{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background-color:transparent;border:1px solid var(--p-surface-300, var(--surface-300, #d1d5db));border-radius:var(--p-border-radius, var(--border-radius, 6px));cursor:pointer;transition:all .2s ease;min-height:42px}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled){border-color:var(--p-primary-color, var(--primary-color))}.inline-edit-fields .inline-edit-field .field-display:hover:not(.disabled) .edit-icon{opacity:1}.inline-edit-fields .inline-edit-field .field-display.disabled{cursor:not-allowed;opacity:.6;background-color:var(--p-surface-50, var(--surface-50, #f9fafb))}.inline-edit-fields .inline-edit-field .field-display .display-value{flex:1;color:var(--text-color)}.inline-edit-fields .inline-edit-field .field-display .display-value:empty:before{content:attr(data-placeholder);color:var(--text-color-secondary);font-style:italic}.inline-edit-fields .inline-edit-field .field-display .edit-icon{color:var(--p-primary-color, var(--primary-color));font-size:.875rem;opacity:0;transition:opacity .2s ease}.inline-edit-fields .inline-edit-field .field-edit{display:flex;align-items:center;gap:.5rem}.inline-edit-fields .inline-edit-field .field-edit .input-container{flex:1}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field{gap:0}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field label{display:none}.inline-edit-fields .inline-edit-field .field-edit .input-container ::ng-deep .field small.p-error{display:none}.inline-edit-fields .inline-edit-field .field-edit .edit-actions{display:flex;gap:0;flex-shrink:0}\n"] }]
|
|
5956
5863
|
}], ctorParameters: () => [{ type: i2$1.FormBuilder }, { type: TranslationService }, { type: MaskService }, { type: LocaleService }], propDecorators: { sections: [{
|
|
5957
5864
|
type: Input
|
|
5958
5865
|
}], entityData: [{
|
|
@@ -6657,7 +6564,7 @@ const createFilterString = (formField, value) => {
|
|
|
6657
6564
|
return getEnumQuery(name, value, multiple);
|
|
6658
6565
|
case FieldType.String: {
|
|
6659
6566
|
const escapedValue = escapeFilterValue(String(value));
|
|
6660
|
-
return `upper(${name})
|
|
6567
|
+
return `containing(upper(${name}), upper('${escapedValue}'))`;
|
|
6661
6568
|
}
|
|
6662
6569
|
case FieldType.Lookup: {
|
|
6663
6570
|
const lookupId = typeof value === 'object' ? value.id : value;
|