@openmfp/ngx 0.14.11 → 0.15.0
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/fesm2022/openmfp-ngx.mjs +148 -11
- package/fesm2022/openmfp-ngx.mjs.map +1 -1
- package/package.json +1 -1
- package/types/openmfp-ngx.d.ts +31 -5
package/fesm2022/openmfp-ngx.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JSONPath } from 'jsonpath-plus';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { input, computed, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, output, signal, ViewEncapsulation, inject, effect, viewChild, Injector, afterNextRender, Injectable, reflectComponentType, isStandalone, isDevMode, ViewContainerRef, Renderer2, ElementRef, model, SecurityContext
|
|
3
|
+
import { input, computed, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, output, signal, ViewEncapsulation, linkedSignal, forwardRef, inject, effect, viewChild, Injector, afterNextRender, Injectable, reflectComponentType, isStandalone, isDevMode, ViewContainerRef, Renderer2, ElementRef, model, SecurityContext } from '@angular/core';
|
|
4
4
|
import { Icon } from '@fundamental-ngx/ui5-webcomponents/icon';
|
|
5
5
|
import { Link } from '@fundamental-ngx/ui5-webcomponents/link';
|
|
6
6
|
import { Tag } from '@fundamental-ngx/ui5-webcomponents/tag';
|
|
@@ -16,16 +16,18 @@ import { TableHeaderCell } from '@fundamental-ngx/ui5-webcomponents/table-header
|
|
|
16
16
|
import { TableHeaderRow } from '@fundamental-ngx/ui5-webcomponents/table-header-row';
|
|
17
17
|
import { TableRow } from '@fundamental-ngx/ui5-webcomponents/table-row';
|
|
18
18
|
import '@ui5/webcomponents-fiori/dist/illustrations/NoData.js';
|
|
19
|
+
import '@ui5/webcomponents-icons/dist/add.js';
|
|
20
|
+
import '@ui5/webcomponents-icons/dist/delete.js';
|
|
21
|
+
import '@ui5/webcomponents-icons/dist/navigation-down-arrow.js';
|
|
22
|
+
import '@ui5/webcomponents-icons/dist/navigation-right-arrow.js';
|
|
19
23
|
import * as i1 from '@angular/forms';
|
|
20
|
-
import { FormBuilder, FormControl, ReactiveFormsModule } from '@angular/forms';
|
|
24
|
+
import { FormBuilder, FormArray, FormControl, ReactiveFormsModule } from '@angular/forms';
|
|
21
25
|
import { Input } from '@fundamental-ngx/ui5-webcomponents/input';
|
|
22
26
|
import { Label } from '@fundamental-ngx/ui5-webcomponents/label';
|
|
23
27
|
import '@ui5/webcomponents-icons/dist/navigation-left-arrow.js';
|
|
24
|
-
import '@ui5/webcomponents-icons/dist/navigation-right-arrow.js';
|
|
25
28
|
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
|
|
26
29
|
import { Dialog } from '@fundamental-ngx/ui5-webcomponents/dialog';
|
|
27
30
|
import { Title } from '@fundamental-ngx/ui5-webcomponents/title';
|
|
28
|
-
import '@ui5/webcomponents-icons/dist/add.js';
|
|
29
31
|
import '@ui5/webcomponents-icons/dist/search.js';
|
|
30
32
|
import { debounceTime, map, filter } from 'rxjs';
|
|
31
33
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
@@ -455,13 +457,80 @@ function setPropertyByPath(object, path, value) {
|
|
|
455
457
|
return object;
|
|
456
458
|
}
|
|
457
459
|
|
|
460
|
+
/**
|
|
461
|
+
* Internal collection editor rendered by `mfp-declarative-form` when a field
|
|
462
|
+
* carries `propertyCollection` sub-fields.
|
|
463
|
+
*
|
|
464
|
+
* Each entry renders as a collapsible card whose expanded body is a nested
|
|
465
|
+
* `<mfp-declarative-form>` bound to that entry. Live changes flow up
|
|
466
|
+
* through the nested form's `(formValueChange)` output — no `viewChildren`
|
|
467
|
+
* on the class, so this component can safely participate in the mutual
|
|
468
|
+
* import cycle with `DeclarativeForm`.
|
|
469
|
+
*/
|
|
470
|
+
class FormCollectionField {
|
|
471
|
+
fields = input.required(...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
|
|
472
|
+
label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
473
|
+
initialEntries = input([], ...(ngDevMode ? [{ debugName: "initialEntries" }] : /* istanbul ignore next */ []));
|
|
474
|
+
valueChange = output();
|
|
475
|
+
entries = linkedSignal(() => [
|
|
476
|
+
...(this.initialEntries() ?? []),
|
|
477
|
+
], ...(ngDevMode ? [{ debugName: "entries" }] : /* istanbul ignore next */ []));
|
|
478
|
+
expandedIndex = linkedSignal({ ...(ngDevMode ? { debugName: "expandedIndex" } : /* istanbul ignore next */ {}), source: this.initialEntries,
|
|
479
|
+
computation: () => null });
|
|
480
|
+
previewFor(entry, index) {
|
|
481
|
+
for (const field of this.fields()) {
|
|
482
|
+
const raw = entry[field.name];
|
|
483
|
+
if (raw !== undefined && raw !== null && String(raw).trim() !== '') {
|
|
484
|
+
return `${field.label ?? field.name}: ${String(raw)}`;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
const prefix = this.label().trim() || 'Item';
|
|
488
|
+
return `${prefix} ${index + 1}`;
|
|
489
|
+
}
|
|
490
|
+
toggle(index) {
|
|
491
|
+
this.expandedIndex.set(this.expandedIndex() === index ? null : index);
|
|
492
|
+
}
|
|
493
|
+
add() {
|
|
494
|
+
const next = [...this.entries(), {}];
|
|
495
|
+
this.entries.set(next);
|
|
496
|
+
this.expandedIndex.set(next.length - 1);
|
|
497
|
+
this.valueChange.emit(next);
|
|
498
|
+
}
|
|
499
|
+
remove(index) {
|
|
500
|
+
const next = this.entries().filter((_, i) => i !== index);
|
|
501
|
+
this.entries.set(next);
|
|
502
|
+
const expandedIndex = this.expandedIndex();
|
|
503
|
+
if (expandedIndex === index) {
|
|
504
|
+
this.expandedIndex.set(null);
|
|
505
|
+
}
|
|
506
|
+
else if (expandedIndex !== null && expandedIndex > index) {
|
|
507
|
+
// Preserve the same expanded row after removing an earlier one.
|
|
508
|
+
this.expandedIndex.set(expandedIndex - 1);
|
|
509
|
+
}
|
|
510
|
+
this.valueChange.emit(next);
|
|
511
|
+
}
|
|
512
|
+
onEntryValueChange(index, value) {
|
|
513
|
+
const next = this.entries().map((entry, i) => i === index ? { ...value } : entry);
|
|
514
|
+
this.entries.set(next);
|
|
515
|
+
this.valueChange.emit(next);
|
|
516
|
+
}
|
|
517
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: FormCollectionField, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
518
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: FormCollectionField, isStandalone: true, selector: "mfp-form-collection-field", inputs: { fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, initialEntries: { classPropertyName: "initialEntries", publicName: "initialEntries", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"collection\" data-testid=\"collection-field\">\n @for (entry of entries(); track $index; let index = $index) {\n @let expanded = expandedIndex() === index;\n <div\n class=\"card\"\n [class.card--expanded]=\"expanded\"\n [attr.data-testid]=\"'collection-item-' + index\"\n >\n <button\n type=\"button\"\n class=\"card__header\"\n [attr.aria-expanded]=\"expanded\"\n [attr.data-testid]=\"'collection-item-' + index + '-toggle'\"\n (click)=\"toggle(index)\"\n >\n <ui5-icon\n class=\"card__chevron\"\n [name]=\"expanded ? 'navigation-down-arrow' : 'navigation-right-arrow'\"\n />\n <span class=\"card__preview\">{{ previewFor(entry, index) }}</span>\n <span class=\"card__spacer\"></span>\n <ui5-button\n class=\"card__action\"\n design=\"Transparent\"\n icon=\"delete\"\n accessibleName=\"Remove\"\n tooltip=\"Remove\"\n [attr.data-testid]=\"'collection-item-' + index + '-remove'\"\n (click)=\"remove(index); $event.stopPropagation()\"\n />\n </button>\n\n @if (expanded) {\n <div class=\"card__body\">\n <mfp-declarative-form\n [attr.data-testid]=\"'collection-item-' + index + '-form'\"\n [fields]=\"fields()\"\n [initialValues]=\"entry\"\n (formValueChange)=\"onEntryValueChange(index, $event)\"\n />\n </div>\n }\n </div>\n }\n\n <ui5-button\n class=\"collection__add\"\n design=\"Transparent\"\n icon=\"add\"\n accessibleName=\"Add\"\n data-testid=\"collection-add\"\n (click)=\"add()\"\n />\n</div>\n", styles: [":host{display:block;width:100%}.collection{display:flex;flex-direction:column;gap:.5rem;width:100%;padding-top:.25rem}.card{border:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9);border-radius:.5rem;background:var(--sapGroup_TitleBackground, #fff);overflow:hidden}.card--expanded{box-shadow:0 1px 2px #0000000a}.card__header{display:flex;align-items:center;gap:.5rem;width:100%;padding:0 .75rem;background:transparent;border:0;text-align:left;cursor:pointer;font:inherit;min-height:1.5rem;color:var(--sapTextColor, #1d2d3e)}.card__header:hover{background:var(--sapList_Hover_Background, rgba(0, 0, 0, .03))}.card__chevron{flex:0 0 auto;color:var(--sapContent_IconColor, #6a6d70)}.card__preview{font-weight:500;color:var(--sapTextColor, #1d2d3e);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.card__spacer{flex:1}.card__action{flex:0 0 auto}.card__body{padding:.75rem 1rem 1rem;border-top:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9)}.collection__add{align-self:flex-start;color:var(--sapButton_IconColor, #0070f2)}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => Button), selector: "ui5-button, [ui5-button]", inputs: ["design", "disabled", "icon", "endIcon", "submits", "tooltip", "accessibleName", "accessibleNameRef", "accessibilityAttributes", "accessibleDescription", "type", "accessibleRole", "loading", "loadingDelay"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: i0.forwardRef(() => Icon), selector: "ui5-icon, [ui5-icon]", inputs: ["design", "name", "accessibleName", "showTooltip", "mode"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }, { kind: "component", type: i0.forwardRef(() => DeclarativeForm), selector: "mfp-declarative-form", inputs: ["fields", "initialValues", "fieldErrors"], outputs: ["fieldChange", "formSubmit", "formValueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
519
|
+
}
|
|
520
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: FormCollectionField, decorators: [{
|
|
521
|
+
type: Component,
|
|
522
|
+
args: [{ selector: 'mfp-form-collection-field', standalone: true, imports: [Button, Icon, forwardRef(() => DeclarativeForm)], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, template: "<div class=\"collection\" data-testid=\"collection-field\">\n @for (entry of entries(); track $index; let index = $index) {\n @let expanded = expandedIndex() === index;\n <div\n class=\"card\"\n [class.card--expanded]=\"expanded\"\n [attr.data-testid]=\"'collection-item-' + index\"\n >\n <button\n type=\"button\"\n class=\"card__header\"\n [attr.aria-expanded]=\"expanded\"\n [attr.data-testid]=\"'collection-item-' + index + '-toggle'\"\n (click)=\"toggle(index)\"\n >\n <ui5-icon\n class=\"card__chevron\"\n [name]=\"expanded ? 'navigation-down-arrow' : 'navigation-right-arrow'\"\n />\n <span class=\"card__preview\">{{ previewFor(entry, index) }}</span>\n <span class=\"card__spacer\"></span>\n <ui5-button\n class=\"card__action\"\n design=\"Transparent\"\n icon=\"delete\"\n accessibleName=\"Remove\"\n tooltip=\"Remove\"\n [attr.data-testid]=\"'collection-item-' + index + '-remove'\"\n (click)=\"remove(index); $event.stopPropagation()\"\n />\n </button>\n\n @if (expanded) {\n <div class=\"card__body\">\n <mfp-declarative-form\n [attr.data-testid]=\"'collection-item-' + index + '-form'\"\n [fields]=\"fields()\"\n [initialValues]=\"entry\"\n (formValueChange)=\"onEntryValueChange(index, $event)\"\n />\n </div>\n }\n </div>\n }\n\n <ui5-button\n class=\"collection__add\"\n design=\"Transparent\"\n icon=\"add\"\n accessibleName=\"Add\"\n data-testid=\"collection-add\"\n (click)=\"add()\"\n />\n</div>\n", styles: [":host{display:block;width:100%}.collection{display:flex;flex-direction:column;gap:.5rem;width:100%;padding-top:.25rem}.card{border:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9);border-radius:.5rem;background:var(--sapGroup_TitleBackground, #fff);overflow:hidden}.card--expanded{box-shadow:0 1px 2px #0000000a}.card__header{display:flex;align-items:center;gap:.5rem;width:100%;padding:0 .75rem;background:transparent;border:0;text-align:left;cursor:pointer;font:inherit;min-height:1.5rem;color:var(--sapTextColor, #1d2d3e)}.card__header:hover{background:var(--sapList_Hover_Background, rgba(0, 0, 0, .03))}.card__chevron{flex:0 0 auto;color:var(--sapContent_IconColor, #6a6d70)}.card__preview{font-weight:500;color:var(--sapTextColor, #1d2d3e);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.card__spacer{flex:1}.card__action{flex:0 0 auto}.card__body{padding:.75rem 1rem 1rem;border-top:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9)}.collection__add{align-self:flex-start;color:var(--sapButton_IconColor, #0070f2)}\n"] }]
|
|
523
|
+
}], propDecorators: { fields: [{ type: i0.Input, args: [{ isSignal: true, alias: "fields", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], initialEntries: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialEntries", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
524
|
+
|
|
458
525
|
class DeclarativeForm {
|
|
459
526
|
fields = input.required(...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
|
|
460
527
|
initialValues = input({}, ...(ngDevMode ? [{ debugName: "initialValues" }] : /* istanbul ignore next */ []));
|
|
461
528
|
fieldErrors = input({}, ...(ngDevMode ? [{ debugName: "fieldErrors" }] : /* istanbul ignore next */ []));
|
|
462
529
|
fieldChange = output();
|
|
463
530
|
formSubmit = output();
|
|
531
|
+
formValueChange = output();
|
|
464
532
|
form;
|
|
533
|
+
collectionSeeds = signal({}, ...(ngDevMode ? [{ debugName: "collectionSeeds" }] : /* istanbul ignore next */ []));
|
|
465
534
|
fb = inject(FormBuilder);
|
|
466
535
|
constructor() {
|
|
467
536
|
this.form = this.fb.group({});
|
|
@@ -490,6 +559,7 @@ class DeclarativeForm {
|
|
|
490
559
|
control.setValue(target.value);
|
|
491
560
|
control.markAsTouched();
|
|
492
561
|
control.markAsDirty();
|
|
562
|
+
this.formValueChange.emit(this.form.value);
|
|
493
563
|
if (field.validation === 'onChange') {
|
|
494
564
|
this.fieldChange.emit({
|
|
495
565
|
fieldProperty: field.name,
|
|
@@ -497,6 +567,24 @@ class DeclarativeForm {
|
|
|
497
567
|
});
|
|
498
568
|
}
|
|
499
569
|
}
|
|
570
|
+
onCollectionValueChange(field, entries) {
|
|
571
|
+
const array = this.form.controls[field.name];
|
|
572
|
+
if (!array)
|
|
573
|
+
return;
|
|
574
|
+
while (array.length)
|
|
575
|
+
array.removeAt(0);
|
|
576
|
+
for (const entry of entries) {
|
|
577
|
+
array.push(this.buildEntryGroup(entry));
|
|
578
|
+
}
|
|
579
|
+
array.markAsDirty();
|
|
580
|
+
array.markAsTouched();
|
|
581
|
+
if (field.validation === 'onChange' || field.validation === 'onBlur') {
|
|
582
|
+
this.fieldChange.emit({
|
|
583
|
+
fieldProperty: field.name,
|
|
584
|
+
value: entries,
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
}
|
|
500
588
|
getError(name) {
|
|
501
589
|
const control = this.form.controls[name];
|
|
502
590
|
const error = this.fieldErrors()[name];
|
|
@@ -520,17 +608,30 @@ class DeclarativeForm {
|
|
|
520
608
|
clear() {
|
|
521
609
|
this.form.reset();
|
|
522
610
|
}
|
|
611
|
+
collectionEntries(field) {
|
|
612
|
+
return this.collectionSeeds()[field.name] ?? [];
|
|
613
|
+
}
|
|
523
614
|
rebuildControls(fields) {
|
|
524
615
|
const existingControls = this.form.controls;
|
|
525
616
|
const nextFieldNames = new Set(fields.map((field) => field.name));
|
|
526
617
|
for (const field of fields) {
|
|
527
618
|
const existingControl = existingControls[field.name];
|
|
528
|
-
|
|
619
|
+
const wantsCollection = !!field.propertyCollection?.length;
|
|
620
|
+
const existingIsCollection = existingControl instanceof FormArray;
|
|
621
|
+
if (existingControl && wantsCollection !== existingIsCollection) {
|
|
622
|
+
this.form.removeControl(field.name);
|
|
623
|
+
}
|
|
624
|
+
else if (existingControl) {
|
|
529
625
|
existingControl.clearValidators();
|
|
530
626
|
existingControl.updateValueAndValidity({ emitEvent: false });
|
|
531
627
|
continue;
|
|
532
628
|
}
|
|
533
|
-
|
|
629
|
+
if (wantsCollection) {
|
|
630
|
+
this.form.addControl(field.name, this.fb.array([]));
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
this.form.addControl(field.name, new FormControl(''));
|
|
634
|
+
}
|
|
534
635
|
}
|
|
535
636
|
for (const controlName of Object.keys(existingControls)) {
|
|
536
637
|
if (!nextFieldNames.has(controlName)) {
|
|
@@ -543,6 +644,25 @@ class DeclarativeForm {
|
|
|
543
644
|
if (!initialValues) {
|
|
544
645
|
return;
|
|
545
646
|
}
|
|
647
|
+
const seeds = {};
|
|
648
|
+
for (const field of this.fields()) {
|
|
649
|
+
if (!field.propertyCollection?.length)
|
|
650
|
+
continue;
|
|
651
|
+
const raw = initialValues[field.name];
|
|
652
|
+
const entries = Array.isArray(raw)
|
|
653
|
+
? raw
|
|
654
|
+
: [];
|
|
655
|
+
const array = this.form.controls[field.name];
|
|
656
|
+
if (array) {
|
|
657
|
+
while (array.length)
|
|
658
|
+
array.removeAt(0);
|
|
659
|
+
for (const entry of entries) {
|
|
660
|
+
array.push(this.buildEntryGroup(entry));
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
seeds[field.name] = entries;
|
|
664
|
+
}
|
|
665
|
+
this.collectionSeeds.set(seeds);
|
|
546
666
|
this.form.patchValue(initialValues, { emitEvent: false });
|
|
547
667
|
this.form.markAsPristine({ emitEvent: false });
|
|
548
668
|
this.form.updateValueAndValidity({ emitEvent: false });
|
|
@@ -550,17 +670,34 @@ class DeclarativeForm {
|
|
|
550
670
|
buildOutputValue() {
|
|
551
671
|
const result = {};
|
|
552
672
|
for (const key of Object.keys(this.form.controls)) {
|
|
553
|
-
|
|
673
|
+
const control = this.form.controls[key];
|
|
674
|
+
let value = control.value;
|
|
675
|
+
if (control instanceof FormArray) {
|
|
676
|
+
value = control.controls.map((group) => group.controls['entry']?.value ?? {});
|
|
677
|
+
}
|
|
678
|
+
setPropertyByPath(result, key, value);
|
|
554
679
|
}
|
|
555
680
|
return result;
|
|
556
681
|
}
|
|
682
|
+
buildEntryGroup(entry) {
|
|
683
|
+
return this.fb.group({
|
|
684
|
+
entry: new FormControl(entry),
|
|
685
|
+
});
|
|
686
|
+
}
|
|
557
687
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DeclarativeForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
558
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: DeclarativeForm, isStandalone: true, selector: "mfp-declarative-form", inputs: { fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: true, transformFunction: null }, initialValues: { classPropertyName: "initialValues", publicName: "initialValues", isSignal: true, isRequired: false, transformFunction: null }, fieldErrors: { classPropertyName: "fieldErrors", publicName: "fieldErrors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fieldChange: "fieldChange", formSubmit: "formSubmit" }, ngImport: i0, template: "<section class=\"form\" data-testid=\"generic-form\" [formGroup]=\"form\">\n @for (field of fields(); track field.name) {\n @let control = form.controls[field.name];\n <div\n class=\"inputs\"\n [attr.data-testid]=\"'generic-form-field-container-' + field.name\"\n >\n <ui5-label\n show-colon\n [attr.data-testid]=\"'generic-form-field-label-' + field.name\"\n [required]=\"field.required\"\n >{{ field.label }}</ui5-label\n >\n @if (field.values?.length) {\n <ui5-select\n class=\"input\"\n [attr.data-testid]=\"'generic-form-field-' + field.name\"\n [disabled]=\"field.disabled\"\n [required]=\"field.required\"\n [value]=\"control.value\"\n [valueState]=\"getValueState(field.name)\"\n (blur)=\"onFieldBlur(field)\"\n (change)=\"setFormControlValue($event, field)\"\n (input)=\"setFormControlValue($event, field)\"\n >\n @if (getError(field.name); as error) {\n <div slot=\"valueStateMessage\">{{ error }}</div>\n }\n @for (value of [''].concat(field.values ?? []); track value) {\n <ui5-option\n [attr.data-testid]=\"\n 'generic-form-field-' +\n field.name +\n '-option-' +\n (value || 'empty')\n \"\n [selected]=\"value === control.value\"\n [value]=\"value\"\n >{{ value }}</ui5-option\n >\n }\n </ui5-select>\n } @else {\n <ui5-input\n class=\"input\"\n [attr.data-testid]=\"'generic-form-field-' + field.name\"\n [disabled]=\"field.disabled\"\n [required]=\"field.required\"\n [value]=\"control.value\"\n [valueState]=\"getValueState(field.name)\"\n (blur)=\"onFieldBlur(field)\"\n (change)=\"setFormControlValue($event, field)\"\n (input)=\"setFormControlValue($event, field)\"\n >\n @if (getError(field.name); as error) {\n <div slot=\"valueStateMessage\">{{ error }}</div>\n }\n </ui5-input>\n }\n </div>\n }\n</section>\n", styles: [".form>div{display:flex;flex-direction:column;justify-content:space-evenly;align-items:flex-start;margin-bottom:.5rem;width:100%}.input{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: Input, selector: "ui5-input, [ui5-input]", inputs: ["disabled", "placeholder", "readonly", "required", "noTypeahead", "type", "value", "valueState", "name", "showSuggestions", "maxlength", "accessibleName", "accessibleNameRef", "accessibleDescription", "accessibleDescriptionRef", "showClearIcon", "open", "filter"], outputs: ["ui5Change", "ui5Input", "ui5Select", "ui5SelectionChange", "ui5Open", "ui5Close"], exportAs: ["ui5Input"] }, { kind: "component", type: Label, selector: "ui5-label, [ui5-label]", inputs: ["for", "showColon", "required", "wrappingType"], exportAs: ["ui5Label"] }, { kind: "component", type: Select, selector: "ui5-select, [ui5-select]", inputs: ["disabled", "name", "valueState", "required", "readonly", "accessibleName", "accessibleNameRef", "accessibleDescription", "accessibleDescriptionRef", "tooltip", "textSeparator", "value"], outputs: ["ui5Change", "ui5LiveChange", "ui5Open", "ui5Close"], exportAs: ["ui5Select"] }, { kind: "component", type: Option, selector: "ui5-option, [ui5-option]", inputs: ["value", "icon", "additionalText", "tooltip", "selected"], exportAs: ["ui5Option"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
688
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: DeclarativeForm, isStandalone: true, selector: "mfp-declarative-form", inputs: { fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: true, transformFunction: null }, initialValues: { classPropertyName: "initialValues", publicName: "initialValues", isSignal: true, isRequired: false, transformFunction: null }, fieldErrors: { classPropertyName: "fieldErrors", publicName: "fieldErrors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fieldChange: "fieldChange", formSubmit: "formSubmit", formValueChange: "formValueChange" }, ngImport: i0, template: "<section class=\"form\" data-testid=\"generic-form\" [formGroup]=\"form\">\n @for (field of fields(); track field.name) {\n @let control = form.controls[field.name];\n <div\n class=\"inputs\"\n [attr.data-testid]=\"'generic-form-field-container-' + field.name\"\n >\n <ui5-label\n show-colon\n [attr.data-testid]=\"'generic-form-field-label-' + field.name\"\n [required]=\"field.required\"\n >{{ field.label }}</ui5-label\n >\n @if (field.propertyCollection?.length) {\n <mfp-form-collection-field\n [attr.data-testid]=\"'generic-form-field-' + field.name\"\n [fields]=\"field.propertyCollection!\"\n [label]=\"field.label\"\n [initialEntries]=\"collectionEntries(field)\"\n (valueChange)=\"onCollectionValueChange(field, $event)\"\n />\n @if (getError(field.name); as error) {\n <div class=\"collection-error\" role=\"alert\">{{ error }}</div>\n }\n } @else if (field.values?.length) {\n <ui5-select\n class=\"input\"\n [attr.data-testid]=\"'generic-form-field-' + field.name\"\n [disabled]=\"field.disabled\"\n [required]=\"field.required\"\n [value]=\"control.value\"\n [valueState]=\"getValueState(field.name)\"\n (blur)=\"onFieldBlur(field)\"\n (change)=\"setFormControlValue($event, field)\"\n (input)=\"setFormControlValue($event, field)\"\n >\n @if (getError(field.name); as error) {\n <div slot=\"valueStateMessage\">{{ error }}</div>\n }\n @for (value of [''].concat(field.values ?? []); track value) {\n <ui5-option\n [attr.data-testid]=\"\n 'generic-form-field-' +\n field.name +\n '-option-' +\n (value || 'empty')\n \"\n [selected]=\"value === control.value\"\n [value]=\"value\"\n >{{ value }}</ui5-option\n >\n }\n </ui5-select>\n } @else {\n <ui5-input\n class=\"input\"\n [attr.data-testid]=\"'generic-form-field-' + field.name\"\n [disabled]=\"field.disabled\"\n [required]=\"field.required\"\n [value]=\"control.value\"\n [valueState]=\"getValueState(field.name)\"\n (blur)=\"onFieldBlur(field)\"\n (change)=\"setFormControlValue($event, field)\"\n (input)=\"setFormControlValue($event, field)\"\n >\n @if (getError(field.name); as error) {\n <div slot=\"valueStateMessage\">{{ error }}</div>\n }\n </ui5-input>\n }\n </div>\n }\n</section>\n", styles: [".form>div{display:flex;flex-direction:column;justify-content:space-evenly;align-items:flex-start;margin-bottom:.5rem;width:100%}.input{width:100%}.collection-error{color:var(--sapNegativeColor, #b00);font-size:.75rem;margin-top:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: Input, selector: "ui5-input, [ui5-input]", inputs: ["disabled", "placeholder", "readonly", "required", "noTypeahead", "type", "value", "valueState", "name", "showSuggestions", "maxlength", "accessibleName", "accessibleNameRef", "accessibleDescription", "accessibleDescriptionRef", "showClearIcon", "open", "filter"], outputs: ["ui5Change", "ui5Input", "ui5Select", "ui5SelectionChange", "ui5Open", "ui5Close"], exportAs: ["ui5Input"] }, { kind: "component", type: Label, selector: "ui5-label, [ui5-label]", inputs: ["for", "showColon", "required", "wrappingType"], exportAs: ["ui5Label"] }, { kind: "component", type: Select, selector: "ui5-select, [ui5-select]", inputs: ["disabled", "name", "valueState", "required", "readonly", "accessibleName", "accessibleNameRef", "accessibleDescription", "accessibleDescriptionRef", "tooltip", "textSeparator", "value"], outputs: ["ui5Change", "ui5LiveChange", "ui5Open", "ui5Close"], exportAs: ["ui5Select"] }, { kind: "component", type: Option, selector: "ui5-option, [ui5-option]", inputs: ["value", "icon", "additionalText", "tooltip", "selected"], exportAs: ["ui5Option"] }, { kind: "component", type: FormCollectionField, selector: "mfp-form-collection-field", inputs: ["fields", "label", "initialEntries"], outputs: ["valueChange"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
559
689
|
}
|
|
560
690
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DeclarativeForm, decorators: [{
|
|
561
691
|
type: Component,
|
|
562
|
-
args: [{ selector: 'mfp-declarative-form', imports: [
|
|
563
|
-
|
|
692
|
+
args: [{ selector: 'mfp-declarative-form', imports: [
|
|
693
|
+
ReactiveFormsModule,
|
|
694
|
+
Input,
|
|
695
|
+
Label,
|
|
696
|
+
Select,
|
|
697
|
+
Option,
|
|
698
|
+
FormCollectionField,
|
|
699
|
+
], encapsulation: ViewEncapsulation.ShadowDom, template: "<section class=\"form\" data-testid=\"generic-form\" [formGroup]=\"form\">\n @for (field of fields(); track field.name) {\n @let control = form.controls[field.name];\n <div\n class=\"inputs\"\n [attr.data-testid]=\"'generic-form-field-container-' + field.name\"\n >\n <ui5-label\n show-colon\n [attr.data-testid]=\"'generic-form-field-label-' + field.name\"\n [required]=\"field.required\"\n >{{ field.label }}</ui5-label\n >\n @if (field.propertyCollection?.length) {\n <mfp-form-collection-field\n [attr.data-testid]=\"'generic-form-field-' + field.name\"\n [fields]=\"field.propertyCollection!\"\n [label]=\"field.label\"\n [initialEntries]=\"collectionEntries(field)\"\n (valueChange)=\"onCollectionValueChange(field, $event)\"\n />\n @if (getError(field.name); as error) {\n <div class=\"collection-error\" role=\"alert\">{{ error }}</div>\n }\n } @else if (field.values?.length) {\n <ui5-select\n class=\"input\"\n [attr.data-testid]=\"'generic-form-field-' + field.name\"\n [disabled]=\"field.disabled\"\n [required]=\"field.required\"\n [value]=\"control.value\"\n [valueState]=\"getValueState(field.name)\"\n (blur)=\"onFieldBlur(field)\"\n (change)=\"setFormControlValue($event, field)\"\n (input)=\"setFormControlValue($event, field)\"\n >\n @if (getError(field.name); as error) {\n <div slot=\"valueStateMessage\">{{ error }}</div>\n }\n @for (value of [''].concat(field.values ?? []); track value) {\n <ui5-option\n [attr.data-testid]=\"\n 'generic-form-field-' +\n field.name +\n '-option-' +\n (value || 'empty')\n \"\n [selected]=\"value === control.value\"\n [value]=\"value\"\n >{{ value }}</ui5-option\n >\n }\n </ui5-select>\n } @else {\n <ui5-input\n class=\"input\"\n [attr.data-testid]=\"'generic-form-field-' + field.name\"\n [disabled]=\"field.disabled\"\n [required]=\"field.required\"\n [value]=\"control.value\"\n [valueState]=\"getValueState(field.name)\"\n (blur)=\"onFieldBlur(field)\"\n (change)=\"setFormControlValue($event, field)\"\n (input)=\"setFormControlValue($event, field)\"\n >\n @if (getError(field.name); as error) {\n <div slot=\"valueStateMessage\">{{ error }}</div>\n }\n </ui5-input>\n }\n </div>\n }\n</section>\n", styles: [".form>div{display:flex;flex-direction:column;justify-content:space-evenly;align-items:flex-start;margin-bottom:.5rem;width:100%}.input{width:100%}.collection-error{color:var(--sapNegativeColor, #b00);font-size:.75rem;margin-top:.25rem}\n"] }]
|
|
700
|
+
}], ctorParameters: () => [], propDecorators: { fields: [{ type: i0.Input, args: [{ isSignal: true, alias: "fields", required: true }] }], initialValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialValues", required: false }] }], fieldErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldErrors", required: false }] }], fieldChange: [{ type: i0.Output, args: ["fieldChange"] }], formSubmit: [{ type: i0.Output, args: ["formSubmit"] }], formValueChange: [{ type: i0.Output, args: ["formValueChange"] }] } });
|
|
564
701
|
|
|
565
702
|
/**
|
|
566
703
|
* Horizontal filter-tab strip rendered above the table by
|
|
@@ -863,7 +1000,7 @@ class DeclarativeTableCard {
|
|
|
863
1000
|
}, {});
|
|
864
1001
|
}
|
|
865
1002
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DeclarativeTableCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
866
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: DeclarativeTableCard, isStandalone: true, selector: "mfp-declarative-table-card", inputs: { resources: { classPropertyName: "resources", publicName: "resources", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, createFormState: { classPropertyName: "createFormState", publicName: "createFormState", isSignal: true, isRequired: false, transformFunction: null }, editFormState: { classPropertyName: "editFormState", publicName: "editFormState", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionButtonClick: "actionButtonClick", tableRowClicked: "tableRowClicked", loadMoreResources: "loadMoreResources", paginationLimitChanged: "paginationLimitChanged", searchChanged: "searchChanged", createFieldChange: "createFieldChange", editFieldChange: "editFieldChange", createSubmit: "createSubmit", editSubmit: "editSubmit", deleteSubmit: "deleteSubmit", filterTabChanged: "filterTabChanged" }, viewQueries: [{ propertyName: "searchInputRef", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"card\" data-testid=\"generic-table-card\">\n <div class=\"card__header\">\n <div class=\"card__title\">\n @if (header(); as header) {\n {{ header }}\n @if (headerTooltip(); as tooltip) {\n <ui5-icon\n class=\"card__info-icon\"\n name=\"hint\"\n [accessibleName]=\"tooltip\"\n [showTooltip]=\"true\"\n />\n }\n }\n </div>\n <div class=\"card__actions\">\n @if (resourcesSearchable()) {\n @if (searchExpanded()) {\n <ui5-input\n #searchInput\n data-testid=\"generic-table-card-search-input\"\n [class]=\"\n 'card__search-input card__search-input--' +\n (searchCollapsing() ? 'leave' : 'enter')\n \"\n [formControl]=\"searchControl\"\n (animationend)=\"onSearchAnimationEnd()\"\n (blur)=\"onSearchBlur()\"\n />\n }\n <ui5-button\n class=\"card__search-btn\"\n data-testid=\"generic-table-card-search-btn\"\n design=\"Transparent\"\n [accessibleName]=\"searchButtonConfig()?.tooltip ?? 'Search'\"\n [icon]=\"searchButtonConfig()?.icon ?? 'search'\"\n [tooltip]=\"searchButtonConfig()?.tooltip ?? 'Search'\"\n (click)=\"toggleSearch()\"\n />\n }\n @if (createFormConfig()) {\n <ui5-button\n class=\"card__create-btn\"\n data-testid=\"generic-table-card-create-btn\"\n [accessibleName]=\"createButtonConfig()?.text || createButtonConfig()?.tooltip || 'Create'\"\n [design]=\"createButtonConfig()?.design ?? 'Transparent'\"\n [icon]=\"createButtonConfig()?.icon ?? 'add'\"\n [tooltip]=\"createButtonConfig()?.tooltip\"\n (click)=\"createDialogOpen.set(true)\"\n >\n {{ createButtonConfig()?.text ?? '' }}\n </ui5-button>\n }\n </div>\n </div>\n\n @if (hasFilterTabs()) {\n <mfp-filter-tabs\n [tabs]=\"filterTabs()\"\n (tabChanged)=\"onFilterTabChanged($event)\"\n />\n }\n\n <div class=\"card__body\">\n @if (tableConfig(); as config) {\n <mfp-declarative-table\n [columns]=\"effectiveColumns()\"\n [growMode]=\"config.growMode ?? 'Button'\"\n [hasMore]=\"config.hasMore ?? false\"\n [height]=\"config.height\"\n [loadMoreButtonText]=\"config.loadMoreButtonText ?? 'Load More'\"\n [paginationLimit]=\"config.paginationLimit ?? 5\"\n [resources]=\"resources()\"\n [totalItemsCount]=\"config.totalItemsCount\"\n (buttonClick)=\"onButtonClick($event)\"\n (loadMoreResources)=\"loadMoreResources.emit()\"\n (paginationLimitChanged)=\"paginationLimitChanged.emit($event)\"\n (tableRowClicked)=\"tableRowClicked.emit($event)\"\n />\n }\n </div>\n</div>\n\n@if (createFormConfig(); as config) {\n <ui5-dialog\n data-testid=\"generic-table-card-create-dialog\"\n [accessibleName]=\"config.title ?? 'Create'\"\n [open]=\"createDialogOpen()\"\n (ui5BeforeClose)=\"createDialogOpen.set(false)\"\n >\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{ config.title ?? 'Create' }}</ui5-title>\n </div>\n <div class=\"dialog__body\">\n <mfp-declarative-form\n #createForm\n [fieldErrors]=\"createFormState().fieldErrors ?? {}\"\n [fields]=\"config.fields\"\n (fieldChange)=\"onCreateFieldChange($event)\"\n (formSubmit)=\"onCreateSubmit($event)\"\n />\n </div>\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"generic-table-card-create-confirm\"\n design=\"Emphasized\"\n [disabled]=\"hasErrors(createFormState())\"\n (click)=\"createForm.submit()\"\n >\n {{ config.confirmLabel ?? 'Save' }}\n </ui5-button>\n <ui5-button data-testid=\"generic-table-card-create-cancel\" design=\"Transparent\" (click)=\"closeCreateDialog()\">\n {{ config.cancelLabel ?? 'Cancel' }}\n </ui5-button>\n </div>\n </ui5-dialog>\n}\n\n@if (editFormConfig(); as config) {\n <ui5-dialog\n data-testid=\"generic-table-card-edit-dialog\"\n [accessibleName]=\"config.title ?? 'Edit'\"\n [open]=\"editDialogOpen()\"\n (ui5BeforeClose)=\"editDialogOpen.set(false)\"\n >\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{ config.title ?? 'Edit' }}</ui5-title>\n </div>\n <div class=\"dialog__body\">\n <mfp-declarative-form\n #editForm\n [fieldErrors]=\"editFormState().fieldErrors ?? {}\"\n [fields]=\"config.fields\"\n [initialValues]=\"editInitialValue()\"\n (fieldChange)=\"onEditFieldChange($event)\"\n (formSubmit)=\"onEditSubmit($event)\"\n />\n </div>\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"generic-table-card-edit-confirm\"\n design=\"Emphasized\"\n [disabled]=\"hasErrors(editFormState())\"\n (click)=\"editForm.submit()\"\n >\n {{ config.confirmLabel ?? 'Edit' }}\n </ui5-button>\n <ui5-button data-testid=\"generic-table-card-edit-cancel\" design=\"Transparent\" (click)=\"closeEditDialog()\">\n {{ config.cancelLabel ?? 'Cancel' }}\n </ui5-button>\n </div>\n </ui5-dialog>\n}\n\n@if (deleteConfirmationConfig(); as config) {\n <ui5-dialog\n data-testid=\"generic-table-card-delete-dialog\"\n [accessibleName]=\"config.title ?? 'Confirm Delete'\"\n [open]=\"deleteDialogOpen()\"\n (ui5BeforeClose)=\"deleteDialogOpen.set(false)\"\n >\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{ config.title ?? 'Confirm Delete' }}</ui5-title>\n </div>\n @if (config.message) {\n <div class=\"dialog__body\">\n <p class=\"dialog__message\">{{ config.message }}</p>\n </div>\n }\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button data-testid=\"generic-table-card-delete-confirm\" design=\"Negative\" (click)=\"onDeleteSubmit()\">\n {{ config.confirmLabel ?? 'Delete' }}\n </ui5-button>\n <ui5-button data-testid=\"generic-table-card-delete-cancel\" design=\"Transparent\" (click)=\"closeDeleteDialog()\">\n {{ config.cancelLabel ?? 'Cancel' }}\n </ui5-button>\n </div>\n </ui5-dialog>\n}\n", styles: [":host{display:block}@keyframes slide-in{0%{opacity:0;transform:scaleX(0)}to{opacity:1;transform:scaleX(1)}}@keyframes slide-out{0%{opacity:1;transform:scaleX(1)}to{opacity:0;transform:scaleX(0)}}.card{display:flex;flex-direction:column;border:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9);border-radius:16px;background:var(--sapGroup_TitleBackground, #fff)}.card__header{display:flex;align-items:center;justify-content:space-between;min-height:3rem;padding:0 1rem}.card__title{color:var(--sapTile_TitleTextColor);text-overflow:ellipsis;font-family:var(--Font-Family-sapFontFamily, 72);font-size:var(--Font-Size-sapFontHeader6Size, 16px);font-style:normal;font-weight:700;line-height:normal;display:flex;align-items:center}.card__actions{display:flex;align-items:center;gap:.5rem}.card__info-icon{color:var(--sapButton_IconColor, #0070f2);margin-left:.5rem}.card__search-input{transform-origin:right center}.card__search-input--enter{animation:slide-in .2s ease-out both}.card__search-input--leave{animation:slide-out .2s ease-in both}.card__create-btn,.card__search-btn{min-width:auto;color:var(--sapButton_IconColor, #0070f2)}.card__body{flex:1;overflow:auto}.dialog__header{display:flex;align-items:flex-start;padding:.75rem 1rem}.dialog__body{margin:-1rem;min-width:320px;padding:1rem}.dialog__message{padding:1rem;margin:0;font-size:.875rem;max-width:320px}.dialog__footer{display:flex;justify-content:space-between;align-items:center;gap:.5rem;padding:.5rem 1rem;margin:0 -1rem;width:100%}\n"], dependencies: [{ kind: "component", type: DeclarativeTable, selector: "mfp-declarative-table", inputs: ["columns", "resources", "trackByPath", "totalItemsCount", "paginationLimit", "hasMore", "growMode", "loadMoreButtonText", "height"], outputs: ["buttonClick", "tableRowClicked", "loadMoreResources", "paginationLimitChanged"] }, { kind: "component", type: DeclarativeForm, selector: "mfp-declarative-form", inputs: ["fields", "initialValues", "fieldErrors"], outputs: ["fieldChange", "formSubmit"] }, { kind: "component", type: FilterTabs, selector: "mfp-filter-tabs", inputs: ["tabs"], outputs: ["tabChanged"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: Dialog, selector: "ui5-dialog, [ui5-dialog]", inputs: ["headerText", "stretch", "draggable", "resizable", "state", "initialFocus", "preventFocusRestore", "accessibleName", "accessibleNameRef", "accessibleRole", "accessibleDescription", "accessibleDescriptionRef", "preventInitialFocus", "open"], outputs: ["ui5BeforeOpen", "ui5Open", "ui5BeforeClose", "ui5Close"], exportAs: ["ui5Dialog"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["wrappingType", "level", "size"], exportAs: ["ui5Title"] }, { kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["design", "disabled", "icon", "endIcon", "submits", "tooltip", "accessibleName", "accessibleNameRef", "accessibilityAttributes", "accessibleDescription", "type", "accessibleRole", "loading", "loadingDelay"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Icon, selector: "ui5-icon, [ui5-icon]", inputs: ["design", "name", "accessibleName", "showTooltip", "mode"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }, { kind: "component", type: Input, selector: "ui5-input, [ui5-input]", inputs: ["disabled", "placeholder", "readonly", "required", "noTypeahead", "type", "value", "valueState", "name", "showSuggestions", "maxlength", "accessibleName", "accessibleNameRef", "accessibleDescription", "accessibleDescriptionRef", "showClearIcon", "open", "filter"], outputs: ["ui5Change", "ui5Input", "ui5Select", "ui5SelectionChange", "ui5Open", "ui5Close"], exportAs: ["ui5Input"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
1003
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: DeclarativeTableCard, isStandalone: true, selector: "mfp-declarative-table-card", inputs: { resources: { classPropertyName: "resources", publicName: "resources", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, createFormState: { classPropertyName: "createFormState", publicName: "createFormState", isSignal: true, isRequired: false, transformFunction: null }, editFormState: { classPropertyName: "editFormState", publicName: "editFormState", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionButtonClick: "actionButtonClick", tableRowClicked: "tableRowClicked", loadMoreResources: "loadMoreResources", paginationLimitChanged: "paginationLimitChanged", searchChanged: "searchChanged", createFieldChange: "createFieldChange", editFieldChange: "editFieldChange", createSubmit: "createSubmit", editSubmit: "editSubmit", deleteSubmit: "deleteSubmit", filterTabChanged: "filterTabChanged" }, viewQueries: [{ propertyName: "searchInputRef", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"card\" data-testid=\"generic-table-card\">\n <div class=\"card__header\">\n <div class=\"card__title\">\n @if (header(); as header) {\n {{ header }}\n @if (headerTooltip(); as tooltip) {\n <ui5-icon\n class=\"card__info-icon\"\n name=\"hint\"\n [accessibleName]=\"tooltip\"\n [showTooltip]=\"true\"\n />\n }\n }\n </div>\n <div class=\"card__actions\">\n @if (resourcesSearchable()) {\n @if (searchExpanded()) {\n <ui5-input\n #searchInput\n data-testid=\"generic-table-card-search-input\"\n [class]=\"\n 'card__search-input card__search-input--' +\n (searchCollapsing() ? 'leave' : 'enter')\n \"\n [formControl]=\"searchControl\"\n (animationend)=\"onSearchAnimationEnd()\"\n (blur)=\"onSearchBlur()\"\n />\n }\n <ui5-button\n class=\"card__search-btn\"\n data-testid=\"generic-table-card-search-btn\"\n design=\"Transparent\"\n [accessibleName]=\"searchButtonConfig()?.tooltip ?? 'Search'\"\n [icon]=\"searchButtonConfig()?.icon ?? 'search'\"\n [tooltip]=\"searchButtonConfig()?.tooltip ?? 'Search'\"\n (click)=\"toggleSearch()\"\n />\n }\n @if (createFormConfig()) {\n <ui5-button\n class=\"card__create-btn\"\n data-testid=\"generic-table-card-create-btn\"\n [accessibleName]=\"createButtonConfig()?.text || createButtonConfig()?.tooltip || 'Create'\"\n [design]=\"createButtonConfig()?.design ?? 'Transparent'\"\n [icon]=\"createButtonConfig()?.icon ?? 'add'\"\n [tooltip]=\"createButtonConfig()?.tooltip\"\n (click)=\"createDialogOpen.set(true)\"\n >\n {{ createButtonConfig()?.text ?? '' }}\n </ui5-button>\n }\n </div>\n </div>\n\n @if (hasFilterTabs()) {\n <mfp-filter-tabs\n [tabs]=\"filterTabs()\"\n (tabChanged)=\"onFilterTabChanged($event)\"\n />\n }\n\n <div class=\"card__body\">\n @if (tableConfig(); as config) {\n <mfp-declarative-table\n [columns]=\"effectiveColumns()\"\n [growMode]=\"config.growMode ?? 'Button'\"\n [hasMore]=\"config.hasMore ?? false\"\n [height]=\"config.height\"\n [loadMoreButtonText]=\"config.loadMoreButtonText ?? 'Load More'\"\n [paginationLimit]=\"config.paginationLimit ?? 5\"\n [resources]=\"resources()\"\n [totalItemsCount]=\"config.totalItemsCount\"\n (buttonClick)=\"onButtonClick($event)\"\n (loadMoreResources)=\"loadMoreResources.emit()\"\n (paginationLimitChanged)=\"paginationLimitChanged.emit($event)\"\n (tableRowClicked)=\"tableRowClicked.emit($event)\"\n />\n }\n </div>\n</div>\n\n@if (createFormConfig(); as config) {\n <ui5-dialog\n data-testid=\"generic-table-card-create-dialog\"\n [accessibleName]=\"config.title ?? 'Create'\"\n [open]=\"createDialogOpen()\"\n (ui5BeforeClose)=\"createDialogOpen.set(false)\"\n >\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{ config.title ?? 'Create' }}</ui5-title>\n </div>\n <div class=\"dialog__body\">\n <mfp-declarative-form\n #createForm\n [fieldErrors]=\"createFormState().fieldErrors ?? {}\"\n [fields]=\"config.fields\"\n (fieldChange)=\"onCreateFieldChange($event)\"\n (formSubmit)=\"onCreateSubmit($event)\"\n />\n </div>\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"generic-table-card-create-confirm\"\n design=\"Emphasized\"\n [disabled]=\"hasErrors(createFormState())\"\n (click)=\"createForm.submit()\"\n >\n {{ config.confirmLabel ?? 'Save' }}\n </ui5-button>\n <ui5-button data-testid=\"generic-table-card-create-cancel\" design=\"Transparent\" (click)=\"closeCreateDialog()\">\n {{ config.cancelLabel ?? 'Cancel' }}\n </ui5-button>\n </div>\n </ui5-dialog>\n}\n\n@if (editFormConfig(); as config) {\n <ui5-dialog\n data-testid=\"generic-table-card-edit-dialog\"\n [accessibleName]=\"config.title ?? 'Edit'\"\n [open]=\"editDialogOpen()\"\n (ui5BeforeClose)=\"editDialogOpen.set(false)\"\n >\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{ config.title ?? 'Edit' }}</ui5-title>\n </div>\n <div class=\"dialog__body\">\n <mfp-declarative-form\n #editForm\n [fieldErrors]=\"editFormState().fieldErrors ?? {}\"\n [fields]=\"config.fields\"\n [initialValues]=\"editInitialValue()\"\n (fieldChange)=\"onEditFieldChange($event)\"\n (formSubmit)=\"onEditSubmit($event)\"\n />\n </div>\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"generic-table-card-edit-confirm\"\n design=\"Emphasized\"\n [disabled]=\"hasErrors(editFormState())\"\n (click)=\"editForm.submit()\"\n >\n {{ config.confirmLabel ?? 'Edit' }}\n </ui5-button>\n <ui5-button data-testid=\"generic-table-card-edit-cancel\" design=\"Transparent\" (click)=\"closeEditDialog()\">\n {{ config.cancelLabel ?? 'Cancel' }}\n </ui5-button>\n </div>\n </ui5-dialog>\n}\n\n@if (deleteConfirmationConfig(); as config) {\n <ui5-dialog\n data-testid=\"generic-table-card-delete-dialog\"\n [accessibleName]=\"config.title ?? 'Confirm Delete'\"\n [open]=\"deleteDialogOpen()\"\n (ui5BeforeClose)=\"deleteDialogOpen.set(false)\"\n >\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{ config.title ?? 'Confirm Delete' }}</ui5-title>\n </div>\n @if (config.message) {\n <div class=\"dialog__body\">\n <p class=\"dialog__message\">{{ config.message }}</p>\n </div>\n }\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button data-testid=\"generic-table-card-delete-confirm\" design=\"Negative\" (click)=\"onDeleteSubmit()\">\n {{ config.confirmLabel ?? 'Delete' }}\n </ui5-button>\n <ui5-button data-testid=\"generic-table-card-delete-cancel\" design=\"Transparent\" (click)=\"closeDeleteDialog()\">\n {{ config.cancelLabel ?? 'Cancel' }}\n </ui5-button>\n </div>\n </ui5-dialog>\n}\n", styles: [":host{display:block}@keyframes slide-in{0%{opacity:0;transform:scaleX(0)}to{opacity:1;transform:scaleX(1)}}@keyframes slide-out{0%{opacity:1;transform:scaleX(1)}to{opacity:0;transform:scaleX(0)}}.card{display:flex;flex-direction:column;border:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9);border-radius:16px;background:var(--sapGroup_TitleBackground, #fff)}.card__header{display:flex;align-items:center;justify-content:space-between;min-height:3rem;padding:0 1rem}.card__title{color:var(--sapTile_TitleTextColor);text-overflow:ellipsis;font-family:var(--Font-Family-sapFontFamily, 72);font-size:var(--Font-Size-sapFontHeader6Size, 16px);font-style:normal;font-weight:700;line-height:normal;display:flex;align-items:center}.card__actions{display:flex;align-items:center;gap:.5rem}.card__info-icon{color:var(--sapButton_IconColor, #0070f2);margin-left:.5rem}.card__search-input{transform-origin:right center}.card__search-input--enter{animation:slide-in .2s ease-out both}.card__search-input--leave{animation:slide-out .2s ease-in both}.card__create-btn,.card__search-btn{min-width:auto;color:var(--sapButton_IconColor, #0070f2)}.card__body{flex:1;overflow:auto}.dialog__header{display:flex;align-items:flex-start;padding:.75rem 1rem}.dialog__body{margin:-1rem;min-width:320px;padding:1rem}.dialog__message{padding:1rem;margin:0;font-size:.875rem;max-width:320px}.dialog__footer{display:flex;justify-content:space-between;align-items:center;gap:.5rem;padding:.5rem 1rem;margin:0 -1rem;width:100%}\n"], dependencies: [{ kind: "component", type: DeclarativeTable, selector: "mfp-declarative-table", inputs: ["columns", "resources", "trackByPath", "totalItemsCount", "paginationLimit", "hasMore", "growMode", "loadMoreButtonText", "height"], outputs: ["buttonClick", "tableRowClicked", "loadMoreResources", "paginationLimitChanged"] }, { kind: "component", type: DeclarativeForm, selector: "mfp-declarative-form", inputs: ["fields", "initialValues", "fieldErrors"], outputs: ["fieldChange", "formSubmit", "formValueChange"] }, { kind: "component", type: FilterTabs, selector: "mfp-filter-tabs", inputs: ["tabs"], outputs: ["tabChanged"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: Dialog, selector: "ui5-dialog, [ui5-dialog]", inputs: ["headerText", "stretch", "draggable", "resizable", "state", "initialFocus", "preventFocusRestore", "accessibleName", "accessibleNameRef", "accessibleRole", "accessibleDescription", "accessibleDescriptionRef", "preventInitialFocus", "open"], outputs: ["ui5BeforeOpen", "ui5Open", "ui5BeforeClose", "ui5Close"], exportAs: ["ui5Dialog"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["wrappingType", "level", "size"], exportAs: ["ui5Title"] }, { kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["design", "disabled", "icon", "endIcon", "submits", "tooltip", "accessibleName", "accessibleNameRef", "accessibilityAttributes", "accessibleDescription", "type", "accessibleRole", "loading", "loadingDelay"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Icon, selector: "ui5-icon, [ui5-icon]", inputs: ["design", "name", "accessibleName", "showTooltip", "mode"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }, { kind: "component", type: Input, selector: "ui5-input, [ui5-input]", inputs: ["disabled", "placeholder", "readonly", "required", "noTypeahead", "type", "value", "valueState", "name", "showSuggestions", "maxlength", "accessibleName", "accessibleNameRef", "accessibleDescription", "accessibleDescriptionRef", "showClearIcon", "open", "filter"], outputs: ["ui5Change", "ui5Input", "ui5Select", "ui5SelectionChange", "ui5Open", "ui5Close"], exportAs: ["ui5Input"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
867
1004
|
}
|
|
868
1005
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DeclarativeTableCard, decorators: [{
|
|
869
1006
|
type: Component,
|