@openmfp/ngx 0.18.13 → 0.20.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/LICENSE +201 -0
- package/README.md +6 -6
- package/fesm2022/openmfp-ngx.mjs +876 -358
- package/package.json +12 -11
- package/types/openmfp-ngx.d.ts +114 -30
- package/fesm2022/openmfp-ngx.mjs.map +0 -1
package/fesm2022/openmfp-ngx.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, Injectable, reflectComponentType, isStandalone, isDevMode, input, output, inject, computed, viewChild, ViewContainerRef, Renderer2, effect, ViewEncapsulation, Component, ElementRef, Injector, model, SecurityContext, linkedSignal, afterNextRender, Pipe, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, forwardRef } from '@angular/core';
|
|
2
|
+
import { signal, Injectable, reflectComponentType, isStandalone, isDevMode, input, output, inject, computed, viewChild, ViewContainerRef, Renderer2, effect, ViewEncapsulation, Component, ElementRef, Injector, model, booleanAttribute, numberAttribute, SecurityContext, linkedSignal, afterNextRender, Pipe, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, forwardRef } from '@angular/core';
|
|
3
3
|
import { Button } from '@fundamental-ngx/ui5-webcomponents/button';
|
|
4
4
|
import { Icon } from '@fundamental-ngx/ui5-webcomponents/icon';
|
|
5
5
|
import '@ui5/webcomponents-icons/dist/resize-corner.js';
|
|
@@ -11,6 +11,7 @@ import { ListItemCustom } from '@fundamental-ngx/ui5-webcomponents/list-item-cus
|
|
|
11
11
|
import { Switch } from '@fundamental-ngx/ui5-webcomponents/switch';
|
|
12
12
|
import { GridStackEngine } from 'gridstack/dist/gridstack-engine';
|
|
13
13
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
14
|
+
import { BusyIndicator } from '@fundamental-ngx/ui5-webcomponents/busy-indicator';
|
|
14
15
|
import { Menu } from '@fundamental-ngx/ui5-webcomponents/menu';
|
|
15
16
|
import { MenuItem } from '@fundamental-ngx/ui5-webcomponents/menu-item';
|
|
16
17
|
import { MenuSeparator } from '@fundamental-ngx/ui5-webcomponents/menu-separator';
|
|
@@ -41,6 +42,7 @@ import { TableHeaderCell } from '@fundamental-ngx/ui5-webcomponents/table-header
|
|
|
41
42
|
import { TableHeaderRow } from '@fundamental-ngx/ui5-webcomponents/table-header-row';
|
|
42
43
|
import { TableRow } from '@fundamental-ngx/ui5-webcomponents/table-row';
|
|
43
44
|
import '@ui5/webcomponents-fiori/dist/illustrations/NoData.js';
|
|
45
|
+
import '@ui5/webcomponents-fiori/dist/illustrations/UnableToLoad.js';
|
|
44
46
|
import '@ui5/webcomponents-icons/dist/close-command-field.js';
|
|
45
47
|
import '@ui5/webcomponents-icons/dist/navigation-left-arrow.js';
|
|
46
48
|
import '@ui5/webcomponents-icons/dist/open-command-field.js';
|
|
@@ -72,40 +74,12 @@ const CELL_HEIGHT = 10;
|
|
|
72
74
|
const DASHBOARD_CARD_DRAG_ORIGIN_CLASS = 'mfp-dashboard-card-drag-origin';
|
|
73
75
|
const DASHBOARD_CARD_DRAG_ORIGIN_SELECTOR = `.${DASHBOARD_CARD_DRAG_ORIGIN_CLASS}`;
|
|
74
76
|
|
|
75
|
-
var
|
|
76
|
-
var
|
|
77
|
-
var
|
|
78
|
-
var
|
|
79
|
-
var save$1 = "Speichern";
|
|
80
|
-
var cancel$1 = "Abbrechen";
|
|
81
|
-
var discard$1 = "Verwerfen";
|
|
82
|
-
var discardChanges$1 = "Änderungen verwerfen";
|
|
83
|
-
var discardConfirmBody$1 = "Änderungen verwerfen? Diese Aktion kann nicht rückgängig gemacht werden.";
|
|
84
|
-
var unsavedNavBody$1 = "Sie verlassen diese Seite. Speichern oder verwerfen Sie die Änderungen, um fortzufahren. Diese Aktion kann nicht rückgängig gemacht werden.";
|
|
85
|
-
var noCardsAvailable$1 = "Keine Karten verfügbar.";
|
|
86
|
-
var removeSection$1 = "Bereich entfernen";
|
|
87
|
-
var removeCard$1 = "Karte entfernen";
|
|
88
|
-
var resizable$1 = "Größenveränderbar";
|
|
89
|
-
var de = {
|
|
90
|
-
unsavedChanges: unsavedChanges$1,
|
|
91
|
-
editCards: editCards$1,
|
|
92
|
-
editView: editView$1,
|
|
93
|
-
actions: actions$1,
|
|
94
|
-
save: save$1,
|
|
95
|
-
cancel: cancel$1,
|
|
96
|
-
discard: discard$1,
|
|
97
|
-
discardChanges: discardChanges$1,
|
|
98
|
-
discardConfirmBody: discardConfirmBody$1,
|
|
99
|
-
unsavedNavBody: unsavedNavBody$1,
|
|
100
|
-
noCardsAvailable: noCardsAvailable$1,
|
|
101
|
-
removeSection: removeSection$1,
|
|
102
|
-
removeCard: removeCard$1,
|
|
103
|
-
resizable: resizable$1
|
|
104
|
-
};
|
|
105
|
-
|
|
77
|
+
var title = "Hi!";
|
|
78
|
+
var description = "You're on the Dashboard";
|
|
79
|
+
var editHomeButton = "Edit Home";
|
|
80
|
+
var editCardsButton = "Edit Cards";
|
|
106
81
|
var unsavedChanges = "Unsaved Changes";
|
|
107
82
|
var editCards = "Edit Cards";
|
|
108
|
-
var editView = "Edit View";
|
|
109
83
|
var actions = "Actions";
|
|
110
84
|
var save = "Save";
|
|
111
85
|
var cancel = "Cancel";
|
|
@@ -114,13 +88,19 @@ var discardChanges = "Discard Changes";
|
|
|
114
88
|
var discardConfirmBody = "Discard the changes? This action cannot be undone.";
|
|
115
89
|
var unsavedNavBody = "You are leaving this page. Save or discard the changes to proceed. This action cannot be undone.";
|
|
116
90
|
var noCardsAvailable = "No cards available.";
|
|
91
|
+
var emptyStateTitle = "Your home is empty";
|
|
92
|
+
var emptyStateDescription = "Add cards to customize your home page.";
|
|
93
|
+
var emptyStateIllustration = "No applications";
|
|
117
94
|
var removeSection = "Remove section";
|
|
118
95
|
var removeCard = "Remove card";
|
|
119
96
|
var resizable = "Resizable";
|
|
120
97
|
var en = {
|
|
98
|
+
title: title,
|
|
99
|
+
description: description,
|
|
100
|
+
editHomeButton: editHomeButton,
|
|
101
|
+
editCardsButton: editCardsButton,
|
|
121
102
|
unsavedChanges: unsavedChanges,
|
|
122
103
|
editCards: editCards,
|
|
123
|
-
editView: editView,
|
|
124
104
|
actions: actions,
|
|
125
105
|
save: save,
|
|
126
106
|
cancel: cancel,
|
|
@@ -129,15 +109,21 @@ var en = {
|
|
|
129
109
|
discardConfirmBody: discardConfirmBody,
|
|
130
110
|
unsavedNavBody: unsavedNavBody,
|
|
131
111
|
noCardsAvailable: noCardsAvailable,
|
|
112
|
+
emptyStateTitle: emptyStateTitle,
|
|
113
|
+
emptyStateDescription: emptyStateDescription,
|
|
114
|
+
emptyStateIllustration: emptyStateIllustration,
|
|
132
115
|
removeSection: removeSection,
|
|
133
116
|
removeCard: removeCard,
|
|
134
117
|
resizable: resizable
|
|
135
118
|
};
|
|
136
119
|
|
|
137
120
|
const DASHBOARD_I18N_KEYS = {
|
|
121
|
+
TITLE: 'title',
|
|
122
|
+
DESCRIPTION: 'description',
|
|
123
|
+
EDIT_HOME_BUTTON: 'editHomeButton',
|
|
124
|
+
EDIT_CARDS_BUTTON: 'editCardsButton',
|
|
138
125
|
UNSAVED_CHANGES: 'unsavedChanges',
|
|
139
126
|
EDIT_CARDS: 'editCards',
|
|
140
|
-
EDIT_VIEW: 'editView',
|
|
141
127
|
ACTIONS: 'actions',
|
|
142
128
|
SAVE: 'save',
|
|
143
129
|
CANCEL: 'cancel',
|
|
@@ -146,32 +132,43 @@ const DASHBOARD_I18N_KEYS = {
|
|
|
146
132
|
DISCARD_CONFIRM_BODY: 'discardConfirmBody',
|
|
147
133
|
UNSAVED_NAV_BODY: 'unsavedNavBody',
|
|
148
134
|
NO_CARDS_AVAILABLE: 'noCardsAvailable',
|
|
135
|
+
EMPTY_STATE_TITLE: 'emptyStateTitle',
|
|
136
|
+
EMPTY_STATE_DESCRIPTION: 'emptyStateDescription',
|
|
137
|
+
EMPTY_STATE_ILLUSTRATION: 'emptyStateIllustration',
|
|
149
138
|
REMOVE_SECTION: 'removeSection',
|
|
150
139
|
REMOVE_CARD: 'removeCard',
|
|
151
140
|
RESIZABLE: 'resizable',
|
|
152
141
|
};
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
142
|
+
/**
|
|
143
|
+
* Built-in English strings. This is the only translation the library ships and
|
|
144
|
+
* the fallback used whenever a key is not supplied by the client through
|
|
145
|
+
* `DashboardConfig.i18n`.
|
|
146
|
+
*/
|
|
147
|
+
const EN_DEFAULTS = en;
|
|
157
148
|
|
|
158
149
|
/**
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
150
|
+
* Resolves translation keys for the dashboard chrome (toolbar buttons,
|
|
151
|
+
* dialogs, a11y labels). Provided at the `Dashboard` component level so every
|
|
152
|
+
* nested dashboard component shares the same instance — child components
|
|
153
|
+
* inject it and react to translation changes automatically because
|
|
154
|
+
* `getTranslation` reads the `overrides` signal on every call.
|
|
155
|
+
*
|
|
156
|
+
* The library ships English only (`EN_DEFAULTS`). Client applications supply
|
|
157
|
+
* translated strings through `DashboardConfig.i18n`, which the `Dashboard`
|
|
158
|
+
* component pushes into `overrides`; switching language is just the client
|
|
159
|
+
* swapping that object. Any key not present in the overrides falls back to the
|
|
160
|
+
* English default, and finally to the key itself.
|
|
165
161
|
*/
|
|
166
162
|
class DashboardI18nService {
|
|
167
|
-
|
|
163
|
+
overrides = signal({}, /* @ts-ignore */
|
|
164
|
+
...(ngDevMode ? [{ debugName: "overrides" }] : /* istanbul ignore next */ []));
|
|
168
165
|
getTranslation(key) {
|
|
169
|
-
return
|
|
166
|
+
return this.overrides()[key] ?? EN_DEFAULTS[key] ?? key;
|
|
170
167
|
}
|
|
171
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
172
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
168
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DashboardI18nService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
169
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DashboardI18nService });
|
|
173
170
|
}
|
|
174
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
171
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DashboardI18nService, decorators: [{
|
|
175
172
|
type: Injectable
|
|
176
173
|
}] });
|
|
177
174
|
|
|
@@ -297,8 +294,10 @@ function mountWcCard(cfg, container, onCleanup, renderer) {
|
|
|
297
294
|
}
|
|
298
295
|
|
|
299
296
|
class DashboardCard {
|
|
300
|
-
card = input.required(
|
|
301
|
-
|
|
297
|
+
card = input.required(/* @ts-ignore */
|
|
298
|
+
...(ngDevMode ? [{ debugName: "card" }] : /* istanbul ignore next */ []));
|
|
299
|
+
editMode = input(false, /* @ts-ignore */
|
|
300
|
+
...(ngDevMode ? [{ debugName: "editMode" }] : /* istanbul ignore next */ []));
|
|
302
301
|
removeCard = output();
|
|
303
302
|
i18n = inject(DashboardI18nService);
|
|
304
303
|
i18nKeys = DASHBOARD_I18N_KEYS;
|
|
@@ -307,11 +306,13 @@ class DashboardCard {
|
|
|
307
306
|
gridColumn = computed(() => {
|
|
308
307
|
const width = this.card().w ?? 12;
|
|
309
308
|
return this.createGridTrack(this.card().x, width);
|
|
310
|
-
},
|
|
309
|
+
}, /* @ts-ignore */
|
|
310
|
+
...(ngDevMode ? [{ debugName: "gridColumn" }] : /* istanbul ignore next */ []));
|
|
311
311
|
gridRow = computed(() => {
|
|
312
312
|
const height = this.card().h ?? 100;
|
|
313
313
|
return this.createGridTrack(this.card().y, height);
|
|
314
|
-
},
|
|
314
|
+
}, /* @ts-ignore */
|
|
315
|
+
...(ngDevMode ? [{ debugName: "gridRow" }] : /* istanbul ignore next */ []));
|
|
315
316
|
host = viewChild('elementHost', { ...(ngDevMode ? { debugName: "host" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
|
|
316
317
|
renderer = inject(Renderer2);
|
|
317
318
|
mountCfg = computed(() => {
|
|
@@ -352,15 +353,15 @@ class DashboardCard {
|
|
|
352
353
|
}
|
|
353
354
|
return `${start + 1} / span ${span}`;
|
|
354
355
|
}
|
|
355
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
356
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
356
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DashboardCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
357
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: DashboardCard, isStandalone: true, selector: "mfp-dashboard-card", inputs: { card: { classPropertyName: "card", publicName: "card", isSignal: true, isRequired: true, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removeCard: "removeCard" }, host: { properties: { "style.grid-column": "gridColumn()", "style.grid-row": "gridRow()" } }, viewQueries: [{ propertyName: "host", first: true, predicate: ["elementHost"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "@if (card().component) {\n <div\n class=\"component-card\"\n [attr.data-testid]=\"'dashboard-card-' + card().id\"\n [class.component-card--editing]=\"editMode()\"\n >\n @if (editMode()) {\n <div class=\"remove-wrapper\">\n <ui5-button\n class=\"card__remove\"\n design=\"Default\"\n icon=\"decline\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_CARD) +\n ': ' +\n (card().label || card().component)\n \"\n [attr.data-testid]=\"'dashboard-card-' + card().id + '-remove'\"\n (click)=\"removeCard.emit()\"\n />\n </div>\n <ui5-icon\n aria-hidden=\"true\"\n class=\"card__resize-indicator\"\n name=\"resize-corner\"\n [accessibleName]=\"i18n.getTranslation(i18nKeys.RESIZABLE)\"\n />\n }\n <div\n [attr.inert]=\"editMode() ? '' : null\"\n [class]=\"componentHostClasses\"\n [style.pointer-events]=\"editMode() ? 'none' : 'auto'\"\n >\n <div #elementHost></div>\n </div>\n </div>\n} @else {\n <div class=\"card\" [attr.data-testid]=\"'dashboard-card-' + card().id\">\n <div\n [attr.inert]=\"editMode() ? '' : null\"\n [class]=\"cardBodyClasses\"\n [style.pointer-events]=\"editMode() ? 'none' : 'auto'\"\n >\n <ng-content />\n </div>\n </div>\n}\n", styles: [":host{display:block;min-width:0;min-height:0;overflow:visible;outline:none;border:0;box-shadow:none}.card__remove{position:absolute;top:0;right:-.5rem;z-index:10;border-radius:50%!important;width:1.25rem!important;height:1.25rem!important;min-width:unset!important;padding:0!important;font-size:.625rem!important}.remove-wrapper{position:sticky;height:.5rem;top:0;right:0;z-index:10}.component-card{position:relative;height:100%;overflow:visible;isolation:isolate;padding-inline-start:var(--mfp_cardContainerPadding, 10px);padding-inline-end:var(--mfp_cardContainerPadding, 10px)}.component-card--editing{cursor:grab}.component-card .component-host{border-radius:var(--sapElement_BorderCornerRadius, 12px)}.component-card--editing:hover{--sapTile_BorderColor: var(--sapHighlightColor, #0070f2);--sapGroup_ContentBorderColor: var(--sapHighlightColor, #0070f2)}.component-card--editing:hover .component-host{border:var(--mfp_cardBorder, none)}:host-context(.grid-stack-item:focus) .component-card--editing{--sapTile_BorderColor: var(--sapHighlightColor, #0070f2);--sapGroup_ContentBorderColor: var(--sapHighlightColor, #0070f2)}:host-context(.grid-stack-item:focus) .component-card--editing .component-host{border:var(--mfp_cardBorder, none)}.component-card--editing:hover .card__resize-indicator{opacity:1}:host-context(.grid-stack-item:focus) .component-card--editing .card__resize-indicator{opacity:1}:host-context(.ui-draggable-dragging) .component-card--editing{cursor:grabbing!important}:host-context(.ui-draggable-dragging) .component-card--editing{--sapTile_BorderColor: var(--sapHighlightColor, #0070f2);--sapGroup_ContentBorderColor: var(--sapHighlightColor, #0070f2)}:host-context(.ui-draggable-dragging) .component-card--editing .card__resize-indicator{opacity:1}:host-context(.zflow-dragging) .remove-wrapper{opacity:0;pointer-events:none}.component-host{position:relative;height:100%}.card__resize-indicator{position:absolute;right:calc(var(--mfp_cardContainerPadding, 10px) + 4px);bottom:4px;width:1rem;height:1rem;pointer-events:none;opacity:0;transition:opacity .12s ease-out;color:var(--sapHighlightColor, #0070f2);z-index:9}.card{position:relative;display:flex;flex-direction:column;height:100%;border:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9);border-radius:.5rem;background:var(--sapBackgroundColor, #fff);overflow:visible}.card__header{padding:.75rem 1rem;font-weight:600;border-bottom:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9);background:var(--sapGroup_TitleBackground, #f5f5f5)}.card__body{flex:1;padding:1rem;overflow:auto}\n"], dependencies: [{ kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Icon, selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }] });
|
|
357
358
|
}
|
|
358
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
359
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DashboardCard, decorators: [{
|
|
359
360
|
type: Component,
|
|
360
361
|
args: [{ selector: 'mfp-dashboard-card', imports: [Button, Icon], encapsulation: ViewEncapsulation.Emulated, host: {
|
|
361
362
|
'[style.grid-column]': 'gridColumn()',
|
|
362
363
|
'[style.grid-row]': 'gridRow()',
|
|
363
|
-
}, template: "@if (card().component) {\n <div
|
|
364
|
+
}, template: "@if (card().component) {\n <div\n class=\"component-card\"\n [attr.data-testid]=\"'dashboard-card-' + card().id\"\n [class.component-card--editing]=\"editMode()\"\n >\n @if (editMode()) {\n <div class=\"remove-wrapper\">\n <ui5-button\n class=\"card__remove\"\n design=\"Default\"\n icon=\"decline\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_CARD) +\n ': ' +\n (card().label || card().component)\n \"\n [attr.data-testid]=\"'dashboard-card-' + card().id + '-remove'\"\n (click)=\"removeCard.emit()\"\n />\n </div>\n <ui5-icon\n aria-hidden=\"true\"\n class=\"card__resize-indicator\"\n name=\"resize-corner\"\n [accessibleName]=\"i18n.getTranslation(i18nKeys.RESIZABLE)\"\n />\n }\n <div\n [attr.inert]=\"editMode() ? '' : null\"\n [class]=\"componentHostClasses\"\n [style.pointer-events]=\"editMode() ? 'none' : 'auto'\"\n >\n <div #elementHost></div>\n </div>\n </div>\n} @else {\n <div class=\"card\" [attr.data-testid]=\"'dashboard-card-' + card().id\">\n <div\n [attr.inert]=\"editMode() ? '' : null\"\n [class]=\"cardBodyClasses\"\n [style.pointer-events]=\"editMode() ? 'none' : 'auto'\"\n >\n <ng-content />\n </div>\n </div>\n}\n", styles: [":host{display:block;min-width:0;min-height:0;overflow:visible;outline:none;border:0;box-shadow:none}.card__remove{position:absolute;top:0;right:-.5rem;z-index:10;border-radius:50%!important;width:1.25rem!important;height:1.25rem!important;min-width:unset!important;padding:0!important;font-size:.625rem!important}.remove-wrapper{position:sticky;height:.5rem;top:0;right:0;z-index:10}.component-card{position:relative;height:100%;overflow:visible;isolation:isolate;padding-inline-start:var(--mfp_cardContainerPadding, 10px);padding-inline-end:var(--mfp_cardContainerPadding, 10px)}.component-card--editing{cursor:grab}.component-card .component-host{border-radius:var(--sapElement_BorderCornerRadius, 12px)}.component-card--editing:hover{--sapTile_BorderColor: var(--sapHighlightColor, #0070f2);--sapGroup_ContentBorderColor: var(--sapHighlightColor, #0070f2)}.component-card--editing:hover .component-host{border:var(--mfp_cardBorder, none)}:host-context(.grid-stack-item:focus) .component-card--editing{--sapTile_BorderColor: var(--sapHighlightColor, #0070f2);--sapGroup_ContentBorderColor: var(--sapHighlightColor, #0070f2)}:host-context(.grid-stack-item:focus) .component-card--editing .component-host{border:var(--mfp_cardBorder, none)}.component-card--editing:hover .card__resize-indicator{opacity:1}:host-context(.grid-stack-item:focus) .component-card--editing .card__resize-indicator{opacity:1}:host-context(.ui-draggable-dragging) .component-card--editing{cursor:grabbing!important}:host-context(.ui-draggable-dragging) .component-card--editing{--sapTile_BorderColor: var(--sapHighlightColor, #0070f2);--sapGroup_ContentBorderColor: var(--sapHighlightColor, #0070f2)}:host-context(.ui-draggable-dragging) .component-card--editing .card__resize-indicator{opacity:1}:host-context(.zflow-dragging) .remove-wrapper{opacity:0;pointer-events:none}.component-host{position:relative;height:100%}.card__resize-indicator{position:absolute;right:calc(var(--mfp_cardContainerPadding, 10px) + 4px);bottom:4px;width:1rem;height:1rem;pointer-events:none;opacity:0;transition:opacity .12s ease-out;color:var(--sapHighlightColor, #0070f2);z-index:9}.card{position:relative;display:flex;flex-direction:column;height:100%;border:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9);border-radius:.5rem;background:var(--sapBackgroundColor, #fff);overflow:visible}.card__header{padding:.75rem 1rem;font-weight:600;border-bottom:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9);background:var(--sapGroup_TitleBackground, #f5f5f5)}.card__body{flex:1;padding:1rem;overflow:auto}\n"] }]
|
|
364
365
|
}], ctorParameters: () => [], propDecorators: { card: [{ type: i0.Input, args: [{ isSignal: true, alias: "card", required: true }] }], editMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editMode", required: false }] }], removeCard: [{ type: i0.Output, args: ["removeCard"] }], host: [{ type: i0.ViewChild, args: ['elementHost', { ...{ read: ViewContainerRef }, isSignal: true }] }] } });
|
|
365
366
|
|
|
366
367
|
/**
|
|
@@ -371,27 +372,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
371
372
|
class DiscardChangesDialog {
|
|
372
373
|
i18n = inject(DashboardI18nService);
|
|
373
374
|
i18nKeys = DASHBOARD_I18N_KEYS;
|
|
374
|
-
open = input(false,
|
|
375
|
+
open = input(false, /* @ts-ignore */
|
|
376
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
375
377
|
confirm = output();
|
|
376
378
|
cancelled = output();
|
|
377
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
378
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
379
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DiscardChangesDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
380
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.2", type: DiscardChangesDialog, isStandalone: true, selector: "mfp-discard-changes-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirm: "confirm", cancelled: "cancelled" }, ngImport: i0, template: "<ui5-dialog\n data-testid=\"dashboard-discard-changes-dialog\"\n state=\"Critical\"\n [open]=\"open()\"\n (ui5BeforeClose)=\"cancelled.emit()\"\n>\n <div class=\"discard-changes-dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{\n i18n.getTranslation(i18nKeys.DISCARD_CHANGES)\n }}</ui5-title>\n </div>\n <div class=\"discard-changes-dialog__body\">\n {{ i18n.getTranslation(i18nKeys.DISCARD_CONFIRM_BODY) }}\n </div>\n <div class=\"discard-changes-dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"dashboard-discard-changes-confirm-btn\"\n design=\"Emphasized\"\n (click)=\"confirm.emit()\"\n >{{ i18n.getTranslation(i18nKeys.DISCARD) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-discard-changes-cancel-btn\"\n design=\"Transparent\"\n (click)=\"cancelled.emit()\"\n >{{ i18n.getTranslation(i18nKeys.CANCEL) }}</ui5-button\n >\n </div>\n</ui5-dialog>\n", styles: [":host{display:contents}.discard-changes-dialog__header{display:flex;align-items:center;width:100%;padding:.75rem 0}.discard-changes-dialog__body{padding:0 0 1rem;min-width:320px}.discard-changes-dialog__footer{display:flex;justify-content:flex-end;align-items:center;width:100%;gap:.5rem}\n"], dependencies: [{ kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Dialog, selector: "ui5-dialog, [ui5-dialog]", inputs: ["accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "accessibleRole", "draggable", "headerText", "initialFocus", "open", "preventFocusRestore", "preventInitialFocus", "resizable", "showFullscreenButton", "state", "stretch"], outputs: ["ui5BeforeClose", "ui5BeforeOpen", "ui5Close", "ui5Open"], exportAs: ["ui5Dialog"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["level", "size", "wrappingType"], exportAs: ["ui5Title"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
379
381
|
}
|
|
380
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
382
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DiscardChangesDialog, decorators: [{
|
|
381
383
|
type: Component,
|
|
382
|
-
args: [{ selector: 'mfp-discard-changes-dialog', imports: [Button, Dialog, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<ui5-dialog
|
|
384
|
+
args: [{ selector: 'mfp-discard-changes-dialog', imports: [Button, Dialog, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<ui5-dialog\n data-testid=\"dashboard-discard-changes-dialog\"\n state=\"Critical\"\n [open]=\"open()\"\n (ui5BeforeClose)=\"cancelled.emit()\"\n>\n <div class=\"discard-changes-dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{\n i18n.getTranslation(i18nKeys.DISCARD_CHANGES)\n }}</ui5-title>\n </div>\n <div class=\"discard-changes-dialog__body\">\n {{ i18n.getTranslation(i18nKeys.DISCARD_CONFIRM_BODY) }}\n </div>\n <div class=\"discard-changes-dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"dashboard-discard-changes-confirm-btn\"\n design=\"Emphasized\"\n (click)=\"confirm.emit()\"\n >{{ i18n.getTranslation(i18nKeys.DISCARD) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-discard-changes-cancel-btn\"\n design=\"Transparent\"\n (click)=\"cancelled.emit()\"\n >{{ i18n.getTranslation(i18nKeys.CANCEL) }}</ui5-button\n >\n </div>\n</ui5-dialog>\n", styles: [":host{display:contents}.discard-changes-dialog__header{display:flex;align-items:center;width:100%;padding:.75rem 0}.discard-changes-dialog__body{padding:0 0 1rem;min-width:320px}.discard-changes-dialog__footer{display:flex;justify-content:flex-end;align-items:center;width:100%;gap:.5rem}\n"] }]
|
|
383
385
|
}], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], confirm: [{ type: i0.Output, args: ["confirm"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
|
|
384
386
|
|
|
385
387
|
class EditCardsDialog {
|
|
386
388
|
host = inject((ElementRef));
|
|
387
389
|
i18n = inject(DashboardI18nService);
|
|
388
390
|
i18nKeys = DASHBOARD_I18N_KEYS;
|
|
389
|
-
availableCards = input([],
|
|
390
|
-
|
|
391
|
-
|
|
391
|
+
availableCards = input([], /* @ts-ignore */
|
|
392
|
+
...(ngDevMode ? [{ debugName: "availableCards" }] : /* istanbul ignore next */ []));
|
|
393
|
+
addedCardsIds = input(new Set(), /* @ts-ignore */
|
|
394
|
+
...(ngDevMode ? [{ debugName: "addedCardsIds" }] : /* istanbul ignore next */ []));
|
|
395
|
+
open = input(false, /* @ts-ignore */
|
|
396
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
392
397
|
confirm = output();
|
|
393
398
|
cancelled = output();
|
|
394
|
-
selectedIds = signal(new Set(),
|
|
399
|
+
selectedIds = signal(new Set(), /* @ts-ignore */
|
|
400
|
+
...(ngDevMode ? [{ debugName: "selectedIds" }] : /* istanbul ignore next */ []));
|
|
395
401
|
constructor() {
|
|
396
402
|
effect(() => {
|
|
397
403
|
if (this.open()) {
|
|
@@ -459,17 +465,19 @@ class EditCardsDialog {
|
|
|
459
465
|
const removed = [...this.addedCardsIds()].filter((id) => availableIds.has(id) && !this.selectedIds().has(id));
|
|
460
466
|
this.confirm.emit({ added, removed });
|
|
461
467
|
}
|
|
462
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
463
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
468
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EditCardsDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
469
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: EditCardsDialog, isStandalone: true, selector: "mfp-edit-cards-dialog", inputs: { availableCards: { classPropertyName: "availableCards", publicName: "availableCards", isSignal: true, isRequired: false, transformFunction: null }, addedCardsIds: { classPropertyName: "addedCardsIds", publicName: "addedCardsIds", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirm: "confirm", cancelled: "cancelled" }, ngImport: i0, template: "<ui5-dialog\n class=\"edit-cards-dialog-container\"\n data-testid=\"dashboard-edit-cards-dialog\"\n [open]=\"open()\"\n (ui5BeforeClose)=\"cancelled.emit()\"\n>\n <div class=\"edit-cards-dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{\n i18n.getTranslation(i18nKeys.EDIT_CARDS)\n }}</ui5-title>\n </div>\n <div class=\"edit-cards-dialog\">\n <ui5-list\n selectionMode=\"None\"\n separators=\"Inner\"\n [noDataText]=\"i18n.getTranslation(i18nKeys.NO_CARDS_AVAILABLE)\"\n >\n @for (availableCard of availableCards(); track availableCard.id) {\n <ui5-li-custom\n class=\"edit-cards-dialog__list-item-container\"\n [accessibleName]=\"availableCard.label || availableCard.component\"\n [attr.data-testid]=\"'dashboard-edit-cards-row-' + availableCard.id\"\n >\n <div class=\"edit-cards-dialog__list-item\">\n <span>{{ availableCard.label || availableCard.component }}</span>\n <ui5-switch\n [accessibleName]=\"availableCard.label || availableCard.component\"\n [attr.data-testid]=\"\n 'dashboard-edit-cards-switch-' + availableCard.id\n \"\n [checked]=\"selectedIds().has(availableCard.id)\"\n (keydown)=\"onSwitchKeydown($event, availableCard.id)\"\n (ui5Change)=\"toggle(availableCard.id)\"\n />\n </div>\n </ui5-li-custom>\n }\n </ui5-list>\n </div>\n <div class=\"edit-cards-dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"dashboard-edit-cards-save-btn\"\n design=\"Emphasized\"\n (click)=\"confirmSave()\"\n >{{ i18n.getTranslation(i18nKeys.SAVE) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-edit-cards-cancel-btn\"\n design=\"Transparent\"\n (click)=\"cancelled.emit()\"\n >{{ i18n.getTranslation(i18nKeys.CANCEL) }}</ui5-button\n >\n </div>\n</ui5-dialog>\n", styles: [":host{display:contents}.edit-cards-dialog-container{min-width:460px;min-height:400px}.edit-cards-dialog{padding:var(--Container-Spacing-Small, 16px) 0;margin:-1rem}.edit-cards-dialog__header{display:flex;align-items:flex-start;justify-content:flex-start;width:100%;padding:.75rem 0}.edit-cards-dialog__list-item{display:flex;align-items:center;justify-content:space-between;padding-right:.25rem;width:100%}.edit-cards-dialog__list-item-container{border-bottom-color:var(--sapGroup_ContentBorderColor, #d9d9d9)}.edit-cards-dialog__footer{display:flex;justify-content:flex-end;align-items:center;width:100%;gap:.5rem}\n"], dependencies: [{ kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Dialog, selector: "ui5-dialog, [ui5-dialog]", inputs: ["accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "accessibleRole", "draggable", "headerText", "initialFocus", "open", "preventFocusRestore", "preventInitialFocus", "resizable", "showFullscreenButton", "state", "stretch"], outputs: ["ui5BeforeClose", "ui5BeforeOpen", "ui5Close", "ui5Open"], exportAs: ["ui5Dialog"] }, { kind: "component", type: List, selector: "ui5-list, [ui5-list]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "accessibleRole", "footerText", "growing", "growingButtonText", "headerText", "indent", "loading", "loadingDelay", "noDataText", "selectionMode", "separators", "stickyHeader"], outputs: ["ui5ItemClick", "ui5ItemClose", "ui5ItemDelete", "ui5ItemToggle", "ui5LoadMore", "ui5Move", "ui5MoveOver", "ui5SelectionChange"], exportAs: ["ui5List"] }, { kind: "component", type: ListItemCustom, selector: "ui5-li-custom, [ui5-li-custom]", inputs: ["accessibilityAttributes", "accessibleName", "accessibleRole", "highlight", "movable", "navigated", "selected", "tooltip", "type"], outputs: ["ui5Click", "ui5DetailClick"], exportAs: ["ui5ListItemCustom"] }, { kind: "component", type: Switch, selector: "ui5-switch, [ui5-switch]", inputs: ["accessibleName", "accessibleNameRef", "checked", "design", "disabled", "name", "readonly", "required", "textOff", "textOn", "tooltip", "value"], outputs: ["ui5Change"], exportAs: ["ui5Switch"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["level", "size", "wrappingType"], exportAs: ["ui5Title"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
464
470
|
}
|
|
465
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
471
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EditCardsDialog, decorators: [{
|
|
466
472
|
type: Component,
|
|
467
|
-
args: [{ selector: 'mfp-edit-cards-dialog', imports: [Button, Dialog, List, ListItemCustom, Switch, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<ui5-dialog
|
|
473
|
+
args: [{ selector: 'mfp-edit-cards-dialog', imports: [Button, Dialog, List, ListItemCustom, Switch, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<ui5-dialog\n class=\"edit-cards-dialog-container\"\n data-testid=\"dashboard-edit-cards-dialog\"\n [open]=\"open()\"\n (ui5BeforeClose)=\"cancelled.emit()\"\n>\n <div class=\"edit-cards-dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{\n i18n.getTranslation(i18nKeys.EDIT_CARDS)\n }}</ui5-title>\n </div>\n <div class=\"edit-cards-dialog\">\n <ui5-list\n selectionMode=\"None\"\n separators=\"Inner\"\n [noDataText]=\"i18n.getTranslation(i18nKeys.NO_CARDS_AVAILABLE)\"\n >\n @for (availableCard of availableCards(); track availableCard.id) {\n <ui5-li-custom\n class=\"edit-cards-dialog__list-item-container\"\n [accessibleName]=\"availableCard.label || availableCard.component\"\n [attr.data-testid]=\"'dashboard-edit-cards-row-' + availableCard.id\"\n >\n <div class=\"edit-cards-dialog__list-item\">\n <span>{{ availableCard.label || availableCard.component }}</span>\n <ui5-switch\n [accessibleName]=\"availableCard.label || availableCard.component\"\n [attr.data-testid]=\"\n 'dashboard-edit-cards-switch-' + availableCard.id\n \"\n [checked]=\"selectedIds().has(availableCard.id)\"\n (keydown)=\"onSwitchKeydown($event, availableCard.id)\"\n (ui5Change)=\"toggle(availableCard.id)\"\n />\n </div>\n </ui5-li-custom>\n }\n </ui5-list>\n </div>\n <div class=\"edit-cards-dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"dashboard-edit-cards-save-btn\"\n design=\"Emphasized\"\n (click)=\"confirmSave()\"\n >{{ i18n.getTranslation(i18nKeys.SAVE) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-edit-cards-cancel-btn\"\n design=\"Transparent\"\n (click)=\"cancelled.emit()\"\n >{{ i18n.getTranslation(i18nKeys.CANCEL) }}</ui5-button\n >\n </div>\n</ui5-dialog>\n", styles: [":host{display:contents}.edit-cards-dialog-container{min-width:460px;min-height:400px}.edit-cards-dialog{padding:var(--Container-Spacing-Small, 16px) 0;margin:-1rem}.edit-cards-dialog__header{display:flex;align-items:flex-start;justify-content:flex-start;width:100%;padding:.75rem 0}.edit-cards-dialog__list-item{display:flex;align-items:center;justify-content:space-between;padding-right:.25rem;width:100%}.edit-cards-dialog__list-item-container{border-bottom-color:var(--sapGroup_ContentBorderColor, #d9d9d9)}.edit-cards-dialog__footer{display:flex;justify-content:flex-end;align-items:center;width:100%;gap:.5rem}\n"] }]
|
|
468
474
|
}], ctorParameters: () => [], propDecorators: { availableCards: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableCards", required: false }] }], addedCardsIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "addedCardsIds", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], confirm: [{ type: i0.Output, args: ["confirm"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
|
|
469
475
|
|
|
470
476
|
class DashboardSection {
|
|
471
|
-
section = input.required(
|
|
472
|
-
|
|
477
|
+
section = input.required(/* @ts-ignore */
|
|
478
|
+
...(ngDevMode ? [{ debugName: "section" }] : /* istanbul ignore next */ []));
|
|
479
|
+
cards = input([], /* @ts-ignore */
|
|
480
|
+
...(ngDevMode ? [{ debugName: "cards" }] : /* istanbul ignore next */ []));
|
|
473
481
|
/**
|
|
474
482
|
* Optional override for the section's inner grid column count. Leave unset
|
|
475
483
|
* (the default) to inherit the responsive defaults from CSS — the section
|
|
@@ -478,16 +486,18 @@ class DashboardSection {
|
|
|
478
486
|
* Pass an explicit number only when a section needs a fixed column count
|
|
479
487
|
* regardless of width.
|
|
480
488
|
*/
|
|
481
|
-
columns = input(undefined,
|
|
482
|
-
|
|
489
|
+
columns = input(undefined, /* @ts-ignore */
|
|
490
|
+
...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
491
|
+
editMode = input(false, /* @ts-ignore */
|
|
492
|
+
...(ngDevMode ? [{ debugName: "editMode" }] : /* istanbul ignore next */ []));
|
|
483
493
|
i18n = inject(DashboardI18nService);
|
|
484
494
|
i18nKeys = DASHBOARD_I18N_KEYS;
|
|
485
495
|
removeSection = output();
|
|
486
496
|
removeCard = output();
|
|
487
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
488
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
497
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DashboardSection, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
498
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: DashboardSection, isStandalone: true, selector: "mfp-dashboard-section", inputs: { section: { classPropertyName: "section", publicName: "section", isSignal: true, isRequired: true, transformFunction: null }, cards: { classPropertyName: "cards", publicName: "cards", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removeSection: "removeSection", removeCard: "removeCard" }, host: { properties: { "style.grid-column": "section().w === undefined || section().w === 12 ? \"1 / -1\" : \"span \" + section().w" } }, ngImport: i0, template: "<div\n class=\"section\"\n [attr.data-testid]=\"'dashboard-section-' + section().id\"\n [class.section--edit]=\"editMode() && section().editable !== false\"\n>\n @if (editMode() && section().editable !== false) {\n <ui5-button\n class=\"section__remove\"\n design=\"Default\"\n icon=\"decline\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_SECTION) +\n ': ' +\n (section().title || section().id)\n \"\n [attr.data-testid]=\"'dashboard-section-' + section().id + '-remove'\"\n (click)=\"removeSection.emit()\"\n />\n }\n @if (section().title) {\n <div class=\"section__header\">\n <span\n class=\"section__title\"\n [attr.data-testid]=\"'dashboard-section-' + section().id + '-title'\"\n >{{ section().title }}</span\n >\n </div>\n }\n <div class=\"section__grid\" [style.--cols]=\"columns() ?? null\">\n @for (card of cards(); track card.id) {\n <mfp-dashboard-card\n [card]=\"card\"\n [editMode]=\"editMode() && section().editable !== false\"\n (removeCard)=\"removeCard.emit($any(card.id))\"\n />\n }\n </div>\n</div>\n", styles: [":host{display:block;min-width:0}.section{position:relative;display:flex;flex-direction:column;border:1px solid transparent;border-top:none;border-radius:0 0 .5rem .5rem;padding-top:1.25rem}.section--edit{border-color:var(--sapGroup_ContentBorderColor, #d9d9d9)}.section__remove{position:absolute;top:-.75rem;right:-.75rem;z-index:10;border-radius:50%!important;width:1.25rem!important;height:1.25rem!important;min-width:unset!important;padding:0!important;font-size:.625rem!important}.section__header{position:absolute;top:0;left:0;right:0;transform:translateY(-50%);display:flex;align-items:center;pointer-events:none}.section__header:before,.section__header:after{content:\"\";flex:1;height:1px;background:transparent}.section__header:before{max-width:.75rem;flex:0 0 .75rem}.section--edit .section__header:before,.section--edit .section__header:after{background:var(--sapGroup_ContentBorderColor, #d9d9d9)}.section__title{font-size:1rem;font-weight:600;color:var(--sapTextColor, #fff);padding:0 .5rem;white-space:nowrap;pointer-events:all}.section__grid{display:grid;grid-auto-rows:var(--row-height, 10px);column-gap:var(--column-gap, 0px);row-gap:var(--row-gap, 0px);grid-template-columns:repeat(var(--cols, var(--dashboard-cols-xl, 14)),1fr)}@container mfp-dashboard (max-width: 599px){.section__grid{grid-template-columns:repeat(var(--cols, var(--dashboard-cols-sm, 1)),1fr)}}@container mfp-dashboard (min-width: 600px) and (max-width: 1023px){.section__grid{grid-template-columns:repeat(var(--cols, var(--dashboard-cols-md, 8)),1fr)}}@container mfp-dashboard (min-width: 1024px) and (max-width: 1439px){.section__grid{grid-template-columns:repeat(var(--cols, var(--dashboard-cols-lg, 12)),1fr)}}\n"], dependencies: [{ kind: "component", type: DashboardCard, selector: "mfp-dashboard-card", inputs: ["card", "editMode"], outputs: ["removeCard"] }, { kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }] });
|
|
489
499
|
}
|
|
490
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
500
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DashboardSection, decorators: [{
|
|
491
501
|
type: Component,
|
|
492
502
|
args: [{ selector: 'mfp-dashboard-section', imports: [DashboardCard, Button], encapsulation: ViewEncapsulation.Emulated, host: {
|
|
493
503
|
// Section width interpretation:
|
|
@@ -501,7 +511,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
501
511
|
// cover 12 of 14 columns, leaving a dead 2-col gutter on the right and
|
|
502
512
|
// squeezing the cards inside it relative to the outer grid's units.
|
|
503
513
|
'[style.grid-column]': 'section().w === undefined || section().w === 12 ? "1 / -1" : "span " + section().w',
|
|
504
|
-
}, template: "<div\n class=\"section\"\n [attr.data-testid]=\"'dashboard-section-' + section().id\"\n [class.section--edit]=\"editMode() && section().editable !== false\"\n>\n @if (editMode() && section().editable !== false) {\n <ui5-button\n class=\"section__remove\"\n design=\"Default\"\n icon=\"decline\"\n [
|
|
514
|
+
}, template: "<div\n class=\"section\"\n [attr.data-testid]=\"'dashboard-section-' + section().id\"\n [class.section--edit]=\"editMode() && section().editable !== false\"\n>\n @if (editMode() && section().editable !== false) {\n <ui5-button\n class=\"section__remove\"\n design=\"Default\"\n icon=\"decline\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_SECTION) +\n ': ' +\n (section().title || section().id)\n \"\n [attr.data-testid]=\"'dashboard-section-' + section().id + '-remove'\"\n (click)=\"removeSection.emit()\"\n />\n }\n @if (section().title) {\n <div class=\"section__header\">\n <span\n class=\"section__title\"\n [attr.data-testid]=\"'dashboard-section-' + section().id + '-title'\"\n >{{ section().title }}</span\n >\n </div>\n }\n <div class=\"section__grid\" [style.--cols]=\"columns() ?? null\">\n @for (card of cards(); track card.id) {\n <mfp-dashboard-card\n [card]=\"card\"\n [editMode]=\"editMode() && section().editable !== false\"\n (removeCard)=\"removeCard.emit($any(card.id))\"\n />\n }\n </div>\n</div>\n", styles: [":host{display:block;min-width:0}.section{position:relative;display:flex;flex-direction:column;border:1px solid transparent;border-top:none;border-radius:0 0 .5rem .5rem;padding-top:1.25rem}.section--edit{border-color:var(--sapGroup_ContentBorderColor, #d9d9d9)}.section__remove{position:absolute;top:-.75rem;right:-.75rem;z-index:10;border-radius:50%!important;width:1.25rem!important;height:1.25rem!important;min-width:unset!important;padding:0!important;font-size:.625rem!important}.section__header{position:absolute;top:0;left:0;right:0;transform:translateY(-50%);display:flex;align-items:center;pointer-events:none}.section__header:before,.section__header:after{content:\"\";flex:1;height:1px;background:transparent}.section__header:before{max-width:.75rem;flex:0 0 .75rem}.section--edit .section__header:before,.section--edit .section__header:after{background:var(--sapGroup_ContentBorderColor, #d9d9d9)}.section__title{font-size:1rem;font-weight:600;color:var(--sapTextColor, #fff);padding:0 .5rem;white-space:nowrap;pointer-events:all}.section__grid{display:grid;grid-auto-rows:var(--row-height, 10px);column-gap:var(--column-gap, 0px);row-gap:var(--row-gap, 0px);grid-template-columns:repeat(var(--cols, var(--dashboard-cols-xl, 14)),1fr)}@container mfp-dashboard (max-width: 599px){.section__grid{grid-template-columns:repeat(var(--cols, var(--dashboard-cols-sm, 1)),1fr)}}@container mfp-dashboard (min-width: 600px) and (max-width: 1023px){.section__grid{grid-template-columns:repeat(var(--cols, var(--dashboard-cols-md, 8)),1fr)}}@container mfp-dashboard (min-width: 1024px) and (max-width: 1439px){.section__grid{grid-template-columns:repeat(var(--cols, var(--dashboard-cols-lg, 12)),1fr)}}\n"] }]
|
|
505
515
|
}], propDecorators: { section: [{ type: i0.Input, args: [{ isSignal: true, alias: "section", required: true }] }], cards: [{ type: i0.Input, args: [{ isSignal: true, alias: "cards", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], editMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editMode", required: false }] }], removeSection: [{ type: i0.Output, args: ["removeSection"] }], removeCard: [{ type: i0.Output, args: ["removeCard"] }] } });
|
|
506
516
|
|
|
507
517
|
/**
|
|
@@ -517,16 +527,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
517
527
|
class UnsavedChangesDialog {
|
|
518
528
|
i18n = inject(DashboardI18nService);
|
|
519
529
|
i18nKeys = DASHBOARD_I18N_KEYS;
|
|
520
|
-
open = input(false,
|
|
530
|
+
open = input(false, /* @ts-ignore */
|
|
531
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
521
532
|
save = output();
|
|
522
533
|
discard = output();
|
|
523
534
|
cancelled = output();
|
|
524
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
525
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
535
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: UnsavedChangesDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
536
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.2", type: UnsavedChangesDialog, isStandalone: true, selector: "mfp-unsaved-changes-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { save: "save", discard: "discard", cancelled: "cancelled" }, ngImport: i0, template: "<ui5-dialog\n data-testid=\"dashboard-unsaved-changes-dialog\"\n state=\"Critical\"\n [open]=\"open()\"\n (ui5BeforeClose)=\"cancelled.emit()\"\n>\n <div class=\"unsaved-changes-dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{\n i18n.getTranslation(i18nKeys.UNSAVED_CHANGES)\n }}</ui5-title>\n </div>\n <div class=\"unsaved-changes-dialog__body\">\n {{ i18n.getTranslation(i18nKeys.UNSAVED_NAV_BODY) }}\n </div>\n <div class=\"unsaved-changes-dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"dashboard-unsaved-changes-save-btn\"\n design=\"Emphasized\"\n (click)=\"save.emit()\"\n >{{ i18n.getTranslation(i18nKeys.SAVE) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-unsaved-changes-discard-btn\"\n design=\"Transparent\"\n (click)=\"discard.emit()\"\n >{{ i18n.getTranslation(i18nKeys.DISCARD) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-unsaved-changes-cancel-btn\"\n design=\"Transparent\"\n (click)=\"cancelled.emit()\"\n >{{ i18n.getTranslation(i18nKeys.CANCEL) }}</ui5-button\n >\n </div>\n</ui5-dialog>\n", styles: [":host{display:contents}.unsaved-changes-dialog__header{display:flex;align-items:center;width:100%;padding:.75rem 0}.unsaved-changes-dialog__body{padding:0 0 1rem;min-width:360px;max-width:32rem}.unsaved-changes-dialog__footer{display:flex;justify-content:flex-end;align-items:center;width:100%;gap:.5rem}\n"], dependencies: [{ kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Dialog, selector: "ui5-dialog, [ui5-dialog]", inputs: ["accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "accessibleRole", "draggable", "headerText", "initialFocus", "open", "preventFocusRestore", "preventInitialFocus", "resizable", "showFullscreenButton", "state", "stretch"], outputs: ["ui5BeforeClose", "ui5BeforeOpen", "ui5Close", "ui5Open"], exportAs: ["ui5Dialog"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["level", "size", "wrappingType"], exportAs: ["ui5Title"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
526
537
|
}
|
|
527
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
538
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: UnsavedChangesDialog, decorators: [{
|
|
528
539
|
type: Component,
|
|
529
|
-
args: [{ selector: 'mfp-unsaved-changes-dialog', imports: [Button, Dialog, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<ui5-dialog
|
|
540
|
+
args: [{ selector: 'mfp-unsaved-changes-dialog', imports: [Button, Dialog, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<ui5-dialog\n data-testid=\"dashboard-unsaved-changes-dialog\"\n state=\"Critical\"\n [open]=\"open()\"\n (ui5BeforeClose)=\"cancelled.emit()\"\n>\n <div class=\"unsaved-changes-dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{\n i18n.getTranslation(i18nKeys.UNSAVED_CHANGES)\n }}</ui5-title>\n </div>\n <div class=\"unsaved-changes-dialog__body\">\n {{ i18n.getTranslation(i18nKeys.UNSAVED_NAV_BODY) }}\n </div>\n <div class=\"unsaved-changes-dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"dashboard-unsaved-changes-save-btn\"\n design=\"Emphasized\"\n (click)=\"save.emit()\"\n >{{ i18n.getTranslation(i18nKeys.SAVE) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-unsaved-changes-discard-btn\"\n design=\"Transparent\"\n (click)=\"discard.emit()\"\n >{{ i18n.getTranslation(i18nKeys.DISCARD) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-unsaved-changes-cancel-btn\"\n design=\"Transparent\"\n (click)=\"cancelled.emit()\"\n >{{ i18n.getTranslation(i18nKeys.CANCEL) }}</ui5-button\n >\n </div>\n</ui5-dialog>\n", styles: [":host{display:contents}.unsaved-changes-dialog__header{display:flex;align-items:center;width:100%;padding:.75rem 0}.unsaved-changes-dialog__body{padding:0 0 1rem;min-width:360px;max-width:32rem}.unsaved-changes-dialog__footer{display:flex;justify-content:flex-end;align-items:center;width:100%;gap:.5rem}\n"] }]
|
|
530
541
|
}], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], save: [{ type: i0.Output, args: ["save"] }], discard: [{ type: i0.Output, args: ["discard"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
|
|
531
542
|
|
|
532
543
|
function getAllowedResizeWidths(maxWidth, columnCount, minWidth = 1, effectiveMax = columnCount) {
|
|
@@ -546,6 +557,13 @@ function resolveResizeWidthStep(rawWidth, maxWidth, columnCount, minWidth = 1, e
|
|
|
546
557
|
: best;
|
|
547
558
|
}, allowed[0]);
|
|
548
559
|
}
|
|
560
|
+
function resolveDirectionalResizeWidthStep(currentWidth, direction, maxWidth, columnCount, minWidth = 1, hardMax = columnCount) {
|
|
561
|
+
const allowed = getAllowedResizeWidths(maxWidth, columnCount, minWidth, hardMax);
|
|
562
|
+
if (direction === 'grow') {
|
|
563
|
+
return allowed.find((width) => width > currentWidth) ?? null;
|
|
564
|
+
}
|
|
565
|
+
return [...allowed].reverse().find((width) => width < currentWidth) ?? null;
|
|
566
|
+
}
|
|
549
567
|
|
|
550
568
|
function hasZFlowOrder(nodes) {
|
|
551
569
|
return nodes.some((n) => n.zFlowOrder !== undefined);
|
|
@@ -705,6 +723,62 @@ function resolveInsertionSlotFromProjectedRect(orderedNodes, sourceId, columnCou
|
|
|
705
723
|
return bestSlot;
|
|
706
724
|
return Math.max(0, Math.min(previousSlot, idsWithoutSource.length));
|
|
707
725
|
}
|
|
726
|
+
function resolveZFlowKeyboardInsertionSlot(nodes, sourceId, command, columnCount) {
|
|
727
|
+
syncNodeOrderFromLayout(nodes);
|
|
728
|
+
const ordered = sortNodesByZFlowOrder(nodes).filter((node) => node.id);
|
|
729
|
+
const source = projectZFlowLayout(ordered, columnCount).find((node) => node.id === sourceId);
|
|
730
|
+
if (!source)
|
|
731
|
+
return null;
|
|
732
|
+
const orderedIds = ordered.map((node) => node.id);
|
|
733
|
+
const idsWithoutSource = orderedIds.filter((id) => id !== sourceId);
|
|
734
|
+
const candidates = [];
|
|
735
|
+
for (let slot = 0; slot <= idsWithoutSource.length; slot++) {
|
|
736
|
+
const candidateIds = reorderByInsertionSlot(orderedIds, sourceId, slot);
|
|
737
|
+
const candidateNodes = candidateIds
|
|
738
|
+
.map((id) => ordered.find((node) => node.id === id))
|
|
739
|
+
.filter((node) => !!node);
|
|
740
|
+
const projected = projectZFlowLayout(candidateNodes, columnCount).find((node) => node.id === sourceId);
|
|
741
|
+
if (!projected)
|
|
742
|
+
continue;
|
|
743
|
+
if (projected.row === source.row && projected.x === source.x)
|
|
744
|
+
continue;
|
|
745
|
+
const isDirectionalMatch = (command === 'left' &&
|
|
746
|
+
projected.row === source.row &&
|
|
747
|
+
projected.x < source.x) ||
|
|
748
|
+
(command === 'right' &&
|
|
749
|
+
projected.row === source.row &&
|
|
750
|
+
projected.x > source.x) ||
|
|
751
|
+
(command === 'up' && projected.row === source.row - 1) ||
|
|
752
|
+
(command === 'down' && projected.row === source.row + 1) ||
|
|
753
|
+
(command === 'row-start' &&
|
|
754
|
+
projected.row === source.row &&
|
|
755
|
+
projected.x < source.x) ||
|
|
756
|
+
(command === 'row-end' &&
|
|
757
|
+
projected.row === source.row &&
|
|
758
|
+
projected.x > source.x);
|
|
759
|
+
if (isDirectionalMatch)
|
|
760
|
+
candidates.push({ slot, projected });
|
|
761
|
+
}
|
|
762
|
+
if (!candidates.length)
|
|
763
|
+
return null;
|
|
764
|
+
candidates.sort((a, b) => {
|
|
765
|
+
const distance = (candidate) => {
|
|
766
|
+
if (command === 'up' || command === 'down') {
|
|
767
|
+
return Math.abs(candidate.projected.x - source.x);
|
|
768
|
+
}
|
|
769
|
+
if (command === 'row-start')
|
|
770
|
+
return candidate.projected.x;
|
|
771
|
+
if (command === 'row-end')
|
|
772
|
+
return -candidate.projected.x;
|
|
773
|
+
return Math.abs(candidate.projected.x - source.x);
|
|
774
|
+
};
|
|
775
|
+
return (distance(a) - distance(b) ||
|
|
776
|
+
Math.abs(a.slot - orderedIds.indexOf(sourceId)) -
|
|
777
|
+
Math.abs(b.slot - orderedIds.indexOf(sourceId)) ||
|
|
778
|
+
a.slot - b.slot);
|
|
779
|
+
});
|
|
780
|
+
return candidates[0].slot;
|
|
781
|
+
}
|
|
708
782
|
function isSameProjectedPosition(a, b) {
|
|
709
783
|
return a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;
|
|
710
784
|
}
|
|
@@ -735,8 +809,59 @@ function applyProjectedLayout(nodes, projected) {
|
|
|
735
809
|
function notifyEngine(engine) {
|
|
736
810
|
engine._notify?.();
|
|
737
811
|
}
|
|
812
|
+
function finalizeEngineChange(engine) {
|
|
813
|
+
const finalizableEngine = engine;
|
|
814
|
+
finalizableEngine.cleanNodes();
|
|
815
|
+
finalizableEngine.saveInitial();
|
|
816
|
+
}
|
|
738
817
|
|
|
739
818
|
class ZflowGridStackEngine extends GridStackEngine {
|
|
819
|
+
applyKeyboardCommand(id, command) {
|
|
820
|
+
if (command === 'grow' || command === 'shrink') {
|
|
821
|
+
return this.stepNodeWidth(id, command);
|
|
822
|
+
}
|
|
823
|
+
return this.moveNodeByKeyboard(id, command);
|
|
824
|
+
}
|
|
825
|
+
moveNodeByKeyboard(id, command) {
|
|
826
|
+
const nodes = this.nodes;
|
|
827
|
+
const slot = resolveZFlowKeyboardInsertionSlot(nodes, id, command, this.column);
|
|
828
|
+
if (slot === null)
|
|
829
|
+
return false;
|
|
830
|
+
const ordered = sortNodesByZFlowOrder(nodes);
|
|
831
|
+
const orderedIds = ordered
|
|
832
|
+
.filter((node) => node.id)
|
|
833
|
+
.map((node) => node.id);
|
|
834
|
+
const nextOrder = reorderByInsertionSlot(orderedIds, id, slot);
|
|
835
|
+
nextOrder.forEach((nodeId, index) => {
|
|
836
|
+
const node = nodes.find((candidate) => candidate.id === nodeId);
|
|
837
|
+
if (node)
|
|
838
|
+
node.zFlowOrder = index;
|
|
839
|
+
});
|
|
840
|
+
const snapshot = this.takeLayoutSnapshot(nodes);
|
|
841
|
+
applyProjectedLayout(nodes, projectZFlowLayout(sortNodesByZFlowOrder(nodes), this.column));
|
|
842
|
+
const changed = this.markLayoutChangesDirty(snapshot);
|
|
843
|
+
if (!changed)
|
|
844
|
+
return false;
|
|
845
|
+
this.notifyAndFinalizeKeyboardChange();
|
|
846
|
+
return true;
|
|
847
|
+
}
|
|
848
|
+
stepNodeWidth(id, direction) {
|
|
849
|
+
const nodes = this.nodes;
|
|
850
|
+
const node = nodes.find((candidate) => candidate.id === id);
|
|
851
|
+
if (!node)
|
|
852
|
+
return false;
|
|
853
|
+
syncNodeOrderFromLayout(nodes);
|
|
854
|
+
const x = node.x ?? 0;
|
|
855
|
+
const maxWidth = node.maxW ?? this.column;
|
|
856
|
+
const hardMax = Math.min(maxWidth, this.column - x);
|
|
857
|
+
const minWidth = Math.max(1, node.minW ?? 1);
|
|
858
|
+
if (minWidth > hardMax)
|
|
859
|
+
return false;
|
|
860
|
+
const target = resolveDirectionalResizeWidthStep(node.w ?? 1, direction, maxWidth, this.column, minWidth, hardMax);
|
|
861
|
+
if (target === null)
|
|
862
|
+
return false;
|
|
863
|
+
return this.applyKeyboardWidth(node, target);
|
|
864
|
+
}
|
|
740
865
|
moveNodeCheck(node, opts) {
|
|
741
866
|
if (opts.resizing) {
|
|
742
867
|
return this.moveNodeCheckWithSteppedResize(node, opts);
|
|
@@ -771,6 +896,21 @@ class ZflowGridStackEngine extends GridStackEngine {
|
|
|
771
896
|
notifyEngine(this);
|
|
772
897
|
return true;
|
|
773
898
|
}
|
|
899
|
+
applyKeyboardWidth(node, width) {
|
|
900
|
+
const nodes = this.nodes;
|
|
901
|
+
const snapshot = this.takeLayoutSnapshot(nodes);
|
|
902
|
+
node.w = resolveResizeWidthStep(width, node.maxW ?? this.column, this.column, node.minW ?? 1, this.column - (node.x ?? 0));
|
|
903
|
+
applyProjectedLayout(nodes, projectZFlowLayout(sortNodesByZFlowOrder(nodes), this.column));
|
|
904
|
+
const changed = this.markLayoutChangesDirty(snapshot);
|
|
905
|
+
if (!changed)
|
|
906
|
+
return false;
|
|
907
|
+
this.notifyAndFinalizeKeyboardChange();
|
|
908
|
+
return true;
|
|
909
|
+
}
|
|
910
|
+
notifyAndFinalizeKeyboardChange() {
|
|
911
|
+
notifyEngine(this);
|
|
912
|
+
finalizeEngineChange(this);
|
|
913
|
+
}
|
|
774
914
|
commitZFlowLayout() {
|
|
775
915
|
const nodes = this.nodes;
|
|
776
916
|
normalizeNodeOrder(nodes);
|
|
@@ -882,15 +1022,9 @@ class ZflowGridStackEngine extends GridStackEngine {
|
|
|
882
1022
|
if (n)
|
|
883
1023
|
n.zFlowOrder = idx;
|
|
884
1024
|
});
|
|
885
|
-
const
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
node.y = projectedSource.y;
|
|
889
|
-
node.w = projectedSource.w;
|
|
890
|
-
node.h = projectedSource.h;
|
|
891
|
-
node._dirty = true;
|
|
892
|
-
notifyEngine(this);
|
|
893
|
-
}
|
|
1025
|
+
const projectedLayout = projectZFlowLayout(sortNodesByZFlowOrder(nodes), this.column);
|
|
1026
|
+
applyProjectedLayout(nodes, projectedLayout);
|
|
1027
|
+
notifyEngine(this);
|
|
894
1028
|
return true;
|
|
895
1029
|
}
|
|
896
1030
|
}
|
|
@@ -915,6 +1049,48 @@ const ENGINE_PROFILES = {
|
|
|
915
1049
|
},
|
|
916
1050
|
};
|
|
917
1051
|
|
|
1052
|
+
function isOnlyModifier(event, modifier) {
|
|
1053
|
+
const modifiers = {
|
|
1054
|
+
shift: event.shiftKey,
|
|
1055
|
+
ctrl: event.ctrlKey,
|
|
1056
|
+
meta: event.metaKey,
|
|
1057
|
+
alt: event.altKey,
|
|
1058
|
+
};
|
|
1059
|
+
return (modifiers[modifier] &&
|
|
1060
|
+
Object.entries(modifiers).every(([name, isPressed]) => name === modifier || !isPressed));
|
|
1061
|
+
}
|
|
1062
|
+
function parseCardKeyCommand(event) {
|
|
1063
|
+
if (isOnlyModifier(event, 'shift')) {
|
|
1064
|
+
if (event.key === 'ArrowRight')
|
|
1065
|
+
return 'grow';
|
|
1066
|
+
if (event.key === 'ArrowLeft')
|
|
1067
|
+
return 'shrink';
|
|
1068
|
+
}
|
|
1069
|
+
if (isOnlyModifier(event, 'meta')) {
|
|
1070
|
+
if (event.key === 'ArrowLeft')
|
|
1071
|
+
return 'row-start';
|
|
1072
|
+
if (event.key === 'ArrowRight')
|
|
1073
|
+
return 'row-end';
|
|
1074
|
+
}
|
|
1075
|
+
if (isOnlyModifier(event, 'ctrl')) {
|
|
1076
|
+
if (event.key === 'ArrowLeft')
|
|
1077
|
+
return 'left';
|
|
1078
|
+
if (event.key === 'ArrowRight')
|
|
1079
|
+
return 'right';
|
|
1080
|
+
if (event.key === 'ArrowUp')
|
|
1081
|
+
return 'up';
|
|
1082
|
+
if (event.key === 'ArrowDown')
|
|
1083
|
+
return 'down';
|
|
1084
|
+
if (event.key === 'Home')
|
|
1085
|
+
return 'row-start';
|
|
1086
|
+
if (event.key === 'End')
|
|
1087
|
+
return 'row-end';
|
|
1088
|
+
}
|
|
1089
|
+
return null;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
const CARD_ARIA_KEYSHORTCUTS = 'Shift+ArrowRight Shift+ArrowLeft Control+ArrowLeft Control+ArrowRight Control+ArrowUp Control+ArrowDown Control+Home Control+End Meta+ArrowLeft Meta+ArrowRight';
|
|
1093
|
+
|
|
918
1094
|
document.body.classList.add('ui5-content-density-compact');
|
|
919
1095
|
class Dashboard {
|
|
920
1096
|
static registerAngularComponents(componentTypes) {
|
|
@@ -923,27 +1099,50 @@ class Dashboard {
|
|
|
923
1099
|
hostEl = inject((ElementRef));
|
|
924
1100
|
injector = inject(Injector);
|
|
925
1101
|
sanitizer = inject(DomSanitizer);
|
|
926
|
-
|
|
927
|
-
config = input
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
1102
|
+
i18nService = inject(DashboardI18nService);
|
|
1103
|
+
config = input({}, /* @ts-ignore */
|
|
1104
|
+
...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
|
|
1105
|
+
sections = model([], /* @ts-ignore */
|
|
1106
|
+
...(ngDevMode ? [{ debugName: "sections" }] : /* istanbul ignore next */ []));
|
|
1107
|
+
cards = model([], /* @ts-ignore */
|
|
1108
|
+
...(ngDevMode ? [{ debugName: "cards" }] : /* istanbul ignore next */ []));
|
|
1109
|
+
availableCards = input([], /* @ts-ignore */
|
|
1110
|
+
...(ngDevMode ? [{ debugName: "availableCards" }] : /* istanbul ignore next */ []));
|
|
1111
|
+
customActions = input([], /* @ts-ignore */
|
|
1112
|
+
...(ngDevMode ? [{ debugName: "customActions" }] : /* istanbul ignore next */ []));
|
|
1113
|
+
i18n = input(EN_DEFAULTS, /* @ts-ignore */
|
|
1114
|
+
...(ngDevMode ? [{ debugName: "i18n" }] : /* istanbul ignore next */ []));
|
|
1115
|
+
loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1116
|
+
loadingDelay = input(1000, { ...(ngDevMode ? { debugName: "loadingDelay" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
932
1117
|
saved = output();
|
|
933
1118
|
actionButtonClick = output();
|
|
934
1119
|
unsavedChangesChange = output();
|
|
935
1120
|
i18nKeys = DASHBOARD_I18N_KEYS;
|
|
936
1121
|
/** True once the user has dragged/resized any grid item while in edit mode. */
|
|
937
|
-
gridDirty = signal(false,
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
1122
|
+
gridDirty = signal(false, /* @ts-ignore */
|
|
1123
|
+
...(ngDevMode ? [{ debugName: "gridDirty" }] : /* istanbul ignore next */ []));
|
|
1124
|
+
isXLPage = signal(true, /* @ts-ignore */
|
|
1125
|
+
...(ngDevMode ? [{ debugName: "isXLPage" }] : /* istanbul ignore next */ []));
|
|
1126
|
+
editMode = signal(false, /* @ts-ignore */
|
|
1127
|
+
...(ngDevMode ? [{ debugName: "editMode" }] : /* istanbul ignore next */ []));
|
|
1128
|
+
compactToolbar = signal(false, /* @ts-ignore */
|
|
1129
|
+
...(ngDevMode ? [{ debugName: "compactToolbar" }] : /* istanbul ignore next */ []));
|
|
1130
|
+
toolbarMenuOpen = signal(false, /* @ts-ignore */
|
|
1131
|
+
...(ngDevMode ? [{ debugName: "toolbarMenuOpen" }] : /* istanbul ignore next */ []));
|
|
1132
|
+
cardDialogOpen = signal(false, /* @ts-ignore */
|
|
1133
|
+
...(ngDevMode ? [{ debugName: "cardDialogOpen" }] : /* istanbul ignore next */ []));
|
|
1134
|
+
discardDialogOpen = signal(false, /* @ts-ignore */
|
|
1135
|
+
...(ngDevMode ? [{ debugName: "discardDialogOpen" }] : /* istanbul ignore next */ []));
|
|
1136
|
+
unsavedNavDialogOpen = signal(false, /* @ts-ignore */
|
|
1137
|
+
...(ngDevMode ? [{ debugName: "unsavedNavDialogOpen" }] : /* istanbul ignore next */ []));
|
|
1138
|
+
backgroundImageHeight = signal(null, /* @ts-ignore */
|
|
1139
|
+
...(ngDevMode ? [{ debugName: "backgroundImageHeight" }] : /* istanbul ignore next */ []));
|
|
1140
|
+
dragOriginStyle = signal(null, /* @ts-ignore */
|
|
1141
|
+
...(ngDevMode ? [{ debugName: "dragOriginStyle" }] : /* istanbul ignore next */ []));
|
|
1142
|
+
dragOriginVisible = signal(false, /* @ts-ignore */
|
|
1143
|
+
...(ngDevMode ? [{ debugName: "dragOriginVisible" }] : /* istanbul ignore next */ []));
|
|
1144
|
+
busyVisible = signal(false, /* @ts-ignore */
|
|
1145
|
+
...(ngDevMode ? [{ debugName: "busyVisible" }] : /* istanbul ignore next */ []));
|
|
947
1146
|
hasUnsavedChanges = computed(() => {
|
|
948
1147
|
if (!this.editMode())
|
|
949
1148
|
return false;
|
|
@@ -951,23 +1150,36 @@ class Dashboard {
|
|
|
951
1150
|
return true;
|
|
952
1151
|
return (JSON.stringify(this.sections()) !== this.sectionsSnapshotJson ||
|
|
953
1152
|
JSON.stringify(this.cards()) !== this.cardsSnapshotJson);
|
|
954
|
-
},
|
|
1153
|
+
}, /* @ts-ignore */
|
|
1154
|
+
...(ngDevMode ? [{ debugName: "hasUnsavedChanges" }] : /* istanbul ignore next */ []));
|
|
955
1155
|
safeTitle = computed(() => {
|
|
956
|
-
const clean = this.sanitizer.sanitize(SecurityContext.HTML, this.config().title
|
|
1156
|
+
const clean = this.sanitizer.sanitize(SecurityContext.HTML, this.config().title ??
|
|
1157
|
+
this.i18nService.getTranslation(DASHBOARD_I18N_KEYS.TITLE)) ?? '';
|
|
957
1158
|
return this.sanitizer.bypassSecurityTrustHtml(clean);
|
|
958
|
-
},
|
|
1159
|
+
}, /* @ts-ignore */
|
|
1160
|
+
...(ngDevMode ? [{ debugName: "safeTitle" }] : /* istanbul ignore next */ []));
|
|
959
1161
|
safeDescription = computed(() => {
|
|
960
|
-
const desc = this.config().description
|
|
1162
|
+
const desc = this.config().description ??
|
|
1163
|
+
this.i18nService.getTranslation(DASHBOARD_I18N_KEYS.DESCRIPTION);
|
|
961
1164
|
if (!desc)
|
|
962
1165
|
return null;
|
|
963
1166
|
const clean = this.sanitizer.sanitize(SecurityContext.HTML, desc) ?? '';
|
|
964
1167
|
return this.sanitizer.bypassSecurityTrustHtml(clean);
|
|
965
|
-
},
|
|
966
|
-
|
|
967
|
-
|
|
1168
|
+
}, /* @ts-ignore */
|
|
1169
|
+
...(ngDevMode ? [{ debugName: "safeDescription" }] : /* istanbul ignore next */ []));
|
|
1170
|
+
engineProfile = computed(() => this.config().zFlow ? ENGINE_PROFILES.zFlow : ENGINE_PROFILES.default, /* @ts-ignore */
|
|
1171
|
+
...(ngDevMode ? [{ debugName: "engineProfile" }] : /* istanbul ignore next */ []));
|
|
1172
|
+
keyboardNavigationActive = computed(() => this.editMode() && !!this.config().zFlow, /* @ts-ignore */
|
|
1173
|
+
...(ngDevMode ? [{ debugName: "keyboardNavigationActive" }] : /* istanbul ignore next */ []));
|
|
1174
|
+
cardAriaKeyshortcuts = CARD_ARIA_KEYSHORTCUTS;
|
|
1175
|
+
hasToolbarMenuContent = computed(() => !!this.config().editable || this.customActions().length > 0, /* @ts-ignore */
|
|
1176
|
+
...(ngDevMode ? [{ debugName: "hasToolbarMenuContent" }] : /* istanbul ignore next */ []));
|
|
1177
|
+
gridStackEngine = computed(() => this.engineProfile().engineClass, /* @ts-ignore */
|
|
1178
|
+
...(ngDevMode ? [{ debugName: "gridStackEngine" }] : /* istanbul ignore next */ []));
|
|
968
1179
|
gridBreakpoints = computed(() => [
|
|
969
1180
|
...this.engineProfile().breakpoints,
|
|
970
|
-
],
|
|
1181
|
+
], /* @ts-ignore */
|
|
1182
|
+
...(ngDevMode ? [{ debugName: "gridBreakpoints" }] : /* istanbul ignore next */ []));
|
|
971
1183
|
columnVars = computed(() => {
|
|
972
1184
|
const [sm, md, lg, xl] = this.engineProfile().sectionColumns;
|
|
973
1185
|
return {
|
|
@@ -976,27 +1188,31 @@ class Dashboard {
|
|
|
976
1188
|
'--dashboard-cols-lg': lg,
|
|
977
1189
|
'--dashboard-cols-xl': xl,
|
|
978
1190
|
};
|
|
979
|
-
},
|
|
980
|
-
|
|
981
|
-
addedCardsIds = computed(() => new Set(this.cards().map((c) => c.id)),
|
|
1191
|
+
}, /* @ts-ignore */
|
|
1192
|
+
...(ngDevMode ? [{ debugName: "columnVars" }] : /* istanbul ignore next */ []));
|
|
1193
|
+
addedCardsIds = computed(() => new Set(this.cards().map((c) => c.id)), /* @ts-ignore */
|
|
1194
|
+
...(ngDevMode ? [{ debugName: "addedCardsIds" }] : /* istanbul ignore next */ []));
|
|
982
1195
|
editViewButton = computed(() => ({
|
|
983
1196
|
icon: 'action-settings',
|
|
984
1197
|
design: 'Transparent',
|
|
985
|
-
tooltip: this.
|
|
986
|
-
text: '',
|
|
1198
|
+
tooltip: this.i18nService.getTranslation(DASHBOARD_I18N_KEYS.EDIT_HOME_BUTTON),
|
|
987
1199
|
...this.config().buttonsSettings?.editViewButton,
|
|
988
|
-
|
|
1200
|
+
text: this.i18nService.getTranslation(DASHBOARD_I18N_KEYS.EDIT_HOME_BUTTON),
|
|
1201
|
+
}), /* @ts-ignore */
|
|
1202
|
+
...(ngDevMode ? [{ debugName: "editViewButton" }] : /* istanbul ignore next */ []));
|
|
989
1203
|
editCardsButton = computed(() => ({
|
|
990
1204
|
icon: '',
|
|
991
1205
|
design: 'Default',
|
|
992
1206
|
tooltip: '',
|
|
993
|
-
text: this.i18n.getTranslation(DASHBOARD_I18N_KEYS.EDIT_CARDS),
|
|
994
1207
|
...this.config().buttonsSettings?.editCardsButton,
|
|
995
|
-
|
|
1208
|
+
text: this.i18nService.getTranslation(DASHBOARD_I18N_KEYS.EDIT_CARDS_BUTTON),
|
|
1209
|
+
}), /* @ts-ignore */
|
|
1210
|
+
...(ngDevMode ? [{ debugName: "editCardsButton" }] : /* istanbul ignore next */ []));
|
|
996
1211
|
sectionCards = computed(() => {
|
|
997
1212
|
const all = this.cards();
|
|
998
1213
|
return (sectionId) => all.filter((c) => c.sectionId === sectionId);
|
|
999
|
-
},
|
|
1214
|
+
}, /* @ts-ignore */
|
|
1215
|
+
...(ngDevMode ? [{ debugName: "sectionCards" }] : /* istanbul ignore next */ []));
|
|
1000
1216
|
looseCards = linkedSignal(() => {
|
|
1001
1217
|
const loose = this.cards().filter((c) => !c.sectionId);
|
|
1002
1218
|
const cardHeight = this.config().zFlow?.cardHeight;
|
|
@@ -1008,7 +1224,12 @@ class Dashboard {
|
|
|
1008
1224
|
maxH: cardHeight,
|
|
1009
1225
|
minH: cardHeight,
|
|
1010
1226
|
}));
|
|
1011
|
-
},
|
|
1227
|
+
}, /* @ts-ignore */
|
|
1228
|
+
...(ngDevMode ? [{ debugName: "looseCards" }] : /* istanbul ignore next */ []));
|
|
1229
|
+
isEmpty = computed(() => this.looseCards().length === 0, /* @ts-ignore */
|
|
1230
|
+
...(ngDevMode ? [{ debugName: "isEmpty" }] : /* istanbul ignore next */ []));
|
|
1231
|
+
isDashboardEditable = computed(() => this.config().editable, /* @ts-ignore */
|
|
1232
|
+
...(ngDevMode ? [{ debugName: "isDashboardEditable" }] : /* istanbul ignore next */ []));
|
|
1012
1233
|
gridOptions = computed(() => ({
|
|
1013
1234
|
cellHeight: CELL_HEIGHT,
|
|
1014
1235
|
sizeToContent: true,
|
|
@@ -1024,14 +1245,19 @@ class Dashboard {
|
|
|
1024
1245
|
// section grid's container queries via --dashboard-cols-* CSS vars).
|
|
1025
1246
|
breakpoints: this.gridBreakpoints(),
|
|
1026
1247
|
},
|
|
1027
|
-
}),
|
|
1248
|
+
}), /* @ts-ignore */
|
|
1249
|
+
...(ngDevMode ? [{ debugName: "gridOptions" }] : /* istanbul ignore next */ []));
|
|
1028
1250
|
/** JSON snapshots of sections/cards taken on entering edit mode, used to detect changes. */
|
|
1029
1251
|
sectionsSnapshotJson = '';
|
|
1030
1252
|
cardsSnapshotJson = '';
|
|
1031
1253
|
sectionsSnapshot = [];
|
|
1032
1254
|
cardsSnapshot = [];
|
|
1033
|
-
gridStack = viewChild.required('grid'
|
|
1034
|
-
|
|
1255
|
+
gridStack = viewChild.required('grid', /* @ts-ignore */
|
|
1256
|
+
...(ngDevMode ? [{ debugName: "gridStack" }] : /* istanbul ignore next */ []));
|
|
1257
|
+
dragOriginPlaceholder = viewChild('dragOriginPlaceholder', /* @ts-ignore */
|
|
1258
|
+
...(ngDevMode ? [{ debugName: "dragOriginPlaceholder" }] : /* istanbul ignore next */ []));
|
|
1259
|
+
addCardBtn = viewChild('editCardsBtn', /* @ts-ignore */
|
|
1260
|
+
...(ngDevMode ? [{ debugName: "addCardBtn" }] : /* istanbul ignore next */ []));
|
|
1035
1261
|
resizeObserver;
|
|
1036
1262
|
cardsPosition = new Map();
|
|
1037
1263
|
/** Callback that resumes the intercepted navigation once the user resolves the dialog. */
|
|
@@ -1050,7 +1276,37 @@ class Dashboard {
|
|
|
1050
1276
|
this.unsavedChangesChange.emit(this.hasUnsavedChanges());
|
|
1051
1277
|
});
|
|
1052
1278
|
effect(() => {
|
|
1053
|
-
this.i18n
|
|
1279
|
+
const supplied = this.i18n();
|
|
1280
|
+
const cfg = this.config();
|
|
1281
|
+
const fromConfig = {};
|
|
1282
|
+
if (cfg.title != null)
|
|
1283
|
+
fromConfig.title = cfg.title;
|
|
1284
|
+
if (cfg.description != null)
|
|
1285
|
+
fromConfig.description = cfg.description;
|
|
1286
|
+
const suppliedNonEmpty = supplied && Object.keys(supplied).length > 0 ? supplied : null;
|
|
1287
|
+
const resolved = suppliedNonEmpty || Object.keys(fromConfig).length > 0
|
|
1288
|
+
? { ...fromConfig, ...suppliedNonEmpty }
|
|
1289
|
+
: EN_DEFAULTS;
|
|
1290
|
+
this.i18nService.overrides.set(resolved);
|
|
1291
|
+
});
|
|
1292
|
+
effect((onCleanup) => {
|
|
1293
|
+
if (!this.loading()) {
|
|
1294
|
+
this.busyVisible.set(false);
|
|
1295
|
+
return;
|
|
1296
|
+
}
|
|
1297
|
+
const delay = Math.max(0, this.loadingDelay());
|
|
1298
|
+
if (delay === 0) {
|
|
1299
|
+
this.busyVisible.set(true);
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1302
|
+
const timer = setTimeout(() => {
|
|
1303
|
+
this.busyVisible.set(true);
|
|
1304
|
+
}, delay);
|
|
1305
|
+
// Covers both the load finishing first and the component being destroyed
|
|
1306
|
+
// mid-flight, so a resolved request never leaves a spinner behind.
|
|
1307
|
+
onCleanup(() => {
|
|
1308
|
+
clearTimeout(timer);
|
|
1309
|
+
});
|
|
1054
1310
|
});
|
|
1055
1311
|
effect((onCleanup) => {
|
|
1056
1312
|
const url = this.config().backgroundImageUrl;
|
|
@@ -1092,6 +1348,7 @@ class Dashboard {
|
|
|
1092
1348
|
}
|
|
1093
1349
|
enterEditMode() {
|
|
1094
1350
|
this.updateCardsPositions();
|
|
1351
|
+
this.getZFlowEngine()?.syncZFlowOrderFromLayout();
|
|
1095
1352
|
this.sectionsSnapshot = [...this.sections()];
|
|
1096
1353
|
this.cardsSnapshot = [...this.cards()];
|
|
1097
1354
|
this.sectionsSnapshotJson = JSON.stringify(this.sections());
|
|
@@ -1102,6 +1359,15 @@ class Dashboard {
|
|
|
1102
1359
|
this.addCardBtn()?.element.focus();
|
|
1103
1360
|
}, { injector: this.injector });
|
|
1104
1361
|
}
|
|
1362
|
+
/**
|
|
1363
|
+
* Empty-state call to action: switch to edit mode and immediately surface the
|
|
1364
|
+
* Edit Cards dialog, so a user starting from an empty home lands directly on
|
|
1365
|
+
* the card picker instead of an empty grid.
|
|
1366
|
+
*/
|
|
1367
|
+
enterEditModeAndEditCards() {
|
|
1368
|
+
this.enterEditMode();
|
|
1369
|
+
this.openCardPanel();
|
|
1370
|
+
}
|
|
1105
1371
|
saveEdit() {
|
|
1106
1372
|
this.updateCardsPositions();
|
|
1107
1373
|
const savedCards = this.cards().map((c) => {
|
|
@@ -1199,6 +1465,61 @@ class Dashboard {
|
|
|
1199
1465
|
this.cardDialogOpen.set(false);
|
|
1200
1466
|
this.gridDirty.set(false);
|
|
1201
1467
|
this.editMode.set(false);
|
|
1468
|
+
afterNextRender(() => {
|
|
1469
|
+
this.restoreGridLayoutFromCards();
|
|
1470
|
+
const engine = this.getZFlowEngine();
|
|
1471
|
+
engine?.syncZFlowOrderFromLayout();
|
|
1472
|
+
engine?.commitZFlowLayout();
|
|
1473
|
+
}, { injector: this.injector });
|
|
1474
|
+
}
|
|
1475
|
+
restoreGridLayoutFromCards() {
|
|
1476
|
+
const grid = this.gridStack().grid;
|
|
1477
|
+
if (!grid)
|
|
1478
|
+
return;
|
|
1479
|
+
grid.load(this.createGridLayoutFromCards(grid.engine.nodes), false);
|
|
1480
|
+
}
|
|
1481
|
+
createGridLayoutFromCards(nodes) {
|
|
1482
|
+
const cardsById = new Map(this.cards().map((card) => [card.id, card]));
|
|
1483
|
+
return nodes.map((node) => {
|
|
1484
|
+
const position = node.id ? cardsById.get(node.id) : undefined;
|
|
1485
|
+
return {
|
|
1486
|
+
id: node.id,
|
|
1487
|
+
x: position?.x ?? node.x,
|
|
1488
|
+
y: position?.y ?? node.y,
|
|
1489
|
+
w: position?.w ?? node.w,
|
|
1490
|
+
h: position?.h ?? node.h,
|
|
1491
|
+
};
|
|
1492
|
+
});
|
|
1493
|
+
}
|
|
1494
|
+
onCardKeydown(event, cardId) {
|
|
1495
|
+
const zFlowEngine = this.getZFlowEngine();
|
|
1496
|
+
if (!this.keyboardNavigationActive() ||
|
|
1497
|
+
!zFlowEngine ||
|
|
1498
|
+
event.target !== event.currentTarget) {
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
const command = parseCardKeyCommand(event);
|
|
1502
|
+
if (!command)
|
|
1503
|
+
return;
|
|
1504
|
+
event.preventDefault();
|
|
1505
|
+
event.stopPropagation();
|
|
1506
|
+
const gridItemHost = event.currentTarget;
|
|
1507
|
+
const node = gridItemHost.gridstackNode;
|
|
1508
|
+
if (!node || node.id !== cardId) {
|
|
1509
|
+
this.restoreCardFocus(gridItemHost);
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
const changed = zFlowEngine.applyKeyboardCommand(cardId, command);
|
|
1513
|
+
if (changed) {
|
|
1514
|
+
this.onGridChange();
|
|
1515
|
+
}
|
|
1516
|
+
this.restoreCardFocus(gridItemHost);
|
|
1517
|
+
}
|
|
1518
|
+
restoreCardFocus(host) {
|
|
1519
|
+
queueMicrotask(() => {
|
|
1520
|
+
if (host.isConnected && this.editMode())
|
|
1521
|
+
host.focus({ preventScroll: true });
|
|
1522
|
+
});
|
|
1202
1523
|
}
|
|
1203
1524
|
removeSection(id) {
|
|
1204
1525
|
this.sections.update((list) => list.filter((s) => s.id !== id));
|
|
@@ -1206,7 +1527,6 @@ class Dashboard {
|
|
|
1206
1527
|
}
|
|
1207
1528
|
removeCard(id) {
|
|
1208
1529
|
const wasLooseCard = this.looseCards().some((c) => c.id === id);
|
|
1209
|
-
this.cardsPosition.delete(id);
|
|
1210
1530
|
this.cards.update((list) => list.filter((c) => c.id !== id));
|
|
1211
1531
|
if (wasLooseCard) {
|
|
1212
1532
|
afterNextRender(() => {
|
|
@@ -1235,22 +1555,18 @@ class Dashboard {
|
|
|
1235
1555
|
}
|
|
1236
1556
|
onDragStart(event) {
|
|
1237
1557
|
this.getZFlowEngine()?.syncZFlowOrderFromLayout();
|
|
1558
|
+
this.dragOriginVisible.set(false);
|
|
1238
1559
|
if (!this.engineProfile().renderOriginPosition) {
|
|
1239
1560
|
return;
|
|
1240
1561
|
}
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
this.dragOriginStyle.set({
|
|
1246
|
-
top: `${elRect.top - gridRect.top}px`,
|
|
1247
|
-
left: `${elRect.left - gridRect.left}px`,
|
|
1248
|
-
width: `${elRect.width}px`,
|
|
1249
|
-
height: `${elRect.height}px`,
|
|
1250
|
-
});
|
|
1562
|
+
this.renderDragOriginPlaceholder(event.el);
|
|
1563
|
+
}
|
|
1564
|
+
onDrag() {
|
|
1565
|
+
this.dragOriginVisible.set(false);
|
|
1251
1566
|
}
|
|
1252
1567
|
onDragStop() {
|
|
1253
1568
|
this.getZFlowEngine()?.commitZFlowLayout();
|
|
1569
|
+
this.dragOriginVisible.set(false);
|
|
1254
1570
|
this.dragOriginStyle.set(null);
|
|
1255
1571
|
}
|
|
1256
1572
|
onGridChange() {
|
|
@@ -1283,6 +1599,39 @@ class Dashboard {
|
|
|
1283
1599
|
const engine = this.gridStack().grid?.engine;
|
|
1284
1600
|
return engine instanceof ZflowGridStackEngine ? engine : null;
|
|
1285
1601
|
}
|
|
1602
|
+
createDragOriginClone(gridItem) {
|
|
1603
|
+
const source = gridItem.querySelector(DASHBOARD_CARD_DRAG_ORIGIN_SELECTOR);
|
|
1604
|
+
if (!source)
|
|
1605
|
+
return null;
|
|
1606
|
+
const clone = source.cloneNode(true);
|
|
1607
|
+
clone.classList.add('mfp-dashboard__drag-origin-content');
|
|
1608
|
+
clone.setAttribute('aria-hidden', 'true');
|
|
1609
|
+
clone.removeAttribute('id');
|
|
1610
|
+
clone.querySelectorAll('[id]').forEach((element) => {
|
|
1611
|
+
element.removeAttribute('id');
|
|
1612
|
+
});
|
|
1613
|
+
return clone;
|
|
1614
|
+
}
|
|
1615
|
+
renderDragOriginPlaceholder(gridItem) {
|
|
1616
|
+
const gridEl = this.gridStack().el;
|
|
1617
|
+
const gridRect = gridEl.getBoundingClientRect();
|
|
1618
|
+
const itemRect = gridItem.getBoundingClientRect();
|
|
1619
|
+
const clone = this.createDragOriginClone(gridItem);
|
|
1620
|
+
this.dragOriginStyle.set({
|
|
1621
|
+
top: `${itemRect.top - gridRect.top}px`,
|
|
1622
|
+
left: `${itemRect.left - gridRect.left}px`,
|
|
1623
|
+
width: `${itemRect.width}px`,
|
|
1624
|
+
height: `${itemRect.height}px`,
|
|
1625
|
+
});
|
|
1626
|
+
this.dragOriginVisible.set(true);
|
|
1627
|
+
if (!clone)
|
|
1628
|
+
return;
|
|
1629
|
+
afterNextRender(() => {
|
|
1630
|
+
if (!this.dragOriginVisible())
|
|
1631
|
+
return;
|
|
1632
|
+
this.dragOriginPlaceholder()?.nativeElement.replaceChildren(clone);
|
|
1633
|
+
}, { injector: this.injector });
|
|
1634
|
+
}
|
|
1286
1635
|
updateCardsForBreakpoint(updateCard) {
|
|
1287
1636
|
this.getZFlowEngine()?.syncZFlowOrderFromLayout();
|
|
1288
1637
|
this.cards.set(this.cards().map(updateCard));
|
|
@@ -1314,10 +1663,10 @@ class Dashboard {
|
|
|
1314
1663
|
}
|
|
1315
1664
|
}
|
|
1316
1665
|
}
|
|
1317
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1318
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: Dashboard, isStandalone: true, selector: "mfp-dashboard", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: false, transformFunction: null }, cards: { classPropertyName: "cards", publicName: "cards", isSignal: true, isRequired: false, transformFunction: null }, availableCards: { classPropertyName: "availableCards", publicName: "availableCards", isSignal: true, isRequired: false, transformFunction: null }, language: { classPropertyName: "language", publicName: "language", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sections: "sectionsChange", cards: "cardsChange", saved: "saved", actionButtonClick: "actionButtonClick", unsavedChangesChange: "unsavedChangesChange" }, host: { properties: { "style.background-image": "config().backgroundImageUrl ? \"url(\" + config().backgroundImageUrl + \")\" : null", "style.background-size": "backgroundImageHeight() ? \"100% \" + backgroundImageHeight() + \"px\" : \"100% auto\"" } }, providers: [DashboardI18nService], viewQueries: [{ propertyName: "gridStack", first: true, predicate: ["grid"], descendants: true, isSignal: true }, { propertyName: "addCardBtn", first: true, predicate: ["editCardsBtn"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"mfp-dashboard\"\n data-testid=\"dashboard\"\n [style]=\"columnVars()\"\n [class.edit]=\"editMode()\"\n>\n <div class=\"mfp-dashboard__topbar\">\n <div class=\"mfp-dashboard__topbar-row\">\n <div class=\"mfp-dashboard__header\">\n <div class=\"mfp-dashboard__title-row\">\n @if (config().title) {\n <ui5-title\n data-testid=\"dashboard-title\"\n level=\"H3\"\n size=\"H3\"\n wrapping-type=\"Normal\"\n >\n <span [innerHTML]=\"safeTitle()\"></span>\n </ui5-title>\n }\n @if (hasUnsavedChanges()) {\n <div class=\"mfp-dashboard__unsaved-changes\" role=\"status\">\n <ui5-icon\n class=\"mfp-dashboard__unsaved-changes-icon\"\n name=\"user-edit\"\n [accessibleName]=\"i18n.getTranslation(i18nKeys.UNSAVED_CHANGES)\"\n />\n <span class=\"mfp-dashboard__unsaved-changes-text\">{{\n i18n.getTranslation(i18nKeys.UNSAVED_CHANGES)\n }}</span>\n </div>\n }\n </div>\n @if (config().description) {\n <ui5-title\n data-testid=\"dashboard-description\"\n level=\"H5\"\n size=\"H5\"\n wrapping-type=\"Normal\"\n >\n <span\n class=\"mfp-dashboard__description\"\n [innerHTML]=\"safeDescription()\"\n ></span>\n </ui5-title>\n }\n </div>\n\n <div class=\"mfp-dashboard__toolbar\">\n @if (editMode()) {\n <ui5-button\n #editCardsBtn\n data-testid=\"dashboard-edit-cards-btn\"\n id=\"edit-cards-btn\"\n [accessibleName]=\"\n editCardsButton().text ||\n editCardsButton().tooltip ||\n i18n.getTranslation(i18nKeys.EDIT_CARDS)\n \"\n [design]=\"editCardsButton().design\"\n [icon]=\"editCardsButton().icon\"\n [tooltip]=\"editCardsButton().tooltip\"\n (click)=\"openCardPanel()\"\n >{{ editCardsButton().text }}</ui5-button\n >\n } @else if (compactToolbar()) {\n <ui5-button\n #menuBtn\n data-testid=\"dashboard-toolbar-menu-btn\"\n design=\"Transparent\"\n icon=\"menu2\"\n [accessibleName]=\"i18n.getTranslation(i18nKeys.ACTIONS)\"\n [tooltip]=\"i18n.getTranslation(i18nKeys.ACTIONS)\"\n (click)=\"toolbarMenuOpen.update((v) => !v)\"\n />\n <ui5-menu\n data-testid=\"dashboard-toolbar-menu\"\n [open]=\"toolbarMenuOpen()\"\n [opener]=\"menuBtn.element\"\n (ui5Close)=\"toolbarMenuOpen.set(false)\"\n (ui5ItemClick)=\"\n onMenuItemClick(\n $any($event).detail.item.dataset['action'],\n $event\n )\n \"\n (ui5Open)=\"toolbarMenuOpen.set(true)\"\n >\n @if (config().editButtonFirst && config().editable) {\n <ui5-menu-item\n data-action=\"edit-view\"\n data-testid=\"dashboard-action-edit-view\"\n [icon]=\"editViewButton().icon\"\n [text]=\"\n editViewButton().text ||\n i18n.getTranslation(i18nKeys.EDIT_VIEW)\n \"\n />\n @if (customActions().length) {\n <ui5-menu-separator />\n }\n }\n @for (action of customActions(); track action.action) {\n <ui5-menu-item\n [attr.data-action]=\"action.action\"\n [attr.data-testid]=\"'dashboard-action-' + action.action\"\n [icon]=\"action.icon ?? ''\"\n [text]=\"action.text ?? ''\"\n />\n }\n @if (!config().editButtonFirst && config().editable) {\n <ui5-menu-separator />\n <ui5-menu-item\n data-action=\"edit-view\"\n data-testid=\"dashboard-action-edit-view\"\n [icon]=\"editViewButton().icon\"\n [text]=\"\n editViewButton().text ||\n i18n.getTranslation(i18nKeys.EDIT_VIEW)\n \"\n />\n }\n </ui5-menu>\n } @else {\n @if (config().editButtonFirst && config().editable) {\n <ui5-button\n data-testid=\"dashboard-edit-view-btn\"\n [accessibleName]=\"\n editViewButton().text ||\n editViewButton().tooltip ||\n i18n.getTranslation(i18nKeys.EDIT_VIEW)\n \"\n [design]=\"editViewButton().design\"\n [icon]=\"editViewButton().icon\"\n [tooltip]=\"editViewButton().tooltip\"\n (click)=\"enterEditMode()\"\n >{{ editViewButton().text }}</ui5-button\n >\n }\n @for (action of customActions(); track action.action) {\n <ui5-button\n [accessibleName]=\"action.text || action.tooltip || action.action\"\n [attr.data-testid]=\"'dashboard-action-' + action.action\"\n [design]=\"action.design ?? 'Default'\"\n [endIcon]=\"action?.endIcon\"\n [icon]=\"action.icon ?? ''\"\n [tooltip]=\"action.tooltip ?? ''\"\n (click)=\"\n actionButtonClick.emit({ event: $event, action: action })\n \"\n >{{ action.text }}</ui5-button\n >\n }\n @if (!config().editButtonFirst && config().editable) {\n <ui5-button\n data-testid=\"dashboard-edit-view-btn\"\n [accessibleName]=\"\n editViewButton().text ||\n editViewButton().tooltip ||\n i18n.getTranslation(i18nKeys.EDIT_VIEW)\n \"\n [design]=\"editViewButton().design\"\n [icon]=\"editViewButton().icon\"\n [tooltip]=\"editViewButton().tooltip\"\n (click)=\"enterEditMode()\"\n >{{ editViewButton().text }}</ui5-button\n >\n }\n }\n </div>\n </div>\n\n <div class=\"mfp-dashboard__subheader\">\n <ng-content select=\"[slot=dashboard-subheader]\" />\n </div>\n </div>\n\n <div class=\"mfp-sections-container\">\n @for (section of sections(); track section.id) {\n <mfp-dashboard-section\n [cards]=\"sectionCards()(section.id)\"\n [editMode]=\"editMode()\"\n [section]=\"section\"\n (removeCard)=\"removeCard($event)\"\n (removeSection)=\"removeSection(section.id)\"\n />\n }\n </div>\n\n <gridstack\n #grid\n data-testid=\"dashboard-grid\"\n [class.zflow-dragging]=\"!!dragOriginStyle()\"\n [options]=\"gridOptions()\"\n (addedCB)=\"onGridChange()\"\n (changeCB)=\"onGridChange()\"\n (dragStartCB)=\"onDragStart($event)\"\n (dragStopCB)=\"onDragStop()\"\n (removedCB)=\"onGridChange()\"\n >\n @if (dragOriginStyle()) {\n <div\n class=\"mfp-dashboard__drag-origin-placeholder\"\n [style]=\"dragOriginStyle()\"\n ></div>\n }\n @for (card of looseCards(); track card.id) {\n <gridstack-item [options]=\"card\">\n <mfp-dashboard-card\n [card]=\"card\"\n [editMode]=\"editMode()\"\n (removeCard)=\"removeCard($any(card.id))\"\n />\n </gridstack-item>\n }\n </gridstack>\n</div>\n@if (editMode()) {\n <div class=\"mfp-dashboard__edit-bar\">\n <ui5-button\n data-testid=\"dashboard-save-btn\"\n design=\"Emphasized\"\n (click)=\"saveEdit()\"\n >{{ i18n.getTranslation(i18nKeys.SAVE) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-cancel-btn\"\n design=\"Transparent\"\n (click)=\"cancelEdit()\"\n >{{ i18n.getTranslation(i18nKeys.CANCEL) }}</ui5-button\n >\n </div>\n}\n\n<mfp-edit-cards-dialog\n [addedCardsIds]=\"addedCardsIds()\"\n [availableCards]=\"availableCards()\"\n [open]=\"cardDialogOpen()\"\n (cancelled)=\"closeCardPanel()\"\n (confirm)=\"onCardsEdited($event)\"\n/>\n\n<mfp-discard-changes-dialog\n [open]=\"discardDialogOpen()\"\n (cancelled)=\"cancelDiscard()\"\n (confirm)=\"confirmDiscard()\"\n/>\n\n<mfp-unsaved-changes-dialog\n [open]=\"unsavedNavDialogOpen()\"\n (cancelled)=\"onUnsavedNavCancel()\"\n (discard)=\"onUnsavedNavDiscard()\"\n (save)=\"onUnsavedNavSave()\"\n/>\n", styles: [".grid-stack{position:relative}.grid-stack-placeholder>.placeholder-content{background-color:#0000001a;margin:0;position:absolute;width:auto;z-index:0!important}.grid-stack>.grid-stack-item{position:absolute;padding:0;top:0;width:var(--gs-column-width);height:var(--gs-cell-height)}.grid-stack>.grid-stack-item>.grid-stack-item-content{margin:0;position:absolute;width:auto;overflow-x:hidden;overflow-y:auto}.grid-stack>.grid-stack-item.size-to-content:not(.size-to-content-max)>.grid-stack-item-content{overflow-y:hidden}.grid-stack:not(.grid-stack-rtl)>.grid-stack-item{left:0}.grid-stack.grid-stack-rtl>.grid-stack-item{right:0}.grid-stack>.grid-stack-item>.grid-stack-item-content,.grid-stack>.grid-stack-placeholder>.placeholder-content{top:var(--gs-item-margin-top);right:var(--gs-item-margin-right);bottom:var(--gs-item-margin-bottom);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;user-select:none;z-index:100}.grid-stack-item.ui-resizable-autohide>.ui-resizable-handle,.grid-stack-item.ui-resizable-disabled>.ui-resizable-handle{display:none}.grid-stack-item>.ui-resizable-ne,.grid-stack-item>.ui-resizable-nw,.grid-stack-item>.ui-resizable-se,.grid-stack-item>.ui-resizable-sw{background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"%23666\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" viewBox=\"0 0 20 20\"><path d=\"m10 3 2 2H8l2-2v14l-2-2h4l-2 2\"/></svg>');background-repeat:no-repeat;background-position:center;z-index:101}.grid-stack-item>.ui-resizable-ne{transform:rotate(45deg)}.grid-stack-item>.ui-resizable-sw{transform:rotate(45deg)}.grid-stack-item>.ui-resizable-nw{transform:rotate(-45deg)}.grid-stack-item>.ui-resizable-se{transform:rotate(-45deg)}.grid-stack-item>.ui-resizable-nw{cursor:nw-resize;width:20px;height:20px;top:var(--gs-item-margin-top);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-n{cursor:n-resize;height:10px;top:var(--gs-item-margin-top);left:25px;right:25px}.grid-stack-item>.ui-resizable-ne{cursor:ne-resize;width:20px;height:20px;top:var(--gs-item-margin-top);right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-e{cursor:e-resize;width:10px;top:15px;bottom:15px;right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-se{cursor:se-resize;width:20px;height:20px;bottom:var(--gs-item-margin-bottom);right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-s{cursor:s-resize;height:10px;left:25px;bottom:var(--gs-item-margin-bottom);right:25px}.grid-stack-item>.ui-resizable-sw{cursor:sw-resize;width:20px;height:20px;bottom:var(--gs-item-margin-bottom);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-w{cursor:w-resize;width:10px;top:15px;bottom:15px;left:var(--gs-item-margin-left)}.grid-stack-item.ui-draggable-dragging>.ui-resizable-handle{display:none!important}.grid-stack-item.ui-draggable-dragging{will-change:left,right,top}.grid-stack-item.ui-resizable-resizing{will-change:width,height}.ui-draggable-dragging,.ui-resizable-resizing{z-index:10000}.ui-draggable-dragging>.grid-stack-item-content,.ui-resizable-resizing>.grid-stack-item-content{box-shadow:1px 4px 6px #0003;opacity:.8}.grid-stack-animate,.grid-stack-animate .grid-stack-item{transition:left .3s,right .3s,top .3s,height .3s,width .3s}.grid-stack-animate .grid-stack-item.grid-stack-placeholder,.grid-stack-animate .grid-stack-item.ui-draggable-dragging,.grid-stack-animate .grid-stack-item.ui-resizable-resizing{transition:left 0s,right 0s,top 0s,height 0s,width 0s}.grid-stack>.grid-stack-item[gs-y=\"0\"]{top:0}.grid-stack:not(.grid-stack-rtl)>.grid-stack-item[gs-x=\"0\"]{left:0}.grid-stack.grid-stack-rtl>.grid-stack-item[gs-x=\"0\"]{right:0}.grid-stack-placeholder{z-index:2;pointer-events:none}.grid-stack-placeholder .placeholder-content{border-radius:16px;height:calc(100% - 30px);top:calc(var(--gs-item-margin-top) * 2 - 2px)!important;width:calc(100% - 19px);left:8px!important;background:var(--sapContent_Selected_Hover_Background, #E3F0FF);border:1px solid var(--sapContent_DragAndDropActiveColor, #0064D9);z-index:2!important}mfp-dashboard,mfp-wc-dashboard{display:block;flex:1;margin:0;padding:0;min-height:100%;background:var(--sapShellColor, #354a5e);background-size:100% auto;background-position:top center;background-repeat:no-repeat;background-attachment:local}.mfp-dashboard{padding:calc(var(--sapShell_Space_XL, 3rem) - 10px);container-type:inline-size;container-name:mfp-dashboard}.mfp-dashboard.edit{padding-bottom:60px}.mfp-sections-container{display:grid;grid-auto-rows:auto;align-content:start;gap:1rem;grid-template-columns:repeat(var(--dashboard-cols-xl, 14),1fr)}@container mfp-dashboard (max-width: 599px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-sm, 1),1fr)}}@container mfp-dashboard (min-width: 600px) and (max-width: 1023px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-md, 8),1fr)}}@container mfp-dashboard (min-width: 1024px) and (max-width: 1439px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-lg, 12),1fr)}}.mfp-dashboard__topbar{grid-column:1/-1;align-self:start;display:flex;flex-direction:column;gap:1rem;padding-bottom:3rem;width:100%;min-width:0}.mfp-dashboard__topbar-row{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;padding:0 10px}.mfp-dashboard__header{display:flex;flex-direction:column;gap:.25rem}.mfp-dashboard__title-row{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap}.mfp-dashboard__unsaved-changes{display:inline-flex;align-items:center;gap:.375rem}.mfp-dashboard__unsaved-changes-icon{width:16px;height:16px;color:var(--sapContent_MarkerIconColor)}.mfp-dashboard__unsaved-changes-text{color:var(--sapContent_LabelColor);text-shadow:0 0 2px var(--sapContent_ContrastTextShadow, #fff);font-family:var(--sapFontFamily);font-size:var(--sapFontSize, 14px);font-style:normal;font-weight:400;line-height:normal}.mfp-dashboard__description{font-weight:400;font-family:var(--sapFontFamily)}.mfp-dashboard__description b,.mfp-dashboard__description strong{font-family:var(--sapFontBoldFamily)}.mfp-dashboard__toolbar{flex-shrink:0;display:flex;gap:.5rem}.mfp-dashboard__subheader{display:flex;align-items:center;gap:1rem}.mfp-dashboard__edit-bar{position:fixed;bottom:20px;left:16px;right:16px;z-index:1000;display:flex;justify-content:flex-end;align-items:center;gap:8px;padding:7px 16px;background:var(--sapPageFooter_Background, white);border-radius:var(--sapElement_BorderCornerRadius, 12px);box-shadow:0 0 0 1px #2235487a,0 2px 8px #2235484d;box-sizing:border-box;overflow:hidden}@media screen and (min-width:0px)and (max-width:599px){.mfp-dashboard{padding:calc(var(--sapShell_Space_S, 1rem) - 10px)}}@media screen and (min-width:600px)and (max-width:1023px){.mfp-dashboard{padding:calc(var(--sapShell_Space_M, 2rem) - 10px)}}@media screen and (min-width:1024px)and (max-width:1439px){.mfp-dashboard{padding:calc(var(--sapShell_Space_L, 2rem) - 10px)}}.grid-stack.grid-stack-dragging,.grid-stack.grid-stack-dragging *{cursor:grabbing!important}.mfp-dashboard__drag-origin-placeholder{position:absolute;pointer-events:none;z-index:1}.mfp-dashboard__drag-origin-placeholder:before{content:\"\";height:calc(100% - 30px);top:calc(var(--gs-item-margin-top) * 2 - 2px)!important;width:calc(100% - 19px);left:8px!important;position:absolute;background:var(--sapNeutralColor, #6a6d75);border-radius:16px;opacity:.3}gridstack{position:relative}.grid-stack:has(.ui-resizable-resizing),.grid-stack:has(.ui-resizable-resizing) *{cursor:nwse-resize!important}.grid-stack-item>.ui-resizable-handle{background-image:none!important}\n"], dependencies: [{ kind: "component", type: GridstackComponent, selector: "gridstack", inputs: ["options", "isEmpty"], outputs: ["addedCB", "changeCB", "disableCB", "dragCB", "dragStartCB", "dragStopCB", "droppedCB", "enableCB", "removedCB", "resizeCB", "resizeStartCB", "resizeStopCB"] }, { kind: "component", type: GridstackItemComponent, selector: "gridstack-item", inputs: ["options"] }, { kind: "component", type: DiscardChangesDialog, selector: "mfp-discard-changes-dialog", inputs: ["open"], outputs: ["confirm", "cancelled"] }, { kind: "component", type: EditCardsDialog, selector: "mfp-edit-cards-dialog", inputs: ["availableCards", "addedCardsIds", "open"], outputs: ["confirm", "cancelled"] }, { kind: "component", type: UnsavedChangesDialog, selector: "mfp-unsaved-changes-dialog", inputs: ["open"], outputs: ["save", "discard", "cancelled"] }, { kind: "component", type: DashboardSection, selector: "mfp-dashboard-section", inputs: ["section", "cards", "columns", "editMode"], outputs: ["removeSection", "removeCard"] }, { kind: "component", type: DashboardCard, selector: "mfp-dashboard-card", inputs: ["card", "editMode"], outputs: ["removeCard"] }, { 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: Menu, selector: "ui5-menu, [ui5-menu]", inputs: ["headerText", "open", "placement", "horizontalAlign", "loading", "loadingDelay", "opener"], outputs: ["ui5ItemClick", "ui5BeforeOpen", "ui5Open", "ui5BeforeClose", "ui5Close"], exportAs: ["ui5Menu"] }, { kind: "component", type: MenuItem, selector: "ui5-menu-item, [ui5-menu-item]", inputs: ["text", "additionalText", "icon", "disabled", "loading", "loadingDelay", "accessibleName", "tooltip", "checked", "accessibilityAttributes", "type", "navigated", "highlight", "selected"], outputs: ["ui5BeforeOpen", "ui5Open", "ui5BeforeClose", "ui5Close", "ui5Check", "ui5DetailClick"], exportAs: ["ui5MenuItem"] }, { kind: "component", type: MenuSeparator, selector: "ui5-menu-separator, [ui5-menu-separator]", exportAs: ["ui5MenuSeparator"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["wrappingType", "level", "size"], exportAs: ["ui5Title"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
1666
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Dashboard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1667
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: Dashboard, isStandalone: true, selector: "mfp-dashboard", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: false, transformFunction: null }, cards: { classPropertyName: "cards", publicName: "cards", isSignal: true, isRequired: false, transformFunction: null }, availableCards: { classPropertyName: "availableCards", publicName: "availableCards", isSignal: true, isRequired: false, transformFunction: null }, customActions: { classPropertyName: "customActions", publicName: "customActions", isSignal: true, isRequired: false, transformFunction: null }, i18n: { classPropertyName: "i18n", publicName: "i18n", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingDelay: { classPropertyName: "loadingDelay", publicName: "loadingDelay", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sections: "sectionsChange", cards: "cardsChange", saved: "saved", actionButtonClick: "actionButtonClick", unsavedChangesChange: "unsavedChangesChange" }, host: { properties: { "style.background-image": "config().backgroundImageUrl ? \"url(\" + config().backgroundImageUrl + \")\" : \"var(--mfp-dashboard-background, none)\"", "style.background-size": "backgroundImageHeight() ? \"100% \" + backgroundImageHeight() + \"px\" : \"100% auto\"" } }, providers: [DashboardI18nService], viewQueries: [{ propertyName: "gridStack", first: true, predicate: ["grid"], descendants: true, isSignal: true }, { propertyName: "dragOriginPlaceholder", first: true, predicate: ["dragOriginPlaceholder"], descendants: true, isSignal: true }, { propertyName: "addCardBtn", first: true, predicate: ["editCardsBtn"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"mfp-dashboard\"\n data-testid=\"dashboard\"\n [class.edit]=\"editMode()\"\n [style]=\"columnVars()\"\n>\n <ui5-busy-indicator\n class=\"mfp-dashboard__busy\"\n data-testid=\"dashboard-busy\"\n size=\"M\"\n [active]=\"busyVisible()\"\n [delay]=\"0\"\n >\n <div\n class=\"mfp-dashboard__busy-content\"\n [class.mfp-dashboard__busy-content--busy]=\"busyVisible()\"\n >\n <div class=\"mfp-dashboard__topbar\">\n <div class=\"mfp-dashboard__topbar-row\">\n <div class=\"mfp-dashboard__header\">\n <div class=\"mfp-dashboard__title-row\">\n @if (i18nService.getTranslation(i18nKeys.TITLE)) {\n <ui5-title\n data-testid=\"dashboard-title\"\n level=\"H3\"\n size=\"H3\"\n wrapping-type=\"Normal\"\n >\n <span [innerHTML]=\"safeTitle()\"></span>\n </ui5-title>\n }\n @if (hasUnsavedChanges()) {\n <div class=\"mfp-dashboard__unsaved-changes\" role=\"status\">\n <ui5-icon\n class=\"mfp-dashboard__unsaved-changes-icon\"\n name=\"user-edit\"\n [accessibleName]=\"\n i18nService.getTranslation(i18nKeys.UNSAVED_CHANGES)\n \"\n />\n <span class=\"mfp-dashboard__unsaved-changes-text\">{{\n i18nService.getTranslation(i18nKeys.UNSAVED_CHANGES)\n }}</span>\n </div>\n }\n </div>\n @if (i18nService.getTranslation(i18nKeys.DESCRIPTION)) {\n <ui5-title\n data-testid=\"dashboard-description\"\n level=\"H5\"\n size=\"H5\"\n wrapping-type=\"Normal\"\n >\n <span\n class=\"mfp-dashboard__description\"\n [innerHTML]=\"safeDescription()\"\n ></span>\n </ui5-title>\n }\n </div>\n\n <div class=\"mfp-dashboard__toolbar\">\n @if (editMode()) {\n <ui5-button\n #editCardsBtn\n data-testid=\"dashboard-edit-cards-btn\"\n id=\"edit-cards-btn\"\n [accessibleName]=\"\n editCardsButton().text ||\n editCardsButton().tooltip ||\n i18nService.getTranslation(i18nKeys.EDIT_CARDS_BUTTON)\n \"\n [design]=\"editCardsButton().design\"\n [icon]=\"editCardsButton().icon\"\n [tooltip]=\"editCardsButton().tooltip\"\n (click)=\"openCardPanel()\"\n >{{ editCardsButton().text }}</ui5-button\n >\n } @else if (compactToolbar() && hasToolbarMenuContent()) {\n <ui5-button\n #menuBtn\n data-testid=\"dashboard-toolbar-menu-btn\"\n design=\"Transparent\"\n icon=\"menu2\"\n [accessibleName]=\"i18nService.getTranslation(i18nKeys.ACTIONS)\"\n [tooltip]=\"i18nService.getTranslation(i18nKeys.ACTIONS)\"\n (click)=\"toolbarMenuOpen.update((v) => !v)\"\n />\n <ui5-menu\n data-testid=\"dashboard-toolbar-menu\"\n [open]=\"toolbarMenuOpen()\"\n [opener]=\"menuBtn.element\"\n (ui5Close)=\"toolbarMenuOpen.set(false)\"\n (ui5ItemClick)=\"\n onMenuItemClick(\n $any($event).detail.item.dataset['action'],\n $event\n )\n \"\n (ui5Open)=\"toolbarMenuOpen.set(true)\"\n >\n @if (config().editButtonFirst && config().editable) {\n <ui5-menu-item\n data-action=\"edit-view\"\n data-testid=\"dashboard-action-edit-view\"\n [icon]=\"editViewButton().icon\"\n [text]=\"\n editViewButton().text ||\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n \"\n />\n @if (customActions().length) {\n <ui5-menu-separator />\n }\n }\n @for (action of customActions(); track action.action) {\n <ui5-menu-item\n [attr.data-action]=\"action.action\"\n [attr.data-testid]=\"'dashboard-action-' + action.action\"\n [icon]=\"action.icon ?? ''\"\n [text]=\"action.text ?? ''\"\n />\n }\n @if (!config().editButtonFirst && config().editable) {\n <ui5-menu-separator />\n <ui5-menu-item\n data-action=\"edit-view\"\n data-testid=\"dashboard-action-edit-view\"\n [icon]=\"editViewButton().icon\"\n [text]=\"\n editViewButton().text ||\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n \"\n />\n }\n </ui5-menu>\n } @else {\n @if (config().editButtonFirst && config().editable) {\n <ui5-button\n data-testid=\"dashboard-edit-view-btn\"\n [accessibleName]=\"\n editViewButton().text ||\n editViewButton().tooltip ||\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n \"\n [design]=\"editViewButton().design\"\n [icon]=\"editViewButton().icon\"\n [tooltip]=\"editViewButton().tooltip\"\n (click)=\"enterEditMode()\"\n >{{ editViewButton().text }}</ui5-button\n >\n }\n @for (action of customActions(); track action.action) {\n <ui5-button\n [accessibleName]=\"\n action.text || action.tooltip || action.action\n \"\n [attr.data-testid]=\"'dashboard-action-' + action.action\"\n [design]=\"action.design ?? 'Default'\"\n [endIcon]=\"action?.endIcon\"\n [icon]=\"action.icon ?? ''\"\n [tooltip]=\"action.tooltip ?? ''\"\n (click)=\"\n actionButtonClick.emit({ event: $event, action: action })\n \"\n >{{ action.text }}</ui5-button\n >\n }\n @if (!config().editButtonFirst && config().editable) {\n <ui5-button\n data-testid=\"dashboard-edit-view-btn\"\n [accessibleName]=\"\n editViewButton().text ||\n editViewButton().tooltip ||\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n \"\n [design]=\"editViewButton().design\"\n [icon]=\"editViewButton().icon\"\n [tooltip]=\"editViewButton().tooltip\"\n (click)=\"enterEditMode()\"\n >{{ editViewButton().text }}</ui5-button\n >\n }\n }\n </div>\n </div>\n\n <div class=\"mfp-dashboard__subheader\">\n <ng-content select=\"[slot=dashboard-subheader]\" />\n </div>\n </div>\n\n <div class=\"mfp-sections-container\">\n @for (section of sections(); track section.id) {\n <mfp-dashboard-section\n [cards]=\"sectionCards()(section.id)\"\n [editMode]=\"editMode()\"\n [section]=\"section\"\n (removeCard)=\"removeCard($event)\"\n (removeSection)=\"removeSection(section.id)\"\n />\n }\n </div>\n\n @if (isEmpty() && isDashboardEditable() && !loading()) {\n <div class=\"mfp-dashboard__empty\" data-testid=\"dashboard-empty-state\">\n <div\n class=\"mfp-dashboard__empty-illustration\"\n data-testid=\"dashboard-empty-state-illustration\"\n role=\"img\"\n [attr.aria-label]=\"\n i18nService.getTranslation(i18nKeys.EMPTY_STATE_ILLUSTRATION)\n \"\n ></div>\n <ui5-title\n class=\"mfp-dashboard__empty-title\"\n data-testid=\"dashboard-empty-state-title\"\n level=\"H4\"\n size=\"H3\"\n wrapping-type=\"Normal\"\n >{{\n i18nService.getTranslation(i18nKeys.EMPTY_STATE_TITLE)\n }}</ui5-title\n >\n <p\n class=\"mfp-dashboard__empty-description\"\n data-testid=\"dashboard-empty-state-description\"\n >\n {{ i18nService.getTranslation(i18nKeys.EMPTY_STATE_DESCRIPTION) }}\n </p>\n @if (isDashboardEditable() && !editMode()) {\n <ui5-button\n data-testid=\"dashboard-empty-state-edit-btn\"\n design=\"Emphasized\"\n [accessibleName]=\"\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n \"\n (click)=\"enterEditModeAndEditCards()\"\n >{{\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n }}</ui5-button\n >\n }\n </div>\n }\n\n <gridstack\n #grid\n data-testid=\"dashboard-grid\"\n [attr.role]=\"keyboardNavigationActive() ? 'list' : null\"\n [class.zflow-dragging]=\"!!dragOriginStyle()\"\n [options]=\"gridOptions()\"\n (addedCB)=\"onGridChange()\"\n (changeCB)=\"onGridChange()\"\n (dragCB)=\"onDrag()\"\n (dragStartCB)=\"onDragStart($event)\"\n (dragStopCB)=\"onDragStop()\"\n (removedCB)=\"onGridChange()\"\n >\n @if (dragOriginStyle() && dragOriginVisible()) {\n <div\n #dragOriginPlaceholder\n class=\"mfp-dashboard__drag-origin-placeholder\"\n [style]=\"dragOriginStyle()\"\n ></div>\n }\n @for (card of looseCards(); track card.id) {\n <gridstack-item\n [attr.aria-keyshortcuts]=\"\n keyboardNavigationActive() ? cardAriaKeyshortcuts : null\n \"\n [attr.aria-label]=\"\n keyboardNavigationActive()\n ? card.label || card.component || card.id\n : null\n \"\n [attr.role]=\"keyboardNavigationActive() ? 'listitem' : null\"\n [attr.tabindex]=\"keyboardNavigationActive() ? '0' : null\"\n [options]=\"card\"\n (keydown)=\"onCardKeydown($event, card.id)\"\n >\n <mfp-dashboard-card\n [card]=\"card\"\n [editMode]=\"editMode()\"\n (removeCard)=\"removeCard($any(card.id))\"\n />\n </gridstack-item>\n }\n </gridstack>\n </div>\n </ui5-busy-indicator>\n</div>\n@if (editMode()) {\n <div class=\"mfp-dashboard__edit-bar\">\n <ui5-button\n data-testid=\"dashboard-save-btn\"\n design=\"Emphasized\"\n (click)=\"saveEdit()\"\n >{{ i18nService.getTranslation(i18nKeys.SAVE) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-cancel-btn\"\n design=\"Transparent\"\n (click)=\"cancelEdit()\"\n >{{ i18nService.getTranslation(i18nKeys.CANCEL) }}</ui5-button\n >\n </div>\n}\n\n<mfp-edit-cards-dialog\n [addedCardsIds]=\"addedCardsIds()\"\n [availableCards]=\"availableCards()\"\n [open]=\"cardDialogOpen()\"\n (cancelled)=\"closeCardPanel()\"\n (confirm)=\"onCardsEdited($event)\"\n/>\n\n<mfp-discard-changes-dialog\n [open]=\"discardDialogOpen()\"\n (cancelled)=\"cancelDiscard()\"\n (confirm)=\"confirmDiscard()\"\n/>\n\n<mfp-unsaved-changes-dialog\n [open]=\"unsavedNavDialogOpen()\"\n (cancelled)=\"onUnsavedNavCancel()\"\n (discard)=\"onUnsavedNavDiscard()\"\n (save)=\"onUnsavedNavSave()\"\n/>\n", styles: [".grid-stack{position:relative}.grid-stack-placeholder>.placeholder-content{background-color:#0000001a;margin:0;position:absolute;width:auto;z-index:0!important}.grid-stack>.grid-stack-item{position:absolute;padding:0;top:0;width:var(--gs-column-width);height:var(--gs-cell-height)}.grid-stack>.grid-stack-item>.grid-stack-item-content{margin:0;position:absolute;width:auto;overflow-x:hidden;overflow-y:auto}.grid-stack>.grid-stack-item.size-to-content:not(.size-to-content-max)>.grid-stack-item-content{overflow-y:hidden}.grid-stack:not(.grid-stack-rtl)>.grid-stack-item{left:0}.grid-stack.grid-stack-rtl>.grid-stack-item{right:0}.grid-stack>.grid-stack-item>.grid-stack-item-content,.grid-stack>.grid-stack-placeholder>.placeholder-content{top:var(--gs-item-margin-top);right:var(--gs-item-margin-right);bottom:var(--gs-item-margin-bottom);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;user-select:none;z-index:100}.grid-stack-item.ui-resizable-autohide>.ui-resizable-handle,.grid-stack-item.ui-resizable-disabled>.ui-resizable-handle{display:none}.grid-stack-item>.ui-resizable-ne,.grid-stack-item>.ui-resizable-nw,.grid-stack-item>.ui-resizable-se,.grid-stack-item>.ui-resizable-sw{background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"%23666\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" viewBox=\"0 0 20 20\"><path d=\"m10 3 2 2H8l2-2v14l-2-2h4l-2 2\"/></svg>');background-repeat:no-repeat;background-position:center;z-index:101}.grid-stack-item>.ui-resizable-ne{transform:rotate(45deg)}.grid-stack-item>.ui-resizable-sw{transform:rotate(45deg)}.grid-stack-item>.ui-resizable-nw{transform:rotate(-45deg)}.grid-stack-item>.ui-resizable-se{transform:rotate(-45deg)}.grid-stack-item>.ui-resizable-nw{cursor:nw-resize;width:20px;height:20px;top:var(--gs-item-margin-top);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-n{cursor:n-resize;height:10px;top:var(--gs-item-margin-top);left:25px;right:25px}.grid-stack-item>.ui-resizable-ne{cursor:ne-resize;width:20px;height:20px;top:var(--gs-item-margin-top);right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-e{cursor:e-resize;width:10px;top:15px;bottom:15px;right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-se{cursor:se-resize;width:20px;height:20px;bottom:var(--gs-item-margin-bottom);right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-s{cursor:s-resize;height:10px;left:25px;bottom:var(--gs-item-margin-bottom);right:25px}.grid-stack-item>.ui-resizable-sw{cursor:sw-resize;width:20px;height:20px;bottom:var(--gs-item-margin-bottom);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-w{cursor:w-resize;width:10px;top:15px;bottom:15px;left:var(--gs-item-margin-left)}.grid-stack-item.ui-draggable-dragging>.ui-resizable-handle{display:none!important}.grid-stack-item.ui-draggable-dragging{will-change:left,right,top}.grid-stack-item.ui-resizable-resizing{will-change:width,height}.ui-draggable-dragging,.ui-resizable-resizing{z-index:10000}.ui-draggable-dragging>.grid-stack-item-content,.ui-resizable-resizing>.grid-stack-item-content{box-shadow:1px 4px 6px #0003;opacity:.8}.grid-stack-animate,.grid-stack-animate .grid-stack-item{transition:left .3s,right .3s,top .3s,height .3s,width .3s}.grid-stack-animate .grid-stack-item.grid-stack-placeholder,.grid-stack-animate .grid-stack-item.ui-draggable-dragging,.grid-stack-animate .grid-stack-item.ui-resizable-resizing{transition:left 0s,right 0s,top 0s,height 0s,width 0s}.grid-stack>.grid-stack-item[gs-y=\"0\"]{top:0}.grid-stack:not(.grid-stack-rtl)>.grid-stack-item[gs-x=\"0\"]{left:0}.grid-stack.grid-stack-rtl>.grid-stack-item[gs-x=\"0\"]{right:0}.gs-print-show{display:none}@media print{@page gs-landscape{size:landscape}@page gs-portrait{size:portrait}.grid-stack{display:block!important;height:auto!important;position:static!important}.grid-stack>.grid-stack-item{display:block!important;float:left!important;position:static!important;height:auto!important;left:auto!important;top:auto!important;width:calc(100% * var(--gs-w)/ var(--gs-columns,12))!important;break-inside:avoid!important;page-break-inside:avoid!important}.grid-stack>.grid-stack-item>.grid-stack-item-content{position:relative!important;height:auto!important;overflow:visible!important;white-space:normal!important;margin-top:var(--gs-item-margin-top)!important;margin-right:var(--gs-item-margin-right)!important;margin-bottom:var(--gs-item-margin-bottom)!important;margin-left:var(--gs-item-margin-left)!important;inset:auto!important}.gs-print-hide{display:none}.gs-print-show{display:block}.grid-stack>.grid-stack-item.gs-print-hide{display:none!important}.grid-stack>.grid-stack-item[gs-page-break=true],.grid-stack>.grid-stack-item[gs-print-orientation]{float:none!important;clear:both!important}.grid-stack>.grid-stack-item[gs-page-break=true]{page-break-before:always!important;break-before:page!important}.grid-stack>.grid-stack-item[gs-print-orientation=landscape]{page:gs-landscape;min-width:calc(100vmax * var(--gs-w)/ var(--gs-columns,12))!important}.grid-stack>.grid-stack-item[gs-print-orientation=portrait]{page:gs-portrait;min-width:calc(100vmin * var(--gs-w)/ var(--gs-columns,12))!important}.grid-stack>.grid-stack-item>.ui-resizable-handle{display:none!important}}.grid-stack-placeholder{z-index:2;pointer-events:none}.grid-stack-placeholder .placeholder-content{border-radius:16px;height:calc(100% - 30px);top:calc(var(--gs-item-margin-top) * 2 - 2px)!important;width:calc(100% - 19px);left:8px!important;background:var(--sapContent_Selected_Hover_Background, #e3f0ff);border:1px solid var(--sapContent_DragAndDropActiveColor, #0064d9);z-index:2!important}mfp-dashboard,mfp-wc-dashboard{display:block;flex:1;margin:0;padding:0;min-height:100%;background-size:100% auto;background-position:top center;background-repeat:no-repeat;background-attachment:local}.mfp-dashboard{padding:calc(var(--sapShell_Space_XL, 3rem) - 10px);container-type:inline-size;container-name:mfp-dashboard}.mfp-dashboard.edit{padding-bottom:60px}.mfp-dashboard.edit>.mfp-dashboard__busy gridstack>.grid-stack-item,.mfp-dashboard.edit>.mfp-dashboard__busy gridstack>.grid-stack-item:focus,.mfp-dashboard.edit>.mfp-dashboard__busy gridstack>.grid-stack-item:focus-visible{outline:none!important;border:0!important;box-shadow:none!important}.mfp-sections-container{display:grid;grid-auto-rows:auto;align-content:start;gap:1rem;grid-template-columns:repeat(var(--dashboard-cols-xl, 14),1fr)}@container mfp-dashboard (max-width: 599px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-sm, 1),1fr)}}@container mfp-dashboard (min-width: 600px) and (max-width: 1023px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-md, 8),1fr)}}@container mfp-dashboard (min-width: 1024px) and (max-width: 1439px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-lg, 12),1fr)}}.mfp-dashboard__topbar{grid-column:1/-1;align-self:start;display:flex;flex-direction:column;gap:1rem;padding-bottom:3rem;width:100%;min-width:0}.mfp-dashboard__topbar-row{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;padding:0 10px}.mfp-dashboard__header{display:flex;flex-direction:column;gap:.25rem}.mfp-dashboard__title-row{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap}.mfp-dashboard__unsaved-changes{display:inline-flex;align-items:center;gap:.375rem}.mfp-dashboard__unsaved-changes-icon{width:16px;height:16px;color:var(--sapContent_MarkerIconColor)}.mfp-dashboard__unsaved-changes-text{color:var(--sapContent_LabelColor);text-shadow:0 0 2px var(--sapContent_ContrastTextShadow, #fff);font-family:var(--sapFontFamily);font-size:var(--sapFontSize, 14px);font-style:normal;font-weight:400;line-height:normal}.mfp-dashboard__description{font-weight:400;font-family:var(--sapFontFamily)}.mfp-dashboard__description b,.mfp-dashboard__description strong{font-family:var(--sapFontBoldFamily)}.mfp-dashboard__toolbar{flex-shrink:0;display:flex;gap:.5rem}.mfp-dashboard__subheader{display:flex;align-items:center;gap:var(--sapShell_Space_S, 1rem)}.mfp-dashboard__busy{display:block;width:100%}.mfp-dashboard__busy-content{width:100%}.mfp-dashboard__busy-content--busy{min-height:60vh}.mfp-dashboard__empty{display:flex;flex-direction:column;align-items:center;gap:.5rem;padding:2rem 1rem 4rem;text-align:center}.mfp-dashboard__empty-illustration{width:320px;max-width:100%;aspect-ratio:320/240;background-image:var(--mfp-dashboard-empty-image, url(\"data:image/svg+xml;utf8,%3Csvg id='tnt-Scene-NoApplications' xmlns='http://www.w3.org/2000/svg' width='320' height='240' fill='none' viewBox='0 0 320 240'%3E%3Crect width='320' height='138' y='59' fill='%2389d1ff' rx='24'/%3E%3Cpath fill='%231b90ff' fill-rule='evenodd' d='m96.085 187.07 133.74-23.88c.83-.15.86-1.32.05-1.53l-83.86-20.89c-1-.25-2.05-.3-3.07-.14L37.355 156.9c-1.87.29-2.23 2.82-.51 3.62l56.21 26.14c.94.44 2.01.58 3.04.39l-.01.02Z' clip-rule='evenodd'/%3E%3Cpath fill='%230070f2' d='M234.425 39.1c.53-.03 1.07.07 1.57.25s.99.47 1.43.83c.44.36.82.79 1.12 1.27.31.49.54 1.03.68 1.6l2.49 10.83-161.93 9.75-2.09-12.04a4.21 4.21 0 0 1 .06-1.81 3.917 3.917 0 0 1 2.07-2.57c.52-.26 1.11-.42 1.76-.46l152.84-7.65Z'/%3E%3Cpath fill='%23ffffff' d='m79.775 63.63 161.92-9.74 20.81 90.49c.14.61.16 1.21.1 1.76-.07.55-.25 1.07-.51 1.52-.27.45-.61.83-1.03 1.11-.42.28-.9.47-1.45.54l-156.56 19.62c-.67.09-1.32.02-1.94-.15-.62-.17-1.21-.47-1.72-.88-.51-.4-.96-.88-1.31-1.45-.35-.57-.6-1.2-.71-1.88L79.785 63.63h-.01Z'/%3E%3Cpath fill='%2389d1ff' d='m95.125 73.19 43.77-2.41c.38-.02.76.03 1.12.14.36.11.69.29.99.51.3.22.55.49.76.79.21.3.34.64.41.99l7.57 38.85a2.51 2.51 0 0 1-.45 1.98c-.2.27-.47.5-.77.68-.3.18-.66.3-1.04.34l-43.82 5.29a3.685 3.685 0 0 1-2.41-.58c-.34-.22-.62-.5-.83-.82-.21-.32-.37-.68-.44-1.07l-7.46-41.74c-.07-.38-.05-.75.05-1.08.1-.33.27-.65.51-.92s.53-.49.88-.65c.35-.16.74-.27 1.16-.3Zm104.68-5.76 32.44-1.79c.28-.02.57.03.84.13s.53.25.76.44c.23.19.44.43.6.69.16.26.29.55.36.86l7.53 33.48c.07.32.08.62.04.91-.04.29-.14.55-.28.78-.14.23-.32.42-.54.57-.22.15-.48.24-.76.28l-32.34 3.91a2.504 2.504 0 0 1-1.8-.53c-.26-.2-.48-.44-.66-.71-.18-.27-.31-.58-.38-.92l-7.58-35.6c-.07-.32-.07-.64-.02-.93.05-.29.17-.55.33-.78.16-.23.37-.41.61-.55.24-.14.53-.22.84-.25l.01.01Zm-48.05 2.64 37.44-2.05c.33-.02.65.03.97.14.32.11.6.27.87.47.27.2.49.45.67.73.18.28.31.59.38.92l7.58 35.95c.07.34.07.67.01.98-.06.31-.18.6-.35.84-.17.24-.39.46-.65.62-.26.16-.56.27-.88.31l-37.4 4.52c-.38.04-.75 0-1.1-.09-.35-.09-.68-.26-.97-.46-.29-.2-.54-.47-.74-.76-.2-.29-.34-.63-.41-.98l-7.58-38.41c-.07-.35-.06-.69.01-1 .07-.31.21-.6.41-.84.2-.24.44-.45.73-.6.29-.15.62-.25.98-.27l.03-.02Z'/%3E%3Cpath fill='%2356bdff' d='M88.485 51.02c.51-.03 1.02.05 1.5.21.49.16.92.41 1.32.72s.73.69 1 1.12c.27.43.46.9.54 1.41.09.5.08.99-.04 1.44-.11.45-.31.86-.59 1.21-.28.35-.63.65-1.04.86-.41.21-.88.34-1.4.37-.51.03-1.02-.05-1.5-.21a4.23 4.23 0 0 1-1.32-.72c-.39-.31-.74-.69-1.01-1.12-.27-.43-.46-.9-.54-1.42-.09-.51-.07-1 .04-1.45.1-.45.31-.87.59-1.21.28-.34.63-.64 1.05-.86.42-.22.88-.34 1.4-.36v.01Z'/%3E%3Cpath fill='%230040b0' d='M103.065 168.93c-.67.08-1.32.02-1.94-.15-.62-.18-1.21-.48-1.72-.88s-.96-.88-1.31-1.46c-.35-.56-.6-1.2-.71-1.88L79.795 63.63l-2.09-12.04c-.06-.3-.08-.61-.07-.9 0-.29.05-.58.11-.86.07-.28.16-.54.28-.79.11-.25.27-.49.43-.7l-2.65 3.45c-.16.22-.3.45-.43.69-.11.25-.21.5-.28.78-.07.28-.1.55-.11.85 0 .29 0 .59.07.89l2.06 11.91 17.29 99.82c.11.68.36 1.3.7 1.86a5.4 5.4 0 0 0 1.29 1.44c.51.39 1.08.68 1.7.87.62.18 1.27.24 1.92.15l155.15-19.6 4.46-2.15-156.56 19.62v.01Z'/%3E%3Cpath fill='%23046c7c' d='m269.075 164.4-3.89 2.51s-.09.06-.13.08c-.04.02-.09.06-.12.08-.04.02-.09.06-.12.08-.04.02-.09.06-.13.08-.83.5-1.68.96-2.55 1.37-.87.41-1.77.76-2.7 1.08-.92.32-1.86.57-2.81.78-.96.21-1.94.37-2.92.47-.49.06-.99.1-1.48.13s-1 .04-1.5.05c-.5 0-1.01 0-1.52-.04s-1.02-.06-1.53-.12c-1.54-.15-3.07-.43-4.6-.81-1.52-.39-3.03-.89-4.5-1.5-1.47-.61-2.92-1.34-4.33-2.17-1.41-.83-2.77-1.76-4.07-2.79a36.883 36.883 0 0 1-3.7-3.36c-1.15-1.2-2.24-2.48-3.23-3.81-.99-1.33-1.89-2.75-2.7-4.2a37.21 37.21 0 0 1-2.12-4.52c-.61-1.55-1.1-3.12-1.48-4.71a34.17 34.17 0 0 1-.8-4.77c-.15-1.6-.19-3.17-.12-4.74.07-1.57.27-3.11.58-4.62.3-1.49.7-2.92 1.21-4.3s1.12-2.71 1.82-3.97c.7-1.26 1.49-2.45 2.38-3.56.89-1.11 1.85-2.15 2.91-3.1l3.43-3.1a26.29 26.29 0 0 0-5.33 6.73 28.19 28.19 0 0 0-3.04 8.35 32.074 32.074 0 0 0-.46 9.46c.15 1.61.42 3.22.81 4.82.39 1.6.89 3.19 1.49 4.76.62 1.57 1.33 3.09 2.14 4.56a38.822 38.822 0 0 0 5.99 8.11c1.17 1.22 2.42 2.35 3.74 3.39a36.466 36.466 0 0 0 8.49 5.03c1.49.63 3.01 1.13 4.55 1.53a31.16 31.16 0 0 0 6.19.95c.52.03 1.02.04 1.53.04s1.01-.02 1.52-.04 1-.07 1.5-.13c.99-.11 1.98-.27 2.95-.47.97-.2 1.92-.47 2.84-.78.93-.31 1.83-.68 2.72-1.08.89-.41 1.74-.87 2.57-1.38.05-.03.09-.06.13-.08.05-.02.09-.06.12-.08.04-.02.09-.06.12-.08.04-.02.09-.06.13-.09'/%3E%3Cpath fill='%230899a7' d='M267.365 111.939c1.68 1.36 3.24 2.86 4.66 4.48 1.42 1.62 2.7 3.35 3.83 5.16 1.13 1.82 2.1 3.73 2.9 5.71.8 1.97 1.44 4.02 1.89 6.1.33 1.56.56 3.11.67 4.67.11 1.56.13 3.1.02 4.61-.11 1.52-.31 3.03-.63 4.5-.32 1.47-.74 2.91-1.27 4.3a27.574 27.574 0 0 1-4.37 7.57c-.91 1.12-1.92 2.16-3.01 3.1-1.09.95-2.26 1.81-3.51 2.57a25.402 25.402 0 0 1-5.29 2.46c-.93.31-1.88.57-2.84.78-.96.21-1.95.37-2.95.47-.5.06-1 .1-1.5.12-.5.03-1.01.04-1.52.04s-1.02 0-1.53-.04c-.51-.03-1.03-.07-1.55-.12-1.55-.15-3.1-.43-4.64-.83-1.53-.4-3.06-.9-4.55-1.53a36.39 36.39 0 0 1-4.37-2.19c-1.42-.84-2.8-1.78-4.12-2.83a38.772 38.772 0 0 1-3.74-3.39 37.388 37.388 0 0 1-3.26-3.86c-.99-1.35-1.92-2.78-2.73-4.25-.81-1.47-1.53-3-2.14-4.57-.62-1.57-1.11-3.16-1.49-4.76-.38-1.6-.65-3.21-.81-4.82-.15-1.61-.19-3.2-.12-4.79.08-1.59.27-3.14.58-4.67.31-1.53.72-3.01 1.24-4.43s1.16-2.78 1.88-4.07c.72-1.3 1.55-2.51 2.48-3.65.93-1.14 1.93-2.2 3.02-3.15 1.09-.97 2.26-1.83 3.49-2.59a26.8 26.8 0 0 1 3.85-1.96c1.33-.55 2.72-.99 4.15-1.32 1.43-.33 2.88-.54 4.38-.64 2-.13 4.01-.05 6.01.23s3.98.75 5.93 1.41c1.95.66 3.85 1.5 5.69 2.52 1.84 1.03 3.61 2.21 5.3 3.58v.03l-.03.05Z'/%3E%3Cpath fill='%23ffffff' d='M248.495 118.529c.32-.02.64.02.95.12.31.1.6.27.85.47.25.2.48.46.66.74.18.28.31.6.38.94l2.62 12.86 12.14-1.04c.32-.03.64.02.94.12.3.1.59.26.84.46a2.943 2.943 0 0 1 1.04 1.68c.07.34.07.67.02.97-.05.3-.17.59-.33.83s-.37.45-.62.6c-.25.15-.54.25-.86.28l-12.15 1.08 2.65 13c.07.35.07.68.01.99-.06.31-.18.6-.35.85a2.066 2.066 0 0 1-1.52.9c-.33.03-.65 0-.96-.11-.31-.11-.6-.26-.86-.47-.26-.21-.49-.46-.67-.75a2.88 2.88 0 0 1-.38-.96l-2.63-13.04-12.41 1.1c-.33.03-.66-.01-.97-.12-.31-.11-.61-.26-.87-.47-.26-.21-.49-.46-.68-.75-.19-.29-.31-.61-.38-.96s-.07-.68 0-.99c.07-.31.19-.6.36-.84.17-.24.4-.45.66-.6.26-.15.56-.25.89-.28l12.4-1.07-2.61-12.9a2.315 2.315 0 0 1 .35-1.79 1.965 1.965 0 0 1 1.51-.85h-.02Z'/%3E%3C/svg%3E\"));background-repeat:no-repeat;background-position:center;background-size:contain}.mfp-dashboard__empty-title{margin-top:1rem}.mfp-dashboard__empty-description{margin:0 0 1.5rem;color:var(--sapContent_LabelColor);font-family:var(--sapFontFamily);font-size:var(--sapFontSize, 14px)}.mfp-dashboard__edit-bar{position:sticky;bottom:var(--sapShell_Space_S, 1rem);margin:var(--sapShell_Space_S, 1rem) var(--sapShell_Space_S, 1rem) 0;z-index:1000;display:flex;justify-content:flex-end;align-items:center;gap:.5rem;padding:.5rem var(--sapShell_Space_S, 1rem);background:var(--sapPageFooter_Background, white);border-radius:var(--sapElement_BorderCornerRadius, 12px);box-shadow:var(--sapContent_Shadow1, 0 0 0 1px rgba(34, 53, 72, .48), 0 2px 8px 0 rgba(34, 53, 72, .3));box-sizing:border-box;overflow:hidden}@media screen and (min-width:0px)and (max-width:599px){.mfp-dashboard{padding:calc(var(--sapShell_Space_S, 1rem) - 10px)}}@media screen and (min-width:600px)and (max-width:1023px){.mfp-dashboard{padding:calc(var(--sapShell_Space_M, 2rem) - 10px)}}@media screen and (min-width:1024px)and (max-width:1439px){.mfp-dashboard{padding:calc(var(--sapShell_Space_L, 2rem) - 10px)}}.grid-stack.grid-stack-dragging,.grid-stack.grid-stack-dragging *{cursor:grabbing!important}.mfp-dashboard__drag-origin-placeholder{position:absolute;pointer-events:none;z-index:1}.mfp-dashboard__drag-origin-placeholder:after,.mfp-dashboard__drag-origin-placeholder .mfp-dashboard__drag-origin-content{height:calc(100% - 30px);top:calc(var(--gs-item-margin-top) * 2 - 2px)!important;width:calc(100% - 19px);left:8px!important;position:absolute;border-radius:16px}.mfp-dashboard__drag-origin-placeholder .mfp-dashboard__drag-origin-content{overflow:hidden}.mfp-dashboard__drag-origin-placeholder:after{content:\"\";background:var(--sapNeutralColor, #6a6d75);opacity:.3}.grid-stack:has(>.mfp-dashboard__drag-origin-placeholder)>.grid-stack-placeholder{visibility:hidden}gridstack{position:relative}.grid-stack:has(.ui-resizable-resizing),.grid-stack:has(.ui-resizable-resizing) *{cursor:nwse-resize!important}.grid-stack-item>.ui-resizable-handle{background-image:none!important}\n"], dependencies: [{ kind: "component", type: GridstackComponent, selector: "gridstack", inputs: ["options", "isEmpty"], outputs: ["addedCB", "changeCB", "disableCB", "dragCB", "dragStartCB", "dragStopCB", "droppedCB", "enableCB", "removedCB", "resizeCB", "resizeStartCB", "resizeStopCB"] }, { kind: "component", type: GridstackItemComponent, selector: "gridstack-item", inputs: ["options"] }, { kind: "component", type: DiscardChangesDialog, selector: "mfp-discard-changes-dialog", inputs: ["open"], outputs: ["confirm", "cancelled"] }, { kind: "component", type: EditCardsDialog, selector: "mfp-edit-cards-dialog", inputs: ["availableCards", "addedCardsIds", "open"], outputs: ["confirm", "cancelled"] }, { kind: "component", type: UnsavedChangesDialog, selector: "mfp-unsaved-changes-dialog", inputs: ["open"], outputs: ["save", "discard", "cancelled"] }, { kind: "component", type: DashboardSection, selector: "mfp-dashboard-section", inputs: ["section", "cards", "columns", "editMode"], outputs: ["removeSection", "removeCard"] }, { kind: "component", type: DashboardCard, selector: "mfp-dashboard-card", inputs: ["card", "editMode"], outputs: ["removeCard"] }, { kind: "component", type: BusyIndicator, selector: "ui5-busy-indicator, [ui5-busy-indicator]", inputs: ["active", "delay", "size", "text", "textPlacement"], exportAs: ["ui5BusyIndicator"] }, { kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Icon, selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }, { kind: "component", type: Menu, selector: "ui5-menu, [ui5-menu]", inputs: ["headerText", "horizontalAlign", "loading", "loadingDelay", "open", "opener", "placement"], outputs: ["ui5BeforeClose", "ui5BeforeOpen", "ui5Close", "ui5ItemClick", "ui5Open"], exportAs: ["ui5Menu"] }, { kind: "component", type: MenuItem, selector: "ui5-menu-item, [ui5-menu-item]", inputs: ["accessibilityAttributes", "accessibleName", "accessibleRole", "additionalText", "checked", "disabled", "highlight", "icon", "loading", "loadingDelay", "navigated", "selected", "text", "tooltip", "type"], outputs: ["ui5BeforeClose", "ui5BeforeOpen", "ui5Check", "ui5Click", "ui5Close", "ui5DetailClick", "ui5Open"], exportAs: ["ui5MenuItem"] }, { kind: "component", type: MenuSeparator, selector: "ui5-menu-separator, [ui5-menu-separator]", exportAs: ["ui5MenuSeparator"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["level", "size", "wrappingType"], exportAs: ["ui5Title"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
1319
1668
|
}
|
|
1320
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1669
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Dashboard, decorators: [{
|
|
1321
1670
|
type: Component,
|
|
1322
1671
|
args: [{ selector: 'mfp-dashboard', imports: [
|
|
1323
1672
|
GridstackComponent,
|
|
@@ -1327,6 +1676,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1327
1676
|
UnsavedChangesDialog,
|
|
1328
1677
|
DashboardSection,
|
|
1329
1678
|
DashboardCard,
|
|
1679
|
+
BusyIndicator,
|
|
1330
1680
|
Button,
|
|
1331
1681
|
Icon,
|
|
1332
1682
|
Menu,
|
|
@@ -1334,10 +1684,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1334
1684
|
MenuSeparator,
|
|
1335
1685
|
Title,
|
|
1336
1686
|
], providers: [DashboardI18nService], encapsulation: ViewEncapsulation.None, host: {
|
|
1337
|
-
'[style.background-image]': 'config().backgroundImageUrl ? "url(" + config().backgroundImageUrl + ")" :
|
|
1687
|
+
'[style.background-image]': 'config().backgroundImageUrl ? "url(" + config().backgroundImageUrl + ")" : "var(--mfp-dashboard-background, none)"',
|
|
1338
1688
|
'[style.background-size]': 'backgroundImageHeight() ? "100% " + backgroundImageHeight() + "px" : "100% auto"',
|
|
1339
|
-
}, template: "<div\n class=\"mfp-dashboard\"\n data-testid=\"dashboard\"\n [style]=\"columnVars()\"\n [class.edit]=\"editMode()\"\n>\n <div class=\"mfp-dashboard__topbar\">\n <div class=\"mfp-dashboard__topbar-row\">\n <div class=\"mfp-dashboard__header\">\n <div class=\"mfp-dashboard__title-row\">\n @if (config().title) {\n <ui5-title\n data-testid=\"dashboard-title\"\n level=\"H3\"\n size=\"H3\"\n wrapping-type=\"Normal\"\n >\n <span [innerHTML]=\"safeTitle()\"></span>\n </ui5-title>\n }\n @if (hasUnsavedChanges()) {\n <div class=\"mfp-dashboard__unsaved-changes\" role=\"status\">\n <ui5-icon\n class=\"mfp-dashboard__unsaved-changes-icon\"\n name=\"user-edit\"\n [accessibleName]=\"i18n.getTranslation(i18nKeys.UNSAVED_CHANGES)\"\n />\n <span class=\"mfp-dashboard__unsaved-changes-text\">{{\n i18n.getTranslation(i18nKeys.UNSAVED_CHANGES)\n }}</span>\n </div>\n }\n </div>\n @if (config().description) {\n <ui5-title\n data-testid=\"dashboard-description\"\n level=\"H5\"\n size=\"H5\"\n wrapping-type=\"Normal\"\n >\n <span\n class=\"mfp-dashboard__description\"\n [innerHTML]=\"safeDescription()\"\n ></span>\n </ui5-title>\n }\n </div>\n\n <div class=\"mfp-dashboard__toolbar\">\n @if (editMode()) {\n <ui5-button\n #editCardsBtn\n data-testid=\"dashboard-edit-cards-btn\"\n id=\"edit-cards-btn\"\n [accessibleName]=\"\n editCardsButton().text ||\n editCardsButton().tooltip ||\n i18n.getTranslation(i18nKeys.EDIT_CARDS)\n \"\n [design]=\"editCardsButton().design\"\n [icon]=\"editCardsButton().icon\"\n [tooltip]=\"editCardsButton().tooltip\"\n (click)=\"openCardPanel()\"\n >{{ editCardsButton().text }}</ui5-button\n >\n } @else if (compactToolbar()) {\n <ui5-button\n #menuBtn\n data-testid=\"dashboard-toolbar-menu-btn\"\n design=\"Transparent\"\n icon=\"menu2\"\n [accessibleName]=\"i18n.getTranslation(i18nKeys.ACTIONS)\"\n [tooltip]=\"i18n.getTranslation(i18nKeys.ACTIONS)\"\n (click)=\"toolbarMenuOpen.update((v) => !v)\"\n />\n <ui5-menu\n data-testid=\"dashboard-toolbar-menu\"\n [open]=\"toolbarMenuOpen()\"\n [opener]=\"menuBtn.element\"\n (ui5Close)=\"toolbarMenuOpen.set(false)\"\n (ui5ItemClick)=\"\n onMenuItemClick(\n $any($event).detail.item.dataset['action'],\n $event\n )\n \"\n (ui5Open)=\"toolbarMenuOpen.set(true)\"\n >\n @if (config().editButtonFirst && config().editable) {\n <ui5-menu-item\n data-action=\"edit-view\"\n data-testid=\"dashboard-action-edit-view\"\n [icon]=\"editViewButton().icon\"\n [text]=\"\n editViewButton().text ||\n i18n.getTranslation(i18nKeys.EDIT_VIEW)\n \"\n />\n @if (customActions().length) {\n <ui5-menu-separator />\n }\n }\n @for (action of customActions(); track action.action) {\n <ui5-menu-item\n [attr.data-action]=\"action.action\"\n [attr.data-testid]=\"'dashboard-action-' + action.action\"\n [icon]=\"action.icon ?? ''\"\n [text]=\"action.text ?? ''\"\n />\n }\n @if (!config().editButtonFirst && config().editable) {\n <ui5-menu-separator />\n <ui5-menu-item\n data-action=\"edit-view\"\n data-testid=\"dashboard-action-edit-view\"\n [icon]=\"editViewButton().icon\"\n [text]=\"\n editViewButton().text ||\n i18n.getTranslation(i18nKeys.EDIT_VIEW)\n \"\n />\n }\n </ui5-menu>\n } @else {\n @if (config().editButtonFirst && config().editable) {\n <ui5-button\n data-testid=\"dashboard-edit-view-btn\"\n [accessibleName]=\"\n editViewButton().text ||\n editViewButton().tooltip ||\n i18n.getTranslation(i18nKeys.EDIT_VIEW)\n \"\n [design]=\"editViewButton().design\"\n [icon]=\"editViewButton().icon\"\n [tooltip]=\"editViewButton().tooltip\"\n (click)=\"enterEditMode()\"\n >{{ editViewButton().text }}</ui5-button\n >\n }\n @for (action of customActions(); track action.action) {\n <ui5-button\n [accessibleName]=\"action.text || action.tooltip || action.action\"\n [attr.data-testid]=\"'dashboard-action-' + action.action\"\n [design]=\"action.design ?? 'Default'\"\n [endIcon]=\"action?.endIcon\"\n [icon]=\"action.icon ?? ''\"\n [tooltip]=\"action.tooltip ?? ''\"\n (click)=\"\n actionButtonClick.emit({ event: $event, action: action })\n \"\n >{{ action.text }}</ui5-button\n >\n }\n @if (!config().editButtonFirst && config().editable) {\n <ui5-button\n data-testid=\"dashboard-edit-view-btn\"\n [accessibleName]=\"\n editViewButton().text ||\n editViewButton().tooltip ||\n i18n.getTranslation(i18nKeys.EDIT_VIEW)\n \"\n [design]=\"editViewButton().design\"\n [icon]=\"editViewButton().icon\"\n [tooltip]=\"editViewButton().tooltip\"\n (click)=\"enterEditMode()\"\n >{{ editViewButton().text }}</ui5-button\n >\n }\n }\n </div>\n </div>\n\n <div class=\"mfp-dashboard__subheader\">\n <ng-content select=\"[slot=dashboard-subheader]\" />\n </div>\n </div>\n\n <div class=\"mfp-sections-container\">\n @for (section of sections(); track section.id) {\n <mfp-dashboard-section\n [cards]=\"sectionCards()(section.id)\"\n [editMode]=\"editMode()\"\n [section]=\"section\"\n (removeCard)=\"removeCard($event)\"\n (removeSection)=\"removeSection(section.id)\"\n />\n }\n </div>\n\n <gridstack\n #grid\n data-testid=\"dashboard-grid\"\n [class.zflow-dragging]=\"!!dragOriginStyle()\"\n [options]=\"gridOptions()\"\n (addedCB)=\"onGridChange()\"\n (changeCB)=\"onGridChange()\"\n (dragStartCB)=\"onDragStart($event)\"\n (dragStopCB)=\"onDragStop()\"\n (removedCB)=\"onGridChange()\"\n >\n @if (dragOriginStyle()) {\n <div\n class=\"mfp-dashboard__drag-origin-placeholder\"\n [style]=\"dragOriginStyle()\"\n ></div>\n }\n @for (card of looseCards(); track card.id) {\n <gridstack-item [options]=\"card\">\n <mfp-dashboard-card\n [card]=\"card\"\n [editMode]=\"editMode()\"\n (removeCard)=\"removeCard($any(card.id))\"\n />\n </gridstack-item>\n }\n </gridstack>\n</div>\n@if (editMode()) {\n <div class=\"mfp-dashboard__edit-bar\">\n <ui5-button\n data-testid=\"dashboard-save-btn\"\n design=\"Emphasized\"\n (click)=\"saveEdit()\"\n >{{ i18n.getTranslation(i18nKeys.SAVE) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-cancel-btn\"\n design=\"Transparent\"\n (click)=\"cancelEdit()\"\n >{{ i18n.getTranslation(i18nKeys.CANCEL) }}</ui5-button\n >\n </div>\n}\n\n<mfp-edit-cards-dialog\n [addedCardsIds]=\"addedCardsIds()\"\n [availableCards]=\"availableCards()\"\n [open]=\"cardDialogOpen()\"\n (cancelled)=\"closeCardPanel()\"\n (confirm)=\"onCardsEdited($event)\"\n/>\n\n<mfp-discard-changes-dialog\n [open]=\"discardDialogOpen()\"\n (cancelled)=\"cancelDiscard()\"\n (confirm)=\"confirmDiscard()\"\n/>\n\n<mfp-unsaved-changes-dialog\n [open]=\"unsavedNavDialogOpen()\"\n (cancelled)=\"onUnsavedNavCancel()\"\n (discard)=\"onUnsavedNavDiscard()\"\n (save)=\"onUnsavedNavSave()\"\n/>\n", styles: [".grid-stack{position:relative}.grid-stack-placeholder>.placeholder-content{background-color:#0000001a;margin:0;position:absolute;width:auto;z-index:0!important}.grid-stack>.grid-stack-item{position:absolute;padding:0;top:0;width:var(--gs-column-width);height:var(--gs-cell-height)}.grid-stack>.grid-stack-item>.grid-stack-item-content{margin:0;position:absolute;width:auto;overflow-x:hidden;overflow-y:auto}.grid-stack>.grid-stack-item.size-to-content:not(.size-to-content-max)>.grid-stack-item-content{overflow-y:hidden}.grid-stack:not(.grid-stack-rtl)>.grid-stack-item{left:0}.grid-stack.grid-stack-rtl>.grid-stack-item{right:0}.grid-stack>.grid-stack-item>.grid-stack-item-content,.grid-stack>.grid-stack-placeholder>.placeholder-content{top:var(--gs-item-margin-top);right:var(--gs-item-margin-right);bottom:var(--gs-item-margin-bottom);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;user-select:none;z-index:100}.grid-stack-item.ui-resizable-autohide>.ui-resizable-handle,.grid-stack-item.ui-resizable-disabled>.ui-resizable-handle{display:none}.grid-stack-item>.ui-resizable-ne,.grid-stack-item>.ui-resizable-nw,.grid-stack-item>.ui-resizable-se,.grid-stack-item>.ui-resizable-sw{background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"%23666\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" viewBox=\"0 0 20 20\"><path d=\"m10 3 2 2H8l2-2v14l-2-2h4l-2 2\"/></svg>');background-repeat:no-repeat;background-position:center;z-index:101}.grid-stack-item>.ui-resizable-ne{transform:rotate(45deg)}.grid-stack-item>.ui-resizable-sw{transform:rotate(45deg)}.grid-stack-item>.ui-resizable-nw{transform:rotate(-45deg)}.grid-stack-item>.ui-resizable-se{transform:rotate(-45deg)}.grid-stack-item>.ui-resizable-nw{cursor:nw-resize;width:20px;height:20px;top:var(--gs-item-margin-top);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-n{cursor:n-resize;height:10px;top:var(--gs-item-margin-top);left:25px;right:25px}.grid-stack-item>.ui-resizable-ne{cursor:ne-resize;width:20px;height:20px;top:var(--gs-item-margin-top);right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-e{cursor:e-resize;width:10px;top:15px;bottom:15px;right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-se{cursor:se-resize;width:20px;height:20px;bottom:var(--gs-item-margin-bottom);right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-s{cursor:s-resize;height:10px;left:25px;bottom:var(--gs-item-margin-bottom);right:25px}.grid-stack-item>.ui-resizable-sw{cursor:sw-resize;width:20px;height:20px;bottom:var(--gs-item-margin-bottom);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-w{cursor:w-resize;width:10px;top:15px;bottom:15px;left:var(--gs-item-margin-left)}.grid-stack-item.ui-draggable-dragging>.ui-resizable-handle{display:none!important}.grid-stack-item.ui-draggable-dragging{will-change:left,right,top}.grid-stack-item.ui-resizable-resizing{will-change:width,height}.ui-draggable-dragging,.ui-resizable-resizing{z-index:10000}.ui-draggable-dragging>.grid-stack-item-content,.ui-resizable-resizing>.grid-stack-item-content{box-shadow:1px 4px 6px #0003;opacity:.8}.grid-stack-animate,.grid-stack-animate .grid-stack-item{transition:left .3s,right .3s,top .3s,height .3s,width .3s}.grid-stack-animate .grid-stack-item.grid-stack-placeholder,.grid-stack-animate .grid-stack-item.ui-draggable-dragging,.grid-stack-animate .grid-stack-item.ui-resizable-resizing{transition:left 0s,right 0s,top 0s,height 0s,width 0s}.grid-stack>.grid-stack-item[gs-y=\"0\"]{top:0}.grid-stack:not(.grid-stack-rtl)>.grid-stack-item[gs-x=\"0\"]{left:0}.grid-stack.grid-stack-rtl>.grid-stack-item[gs-x=\"0\"]{right:0}.grid-stack-placeholder{z-index:2;pointer-events:none}.grid-stack-placeholder .placeholder-content{border-radius:16px;height:calc(100% - 30px);top:calc(var(--gs-item-margin-top) * 2 - 2px)!important;width:calc(100% - 19px);left:8px!important;background:var(--sapContent_Selected_Hover_Background, #E3F0FF);border:1px solid var(--sapContent_DragAndDropActiveColor, #0064D9);z-index:2!important}mfp-dashboard,mfp-wc-dashboard{display:block;flex:1;margin:0;padding:0;min-height:100%;background:var(--sapShellColor, #354a5e);background-size:100% auto;background-position:top center;background-repeat:no-repeat;background-attachment:local}.mfp-dashboard{padding:calc(var(--sapShell_Space_XL, 3rem) - 10px);container-type:inline-size;container-name:mfp-dashboard}.mfp-dashboard.edit{padding-bottom:60px}.mfp-sections-container{display:grid;grid-auto-rows:auto;align-content:start;gap:1rem;grid-template-columns:repeat(var(--dashboard-cols-xl, 14),1fr)}@container mfp-dashboard (max-width: 599px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-sm, 1),1fr)}}@container mfp-dashboard (min-width: 600px) and (max-width: 1023px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-md, 8),1fr)}}@container mfp-dashboard (min-width: 1024px) and (max-width: 1439px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-lg, 12),1fr)}}.mfp-dashboard__topbar{grid-column:1/-1;align-self:start;display:flex;flex-direction:column;gap:1rem;padding-bottom:3rem;width:100%;min-width:0}.mfp-dashboard__topbar-row{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;padding:0 10px}.mfp-dashboard__header{display:flex;flex-direction:column;gap:.25rem}.mfp-dashboard__title-row{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap}.mfp-dashboard__unsaved-changes{display:inline-flex;align-items:center;gap:.375rem}.mfp-dashboard__unsaved-changes-icon{width:16px;height:16px;color:var(--sapContent_MarkerIconColor)}.mfp-dashboard__unsaved-changes-text{color:var(--sapContent_LabelColor);text-shadow:0 0 2px var(--sapContent_ContrastTextShadow, #fff);font-family:var(--sapFontFamily);font-size:var(--sapFontSize, 14px);font-style:normal;font-weight:400;line-height:normal}.mfp-dashboard__description{font-weight:400;font-family:var(--sapFontFamily)}.mfp-dashboard__description b,.mfp-dashboard__description strong{font-family:var(--sapFontBoldFamily)}.mfp-dashboard__toolbar{flex-shrink:0;display:flex;gap:.5rem}.mfp-dashboard__subheader{display:flex;align-items:center;gap:1rem}.mfp-dashboard__edit-bar{position:fixed;bottom:20px;left:16px;right:16px;z-index:1000;display:flex;justify-content:flex-end;align-items:center;gap:8px;padding:7px 16px;background:var(--sapPageFooter_Background, white);border-radius:var(--sapElement_BorderCornerRadius, 12px);box-shadow:0 0 0 1px #2235487a,0 2px 8px #2235484d;box-sizing:border-box;overflow:hidden}@media screen and (min-width:0px)and (max-width:599px){.mfp-dashboard{padding:calc(var(--sapShell_Space_S, 1rem) - 10px)}}@media screen and (min-width:600px)and (max-width:1023px){.mfp-dashboard{padding:calc(var(--sapShell_Space_M, 2rem) - 10px)}}@media screen and (min-width:1024px)and (max-width:1439px){.mfp-dashboard{padding:calc(var(--sapShell_Space_L, 2rem) - 10px)}}.grid-stack.grid-stack-dragging,.grid-stack.grid-stack-dragging *{cursor:grabbing!important}.mfp-dashboard__drag-origin-placeholder{position:absolute;pointer-events:none;z-index:1}.mfp-dashboard__drag-origin-placeholder:before{content:\"\";height:calc(100% - 30px);top:calc(var(--gs-item-margin-top) * 2 - 2px)!important;width:calc(100% - 19px);left:8px!important;position:absolute;background:var(--sapNeutralColor, #6a6d75);border-radius:16px;opacity:.3}gridstack{position:relative}.grid-stack:has(.ui-resizable-resizing),.grid-stack:has(.ui-resizable-resizing) *{cursor:nwse-resize!important}.grid-stack-item>.ui-resizable-handle{background-image:none!important}\n"] }]
|
|
1340
|
-
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required:
|
|
1689
|
+
}, template: "<div\n class=\"mfp-dashboard\"\n data-testid=\"dashboard\"\n [class.edit]=\"editMode()\"\n [style]=\"columnVars()\"\n>\n <ui5-busy-indicator\n class=\"mfp-dashboard__busy\"\n data-testid=\"dashboard-busy\"\n size=\"M\"\n [active]=\"busyVisible()\"\n [delay]=\"0\"\n >\n <div\n class=\"mfp-dashboard__busy-content\"\n [class.mfp-dashboard__busy-content--busy]=\"busyVisible()\"\n >\n <div class=\"mfp-dashboard__topbar\">\n <div class=\"mfp-dashboard__topbar-row\">\n <div class=\"mfp-dashboard__header\">\n <div class=\"mfp-dashboard__title-row\">\n @if (i18nService.getTranslation(i18nKeys.TITLE)) {\n <ui5-title\n data-testid=\"dashboard-title\"\n level=\"H3\"\n size=\"H3\"\n wrapping-type=\"Normal\"\n >\n <span [innerHTML]=\"safeTitle()\"></span>\n </ui5-title>\n }\n @if (hasUnsavedChanges()) {\n <div class=\"mfp-dashboard__unsaved-changes\" role=\"status\">\n <ui5-icon\n class=\"mfp-dashboard__unsaved-changes-icon\"\n name=\"user-edit\"\n [accessibleName]=\"\n i18nService.getTranslation(i18nKeys.UNSAVED_CHANGES)\n \"\n />\n <span class=\"mfp-dashboard__unsaved-changes-text\">{{\n i18nService.getTranslation(i18nKeys.UNSAVED_CHANGES)\n }}</span>\n </div>\n }\n </div>\n @if (i18nService.getTranslation(i18nKeys.DESCRIPTION)) {\n <ui5-title\n data-testid=\"dashboard-description\"\n level=\"H5\"\n size=\"H5\"\n wrapping-type=\"Normal\"\n >\n <span\n class=\"mfp-dashboard__description\"\n [innerHTML]=\"safeDescription()\"\n ></span>\n </ui5-title>\n }\n </div>\n\n <div class=\"mfp-dashboard__toolbar\">\n @if (editMode()) {\n <ui5-button\n #editCardsBtn\n data-testid=\"dashboard-edit-cards-btn\"\n id=\"edit-cards-btn\"\n [accessibleName]=\"\n editCardsButton().text ||\n editCardsButton().tooltip ||\n i18nService.getTranslation(i18nKeys.EDIT_CARDS_BUTTON)\n \"\n [design]=\"editCardsButton().design\"\n [icon]=\"editCardsButton().icon\"\n [tooltip]=\"editCardsButton().tooltip\"\n (click)=\"openCardPanel()\"\n >{{ editCardsButton().text }}</ui5-button\n >\n } @else if (compactToolbar() && hasToolbarMenuContent()) {\n <ui5-button\n #menuBtn\n data-testid=\"dashboard-toolbar-menu-btn\"\n design=\"Transparent\"\n icon=\"menu2\"\n [accessibleName]=\"i18nService.getTranslation(i18nKeys.ACTIONS)\"\n [tooltip]=\"i18nService.getTranslation(i18nKeys.ACTIONS)\"\n (click)=\"toolbarMenuOpen.update((v) => !v)\"\n />\n <ui5-menu\n data-testid=\"dashboard-toolbar-menu\"\n [open]=\"toolbarMenuOpen()\"\n [opener]=\"menuBtn.element\"\n (ui5Close)=\"toolbarMenuOpen.set(false)\"\n (ui5ItemClick)=\"\n onMenuItemClick(\n $any($event).detail.item.dataset['action'],\n $event\n )\n \"\n (ui5Open)=\"toolbarMenuOpen.set(true)\"\n >\n @if (config().editButtonFirst && config().editable) {\n <ui5-menu-item\n data-action=\"edit-view\"\n data-testid=\"dashboard-action-edit-view\"\n [icon]=\"editViewButton().icon\"\n [text]=\"\n editViewButton().text ||\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n \"\n />\n @if (customActions().length) {\n <ui5-menu-separator />\n }\n }\n @for (action of customActions(); track action.action) {\n <ui5-menu-item\n [attr.data-action]=\"action.action\"\n [attr.data-testid]=\"'dashboard-action-' + action.action\"\n [icon]=\"action.icon ?? ''\"\n [text]=\"action.text ?? ''\"\n />\n }\n @if (!config().editButtonFirst && config().editable) {\n <ui5-menu-separator />\n <ui5-menu-item\n data-action=\"edit-view\"\n data-testid=\"dashboard-action-edit-view\"\n [icon]=\"editViewButton().icon\"\n [text]=\"\n editViewButton().text ||\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n \"\n />\n }\n </ui5-menu>\n } @else {\n @if (config().editButtonFirst && config().editable) {\n <ui5-button\n data-testid=\"dashboard-edit-view-btn\"\n [accessibleName]=\"\n editViewButton().text ||\n editViewButton().tooltip ||\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n \"\n [design]=\"editViewButton().design\"\n [icon]=\"editViewButton().icon\"\n [tooltip]=\"editViewButton().tooltip\"\n (click)=\"enterEditMode()\"\n >{{ editViewButton().text }}</ui5-button\n >\n }\n @for (action of customActions(); track action.action) {\n <ui5-button\n [accessibleName]=\"\n action.text || action.tooltip || action.action\n \"\n [attr.data-testid]=\"'dashboard-action-' + action.action\"\n [design]=\"action.design ?? 'Default'\"\n [endIcon]=\"action?.endIcon\"\n [icon]=\"action.icon ?? ''\"\n [tooltip]=\"action.tooltip ?? ''\"\n (click)=\"\n actionButtonClick.emit({ event: $event, action: action })\n \"\n >{{ action.text }}</ui5-button\n >\n }\n @if (!config().editButtonFirst && config().editable) {\n <ui5-button\n data-testid=\"dashboard-edit-view-btn\"\n [accessibleName]=\"\n editViewButton().text ||\n editViewButton().tooltip ||\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n \"\n [design]=\"editViewButton().design\"\n [icon]=\"editViewButton().icon\"\n [tooltip]=\"editViewButton().tooltip\"\n (click)=\"enterEditMode()\"\n >{{ editViewButton().text }}</ui5-button\n >\n }\n }\n </div>\n </div>\n\n <div class=\"mfp-dashboard__subheader\">\n <ng-content select=\"[slot=dashboard-subheader]\" />\n </div>\n </div>\n\n <div class=\"mfp-sections-container\">\n @for (section of sections(); track section.id) {\n <mfp-dashboard-section\n [cards]=\"sectionCards()(section.id)\"\n [editMode]=\"editMode()\"\n [section]=\"section\"\n (removeCard)=\"removeCard($event)\"\n (removeSection)=\"removeSection(section.id)\"\n />\n }\n </div>\n\n @if (isEmpty() && isDashboardEditable() && !loading()) {\n <div class=\"mfp-dashboard__empty\" data-testid=\"dashboard-empty-state\">\n <div\n class=\"mfp-dashboard__empty-illustration\"\n data-testid=\"dashboard-empty-state-illustration\"\n role=\"img\"\n [attr.aria-label]=\"\n i18nService.getTranslation(i18nKeys.EMPTY_STATE_ILLUSTRATION)\n \"\n ></div>\n <ui5-title\n class=\"mfp-dashboard__empty-title\"\n data-testid=\"dashboard-empty-state-title\"\n level=\"H4\"\n size=\"H3\"\n wrapping-type=\"Normal\"\n >{{\n i18nService.getTranslation(i18nKeys.EMPTY_STATE_TITLE)\n }}</ui5-title\n >\n <p\n class=\"mfp-dashboard__empty-description\"\n data-testid=\"dashboard-empty-state-description\"\n >\n {{ i18nService.getTranslation(i18nKeys.EMPTY_STATE_DESCRIPTION) }}\n </p>\n @if (isDashboardEditable() && !editMode()) {\n <ui5-button\n data-testid=\"dashboard-empty-state-edit-btn\"\n design=\"Emphasized\"\n [accessibleName]=\"\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n \"\n (click)=\"enterEditModeAndEditCards()\"\n >{{\n i18nService.getTranslation(i18nKeys.EDIT_HOME_BUTTON)\n }}</ui5-button\n >\n }\n </div>\n }\n\n <gridstack\n #grid\n data-testid=\"dashboard-grid\"\n [attr.role]=\"keyboardNavigationActive() ? 'list' : null\"\n [class.zflow-dragging]=\"!!dragOriginStyle()\"\n [options]=\"gridOptions()\"\n (addedCB)=\"onGridChange()\"\n (changeCB)=\"onGridChange()\"\n (dragCB)=\"onDrag()\"\n (dragStartCB)=\"onDragStart($event)\"\n (dragStopCB)=\"onDragStop()\"\n (removedCB)=\"onGridChange()\"\n >\n @if (dragOriginStyle() && dragOriginVisible()) {\n <div\n #dragOriginPlaceholder\n class=\"mfp-dashboard__drag-origin-placeholder\"\n [style]=\"dragOriginStyle()\"\n ></div>\n }\n @for (card of looseCards(); track card.id) {\n <gridstack-item\n [attr.aria-keyshortcuts]=\"\n keyboardNavigationActive() ? cardAriaKeyshortcuts : null\n \"\n [attr.aria-label]=\"\n keyboardNavigationActive()\n ? card.label || card.component || card.id\n : null\n \"\n [attr.role]=\"keyboardNavigationActive() ? 'listitem' : null\"\n [attr.tabindex]=\"keyboardNavigationActive() ? '0' : null\"\n [options]=\"card\"\n (keydown)=\"onCardKeydown($event, card.id)\"\n >\n <mfp-dashboard-card\n [card]=\"card\"\n [editMode]=\"editMode()\"\n (removeCard)=\"removeCard($any(card.id))\"\n />\n </gridstack-item>\n }\n </gridstack>\n </div>\n </ui5-busy-indicator>\n</div>\n@if (editMode()) {\n <div class=\"mfp-dashboard__edit-bar\">\n <ui5-button\n data-testid=\"dashboard-save-btn\"\n design=\"Emphasized\"\n (click)=\"saveEdit()\"\n >{{ i18nService.getTranslation(i18nKeys.SAVE) }}</ui5-button\n >\n <ui5-button\n data-testid=\"dashboard-cancel-btn\"\n design=\"Transparent\"\n (click)=\"cancelEdit()\"\n >{{ i18nService.getTranslation(i18nKeys.CANCEL) }}</ui5-button\n >\n </div>\n}\n\n<mfp-edit-cards-dialog\n [addedCardsIds]=\"addedCardsIds()\"\n [availableCards]=\"availableCards()\"\n [open]=\"cardDialogOpen()\"\n (cancelled)=\"closeCardPanel()\"\n (confirm)=\"onCardsEdited($event)\"\n/>\n\n<mfp-discard-changes-dialog\n [open]=\"discardDialogOpen()\"\n (cancelled)=\"cancelDiscard()\"\n (confirm)=\"confirmDiscard()\"\n/>\n\n<mfp-unsaved-changes-dialog\n [open]=\"unsavedNavDialogOpen()\"\n (cancelled)=\"onUnsavedNavCancel()\"\n (discard)=\"onUnsavedNavDiscard()\"\n (save)=\"onUnsavedNavSave()\"\n/>\n", styles: [".grid-stack{position:relative}.grid-stack-placeholder>.placeholder-content{background-color:#0000001a;margin:0;position:absolute;width:auto;z-index:0!important}.grid-stack>.grid-stack-item{position:absolute;padding:0;top:0;width:var(--gs-column-width);height:var(--gs-cell-height)}.grid-stack>.grid-stack-item>.grid-stack-item-content{margin:0;position:absolute;width:auto;overflow-x:hidden;overflow-y:auto}.grid-stack>.grid-stack-item.size-to-content:not(.size-to-content-max)>.grid-stack-item-content{overflow-y:hidden}.grid-stack:not(.grid-stack-rtl)>.grid-stack-item{left:0}.grid-stack.grid-stack-rtl>.grid-stack-item{right:0}.grid-stack>.grid-stack-item>.grid-stack-item-content,.grid-stack>.grid-stack-placeholder>.placeholder-content{top:var(--gs-item-margin-top);right:var(--gs-item-margin-right);bottom:var(--gs-item-margin-bottom);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;user-select:none;z-index:100}.grid-stack-item.ui-resizable-autohide>.ui-resizable-handle,.grid-stack-item.ui-resizable-disabled>.ui-resizable-handle{display:none}.grid-stack-item>.ui-resizable-ne,.grid-stack-item>.ui-resizable-nw,.grid-stack-item>.ui-resizable-se,.grid-stack-item>.ui-resizable-sw{background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"%23666\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" viewBox=\"0 0 20 20\"><path d=\"m10 3 2 2H8l2-2v14l-2-2h4l-2 2\"/></svg>');background-repeat:no-repeat;background-position:center;z-index:101}.grid-stack-item>.ui-resizable-ne{transform:rotate(45deg)}.grid-stack-item>.ui-resizable-sw{transform:rotate(45deg)}.grid-stack-item>.ui-resizable-nw{transform:rotate(-45deg)}.grid-stack-item>.ui-resizable-se{transform:rotate(-45deg)}.grid-stack-item>.ui-resizable-nw{cursor:nw-resize;width:20px;height:20px;top:var(--gs-item-margin-top);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-n{cursor:n-resize;height:10px;top:var(--gs-item-margin-top);left:25px;right:25px}.grid-stack-item>.ui-resizable-ne{cursor:ne-resize;width:20px;height:20px;top:var(--gs-item-margin-top);right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-e{cursor:e-resize;width:10px;top:15px;bottom:15px;right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-se{cursor:se-resize;width:20px;height:20px;bottom:var(--gs-item-margin-bottom);right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-s{cursor:s-resize;height:10px;left:25px;bottom:var(--gs-item-margin-bottom);right:25px}.grid-stack-item>.ui-resizable-sw{cursor:sw-resize;width:20px;height:20px;bottom:var(--gs-item-margin-bottom);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-w{cursor:w-resize;width:10px;top:15px;bottom:15px;left:var(--gs-item-margin-left)}.grid-stack-item.ui-draggable-dragging>.ui-resizable-handle{display:none!important}.grid-stack-item.ui-draggable-dragging{will-change:left,right,top}.grid-stack-item.ui-resizable-resizing{will-change:width,height}.ui-draggable-dragging,.ui-resizable-resizing{z-index:10000}.ui-draggable-dragging>.grid-stack-item-content,.ui-resizable-resizing>.grid-stack-item-content{box-shadow:1px 4px 6px #0003;opacity:.8}.grid-stack-animate,.grid-stack-animate .grid-stack-item{transition:left .3s,right .3s,top .3s,height .3s,width .3s}.grid-stack-animate .grid-stack-item.grid-stack-placeholder,.grid-stack-animate .grid-stack-item.ui-draggable-dragging,.grid-stack-animate .grid-stack-item.ui-resizable-resizing{transition:left 0s,right 0s,top 0s,height 0s,width 0s}.grid-stack>.grid-stack-item[gs-y=\"0\"]{top:0}.grid-stack:not(.grid-stack-rtl)>.grid-stack-item[gs-x=\"0\"]{left:0}.grid-stack.grid-stack-rtl>.grid-stack-item[gs-x=\"0\"]{right:0}.gs-print-show{display:none}@media print{@page gs-landscape{size:landscape}@page gs-portrait{size:portrait}.grid-stack{display:block!important;height:auto!important;position:static!important}.grid-stack>.grid-stack-item{display:block!important;float:left!important;position:static!important;height:auto!important;left:auto!important;top:auto!important;width:calc(100% * var(--gs-w)/ var(--gs-columns,12))!important;break-inside:avoid!important;page-break-inside:avoid!important}.grid-stack>.grid-stack-item>.grid-stack-item-content{position:relative!important;height:auto!important;overflow:visible!important;white-space:normal!important;margin-top:var(--gs-item-margin-top)!important;margin-right:var(--gs-item-margin-right)!important;margin-bottom:var(--gs-item-margin-bottom)!important;margin-left:var(--gs-item-margin-left)!important;inset:auto!important}.gs-print-hide{display:none}.gs-print-show{display:block}.grid-stack>.grid-stack-item.gs-print-hide{display:none!important}.grid-stack>.grid-stack-item[gs-page-break=true],.grid-stack>.grid-stack-item[gs-print-orientation]{float:none!important;clear:both!important}.grid-stack>.grid-stack-item[gs-page-break=true]{page-break-before:always!important;break-before:page!important}.grid-stack>.grid-stack-item[gs-print-orientation=landscape]{page:gs-landscape;min-width:calc(100vmax * var(--gs-w)/ var(--gs-columns,12))!important}.grid-stack>.grid-stack-item[gs-print-orientation=portrait]{page:gs-portrait;min-width:calc(100vmin * var(--gs-w)/ var(--gs-columns,12))!important}.grid-stack>.grid-stack-item>.ui-resizable-handle{display:none!important}}.grid-stack-placeholder{z-index:2;pointer-events:none}.grid-stack-placeholder .placeholder-content{border-radius:16px;height:calc(100% - 30px);top:calc(var(--gs-item-margin-top) * 2 - 2px)!important;width:calc(100% - 19px);left:8px!important;background:var(--sapContent_Selected_Hover_Background, #e3f0ff);border:1px solid var(--sapContent_DragAndDropActiveColor, #0064d9);z-index:2!important}mfp-dashboard,mfp-wc-dashboard{display:block;flex:1;margin:0;padding:0;min-height:100%;background-size:100% auto;background-position:top center;background-repeat:no-repeat;background-attachment:local}.mfp-dashboard{padding:calc(var(--sapShell_Space_XL, 3rem) - 10px);container-type:inline-size;container-name:mfp-dashboard}.mfp-dashboard.edit{padding-bottom:60px}.mfp-dashboard.edit>.mfp-dashboard__busy gridstack>.grid-stack-item,.mfp-dashboard.edit>.mfp-dashboard__busy gridstack>.grid-stack-item:focus,.mfp-dashboard.edit>.mfp-dashboard__busy gridstack>.grid-stack-item:focus-visible{outline:none!important;border:0!important;box-shadow:none!important}.mfp-sections-container{display:grid;grid-auto-rows:auto;align-content:start;gap:1rem;grid-template-columns:repeat(var(--dashboard-cols-xl, 14),1fr)}@container mfp-dashboard (max-width: 599px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-sm, 1),1fr)}}@container mfp-dashboard (min-width: 600px) and (max-width: 1023px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-md, 8),1fr)}}@container mfp-dashboard (min-width: 1024px) and (max-width: 1439px){.mfp-sections-container{grid-template-columns:repeat(var(--dashboard-cols-lg, 12),1fr)}}.mfp-dashboard__topbar{grid-column:1/-1;align-self:start;display:flex;flex-direction:column;gap:1rem;padding-bottom:3rem;width:100%;min-width:0}.mfp-dashboard__topbar-row{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;padding:0 10px}.mfp-dashboard__header{display:flex;flex-direction:column;gap:.25rem}.mfp-dashboard__title-row{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap}.mfp-dashboard__unsaved-changes{display:inline-flex;align-items:center;gap:.375rem}.mfp-dashboard__unsaved-changes-icon{width:16px;height:16px;color:var(--sapContent_MarkerIconColor)}.mfp-dashboard__unsaved-changes-text{color:var(--sapContent_LabelColor);text-shadow:0 0 2px var(--sapContent_ContrastTextShadow, #fff);font-family:var(--sapFontFamily);font-size:var(--sapFontSize, 14px);font-style:normal;font-weight:400;line-height:normal}.mfp-dashboard__description{font-weight:400;font-family:var(--sapFontFamily)}.mfp-dashboard__description b,.mfp-dashboard__description strong{font-family:var(--sapFontBoldFamily)}.mfp-dashboard__toolbar{flex-shrink:0;display:flex;gap:.5rem}.mfp-dashboard__subheader{display:flex;align-items:center;gap:var(--sapShell_Space_S, 1rem)}.mfp-dashboard__busy{display:block;width:100%}.mfp-dashboard__busy-content{width:100%}.mfp-dashboard__busy-content--busy{min-height:60vh}.mfp-dashboard__empty{display:flex;flex-direction:column;align-items:center;gap:.5rem;padding:2rem 1rem 4rem;text-align:center}.mfp-dashboard__empty-illustration{width:320px;max-width:100%;aspect-ratio:320/240;background-image:var(--mfp-dashboard-empty-image, url(\"data:image/svg+xml;utf8,%3Csvg id='tnt-Scene-NoApplications' xmlns='http://www.w3.org/2000/svg' width='320' height='240' fill='none' viewBox='0 0 320 240'%3E%3Crect width='320' height='138' y='59' fill='%2389d1ff' rx='24'/%3E%3Cpath fill='%231b90ff' fill-rule='evenodd' d='m96.085 187.07 133.74-23.88c.83-.15.86-1.32.05-1.53l-83.86-20.89c-1-.25-2.05-.3-3.07-.14L37.355 156.9c-1.87.29-2.23 2.82-.51 3.62l56.21 26.14c.94.44 2.01.58 3.04.39l-.01.02Z' clip-rule='evenodd'/%3E%3Cpath fill='%230070f2' d='M234.425 39.1c.53-.03 1.07.07 1.57.25s.99.47 1.43.83c.44.36.82.79 1.12 1.27.31.49.54 1.03.68 1.6l2.49 10.83-161.93 9.75-2.09-12.04a4.21 4.21 0 0 1 .06-1.81 3.917 3.917 0 0 1 2.07-2.57c.52-.26 1.11-.42 1.76-.46l152.84-7.65Z'/%3E%3Cpath fill='%23ffffff' d='m79.775 63.63 161.92-9.74 20.81 90.49c.14.61.16 1.21.1 1.76-.07.55-.25 1.07-.51 1.52-.27.45-.61.83-1.03 1.11-.42.28-.9.47-1.45.54l-156.56 19.62c-.67.09-1.32.02-1.94-.15-.62-.17-1.21-.47-1.72-.88-.51-.4-.96-.88-1.31-1.45-.35-.57-.6-1.2-.71-1.88L79.785 63.63h-.01Z'/%3E%3Cpath fill='%2389d1ff' d='m95.125 73.19 43.77-2.41c.38-.02.76.03 1.12.14.36.11.69.29.99.51.3.22.55.49.76.79.21.3.34.64.41.99l7.57 38.85a2.51 2.51 0 0 1-.45 1.98c-.2.27-.47.5-.77.68-.3.18-.66.3-1.04.34l-43.82 5.29a3.685 3.685 0 0 1-2.41-.58c-.34-.22-.62-.5-.83-.82-.21-.32-.37-.68-.44-1.07l-7.46-41.74c-.07-.38-.05-.75.05-1.08.1-.33.27-.65.51-.92s.53-.49.88-.65c.35-.16.74-.27 1.16-.3Zm104.68-5.76 32.44-1.79c.28-.02.57.03.84.13s.53.25.76.44c.23.19.44.43.6.69.16.26.29.55.36.86l7.53 33.48c.07.32.08.62.04.91-.04.29-.14.55-.28.78-.14.23-.32.42-.54.57-.22.15-.48.24-.76.28l-32.34 3.91a2.504 2.504 0 0 1-1.8-.53c-.26-.2-.48-.44-.66-.71-.18-.27-.31-.58-.38-.92l-7.58-35.6c-.07-.32-.07-.64-.02-.93.05-.29.17-.55.33-.78.16-.23.37-.41.61-.55.24-.14.53-.22.84-.25l.01.01Zm-48.05 2.64 37.44-2.05c.33-.02.65.03.97.14.32.11.6.27.87.47.27.2.49.45.67.73.18.28.31.59.38.92l7.58 35.95c.07.34.07.67.01.98-.06.31-.18.6-.35.84-.17.24-.39.46-.65.62-.26.16-.56.27-.88.31l-37.4 4.52c-.38.04-.75 0-1.1-.09-.35-.09-.68-.26-.97-.46-.29-.2-.54-.47-.74-.76-.2-.29-.34-.63-.41-.98l-7.58-38.41c-.07-.35-.06-.69.01-1 .07-.31.21-.6.41-.84.2-.24.44-.45.73-.6.29-.15.62-.25.98-.27l.03-.02Z'/%3E%3Cpath fill='%2356bdff' d='M88.485 51.02c.51-.03 1.02.05 1.5.21.49.16.92.41 1.32.72s.73.69 1 1.12c.27.43.46.9.54 1.41.09.5.08.99-.04 1.44-.11.45-.31.86-.59 1.21-.28.35-.63.65-1.04.86-.41.21-.88.34-1.4.37-.51.03-1.02-.05-1.5-.21a4.23 4.23 0 0 1-1.32-.72c-.39-.31-.74-.69-1.01-1.12-.27-.43-.46-.9-.54-1.42-.09-.51-.07-1 .04-1.45.1-.45.31-.87.59-1.21.28-.34.63-.64 1.05-.86.42-.22.88-.34 1.4-.36v.01Z'/%3E%3Cpath fill='%230040b0' d='M103.065 168.93c-.67.08-1.32.02-1.94-.15-.62-.18-1.21-.48-1.72-.88s-.96-.88-1.31-1.46c-.35-.56-.6-1.2-.71-1.88L79.795 63.63l-2.09-12.04c-.06-.3-.08-.61-.07-.9 0-.29.05-.58.11-.86.07-.28.16-.54.28-.79.11-.25.27-.49.43-.7l-2.65 3.45c-.16.22-.3.45-.43.69-.11.25-.21.5-.28.78-.07.28-.1.55-.11.85 0 .29 0 .59.07.89l2.06 11.91 17.29 99.82c.11.68.36 1.3.7 1.86a5.4 5.4 0 0 0 1.29 1.44c.51.39 1.08.68 1.7.87.62.18 1.27.24 1.92.15l155.15-19.6 4.46-2.15-156.56 19.62v.01Z'/%3E%3Cpath fill='%23046c7c' d='m269.075 164.4-3.89 2.51s-.09.06-.13.08c-.04.02-.09.06-.12.08-.04.02-.09.06-.12.08-.04.02-.09.06-.13.08-.83.5-1.68.96-2.55 1.37-.87.41-1.77.76-2.7 1.08-.92.32-1.86.57-2.81.78-.96.21-1.94.37-2.92.47-.49.06-.99.1-1.48.13s-1 .04-1.5.05c-.5 0-1.01 0-1.52-.04s-1.02-.06-1.53-.12c-1.54-.15-3.07-.43-4.6-.81-1.52-.39-3.03-.89-4.5-1.5-1.47-.61-2.92-1.34-4.33-2.17-1.41-.83-2.77-1.76-4.07-2.79a36.883 36.883 0 0 1-3.7-3.36c-1.15-1.2-2.24-2.48-3.23-3.81-.99-1.33-1.89-2.75-2.7-4.2a37.21 37.21 0 0 1-2.12-4.52c-.61-1.55-1.1-3.12-1.48-4.71a34.17 34.17 0 0 1-.8-4.77c-.15-1.6-.19-3.17-.12-4.74.07-1.57.27-3.11.58-4.62.3-1.49.7-2.92 1.21-4.3s1.12-2.71 1.82-3.97c.7-1.26 1.49-2.45 2.38-3.56.89-1.11 1.85-2.15 2.91-3.1l3.43-3.1a26.29 26.29 0 0 0-5.33 6.73 28.19 28.19 0 0 0-3.04 8.35 32.074 32.074 0 0 0-.46 9.46c.15 1.61.42 3.22.81 4.82.39 1.6.89 3.19 1.49 4.76.62 1.57 1.33 3.09 2.14 4.56a38.822 38.822 0 0 0 5.99 8.11c1.17 1.22 2.42 2.35 3.74 3.39a36.466 36.466 0 0 0 8.49 5.03c1.49.63 3.01 1.13 4.55 1.53a31.16 31.16 0 0 0 6.19.95c.52.03 1.02.04 1.53.04s1.01-.02 1.52-.04 1-.07 1.5-.13c.99-.11 1.98-.27 2.95-.47.97-.2 1.92-.47 2.84-.78.93-.31 1.83-.68 2.72-1.08.89-.41 1.74-.87 2.57-1.38.05-.03.09-.06.13-.08.05-.02.09-.06.12-.08.04-.02.09-.06.12-.08.04-.02.09-.06.13-.09'/%3E%3Cpath fill='%230899a7' d='M267.365 111.939c1.68 1.36 3.24 2.86 4.66 4.48 1.42 1.62 2.7 3.35 3.83 5.16 1.13 1.82 2.1 3.73 2.9 5.71.8 1.97 1.44 4.02 1.89 6.1.33 1.56.56 3.11.67 4.67.11 1.56.13 3.1.02 4.61-.11 1.52-.31 3.03-.63 4.5-.32 1.47-.74 2.91-1.27 4.3a27.574 27.574 0 0 1-4.37 7.57c-.91 1.12-1.92 2.16-3.01 3.1-1.09.95-2.26 1.81-3.51 2.57a25.402 25.402 0 0 1-5.29 2.46c-.93.31-1.88.57-2.84.78-.96.21-1.95.37-2.95.47-.5.06-1 .1-1.5.12-.5.03-1.01.04-1.52.04s-1.02 0-1.53-.04c-.51-.03-1.03-.07-1.55-.12-1.55-.15-3.1-.43-4.64-.83-1.53-.4-3.06-.9-4.55-1.53a36.39 36.39 0 0 1-4.37-2.19c-1.42-.84-2.8-1.78-4.12-2.83a38.772 38.772 0 0 1-3.74-3.39 37.388 37.388 0 0 1-3.26-3.86c-.99-1.35-1.92-2.78-2.73-4.25-.81-1.47-1.53-3-2.14-4.57-.62-1.57-1.11-3.16-1.49-4.76-.38-1.6-.65-3.21-.81-4.82-.15-1.61-.19-3.2-.12-4.79.08-1.59.27-3.14.58-4.67.31-1.53.72-3.01 1.24-4.43s1.16-2.78 1.88-4.07c.72-1.3 1.55-2.51 2.48-3.65.93-1.14 1.93-2.2 3.02-3.15 1.09-.97 2.26-1.83 3.49-2.59a26.8 26.8 0 0 1 3.85-1.96c1.33-.55 2.72-.99 4.15-1.32 1.43-.33 2.88-.54 4.38-.64 2-.13 4.01-.05 6.01.23s3.98.75 5.93 1.41c1.95.66 3.85 1.5 5.69 2.52 1.84 1.03 3.61 2.21 5.3 3.58v.03l-.03.05Z'/%3E%3Cpath fill='%23ffffff' d='M248.495 118.529c.32-.02.64.02.95.12.31.1.6.27.85.47.25.2.48.46.66.74.18.28.31.6.38.94l2.62 12.86 12.14-1.04c.32-.03.64.02.94.12.3.1.59.26.84.46a2.943 2.943 0 0 1 1.04 1.68c.07.34.07.67.02.97-.05.3-.17.59-.33.83s-.37.45-.62.6c-.25.15-.54.25-.86.28l-12.15 1.08 2.65 13c.07.35.07.68.01.99-.06.31-.18.6-.35.85a2.066 2.066 0 0 1-1.52.9c-.33.03-.65 0-.96-.11-.31-.11-.6-.26-.86-.47-.26-.21-.49-.46-.67-.75a2.88 2.88 0 0 1-.38-.96l-2.63-13.04-12.41 1.1c-.33.03-.66-.01-.97-.12-.31-.11-.61-.26-.87-.47-.26-.21-.49-.46-.68-.75-.19-.29-.31-.61-.38-.96s-.07-.68 0-.99c.07-.31.19-.6.36-.84.17-.24.4-.45.66-.6.26-.15.56-.25.89-.28l12.4-1.07-2.61-12.9a2.315 2.315 0 0 1 .35-1.79 1.965 1.965 0 0 1 1.51-.85h-.02Z'/%3E%3C/svg%3E\"));background-repeat:no-repeat;background-position:center;background-size:contain}.mfp-dashboard__empty-title{margin-top:1rem}.mfp-dashboard__empty-description{margin:0 0 1.5rem;color:var(--sapContent_LabelColor);font-family:var(--sapFontFamily);font-size:var(--sapFontSize, 14px)}.mfp-dashboard__edit-bar{position:sticky;bottom:var(--sapShell_Space_S, 1rem);margin:var(--sapShell_Space_S, 1rem) var(--sapShell_Space_S, 1rem) 0;z-index:1000;display:flex;justify-content:flex-end;align-items:center;gap:.5rem;padding:.5rem var(--sapShell_Space_S, 1rem);background:var(--sapPageFooter_Background, white);border-radius:var(--sapElement_BorderCornerRadius, 12px);box-shadow:var(--sapContent_Shadow1, 0 0 0 1px rgba(34, 53, 72, .48), 0 2px 8px 0 rgba(34, 53, 72, .3));box-sizing:border-box;overflow:hidden}@media screen and (min-width:0px)and (max-width:599px){.mfp-dashboard{padding:calc(var(--sapShell_Space_S, 1rem) - 10px)}}@media screen and (min-width:600px)and (max-width:1023px){.mfp-dashboard{padding:calc(var(--sapShell_Space_M, 2rem) - 10px)}}@media screen and (min-width:1024px)and (max-width:1439px){.mfp-dashboard{padding:calc(var(--sapShell_Space_L, 2rem) - 10px)}}.grid-stack.grid-stack-dragging,.grid-stack.grid-stack-dragging *{cursor:grabbing!important}.mfp-dashboard__drag-origin-placeholder{position:absolute;pointer-events:none;z-index:1}.mfp-dashboard__drag-origin-placeholder:after,.mfp-dashboard__drag-origin-placeholder .mfp-dashboard__drag-origin-content{height:calc(100% - 30px);top:calc(var(--gs-item-margin-top) * 2 - 2px)!important;width:calc(100% - 19px);left:8px!important;position:absolute;border-radius:16px}.mfp-dashboard__drag-origin-placeholder .mfp-dashboard__drag-origin-content{overflow:hidden}.mfp-dashboard__drag-origin-placeholder:after{content:\"\";background:var(--sapNeutralColor, #6a6d75);opacity:.3}.grid-stack:has(>.mfp-dashboard__drag-origin-placeholder)>.grid-stack-placeholder{visibility:hidden}gridstack{position:relative}.grid-stack:has(.ui-resizable-resizing),.grid-stack:has(.ui-resizable-resizing) *{cursor:nwse-resize!important}.grid-stack-item>.ui-resizable-handle{background-image:none!important}\n"] }]
|
|
1690
|
+
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], sections: [{ type: i0.Input, args: [{ isSignal: true, alias: "sections", required: false }] }, { type: i0.Output, args: ["sectionsChange"] }], cards: [{ type: i0.Input, args: [{ isSignal: true, alias: "cards", required: false }] }, { type: i0.Output, args: ["cardsChange"] }], availableCards: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableCards", required: false }] }], customActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "customActions", required: false }] }], i18n: [{ type: i0.Input, args: [{ isSignal: true, alias: "i18n", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingDelay", required: false }] }], saved: [{ type: i0.Output, args: ["saved"] }], actionButtonClick: [{ type: i0.Output, args: ["actionButtonClick"] }], unsavedChangesChange: [{ type: i0.Output, args: ["unsavedChangesChange"] }], gridStack: [{ type: i0.ViewChild, args: ['grid', { isSignal: true }] }], dragOriginPlaceholder: [{ type: i0.ViewChild, args: ['dragOriginPlaceholder', { isSignal: true }] }], addCardBtn: [{ type: i0.ViewChild, args: ['editCardsBtn', { isSignal: true }] }] } });
|
|
1341
1691
|
|
|
1342
1692
|
/**
|
|
1343
1693
|
* Public no-argument, `void`-returning handlers on {@link Dashboard} that we
|
|
@@ -1401,10 +1751,10 @@ class SanitizeHtmlPipe {
|
|
|
1401
1751
|
}
|
|
1402
1752
|
return this.sanitizer.sanitize(SecurityContext.HTML, value) ?? '';
|
|
1403
1753
|
}
|
|
1404
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1405
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "
|
|
1754
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SanitizeHtmlPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1755
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.2", ngImport: i0, type: SanitizeHtmlPipe, isStandalone: true, name: "sanitizeHtml" });
|
|
1406
1756
|
}
|
|
1407
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1757
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SanitizeHtmlPipe, decorators: [{
|
|
1408
1758
|
type: Pipe,
|
|
1409
1759
|
args: [{
|
|
1410
1760
|
name: 'sanitizeHtml',
|
|
@@ -1413,8 +1763,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1413
1763
|
}] });
|
|
1414
1764
|
|
|
1415
1765
|
class DeleteConfirmationDialog {
|
|
1416
|
-
open = input(false,
|
|
1417
|
-
|
|
1766
|
+
open = input(false, /* @ts-ignore */
|
|
1767
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
1768
|
+
config = input(undefined, /* @ts-ignore */
|
|
1769
|
+
...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
|
|
1418
1770
|
confirmed = output();
|
|
1419
1771
|
cancelled = output();
|
|
1420
1772
|
/** Input used to confirm deletion by typing `confirmationText`. */
|
|
@@ -1422,7 +1774,8 @@ class DeleteConfirmationDialog {
|
|
|
1422
1774
|
nonNullable: true,
|
|
1423
1775
|
});
|
|
1424
1776
|
/** True when the config requires typing a confirmation phrase before deleting. */
|
|
1425
|
-
requiresConfirmation = computed(() => !!this.config()?.confirmationText,
|
|
1777
|
+
requiresConfirmation = computed(() => !!this.config()?.confirmationText, /* @ts-ignore */
|
|
1778
|
+
...(ngDevMode ? [{ debugName: "requiresConfirmation" }] : /* istanbul ignore next */ []));
|
|
1426
1779
|
/** Recomputes whenever the control's validity changes. */
|
|
1427
1780
|
status = toSignal(this.confirmationControl.statusChanges, {
|
|
1428
1781
|
initialValue: this.confirmationControl.status,
|
|
@@ -1434,7 +1787,8 @@ class DeleteConfirmationDialog {
|
|
|
1434
1787
|
return this.confirmationControl.invalid;
|
|
1435
1788
|
}
|
|
1436
1789
|
return false;
|
|
1437
|
-
},
|
|
1790
|
+
}, /* @ts-ignore */
|
|
1791
|
+
...(ngDevMode ? [{ debugName: "confirmDisabled" }] : /* istanbul ignore next */ []));
|
|
1438
1792
|
constructor() {
|
|
1439
1793
|
effect(() => {
|
|
1440
1794
|
if (!this.open()) {
|
|
@@ -1463,10 +1817,10 @@ class DeleteConfirmationDialog {
|
|
|
1463
1817
|
? null
|
|
1464
1818
|
: { confirmationMismatch: true };
|
|
1465
1819
|
}
|
|
1466
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1467
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
1820
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DeleteConfirmationDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1821
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: DeleteConfirmationDialog, isStandalone: true, selector: "mfp-delete-confirmation-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled" }, ngImport: i0, template: "<ui5-dialog\n data-testid=\"generic-table-card-delete-dialog\"\n [accessibleName]=\"config()?.title ?? 'Confirm Delete'\"\n [open]=\"open()\"\n (ui5BeforeClose)=\"cancelled.emit()\"\n>\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-icon class=\"dialog__header-icon\" design=\"Critical\" name=\"alert\" />\n <ui5-title level=\"H5\">\n <span\n [innerHTML]=\"config()?.title ?? 'Confirm Delete' | sanitizeHtml\"\n ></span>\n </ui5-title>\n </div>\n @if (config()?.message || requiresConfirmation()) {\n <div class=\"dialog__body\">\n @if (config()?.message; as message) {\n <p class=\"dialog__message\" [innerHTML]=\"message | sanitizeHtml\"></p>\n }\n @if (requiresConfirmation()) {\n <p class=\"dialog__message\">\n <ui5-input\n class=\"dialog__confirmation-input\"\n data-testid=\"generic-table-card-delete-confirmation-input\"\n [formControl]=\"confirmationControl\"\n [placeholder]=\"\n config()?.confirmationPlaceholder ?? 'Type to confirm'\n \"\n [valueState]=\"\n confirmationControl.invalid && confirmationControl.dirty\n ? 'Negative'\n : 'None'\n \"\n />\n </p>\n }\n </div>\n }\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"generic-table-card-delete-confirm\"\n design=\"Negative\"\n [disabled]=\"confirmDisabled()\"\n (click)=\"onConfirm()\"\n >\n {{ config()?.confirmLabel ?? 'Delete' }}\n </ui5-button>\n <ui5-button\n data-testid=\"generic-table-card-delete-cancel\"\n design=\"Transparent\"\n (click)=\"cancelled.emit()\"\n >\n {{ config()?.cancelLabel ?? 'Cancel' }}\n </ui5-button>\n </div>\n</ui5-dialog>\n", styles: [":host{display:contents}.dialog__header{display:flex;align-items:center;gap:.5rem;padding:.75rem 1rem}.dialog__header-icon{color:var(--sapCriticalColor)}.dialog__body{margin:-1rem;min-width:320px;padding:1rem}.dialog__message{margin:0;font-size:.875rem;max-width:320px}.dialog__message--critical{color:var(--sapCriticalElementColor)}.dialog__confirmation-input{display:block;width:100%;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: Dialog, selector: "ui5-dialog, [ui5-dialog]", inputs: ["accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "accessibleRole", "draggable", "headerText", "initialFocus", "open", "preventFocusRestore", "preventInitialFocus", "resizable", "showFullscreenButton", "state", "stretch"], outputs: ["ui5BeforeClose", "ui5BeforeOpen", "ui5Close", "ui5Open"], exportAs: ["ui5Dialog"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["level", "size", "wrappingType"], exportAs: ["ui5Title"] }, { kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Input, selector: "ui5-input, [ui5-input]", inputs: ["accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "disabled", "filter", "maxlength", "name", "noTypeahead", "open", "placeholder", "readonly", "required", "showClearIcon", "showSuggestions", "type", "value", "valueState"], outputs: ["ui5Change", "ui5Close", "ui5Input", "ui5Open", "ui5Select", "ui5SelectionChange"], exportAs: ["ui5Input"] }, { kind: "component", type: Icon, selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }, { 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: "pipe", type: SanitizeHtmlPipe, name: "sanitizeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
1468
1822
|
}
|
|
1469
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1823
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DeleteConfirmationDialog, decorators: [{
|
|
1470
1824
|
type: Component,
|
|
1471
1825
|
args: [{ selector: 'mfp-delete-confirmation-dialog', imports: [
|
|
1472
1826
|
Dialog,
|
|
@@ -1476,14 +1830,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1476
1830
|
Icon,
|
|
1477
1831
|
ReactiveFormsModule,
|
|
1478
1832
|
SanitizeHtmlPipe,
|
|
1479
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<ui5-dialog\n data-testid=\"generic-table-card-delete-dialog\"\n [accessibleName]=\"config()?.title ?? 'Confirm Delete'\"\n [open]=\"open()\"\n (ui5BeforeClose)=\"cancelled.emit()\"\n>\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-icon class=\"dialog__header-icon\"
|
|
1833
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<ui5-dialog\n data-testid=\"generic-table-card-delete-dialog\"\n [accessibleName]=\"config()?.title ?? 'Confirm Delete'\"\n [open]=\"open()\"\n (ui5BeforeClose)=\"cancelled.emit()\"\n>\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-icon class=\"dialog__header-icon\" design=\"Critical\" name=\"alert\" />\n <ui5-title level=\"H5\">\n <span\n [innerHTML]=\"config()?.title ?? 'Confirm Delete' | sanitizeHtml\"\n ></span>\n </ui5-title>\n </div>\n @if (config()?.message || requiresConfirmation()) {\n <div class=\"dialog__body\">\n @if (config()?.message; as message) {\n <p class=\"dialog__message\" [innerHTML]=\"message | sanitizeHtml\"></p>\n }\n @if (requiresConfirmation()) {\n <p class=\"dialog__message\">\n <ui5-input\n class=\"dialog__confirmation-input\"\n data-testid=\"generic-table-card-delete-confirmation-input\"\n [formControl]=\"confirmationControl\"\n [placeholder]=\"\n config()?.confirmationPlaceholder ?? 'Type to confirm'\n \"\n [valueState]=\"\n confirmationControl.invalid && confirmationControl.dirty\n ? 'Negative'\n : 'None'\n \"\n />\n </p>\n }\n </div>\n }\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"generic-table-card-delete-confirm\"\n design=\"Negative\"\n [disabled]=\"confirmDisabled()\"\n (click)=\"onConfirm()\"\n >\n {{ config()?.confirmLabel ?? 'Delete' }}\n </ui5-button>\n <ui5-button\n data-testid=\"generic-table-card-delete-cancel\"\n design=\"Transparent\"\n (click)=\"cancelled.emit()\"\n >\n {{ config()?.cancelLabel ?? 'Cancel' }}\n </ui5-button>\n </div>\n</ui5-dialog>\n", styles: [":host{display:contents}.dialog__header{display:flex;align-items:center;gap:.5rem;padding:.75rem 1rem}.dialog__header-icon{color:var(--sapCriticalColor)}.dialog__body{margin:-1rem;min-width:320px;padding:1rem}.dialog__message{margin:0;font-size:.875rem;max-width:320px}.dialog__message--critical{color:var(--sapCriticalElementColor)}.dialog__confirmation-input{display:block;width:100%;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"] }]
|
|
1480
1834
|
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], confirmed: [{ type: i0.Output, args: ["confirmed"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
|
|
1481
1835
|
|
|
1836
|
+
const FORBIDDEN_SEGMENTS = new Set(['__proto__', 'prototype', 'constructor']);
|
|
1482
1837
|
function setPropertyByPath(object, path, value) {
|
|
1483
1838
|
const segments = path.split('.').filter(Boolean);
|
|
1484
1839
|
if (segments.length === 0) {
|
|
1485
1840
|
return object;
|
|
1486
1841
|
}
|
|
1842
|
+
if (segments.some((segment) => FORBIDDEN_SEGMENTS.has(segment))) {
|
|
1843
|
+
return object;
|
|
1844
|
+
}
|
|
1487
1845
|
let current = object;
|
|
1488
1846
|
for (let i = 0; i < segments.length; i += 1) {
|
|
1489
1847
|
const key = segments[i];
|
|
@@ -1492,7 +1850,9 @@ function setPropertyByPath(object, path, value) {
|
|
|
1492
1850
|
break;
|
|
1493
1851
|
}
|
|
1494
1852
|
const existing = current[key];
|
|
1495
|
-
if (existing === undefined ||
|
|
1853
|
+
if (existing === undefined ||
|
|
1854
|
+
existing === null ||
|
|
1855
|
+
typeof existing !== 'object') {
|
|
1496
1856
|
current[key] = {};
|
|
1497
1857
|
}
|
|
1498
1858
|
current = current[key];
|
|
@@ -1511,13 +1871,17 @@ function setPropertyByPath(object, path, value) {
|
|
|
1511
1871
|
* import cycle with `DeclarativeForm`.
|
|
1512
1872
|
*/
|
|
1513
1873
|
class FormCollectionField {
|
|
1514
|
-
fields = input.required(
|
|
1515
|
-
|
|
1516
|
-
|
|
1874
|
+
fields = input.required(/* @ts-ignore */
|
|
1875
|
+
...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
|
|
1876
|
+
label = input.required(/* @ts-ignore */
|
|
1877
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1878
|
+
initialEntries = input([], /* @ts-ignore */
|
|
1879
|
+
...(ngDevMode ? [{ debugName: "initialEntries" }] : /* istanbul ignore next */ []));
|
|
1517
1880
|
valueChange = output();
|
|
1518
1881
|
entries = linkedSignal(() => [
|
|
1519
1882
|
...(this.initialEntries() ?? []),
|
|
1520
|
-
],
|
|
1883
|
+
], /* @ts-ignore */
|
|
1884
|
+
...(ngDevMode ? [{ debugName: "entries" }] : /* istanbul ignore next */ []));
|
|
1521
1885
|
expandedIndex = linkedSignal({ ...(ngDevMode ? { debugName: "expandedIndex" } : /* istanbul ignore next */ {}), source: this.initialEntries,
|
|
1522
1886
|
computation: () => null });
|
|
1523
1887
|
previewFor(entry, index) {
|
|
@@ -1557,23 +1921,27 @@ class FormCollectionField {
|
|
|
1557
1921
|
this.entries.set(next);
|
|
1558
1922
|
this.valueChange.emit(next);
|
|
1559
1923
|
}
|
|
1560
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1561
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
1924
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FormCollectionField, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1925
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", 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) {\n @let expanded = expandedIndex() === $index;\n <div\n class=\"card\"\n [attr.data-testid]=\"'collection-item-' + $index\"\n [class.card--expanded]=\"expanded\"\n >\n <button\n class=\"card__header\"\n type=\"button\"\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 accessibleName=\"Remove\"\n class=\"card__action\"\n design=\"Transparent\"\n icon=\"delete\"\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 accessibleName=\"Add\"\n class=\"collection__add\"\n data-testid=\"collection-add\"\n design=\"Transparent\"\n icon=\"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:var(--sapContent_Shadow0, 0 1px 2px rgba(0, 0, 0, .04))}.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: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: i0.forwardRef(() => Icon), selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], 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 });
|
|
1562
1926
|
}
|
|
1563
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1927
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FormCollectionField, decorators: [{
|
|
1564
1928
|
type: Component,
|
|
1565
|
-
args: [{ selector: 'mfp-form-collection-field',
|
|
1929
|
+
args: [{ selector: 'mfp-form-collection-field', imports: [Button, Icon, forwardRef(() => DeclarativeForm)], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, template: "<div class=\"collection\" data-testid=\"collection-field\">\n @for (entry of entries(); track $index) {\n @let expanded = expandedIndex() === $index;\n <div\n class=\"card\"\n [attr.data-testid]=\"'collection-item-' + $index\"\n [class.card--expanded]=\"expanded\"\n >\n <button\n class=\"card__header\"\n type=\"button\"\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 accessibleName=\"Remove\"\n class=\"card__action\"\n design=\"Transparent\"\n icon=\"delete\"\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 accessibleName=\"Add\"\n class=\"collection__add\"\n data-testid=\"collection-add\"\n design=\"Transparent\"\n icon=\"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:var(--sapContent_Shadow0, 0 1px 2px rgba(0, 0, 0, .04))}.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"] }]
|
|
1566
1930
|
}], 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"] }] } });
|
|
1567
1931
|
|
|
1568
1932
|
class DeclarativeForm {
|
|
1569
|
-
fields = input
|
|
1570
|
-
|
|
1571
|
-
|
|
1933
|
+
fields = input([], /* @ts-ignore */
|
|
1934
|
+
...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
|
|
1935
|
+
initialValues = input({}, /* @ts-ignore */
|
|
1936
|
+
...(ngDevMode ? [{ debugName: "initialValues" }] : /* istanbul ignore next */ []));
|
|
1937
|
+
fieldErrors = input({}, /* @ts-ignore */
|
|
1938
|
+
...(ngDevMode ? [{ debugName: "fieldErrors" }] : /* istanbul ignore next */ []));
|
|
1572
1939
|
fieldChange = output();
|
|
1573
1940
|
formSubmit = output();
|
|
1574
1941
|
formValueChange = output();
|
|
1575
1942
|
form;
|
|
1576
|
-
collectionSeeds = signal({},
|
|
1943
|
+
collectionSeeds = signal({}, /* @ts-ignore */
|
|
1944
|
+
...(ngDevMode ? [{ debugName: "collectionSeeds" }] : /* istanbul ignore next */ []));
|
|
1577
1945
|
fb = inject(FormBuilder);
|
|
1578
1946
|
constructor() {
|
|
1579
1947
|
this.form = this.fb.group({});
|
|
@@ -1727,10 +2095,10 @@ class DeclarativeForm {
|
|
|
1727
2095
|
entry: new FormControl(entry),
|
|
1728
2096
|
});
|
|
1729
2097
|
}
|
|
1730
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1731
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2098
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DeclarativeForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2099
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: DeclarativeForm, isStandalone: true, selector: "mfp-declarative-form", inputs: { fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, 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 [attr.for]=\"'generic-form-field-input-' + 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 [initialEntries]=\"collectionEntries(field)\"\n [label]=\"field.label\"\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 [id]=\"'generic-form-field-input-' + field.name\"\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 [id]=\"'generic-form-field-input-' + field.name\"\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: ["accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "disabled", "filter", "maxlength", "name", "noTypeahead", "open", "placeholder", "readonly", "required", "showClearIcon", "showSuggestions", "type", "value", "valueState"], outputs: ["ui5Change", "ui5Close", "ui5Input", "ui5Open", "ui5Select", "ui5SelectionChange"], exportAs: ["ui5Input"] }, { kind: "component", type: Label, selector: "ui5-label, [ui5-label]", inputs: ["for", "required", "showColon", "wrappingType"], exportAs: ["ui5Label"] }, { kind: "component", type: Select, selector: "ui5-select, [ui5-select]", inputs: ["accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "disabled", "name", "readonly", "required", "textSeparator", "tooltip", "value", "valueState"], outputs: ["ui5Change", "ui5Close", "ui5LiveChange", "ui5Open"], exportAs: ["ui5Select"] }, { kind: "component", type: Option, selector: "ui5-option, [ui5-option]", inputs: ["additionalText", "icon", "selected", "tooltip", "value"], outputs: ["ui5Click"], exportAs: ["ui5Option"] }, { kind: "component", type: FormCollectionField, selector: "mfp-form-collection-field", inputs: ["fields", "label", "initialEntries"], outputs: ["valueChange"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
1732
2100
|
}
|
|
1733
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2101
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DeclarativeForm, decorators: [{
|
|
1734
2102
|
type: Component,
|
|
1735
2103
|
args: [{ selector: 'mfp-declarative-form', imports: [
|
|
1736
2104
|
ReactiveFormsModule,
|
|
@@ -1739,32 +2107,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1739
2107
|
Select,
|
|
1740
2108
|
Option,
|
|
1741
2109
|
FormCollectionField,
|
|
1742
|
-
], 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 [
|
|
1743
|
-
}], ctorParameters: () => [], propDecorators: { fields: [{ type: i0.Input, args: [{ isSignal: true, alias: "fields", required:
|
|
2110
|
+
], 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 [attr.for]=\"'generic-form-field-input-' + 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 [initialEntries]=\"collectionEntries(field)\"\n [label]=\"field.label\"\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 [id]=\"'generic-form-field-input-' + field.name\"\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 [id]=\"'generic-form-field-input-' + field.name\"\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"] }]
|
|
2111
|
+
}], ctorParameters: () => [], propDecorators: { fields: [{ type: i0.Input, args: [{ isSignal: true, alias: "fields", required: false }] }], 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"] }] } });
|
|
1744
2112
|
|
|
1745
2113
|
class ResourceFormDialog {
|
|
1746
|
-
open = input(false,
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
2114
|
+
open = input(false, /* @ts-ignore */
|
|
2115
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
2116
|
+
config = input(undefined, /* @ts-ignore */
|
|
2117
|
+
...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
|
|
2118
|
+
fields = input([], /* @ts-ignore */
|
|
2119
|
+
...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
|
|
2120
|
+
fieldErrors = input({}, /* @ts-ignore */
|
|
2121
|
+
...(ngDevMode ? [{ debugName: "fieldErrors" }] : /* istanbul ignore next */ []));
|
|
2122
|
+
initialValues = input({}, /* @ts-ignore */
|
|
2123
|
+
...(ngDevMode ? [{ debugName: "initialValues" }] : /* istanbul ignore next */ []));
|
|
2124
|
+
defaultTitle = input('Create', /* @ts-ignore */
|
|
2125
|
+
...(ngDevMode ? [{ debugName: "defaultTitle" }] : /* istanbul ignore next */ []));
|
|
2126
|
+
defaultConfirmLabel = input('Save', /* @ts-ignore */
|
|
2127
|
+
...(ngDevMode ? [{ debugName: "defaultConfirmLabel" }] : /* istanbul ignore next */ []));
|
|
2128
|
+
defaultCancelLabel = input('Cancel', /* @ts-ignore */
|
|
2129
|
+
...(ngDevMode ? [{ debugName: "defaultCancelLabel" }] : /* istanbul ignore next */ []));
|
|
2130
|
+
dataTestidPrefix = input('generic-table-card-create', /* @ts-ignore */
|
|
2131
|
+
...(ngDevMode ? [{ debugName: "dataTestidPrefix" }] : /* istanbul ignore next */ []));
|
|
1755
2132
|
fieldChange = output();
|
|
1756
2133
|
submitted = output();
|
|
1757
2134
|
cancelled = output();
|
|
1758
2135
|
hasErrors = computed(() => {
|
|
1759
2136
|
const errors = this.fieldErrors();
|
|
1760
2137
|
return !!errors && Object.values(errors).some((val) => !!val);
|
|
1761
|
-
},
|
|
1762
|
-
|
|
1763
|
-
static
|
|
2138
|
+
}, /* @ts-ignore */
|
|
2139
|
+
...(ngDevMode ? [{ debugName: "hasErrors" }] : /* istanbul ignore next */ []));
|
|
2140
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ResourceFormDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2141
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.2", type: ResourceFormDialog, isStandalone: true, selector: "mfp-resource-form-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, fieldErrors: { classPropertyName: "fieldErrors", publicName: "fieldErrors", isSignal: true, isRequired: false, transformFunction: null }, initialValues: { classPropertyName: "initialValues", publicName: "initialValues", isSignal: true, isRequired: false, transformFunction: null }, defaultTitle: { classPropertyName: "defaultTitle", publicName: "defaultTitle", isSignal: true, isRequired: false, transformFunction: null }, defaultConfirmLabel: { classPropertyName: "defaultConfirmLabel", publicName: "defaultConfirmLabel", isSignal: true, isRequired: false, transformFunction: null }, defaultCancelLabel: { classPropertyName: "defaultCancelLabel", publicName: "defaultCancelLabel", isSignal: true, isRequired: false, transformFunction: null }, dataTestidPrefix: { classPropertyName: "dataTestidPrefix", publicName: "dataTestidPrefix", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fieldChange: "fieldChange", submitted: "submitted", cancelled: "cancelled" }, ngImport: i0, template: "<ui5-dialog\n [accessibleName]=\"config()?.title ?? defaultTitle()\"\n [attr.data-testid]=\"dataTestidPrefix() + '-dialog'\"\n [open]=\"open()\"\n (ui5BeforeClose)=\"cancelled.emit()\"\n>\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">\n <span\n [innerHTML]=\"config()?.title ?? defaultTitle() | sanitizeHtml\"\n ></span>\n </ui5-title>\n </div>\n <div class=\"dialog__body\">\n <mfp-declarative-form\n #form\n [fieldErrors]=\"fieldErrors()\"\n [fields]=\"fields()\"\n [initialValues]=\"initialValues()\"\n (fieldChange)=\"fieldChange.emit($event)\"\n (formSubmit)=\"submitted.emit($event)\"\n />\n </div>\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button\n design=\"Emphasized\"\n [attr.data-testid]=\"dataTestidPrefix() + '-confirm'\"\n [disabled]=\"hasErrors()\"\n (click)=\"form.submit()\"\n >\n {{ config()?.confirmLabel ?? defaultConfirmLabel() }}\n </ui5-button>\n <ui5-button\n design=\"Transparent\"\n [attr.data-testid]=\"dataTestidPrefix() + '-cancel'\"\n (click)=\"cancelled.emit()\"\n >\n {{ config()?.cancelLabel ?? defaultCancelLabel() }}\n </ui5-button>\n </div>\n</ui5-dialog>\n", styles: [":host{display:contents}.dialog__header{display:flex;align-items:flex-start;padding:.75rem 1rem}.dialog__body{margin:-1rem;min-width:320px;padding:1rem}.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: Dialog, selector: "ui5-dialog, [ui5-dialog]", inputs: ["accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "accessibleRole", "draggable", "headerText", "initialFocus", "open", "preventFocusRestore", "preventInitialFocus", "resizable", "showFullscreenButton", "state", "stretch"], outputs: ["ui5BeforeClose", "ui5BeforeOpen", "ui5Close", "ui5Open"], exportAs: ["ui5Dialog"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["level", "size", "wrappingType"], exportAs: ["ui5Title"] }, { kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: DeclarativeForm, selector: "mfp-declarative-form", inputs: ["fields", "initialValues", "fieldErrors"], outputs: ["fieldChange", "formSubmit", "formValueChange"] }, { kind: "pipe", type: SanitizeHtmlPipe, name: "sanitizeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
1764
2142
|
}
|
|
1765
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2143
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ResourceFormDialog, decorators: [{
|
|
1766
2144
|
type: Component,
|
|
1767
|
-
args: [{ selector: 'mfp-resource-form-dialog', imports: [Dialog, Title, Button, DeclarativeForm, SanitizeHtmlPipe], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<ui5-dialog\n [
|
|
2145
|
+
args: [{ selector: 'mfp-resource-form-dialog', imports: [Dialog, Title, Button, DeclarativeForm, SanitizeHtmlPipe], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<ui5-dialog\n [accessibleName]=\"config()?.title ?? defaultTitle()\"\n [attr.data-testid]=\"dataTestidPrefix() + '-dialog'\"\n [open]=\"open()\"\n (ui5BeforeClose)=\"cancelled.emit()\"\n>\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">\n <span\n [innerHTML]=\"config()?.title ?? defaultTitle() | sanitizeHtml\"\n ></span>\n </ui5-title>\n </div>\n <div class=\"dialog__body\">\n <mfp-declarative-form\n #form\n [fieldErrors]=\"fieldErrors()\"\n [fields]=\"fields()\"\n [initialValues]=\"initialValues()\"\n (fieldChange)=\"fieldChange.emit($event)\"\n (formSubmit)=\"submitted.emit($event)\"\n />\n </div>\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button\n design=\"Emphasized\"\n [attr.data-testid]=\"dataTestidPrefix() + '-confirm'\"\n [disabled]=\"hasErrors()\"\n (click)=\"form.submit()\"\n >\n {{ config()?.confirmLabel ?? defaultConfirmLabel() }}\n </ui5-button>\n <ui5-button\n design=\"Transparent\"\n [attr.data-testid]=\"dataTestidPrefix() + '-cancel'\"\n (click)=\"cancelled.emit()\"\n >\n {{ config()?.cancelLabel ?? defaultCancelLabel() }}\n </ui5-button>\n </div>\n</ui5-dialog>\n", styles: [":host{display:contents}.dialog__header{display:flex;align-items:flex-start;padding:.75rem 1rem}.dialog__body{margin:-1rem;min-width:320px;padding:1rem}.dialog__footer{display:flex;justify-content:space-between;align-items:center;gap:.5rem;padding:.5rem 1rem;margin:0 -1rem;width:100%}\n"] }]
|
|
1768
2146
|
}], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], fields: [{ type: i0.Input, args: [{ isSignal: true, alias: "fields", required: false }] }], fieldErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldErrors", required: false }] }], initialValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialValues", required: false }] }], defaultTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultTitle", required: false }] }], defaultConfirmLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultConfirmLabel", required: false }] }], defaultCancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultCancelLabel", required: false }] }], dataTestidPrefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataTestidPrefix", required: false }] }], fieldChange: [{ type: i0.Output, args: ["fieldChange"] }], submitted: [{ type: i0.Output, args: ["submitted"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
|
|
1769
2147
|
|
|
1770
2148
|
const getResourceValueByJsonPath = (resource, field) => {
|
|
@@ -1929,34 +2307,40 @@ const ICON_NAME_POSITIVE = 'accept';
|
|
|
1929
2307
|
const ICON_NAME_NEGATIVE = 'decline';
|
|
1930
2308
|
|
|
1931
2309
|
class BooleanValue {
|
|
1932
|
-
boolValue = input.required(
|
|
1933
|
-
|
|
2310
|
+
boolValue = input.required(/* @ts-ignore */
|
|
2311
|
+
...(ngDevMode ? [{ debugName: "boolValue" }] : /* istanbul ignore next */ []));
|
|
2312
|
+
testId = input('boolean-value-icon', /* @ts-ignore */
|
|
2313
|
+
...(ngDevMode ? [{ debugName: "testId" }] : /* istanbul ignore next */ []));
|
|
1934
2314
|
iconDesign = computed(() => {
|
|
1935
2315
|
return this.boolValue() ? ICON_DESIGN_POSITIVE : ICON_DESIGN_NEGATIVE;
|
|
1936
|
-
},
|
|
2316
|
+
}, /* @ts-ignore */
|
|
2317
|
+
...(ngDevMode ? [{ debugName: "iconDesign" }] : /* istanbul ignore next */ []));
|
|
1937
2318
|
iconName = computed(() => {
|
|
1938
2319
|
return this.boolValue() ? ICON_NAME_POSITIVE : ICON_NAME_NEGATIVE;
|
|
1939
|
-
},
|
|
1940
|
-
|
|
1941
|
-
static
|
|
2320
|
+
}, /* @ts-ignore */
|
|
2321
|
+
...(ngDevMode ? [{ debugName: "iconName" }] : /* istanbul ignore next */ []));
|
|
2322
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: BooleanValue, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2323
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.2", type: BooleanValue, isStandalone: true, selector: "mfp-boolean-value", inputs: { boolValue: { classPropertyName: "boolValue", publicName: "boolValue", isSignal: true, isRequired: true, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ui5-icon\n [attr.data-testid]=\"testId()\"\n [design]=\"iconDesign()\"\n [name]=\"iconName()\"\n/>\n", styles: [""], dependencies: [{ kind: "component", type: Icon, selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1942
2324
|
}
|
|
1943
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2325
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: BooleanValue, decorators: [{
|
|
1944
2326
|
type: Component,
|
|
1945
|
-
args: [{ selector: 'mfp-boolean-value', imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<ui5-icon
|
|
2327
|
+
args: [{ selector: 'mfp-boolean-value', imports: [Icon], changeDetection: ChangeDetectionStrategy.OnPush, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<ui5-icon\n [attr.data-testid]=\"testId()\"\n [design]=\"iconDesign()\"\n [name]=\"iconName()\"\n/>\n" }]
|
|
1946
2328
|
}], propDecorators: { boolValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "boolValue", required: true }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", required: false }] }] } });
|
|
1947
2329
|
|
|
1948
2330
|
class LinkValue {
|
|
1949
|
-
urlValue = input.required(
|
|
1950
|
-
|
|
2331
|
+
urlValue = input.required(/* @ts-ignore */
|
|
2332
|
+
...(ngDevMode ? [{ debugName: "urlValue" }] : /* istanbul ignore next */ []));
|
|
2333
|
+
testId = input('link-value-link', /* @ts-ignore */
|
|
2334
|
+
...(ngDevMode ? [{ debugName: "testId" }] : /* istanbul ignore next */ []));
|
|
1951
2335
|
stopPropagation(event) {
|
|
1952
2336
|
event.stopPropagation();
|
|
1953
2337
|
}
|
|
1954
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1955
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
2338
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: LinkValue, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2339
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.2", type: LinkValue, isStandalone: true, selector: "mfp-link-value", inputs: { urlValue: { classPropertyName: "urlValue", publicName: "urlValue", isSignal: true, isRequired: true, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ui5-link\n target=\"_blank\"\n [attr.data-testid]=\"testId()\"\n [href]=\"urlValue()\"\n [tooltip]=\"urlValue()\"\n (click)=\"stopPropagation($event)\"\n >Link</ui5-link\n>\n", styles: [""], dependencies: [{ kind: "component", type: Link, selector: "ui5-link, [ui5-link]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "href", "icon", "interactiveAreaSize", "target", "tooltip", "wrappingType"], outputs: ["ui5Click"], exportAs: ["ui5Link"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1956
2340
|
}
|
|
1957
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2341
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: LinkValue, decorators: [{
|
|
1958
2342
|
type: Component,
|
|
1959
|
-
args: [{ selector: 'mfp-link-value', imports: [Link], changeDetection: ChangeDetectionStrategy.OnPush, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<ui5-link\n target=\"_blank\"\n [attr.data-testid]=\"testId()\"\n [href]=\"urlValue()\"\n [tooltip]=\"urlValue()\"\n (click)=\"stopPropagation($event)\"\n>Link</ui5-link>\n" }]
|
|
2343
|
+
args: [{ selector: 'mfp-link-value', imports: [Link], changeDetection: ChangeDetectionStrategy.OnPush, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<ui5-link\n target=\"_blank\"\n [attr.data-testid]=\"testId()\"\n [href]=\"urlValue()\"\n [tooltip]=\"urlValue()\"\n (click)=\"stopPropagation($event)\"\n >Link</ui5-link\n>\n" }]
|
|
1960
2344
|
}], propDecorators: { urlValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "urlValue", required: true }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", required: false }] }] } });
|
|
1961
2345
|
|
|
1962
2346
|
/**
|
|
@@ -1967,19 +2351,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
1967
2351
|
* `mfp-form-collection-field`.
|
|
1968
2352
|
*/
|
|
1969
2353
|
class ResourceCollectionField {
|
|
1970
|
-
fieldDefinition = input.required(
|
|
1971
|
-
|
|
1972
|
-
|
|
2354
|
+
fieldDefinition = input.required(/* @ts-ignore */
|
|
2355
|
+
...(ngDevMode ? [{ debugName: "fieldDefinition" }] : /* istanbul ignore next */ []));
|
|
2356
|
+
resource = input(/* @ts-ignore */
|
|
2357
|
+
...(ngDevMode ? [undefined, { debugName: "resource" }] : /* istanbul ignore next */ []));
|
|
2358
|
+
expandedIndex = signal(null, /* @ts-ignore */
|
|
2359
|
+
...(ngDevMode ? [{ debugName: "expandedIndex" }] : /* istanbul ignore next */ []));
|
|
1973
2360
|
collectionPath = computed(() => {
|
|
1974
2361
|
const property = this.fieldDefinition().property;
|
|
1975
2362
|
return typeof property === 'string' ? property : undefined;
|
|
1976
|
-
},
|
|
2363
|
+
}, /* @ts-ignore */
|
|
2364
|
+
...(ngDevMode ? [{ debugName: "collectionPath" }] : /* istanbul ignore next */ []));
|
|
1977
2365
|
entries = computed(() => {
|
|
1978
2366
|
const value = getResourceValueByJsonPath(this.resource() ?? {}, {
|
|
1979
2367
|
property: this.collectionPath(),
|
|
1980
2368
|
});
|
|
1981
2369
|
return Array.isArray(value) ? value : [];
|
|
1982
|
-
},
|
|
2370
|
+
}, /* @ts-ignore */
|
|
2371
|
+
...(ngDevMode ? [{ debugName: "entries" }] : /* istanbul ignore next */ []));
|
|
1983
2372
|
rows = computed(() => {
|
|
1984
2373
|
const parent = this.collectionPath();
|
|
1985
2374
|
return (this.fieldDefinition().propertyCollection ?? []).map((sub) => {
|
|
@@ -1991,7 +2380,8 @@ class ResourceCollectionField {
|
|
|
1991
2380
|
field: { ...sub, property },
|
|
1992
2381
|
};
|
|
1993
2382
|
});
|
|
1994
|
-
},
|
|
2383
|
+
}, /* @ts-ignore */
|
|
2384
|
+
...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
1995
2385
|
toggle(index, event) {
|
|
1996
2386
|
event?.stopPropagation();
|
|
1997
2387
|
this.expandedIndex.set(this.expandedIndex() === index ? null : index);
|
|
@@ -2022,72 +2412,102 @@ class ResourceCollectionField {
|
|
|
2022
2412
|
const segments = property.split('.');
|
|
2023
2413
|
return segments[segments.length - 1];
|
|
2024
2414
|
}
|
|
2025
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2026
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2415
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ResourceCollectionField, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2416
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: ResourceCollectionField, isStandalone: true, selector: "mfp-resource-collection-field", inputs: { fieldDefinition: { classPropertyName: "fieldDefinition", publicName: "fieldDefinition", isSignal: true, isRequired: true, transformFunction: null }, resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"collection\" data-testid=\"resource-collection-field\">\n @for (entry of entries(); track $index; let index = $index) {\n @let expanded = expandedIndex() === index;\n <div\n class=\"card\"\n [attr.data-testid]=\"'resource-collection-item-' + index\"\n [class.card--expanded]=\"expanded\"\n >\n <button\n class=\"card__header\"\n type=\"button\"\n [attr.aria-expanded]=\"expanded\"\n [attr.data-testid]=\"'resource-collection-item-' + index + '-toggle'\"\n (click)=\"toggle(index, $event)\"\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 </button>\n\n @if (expanded) {\n <!-- Not an interactive control: the click guard only stops expanded-card\n clicks from bubbling to the enclosing clickable `ui5-table-row`\n (`onRowClick`). No keyboard/focus semantics are needed. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"card__body\" (click)=\"$event.stopPropagation()\">\n @for (row of rows(); track row.field.property) {\n <div class=\"row\">\n <span class=\"row__label\">{{ row.label }}:</span>\n <mfp-resource-field\n [fieldDefinition]=\"row.field\"\n [resource]=\"entry\"\n />\n </div>\n }\n </div>\n }\n </div>\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:var(--sapContent_Shadow0, 0 1px 2px rgba(0, 0, 0, .04))}.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__body{display:flex;flex-direction:column;gap:.5rem;padding:.75rem 1rem 1rem;border-top:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9)}.row{display:flex;gap:.25rem;align-items:baseline}.row__label{font-weight:500;color:var(--sapContent_LabelColor, #556b82);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => Icon), selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }, { kind: "component", type: i0.forwardRef(() => ResourceField), selector: "mfp-resource-field", inputs: ["fieldDefinition", "resource", "permissions"], outputs: ["buttonClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2027
2417
|
}
|
|
2028
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2418
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ResourceCollectionField, decorators: [{
|
|
2029
2419
|
type: Component,
|
|
2030
|
-
args: [{ selector: 'mfp-resource-collection-field', imports: [Icon, forwardRef(() => ResourceField)], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"collection\" data-testid=\"resource-collection-field\">\n @for (entry of entries(); track $index; let index = $index) {\n @let expanded = expandedIndex() === index;\n <div\n class=\"card\"\n [
|
|
2420
|
+
args: [{ selector: 'mfp-resource-collection-field', imports: [Icon, forwardRef(() => ResourceField)], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"collection\" data-testid=\"resource-collection-field\">\n @for (entry of entries(); track $index; let index = $index) {\n @let expanded = expandedIndex() === index;\n <div\n class=\"card\"\n [attr.data-testid]=\"'resource-collection-item-' + index\"\n [class.card--expanded]=\"expanded\"\n >\n <button\n class=\"card__header\"\n type=\"button\"\n [attr.aria-expanded]=\"expanded\"\n [attr.data-testid]=\"'resource-collection-item-' + index + '-toggle'\"\n (click)=\"toggle(index, $event)\"\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 </button>\n\n @if (expanded) {\n <!-- Not an interactive control: the click guard only stops expanded-card\n clicks from bubbling to the enclosing clickable `ui5-table-row`\n (`onRowClick`). No keyboard/focus semantics are needed. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"card__body\" (click)=\"$event.stopPropagation()\">\n @for (row of rows(); track row.field.property) {\n <div class=\"row\">\n <span class=\"row__label\">{{ row.label }}:</span>\n <mfp-resource-field\n [fieldDefinition]=\"row.field\"\n [resource]=\"entry\"\n />\n </div>\n }\n </div>\n }\n </div>\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:var(--sapContent_Shadow0, 0 1px 2px rgba(0, 0, 0, .04))}.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__body{display:flex;flex-direction:column;gap:.5rem;padding:.75rem 1rem 1rem;border-top:1px solid var(--sapGroup_ContentBorderColor, #d9d9d9)}.row{display:flex;gap:.25rem;align-items:baseline}.row__label{font-weight:500;color:var(--sapContent_LabelColor, #556b82);white-space:nowrap}\n"] }]
|
|
2031
2421
|
}], propDecorators: { fieldDefinition: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldDefinition", required: true }] }], resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: false }] }] } });
|
|
2032
2422
|
|
|
2033
2423
|
class SecretValue {
|
|
2034
|
-
value = input.required(
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2424
|
+
value = input.required(/* @ts-ignore */
|
|
2425
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
2426
|
+
isVisible = input(false, /* @ts-ignore */
|
|
2427
|
+
...(ngDevMode ? [{ debugName: "isVisible" }] : /* istanbul ignore next */ []));
|
|
2428
|
+
testId = input('secret-value', /* @ts-ignore */
|
|
2429
|
+
...(ngDevMode ? [{ debugName: "testId" }] : /* istanbul ignore next */ []));
|
|
2430
|
+
maskedValue = computed(() => '*'.repeat(this.value()?.length || 8), /* @ts-ignore */
|
|
2431
|
+
...(ngDevMode ? [{ debugName: "maskedValue" }] : /* istanbul ignore next */ []));
|
|
2432
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SecretValue, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2433
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: SecretValue, isStandalone: true, selector: "mfp-secret-value", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, isVisible: { classPropertyName: "isVisible", publicName: "isVisible", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span\n class=\"secret-value\"\n [attr.data-testid]=\"testId()\"\n [class.masked]=\"!isVisible()\"\n>\n @if (isVisible()) {\n {{ value() }}\n } @else {\n {{ maskedValue() }}\n }\n</span>\n", styles: [".secret-value{display:inline-flex;align-items:center;gap:.25rem}.masked{transform:translateY(.2em);display:flex}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2434
|
+
}
|
|
2435
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SecretValue, decorators: [{
|
|
2042
2436
|
type: Component,
|
|
2043
|
-
args: [{ selector: 'mfp-secret-value', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, schemas: [], template: "<span
|
|
2437
|
+
args: [{ selector: 'mfp-secret-value', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, schemas: [], template: "<span\n class=\"secret-value\"\n [attr.data-testid]=\"testId()\"\n [class.masked]=\"!isVisible()\"\n>\n @if (isVisible()) {\n {{ value() }}\n } @else {\n {{ maskedValue() }}\n }\n</span>\n", styles: [".secret-value{display:inline-flex;align-items:center;gap:.25rem}.masked{transform:translateY(.2em);display:flex}\n"] }]
|
|
2044
2438
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], isVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "isVisible", required: false }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", required: false }] }] } });
|
|
2045
2439
|
|
|
2046
2440
|
class TagListValue {
|
|
2047
|
-
tags = input.required(
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2441
|
+
tags = input.required(/* @ts-ignore */
|
|
2442
|
+
...(ngDevMode ? [{ debugName: "tags" }] : /* istanbul ignore next */ []));
|
|
2443
|
+
tagSettings = input(/* @ts-ignore */
|
|
2444
|
+
...(ngDevMode ? [undefined, { debugName: "tagSettings" }] : /* istanbul ignore next */ []));
|
|
2445
|
+
testId = input('tag-list-value', /* @ts-ignore */
|
|
2446
|
+
...(ngDevMode ? [{ debugName: "testId" }] : /* istanbul ignore next */ []));
|
|
2447
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: TagListValue, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2448
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: TagListValue, isStandalone: true, selector: "mfp-tag-list-value", inputs: { tags: { classPropertyName: "tags", publicName: "tags", isSignal: true, isRequired: true, transformFunction: null }, tagSettings: { classPropertyName: "tagSettings", publicName: "tagSettings", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span class=\"tag-list\" [attr.data-testid]=\"testId()\">\n @for (tag of tags(); track $index) {\n <ui5-tag\n [colorScheme]=\"tagSettings()?.colorScheme\"\n [design]=\"tagSettings()?.design ?? 'Neutral'\"\n [hideStateIcon]=\"true\"\n >{{ tag }}</ui5-tag\n >\n }\n</span>\n", styles: [":host{display:inline-flex}.tag-list{display:flex;flex-wrap:wrap;gap:4px}\n"], dependencies: [{ kind: "component", type: Tag, selector: "ui5-tag, [ui5-tag]", inputs: ["colorScheme", "design", "hideStateIcon", "interactive", "size", "wrappingType"], outputs: ["ui5Click"], exportAs: ["ui5Tag"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2052
2449
|
}
|
|
2053
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2450
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: TagListValue, decorators: [{
|
|
2054
2451
|
type: Component,
|
|
2055
|
-
args: [{ selector: 'mfp-tag-list-value', imports: [Tag], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"tag-list\" [attr.data-testid]=\"testId()\">\n @for (tag of tags(); track $index) {\n <ui5-tag\n [colorScheme]=\"tagSettings()?.colorScheme\"\n [design]=\"tagSettings()?.design ?? 'Neutral'\"\n [hideStateIcon]=\"true\"\n
|
|
2452
|
+
args: [{ selector: 'mfp-tag-list-value', imports: [Tag], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"tag-list\" [attr.data-testid]=\"testId()\">\n @for (tag of tags(); track $index) {\n <ui5-tag\n [colorScheme]=\"tagSettings()?.colorScheme\"\n [design]=\"tagSettings()?.design ?? 'Neutral'\"\n [hideStateIcon]=\"true\"\n >{{ tag }}</ui5-tag\n >\n }\n</span>\n", styles: [":host{display:inline-flex}.tag-list{display:flex;flex-wrap:wrap;gap:4px}\n"] }]
|
|
2056
2453
|
}], propDecorators: { tags: [{ type: i0.Input, args: [{ isSignal: true, alias: "tags", required: true }] }], tagSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "tagSettings", required: false }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", required: false }] }] } });
|
|
2057
2454
|
|
|
2058
2455
|
class ResourceField {
|
|
2059
|
-
fieldDefinition = input.required(
|
|
2060
|
-
|
|
2456
|
+
fieldDefinition = input.required(/* @ts-ignore */
|
|
2457
|
+
...(ngDevMode ? [{ debugName: "fieldDefinition" }] : /* istanbul ignore next */ []));
|
|
2458
|
+
resource = input(/* @ts-ignore */
|
|
2459
|
+
...(ngDevMode ? [undefined, { debugName: "resource" }] : /* istanbul ignore next */ []));
|
|
2061
2460
|
// keyed by row id; host sets row.id = permissionKey(entity/ns/name)
|
|
2062
|
-
permissions = input(
|
|
2461
|
+
permissions = input(/* @ts-ignore */
|
|
2462
|
+
...(ngDevMode ? [undefined, { debugName: "permissions" }] : /* istanbul ignore next */ []));
|
|
2063
2463
|
buttonClick = output();
|
|
2064
|
-
value = computed(() => getFieldValue(this.fieldDefinition(), this.resource()),
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2464
|
+
value = computed(() => getFieldValue(this.fieldDefinition(), this.resource()), /* @ts-ignore */
|
|
2465
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
2466
|
+
uiSettings = computed(() => this.fieldDefinition().uiSettings, /* @ts-ignore */
|
|
2467
|
+
...(ngDevMode ? [{ debugName: "uiSettings" }] : /* istanbul ignore next */ []));
|
|
2468
|
+
displayAs = computed(() => this.uiSettings()?.displayAs, /* @ts-ignore */
|
|
2469
|
+
...(ngDevMode ? [{ debugName: "displayAs" }] : /* istanbul ignore next */ []));
|
|
2470
|
+
withCopyButton = computed(() => this.uiSettings()?.withCopyButton, /* @ts-ignore */
|
|
2471
|
+
...(ngDevMode ? [{ debugName: "withCopyButton" }] : /* istanbul ignore next */ []));
|
|
2472
|
+
cssCustomization = computed(() => this.uiSettings()?.cssCustomization, /* @ts-ignore */
|
|
2473
|
+
...(ngDevMode ? [{ debugName: "cssCustomization" }] : /* istanbul ignore next */ []));
|
|
2474
|
+
tooltipIcon = computed(() => this.uiSettings()?.tooltipIcon, /* @ts-ignore */
|
|
2475
|
+
...(ngDevMode ? [{ debugName: "tooltipIcon" }] : /* istanbul ignore next */ []));
|
|
2476
|
+
cssRules = computed(() => evaluateCssRules(this.value(), this.uiSettings()?.cssRules), /* @ts-ignore */
|
|
2477
|
+
...(ngDevMode ? [{ debugName: "cssRules" }] : /* istanbul ignore next */ []));
|
|
2071
2478
|
cssStyles = computed(() => ({
|
|
2072
2479
|
...this.cssCustomization(),
|
|
2073
2480
|
...this.cssRules(),
|
|
2074
|
-
}),
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2481
|
+
}), /* @ts-ignore */
|
|
2482
|
+
...(ngDevMode ? [{ debugName: "cssStyles" }] : /* istanbul ignore next */ []));
|
|
2483
|
+
displayValue = computed(() => evaluateValueRules(this.value() ?? '', this.uiSettings()?.valueRules), /* @ts-ignore */
|
|
2484
|
+
...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
|
|
2485
|
+
isBoolLike = computed(() => this.boolValue() !== undefined, /* @ts-ignore */
|
|
2486
|
+
...(ngDevMode ? [{ debugName: "isBoolLike" }] : /* istanbul ignore next */ []));
|
|
2487
|
+
isUrlValue = computed(() => this.checkValidUrl(this.stringValue()), /* @ts-ignore */
|
|
2488
|
+
...(ngDevMode ? [{ debugName: "isUrlValue" }] : /* istanbul ignore next */ []));
|
|
2489
|
+
testId = computed(() => `resource-field-${this.fieldDefinition().property}`, /* @ts-ignore */
|
|
2490
|
+
...(ngDevMode ? [{ debugName: "testId" }] : /* istanbul ignore next */ []));
|
|
2491
|
+
buttonDisabled = computed(() => this.resource()?.isAvailable === false, /* @ts-ignore */
|
|
2492
|
+
...(ngDevMode ? [{ debugName: "buttonDisabled" }] : /* istanbul ignore next */ []));
|
|
2080
2493
|
buttonAccessibleName = computed(() => (this.buttonDisabled() ? this.resource()?.accessibleName : undefined) ??
|
|
2081
2494
|
this.uiSettings()?.buttonSettings?.text ??
|
|
2082
2495
|
this.uiSettings()?.buttonSettings?.tooltip ??
|
|
2083
2496
|
this.uiSettings()?.buttonSettings?.icon ??
|
|
2084
|
-
'',
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2497
|
+
'', /* @ts-ignore */
|
|
2498
|
+
...(ngDevMode ? [{ debugName: "buttonAccessibleName" }] : /* istanbul ignore next */ []));
|
|
2499
|
+
boolValue = computed(() => this.normalizeBoolean(this.value()), /* @ts-ignore */
|
|
2500
|
+
...(ngDevMode ? [{ debugName: "boolValue" }] : /* istanbul ignore next */ []));
|
|
2501
|
+
stringValue = computed(() => this.normalizeString(this.value()), /* @ts-ignore */
|
|
2502
|
+
...(ngDevMode ? [{ debugName: "stringValue" }] : /* istanbul ignore next */ []));
|
|
2503
|
+
tags = computed(() => this.normalizeTagsArray(this.value()), /* @ts-ignore */
|
|
2504
|
+
...(ngDevMode ? [{ debugName: "tags" }] : /* istanbul ignore next */ []));
|
|
2505
|
+
isVisible = signal(false, /* @ts-ignore */
|
|
2506
|
+
...(ngDevMode ? [{ debugName: "isVisible" }] : /* istanbul ignore next */ []));
|
|
2507
|
+
copySuccess = signal(false, /* @ts-ignore */
|
|
2508
|
+
...(ngDevMode ? [{ debugName: "copySuccess" }] : /* istanbul ignore next */ []));
|
|
2509
|
+
isCollection = computed(() => !!this.fieldDefinition().propertyCollection?.length, /* @ts-ignore */
|
|
2510
|
+
...(ngDevMode ? [{ debugName: "isCollection" }] : /* istanbul ignore next */ []));
|
|
2091
2511
|
canRenderField = computed(() => {
|
|
2092
2512
|
const perm = this.fieldDefinition().requirePermission;
|
|
2093
2513
|
if (!perm) {
|
|
@@ -2098,7 +2518,8 @@ class ResourceField {
|
|
|
2098
2518
|
return false;
|
|
2099
2519
|
}
|
|
2100
2520
|
return this.permissions()?.[resourceId]?.includes(perm) ?? false;
|
|
2101
|
-
},
|
|
2521
|
+
}, /* @ts-ignore */
|
|
2522
|
+
...(ngDevMode ? [{ debugName: "canRenderField" }] : /* istanbul ignore next */ []));
|
|
2102
2523
|
toggleVisibility(e) {
|
|
2103
2524
|
e.stopPropagation();
|
|
2104
2525
|
this.isVisible.set(!this.isVisible());
|
|
@@ -2164,10 +2585,10 @@ class ResourceField {
|
|
|
2164
2585
|
resource: this.resource(),
|
|
2165
2586
|
});
|
|
2166
2587
|
}
|
|
2167
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2168
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2588
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ResourceField, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2589
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: ResourceField, isStandalone: true, selector: "mfp-resource-field", inputs: { fieldDefinition: { classPropertyName: "fieldDefinition", publicName: "fieldDefinition", isSignal: true, isRequired: true, transformFunction: null }, resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: false, transformFunction: null }, permissions: { classPropertyName: "permissions", publicName: "permissions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { buttonClick: "buttonClick" }, host: { properties: { "class.resource-field--collection": "isCollection()" } }, ngImport: i0, template: "@if (canRenderField()) {\n @if (isCollection()) {\n <mfp-resource-collection-field\n [fieldDefinition]=\"fieldDefinition()\"\n [resource]=\"resource()\"\n />\n } @else {\n @let displayType = displayAs();\n <span [attr.data-testid]=\"testId()\" [style]=\"cssStyles()\">\n @if (displayType === 'secret') {\n <span class=\"secret-value-container\">\n <mfp-secret-value\n [isVisible]=\"isVisible()\"\n [testId]=\"testId() + '-secret'\"\n [value]=\"value()\"\n />\n <ui5-icon\n class=\"toggle-icon\"\n mode=\"Interactive\"\n [accessibleName]=\"isVisible() ? 'Hide value' : 'Show value'\"\n [attr.data-testid]=\"testId() + '-secret-toggle'\"\n [name]=\"isVisible() ? 'hide' : 'show'\"\n (click)=\"toggleVisibility($event)\"\n />\n </span>\n } @else if (displayType === 'boolIcon' && isBoolLike()) {\n <mfp-boolean-value\n [boolValue]=\"boolValue()!\"\n [testId]=\"testId() + '-boolean'\"\n />\n } @else if (displayType === 'link' && isUrlValue()) {\n <mfp-link-value\n [testId]=\"testId() + '-link'\"\n [urlValue]=\"stringValue()!\"\n />\n } @else if (displayType === 'tooltip') {\n <ui5-icon\n [accessibleName]=\"stringValue()!\"\n [attr.data-testid]=\"testId() + '-tooltip'\"\n [name]=\"tooltipIcon() ?? 'hint'\"\n [showTooltip]=\"true\"\n />\n } @else if (displayType === 'alert') {\n @if (!value()) {\n <ui5-icon\n design=\"Critical\"\n name=\"alert\"\n [accessibleName]=\"resource()?.accessibleName ?? ''\"\n [attr.data-testid]=\"testId() + '-icon'\"\n [showTooltip]=\"true\"\n (click)=\"$event.stopPropagation()\"\n />\n }\n } @else if (displayType === 'img' && value()) {\n <img alt=\"Resource image\" class=\"image-cell\" [src]=\"value()\" />\n } @else if (displayType === 'button') {\n @let buttonSettings = uiSettings()?.buttonSettings;\n <ui5-button\n [accessibleName]=\"buttonAccessibleName()\"\n [attr.data-testid]=\"testId() + '-button'\"\n [design]=\"buttonSettings?.design\"\n [disabled]=\"buttonDisabled()\"\n [endIcon]=\"buttonSettings?.endIcon\"\n [icon]=\"buttonSettings?.icon\"\n [tooltip]=\"buttonSettings?.tooltip\"\n (click)=\"buttonClicked($event)\"\n >{{ buttonSettings?.text }}</ui5-button\n > \n } @else if (displayType === 'tag') {\n <mfp-tag-list-value\n [tagSettings]=\"uiSettings()?.tagSettings\"\n [tags]=\"tags()\"\n [testId]=\"testId() + '-tags'\"\n />\n } @else {\n {{ displayValue() }}\n }\n </span>\n\n @if (withCopyButton()) {\n <ui5-icon\n class=\"toggle-icon\"\n mode=\"Interactive\"\n [accessibleName]=\"copySuccess() ? 'Copied' : 'Copy value'\"\n [attr.data-testid]=\"testId() + '-copy'\"\n [design]=\"copySuccess() ? 'Positive' : 'Default'\"\n [name]=\"copySuccess() ? 'accept' : 'copy'\"\n (click)=\"copyValue($event)\"\n />\n }\n }\n}\n", styles: [":host{display:inline-flex;align-items:center}:host(.resource-field--collection){display:block;width:100%}.secret-value-container{display:flex;align-items:center;gap:.25rem}.toggle-icon{cursor:pointer;transition:color .2s ease;padding:.25rem}.toggle-icon:hover{color:var(--sapButton_Hover_TextColor, #0854a0)}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => Icon), selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }, { kind: "component", type: i0.forwardRef(() => BooleanValue), selector: "mfp-boolean-value", inputs: ["boolValue", "testId"] }, { kind: "component", type: i0.forwardRef(() => LinkValue), selector: "mfp-link-value", inputs: ["urlValue", "testId"] }, { kind: "component", type: i0.forwardRef(() => SecretValue), selector: "mfp-secret-value", inputs: ["value", "isVisible", "testId"] }, { kind: "component", type: i0.forwardRef(() => Button), selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: i0.forwardRef(() => TagListValue), selector: "mfp-tag-list-value", inputs: ["tags", "tagSettings", "testId"] }, { kind: "component", type: i0.forwardRef(() => ResourceCollectionField), selector: "mfp-resource-collection-field", inputs: ["fieldDefinition", "resource"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2169
2590
|
}
|
|
2170
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2591
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ResourceField, decorators: [{
|
|
2171
2592
|
type: Component,
|
|
2172
2593
|
args: [{ selector: 'mfp-resource-field', imports: [
|
|
2173
2594
|
Icon,
|
|
@@ -2183,7 +2604,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
2183
2604
|
forwardRef(() => ResourceCollectionField),
|
|
2184
2605
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, host: {
|
|
2185
2606
|
'[class.resource-field--collection]': 'isCollection()',
|
|
2186
|
-
}, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "@if (canRenderField()) {\n @if (isCollection()) {\n <mfp-resource-collection-field\n [fieldDefinition]=\"fieldDefinition()\"\n [resource]=\"resource()\"\n />\n } @else {\n @let displayType = displayAs();\n <span [attr.data-testid]=\"testId()\" [style]=\"cssStyles()\">\n @if (displayType === 'secret') {\n <span class=\"secret-value-container\">\n <mfp-secret-value
|
|
2607
|
+
}, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "@if (canRenderField()) {\n @if (isCollection()) {\n <mfp-resource-collection-field\n [fieldDefinition]=\"fieldDefinition()\"\n [resource]=\"resource()\"\n />\n } @else {\n @let displayType = displayAs();\n <span [attr.data-testid]=\"testId()\" [style]=\"cssStyles()\">\n @if (displayType === 'secret') {\n <span class=\"secret-value-container\">\n <mfp-secret-value\n [isVisible]=\"isVisible()\"\n [testId]=\"testId() + '-secret'\"\n [value]=\"value()\"\n />\n <ui5-icon\n class=\"toggle-icon\"\n mode=\"Interactive\"\n [accessibleName]=\"isVisible() ? 'Hide value' : 'Show value'\"\n [attr.data-testid]=\"testId() + '-secret-toggle'\"\n [name]=\"isVisible() ? 'hide' : 'show'\"\n (click)=\"toggleVisibility($event)\"\n />\n </span>\n } @else if (displayType === 'boolIcon' && isBoolLike()) {\n <mfp-boolean-value\n [boolValue]=\"boolValue()!\"\n [testId]=\"testId() + '-boolean'\"\n />\n } @else if (displayType === 'link' && isUrlValue()) {\n <mfp-link-value\n [testId]=\"testId() + '-link'\"\n [urlValue]=\"stringValue()!\"\n />\n } @else if (displayType === 'tooltip') {\n <ui5-icon\n [accessibleName]=\"stringValue()!\"\n [attr.data-testid]=\"testId() + '-tooltip'\"\n [name]=\"tooltipIcon() ?? 'hint'\"\n [showTooltip]=\"true\"\n />\n } @else if (displayType === 'alert') {\n @if (!value()) {\n <ui5-icon\n design=\"Critical\"\n name=\"alert\"\n [accessibleName]=\"resource()?.accessibleName ?? ''\"\n [attr.data-testid]=\"testId() + '-icon'\"\n [showTooltip]=\"true\"\n (click)=\"$event.stopPropagation()\"\n />\n }\n } @else if (displayType === 'img' && value()) {\n <img alt=\"Resource image\" class=\"image-cell\" [src]=\"value()\" />\n } @else if (displayType === 'button') {\n @let buttonSettings = uiSettings()?.buttonSettings;\n <ui5-button\n [accessibleName]=\"buttonAccessibleName()\"\n [attr.data-testid]=\"testId() + '-button'\"\n [design]=\"buttonSettings?.design\"\n [disabled]=\"buttonDisabled()\"\n [endIcon]=\"buttonSettings?.endIcon\"\n [icon]=\"buttonSettings?.icon\"\n [tooltip]=\"buttonSettings?.tooltip\"\n (click)=\"buttonClicked($event)\"\n >{{ buttonSettings?.text }}</ui5-button\n > \n } @else if (displayType === 'tag') {\n <mfp-tag-list-value\n [tagSettings]=\"uiSettings()?.tagSettings\"\n [tags]=\"tags()\"\n [testId]=\"testId() + '-tags'\"\n />\n } @else {\n {{ displayValue() }}\n }\n </span>\n\n @if (withCopyButton()) {\n <ui5-icon\n class=\"toggle-icon\"\n mode=\"Interactive\"\n [accessibleName]=\"copySuccess() ? 'Copied' : 'Copy value'\"\n [attr.data-testid]=\"testId() + '-copy'\"\n [design]=\"copySuccess() ? 'Positive' : 'Default'\"\n [name]=\"copySuccess() ? 'accept' : 'copy'\"\n (click)=\"copyValue($event)\"\n />\n }\n }\n}\n", styles: [":host{display:inline-flex;align-items:center}:host(.resource-field--collection){display:block;width:100%}.secret-value-container{display:flex;align-items:center;gap:.25rem}.toggle-icon{cursor:pointer;transition:color .2s ease;padding:.25rem}.toggle-icon:hover{color:var(--sapButton_Hover_TextColor, #0854a0)}\n"] }]
|
|
2187
2608
|
}], propDecorators: { fieldDefinition: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldDefinition", required: true }] }], resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: false }] }], permissions: [{ type: i0.Input, args: [{ isSignal: true, alias: "permissions", required: false }] }], buttonClick: [{ type: i0.Output, args: ["buttonClick"] }] } });
|
|
2188
2609
|
|
|
2189
2610
|
const processGroupFields = (fields) => {
|
|
@@ -2231,39 +2652,64 @@ const combineGroupFields = (fields) => {
|
|
|
2231
2652
|
};
|
|
2232
2653
|
|
|
2233
2654
|
class DeclarativeTable {
|
|
2234
|
-
columns = input
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2655
|
+
columns = input([], /* @ts-ignore */
|
|
2656
|
+
...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
2657
|
+
resources = input([], /* @ts-ignore */
|
|
2658
|
+
...(ngDevMode ? [{ debugName: "resources" }] : /* istanbul ignore next */ []));
|
|
2659
|
+
trackByPath = input('id', /* @ts-ignore */
|
|
2660
|
+
...(ngDevMode ? [{ debugName: "trackByPath" }] : /* istanbul ignore next */ []));
|
|
2661
|
+
permissions = input(/* @ts-ignore */
|
|
2662
|
+
...(ngDevMode ? [undefined, { debugName: "permissions" }] : /* istanbul ignore next */ []));
|
|
2663
|
+
loading = input(false, /* @ts-ignore */
|
|
2664
|
+
...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
2665
|
+
loadingDelay = input(1000, /* @ts-ignore */
|
|
2666
|
+
...(ngDevMode ? [{ debugName: "loadingDelay" }] : /* istanbul ignore next */ []));
|
|
2667
|
+
error = input(false, /* @ts-ignore */
|
|
2668
|
+
...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
2669
|
+
totalItemsCount = input(/* @ts-ignore */
|
|
2670
|
+
...(ngDevMode ? [undefined, { debugName: "totalItemsCount" }] : /* istanbul ignore next */ []));
|
|
2671
|
+
paginationLimit = input(5, /* @ts-ignore */
|
|
2672
|
+
...(ngDevMode ? [{ debugName: "paginationLimit" }] : /* istanbul ignore next */ []));
|
|
2673
|
+
hasMore = input(false, /* @ts-ignore */
|
|
2674
|
+
...(ngDevMode ? [{ debugName: "hasMore" }] : /* istanbul ignore next */ []));
|
|
2675
|
+
loadMode = input('button', /* @ts-ignore */
|
|
2676
|
+
...(ngDevMode ? [{ debugName: "loadMode" }] : /* istanbul ignore next */ []));
|
|
2677
|
+
loadMoreButtonText = input('Load More', /* @ts-ignore */
|
|
2678
|
+
...(ngDevMode ? [{ debugName: "loadMoreButtonText" }] : /* istanbul ignore next */ []));
|
|
2679
|
+
height = input(/* @ts-ignore */
|
|
2680
|
+
...(ngDevMode ? [undefined, { debugName: "height" }] : /* istanbul ignore next */ []));
|
|
2681
|
+
currentPage = input(1, /* @ts-ignore */
|
|
2682
|
+
...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
|
|
2245
2683
|
buttonClick = output();
|
|
2246
2684
|
tableRowClicked = output();
|
|
2247
2685
|
loadMoreResources = output();
|
|
2248
2686
|
paginationLimitChanged = output();
|
|
2249
2687
|
pageChange = output();
|
|
2688
|
+
retry = output();
|
|
2250
2689
|
columnTrackBy = (column, index) => column.property ?? column.value ?? index;
|
|
2251
2690
|
rowTrackBy = (_index, item) => getResourceValueByJsonPath(item, { property: this.trackByPath() }) ??
|
|
2252
2691
|
_index;
|
|
2253
|
-
viewColumns = computed(() => processGroupFields(this.columns()),
|
|
2692
|
+
viewColumns = computed(() => processGroupFields(this.columns()), /* @ts-ignore */
|
|
2693
|
+
...(ngDevMode ? [{ debugName: "viewColumns" }] : /* istanbul ignore next */ []));
|
|
2254
2694
|
onRowClick(item) {
|
|
2255
2695
|
if (item.isAvailable !== false) {
|
|
2256
2696
|
this.tableRowClicked.emit(item);
|
|
2257
2697
|
}
|
|
2258
2698
|
}
|
|
2259
|
-
isPagerMode = computed(() => this.loadMode() === 'pager',
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2699
|
+
isPagerMode = computed(() => this.loadMode() === 'pager', /* @ts-ignore */
|
|
2700
|
+
...(ngDevMode ? [{ debugName: "isPagerMode" }] : /* istanbul ignore next */ []));
|
|
2701
|
+
knowsTotal = computed(() => this.totalItemsCount() !== undefined, /* @ts-ignore */
|
|
2702
|
+
...(ngDevMode ? [{ debugName: "knowsTotal" }] : /* istanbul ignore next */ []));
|
|
2703
|
+
hasResults = computed(() => (this.totalItemsCount() ?? 0) > 0, /* @ts-ignore */
|
|
2704
|
+
...(ngDevMode ? [{ debugName: "hasResults" }] : /* istanbul ignore next */ []));
|
|
2705
|
+
totalPages = computed(() => Math.max(1, Math.ceil((this.totalItemsCount() ?? 0) / this.paginationLimit())), /* @ts-ignore */
|
|
2706
|
+
...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
2707
|
+
canPrev = computed(() => this.currentPage() > 1, /* @ts-ignore */
|
|
2708
|
+
...(ngDevMode ? [{ debugName: "canPrev" }] : /* istanbul ignore next */ []));
|
|
2264
2709
|
canNext = computed(() => this.knowsTotal()
|
|
2265
2710
|
? this.hasResults() && this.currentPage() < this.totalPages()
|
|
2266
|
-
: this.hasMore(),
|
|
2711
|
+
: this.hasMore(), /* @ts-ignore */
|
|
2712
|
+
...(ngDevMode ? [{ debugName: "canNext" }] : /* istanbul ignore next */ []));
|
|
2267
2713
|
goToPage(page) {
|
|
2268
2714
|
const maxPage = this.knowsTotal() ? this.totalPages() : Infinity;
|
|
2269
2715
|
const target = Math.min(Math.max(1, page), maxPage);
|
|
@@ -2283,10 +2729,10 @@ class DeclarativeTable {
|
|
|
2283
2729
|
lastPage = () => {
|
|
2284
2730
|
this.goToPage(this.totalPages());
|
|
2285
2731
|
};
|
|
2286
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2287
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: DeclarativeTable, isStandalone: true, selector: "mfp-declarative-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, resources: { classPropertyName: "resources", publicName: "resources", isSignal: true, isRequired: true, transformFunction: null }, trackByPath: { classPropertyName: "trackByPath", publicName: "trackByPath", isSignal: true, isRequired: false, transformFunction: null }, permissions: { classPropertyName: "permissions", publicName: "permissions", isSignal: true, isRequired: false, transformFunction: null }, totalItemsCount: { classPropertyName: "totalItemsCount", publicName: "totalItemsCount", isSignal: true, isRequired: false, transformFunction: null }, paginationLimit: { classPropertyName: "paginationLimit", publicName: "paginationLimit", isSignal: true, isRequired: false, transformFunction: null }, hasMore: { classPropertyName: "hasMore", publicName: "hasMore", isSignal: true, isRequired: false, transformFunction: null }, loadMode: { classPropertyName: "loadMode", publicName: "loadMode", isSignal: true, isRequired: false, transformFunction: null }, loadMoreButtonText: { classPropertyName: "loadMoreButtonText", publicName: "loadMoreButtonText", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { buttonClick: "buttonClick", tableRowClicked: "tableRowClicked", loadMoreResources: "loadMoreResources", paginationLimitChanged: "paginationLimitChanged", pageChange: "pageChange" }, ngImport: i0, template: "<ui5-table\n data-testid=\"generic-table\"\n [style.height]=\"height() ? height() + 'px' : null\"\n [style.overflow-y]=\"'auto'\"\n>\n <ui5-table-header-row\n slot=\"headerRow\"\n [sticky]=\"loadMode() === 'scroll' && !!height()\"\n >\n @for (column of viewColumns(); track columnTrackBy(column, $index)) {\n @if (column.group) {\n <ui5-table-header-cell\n [attr.data-testid]=\"'generic-table-header-' + column.group.name\"\n [width]=\"column.uiSettings?.columnWidth ?? 'auto'\"\n >{{ column.group.label ?? column.group.name }}</ui5-table-header-cell\n >\n } @else {\n <ui5-table-header-cell\n [attr.data-testid]=\"'generic-table-header-' + column.property\"\n [width]=\"column.uiSettings?.columnWidth ?? 'auto'\"\n >{{ column.label }}</ui5-table-header-cell\n >\n }\n }\n </ui5-table-header-row>\n\n @for (item of resources(); let i = $index; track rowTrackBy($index, item)) {\n <ui5-table-row\n [attr.data-testid]=\"'generic-table-row-' + i\"\n [class.disabled]=\"item.isAvailable === false\"\n [interactive]=\"item.isAvailable !== false\"\n (click)=\"onRowClick(item)\"\n >\n @for (column of viewColumns(); track columnTrackBy(column, $index)) {\n @if (column.group) {\n <ui5-table-cell\n [attr.data-testid]=\"'generic-table-cell-' + i + '-' + column.group.name\"\n >\n @let isMultiline = column.group.multiline ?? true;\n <div\n class=\"flex\"\n [style.alignItems]=\"isMultiline ? column.uiSettings?.align : null\"\n [style.flexDirection]=\"isMultiline ? 'column' : 'row'\"\n [style.justifyContent]=\"\n isMultiline ? null : column.uiSettings?.align\n \"\n >\n @for (\n field of column.group.fields;\n let last = $last;\n track columnTrackBy(field, $index)\n ) {\n <span\n class=\"group-value\"\n [attr.data-testid]=\"\n 'generic-table-cell-' +\n i +\n '-' +\n column.group.name +\n '-' +\n field.property\n \"\n >\n @if (field.label) {\n <span>{{ field.label }}: </span>\n }\n <mfp-resource-field\n [fieldDefinition]=\"field\"\n [resource]=\"item\"\n [permissions]=\"permissions()\"\n (buttonClick)=\"buttonClick.emit($event)\"\n />\n </span>\n @if (!last && column.group.delimiter) {\n <span class=\"delimiter\">{{ column.group.delimiter }}</span>\n }\n }\n </div>\n </ui5-table-cell>\n } @else {\n <ui5-table-cell\n [attr.data-testid]=\"'generic-table-cell-' + i + '-' + column.property\"\n >\n <div class=\"flex\" [style.justifyContent]=\"column.uiSettings?.align\">\n <mfp-resource-field\n [fieldDefinition]=\"column\"\n [resource]=\"item\"\n [permissions]=\"permissions()\"\n (buttonClick)=\"buttonClick.emit($event)\"\n />\n </div>\n </ui5-table-cell>\n }\n }\n </ui5-table-row>\n } @empty {\n <ui5-illustrated-message\n data-testid=\"generic-table-view-nodata\"\n name=\"NoData\"\n slot=\"noData\"\n >\n <span slot=\"title\">No Resources</span>\n <span slot=\"subtitle\">There are currently no items to show.</span>\n </ui5-illustrated-message>\n }\n\n @if (loadMode() !== 'pager' && hasMore()) {\n <ui5-table-growing\n data-testid=\"generic-table-growing\"\n id=\"growing\"\n slot=\"features\"\n [mode]=\"loadMode() === 'scroll' ? 'Scroll' : 'Button'\"\n [text]=\"loadMoreButtonText()\"\n (ui5LoadMore)=\"loadMoreResources.emit()\"\n />\n }\n</ui5-table>\n\n<!-- Pagination Control -->\n<div\n class=\"pagination-footer\"\n style=\"\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0rem 1rem;\n min-height: 3rem;\n border-top: 1px solid var(--sapList_BorderColor);\n \"\n>\n <div class=\"pagination-footer__side\" style=\"display: flex; align-items: center; gap: 0.5rem\">\n <span style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\">\n {{ isPagerMode() ? 'Items per page:' : 'Items per load:' }}\n </span>\n <ui5-select\n data-testid=\"generic-table-pagination-select\"\n style=\"width: 5rem\"\n [value]=\"paginationLimit().toString()\"\n (change)=\"paginationLimitChanged.emit(+$any($event)?.target?.value)\"\n >\n <ui5-option value=\"5\">5</ui5-option>\n <ui5-option value=\"10\">10</ui5-option>\n <ui5-option value=\"20\">20</ui5-option>\n <ui5-option value=\"50\">50</ui5-option>\n <ui5-option value=\"100\">100</ui5-option>\n </ui5-select>\n </div>\n\n @if (isPagerMode()) {\n <div class=\"pager\" data-testid=\"generic-table-pager\">\n @if (knowsTotal()) {\n <ui5-button\n accessibleName=\"First page\"\n data-testid=\"generic-table-pager-first\"\n design=\"Transparent\"\n icon=\"close-command-field\"\n [disabled]=\"!canPrev()\"\n (click)=\"firstPage()\"\n />\n }\n <ui5-button\n accessibleName=\"Previous page\"\n data-testid=\"generic-table-pager-prev\"\n design=\"Transparent\"\n icon=\"navigation-left-arrow\"\n [disabled]=\"!canPrev()\"\n (click)=\"prevPage()\"\n />\n <span\n class=\"pager__indicator\"\n data-testid=\"generic-table-pager-indicator\"\n >{{\n knowsTotal()\n ? (hasResults() ? currentPage() + ' / ' + totalPages() : '\u2013')\n : currentPage()\n }}</span\n >\n <ui5-button\n accessibleName=\"Next page\"\n data-testid=\"generic-table-pager-next\"\n design=\"Transparent\"\n icon=\"navigation-right-arrow\"\n [disabled]=\"!canNext()\"\n (click)=\"nextPage()\"\n />\n @if (knowsTotal()) {\n <ui5-button\n accessibleName=\"Last page\"\n data-testid=\"generic-table-pager-last\"\n design=\"Transparent\"\n icon=\"open-command-field\"\n [disabled]=\"!canNext()\"\n (click)=\"lastPage()\"\n />\n }\n </div>\n <div class=\"pagination-footer__side pagination-footer__side--end\">\n @if (knowsTotal()) {\n <span\n data-testid=\"generic-table-item-count\"\n style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\"\n >\n <b style=\"font-size: var(--sapFontSize)\">{{ totalItemsCount() }}</b>\n Items\n </span>\n }\n </div>\n } @else {\n <div class=\"pagination-footer__side pagination-footer__side--end\">\n <span\n style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\"\n >\n Items loaded:\n <b style=\"font-size: var(--sapFontSize)\">{{\n totalItemsCount() !== undefined\n ? resources().length + ' / ' + totalItemsCount()\n : resources().length\n }}</b>\n </span>\n </div>\n }\n</div>\n", styles: [".multiline{display:block}.disabled{filter:brightness(.92);pointer-events:none}.disabled ui5-table-cell:not(:first-child){color:var(--sapContent_DisabledTextColor, #6a6d70)}.disabled ui5-table-cell:not(:first-child) ui5-icon{color:var(--sapContent_DisabledTextColor, #6a6d70)}.group-value{display:flex;align-items:center}.flex{display:flex;width:100%}.delimiter{min-width:4px}ui5-table-header-row{padding-block-start:.75rem;padding-block-end:.25rem}.pagination-footer{gap:.5rem}.pagination-footer__side{flex:1 1 0;display:flex;align-items:center;gap:.5rem;min-width:0}.pagination-footer__side--end{justify-content:flex-end}.pager{flex:0 0 auto;display:flex;align-items:center;gap:.25rem;justify-content:center}.pager ui5-button{color:var(--sapContent_IconColor, #1d2d3e);--sapButton_IconColor: var(--sapContent_IconColor, #1d2d3e);--sapButton_Hover_IconColor: var(--sapContent_IconColor, #1d2d3e)}.pager ui5-button[disabled]{color:var(--sapContent_DisabledTextColor, #b3b3b3);--sapButton_IconColor: var(--sapContent_DisabledTextColor, #b3b3b3)}.pager__indicator{min-width:3rem;text-align:center;color:var(--sapTextColor);font-size:var(--sapFontSize);font-weight:700}\n"], dependencies: [{ kind: "component", type: IllustratedMessage, selector: "ui5-illustrated-message, [ui5-illustrated-message]", inputs: ["name", "design", "subtitleText", "titleText", "accessibleNameRef", "decorative"], exportAs: ["ui5IllustratedMessage"] }, { kind: "component", type: Table, selector: "ui5-table, [ui5-table]", inputs: ["accessibleName", "accessibleNameRef", "noDataText", "overflowMode", "loading", "loadingDelay", "rowActionCount", "alternateRowColors"], outputs: ["ui5RowClick", "ui5MoveOver", "ui5Move", "ui5RowActionClick"], exportAs: ["ui5Table"] }, { kind: "component", type: TableCell, selector: "ui5-table-cell, [ui5-table-cell]", inputs: ["horizontalAlign"], exportAs: ["ui5TableCell"] }, { kind: "component", type: TableHeaderCell, selector: "ui5-table-header-cell, [ui5-table-header-cell]", inputs: ["width", "minWidth", "importance", "popinText", "sortIndicator", "popinHidden", "horizontalAlign"], exportAs: ["ui5TableHeaderCell"] }, { kind: "component", type: TableHeaderRow, selector: "ui5-table-header-row, [ui5-table-header-row]", inputs: ["sticky"], exportAs: ["ui5TableHeaderRow"] }, { kind: "component", type: TableRow, selector: "ui5-table-row, [ui5-table-row]", inputs: ["rowKey", "position", "interactive", "navigated", "movable"], exportAs: ["ui5TableRow"] }, { kind: "component", type: ResourceField, selector: "mfp-resource-field", inputs: ["fieldDefinition", "resource", "permissions"], outputs: ["buttonClick"] }, { 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: TableGrowing, selector: "ui5-table-growing, [ui5-table-growing]", inputs: ["mode", "text", "subtext"], outputs: ["ui5LoadMore"], exportAs: ["ui5TableGrowing"] }, { 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"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2732
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DeclarativeTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2733
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: DeclarativeTable, isStandalone: true, selector: "mfp-declarative-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, resources: { classPropertyName: "resources", publicName: "resources", isSignal: true, isRequired: false, transformFunction: null }, trackByPath: { classPropertyName: "trackByPath", publicName: "trackByPath", isSignal: true, isRequired: false, transformFunction: null }, permissions: { classPropertyName: "permissions", publicName: "permissions", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingDelay: { classPropertyName: "loadingDelay", publicName: "loadingDelay", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, totalItemsCount: { classPropertyName: "totalItemsCount", publicName: "totalItemsCount", isSignal: true, isRequired: false, transformFunction: null }, paginationLimit: { classPropertyName: "paginationLimit", publicName: "paginationLimit", isSignal: true, isRequired: false, transformFunction: null }, hasMore: { classPropertyName: "hasMore", publicName: "hasMore", isSignal: true, isRequired: false, transformFunction: null }, loadMode: { classPropertyName: "loadMode", publicName: "loadMode", isSignal: true, isRequired: false, transformFunction: null }, loadMoreButtonText: { classPropertyName: "loadMoreButtonText", publicName: "loadMoreButtonText", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { buttonClick: "buttonClick", tableRowClicked: "tableRowClicked", loadMoreResources: "loadMoreResources", paginationLimitChanged: "paginationLimitChanged", pageChange: "pageChange", retry: "retry" }, ngImport: i0, template: "<ui5-table\n data-testid=\"generic-table\"\n [loading]=\"loading() && !error()\"\n [loadingDelay]=\"loadingDelay()\"\n [style.height]=\"height() ? height() + 'px' : null\"\n [style.overflow-y]=\"'auto'\"\n>\n <ui5-table-header-row\n slot=\"headerRow\"\n [sticky]=\"loadMode() === 'scroll' && !!height()\"\n >\n @for (column of viewColumns(); track columnTrackBy(column, $index)) {\n @if (column.group) {\n <ui5-table-header-cell\n [attr.data-testid]=\"'generic-table-header-' + column.group.name\"\n [width]=\"column.uiSettings?.columnWidth ?? 'auto'\"\n >{{ column.group.label ?? column.group.name }}</ui5-table-header-cell\n >\n } @else {\n <ui5-table-header-cell\n [attr.data-testid]=\"'generic-table-header-' + column.property\"\n [width]=\"column.uiSettings?.columnWidth ?? 'auto'\"\n >{{ column.label }}</ui5-table-header-cell\n >\n }\n }\n </ui5-table-header-row>\n\n @if (error()) {\n <ui5-illustrated-message\n data-testid=\"generic-table-view-error\"\n name=\"UnableToLoad\"\n slot=\"noData\"\n >\n <ui5-button\n data-testid=\"generic-table-retry\"\n design=\"Emphasized\"\n (click)=\"retry.emit()\"\n >Retry</ui5-button\n >\n </ui5-illustrated-message>\n }\n\n @for (\n item of error() ? [] : resources();\n let i = $index;\n track rowTrackBy($index, item)\n ) {\n <ui5-table-row\n [attr.data-testid]=\"'generic-table-row-' + i\"\n [class.disabled]=\"item.isAvailable === false\"\n [interactive]=\"item.isAvailable !== false\"\n (click)=\"onRowClick(item)\"\n >\n @for (column of viewColumns(); track columnTrackBy(column, $index)) {\n @if (column.group) {\n <ui5-table-cell\n [attr.data-testid]=\"\n 'generic-table-cell-' + i + '-' + column.group.name\n \"\n >\n @let isMultiline = column.group.multiline ?? true;\n <div\n class=\"flex\"\n [style.alignItems]=\"isMultiline ? column.uiSettings?.align : null\"\n [style.flexDirection]=\"isMultiline ? 'column' : 'row'\"\n [style.justifyContent]=\"\n isMultiline ? null : column.uiSettings?.align\n \"\n >\n @for (\n field of column.group.fields;\n let last = $last;\n track columnTrackBy(field, $index)\n ) {\n <span\n class=\"group-value\"\n [attr.data-testid]=\"\n 'generic-table-cell-' +\n i +\n '-' +\n column.group.name +\n '-' +\n field.property\n \"\n >\n @if (field.label) {\n <span>{{ field.label }}: </span>\n }\n <mfp-resource-field\n [fieldDefinition]=\"field\"\n [permissions]=\"permissions()\"\n [resource]=\"item\"\n (buttonClick)=\"buttonClick.emit($event)\"\n />\n </span>\n @if (!last && column.group.delimiter) {\n <span class=\"delimiter\">{{ column.group.delimiter }}</span>\n }\n }\n </div>\n </ui5-table-cell>\n } @else {\n <ui5-table-cell\n [attr.data-testid]=\"\n 'generic-table-cell-' + i + '-' + column.property\n \"\n >\n <div class=\"flex\" [style.justifyContent]=\"column.uiSettings?.align\">\n <mfp-resource-field\n [fieldDefinition]=\"column\"\n [permissions]=\"permissions()\"\n [resource]=\"item\"\n (buttonClick)=\"buttonClick.emit($event)\"\n />\n </div>\n </ui5-table-cell>\n }\n }\n </ui5-table-row>\n } @empty {\n @if (!error()) {\n @if (loading()) {\n <span\n aria-hidden=\"true\"\n data-testid=\"generic-table-view-loading\"\n slot=\"noData\"\n ></span>\n } @else {\n <ui5-illustrated-message\n data-testid=\"generic-table-view-nodata\"\n name=\"NoData\"\n slot=\"noData\"\n >\n <span slot=\"title\">No Resources</span>\n <span slot=\"subtitle\">There are currently no items to show.</span>\n </ui5-illustrated-message>\n }\n }\n }\n\n @if (!error() && !loading() && loadMode() !== 'pager' && hasMore()) {\n <ui5-table-growing\n data-testid=\"generic-table-growing\"\n id=\"growing\"\n slot=\"features\"\n [mode]=\"loadMode() === 'scroll' ? 'Scroll' : 'Button'\"\n [text]=\"loadMoreButtonText()\"\n (ui5LoadMore)=\"loadMoreResources.emit()\"\n />\n }\n</ui5-table>\n\n<!-- Pagination Control -->\n<div\n class=\"pagination-footer\"\n style=\"\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0rem 1rem;\n min-height: 3rem;\n border-top: 1px solid var(--sapList_BorderColor);\n \"\n [hidden]=\"error() || (loading() && resources().length === 0)\"\n>\n <div\n class=\"pagination-footer__side\"\n style=\"display: flex; align-items: center; gap: 0.5rem\"\n >\n <span\n style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\"\n >\n {{ isPagerMode() ? 'Items per page:' : 'Items per load:' }}\n </span>\n <ui5-select\n data-testid=\"generic-table-pagination-select\"\n style=\"width: 5rem\"\n [accessibleName]=\"isPagerMode() ? 'Items per page' : 'Items per load'\"\n [disabled]=\"loading()\"\n [value]=\"paginationLimit().toString()\"\n (change)=\"paginationLimitChanged.emit(+$any($event)?.target?.value)\"\n >\n <ui5-option value=\"5\">5</ui5-option>\n <ui5-option value=\"10\">10</ui5-option>\n <ui5-option value=\"20\">20</ui5-option>\n <ui5-option value=\"50\">50</ui5-option>\n <ui5-option value=\"100\">100</ui5-option>\n </ui5-select>\n </div>\n\n @if (isPagerMode()) {\n <div class=\"pager\" data-testid=\"generic-table-pager\">\n @if (knowsTotal()) {\n <ui5-button\n accessibleName=\"First page\"\n data-testid=\"generic-table-pager-first\"\n design=\"Transparent\"\n icon=\"close-command-field\"\n [disabled]=\"loading() || !canPrev()\"\n (click)=\"firstPage()\"\n />\n }\n <ui5-button\n accessibleName=\"Previous page\"\n data-testid=\"generic-table-pager-prev\"\n design=\"Transparent\"\n icon=\"navigation-left-arrow\"\n [disabled]=\"loading() || !canPrev()\"\n (click)=\"prevPage()\"\n />\n <span\n class=\"pager__indicator\"\n data-testid=\"generic-table-pager-indicator\"\n >{{\n knowsTotal()\n ? hasResults()\n ? currentPage() + ' / ' + totalPages()\n : '\u2013'\n : currentPage()\n }}</span\n >\n <ui5-button\n accessibleName=\"Next page\"\n data-testid=\"generic-table-pager-next\"\n design=\"Transparent\"\n icon=\"navigation-right-arrow\"\n [disabled]=\"loading() || !canNext()\"\n (click)=\"nextPage()\"\n />\n @if (knowsTotal()) {\n <ui5-button\n accessibleName=\"Last page\"\n data-testid=\"generic-table-pager-last\"\n design=\"Transparent\"\n icon=\"open-command-field\"\n [disabled]=\"loading() || !canNext()\"\n (click)=\"lastPage()\"\n />\n }\n </div>\n <div class=\"pagination-footer__side pagination-footer__side--end\">\n @if (knowsTotal()) {\n <span\n data-testid=\"generic-table-item-count\"\n style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\"\n >\n <b style=\"font-size: var(--sapFontSize)\">{{ totalItemsCount() }}</b>\n Items\n </span>\n }\n </div>\n } @else {\n <div class=\"pagination-footer__side pagination-footer__side--end\">\n <span\n style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\"\n >\n Items loaded:\n <b style=\"font-size: var(--sapFontSize)\">{{\n totalItemsCount() !== undefined\n ? resources().length + ' / ' + totalItemsCount()\n : resources().length\n }}</b>\n </span>\n </div>\n }\n</div>\n", styles: [".multiline{display:block}.disabled{filter:brightness(.92);pointer-events:none}.disabled ui5-table-cell:not(:first-child){color:var(--sapContent_DisabledTextColor, #6a6d70)}.disabled ui5-table-cell:not(:first-child) ui5-icon{color:var(--sapContent_DisabledTextColor, #6a6d70)}.group-value{display:flex;align-items:center}.flex{display:flex;width:100%}.delimiter{min-width:4px}ui5-table-header-row{padding-block-start:.75rem;padding-block-end:.25rem}.pagination-footer{gap:.5rem}.pagination-footer__side{flex:1 1 0;display:flex;align-items:center;gap:.5rem;min-width:0}.pagination-footer__side--end{justify-content:flex-end}.pager{flex:0 0 auto;display:flex;align-items:center;gap:.25rem;justify-content:center}.pager ui5-button{color:var(--sapContent_IconColor, #1d2d3e);--sapButton_IconColor: var(--sapContent_IconColor, #1d2d3e);--sapButton_Hover_IconColor: var(--sapContent_IconColor, #1d2d3e)}.pager ui5-button[disabled]{color:var(--sapContent_DisabledTextColor, #b3b3b3);--sapButton_IconColor: var(--sapContent_DisabledTextColor, #b3b3b3)}.pager__indicator{min-width:3rem;text-align:center;color:var(--sapTextColor);font-size:var(--sapFontSize);font-weight:700}\n"], dependencies: [{ kind: "component", type: IllustratedMessage, selector: "ui5-illustrated-message, [ui5-illustrated-message]", inputs: ["accessibleNameRef", "decorative", "design", "name", "subtitleText", "titleText"], exportAs: ["ui5IllustratedMessage"] }, { kind: "component", type: Table, selector: "ui5-table, [ui5-table]", inputs: ["accessibleName", "accessibleNameRef", "alternateRowColors", "loading", "loadingDelay", "noDataText", "overflowMode", "rowActionCount"], outputs: ["ui5Move", "ui5MoveOver", "ui5RowActionClick", "ui5RowClick"], exportAs: ["ui5Table"] }, { kind: "component", type: TableCell, selector: "ui5-table-cell, [ui5-table-cell]", inputs: ["horizontalAlign", "merged"], exportAs: ["ui5TableCell"] }, { kind: "component", type: TableHeaderCell, selector: "ui5-table-header-cell, [ui5-table-header-cell]", inputs: ["horizontalAlign", "importance", "minWidth", "popinHidden", "popinText", "sortIndicator", "width"], exportAs: ["ui5TableHeaderCell"] }, { kind: "component", type: TableHeaderRow, selector: "ui5-table-header-row, [ui5-table-header-row]", inputs: ["sticky"], exportAs: ["ui5TableHeaderRow"] }, { kind: "component", type: TableRow, selector: "ui5-table-row, [ui5-table-row]", inputs: ["interactive", "movable", "navigated", "position", "rowKey"], exportAs: ["ui5TableRow"] }, { kind: "component", type: ResourceField, selector: "mfp-resource-field", inputs: ["fieldDefinition", "resource", "permissions"], outputs: ["buttonClick"] }, { kind: "component", type: Select, selector: "ui5-select, [ui5-select]", inputs: ["accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "disabled", "name", "readonly", "required", "textSeparator", "tooltip", "value", "valueState"], outputs: ["ui5Change", "ui5Close", "ui5LiveChange", "ui5Open"], exportAs: ["ui5Select"] }, { kind: "component", type: Option, selector: "ui5-option, [ui5-option]", inputs: ["additionalText", "icon", "selected", "tooltip", "value"], outputs: ["ui5Click"], exportAs: ["ui5Option"] }, { kind: "component", type: TableGrowing, selector: "ui5-table-growing, [ui5-table-growing]", inputs: ["mode", "subtext", "text"], outputs: ["ui5LoadMore"], exportAs: ["ui5TableGrowing"] }, { kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2288
2734
|
}
|
|
2289
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2735
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DeclarativeTable, decorators: [{
|
|
2290
2736
|
type: Component,
|
|
2291
2737
|
args: [{ selector: 'mfp-declarative-table', imports: [
|
|
2292
2738
|
IllustratedMessage,
|
|
@@ -2300,8 +2746,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
2300
2746
|
Option,
|
|
2301
2747
|
TableGrowing,
|
|
2302
2748
|
Button,
|
|
2303
|
-
], encapsulation: ViewEncapsulation.ShadowDom, template: "<ui5-table\n data-testid=\"generic-table\"\n [style.height]=\"height() ? height() + 'px' : null\"\n [style.overflow-y]=\"'auto'\"\n>\n <ui5-table-header-row\n slot=\"headerRow\"\n [sticky]=\"loadMode() === 'scroll' && !!height()\"\n >\n @for (column of viewColumns(); track columnTrackBy(column, $index)) {\n @if (column.group) {\n <ui5-table-header-cell\n [attr.data-testid]=\"'generic-table-header-' + column.group.name\"\n [width]=\"column.uiSettings?.columnWidth ?? 'auto'\"\n >{{ column.group.label ?? column.group.name }}</ui5-table-header-cell\n >\n } @else {\n <ui5-table-header-cell\n [attr.data-testid]=\"'generic-table-header-' + column.property\"\n [width]=\"column.uiSettings?.columnWidth ?? 'auto'\"\n >{{ column.label }}</ui5-table-header-cell\n >\n }\n }\n </ui5-table-header-row>\n\n @for (item of resources(); let i = $index; track rowTrackBy($index, item)) {\n <ui5-table-row\n [attr.data-testid]=\"'generic-table-row-' + i\"\n [class.disabled]=\"item.isAvailable === false\"\n [interactive]=\"item.isAvailable !== false\"\n (click)=\"onRowClick(item)\"\n >\n @for (column of viewColumns(); track columnTrackBy(column, $index)) {\n @if (column.group) {\n <ui5-table-cell\n [attr.data-testid]=\"'generic-table-cell-' + i + '-' + column.group.name\"\n >\n @let isMultiline = column.group.multiline ?? true;\n <div\n class=\"flex\"\n [style.alignItems]=\"isMultiline ? column.uiSettings?.align : null\"\n [style.flexDirection]=\"isMultiline ? 'column' : 'row'\"\n [style.justifyContent]=\"\n isMultiline ? null : column.uiSettings?.align\n \"\n >\n @for (\n field of column.group.fields;\n let last = $last;\n track columnTrackBy(field, $index)\n ) {\n <span\n class=\"group-value\"\n [attr.data-testid]=\"\n 'generic-table-cell-' +\n i +\n '-' +\n column.group.name +\n '-' +\n field.property\n \"\n >\n @if (field.label) {\n <span>{{ field.label }}: </span>\n }\n <mfp-resource-field\n [fieldDefinition]=\"field\"\n [resource]=\"item\"\n [permissions]=\"permissions()\"\n (buttonClick)=\"buttonClick.emit($event)\"\n />\n </span>\n @if (!last && column.group.delimiter) {\n <span class=\"delimiter\">{{ column.group.delimiter }}</span>\n }\n }\n </div>\n </ui5-table-cell>\n } @else {\n <ui5-table-cell\n [attr.data-testid]=\"'generic-table-cell-' + i + '-' + column.property\"\n >\n <div class=\"flex\" [style.justifyContent]=\"column.uiSettings?.align\">\n <mfp-resource-field\n [fieldDefinition]=\"column\"\n [resource]=\"item\"\n [permissions]=\"permissions()\"\n (buttonClick)=\"buttonClick.emit($event)\"\n />\n </div>\n </ui5-table-cell>\n }\n }\n </ui5-table-row>\n } @empty {\n <ui5-illustrated-message\n data-testid=\"generic-table-view-nodata\"\n name=\"NoData\"\n slot=\"noData\"\n >\n <span slot=\"title\">No Resources</span>\n <span slot=\"subtitle\">There are currently no items to show.</span>\n </ui5-illustrated-message>\n }\n\n @if (loadMode() !== 'pager' && hasMore()) {\n <ui5-table-growing\n data-testid=\"generic-table-growing\"\n id=\"growing\"\n slot=\"features\"\n [mode]=\"loadMode() === 'scroll' ? 'Scroll' : 'Button'\"\n [text]=\"loadMoreButtonText()\"\n (ui5LoadMore)=\"loadMoreResources.emit()\"\n />\n }\n</ui5-table>\n\n<!-- Pagination Control -->\n<div\n class=\"pagination-footer\"\n style=\"\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0rem 1rem;\n min-height: 3rem;\n border-top: 1px solid var(--sapList_BorderColor);\n \"\n>\n <div class=\"pagination-footer__side\" style=\"display: flex; align-items: center; gap: 0.5rem\">\n <span style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\">\n {{ isPagerMode() ? 'Items per page:' : 'Items per load:' }}\n </span>\n <ui5-select\n data-testid=\"generic-table-pagination-select\"\n style=\"width: 5rem\"\n [value]=\"paginationLimit().toString()\"\n (change)=\"paginationLimitChanged.emit(+$any($event)?.target?.value)\"\n >\n <ui5-option value=\"5\">5</ui5-option>\n <ui5-option value=\"10\">10</ui5-option>\n <ui5-option value=\"20\">20</ui5-option>\n <ui5-option value=\"50\">50</ui5-option>\n <ui5-option value=\"100\">100</ui5-option>\n </ui5-select>\n </div>\n\n @if (isPagerMode()) {\n <div class=\"pager\" data-testid=\"generic-table-pager\">\n @if (knowsTotal()) {\n <ui5-button\n accessibleName=\"First page\"\n data-testid=\"generic-table-pager-first\"\n design=\"Transparent\"\n icon=\"close-command-field\"\n [disabled]=\"!canPrev()\"\n (click)=\"firstPage()\"\n />\n }\n <ui5-button\n accessibleName=\"Previous page\"\n data-testid=\"generic-table-pager-prev\"\n design=\"Transparent\"\n icon=\"navigation-left-arrow\"\n [disabled]=\"!canPrev()\"\n (click)=\"prevPage()\"\n />\n <span\n class=\"pager__indicator\"\n data-testid=\"generic-table-pager-indicator\"\n >{{\n knowsTotal()\n ? (hasResults() ? currentPage() + ' / ' + totalPages() : '\u2013')\n : currentPage()\n }}</span\n >\n <ui5-button\n accessibleName=\"Next page\"\n data-testid=\"generic-table-pager-next\"\n design=\"Transparent\"\n icon=\"navigation-right-arrow\"\n [disabled]=\"!canNext()\"\n (click)=\"nextPage()\"\n />\n @if (knowsTotal()) {\n <ui5-button\n accessibleName=\"Last page\"\n data-testid=\"generic-table-pager-last\"\n design=\"Transparent\"\n icon=\"open-command-field\"\n [disabled]=\"!canNext()\"\n (click)=\"lastPage()\"\n />\n }\n </div>\n <div class=\"pagination-footer__side pagination-footer__side--end\">\n @if (knowsTotal()) {\n <span\n data-testid=\"generic-table-item-count\"\n style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\"\n >\n <b style=\"font-size: var(--sapFontSize)\">{{ totalItemsCount() }}</b>\n Items\n </span>\n }\n </div>\n } @else {\n <div class=\"pagination-footer__side pagination-footer__side--end\">\n <span\n style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\"\n >\n Items loaded:\n <b style=\"font-size: var(--sapFontSize)\">{{\n totalItemsCount() !== undefined\n ? resources().length + ' / ' + totalItemsCount()\n : resources().length\n }}</b>\n </span>\n </div>\n }\n</div>\n", styles: [".multiline{display:block}.disabled{filter:brightness(.92);pointer-events:none}.disabled ui5-table-cell:not(:first-child){color:var(--sapContent_DisabledTextColor, #6a6d70)}.disabled ui5-table-cell:not(:first-child) ui5-icon{color:var(--sapContent_DisabledTextColor, #6a6d70)}.group-value{display:flex;align-items:center}.flex{display:flex;width:100%}.delimiter{min-width:4px}ui5-table-header-row{padding-block-start:.75rem;padding-block-end:.25rem}.pagination-footer{gap:.5rem}.pagination-footer__side{flex:1 1 0;display:flex;align-items:center;gap:.5rem;min-width:0}.pagination-footer__side--end{justify-content:flex-end}.pager{flex:0 0 auto;display:flex;align-items:center;gap:.25rem;justify-content:center}.pager ui5-button{color:var(--sapContent_IconColor, #1d2d3e);--sapButton_IconColor: var(--sapContent_IconColor, #1d2d3e);--sapButton_Hover_IconColor: var(--sapContent_IconColor, #1d2d3e)}.pager ui5-button[disabled]{color:var(--sapContent_DisabledTextColor, #b3b3b3);--sapButton_IconColor: var(--sapContent_DisabledTextColor, #b3b3b3)}.pager__indicator{min-width:3rem;text-align:center;color:var(--sapTextColor);font-size:var(--sapFontSize);font-weight:700}\n"] }]
|
|
2304
|
-
}], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required:
|
|
2749
|
+
], encapsulation: ViewEncapsulation.ShadowDom, template: "<ui5-table\n data-testid=\"generic-table\"\n [loading]=\"loading() && !error()\"\n [loadingDelay]=\"loadingDelay()\"\n [style.height]=\"height() ? height() + 'px' : null\"\n [style.overflow-y]=\"'auto'\"\n>\n <ui5-table-header-row\n slot=\"headerRow\"\n [sticky]=\"loadMode() === 'scroll' && !!height()\"\n >\n @for (column of viewColumns(); track columnTrackBy(column, $index)) {\n @if (column.group) {\n <ui5-table-header-cell\n [attr.data-testid]=\"'generic-table-header-' + column.group.name\"\n [width]=\"column.uiSettings?.columnWidth ?? 'auto'\"\n >{{ column.group.label ?? column.group.name }}</ui5-table-header-cell\n >\n } @else {\n <ui5-table-header-cell\n [attr.data-testid]=\"'generic-table-header-' + column.property\"\n [width]=\"column.uiSettings?.columnWidth ?? 'auto'\"\n >{{ column.label }}</ui5-table-header-cell\n >\n }\n }\n </ui5-table-header-row>\n\n @if (error()) {\n <ui5-illustrated-message\n data-testid=\"generic-table-view-error\"\n name=\"UnableToLoad\"\n slot=\"noData\"\n >\n <ui5-button\n data-testid=\"generic-table-retry\"\n design=\"Emphasized\"\n (click)=\"retry.emit()\"\n >Retry</ui5-button\n >\n </ui5-illustrated-message>\n }\n\n @for (\n item of error() ? [] : resources();\n let i = $index;\n track rowTrackBy($index, item)\n ) {\n <ui5-table-row\n [attr.data-testid]=\"'generic-table-row-' + i\"\n [class.disabled]=\"item.isAvailable === false\"\n [interactive]=\"item.isAvailable !== false\"\n (click)=\"onRowClick(item)\"\n >\n @for (column of viewColumns(); track columnTrackBy(column, $index)) {\n @if (column.group) {\n <ui5-table-cell\n [attr.data-testid]=\"\n 'generic-table-cell-' + i + '-' + column.group.name\n \"\n >\n @let isMultiline = column.group.multiline ?? true;\n <div\n class=\"flex\"\n [style.alignItems]=\"isMultiline ? column.uiSettings?.align : null\"\n [style.flexDirection]=\"isMultiline ? 'column' : 'row'\"\n [style.justifyContent]=\"\n isMultiline ? null : column.uiSettings?.align\n \"\n >\n @for (\n field of column.group.fields;\n let last = $last;\n track columnTrackBy(field, $index)\n ) {\n <span\n class=\"group-value\"\n [attr.data-testid]=\"\n 'generic-table-cell-' +\n i +\n '-' +\n column.group.name +\n '-' +\n field.property\n \"\n >\n @if (field.label) {\n <span>{{ field.label }}: </span>\n }\n <mfp-resource-field\n [fieldDefinition]=\"field\"\n [permissions]=\"permissions()\"\n [resource]=\"item\"\n (buttonClick)=\"buttonClick.emit($event)\"\n />\n </span>\n @if (!last && column.group.delimiter) {\n <span class=\"delimiter\">{{ column.group.delimiter }}</span>\n }\n }\n </div>\n </ui5-table-cell>\n } @else {\n <ui5-table-cell\n [attr.data-testid]=\"\n 'generic-table-cell-' + i + '-' + column.property\n \"\n >\n <div class=\"flex\" [style.justifyContent]=\"column.uiSettings?.align\">\n <mfp-resource-field\n [fieldDefinition]=\"column\"\n [permissions]=\"permissions()\"\n [resource]=\"item\"\n (buttonClick)=\"buttonClick.emit($event)\"\n />\n </div>\n </ui5-table-cell>\n }\n }\n </ui5-table-row>\n } @empty {\n @if (!error()) {\n @if (loading()) {\n <span\n aria-hidden=\"true\"\n data-testid=\"generic-table-view-loading\"\n slot=\"noData\"\n ></span>\n } @else {\n <ui5-illustrated-message\n data-testid=\"generic-table-view-nodata\"\n name=\"NoData\"\n slot=\"noData\"\n >\n <span slot=\"title\">No Resources</span>\n <span slot=\"subtitle\">There are currently no items to show.</span>\n </ui5-illustrated-message>\n }\n }\n }\n\n @if (!error() && !loading() && loadMode() !== 'pager' && hasMore()) {\n <ui5-table-growing\n data-testid=\"generic-table-growing\"\n id=\"growing\"\n slot=\"features\"\n [mode]=\"loadMode() === 'scroll' ? 'Scroll' : 'Button'\"\n [text]=\"loadMoreButtonText()\"\n (ui5LoadMore)=\"loadMoreResources.emit()\"\n />\n }\n</ui5-table>\n\n<!-- Pagination Control -->\n<div\n class=\"pagination-footer\"\n style=\"\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0rem 1rem;\n min-height: 3rem;\n border-top: 1px solid var(--sapList_BorderColor);\n \"\n [hidden]=\"error() || (loading() && resources().length === 0)\"\n>\n <div\n class=\"pagination-footer__side\"\n style=\"display: flex; align-items: center; gap: 0.5rem\"\n >\n <span\n style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\"\n >\n {{ isPagerMode() ? 'Items per page:' : 'Items per load:' }}\n </span>\n <ui5-select\n data-testid=\"generic-table-pagination-select\"\n style=\"width: 5rem\"\n [accessibleName]=\"isPagerMode() ? 'Items per page' : 'Items per load'\"\n [disabled]=\"loading()\"\n [value]=\"paginationLimit().toString()\"\n (change)=\"paginationLimitChanged.emit(+$any($event)?.target?.value)\"\n >\n <ui5-option value=\"5\">5</ui5-option>\n <ui5-option value=\"10\">10</ui5-option>\n <ui5-option value=\"20\">20</ui5-option>\n <ui5-option value=\"50\">50</ui5-option>\n <ui5-option value=\"100\">100</ui5-option>\n </ui5-select>\n </div>\n\n @if (isPagerMode()) {\n <div class=\"pager\" data-testid=\"generic-table-pager\">\n @if (knowsTotal()) {\n <ui5-button\n accessibleName=\"First page\"\n data-testid=\"generic-table-pager-first\"\n design=\"Transparent\"\n icon=\"close-command-field\"\n [disabled]=\"loading() || !canPrev()\"\n (click)=\"firstPage()\"\n />\n }\n <ui5-button\n accessibleName=\"Previous page\"\n data-testid=\"generic-table-pager-prev\"\n design=\"Transparent\"\n icon=\"navigation-left-arrow\"\n [disabled]=\"loading() || !canPrev()\"\n (click)=\"prevPage()\"\n />\n <span\n class=\"pager__indicator\"\n data-testid=\"generic-table-pager-indicator\"\n >{{\n knowsTotal()\n ? hasResults()\n ? currentPage() + ' / ' + totalPages()\n : '\u2013'\n : currentPage()\n }}</span\n >\n <ui5-button\n accessibleName=\"Next page\"\n data-testid=\"generic-table-pager-next\"\n design=\"Transparent\"\n icon=\"navigation-right-arrow\"\n [disabled]=\"loading() || !canNext()\"\n (click)=\"nextPage()\"\n />\n @if (knowsTotal()) {\n <ui5-button\n accessibleName=\"Last page\"\n data-testid=\"generic-table-pager-last\"\n design=\"Transparent\"\n icon=\"open-command-field\"\n [disabled]=\"loading() || !canNext()\"\n (click)=\"lastPage()\"\n />\n }\n </div>\n <div class=\"pagination-footer__side pagination-footer__side--end\">\n @if (knowsTotal()) {\n <span\n data-testid=\"generic-table-item-count\"\n style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\"\n >\n <b style=\"font-size: var(--sapFontSize)\">{{ totalItemsCount() }}</b>\n Items\n </span>\n }\n </div>\n } @else {\n <div class=\"pagination-footer__side pagination-footer__side--end\">\n <span\n style=\"color: var(--sapTextColor); font-size: var(--sapFontSmallSize)\"\n >\n Items loaded:\n <b style=\"font-size: var(--sapFontSize)\">{{\n totalItemsCount() !== undefined\n ? resources().length + ' / ' + totalItemsCount()\n : resources().length\n }}</b>\n </span>\n </div>\n }\n</div>\n", styles: [".multiline{display:block}.disabled{filter:brightness(.92);pointer-events:none}.disabled ui5-table-cell:not(:first-child){color:var(--sapContent_DisabledTextColor, #6a6d70)}.disabled ui5-table-cell:not(:first-child) ui5-icon{color:var(--sapContent_DisabledTextColor, #6a6d70)}.group-value{display:flex;align-items:center}.flex{display:flex;width:100%}.delimiter{min-width:4px}ui5-table-header-row{padding-block-start:.75rem;padding-block-end:.25rem}.pagination-footer{gap:.5rem}.pagination-footer__side{flex:1 1 0;display:flex;align-items:center;gap:.5rem;min-width:0}.pagination-footer__side--end{justify-content:flex-end}.pager{flex:0 0 auto;display:flex;align-items:center;gap:.25rem;justify-content:center}.pager ui5-button{color:var(--sapContent_IconColor, #1d2d3e);--sapButton_IconColor: var(--sapContent_IconColor, #1d2d3e);--sapButton_Hover_IconColor: var(--sapContent_IconColor, #1d2d3e)}.pager ui5-button[disabled]{color:var(--sapContent_DisabledTextColor, #b3b3b3);--sapButton_IconColor: var(--sapContent_DisabledTextColor, #b3b3b3)}.pager__indicator{min-width:3rem;text-align:center;color:var(--sapTextColor);font-size:var(--sapFontSize);font-weight:700}\n"] }]
|
|
2750
|
+
}], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], resources: [{ type: i0.Input, args: [{ isSignal: true, alias: "resources", required: false }] }], trackByPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackByPath", required: false }] }], permissions: [{ type: i0.Input, args: [{ isSignal: true, alias: "permissions", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingDelay", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], totalItemsCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItemsCount", required: false }] }], paginationLimit: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginationLimit", required: false }] }], hasMore: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMore", required: false }] }], loadMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadMode", required: false }] }], loadMoreButtonText: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadMoreButtonText", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }], buttonClick: [{ type: i0.Output, args: ["buttonClick"] }], tableRowClicked: [{ type: i0.Output, args: ["tableRowClicked"] }], loadMoreResources: [{ type: i0.Output, args: ["loadMoreResources"] }], paginationLimitChanged: [{ type: i0.Output, args: ["paginationLimitChanged"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], retry: [{ type: i0.Output, args: ["retry"] }] } });
|
|
2305
2751
|
|
|
2306
2752
|
/**
|
|
2307
2753
|
* Horizontal filter-tab strip rendered above the table by
|
|
@@ -2323,12 +2769,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
2323
2769
|
* forward compatibility with hosts that want to clear the selection.
|
|
2324
2770
|
*/
|
|
2325
2771
|
class FilterTabs {
|
|
2326
|
-
tabs = input.required(
|
|
2772
|
+
tabs = input.required(/* @ts-ignore */
|
|
2773
|
+
...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
|
|
2327
2774
|
tabChanged = output();
|
|
2328
|
-
activeTab = signal(undefined,
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2775
|
+
activeTab = signal(undefined, /* @ts-ignore */
|
|
2776
|
+
...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
|
|
2777
|
+
stripRef = viewChild('strip', /* @ts-ignore */
|
|
2778
|
+
...(ngDevMode ? [{ debugName: "stripRef" }] : /* istanbul ignore next */ []));
|
|
2779
|
+
canScrollLeft = signal(false, /* @ts-ignore */
|
|
2780
|
+
...(ngDevMode ? [{ debugName: "canScrollLeft" }] : /* istanbul ignore next */ []));
|
|
2781
|
+
canScrollRight = signal(false, /* @ts-ignore */
|
|
2782
|
+
...(ngDevMode ? [{ debugName: "canScrollRight" }] : /* istanbul ignore next */ []));
|
|
2332
2783
|
injector = inject(Injector);
|
|
2333
2784
|
resizeObserver;
|
|
2334
2785
|
constructor() {
|
|
@@ -2336,7 +2787,9 @@ class FilterTabs {
|
|
|
2336
2787
|
const tabs = this.tabs();
|
|
2337
2788
|
const next = tabs.find((t) => t.default) ?? tabs[0];
|
|
2338
2789
|
this.activeTab.set(next);
|
|
2339
|
-
afterNextRender(() =>
|
|
2790
|
+
afterNextRender(() => {
|
|
2791
|
+
this.recomputeScrollState();
|
|
2792
|
+
}, {
|
|
2340
2793
|
injector: this.injector,
|
|
2341
2794
|
});
|
|
2342
2795
|
});
|
|
@@ -2344,7 +2797,9 @@ class FilterTabs {
|
|
|
2344
2797
|
const el = this.stripRef()?.nativeElement;
|
|
2345
2798
|
if (!el)
|
|
2346
2799
|
return;
|
|
2347
|
-
this.resizeObserver = new ResizeObserver(() =>
|
|
2800
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
2801
|
+
this.recomputeScrollState();
|
|
2802
|
+
});
|
|
2348
2803
|
this.resizeObserver.observe(el);
|
|
2349
2804
|
this.recomputeScrollState();
|
|
2350
2805
|
}, { injector: this.injector });
|
|
@@ -2387,25 +2842,37 @@ class FilterTabs {
|
|
|
2387
2842
|
this.activeTab.set(tab);
|
|
2388
2843
|
this.tabChanged.emit(tab);
|
|
2389
2844
|
}
|
|
2390
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2391
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2845
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FilterTabs, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2846
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: FilterTabs, isStandalone: true, selector: "mfp-filter-tabs", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { tabChanged: "tabChanged" }, viewQueries: [{ propertyName: "stripRef", first: true, predicate: ["strip"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"filter-tabs\">\n @if (canScrollLeft()) {\n <button\n aria-label=\"Scroll filters left\"\n class=\"filter-tabs__chevron filter-tabs__chevron--left\"\n type=\"button\"\n (click)=\"scroll('left')\"\n >\n <ui5-icon name=\"navigation-left-arrow\" />\n </button>\n }\n <div #strip class=\"filter-tabs__strip\" role=\"tablist\" (scroll)=\"onScroll()\">\n @for (tab of tabs(); track tab.property + ':' + tab.value) {\n <button\n class=\"filter-tabs__tab\"\n role=\"tab\"\n type=\"button\"\n [attr.aria-selected]=\"activeTab() === tab\"\n [class.filter-tabs__tab--active]=\"activeTab() === tab\"\n (click)=\"select(tab)\"\n >\n {{ tab.label }}\n </button>\n }\n </div>\n @if (canScrollRight()) {\n <button\n aria-label=\"Scroll filters right\"\n class=\"filter-tabs__chevron filter-tabs__chevron--right\"\n type=\"button\"\n (click)=\"scroll('right')\"\n >\n <ui5-icon name=\"navigation-right-arrow\" />\n </button>\n }\n</div>\n", styles: [":host{display:block}.filter-tabs{position:relative;display:flex;align-items:stretch;padding:0 1rem;min-height:2.5rem}.filter-tabs__strip{display:flex;flex:1;align-items:stretch;gap:2.25rem;overflow-x:auto;scroll-behavior:smooth;scrollbar-width:none;-ms-overflow-style:none}.filter-tabs__strip::-webkit-scrollbar{display:none}.filter-tabs__tab{appearance:none;background:transparent;border:0;padding:.75rem 0;cursor:pointer;white-space:nowrap;font-family:var(--Font-Family-sapFontFamily, 72);font-size:.875rem;font-weight:500;color:var(--sapTextColor, #1d2d3e);border-bottom:3px solid transparent;transition:color .15s ease,border-color .15s ease}.filter-tabs__tab:hover:not(.filter-tabs__tab--active){color:var(--sapLink_Hover_Color, var(--sapButton_Selected_TextColor, #0070f2))}.filter-tabs__tab:focus-visible{outline:1px solid var(--sapContent_FocusColor, #0070f2);outline-offset:2px}.filter-tabs__tab--active{color:var(--sapButton_Selected_TextColor, var(--sapButton_IconColor, #0070f2));border-bottom-color:var(--sapButton_Selected_BorderColor, var(--sapButton_IconColor, #0070f2))}.filter-tabs__chevron{appearance:none;background:transparent;border:0;cursor:pointer;display:flex;align-items:center;justify-content:center;width:2rem;color:var(--sapButton_IconColor, #0070f2);flex:0 0 auto}.filter-tabs__chevron--left{margin-right:.25rem}.filter-tabs__chevron--right{margin-left:.25rem}.filter-tabs__chevron:hover{background:var(--sapButton_Lite_Hover_Background, rgba(0, 0, 0, .04))}\n"], dependencies: [{ kind: "component", type: Icon, selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2392
2847
|
}
|
|
2393
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2848
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FilterTabs, decorators: [{
|
|
2394
2849
|
type: Component,
|
|
2395
|
-
args: [{ selector: 'mfp-filter-tabs',
|
|
2850
|
+
args: [{ selector: 'mfp-filter-tabs', imports: [Icon], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, template: "<div class=\"filter-tabs\">\n @if (canScrollLeft()) {\n <button\n aria-label=\"Scroll filters left\"\n class=\"filter-tabs__chevron filter-tabs__chevron--left\"\n type=\"button\"\n (click)=\"scroll('left')\"\n >\n <ui5-icon name=\"navigation-left-arrow\" />\n </button>\n }\n <div #strip class=\"filter-tabs__strip\" role=\"tablist\" (scroll)=\"onScroll()\">\n @for (tab of tabs(); track tab.property + ':' + tab.value) {\n <button\n class=\"filter-tabs__tab\"\n role=\"tab\"\n type=\"button\"\n [attr.aria-selected]=\"activeTab() === tab\"\n [class.filter-tabs__tab--active]=\"activeTab() === tab\"\n (click)=\"select(tab)\"\n >\n {{ tab.label }}\n </button>\n }\n </div>\n @if (canScrollRight()) {\n <button\n aria-label=\"Scroll filters right\"\n class=\"filter-tabs__chevron filter-tabs__chevron--right\"\n type=\"button\"\n (click)=\"scroll('right')\"\n >\n <ui5-icon name=\"navigation-right-arrow\" />\n </button>\n }\n</div>\n", styles: [":host{display:block}.filter-tabs{position:relative;display:flex;align-items:stretch;padding:0 1rem;min-height:2.5rem}.filter-tabs__strip{display:flex;flex:1;align-items:stretch;gap:2.25rem;overflow-x:auto;scroll-behavior:smooth;scrollbar-width:none;-ms-overflow-style:none}.filter-tabs__strip::-webkit-scrollbar{display:none}.filter-tabs__tab{appearance:none;background:transparent;border:0;padding:.75rem 0;cursor:pointer;white-space:nowrap;font-family:var(--Font-Family-sapFontFamily, 72);font-size:.875rem;font-weight:500;color:var(--sapTextColor, #1d2d3e);border-bottom:3px solid transparent;transition:color .15s ease,border-color .15s ease}.filter-tabs__tab:hover:not(.filter-tabs__tab--active){color:var(--sapLink_Hover_Color, var(--sapButton_Selected_TextColor, #0070f2))}.filter-tabs__tab:focus-visible{outline:1px solid var(--sapContent_FocusColor, #0070f2);outline-offset:2px}.filter-tabs__tab--active{color:var(--sapButton_Selected_TextColor, var(--sapButton_IconColor, #0070f2));border-bottom-color:var(--sapButton_Selected_BorderColor, var(--sapButton_IconColor, #0070f2))}.filter-tabs__chevron{appearance:none;background:transparent;border:0;cursor:pointer;display:flex;align-items:center;justify-content:center;width:2rem;color:var(--sapButton_IconColor, #0070f2);flex:0 0 auto}.filter-tabs__chevron--left{margin-right:.25rem}.filter-tabs__chevron--right{margin-left:.25rem}.filter-tabs__chevron:hover{background:var(--sapButton_Lite_Hover_Background, rgba(0, 0, 0, .04))}\n"] }]
|
|
2396
2851
|
}], ctorParameters: () => [], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], tabChanged: [{ type: i0.Output, args: ["tabChanged"] }], stripRef: [{ type: i0.ViewChild, args: ['strip', { isSignal: true }] }] } });
|
|
2397
2852
|
|
|
2398
2853
|
class DeclarativeTableCard {
|
|
2399
|
-
resources = input
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2854
|
+
resources = input([], /* @ts-ignore */
|
|
2855
|
+
...(ngDevMode ? [{ debugName: "resources" }] : /* istanbul ignore next */ []));
|
|
2856
|
+
permissions = input(/* @ts-ignore */
|
|
2857
|
+
...(ngDevMode ? [undefined, { debugName: "permissions" }] : /* istanbul ignore next */ []));
|
|
2858
|
+
loading = input(false, /* @ts-ignore */
|
|
2859
|
+
...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
2860
|
+
loadingDelay = input(1000, /* @ts-ignore */
|
|
2861
|
+
...(ngDevMode ? [{ debugName: "loadingDelay" }] : /* istanbul ignore next */ []));
|
|
2862
|
+
error = input(false, /* @ts-ignore */
|
|
2863
|
+
...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
2864
|
+
config = input(undefined, /* @ts-ignore */
|
|
2865
|
+
...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
|
|
2866
|
+
createFormState = input({}, /* @ts-ignore */
|
|
2867
|
+
...(ngDevMode ? [{ debugName: "createFormState" }] : /* istanbul ignore next */ []));
|
|
2868
|
+
editFormState = input({}, /* @ts-ignore */
|
|
2869
|
+
...(ngDevMode ? [{ debugName: "editFormState" }] : /* istanbul ignore next */ []));
|
|
2404
2870
|
actionButtonClick = output();
|
|
2405
2871
|
tableRowClicked = output();
|
|
2406
2872
|
loadMoreResources = output();
|
|
2407
2873
|
paginationLimitChanged = output();
|
|
2408
2874
|
pageChange = output();
|
|
2875
|
+
retry = output();
|
|
2409
2876
|
searchChanged = output();
|
|
2410
2877
|
createFieldChange = output();
|
|
2411
2878
|
editFieldChange = output();
|
|
@@ -2414,33 +2881,48 @@ class DeclarativeTableCard {
|
|
|
2414
2881
|
deleteSubmit = output();
|
|
2415
2882
|
filterTabChanged = output();
|
|
2416
2883
|
searchControl = new FormControl('');
|
|
2417
|
-
createDialogOpen = signal(false,
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2884
|
+
createDialogOpen = signal(false, /* @ts-ignore */
|
|
2885
|
+
...(ngDevMode ? [{ debugName: "createDialogOpen" }] : /* istanbul ignore next */ []));
|
|
2886
|
+
editDialogOpen = signal(false, /* @ts-ignore */
|
|
2887
|
+
...(ngDevMode ? [{ debugName: "editDialogOpen" }] : /* istanbul ignore next */ []));
|
|
2888
|
+
deleteDialogOpen = signal(false, /* @ts-ignore */
|
|
2889
|
+
...(ngDevMode ? [{ debugName: "deleteDialogOpen" }] : /* istanbul ignore next */ []));
|
|
2890
|
+
pendingResource = signal(null, /* @ts-ignore */
|
|
2891
|
+
...(ngDevMode ? [{ debugName: "pendingResource" }] : /* istanbul ignore next */ []));
|
|
2892
|
+
resolvedCreateFields = signal([], /* @ts-ignore */
|
|
2893
|
+
...(ngDevMode ? [{ debugName: "resolvedCreateFields" }] : /* istanbul ignore next */ []));
|
|
2894
|
+
resolvedEditFields = signal([], /* @ts-ignore */
|
|
2895
|
+
...(ngDevMode ? [{ debugName: "resolvedEditFields" }] : /* istanbul ignore next */ []));
|
|
2896
|
+
tableConfig = computed(() => this.config()?.tableConfig, /* @ts-ignore */
|
|
2897
|
+
...(ngDevMode ? [{ debugName: "tableConfig" }] : /* istanbul ignore next */ []));
|
|
2898
|
+
header = computed(() => this.config()?.header, /* @ts-ignore */
|
|
2899
|
+
...(ngDevMode ? [{ debugName: "header" }] : /* istanbul ignore next */ []));
|
|
2900
|
+
headerTooltip = computed(() => this.config()?.headerTooltip, /* @ts-ignore */
|
|
2901
|
+
...(ngDevMode ? [{ debugName: "headerTooltip" }] : /* istanbul ignore next */ []));
|
|
2902
|
+
createFormConfig = computed(() => this.config()?.createResourceFormConfig, /* @ts-ignore */
|
|
2903
|
+
...(ngDevMode ? [{ debugName: "createFormConfig" }] : /* istanbul ignore next */ []));
|
|
2427
2904
|
editFormConfig = computed(() => {
|
|
2428
2905
|
const pendingResource = this.pendingResource();
|
|
2429
2906
|
if (!pendingResource) {
|
|
2430
2907
|
return;
|
|
2431
2908
|
}
|
|
2432
|
-
return this.config()
|
|
2433
|
-
},
|
|
2909
|
+
return this.config()?.editResourceFormConfig?.(pendingResource);
|
|
2910
|
+
}, /* @ts-ignore */
|
|
2911
|
+
...(ngDevMode ? [{ debugName: "editFormConfig" }] : /* istanbul ignore next */ []));
|
|
2434
2912
|
deleteConfirmationConfig = computed(() => {
|
|
2435
2913
|
const pendingResource = this.pendingResource();
|
|
2436
2914
|
if (!pendingResource) {
|
|
2437
2915
|
return;
|
|
2438
2916
|
}
|
|
2439
|
-
return this.config()
|
|
2440
|
-
},
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2917
|
+
return this.config()?.deleteResourceConfirmationConfig?.(pendingResource);
|
|
2918
|
+
}, /* @ts-ignore */
|
|
2919
|
+
...(ngDevMode ? [{ debugName: "deleteConfirmationConfig" }] : /* istanbul ignore next */ []));
|
|
2920
|
+
createButtonConfig = computed(() => this.config()?.buttonSettings?.createButton, /* @ts-ignore */
|
|
2921
|
+
...(ngDevMode ? [{ debugName: "createButtonConfig" }] : /* istanbul ignore next */ []));
|
|
2922
|
+
searchButtonConfig = computed(() => this.config()?.buttonSettings?.searchButton, /* @ts-ignore */
|
|
2923
|
+
...(ngDevMode ? [{ debugName: "searchButtonConfig" }] : /* istanbul ignore next */ []));
|
|
2924
|
+
effectiveColumns = computed(() => this.tableConfig()?.fields ?? [], /* @ts-ignore */
|
|
2925
|
+
...(ngDevMode ? [{ debugName: "effectiveColumns" }] : /* istanbul ignore next */ []));
|
|
2444
2926
|
editInitialValue = computed(() => {
|
|
2445
2927
|
const pendingResource = this.pendingResource();
|
|
2446
2928
|
const editConfig = this.editFormConfig();
|
|
@@ -2448,10 +2930,14 @@ class DeclarativeTableCard {
|
|
|
2448
2930
|
return {};
|
|
2449
2931
|
}
|
|
2450
2932
|
return this.buildInitialValues(this.resolvedEditFields(), pendingResource);
|
|
2451
|
-
},
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2933
|
+
}, /* @ts-ignore */
|
|
2934
|
+
...(ngDevMode ? [{ debugName: "editInitialValue" }] : /* istanbul ignore next */ []));
|
|
2935
|
+
searchConfig = computed(() => this.config()?.searchConfig, /* @ts-ignore */
|
|
2936
|
+
...(ngDevMode ? [{ debugName: "searchConfig" }] : /* istanbul ignore next */ []));
|
|
2937
|
+
resourcesSearchable = computed(() => !!this.searchConfig(), /* @ts-ignore */
|
|
2938
|
+
...(ngDevMode ? [{ debugName: "resourcesSearchable" }] : /* istanbul ignore next */ []));
|
|
2939
|
+
searchPlaceholder = computed(() => this.searchConfig()?.placeholder ?? 'Search', /* @ts-ignore */
|
|
2940
|
+
...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : /* istanbul ignore next */ []));
|
|
2455
2941
|
filterTabs = computed(() => {
|
|
2456
2942
|
const tabs = this.searchConfig()?.filterTabs;
|
|
2457
2943
|
if (!tabs?.length)
|
|
@@ -2468,8 +2954,10 @@ class DeclarativeTableCard {
|
|
|
2468
2954
|
: tab.default
|
|
2469
2955
|
? { ...tab, default: false }
|
|
2470
2956
|
: tab);
|
|
2471
|
-
},
|
|
2472
|
-
|
|
2957
|
+
}, /* @ts-ignore */
|
|
2958
|
+
...(ngDevMode ? [{ debugName: "filterTabs" }] : /* istanbul ignore next */ []));
|
|
2959
|
+
hasFilterTabs = computed(() => this.filterTabs().length > 0, /* @ts-ignore */
|
|
2960
|
+
...(ngDevMode ? [{ debugName: "hasFilterTabs" }] : /* istanbul ignore next */ []));
|
|
2473
2961
|
constructor() {
|
|
2474
2962
|
this.searchControl.valueChanges
|
|
2475
2963
|
.pipe(debounceTime(500), distinctUntilChanged(), takeUntilDestroyed())
|
|
@@ -2510,7 +2998,7 @@ class DeclarativeTableCard {
|
|
|
2510
2998
|
this.createDialogOpen.set(true);
|
|
2511
2999
|
}
|
|
2512
3000
|
async openEditDialog(resource) {
|
|
2513
|
-
const config = this.config()
|
|
3001
|
+
const config = this.config()?.editResourceFormConfig?.(resource);
|
|
2514
3002
|
const fields = await this.resolveFormFields(config?.fields);
|
|
2515
3003
|
// A newer update action may have replaced the pending resource while we
|
|
2516
3004
|
// awaited the field resolver; ignore this stale result so the dialog never
|
|
@@ -2570,10 +3058,10 @@ class DeclarativeTableCard {
|
|
|
2570
3058
|
return acc;
|
|
2571
3059
|
}, {});
|
|
2572
3060
|
}
|
|
2573
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2574
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3061
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DeclarativeTableCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3062
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: DeclarativeTableCard, isStandalone: true, selector: "mfp-declarative-table-card", inputs: { resources: { classPropertyName: "resources", publicName: "resources", isSignal: true, isRequired: false, transformFunction: null }, permissions: { classPropertyName: "permissions", publicName: "permissions", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingDelay: { classPropertyName: "loadingDelay", publicName: "loadingDelay", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, 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", pageChange: "pageChange", retry: "retry", searchChanged: "searchChanged", createFieldChange: "createFieldChange", editFieldChange: "editFieldChange", createSubmit: "createSubmit", editSubmit: "editSubmit", deleteSubmit: "deleteSubmit", filterTabChanged: "filterTabChanged" }, 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 <ui5-input\n class=\"card__search-input\"\n data-testid=\"generic-table-card-search-input\"\n [formControl]=\"searchControl\"\n [placeholder]=\"searchPlaceholder()\"\n [showClearIcon]=\"true\"\n >\n <ui5-icon\n class=\"card__search-icon\"\n data-testid=\"generic-table-card-search-icon\"\n name=\"search\"\n slot=\"icon\"\n [accessibleName]=\"searchButtonConfig()?.tooltip ?? 'Search'\"\n [showTooltip]=\"true\"\n (click)=\"submitSearch()\"\n />\n </ui5-input>\n }\n @if (createFormConfig()) {\n <ui5-button\n class=\"card__create-btn\"\n data-testid=\"generic-table-card-create-btn\"\n [accessibleName]=\"\n createButtonConfig()?.text ||\n createButtonConfig()?.tooltip ||\n 'Create'\n \"\n [design]=\"createButtonConfig()?.design ?? 'Transparent'\"\n [icon]=\"createButtonConfig()?.icon ?? 'add'\"\n [tooltip]=\"createButtonConfig()?.tooltip\"\n (click)=\"openCreateDialog()\"\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 [currentPage]=\"config.currentPage ?? 1\"\n [error]=\"error()\"\n [hasMore]=\"config.hasMore ?? false\"\n [height]=\"config.height\"\n [loadMode]=\"config.loadMode ?? 'button'\"\n [loadMoreButtonText]=\"config.loadMoreButtonText ?? 'Load More'\"\n [loading]=\"loading()\"\n [loadingDelay]=\"loadingDelay()\"\n [paginationLimit]=\"config.paginationLimit ?? 5\"\n [permissions]=\"permissions()\"\n [resources]=\"resources()\"\n [totalItemsCount]=\"config.totalItemsCount\"\n (buttonClick)=\"onButtonClick($event)\"\n (loadMoreResources)=\"loadMoreResources.emit()\"\n (pageChange)=\"pageChange.emit($event)\"\n (paginationLimitChanged)=\"paginationLimitChanged.emit($event)\"\n (retry)=\"retry.emit()\"\n (tableRowClicked)=\"tableRowClicked.emit($event)\"\n />\n }\n </div>\n</div>\n\n@if (createDialogOpen()) {\n <mfp-resource-form-dialog\n dataTestidPrefix=\"generic-table-card-create\"\n defaultConfirmLabel=\"Save\"\n defaultTitle=\"Create\"\n [config]=\"createFormConfig()\"\n [fieldErrors]=\"createFormState().fieldErrors ?? {}\"\n [fields]=\"resolvedCreateFields()\"\n [initialValues]=\"{}\"\n [open]=\"createDialogOpen()\"\n (cancelled)=\"closeCreateDialog()\"\n (fieldChange)=\"onCreateFieldChange($event)\"\n (submitted)=\"onCreateSubmit($event)\"\n />\n}\n\n@if (editDialogOpen()) {\n <mfp-resource-form-dialog\n dataTestidPrefix=\"generic-table-card-edit\"\n defaultConfirmLabel=\"Edit\"\n defaultTitle=\"Edit\"\n [config]=\"editFormConfig()\"\n [fieldErrors]=\"editFormState().fieldErrors ?? {}\"\n [fields]=\"resolvedEditFields()\"\n [initialValues]=\"editInitialValue()\"\n [open]=\"editDialogOpen()\"\n (cancelled)=\"closeEditDialog()\"\n (fieldChange)=\"onEditFieldChange($event)\"\n (submitted)=\"onEditSubmit($event)\"\n />\n}\n\n<mfp-delete-confirmation-dialog\n [config]=\"deleteConfirmationConfig()\"\n [open]=\"deleteDialogOpen()\"\n (cancelled)=\"closeDeleteDialog()\"\n (confirmed)=\"onDeleteSubmit()\"\n/>\n", styles: [":host{display:block}.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-icon{cursor:pointer}.card__create-btn{min-width:auto;color:var(--sapButton_IconColor, #0070f2)}.card__body{flex:1;overflow:auto}\n"], dependencies: [{ kind: "component", type: DeclarativeTable, selector: "mfp-declarative-table", inputs: ["columns", "resources", "trackByPath", "permissions", "loading", "loadingDelay", "error", "totalItemsCount", "paginationLimit", "hasMore", "loadMode", "loadMoreButtonText", "height", "currentPage"], outputs: ["buttonClick", "tableRowClicked", "loadMoreResources", "paginationLimitChanged", "pageChange", "retry"] }, { 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: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Icon, selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }, { kind: "component", type: Input, selector: "ui5-input, [ui5-input]", inputs: ["accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "disabled", "filter", "maxlength", "name", "noTypeahead", "open", "placeholder", "readonly", "required", "showClearIcon", "showSuggestions", "type", "value", "valueState"], outputs: ["ui5Change", "ui5Close", "ui5Input", "ui5Open", "ui5Select", "ui5SelectionChange"], exportAs: ["ui5Input"] }, { kind: "component", type: ResourceFormDialog, selector: "mfp-resource-form-dialog", inputs: ["open", "config", "fields", "fieldErrors", "initialValues", "defaultTitle", "defaultConfirmLabel", "defaultCancelLabel", "dataTestidPrefix"], outputs: ["fieldChange", "submitted", "cancelled"] }, { kind: "component", type: DeleteConfirmationDialog, selector: "mfp-delete-confirmation-dialog", inputs: ["open", "config"], outputs: ["confirmed", "cancelled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2575
3063
|
}
|
|
2576
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3064
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DeclarativeTableCard, decorators: [{
|
|
2577
3065
|
type: Component,
|
|
2578
3066
|
args: [{ selector: 'mfp-declarative-table-card', imports: [
|
|
2579
3067
|
DeclarativeTable,
|
|
@@ -2584,36 +3072,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
2584
3072
|
Input,
|
|
2585
3073
|
ResourceFormDialog,
|
|
2586
3074
|
DeleteConfirmationDialog,
|
|
2587
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, schemas: [CUSTOM_ELEMENTS_SCHEMA], 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 <ui5-input\n class=\"card__search-input\"\n data-testid=\"generic-table-card-search-input\"\n [formControl]=\"searchControl\"\n [placeholder]=\"searchPlaceholder()\"\n [showClearIcon]=\"true\"\n >\n <ui5-icon\n class=\"card__search-icon\"\n data-testid=\"generic-table-card-search-icon\"\n name=\"search\"\n slot=\"icon\"\n [accessibleName]=\"searchButtonConfig()?.tooltip ?? 'Search'\"\n [showTooltip]=\"true\"\n (click)=\"submitSearch()\"\n />\n </ui5-input>\n }\n @if (createFormConfig()) {\n <ui5-button\n class=\"card__create-btn\"\n data-testid=\"generic-table-card-create-btn\"\n [accessibleName]=\"\n createButtonConfig()?.text ||\n createButtonConfig()?.tooltip ||\n 'Create'\n \"\n [design]=\"createButtonConfig()?.design ?? 'Transparent'\"\n [icon]=\"createButtonConfig()?.icon ?? 'add'\"\n [tooltip]=\"createButtonConfig()?.tooltip\"\n (click)=\"openCreateDialog()\"\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 [currentPage]=\"config.currentPage ?? 1\"\n [hasMore]=\"config.hasMore ?? false\"\n [height]=\"config.height\"\n [loadMode]=\"config.loadMode ?? 'button'\"\n [loadMoreButtonText]=\"config.loadMoreButtonText ?? 'Load More'\"\n [paginationLimit]=\"config.paginationLimit ?? 5\"\n [permissions]=\"permissions()\"\n [resources]=\"resources()\"\n [totalItemsCount]=\"config.totalItemsCount\"\n (buttonClick)=\"onButtonClick($event)\"\n (loadMoreResources)=\"loadMoreResources.emit()\"\n (pageChange)=\"pageChange.emit($event)\"\n (paginationLimitChanged)=\"paginationLimitChanged.emit($event)\"\n (tableRowClicked)=\"tableRowClicked.emit($event)\"\n />\n }\n </div>\n</div>\n\n@if (createDialogOpen()) {\n <mfp-resource-form-dialog\n
|
|
2588
|
-
}], ctorParameters: () => [], propDecorators: { resources: [{ type: i0.Input, args: [{ isSignal: true, alias: "resources", required:
|
|
3075
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, schemas: [CUSTOM_ELEMENTS_SCHEMA], 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 <ui5-input\n class=\"card__search-input\"\n data-testid=\"generic-table-card-search-input\"\n [formControl]=\"searchControl\"\n [placeholder]=\"searchPlaceholder()\"\n [showClearIcon]=\"true\"\n >\n <ui5-icon\n class=\"card__search-icon\"\n data-testid=\"generic-table-card-search-icon\"\n name=\"search\"\n slot=\"icon\"\n [accessibleName]=\"searchButtonConfig()?.tooltip ?? 'Search'\"\n [showTooltip]=\"true\"\n (click)=\"submitSearch()\"\n />\n </ui5-input>\n }\n @if (createFormConfig()) {\n <ui5-button\n class=\"card__create-btn\"\n data-testid=\"generic-table-card-create-btn\"\n [accessibleName]=\"\n createButtonConfig()?.text ||\n createButtonConfig()?.tooltip ||\n 'Create'\n \"\n [design]=\"createButtonConfig()?.design ?? 'Transparent'\"\n [icon]=\"createButtonConfig()?.icon ?? 'add'\"\n [tooltip]=\"createButtonConfig()?.tooltip\"\n (click)=\"openCreateDialog()\"\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 [currentPage]=\"config.currentPage ?? 1\"\n [error]=\"error()\"\n [hasMore]=\"config.hasMore ?? false\"\n [height]=\"config.height\"\n [loadMode]=\"config.loadMode ?? 'button'\"\n [loadMoreButtonText]=\"config.loadMoreButtonText ?? 'Load More'\"\n [loading]=\"loading()\"\n [loadingDelay]=\"loadingDelay()\"\n [paginationLimit]=\"config.paginationLimit ?? 5\"\n [permissions]=\"permissions()\"\n [resources]=\"resources()\"\n [totalItemsCount]=\"config.totalItemsCount\"\n (buttonClick)=\"onButtonClick($event)\"\n (loadMoreResources)=\"loadMoreResources.emit()\"\n (pageChange)=\"pageChange.emit($event)\"\n (paginationLimitChanged)=\"paginationLimitChanged.emit($event)\"\n (retry)=\"retry.emit()\"\n (tableRowClicked)=\"tableRowClicked.emit($event)\"\n />\n }\n </div>\n</div>\n\n@if (createDialogOpen()) {\n <mfp-resource-form-dialog\n dataTestidPrefix=\"generic-table-card-create\"\n defaultConfirmLabel=\"Save\"\n defaultTitle=\"Create\"\n [config]=\"createFormConfig()\"\n [fieldErrors]=\"createFormState().fieldErrors ?? {}\"\n [fields]=\"resolvedCreateFields()\"\n [initialValues]=\"{}\"\n [open]=\"createDialogOpen()\"\n (cancelled)=\"closeCreateDialog()\"\n (fieldChange)=\"onCreateFieldChange($event)\"\n (submitted)=\"onCreateSubmit($event)\"\n />\n}\n\n@if (editDialogOpen()) {\n <mfp-resource-form-dialog\n dataTestidPrefix=\"generic-table-card-edit\"\n defaultConfirmLabel=\"Edit\"\n defaultTitle=\"Edit\"\n [config]=\"editFormConfig()\"\n [fieldErrors]=\"editFormState().fieldErrors ?? {}\"\n [fields]=\"resolvedEditFields()\"\n [initialValues]=\"editInitialValue()\"\n [open]=\"editDialogOpen()\"\n (cancelled)=\"closeEditDialog()\"\n (fieldChange)=\"onEditFieldChange($event)\"\n (submitted)=\"onEditSubmit($event)\"\n />\n}\n\n<mfp-delete-confirmation-dialog\n [config]=\"deleteConfirmationConfig()\"\n [open]=\"deleteDialogOpen()\"\n (cancelled)=\"closeDeleteDialog()\"\n (confirmed)=\"onDeleteSubmit()\"\n/>\n", styles: [":host{display:block}.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-icon{cursor:pointer}.card__create-btn{min-width:auto;color:var(--sapButton_IconColor, #0070f2)}.card__body{flex:1;overflow:auto}\n"] }]
|
|
3076
|
+
}], ctorParameters: () => [], propDecorators: { resources: [{ type: i0.Input, args: [{ isSignal: true, alias: "resources", required: false }] }], permissions: [{ type: i0.Input, args: [{ isSignal: true, alias: "permissions", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingDelay", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], createFormState: [{ type: i0.Input, args: [{ isSignal: true, alias: "createFormState", required: false }] }], editFormState: [{ type: i0.Input, args: [{ isSignal: true, alias: "editFormState", required: false }] }], actionButtonClick: [{ type: i0.Output, args: ["actionButtonClick"] }], tableRowClicked: [{ type: i0.Output, args: ["tableRowClicked"] }], loadMoreResources: [{ type: i0.Output, args: ["loadMoreResources"] }], paginationLimitChanged: [{ type: i0.Output, args: ["paginationLimitChanged"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], retry: [{ type: i0.Output, args: ["retry"] }], searchChanged: [{ type: i0.Output, args: ["searchChanged"] }], createFieldChange: [{ type: i0.Output, args: ["createFieldChange"] }], editFieldChange: [{ type: i0.Output, args: ["editFieldChange"] }], createSubmit: [{ type: i0.Output, args: ["createSubmit"] }], editSubmit: [{ type: i0.Output, args: ["editSubmit"] }], deleteSubmit: [{ type: i0.Output, args: ["deleteSubmit"] }], filterTabChanged: [{ type: i0.Output, args: ["filterTabChanged"] }] } });
|
|
2589
3077
|
|
|
2590
3078
|
class VisitedServiceCard {
|
|
2591
|
-
serviceType = input.required(
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
3079
|
+
serviceType = input.required(/* @ts-ignore */
|
|
3080
|
+
...(ngDevMode ? [{ debugName: "serviceType" }] : /* istanbul ignore next */ []));
|
|
3081
|
+
serviceName = input.required(/* @ts-ignore */
|
|
3082
|
+
...(ngDevMode ? [{ debugName: "serviceName" }] : /* istanbul ignore next */ []));
|
|
3083
|
+
serviceDescription = input.required(/* @ts-ignore */
|
|
3084
|
+
...(ngDevMode ? [{ debugName: "serviceDescription" }] : /* istanbul ignore next */ []));
|
|
3085
|
+
serviceIcon = input.required(/* @ts-ignore */
|
|
3086
|
+
...(ngDevMode ? [{ debugName: "serviceIcon" }] : /* istanbul ignore next */ []));
|
|
3087
|
+
path = input.required(/* @ts-ignore */
|
|
3088
|
+
...(ngDevMode ? [{ debugName: "path" }] : /* istanbul ignore next */ []));
|
|
2596
3089
|
cardClick = output();
|
|
2597
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2598
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
3090
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: VisitedServiceCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3091
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.2", type: VisitedServiceCard, isStandalone: true, selector: "mfp-visited-service-card", inputs: { serviceType: { classPropertyName: "serviceType", publicName: "serviceType", isSignal: true, isRequired: true, transformFunction: null }, serviceName: { classPropertyName: "serviceName", publicName: "serviceName", isSignal: true, isRequired: true, transformFunction: null }, serviceDescription: { classPropertyName: "serviceDescription", publicName: "serviceDescription", isSignal: true, isRequired: true, transformFunction: null }, serviceIcon: { classPropertyName: "serviceIcon", publicName: "serviceIcon", isSignal: true, isRequired: true, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { cardClick: "cardClick" }, ngImport: i0, template: "<div\n class=\"visited-card-wrapper\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"cardClick.emit(path())\"\n (keydown.enter)=\"cardClick.emit(path())\"\n (keydown.space)=\"$event.preventDefault(); cardClick.emit(path())\"\n>\n <span class=\"visited-card__type-badge\">{{ serviceType() }}</span>\n <ui5-card class=\"visited-card\">\n <ui5-card-header\n slot=\"header\"\n [interactive]=\"false\"\n [subtitleText]=\"serviceDescription()\"\n [titleText]=\"serviceName()\"\n >\n <ui5-icon\n class=\"visited-card__icon\"\n slot=\"avatar\"\n [name]=\"serviceIcon()\"\n />\n </ui5-card-header>\n </ui5-card>\n</div>\n", styles: [":host{display:block}.visited-card-wrapper{position:relative;cursor:pointer}.visited-card{width:100%}.visited-card__type-badge{position:absolute;top:-.625rem;right:.75rem;display:inline-block;padding:.125rem .625rem;border-radius:.75rem;background-color:#e8f3ff;color:#0070f2;font-size:var(--sapFontSmallSize, .75rem);font-weight:700;white-space:nowrap;z-index:1}.visited-card__icon{width:2.5rem;height:2.5rem;color:var(--sapHighlightColor, #0070f2)}\n"], dependencies: [{ kind: "component", type: Card, selector: "ui5-card, [ui5-card]", inputs: ["accessibleName", "accessibleNameRef", "loading", "loadingDelay"], exportAs: ["ui5Card"] }, { kind: "component", type: CardHeader, selector: "ui5-card-header, [ui5-card-header]", inputs: ["additionalText", "interactive", "subtitleText", "titleText"], outputs: ["ui5Click"], exportAs: ["ui5CardHeader"] }, { kind: "component", type: Icon, selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2599
3092
|
}
|
|
2600
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3093
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: VisitedServiceCard, decorators: [{
|
|
2601
3094
|
type: Component,
|
|
2602
|
-
args: [{ selector: 'mfp-visited-service-card', imports: [Card, CardHeader, Icon], encapsulation: ViewEncapsulation.ShadowDom, template: "<div\n class=\"visited-card-wrapper\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"cardClick.emit(path())\"\n (keydown.enter)=\"cardClick.emit(path())\"\n>\n <span class=\"visited-card__type-badge\">{{ serviceType() }}</span>\n <ui5-card class=\"visited-card\">\n <ui5-card-header\n slot=\"header\"\n [interactive]=\"
|
|
3095
|
+
args: [{ selector: 'mfp-visited-service-card', imports: [Card, CardHeader, Icon], encapsulation: ViewEncapsulation.ShadowDom, template: "<div\n class=\"visited-card-wrapper\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"cardClick.emit(path())\"\n (keydown.enter)=\"cardClick.emit(path())\"\n (keydown.space)=\"$event.preventDefault(); cardClick.emit(path())\"\n>\n <span class=\"visited-card__type-badge\">{{ serviceType() }}</span>\n <ui5-card class=\"visited-card\">\n <ui5-card-header\n slot=\"header\"\n [interactive]=\"false\"\n [subtitleText]=\"serviceDescription()\"\n [titleText]=\"serviceName()\"\n >\n <ui5-icon\n class=\"visited-card__icon\"\n slot=\"avatar\"\n [name]=\"serviceIcon()\"\n />\n </ui5-card-header>\n </ui5-card>\n</div>\n", styles: [":host{display:block}.visited-card-wrapper{position:relative;cursor:pointer}.visited-card{width:100%}.visited-card__type-badge{position:absolute;top:-.625rem;right:.75rem;display:inline-block;padding:.125rem .625rem;border-radius:.75rem;background-color:#e8f3ff;color:#0070f2;font-size:var(--sapFontSmallSize, .75rem);font-weight:700;white-space:nowrap;z-index:1}.visited-card__icon{width:2.5rem;height:2.5rem;color:var(--sapHighlightColor, #0070f2)}\n"] }]
|
|
2603
3096
|
}], propDecorators: { serviceType: [{ type: i0.Input, args: [{ isSignal: true, alias: "serviceType", required: true }] }], serviceName: [{ type: i0.Input, args: [{ isSignal: true, alias: "serviceName", required: true }] }], serviceDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "serviceDescription", required: true }] }], serviceIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "serviceIcon", required: true }] }], path: [{ type: i0.Input, args: [{ isSignal: true, alias: "path", required: true }] }], cardClick: [{ type: i0.Output, args: ["cardClick"] }] } });
|
|
2604
3097
|
|
|
2605
3098
|
class Favorites {
|
|
2606
3099
|
items = [
|
|
2607
3100
|
{ label: 'Create Account', icon: 'add', action: 'create-account' },
|
|
2608
|
-
{
|
|
2609
|
-
|
|
3101
|
+
{
|
|
3102
|
+
label: 'Start Approval',
|
|
3103
|
+
icon: 'workflow-tasks',
|
|
3104
|
+
action: 'start-approval',
|
|
3105
|
+
},
|
|
3106
|
+
{
|
|
3107
|
+
label: 'Add User to Account',
|
|
3108
|
+
icon: 'person-placeholder',
|
|
3109
|
+
action: 'add-user',
|
|
3110
|
+
},
|
|
2610
3111
|
];
|
|
2611
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2612
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3112
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Favorites, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3113
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: Favorites, isStandalone: true, selector: "mfp-favorites", ngImport: i0, template: "<div class=\"favorites\">\n <ui5-title class=\"favorites__title\" level=\"H5\">Favorites</ui5-title>\n <div class=\"favorites__list\">\n @for (item of items; track item.action) {\n <div class=\"favorites__item\">\n <ui5-icon class=\"favorites__icon\" [name]=\"item.icon\" />\n <span class=\"favorites__label\">{{ item.label }}</span>\n <ui5-button design=\"Transparent\" [icon]=\"item.icon\">{{\n item.label\n }}</ui5-button>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.favorites{display:flex;flex-direction:column;height:100%;background:var(--sapTile_Background, #fff);border-radius:var(--_ui5_card_border-radius, .5rem);border:var(--_ui5_card_border, 1px solid var(--sapTile_BorderColor, #e5e5e5));box-shadow:var(--_ui5_card_box_shadow, var(--sapContent_Shadow0));overflow:hidden}.favorites__title{padding:1rem 1rem .5rem;flex-shrink:0}.favorites__list{display:flex;flex-direction:column;flex:1;overflow-y:auto}.favorites__item{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem;border-bottom:1px solid var(--sapList_BorderColor, #e5e5e5)}.favorites__item:last-child{border-bottom:none}.favorites__icon{flex-shrink:0;color:var(--sapHighlightColor, #0070f2)}.favorites__label{flex:1;font-size:var(--sapFontSize, .875rem);color:var(--sapTextColor, #32363a)}\n"], dependencies: [{ kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Icon, selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["level", "size", "wrappingType"], exportAs: ["ui5Title"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2613
3114
|
}
|
|
2614
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Favorites, decorators: [{
|
|
2615
3116
|
type: Component,
|
|
2616
|
-
args: [{ selector: 'mfp-favorites', imports: [Button, Icon, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<div class=\"favorites\">\n <ui5-title class=\"favorites__title\" level=\"H5\">Favorites</ui5-title>\n <div class=\"favorites__list\">\n @for (item of items; track item.action) {\n <div class=\"favorites__item\">\n <ui5-icon class=\"favorites__icon\" [name]=\"item.icon\" />\n <span class=\"favorites__label\">{{ item.label }}</span>\n <ui5-button design=\"Transparent\" [icon]=\"item.icon\">{{
|
|
3117
|
+
args: [{ selector: 'mfp-favorites', imports: [Button, Icon, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<div class=\"favorites\">\n <ui5-title class=\"favorites__title\" level=\"H5\">Favorites</ui5-title>\n <div class=\"favorites__list\">\n @for (item of items; track item.action) {\n <div class=\"favorites__item\">\n <ui5-icon class=\"favorites__icon\" [name]=\"item.icon\" />\n <span class=\"favorites__label\">{{ item.label }}</span>\n <ui5-button design=\"Transparent\" [icon]=\"item.icon\">{{\n item.label\n }}</ui5-button>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.favorites{display:flex;flex-direction:column;height:100%;background:var(--sapTile_Background, #fff);border-radius:var(--_ui5_card_border-radius, .5rem);border:var(--_ui5_card_border, 1px solid var(--sapTile_BorderColor, #e5e5e5));box-shadow:var(--_ui5_card_box_shadow, var(--sapContent_Shadow0));overflow:hidden}.favorites__title{padding:1rem 1rem .5rem;flex-shrink:0}.favorites__list{display:flex;flex-direction:column;flex:1;overflow-y:auto}.favorites__item{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem;border-bottom:1px solid var(--sapList_BorderColor, #e5e5e5)}.favorites__item:last-child{border-bottom:none}.favorites__icon{flex-shrink:0;color:var(--sapHighlightColor, #0070f2)}.favorites__label{flex:1;font-size:var(--sapFontSize, .875rem);color:var(--sapTextColor, #32363a)}\n"] }]
|
|
2617
3118
|
}] });
|
|
2618
3119
|
|
|
2619
3120
|
class ServiceStatusCard {
|
|
@@ -2626,17 +3127,33 @@ class ServiceStatusCard {
|
|
|
2626
3127
|
{ name: 'Audit Log', icon: 'log', status: 'outage' },
|
|
2627
3128
|
];
|
|
2628
3129
|
statusConfig = {
|
|
2629
|
-
operational: {
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
3130
|
+
operational: {
|
|
3131
|
+
label: 'Operational',
|
|
3132
|
+
icon: 'status-positive',
|
|
3133
|
+
colorClass: 'status--operational',
|
|
3134
|
+
},
|
|
3135
|
+
degraded: {
|
|
3136
|
+
label: 'Degraded',
|
|
3137
|
+
icon: 'status-critical',
|
|
3138
|
+
colorClass: 'status--degraded',
|
|
3139
|
+
},
|
|
3140
|
+
outage: {
|
|
3141
|
+
label: 'Outage',
|
|
3142
|
+
icon: 'status-negative',
|
|
3143
|
+
colorClass: 'status--outage',
|
|
3144
|
+
},
|
|
3145
|
+
maintenance: {
|
|
3146
|
+
label: 'Maintenance',
|
|
3147
|
+
icon: 'status-inactive',
|
|
3148
|
+
colorClass: 'status--maintenance',
|
|
3149
|
+
},
|
|
2633
3150
|
};
|
|
2634
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2635
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3151
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ServiceStatusCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3152
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: ServiceStatusCard, isStandalone: true, selector: "mfp-service-status-card", ngImport: i0, template: "<div class=\"service-status\">\n <ui5-title class=\"service-status__title\" level=\"H5\"\n >Service Availability</ui5-title\n >\n <div class=\"service-status__list\">\n @for (service of services; track service.name) {\n <div class=\"service-status__item\">\n <ui5-icon class=\"service-status__icon\" [name]=\"service.icon\" />\n <span class=\"service-status__name\">{{ service.name }}</span>\n <div\n [class]=\"\n 'service-status__status ' + statusConfig[service.status].colorClass\n \"\n >\n <ui5-icon\n class=\"service-status__status-icon\"\n [name]=\"statusConfig[service.status].icon\"\n />\n <span class=\"service-status__status-label\">{{\n statusConfig[service.status].label\n }}</span>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.service-status{display:flex;flex-direction:column;height:100%;background:var(--sapTile_Background, #fff);border-radius:var(--_ui5_card_border-radius, .5rem);border:var(--_ui5_card_border, 1px solid var(--sapTile_BorderColor, #e5e5e5));box-shadow:var(--_ui5_card_box_shadow, var(--sapContent_Shadow0));overflow:hidden}.service-status__title{padding:1rem 1rem .5rem;flex-shrink:0}.service-status__list{display:flex;flex-direction:column;flex:1;overflow-y:auto}.service-status__item{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem;border-bottom:1px solid var(--sapList_BorderColor, #e5e5e5)}.service-status__item:last-child{border-bottom:none}.service-status__icon{flex-shrink:0;color:var(--sapHighlightColor, #0070f2)}.service-status__name{flex:1;font-size:var(--sapFontSize, .875rem);color:var(--sapTextColor, #32363a)}.service-status__status{display:flex;align-items:center;gap:.25rem;flex-shrink:0;font-size:.75rem;font-weight:500;border-radius:.75rem;padding:.125rem .5rem}.service-status__status--operational{color:var(--sapPositiveColor, #256f3a);background:var(--sapPositiveBackground, #f1fdf6)}.service-status__status--degraded{color:var(--sapCriticalColor, #e76500);background:var(--sapCriticalBackground, #fef7f1)}.service-status__status--outage{color:var(--sapNegativeColor, #aa0808);background:var(--sapNegativeBackground, #fff1f1)}.service-status__status--maintenance{color:var(--sapNeutralColor, #5b738b);background:var(--sapNeutralBackground, #f5f6f7)}.service-status__status-icon{font-size:.75rem;width:.875rem;height:.875rem}\n"], dependencies: [{ kind: "component", type: Icon, selector: "ui5-icon, [ui5-icon]", inputs: ["accessibleName", "design", "mode", "name", "showTooltip"], outputs: ["ui5Click"], exportAs: ["ui5Icon"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["level", "size", "wrappingType"], exportAs: ["ui5Title"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2636
3153
|
}
|
|
2637
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3154
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ServiceStatusCard, decorators: [{
|
|
2638
3155
|
type: Component,
|
|
2639
|
-
args: [{ selector: 'mfp-service-status-card', imports: [Icon, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<div class=\"service-status\">\n <ui5-title class=\"service-status__title\" level=\"H5\">Service Availability</ui5-title>\n <div class=\"service-status__list\">\n @for (service of services; track service.name) {\n <div class=\"service-status__item\">\n <ui5-icon class=\"service-status__icon\" [name]=\"service.icon\" />\n <span class=\"service-status__name\">{{ service.name }}</span>\n <div
|
|
3156
|
+
args: [{ selector: 'mfp-service-status-card', imports: [Icon, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<div class=\"service-status\">\n <ui5-title class=\"service-status__title\" level=\"H5\"\n >Service Availability</ui5-title\n >\n <div class=\"service-status__list\">\n @for (service of services; track service.name) {\n <div class=\"service-status__item\">\n <ui5-icon class=\"service-status__icon\" [name]=\"service.icon\" />\n <span class=\"service-status__name\">{{ service.name }}</span>\n <div\n [class]=\"\n 'service-status__status ' + statusConfig[service.status].colorClass\n \"\n >\n <ui5-icon\n class=\"service-status__status-icon\"\n [name]=\"statusConfig[service.status].icon\"\n />\n <span class=\"service-status__status-label\">{{\n statusConfig[service.status].label\n }}</span>\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.service-status{display:flex;flex-direction:column;height:100%;background:var(--sapTile_Background, #fff);border-radius:var(--_ui5_card_border-radius, .5rem);border:var(--_ui5_card_border, 1px solid var(--sapTile_BorderColor, #e5e5e5));box-shadow:var(--_ui5_card_box_shadow, var(--sapContent_Shadow0));overflow:hidden}.service-status__title{padding:1rem 1rem .5rem;flex-shrink:0}.service-status__list{display:flex;flex-direction:column;flex:1;overflow-y:auto}.service-status__item{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem;border-bottom:1px solid var(--sapList_BorderColor, #e5e5e5)}.service-status__item:last-child{border-bottom:none}.service-status__icon{flex-shrink:0;color:var(--sapHighlightColor, #0070f2)}.service-status__name{flex:1;font-size:var(--sapFontSize, .875rem);color:var(--sapTextColor, #32363a)}.service-status__status{display:flex;align-items:center;gap:.25rem;flex-shrink:0;font-size:.75rem;font-weight:500;border-radius:.75rem;padding:.125rem .5rem}.service-status__status--operational{color:var(--sapPositiveColor, #256f3a);background:var(--sapPositiveBackground, #f1fdf6)}.service-status__status--degraded{color:var(--sapCriticalColor, #e76500);background:var(--sapCriticalBackground, #fef7f1)}.service-status__status--outage{color:var(--sapNegativeColor, #aa0808);background:var(--sapNegativeBackground, #fff1f1)}.service-status__status--maintenance{color:var(--sapNeutralColor, #5b738b);background:var(--sapNeutralBackground, #f5f6f7)}.service-status__status-icon{font-size:.75rem;width:.875rem;height:.875rem}\n"] }]
|
|
2640
3157
|
}] });
|
|
2641
3158
|
|
|
2642
3159
|
class WhatsNew {
|
|
@@ -2672,20 +3189,21 @@ class WhatsNew {
|
|
|
2672
3189
|
icon: 'accelerated',
|
|
2673
3190
|
},
|
|
2674
3191
|
];
|
|
2675
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2676
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3192
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WhatsNew, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3193
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: WhatsNew, isStandalone: true, selector: "mfp-whats-new", ngImport: i0, template: "<div class=\"whats-new\">\n <ui5-title class=\"whats-new__title\" level=\"H5\">What's New</ui5-title>\n <ui5-list class=\"whats-new__list\" separators=\"Inner\">\n @for (item of headlines; track item.title) {\n <ui5-li [description]=\"item.description\" [icon]=\"item.icon\">\n {{ item.title }}\n </ui5-li>\n }\n </ui5-list>\n</div>\n", styles: [":host{display:block;height:100%}.whats-new{display:flex;flex-direction:column;height:100%;background:var(--sapTile_Background, #fff);border-radius:var(--_ui5_card_border-radius, .5rem);border:var(--_ui5_card_border, 1px solid var(--sapTile_BorderColor, #e5e5e5));box-shadow:var(--_ui5_card_box_shadow, var(--sapContent_Shadow0));overflow:hidden}.whats-new__title{padding:1rem 1rem .5rem;flex-shrink:0}.whats-new__list{flex:1;overflow-y:auto}\n"], dependencies: [{ kind: "component", type: List, selector: "ui5-list, [ui5-list]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleDescriptionRef", "accessibleName", "accessibleNameRef", "accessibleRole", "footerText", "growing", "growingButtonText", "headerText", "indent", "loading", "loadingDelay", "noDataText", "selectionMode", "separators", "stickyHeader"], outputs: ["ui5ItemClick", "ui5ItemClose", "ui5ItemDelete", "ui5ItemToggle", "ui5LoadMore", "ui5Move", "ui5MoveOver", "ui5SelectionChange"], exportAs: ["ui5List"] }, { kind: "component", type: ListItemStandard, selector: "ui5-li, [ui5-li]", inputs: ["accessibilityAttributes", "accessibleName", "accessibleRole", "additionalText", "additionalTextState", "description", "highlight", "icon", "iconEnd", "movable", "navigated", "selected", "text", "tooltip", "type", "wrappingType"], outputs: ["ui5Click", "ui5DetailClick"], exportAs: ["ui5ListItemStandard"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["level", "size", "wrappingType"], exportAs: ["ui5Title"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2677
3194
|
}
|
|
2678
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3195
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: WhatsNew, decorators: [{
|
|
2679
3196
|
type: Component,
|
|
2680
3197
|
args: [{ selector: 'mfp-whats-new', imports: [List, ListItemStandard, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<div class=\"whats-new\">\n <ui5-title class=\"whats-new__title\" level=\"H5\">What's New</ui5-title>\n <ui5-list class=\"whats-new__list\" separators=\"Inner\">\n @for (item of headlines; track item.title) {\n <ui5-li [description]=\"item.description\" [icon]=\"item.icon\">\n {{ item.title }}\n </ui5-li>\n }\n </ui5-list>\n</div>\n", styles: [":host{display:block;height:100%}.whats-new{display:flex;flex-direction:column;height:100%;background:var(--sapTile_Background, #fff);border-radius:var(--_ui5_card_border-radius, .5rem);border:var(--_ui5_card_border, 1px solid var(--sapTile_BorderColor, #e5e5e5));box-shadow:var(--_ui5_card_box_shadow, var(--sapContent_Shadow0));overflow:hidden}.whats-new__title{padding:1rem 1rem .5rem;flex-shrink:0}.whats-new__list{flex:1;overflow-y:auto}\n"] }]
|
|
2681
3198
|
}] });
|
|
2682
3199
|
|
|
2683
3200
|
class MockCard {
|
|
2684
|
-
title = input('Card Name',
|
|
2685
|
-
|
|
2686
|
-
static
|
|
3201
|
+
title = input('Card Name', /* @ts-ignore */
|
|
3202
|
+
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
3203
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: MockCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3204
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.2", type: MockCard, isStandalone: true, selector: "mfp-mock-card", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"mock-card\">\n <div class=\"mock-card__header\">\n <ui5-title class=\"mock-card__title\" level=\"H5\">{{ title() }}</ui5-title>\n <ui5-button\n accessibleName=\"More actions\"\n class=\"mock-card__menu\"\n design=\"Transparent\"\n icon=\"overflow\"\n />\n </div>\n <div class=\"mock-card__body\"></div>\n</div>\n", styles: [":host{display:block;height:100%}.mock-card{display:flex;flex-direction:column;height:100%;background:var(--sapTile_Background, #fff);border-radius:12px;border:var(--_ui5_card_border, 1px solid var(--sapTile_BorderColor, #e5e5e5));box-shadow:var(--_ui5_card_box_shadow, var(--sapContent_Shadow0));overflow:hidden}.mock-card__header{display:flex;align-items:center;justify-content:space-between;padding:.75rem .5rem .75rem 1rem;flex-shrink:0}.mock-card__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mock-card__menu{flex-shrink:0}.mock-card__body{flex:1;min-height:20rem}\n"], dependencies: [{ kind: "component", type: Button, selector: "ui5-button, [ui5-button]", inputs: ["accessibilityAttributes", "accessibleDescription", "accessibleName", "accessibleNameRef", "accessibleRole", "design", "disabled", "endIcon", "form", "icon", "loading", "loadingDelay", "submits", "tooltip", "type"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["level", "size", "wrappingType"], exportAs: ["ui5Title"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2687
3205
|
}
|
|
2688
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3206
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: MockCard, decorators: [{
|
|
2689
3207
|
type: Component,
|
|
2690
3208
|
args: [{ selector: 'mfp-mock-card', imports: [Button, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<div class=\"mock-card\">\n <div class=\"mock-card__header\">\n <ui5-title class=\"mock-card__title\" level=\"H5\">{{ title() }}</ui5-title>\n <ui5-button\n accessibleName=\"More actions\"\n class=\"mock-card__menu\"\n design=\"Transparent\"\n icon=\"overflow\"\n />\n </div>\n <div class=\"mock-card__body\"></div>\n</div>\n", styles: [":host{display:block;height:100%}.mock-card{display:flex;flex-direction:column;height:100%;background:var(--sapTile_Background, #fff);border-radius:12px;border:var(--_ui5_card_border, 1px solid var(--sapTile_BorderColor, #e5e5e5));box-shadow:var(--_ui5_card_box_shadow, var(--sapContent_Shadow0));overflow:hidden}.mock-card__header{display:flex;align-items:center;justify-content:space-between;padding:.75rem .5rem .75rem 1rem;flex-shrink:0}.mock-card__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mock-card__menu{flex-shrink:0}.mock-card__body{flex:1;min-height:20rem}\n"] }]
|
|
2691
3209
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }] } });
|
|
@@ -2694,5 +3212,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
2694
3212
|
* Generated bundle index. Do not edit.
|
|
2695
3213
|
*/
|
|
2696
3214
|
|
|
2697
|
-
export { BooleanValue, CARD_TYPES, Dashboard, DeclarativeForm, DeclarativeTable, DeclarativeTableCard, DeleteConfirmationDialog, Favorites, LinkValue, MockCard, ResourceField, ResourceFormDialog, SanitizeHtmlPipe, SecretValue, ServiceStatusCard, TagListValue, VisitedServiceCard, WhatsNew, defineDashboardElementMethods };
|
|
3215
|
+
export { BooleanValue, CARD_TYPES, DASHBOARD_I18N_KEYS, Dashboard, DashboardI18nService, DeclarativeForm, DeclarativeTable, DeclarativeTableCard, DeleteConfirmationDialog, EN_DEFAULTS, Favorites, LinkValue, MockCard, ResourceField, ResourceFormDialog, SanitizeHtmlPipe, SecretValue, ServiceStatusCard, TagListValue, VisitedServiceCard, WhatsNew, defineDashboardElementMethods };
|
|
2698
3216
|
//# sourceMappingURL=openmfp-ngx.mjs.map
|