@openmfp/ngx 0.18.3 → 0.18.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/openmfp-ngx.mjs +561 -75
- package/fesm2022/openmfp-ngx.mjs.map +1 -1
- package/package.json +2 -2
- package/types/openmfp-ngx.d.ts +97 -46
package/fesm2022/openmfp-ngx.mjs
CHANGED
|
@@ -32,6 +32,12 @@ import { Dialog } from '@fundamental-ngx/ui5-webcomponents/dialog';
|
|
|
32
32
|
import { Title } from '@fundamental-ngx/ui5-webcomponents/title';
|
|
33
33
|
import '@ui5/webcomponents-icons/dist/search.js';
|
|
34
34
|
import { debounceTime, distinctUntilChanged, map, filter } from 'rxjs';
|
|
35
|
+
import '@ui5/webcomponents-icons/dist/resize-corner.js';
|
|
36
|
+
import '@ui5/webcomponents-icons/dist/alert.js';
|
|
37
|
+
import { List } from '@fundamental-ngx/ui5-webcomponents/list';
|
|
38
|
+
import { ListItemCustom } from '@fundamental-ngx/ui5-webcomponents/list-item-custom';
|
|
39
|
+
import { Switch } from '@fundamental-ngx/ui5-webcomponents/switch';
|
|
40
|
+
import { GridStackEngine } from 'gridstack/dist/gridstack-engine';
|
|
35
41
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
36
42
|
import { Menu } from '@fundamental-ngx/ui5-webcomponents/menu';
|
|
37
43
|
import { MenuItem } from '@fundamental-ngx/ui5-webcomponents/menu-item';
|
|
@@ -40,14 +46,10 @@ import '@ui5/webcomponents-icons/dist/action-settings.js';
|
|
|
40
46
|
import '@ui5/webcomponents-icons/dist/menu2.js';
|
|
41
47
|
import '@ui5/webcomponents-icons/dist/user-edit.js';
|
|
42
48
|
import { GridstackComponent, GridstackItemComponent } from 'gridstack/dist/angular';
|
|
43
|
-
import '@ui5/webcomponents-icons/dist/resize-corner.js';
|
|
44
|
-
import '@ui5/webcomponents-icons/dist/alert.js';
|
|
45
|
-
import { List } from '@fundamental-ngx/ui5-webcomponents/list';
|
|
46
|
-
import { ListItemCustom } from '@fundamental-ngx/ui5-webcomponents/list-item-custom';
|
|
47
|
-
import { Switch } from '@fundamental-ngx/ui5-webcomponents/switch';
|
|
48
49
|
import { Card } from '@fundamental-ngx/ui5-webcomponents/card';
|
|
49
50
|
import { CardHeader } from '@fundamental-ngx/ui5-webcomponents/card-header';
|
|
50
51
|
import { ListItemStandard } from '@fundamental-ngx/ui5-webcomponents/list-item-standard';
|
|
52
|
+
import '@ui5/webcomponents-icons/dist/overflow.js';
|
|
51
53
|
|
|
52
54
|
const getResourceValueByJsonPath = (resource, field) => {
|
|
53
55
|
const property = field.jsonPathExpression || field.property;
|
|
@@ -1127,6 +1129,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
1127
1129
|
], 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 [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 @let config = createFormConfig();\n <ui5-dialog\n data-testid=\"generic-table-card-create-dialog\"\n [accessibleName]=\"config?.title ?? 'Create'\"\n [open]=\"true\"\n (ui5BeforeClose)=\"createDialogOpen.set(false)\"\n >\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{ config?.title ?? 'Create' }}</ui5-title>\n </div>\n <div class=\"dialog__body\">\n <mfp-declarative-form\n #createForm\n [fieldErrors]=\"createFormState().fieldErrors ?? {}\"\n [fields]=\"resolvedCreateFields()\"\n (fieldChange)=\"onCreateFieldChange($event)\"\n (formSubmit)=\"onCreateSubmit($event)\"\n />\n </div>\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"generic-table-card-create-confirm\"\n design=\"Emphasized\"\n [disabled]=\"hasErrors(createFormState())\"\n (click)=\"createForm.submit()\"\n >\n {{ config?.confirmLabel ?? 'Save' }}\n </ui5-button>\n <ui5-button\n data-testid=\"generic-table-card-create-cancel\"\n design=\"Transparent\"\n (click)=\"closeCreateDialog()\"\n >\n {{ config?.cancelLabel ?? 'Cancel' }}\n </ui5-button>\n </div>\n </ui5-dialog>\n}\n\n@if (editDialogOpen()) {\n @let config = editFormConfig();\n <ui5-dialog\n data-testid=\"generic-table-card-edit-dialog\"\n [accessibleName]=\"config?.title ?? 'Edit'\"\n [open]=\"true\"\n (ui5BeforeClose)=\"editDialogOpen.set(false)\"\n >\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{ config?.title ?? 'Edit' }}</ui5-title>\n </div>\n <div class=\"dialog__body\">\n <mfp-declarative-form\n #editForm\n [fieldErrors]=\"editFormState().fieldErrors ?? {}\"\n [fields]=\"resolvedEditFields()\"\n [initialValues]=\"editInitialValue()\"\n (fieldChange)=\"onEditFieldChange($event)\"\n (formSubmit)=\"onEditSubmit($event)\"\n />\n </div>\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"generic-table-card-edit-confirm\"\n design=\"Emphasized\"\n [disabled]=\"hasErrors(editFormState())\"\n (click)=\"editForm.submit()\"\n >\n {{ config?.confirmLabel ?? 'Edit' }}\n </ui5-button>\n <ui5-button\n data-testid=\"generic-table-card-edit-cancel\"\n design=\"Transparent\"\n (click)=\"closeEditDialog()\"\n >\n {{ config?.cancelLabel ?? 'Cancel' }}\n </ui5-button>\n </div>\n </ui5-dialog>\n}\n\n@if (deleteConfirmationConfig(); as config) {\n <ui5-dialog\n data-testid=\"generic-table-card-delete-dialog\"\n [accessibleName]=\"config.title ?? 'Confirm Delete'\"\n [open]=\"deleteDialogOpen()\"\n (ui5BeforeClose)=\"deleteDialogOpen.set(false)\"\n >\n <div class=\"dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{ config.title ?? 'Confirm Delete' }}</ui5-title>\n </div>\n @if (config.message) {\n <div class=\"dialog__body\">\n <p class=\"dialog__message\">{{ config.message }}</p>\n </div>\n }\n <div class=\"dialog__footer\" slot=\"footer\">\n <ui5-button\n data-testid=\"generic-table-card-delete-confirm\"\n design=\"Negative\"\n (click)=\"onDeleteSubmit()\"\n >\n {{ config.confirmLabel ?? 'Delete' }}\n </ui5-button>\n <ui5-button\n data-testid=\"generic-table-card-delete-cancel\"\n design=\"Transparent\"\n (click)=\"closeDeleteDialog()\"\n >\n {{ config.cancelLabel ?? 'Cancel' }}\n </ui5-button>\n </div>\n </ui5-dialog>\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}.dialog__header{display:flex;align-items:flex-start;padding:.75rem 1rem}.dialog__body{margin:-1rem;min-width:320px;padding:1rem}.dialog__message{padding:1rem;margin:0;font-size:.875rem;max-width:320px}.dialog__footer{display:flex;justify-content:space-between;align-items:center;gap:.5rem;padding:.5rem 1rem;margin:0 -1rem;width:100%}\n"] }]
|
|
1128
1130
|
}], ctorParameters: () => [], propDecorators: { resources: [{ type: i0.Input, args: [{ isSignal: true, alias: "resources", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], 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"] }], 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"] }] } });
|
|
1129
1131
|
|
|
1132
|
+
/** Default engine breakpoints: 14/12/8/1 columns (matches main). */
|
|
1133
|
+
const DASHBOARD_BREAKPOINTS = [
|
|
1134
|
+
{ w: 4000, c: 14, layout: 'compact' },
|
|
1135
|
+
{ w: 1439, c: 12, layout: 'compact' },
|
|
1136
|
+
{ w: 1023, c: 8, layout: 'compact' },
|
|
1137
|
+
{ w: 599, c: 1, layout: 'list' },
|
|
1138
|
+
];
|
|
1139
|
+
/** zFlow engine breakpoints: 4/4/4/1 columns. */
|
|
1140
|
+
const ZFLOW_DASHBOARD_BREAKPOINTS = [
|
|
1141
|
+
{ w: 4000, c: 4, layout: 'compact' },
|
|
1142
|
+
{ w: 1439, c: 4, layout: 'compact' },
|
|
1143
|
+
{ w: 1023, c: 4, layout: 'compact' },
|
|
1144
|
+
{ w: 599, c: 1, layout: 'list' },
|
|
1145
|
+
];
|
|
1146
|
+
const XL_PAGE = 1440;
|
|
1147
|
+
|
|
1148
|
+
const COMPACT_BREAKPOINT = 726;
|
|
1149
|
+
const CELL_HEIGHT = 10;
|
|
1150
|
+
const DASHBOARD_CARD_DRAG_ORIGIN_CLASS = 'mfp-dashboard-card-drag-origin';
|
|
1151
|
+
const DASHBOARD_CARD_DRAG_ORIGIN_SELECTOR = `.${DASHBOARD_CARD_DRAG_ORIGIN_CLASS}`;
|
|
1152
|
+
|
|
1130
1153
|
var unsavedChanges$1 = "Nicht gespeicherte Änderungen";
|
|
1131
1154
|
var editCards$1 = "Karten bearbeiten";
|
|
1132
1155
|
var editView$1 = "Ansicht bearbeiten";
|
|
@@ -1357,6 +1380,8 @@ class DashboardCard {
|
|
|
1357
1380
|
removeCard = output();
|
|
1358
1381
|
i18n = inject(DashboardI18nService);
|
|
1359
1382
|
i18nKeys = DASHBOARD_I18N_KEYS;
|
|
1383
|
+
componentHostClasses = `component-host ${DASHBOARD_CARD_DRAG_ORIGIN_CLASS}`;
|
|
1384
|
+
cardBodyClasses = `card__body ${DASHBOARD_CARD_DRAG_ORIGIN_CLASS}`;
|
|
1360
1385
|
gridColumn = computed(() => {
|
|
1361
1386
|
const width = this.card().w ?? 12;
|
|
1362
1387
|
return this.createGridTrack(this.card().x, width);
|
|
@@ -1406,27 +1431,16 @@ class DashboardCard {
|
|
|
1406
1431
|
return `${start + 1} / span ${span}`;
|
|
1407
1432
|
}
|
|
1408
1433
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DashboardCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1409
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", 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 class=\"component-card\" [attr.data-testid]=\"'dashboard-card-' + card().id\" [class.component-card--editing]=\"editMode()\">\n @if (editMode()) {\n <div class=\"remove-wrapper\">\n <ui5-button\n class=\"card__remove\"\n design=\"Default\"\n icon=\"decline\"\n [attr.data-testid]=\"'dashboard-card-' + card().id + '-remove'\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_CARD) +\n ': ' +\n (card().label || card().component)\n \"\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 class=\"
|
|
1434
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", 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 class=\"component-card\" [attr.data-testid]=\"'dashboard-card-' + card().id\" [class.component-card--editing]=\"editMode()\">\n @if (editMode()) {\n <div class=\"remove-wrapper\">\n <ui5-button\n class=\"card__remove\"\n design=\"Default\"\n icon=\"decline\"\n [attr.data-testid]=\"'dashboard-card-' + card().id + '-remove'\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_CARD) +\n ': ' +\n (card().label || card().component)\n \"\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 [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 [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}.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--editing:hover{--sapTile_BorderColor: var(--sapHighlightColor, #0070f2);--sapGroup_ContentBorderColor: var(--sapHighlightColor, #0070f2)}.component-card--editing:hover .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: ["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"] }] });
|
|
1410
1435
|
}
|
|
1411
1436
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DashboardCard, decorators: [{
|
|
1412
1437
|
type: Component,
|
|
1413
1438
|
args: [{ selector: 'mfp-dashboard-card', imports: [Button, Icon], encapsulation: ViewEncapsulation.Emulated, host: {
|
|
1414
1439
|
'[style.grid-column]': 'gridColumn()',
|
|
1415
1440
|
'[style.grid-row]': 'gridRow()',
|
|
1416
|
-
}, template: "@if (card().component) {\n <div class=\"component-card\" [attr.data-testid]=\"'dashboard-card-' + card().id\" [class.component-card--editing]=\"editMode()\">\n @if (editMode()) {\n <div class=\"remove-wrapper\">\n <ui5-button\n class=\"card__remove\"\n design=\"Default\"\n icon=\"decline\"\n [attr.data-testid]=\"'dashboard-card-' + card().id + '-remove'\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_CARD) +\n ': ' +\n (card().label || card().component)\n \"\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 class=\"
|
|
1441
|
+
}, template: "@if (card().component) {\n <div class=\"component-card\" [attr.data-testid]=\"'dashboard-card-' + card().id\" [class.component-card--editing]=\"editMode()\">\n @if (editMode()) {\n <div class=\"remove-wrapper\">\n <ui5-button\n class=\"card__remove\"\n design=\"Default\"\n icon=\"decline\"\n [attr.data-testid]=\"'dashboard-card-' + card().id + '-remove'\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_CARD) +\n ': ' +\n (card().label || card().component)\n \"\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 [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 [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}.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--editing:hover{--sapTile_BorderColor: var(--sapHighlightColor, #0070f2);--sapGroup_ContentBorderColor: var(--sapHighlightColor, #0070f2)}.component-card--editing:hover .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"] }]
|
|
1417
1442
|
}], 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 }] }] } });
|
|
1418
1443
|
|
|
1419
|
-
/** Single source of truth for grid + section breakpoints (TypeScript half). */
|
|
1420
|
-
const DASHBOARD_BREAKPOINTS = [
|
|
1421
|
-
{ w: 4000, c: 14, layout: 'compact' },
|
|
1422
|
-
{ w: 1439, c: 12, layout: 'compact' },
|
|
1423
|
-
{ w: 1023, c: 8, layout: 'compact' },
|
|
1424
|
-
{ w: 599, c: 1, layout: 'list' },
|
|
1425
|
-
];
|
|
1426
|
-
|
|
1427
|
-
const COMPACT_BREAKPOINT = 726;
|
|
1428
|
-
const CELL_HEIGHT = 10;
|
|
1429
|
-
|
|
1430
1444
|
/**
|
|
1431
1445
|
* Confirmation popup shown when the user tries to abandon edit mode while
|
|
1432
1446
|
* there are unsaved dashboard changes. Emits `confirm` when the user accepts
|
|
@@ -1549,7 +1563,7 @@ class DashboardSection {
|
|
|
1549
1563
|
removeSection = output();
|
|
1550
1564
|
removeCard = output();
|
|
1551
1565
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DashboardSection, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1552
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", 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 [attr.data-testid]=\"'dashboard-section-' + section().id + '-remove'\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_SECTION) +\n ': ' +\n (section().title || section().id)\n \"\n (click)=\"removeSection.emit()\"\n />\n }\n @if (section().title) {\n <div class=\"section__header\">\n <span class=\"section__title\" [attr.data-testid]=\"'dashboard-section-' + section().id + '-title'\">{{ section().title }}</span>\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, 14),1fr)}@container mfp-dashboard (max-width: 599px){.section__grid{grid-template-columns:repeat(var(--cols, 1),1fr)}}@container mfp-dashboard (min-width: 600px) and (max-width: 1023px){.section__grid{grid-template-columns:repeat(var(--cols, 8),1fr)}}@container mfp-dashboard (min-width: 1024px) and (max-width: 1439px){.section__grid{grid-template-columns:repeat(var(--cols, 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: ["design", "disabled", "icon", "endIcon", "submits", "tooltip", "accessibleName", "accessibleNameRef", "accessibilityAttributes", "accessibleDescription", "type", "accessibleRole", "loading", "loadingDelay"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }] });
|
|
1566
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", 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 [attr.data-testid]=\"'dashboard-section-' + section().id + '-remove'\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_SECTION) +\n ': ' +\n (section().title || section().id)\n \"\n (click)=\"removeSection.emit()\"\n />\n }\n @if (section().title) {\n <div class=\"section__header\">\n <span class=\"section__title\" [attr.data-testid]=\"'dashboard-section-' + section().id + '-title'\">{{ section().title }}</span>\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: ["design", "disabled", "icon", "endIcon", "submits", "tooltip", "accessibleName", "accessibleNameRef", "accessibilityAttributes", "accessibleDescription", "type", "accessibleRole", "loading", "loadingDelay"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }] });
|
|
1553
1567
|
}
|
|
1554
1568
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DashboardSection, decorators: [{
|
|
1555
1569
|
type: Component,
|
|
@@ -1565,7 +1579,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
1565
1579
|
// cover 12 of 14 columns, leaving a dead 2-col gutter on the right and
|
|
1566
1580
|
// squeezing the cards inside it relative to the outer grid's units.
|
|
1567
1581
|
'[style.grid-column]': 'section().w === undefined || section().w === 12 ? "1 / -1" : "span " + section().w',
|
|
1568
|
-
}, 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 [attr.data-testid]=\"'dashboard-section-' + section().id + '-remove'\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_SECTION) +\n ': ' +\n (section().title || section().id)\n \"\n (click)=\"removeSection.emit()\"\n />\n }\n @if (section().title) {\n <div class=\"section__header\">\n <span class=\"section__title\" [attr.data-testid]=\"'dashboard-section-' + section().id + '-title'\">{{ section().title }}</span>\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, 14),1fr)}@container mfp-dashboard (max-width: 599px){.section__grid{grid-template-columns:repeat(var(--cols, 1),1fr)}}@container mfp-dashboard (min-width: 600px) and (max-width: 1023px){.section__grid{grid-template-columns:repeat(var(--cols, 8),1fr)}}@container mfp-dashboard (min-width: 1024px) and (max-width: 1439px){.section__grid{grid-template-columns:repeat(var(--cols, 12),1fr)}}\n"] }]
|
|
1582
|
+
}, 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 [attr.data-testid]=\"'dashboard-section-' + section().id + '-remove'\"\n [accessibleName]=\"\n i18n.getTranslation(i18nKeys.REMOVE_SECTION) +\n ': ' +\n (section().title || section().id)\n \"\n (click)=\"removeSection.emit()\"\n />\n }\n @if (section().title) {\n <div class=\"section__header\">\n <span class=\"section__title\" [attr.data-testid]=\"'dashboard-section-' + section().id + '-title'\">{{ section().title }}</span>\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"] }]
|
|
1569
1583
|
}], 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"] }] } });
|
|
1570
1584
|
|
|
1571
1585
|
/**
|
|
@@ -1593,11 +1607,398 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
1593
1607
|
args: [{ selector: 'mfp-unsaved-changes-dialog', imports: [Button, Dialog, Title], encapsulation: ViewEncapsulation.ShadowDom, template: "<ui5-dialog data-testid=\"dashboard-unsaved-changes-dialog\" state=\"Critical\" [open]=\"open()\" (ui5BeforeClose)=\"cancelled.emit()\">\n <div class=\"unsaved-changes-dialog__header\" slot=\"header\">\n <ui5-title level=\"H5\">{{ i18n.getTranslation(i18nKeys.UNSAVED_CHANGES) }}</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 data-testid=\"dashboard-unsaved-changes-save-btn\" design=\"Emphasized\" (click)=\"save.emit()\">{{ i18n.getTranslation(i18nKeys.SAVE) }}</ui5-button>\n <ui5-button data-testid=\"dashboard-unsaved-changes-discard-btn\" design=\"Transparent\" (click)=\"discard.emit()\">{{ i18n.getTranslation(i18nKeys.DISCARD) }}</ui5-button>\n <ui5-button data-testid=\"dashboard-unsaved-changes-cancel-btn\" design=\"Transparent\" (click)=\"cancelled.emit()\">{{ i18n.getTranslation(i18nKeys.CANCEL) }}</ui5-button>\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"] }]
|
|
1594
1608
|
}], 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"] }] } });
|
|
1595
1609
|
|
|
1610
|
+
function getAllowedResizeWidths(maxWidth, columnCount, minWidth = 1, effectiveMax = columnCount) {
|
|
1611
|
+
return [1, 2, maxWidth]
|
|
1612
|
+
.map((w) => Math.min(Math.max(w, minWidth), columnCount))
|
|
1613
|
+
.filter((w, i, list) => list.indexOf(w) === i && w <= effectiveMax)
|
|
1614
|
+
.sort((a, b) => a - b);
|
|
1615
|
+
}
|
|
1616
|
+
function resolveResizeWidthStep(rawWidth, maxWidth, columnCount, minWidth = 1, effectiveMax = columnCount) {
|
|
1617
|
+
const allowed = getAllowedResizeWidths(maxWidth, columnCount, minWidth, effectiveMax);
|
|
1618
|
+
if (!allowed.length) {
|
|
1619
|
+
return effectiveMax;
|
|
1620
|
+
}
|
|
1621
|
+
return allowed.reduce((best, candidate) => {
|
|
1622
|
+
return Math.abs(candidate - rawWidth) <= Math.abs(best - rawWidth)
|
|
1623
|
+
? candidate
|
|
1624
|
+
: best;
|
|
1625
|
+
}, allowed[0]);
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
function hasZFlowOrder(nodes) {
|
|
1629
|
+
return nodes.some((n) => n.zFlowOrder !== undefined);
|
|
1630
|
+
}
|
|
1631
|
+
function syncNodeOrderFromLayout(nodes) {
|
|
1632
|
+
const sorted = [...nodes].sort(compareNodesByLayoutPosition);
|
|
1633
|
+
sorted.forEach((n, i) => {
|
|
1634
|
+
n.zFlowOrder = i;
|
|
1635
|
+
});
|
|
1636
|
+
}
|
|
1637
|
+
function seedNodeOrder(nodes) {
|
|
1638
|
+
if (hasZFlowOrder(nodes))
|
|
1639
|
+
return;
|
|
1640
|
+
syncNodeOrderFromLayout(nodes);
|
|
1641
|
+
}
|
|
1642
|
+
function sortNodesByZFlowOrder(nodes) {
|
|
1643
|
+
return [...nodes].sort((a, b) => {
|
|
1644
|
+
if (a.zFlowOrder !== undefined && b.zFlowOrder !== undefined) {
|
|
1645
|
+
return a.zFlowOrder - b.zFlowOrder;
|
|
1646
|
+
}
|
|
1647
|
+
if (a.zFlowOrder !== undefined)
|
|
1648
|
+
return -1;
|
|
1649
|
+
if (b.zFlowOrder !== undefined)
|
|
1650
|
+
return 1;
|
|
1651
|
+
const ay = a.y ?? 0;
|
|
1652
|
+
const by = b.y ?? 0;
|
|
1653
|
+
if (ay !== by)
|
|
1654
|
+
return ay - by;
|
|
1655
|
+
return (a.x ?? 0) - (b.x ?? 0);
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1658
|
+
function compareNodesByLayoutPosition(a, b) {
|
|
1659
|
+
const ay = a.y ?? 0;
|
|
1660
|
+
const by = b.y ?? 0;
|
|
1661
|
+
if (ay !== by)
|
|
1662
|
+
return ay - by;
|
|
1663
|
+
return (a.x ?? 0) - (b.x ?? 0);
|
|
1664
|
+
}
|
|
1665
|
+
const PROJECTED_SLOT_OVERLAP_THRESHOLD = 0.5;
|
|
1666
|
+
function getZFlowRowHeight(nodes) {
|
|
1667
|
+
return Math.max(...nodes.map((n) => n.h ?? 1), 1);
|
|
1668
|
+
}
|
|
1669
|
+
function projectZFlowLayout(nodes, columnCount) {
|
|
1670
|
+
const result = [];
|
|
1671
|
+
let curX = 0;
|
|
1672
|
+
let curRow = 0;
|
|
1673
|
+
const rowHeight = getZFlowRowHeight(nodes);
|
|
1674
|
+
for (const node of nodes) {
|
|
1675
|
+
if (!node.id)
|
|
1676
|
+
continue;
|
|
1677
|
+
const w = Math.min(node.w ?? 1, columnCount);
|
|
1678
|
+
const h = node.h ?? rowHeight;
|
|
1679
|
+
if (curX > 0 && curX + w > columnCount) {
|
|
1680
|
+
curX = 0;
|
|
1681
|
+
curRow++;
|
|
1682
|
+
}
|
|
1683
|
+
result.push({
|
|
1684
|
+
id: node.id,
|
|
1685
|
+
row: curRow,
|
|
1686
|
+
x: curX,
|
|
1687
|
+
y: curRow * rowHeight,
|
|
1688
|
+
w,
|
|
1689
|
+
h,
|
|
1690
|
+
});
|
|
1691
|
+
curX += w;
|
|
1692
|
+
}
|
|
1693
|
+
return result;
|
|
1694
|
+
}
|
|
1695
|
+
function resolveDropRowFromRect(dragRectTopPx, dragRectHeightPx, rowHeightPx, rowCount, previousRow) {
|
|
1696
|
+
if (rowHeightPx <= 0 || rowCount <= 0)
|
|
1697
|
+
return previousRow;
|
|
1698
|
+
const clampedPreviousRow = Math.max(0, Math.min(previousRow, rowCount - 1));
|
|
1699
|
+
const dragBottomPx = dragRectTopPx + dragRectHeightPx;
|
|
1700
|
+
let bestRow = clampedPreviousRow;
|
|
1701
|
+
let bestOverlap = 0;
|
|
1702
|
+
for (let row = 0; row < rowCount; row++) {
|
|
1703
|
+
const rowTopPx = row * rowHeightPx;
|
|
1704
|
+
const rowBottomPx = rowTopPx + rowHeightPx;
|
|
1705
|
+
const overlap = Math.max(0, Math.min(dragBottomPx, rowBottomPx) - Math.max(dragRectTopPx, rowTopPx));
|
|
1706
|
+
if (overlap > bestOverlap) {
|
|
1707
|
+
bestOverlap = overlap;
|
|
1708
|
+
bestRow = row;
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
return bestOverlap > 0 ? bestRow : clampedPreviousRow;
|
|
1712
|
+
}
|
|
1713
|
+
function resolveInsertionSlotFromRow(dragRectCenterXPx, rowNodes, sourceId, cellWidthPx) {
|
|
1714
|
+
const candidates = rowNodes.filter((n) => n.id !== sourceId);
|
|
1715
|
+
if (candidates.length === 0)
|
|
1716
|
+
return 0;
|
|
1717
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
1718
|
+
const n = candidates[i];
|
|
1719
|
+
const nodeX = (n.x ?? 0) * cellWidthPx;
|
|
1720
|
+
const nodeW = (n.w ?? 1) * cellWidthPx;
|
|
1721
|
+
const nodeMid = nodeX + nodeW / 2;
|
|
1722
|
+
if (dragRectCenterXPx <= nodeMid)
|
|
1723
|
+
return i;
|
|
1724
|
+
}
|
|
1725
|
+
return candidates.length;
|
|
1726
|
+
}
|
|
1727
|
+
function reorderByInsertionSlot(orderedIds, sourceId, targetSlot) {
|
|
1728
|
+
const withoutSource = orderedIds.filter((id) => id !== sourceId);
|
|
1729
|
+
const clamped = Math.max(0, Math.min(targetSlot, withoutSource.length));
|
|
1730
|
+
withoutSource.splice(clamped, 0, sourceId);
|
|
1731
|
+
return withoutSource;
|
|
1732
|
+
}
|
|
1733
|
+
function resolveInsertionSlotFromProjectedRect(orderedNodes, sourceId, columnCount, dragRect, cellWidthPx, cellHeightPx, previousSlot) {
|
|
1734
|
+
if (cellWidthPx <= 0 || cellHeightPx <= 0) {
|
|
1735
|
+
return previousSlot;
|
|
1736
|
+
}
|
|
1737
|
+
const orderedIds = orderedNodes
|
|
1738
|
+
.filter((node) => node.id)
|
|
1739
|
+
.map((node) => node.id);
|
|
1740
|
+
const nodesById = new Map(orderedNodes
|
|
1741
|
+
.filter((node) => !!node.id)
|
|
1742
|
+
.map((node) => [node.id, node]));
|
|
1743
|
+
const idsWithoutSource = orderedIds.filter((id) => id !== sourceId);
|
|
1744
|
+
const sourceNode = nodesById.get(sourceId);
|
|
1745
|
+
if (!sourceNode)
|
|
1746
|
+
return previousSlot;
|
|
1747
|
+
let bestSlot = previousSlot;
|
|
1748
|
+
let bestOverlapRatio = 0;
|
|
1749
|
+
let bestProjectedSource;
|
|
1750
|
+
for (let slot = 0; slot <= idsWithoutSource.length; slot++) {
|
|
1751
|
+
const candidateIds = reorderByInsertionSlot(orderedIds, sourceId, slot);
|
|
1752
|
+
const candidateNodes = candidateIds
|
|
1753
|
+
.map((id) => nodesById.get(id))
|
|
1754
|
+
.filter((node) => !!node);
|
|
1755
|
+
const projectedSource = projectZFlowLayout(candidateNodes, columnCount).find((projected) => projected.id === sourceId);
|
|
1756
|
+
if (!projectedSource)
|
|
1757
|
+
continue;
|
|
1758
|
+
const overlapAreaPx = getRectOverlapAreaPx(dragRect, {
|
|
1759
|
+
leftPx: projectedSource.x * cellWidthPx,
|
|
1760
|
+
topPx: projectedSource.y * cellHeightPx,
|
|
1761
|
+
widthPx: projectedSource.w * cellWidthPx,
|
|
1762
|
+
heightPx: projectedSource.h * cellHeightPx,
|
|
1763
|
+
});
|
|
1764
|
+
const projectedAreaPx = projectedSource.w *
|
|
1765
|
+
cellWidthPx *
|
|
1766
|
+
projectedSource.h *
|
|
1767
|
+
cellHeightPx;
|
|
1768
|
+
const overlapRatio = projectedAreaPx > 0 ? overlapAreaPx / projectedAreaPx : 0;
|
|
1769
|
+
if (overlapRatio > bestOverlapRatio ||
|
|
1770
|
+
(overlapRatio === bestOverlapRatio &&
|
|
1771
|
+
bestProjectedSource &&
|
|
1772
|
+
isSameProjectedPosition(projectedSource, bestProjectedSource) &&
|
|
1773
|
+
slot > bestSlot)) {
|
|
1774
|
+
bestOverlapRatio = overlapRatio;
|
|
1775
|
+
bestProjectedSource = projectedSource;
|
|
1776
|
+
bestSlot = slot;
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
if (bestOverlapRatio > PROJECTED_SLOT_OVERLAP_THRESHOLD)
|
|
1780
|
+
return bestSlot;
|
|
1781
|
+
return Math.max(0, Math.min(previousSlot, idsWithoutSource.length));
|
|
1782
|
+
}
|
|
1783
|
+
function isSameProjectedPosition(a, b) {
|
|
1784
|
+
return a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;
|
|
1785
|
+
}
|
|
1786
|
+
function getRectOverlapAreaPx(a, b) {
|
|
1787
|
+
const overlapWidthPx = Math.max(0, Math.min(a.leftPx + a.widthPx, b.leftPx + b.widthPx) -
|
|
1788
|
+
Math.max(a.leftPx, b.leftPx));
|
|
1789
|
+
const overlapHeightPx = Math.max(0, Math.min(a.topPx + a.heightPx, b.topPx + b.heightPx) -
|
|
1790
|
+
Math.max(a.topPx, b.topPx));
|
|
1791
|
+
return overlapWidthPx * overlapHeightPx;
|
|
1792
|
+
}
|
|
1793
|
+
function applyProjectedLayout(nodes, projected) {
|
|
1794
|
+
for (const proj of projected) {
|
|
1795
|
+
const node = nodes.find((n) => n.id === proj.id);
|
|
1796
|
+
if (!node)
|
|
1797
|
+
continue;
|
|
1798
|
+
if (node.x !== proj.x ||
|
|
1799
|
+
node.y !== proj.y ||
|
|
1800
|
+
node.w !== proj.w ||
|
|
1801
|
+
node.h !== proj.h) {
|
|
1802
|
+
node.x = proj.x;
|
|
1803
|
+
node.y = proj.y;
|
|
1804
|
+
node.w = proj.w;
|
|
1805
|
+
node.h = proj.h;
|
|
1806
|
+
node._dirty = true;
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
function notifyEngine(engine) {
|
|
1811
|
+
engine._notify?.();
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
class ZflowGridStackEngine extends GridStackEngine {
|
|
1815
|
+
moveNodeCheck(node, opts) {
|
|
1816
|
+
if (opts.resizing) {
|
|
1817
|
+
return this.moveNodeCheckWithSteppedResize(node, opts);
|
|
1818
|
+
}
|
|
1819
|
+
if (node._moving && !opts.nested) {
|
|
1820
|
+
return this.moveNodeCheckWithZFlowDrag(node, opts);
|
|
1821
|
+
}
|
|
1822
|
+
return super.moveNodeCheck(node, opts);
|
|
1823
|
+
}
|
|
1824
|
+
moveNodeCheckWithSteppedResize(node, opts) {
|
|
1825
|
+
if (!node.id || opts.w === undefined)
|
|
1826
|
+
return super.moveNodeCheck(node, opts);
|
|
1827
|
+
const nodes = this.nodes;
|
|
1828
|
+
const sourceNode = nodes.find((n) => n.id === node.id);
|
|
1829
|
+
if (!sourceNode)
|
|
1830
|
+
return super.moveNodeCheck(node, opts);
|
|
1831
|
+
syncNodeOrderFromLayout(nodes);
|
|
1832
|
+
const snapshot = this.takeLayoutSnapshot(nodes);
|
|
1833
|
+
const effectiveMax = this.column - (sourceNode.x ?? 0);
|
|
1834
|
+
const nextWidth = resolveResizeWidthStep(opts.w, sourceNode.maxW ?? this.column, this.column, sourceNode.minW ?? 1, effectiveMax);
|
|
1835
|
+
sourceNode.w = nextWidth;
|
|
1836
|
+
opts.w = nextWidth;
|
|
1837
|
+
opts.x = sourceNode.x;
|
|
1838
|
+
opts.y = sourceNode.y;
|
|
1839
|
+
opts.h = sourceNode.h;
|
|
1840
|
+
const ordered = sortNodesByZFlowOrder(nodes);
|
|
1841
|
+
const projected = projectZFlowLayout(ordered, this.column);
|
|
1842
|
+
applyProjectedLayout(nodes, projected);
|
|
1843
|
+
const changed = this.markLayoutChangesDirty(snapshot);
|
|
1844
|
+
if (!changed)
|
|
1845
|
+
return false;
|
|
1846
|
+
notifyEngine(this);
|
|
1847
|
+
return true;
|
|
1848
|
+
}
|
|
1849
|
+
commitZFlowLayout() {
|
|
1850
|
+
const nodes = this.nodes;
|
|
1851
|
+
seedNodeOrder(nodes);
|
|
1852
|
+
const snapshot = this.takeLayoutSnapshot(nodes);
|
|
1853
|
+
const ordered = sortNodesByZFlowOrder(nodes);
|
|
1854
|
+
const projected = projectZFlowLayout(ordered, this.column);
|
|
1855
|
+
applyProjectedLayout(nodes, projected);
|
|
1856
|
+
const changed = this.markLayoutChangesDirty(snapshot);
|
|
1857
|
+
if (!changed)
|
|
1858
|
+
return false;
|
|
1859
|
+
notifyEngine(this);
|
|
1860
|
+
return true;
|
|
1861
|
+
}
|
|
1862
|
+
syncZFlowOrderFromLayout() {
|
|
1863
|
+
syncNodeOrderFromLayout(this.nodes);
|
|
1864
|
+
}
|
|
1865
|
+
takeLayoutSnapshot(nodes) {
|
|
1866
|
+
return nodes.map((n) => ({
|
|
1867
|
+
node: n,
|
|
1868
|
+
x: n.x,
|
|
1869
|
+
y: n.y,
|
|
1870
|
+
w: n.w,
|
|
1871
|
+
h: n.h,
|
|
1872
|
+
}));
|
|
1873
|
+
}
|
|
1874
|
+
markLayoutChangesDirty(snapshot) {
|
|
1875
|
+
let changed = false;
|
|
1876
|
+
for (const { node, x, y, w, h } of snapshot) {
|
|
1877
|
+
if (node.x === x && node.y === y && node.w === w && node.h === h) {
|
|
1878
|
+
continue;
|
|
1879
|
+
}
|
|
1880
|
+
node._dirty = true;
|
|
1881
|
+
changed = true;
|
|
1882
|
+
}
|
|
1883
|
+
return changed;
|
|
1884
|
+
}
|
|
1885
|
+
moveNodeCheckWithZFlowDrag(node, opts) {
|
|
1886
|
+
if (!node.id)
|
|
1887
|
+
return super.moveNodeCheck(node, opts);
|
|
1888
|
+
const nodes = this.nodes;
|
|
1889
|
+
seedNodeOrder(nodes);
|
|
1890
|
+
const ordered = sortNodesByZFlowOrder(nodes);
|
|
1891
|
+
const orderedIds = ordered.filter((n) => n.id).map((n) => n.id);
|
|
1892
|
+
const rect = opts.rect;
|
|
1893
|
+
const cellWidth = opts.cellWidth ?? 1;
|
|
1894
|
+
const cellHeight = opts.cellHeight ?? 60;
|
|
1895
|
+
const rowHeight = getZFlowRowHeight(ordered);
|
|
1896
|
+
const rowHeightPx = rowHeight * cellHeight;
|
|
1897
|
+
const projected = projectZFlowLayout(ordered, this.column);
|
|
1898
|
+
const rowCount = projected.length > 0 ? Math.max(...projected.map((p) => p.row)) + 1 : 1;
|
|
1899
|
+
const sourceNode = nodes.find((n) => n.id === node.id);
|
|
1900
|
+
const sourceProjected = projected.find((p) => p.id === node.id);
|
|
1901
|
+
const previousRow = sourceProjected?.row ?? 0;
|
|
1902
|
+
let targetRow;
|
|
1903
|
+
if (rect) {
|
|
1904
|
+
const rectTop = rect.top ?? rect.y ?? 0;
|
|
1905
|
+
const rectHeight = rect.height ??
|
|
1906
|
+
rect.h ??
|
|
1907
|
+
rowHeightPx;
|
|
1908
|
+
targetRow = resolveDropRowFromRect(rectTop, rectHeight, rowHeightPx, rowCount, previousRow);
|
|
1909
|
+
}
|
|
1910
|
+
else {
|
|
1911
|
+
targetRow = Math.floor((opts.y ?? sourceNode?.y ?? 0) / rowHeight);
|
|
1912
|
+
}
|
|
1913
|
+
targetRow = Math.max(0, Math.min(targetRow, rowCount - 1));
|
|
1914
|
+
const rowNodes = projected
|
|
1915
|
+
.filter((p) => p.row === targetRow)
|
|
1916
|
+
.map((p) => ({ id: p.id, x: p.x, w: p.w }));
|
|
1917
|
+
const idsWithoutSource = orderedIds.filter((id) => id !== node.id);
|
|
1918
|
+
let absoluteSlot;
|
|
1919
|
+
if (rect) {
|
|
1920
|
+
const rectLeft = rect.left ?? rect.x ?? 0;
|
|
1921
|
+
const rectTop = rect.top ?? rect.y ?? 0;
|
|
1922
|
+
const rectWidth = rect.width ?? rect.w ?? cellWidth;
|
|
1923
|
+
const rectHeight = rect.height ??
|
|
1924
|
+
rect.h ??
|
|
1925
|
+
rowHeightPx;
|
|
1926
|
+
absoluteSlot = resolveInsertionSlotFromProjectedRect(ordered, node.id, this.column, {
|
|
1927
|
+
leftPx: rectLeft,
|
|
1928
|
+
topPx: rectTop,
|
|
1929
|
+
widthPx: rectWidth,
|
|
1930
|
+
heightPx: rectHeight,
|
|
1931
|
+
}, cellWidth, cellHeight, orderedIds.indexOf(node.id));
|
|
1932
|
+
}
|
|
1933
|
+
else {
|
|
1934
|
+
const targetX = opts.x ?? sourceNode?.x ?? 0;
|
|
1935
|
+
const insertionSlotInRow = rowNodes.filter((n) => {
|
|
1936
|
+
const proj = projected.find((p) => p.id === n.id);
|
|
1937
|
+
return proj && proj.x <= targetX && n.id !== node.id;
|
|
1938
|
+
}).length;
|
|
1939
|
+
const rowIdsWithoutSource = rowNodes
|
|
1940
|
+
.filter((n) => n.id && n.id !== node.id)
|
|
1941
|
+
.map((n) => n.id);
|
|
1942
|
+
if (rowIdsWithoutSource.length === 0) {
|
|
1943
|
+
absoluteSlot = orderedIds.indexOf(node.id);
|
|
1944
|
+
}
|
|
1945
|
+
else {
|
|
1946
|
+
const firstRowIdxInFull = idsWithoutSource.indexOf(rowIdsWithoutSource[0]);
|
|
1947
|
+
absoluteSlot = firstRowIdxInFull + insertionSlotInRow;
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
absoluteSlot = Math.max(0, Math.min(absoluteSlot, idsWithoutSource.length));
|
|
1951
|
+
const newOrderedIds = reorderByInsertionSlot(orderedIds, node.id, absoluteSlot);
|
|
1952
|
+
const orderChanged = newOrderedIds.some((id, i) => id !== orderedIds[i]);
|
|
1953
|
+
if (!orderChanged)
|
|
1954
|
+
return false;
|
|
1955
|
+
newOrderedIds.forEach((id, idx) => {
|
|
1956
|
+
const n = nodes.find((nn) => nn.id === id);
|
|
1957
|
+
if (n)
|
|
1958
|
+
n.zFlowOrder = idx;
|
|
1959
|
+
});
|
|
1960
|
+
const projectedSource = projectZFlowLayout(sortNodesByZFlowOrder(nodes), this.column).find((projected) => projected.id === node.id);
|
|
1961
|
+
if (projectedSource) {
|
|
1962
|
+
node.x = projectedSource.x;
|
|
1963
|
+
node.y = projectedSource.y;
|
|
1964
|
+
node.w = projectedSource.w;
|
|
1965
|
+
node.h = projectedSource.h;
|
|
1966
|
+
node._dirty = true;
|
|
1967
|
+
notifyEngine(this);
|
|
1968
|
+
}
|
|
1969
|
+
return true;
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
const getColumns = (breakpoints) => breakpoints.map((bp) => bp.c).reverse();
|
|
1974
|
+
const ENGINE_PROFILES = {
|
|
1975
|
+
zFlow: {
|
|
1976
|
+
engineClass: ZflowGridStackEngine,
|
|
1977
|
+
breakpoints: ZFLOW_DASHBOARD_BREAKPOINTS,
|
|
1978
|
+
sectionColumns: [1, 2, 3, 3],
|
|
1979
|
+
fixedCardHeight: true,
|
|
1980
|
+
xlWidthSwap: true,
|
|
1981
|
+
renderOriginPosition: true,
|
|
1982
|
+
},
|
|
1983
|
+
default: {
|
|
1984
|
+
engineClass: undefined,
|
|
1985
|
+
breakpoints: DASHBOARD_BREAKPOINTS,
|
|
1986
|
+
sectionColumns: getColumns(DASHBOARD_BREAKPOINTS),
|
|
1987
|
+
fixedCardHeight: false,
|
|
1988
|
+
xlWidthSwap: false,
|
|
1989
|
+
renderOriginPosition: false,
|
|
1990
|
+
},
|
|
1991
|
+
};
|
|
1992
|
+
|
|
1596
1993
|
document.body.classList.add('ui5-content-density-compact');
|
|
1597
1994
|
class Dashboard {
|
|
1598
1995
|
static registerAngularComponents(componentTypes) {
|
|
1599
1996
|
addComponentToRegistry(componentTypes);
|
|
1600
1997
|
}
|
|
1998
|
+
hostEl = inject((ElementRef));
|
|
1999
|
+
injector = inject(Injector);
|
|
2000
|
+
sanitizer = inject(DomSanitizer);
|
|
2001
|
+
i18n = inject(DashboardI18nService);
|
|
1601
2002
|
config = input.required(...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
|
|
1602
2003
|
sections = model([], ...(ngDevMode ? [{ debugName: "sections" }] : /* istanbul ignore next */ []));
|
|
1603
2004
|
cards = model([], ...(ngDevMode ? [{ debugName: "cards" }] : /* istanbul ignore next */ []));
|
|
@@ -1606,20 +2007,18 @@ class Dashboard {
|
|
|
1606
2007
|
saved = output();
|
|
1607
2008
|
actionButtonClick = output();
|
|
1608
2009
|
unsavedChangesChange = output();
|
|
2010
|
+
i18nKeys = DASHBOARD_I18N_KEYS;
|
|
2011
|
+
/** True once the user has dragged/resized any grid item while in edit mode. */
|
|
2012
|
+
gridDirty = signal(false, ...(ngDevMode ? [{ debugName: "gridDirty" }] : /* istanbul ignore next */ []));
|
|
2013
|
+
isXLPage = signal(true, ...(ngDevMode ? [{ debugName: "isXLPage" }] : /* istanbul ignore next */ []));
|
|
1609
2014
|
editMode = signal(false, ...(ngDevMode ? [{ debugName: "editMode" }] : /* istanbul ignore next */ []));
|
|
1610
2015
|
compactToolbar = signal(false, ...(ngDevMode ? [{ debugName: "compactToolbar" }] : /* istanbul ignore next */ []));
|
|
1611
2016
|
toolbarMenuOpen = signal(false, ...(ngDevMode ? [{ debugName: "toolbarMenuOpen" }] : /* istanbul ignore next */ []));
|
|
1612
|
-
|
|
1613
|
-
|
|
2017
|
+
cardDialogOpen = signal(false, ...(ngDevMode ? [{ debugName: "cardDialogOpen" }] : /* istanbul ignore next */ []));
|
|
2018
|
+
discardDialogOpen = signal(false, ...(ngDevMode ? [{ debugName: "discardDialogOpen" }] : /* istanbul ignore next */ []));
|
|
2019
|
+
unsavedNavDialogOpen = signal(false, ...(ngDevMode ? [{ debugName: "unsavedNavDialogOpen" }] : /* istanbul ignore next */ []));
|
|
1614
2020
|
backgroundImageHeight = signal(null, ...(ngDevMode ? [{ debugName: "backgroundImageHeight" }] : /* istanbul ignore next */ []));
|
|
1615
|
-
|
|
1616
|
-
sectionsSnapshotJson = '';
|
|
1617
|
-
cardsSnapshotJson = '';
|
|
1618
|
-
/**
|
|
1619
|
-
* True when the user is in edit mode AND has made any change (sections/cards
|
|
1620
|
-
* mutated, or grid items moved/resized). Resets when entering edit mode and
|
|
1621
|
-
* after save/cancel.
|
|
1622
|
-
*/
|
|
2021
|
+
dragOriginStyle = signal(null, ...(ngDevMode ? [{ debugName: "dragOriginStyle" }] : /* istanbul ignore next */ []));
|
|
1623
2022
|
hasUnsavedChanges = computed(() => {
|
|
1624
2023
|
if (!this.editMode())
|
|
1625
2024
|
return false;
|
|
@@ -1628,16 +2027,6 @@ class Dashboard {
|
|
|
1628
2027
|
return (JSON.stringify(this.sections()) !== this.sectionsSnapshotJson ||
|
|
1629
2028
|
JSON.stringify(this.cards()) !== this.cardsSnapshotJson);
|
|
1630
2029
|
}, ...(ngDevMode ? [{ debugName: "hasUnsavedChanges" }] : /* istanbul ignore next */ []));
|
|
1631
|
-
sectionsSnapshot = [];
|
|
1632
|
-
cardsSnapshot = [];
|
|
1633
|
-
gridStackItems = viewChild.required('grid');
|
|
1634
|
-
addCardBtn = viewChild('editCardsBtn', ...(ngDevMode ? [{ debugName: "addCardBtn" }] : /* istanbul ignore next */ []));
|
|
1635
|
-
resizeObserver;
|
|
1636
|
-
hostEl = inject((ElementRef));
|
|
1637
|
-
injector = inject(Injector);
|
|
1638
|
-
sanitizer = inject(DomSanitizer);
|
|
1639
|
-
i18n = inject(DashboardI18nService);
|
|
1640
|
-
i18nKeys = DASHBOARD_I18N_KEYS;
|
|
1641
2030
|
safeTitle = computed(() => {
|
|
1642
2031
|
const clean = this.sanitizer.sanitize(SecurityContext.HTML, this.config().title) ?? '';
|
|
1643
2032
|
return this.sanitizer.bypassSecurityTrustHtml(clean);
|
|
@@ -1649,6 +2038,52 @@ class Dashboard {
|
|
|
1649
2038
|
const clean = this.sanitizer.sanitize(SecurityContext.HTML, desc) ?? '';
|
|
1650
2039
|
return this.sanitizer.bypassSecurityTrustHtml(clean);
|
|
1651
2040
|
}, ...(ngDevMode ? [{ debugName: "safeDescription" }] : /* istanbul ignore next */ []));
|
|
2041
|
+
engineProfile = computed(() => this.config().zFlow ? ENGINE_PROFILES.zFlow : ENGINE_PROFILES.default, ...(ngDevMode ? [{ debugName: "engineProfile" }] : /* istanbul ignore next */ []));
|
|
2042
|
+
gridStackEngine = computed(() => this.engineProfile().engineClass, ...(ngDevMode ? [{ debugName: "gridStackEngine" }] : /* istanbul ignore next */ []));
|
|
2043
|
+
gridBreakpoints = computed(() => [
|
|
2044
|
+
...this.engineProfile().breakpoints,
|
|
2045
|
+
], ...(ngDevMode ? [{ debugName: "gridBreakpoints" }] : /* istanbul ignore next */ []));
|
|
2046
|
+
columnVars = computed(() => {
|
|
2047
|
+
const [sm, md, lg, xl] = this.engineProfile().sectionColumns;
|
|
2048
|
+
return {
|
|
2049
|
+
'--dashboard-cols-sm': sm,
|
|
2050
|
+
'--dashboard-cols-md': md,
|
|
2051
|
+
'--dashboard-cols-lg': lg,
|
|
2052
|
+
'--dashboard-cols-xl': xl,
|
|
2053
|
+
};
|
|
2054
|
+
}, ...(ngDevMode ? [{ debugName: "columnVars" }] : /* istanbul ignore next */ []));
|
|
2055
|
+
customActions = computed(() => this.config().customActions ?? [], ...(ngDevMode ? [{ debugName: "customActions" }] : /* istanbul ignore next */ []));
|
|
2056
|
+
addedCardsIds = computed(() => new Set(this.cards().map((c) => c.id)), ...(ngDevMode ? [{ debugName: "addedCardsIds" }] : /* istanbul ignore next */ []));
|
|
2057
|
+
editViewButton = computed(() => ({
|
|
2058
|
+
icon: 'action-settings',
|
|
2059
|
+
design: 'Transparent',
|
|
2060
|
+
tooltip: this.i18n.getTranslation(DASHBOARD_I18N_KEYS.EDIT_VIEW),
|
|
2061
|
+
text: '',
|
|
2062
|
+
...this.config().buttonsSettings?.editViewButton,
|
|
2063
|
+
}), ...(ngDevMode ? [{ debugName: "editViewButton" }] : /* istanbul ignore next */ []));
|
|
2064
|
+
editCardsButton = computed(() => ({
|
|
2065
|
+
icon: '',
|
|
2066
|
+
design: 'Default',
|
|
2067
|
+
tooltip: '',
|
|
2068
|
+
text: this.i18n.getTranslation(DASHBOARD_I18N_KEYS.EDIT_CARDS),
|
|
2069
|
+
...this.config().buttonsSettings?.editCardsButton,
|
|
2070
|
+
}), ...(ngDevMode ? [{ debugName: "editCardsButton" }] : /* istanbul ignore next */ []));
|
|
2071
|
+
sectionCards = computed(() => {
|
|
2072
|
+
const all = this.cards();
|
|
2073
|
+
return (sectionId) => all.filter((c) => c.sectionId === sectionId);
|
|
2074
|
+
}, ...(ngDevMode ? [{ debugName: "sectionCards" }] : /* istanbul ignore next */ []));
|
|
2075
|
+
looseCards = linkedSignal(() => {
|
|
2076
|
+
const loose = this.cards().filter((c) => !c.sectionId);
|
|
2077
|
+
const cardHeight = this.config().zFlow?.cardHeight;
|
|
2078
|
+
if (!this.engineProfile().fixedCardHeight || cardHeight === undefined)
|
|
2079
|
+
return loose;
|
|
2080
|
+
return loose.map((c) => ({
|
|
2081
|
+
...c,
|
|
2082
|
+
h: cardHeight,
|
|
2083
|
+
maxH: cardHeight,
|
|
2084
|
+
minH: cardHeight,
|
|
2085
|
+
}));
|
|
2086
|
+
}, ...(ngDevMode ? [{ debugName: "looseCards" }] : /* istanbul ignore next */ []));
|
|
1652
2087
|
gridOptions = computed(() => ({
|
|
1653
2088
|
cellHeight: CELL_HEIGHT,
|
|
1654
2089
|
sizeToContent: true,
|
|
@@ -1657,15 +2092,23 @@ class Dashboard {
|
|
|
1657
2092
|
marginBottom: 0,
|
|
1658
2093
|
marginLeft: 0,
|
|
1659
2094
|
marginRight: 0,
|
|
2095
|
+
engineClass: this.gridStackEngine(),
|
|
1660
2096
|
columnOpts: {
|
|
1661
|
-
// Source of truth: ../
|
|
1662
|
-
// ../
|
|
1663
|
-
|
|
2097
|
+
// Source of truth: ../constants/breakpoints.ts — active profile's
|
|
2098
|
+
// breakpoints (paired with ../constants/_breakpoints.scss for the
|
|
2099
|
+
// section grid's container queries via --dashboard-cols-* CSS vars).
|
|
2100
|
+
breakpoints: this.gridBreakpoints(),
|
|
1664
2101
|
},
|
|
1665
2102
|
}), ...(ngDevMode ? [{ debugName: "gridOptions" }] : /* istanbul ignore next */ []));
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
2103
|
+
/** JSON snapshots of sections/cards taken on entering edit mode, used to detect changes. */
|
|
2104
|
+
sectionsSnapshotJson = '';
|
|
2105
|
+
cardsSnapshotJson = '';
|
|
2106
|
+
sectionsSnapshot = [];
|
|
2107
|
+
cardsSnapshot = [];
|
|
2108
|
+
gridStack = viewChild.required('grid');
|
|
2109
|
+
addCardBtn = viewChild('editCardsBtn', ...(ngDevMode ? [{ debugName: "addCardBtn" }] : /* istanbul ignore next */ []));
|
|
2110
|
+
resizeObserver;
|
|
2111
|
+
cardsPosition = new Map();
|
|
1669
2112
|
/** Callback that resumes the intercepted navigation once the user resolves the dialog. */
|
|
1670
2113
|
pendingNavigation = null;
|
|
1671
2114
|
/** beforeunload handler kept on instance so add/removeEventListener pair up. */
|
|
@@ -1677,29 +2120,6 @@ class Dashboard {
|
|
|
1677
2120
|
event.returnValue = '';
|
|
1678
2121
|
}
|
|
1679
2122
|
};
|
|
1680
|
-
customActions = computed(() => this.config().customActions ?? [], ...(ngDevMode ? [{ debugName: "customActions" }] : /* istanbul ignore next */ []));
|
|
1681
|
-
addedCardsIds = computed(() => new Set(this.cards().map((c) => c.id)), ...(ngDevMode ? [{ debugName: "addedCardsIds" }] : /* istanbul ignore next */ []));
|
|
1682
|
-
editViewButton = computed(() => ({
|
|
1683
|
-
icon: 'action-settings',
|
|
1684
|
-
design: 'Transparent',
|
|
1685
|
-
tooltip: this.i18n.getTranslation(DASHBOARD_I18N_KEYS.EDIT_VIEW),
|
|
1686
|
-
text: '',
|
|
1687
|
-
...this.config().buttonsSettings?.editViewButton,
|
|
1688
|
-
}), ...(ngDevMode ? [{ debugName: "editViewButton" }] : /* istanbul ignore next */ []));
|
|
1689
|
-
editCardsButton = computed(() => ({
|
|
1690
|
-
icon: '',
|
|
1691
|
-
design: 'Default',
|
|
1692
|
-
tooltip: '',
|
|
1693
|
-
text: this.i18n.getTranslation(DASHBOARD_I18N_KEYS.EDIT_CARDS),
|
|
1694
|
-
...this.config().buttonsSettings?.editCardsButton,
|
|
1695
|
-
}), ...(ngDevMode ? [{ debugName: "editCardsButton" }] : /* istanbul ignore next */ []));
|
|
1696
|
-
sectionCards = computed(() => {
|
|
1697
|
-
const all = this.cards();
|
|
1698
|
-
return (sectionId) => all.filter((c) => c.sectionId === sectionId);
|
|
1699
|
-
}, ...(ngDevMode ? [{ debugName: "sectionCards" }] : /* istanbul ignore next */ []));
|
|
1700
|
-
cardsPosition = new Map();
|
|
1701
|
-
looseCards = linkedSignal(() => this.cards().filter((c) => !c.sectionId), ...(ngDevMode ? [{ debugName: "looseCards" }] : /* istanbul ignore next */ []));
|
|
1702
|
-
newGridStackNodes = [];
|
|
1703
2123
|
constructor() {
|
|
1704
2124
|
effect(() => {
|
|
1705
2125
|
this.unsavedChangesChange.emit(this.hasUnsavedChanges());
|
|
@@ -1726,6 +2146,7 @@ class Dashboard {
|
|
|
1726
2146
|
this.resizeObserver = new ResizeObserver((entries) => {
|
|
1727
2147
|
const width = entries[0]?.contentRect.width ?? 0;
|
|
1728
2148
|
this.compactToolbar.set(width < COMPACT_BREAKPOINT);
|
|
2149
|
+
this.changeCardSettingsForXlPage(width);
|
|
1729
2150
|
});
|
|
1730
2151
|
this.resizeObserver.observe(this.hostEl.nativeElement);
|
|
1731
2152
|
window.addEventListener('beforeunload', this.beforeUnloadHandler);
|
|
@@ -1864,7 +2285,7 @@ class Dashboard {
|
|
|
1864
2285
|
this.cards.update((list) => list.filter((c) => c.id !== id));
|
|
1865
2286
|
if (wasLooseCard) {
|
|
1866
2287
|
afterNextRender(() => {
|
|
1867
|
-
this.
|
|
2288
|
+
this.gridStack().grid?.compact('compact', false);
|
|
1868
2289
|
}, { injector: this.injector });
|
|
1869
2290
|
}
|
|
1870
2291
|
}
|
|
@@ -1881,6 +2302,26 @@ class Dashboard {
|
|
|
1881
2302
|
});
|
|
1882
2303
|
this.closeCardPanel();
|
|
1883
2304
|
}
|
|
2305
|
+
onDragStart(event) {
|
|
2306
|
+
this.getZFlowEngine()?.syncZFlowOrderFromLayout();
|
|
2307
|
+
if (!this.engineProfile().renderOriginPosition) {
|
|
2308
|
+
return;
|
|
2309
|
+
}
|
|
2310
|
+
const el = event.el;
|
|
2311
|
+
const gridEl = this.gridStack().el;
|
|
2312
|
+
const gridRect = gridEl.getBoundingClientRect();
|
|
2313
|
+
const elRect = el.getBoundingClientRect();
|
|
2314
|
+
this.dragOriginStyle.set({
|
|
2315
|
+
top: `${elRect.top - gridRect.top}px`,
|
|
2316
|
+
left: `${elRect.left - gridRect.left}px`,
|
|
2317
|
+
width: `${elRect.width}px`,
|
|
2318
|
+
height: `${elRect.height}px`,
|
|
2319
|
+
});
|
|
2320
|
+
}
|
|
2321
|
+
onDragStop() {
|
|
2322
|
+
this.getZFlowEngine()?.commitZFlowLayout();
|
|
2323
|
+
this.dragOriginStyle.set(null);
|
|
2324
|
+
}
|
|
1884
2325
|
onGridChange() {
|
|
1885
2326
|
if (this.editMode()) {
|
|
1886
2327
|
this.gridDirty.set(true);
|
|
@@ -1899,15 +2340,50 @@ class Dashboard {
|
|
|
1899
2340
|
});
|
|
1900
2341
|
}
|
|
1901
2342
|
updateCardsPositions() {
|
|
1902
|
-
const gridStackNodes = this.
|
|
2343
|
+
const gridStackNodes = this.gridStack()
|
|
1903
2344
|
.gridstackItems?.toArray()
|
|
1904
2345
|
.map((node) => node.options);
|
|
1905
2346
|
if (gridStackNodes) {
|
|
1906
2347
|
this.saveCardsPosition(gridStackNodes);
|
|
1907
2348
|
}
|
|
1908
2349
|
}
|
|
2350
|
+
getZFlowEngine() {
|
|
2351
|
+
const engine = this.gridStack().grid?.engine;
|
|
2352
|
+
return engine instanceof ZflowGridStackEngine ? engine : null;
|
|
2353
|
+
}
|
|
2354
|
+
updateCardsForBreakpoint(updateCard) {
|
|
2355
|
+
this.getZFlowEngine()?.syncZFlowOrderFromLayout();
|
|
2356
|
+
this.cards.set(this.cards().map(updateCard));
|
|
2357
|
+
afterNextRender(() => {
|
|
2358
|
+
this.getZFlowEngine()?.commitZFlowLayout();
|
|
2359
|
+
}, { injector: this.injector });
|
|
2360
|
+
}
|
|
2361
|
+
changeCardSettingsForXlPage(width) {
|
|
2362
|
+
if (!this.engineProfile().xlWidthSwap)
|
|
2363
|
+
return;
|
|
2364
|
+
if (width >= XL_PAGE) {
|
|
2365
|
+
if (!this.isXLPage()) {
|
|
2366
|
+
this.isXLPage.set(true);
|
|
2367
|
+
this.updateCardsForBreakpoint((c) => ({
|
|
2368
|
+
...c,
|
|
2369
|
+
w: c.w === 4 ? 3 : c.w,
|
|
2370
|
+
maxW: c.maxW === 4 ? 3 : c.maxW,
|
|
2371
|
+
}));
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
else {
|
|
2375
|
+
if (this.isXLPage()) {
|
|
2376
|
+
this.isXLPage.set(false);
|
|
2377
|
+
this.updateCardsForBreakpoint((c) => ({
|
|
2378
|
+
...c,
|
|
2379
|
+
w: c.w === 3 ? 4 : c.w,
|
|
2380
|
+
maxW: c.maxW === 3 ? 4 : c.maxW,
|
|
2381
|
+
}));
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
1909
2385
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: Dashboard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1910
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", 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: "gridStackItems", first: true, predicate: ["grid"], descendants: true, isSignal: true }, { propertyName: "addCardBtn", first: true, predicate: ["editCardsBtn"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"mfp-dashboard\" data-testid=\"dashboard\">\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 level=\"H3\" size=\"H3\" wrapping-type=\"Normal\" data-testid=\"dashboard-title\">\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 level=\"H5\" size=\"H5\" wrapping-type=\"Normal\" data-testid=\"dashboard-description\">\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 id=\"edit-cards-btn\"\n data-testid=\"dashboard-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 [attr.data-testid]=\"'dashboard-action-' + action.action\"\n [accessibleName]=\"action.text || action.tooltip || 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 [options]=\"gridOptions()\"\n (addedCB)=\"onGridChange()\"\n (changeCB)=\"onGridChange()\"\n (removedCB)=\"onGridChange()\"\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\n</div>\n@if (editMode()) {\n <div class=\"mfp-dashboard__edit-bar\">\n <ui5-button data-testid=\"dashboard-save-btn\" design=\"Emphasized\" (click)=\"saveEdit()\">{{\n i18n.getTranslation(i18nKeys.SAVE)\n }}</ui5-button>\n <ui5-button data-testid=\"dashboard-cancel-btn\" design=\"Transparent\" (click)=\"cancelEdit()\">{{\n i18n.getTranslation(i18nKeys.CANCEL)\n }}</ui5-button>\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 .placeholder-content{border-radius:16px;height:calc(100% - 30px);top:calc(var(--gs-item-margin-top) * 2)!important;width:calc(100% - 20px);left:10px!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-sections-container{display:grid;grid-auto-rows:auto;align-content:start;gap:1rem;grid-template-columns:repeat(14,1fr)}@container mfp-dashboard (max-width: 599px){.mfp-sections-container{grid-template-columns:repeat(1,1fr)}}@container mfp-dashboard (min-width: 600px) and (max-width: 1023px){.mfp-sections-container{grid-template-columns:repeat(8,1fr)}}@container mfp-dashboard (min-width: 1024px) and (max-width: 1439px){.mfp-sections-container{grid-template-columns:repeat(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}.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 });
|
|
2386
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", 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 class=\"mfp-dashboard\" data-testid=\"dashboard\" [style]=\"columnVars()\" [class.edit]=\"editMode()\">\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 data-testid=\"dashboard-title\" level=\"H3\" size=\"H3\" wrapping-type=\"Normal\">\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 data-testid=\"dashboard-description\" level=\"H5\" size=\"H5\" wrapping-type=\"Normal\">\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 class=\"mfp-dashboard__drag-origin-placeholder\" [style]=\"dragOriginStyle()\"></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\n</div>\n@if (editMode()) {\n <div class=\"mfp-dashboard__edit-bar\">\n <ui5-button data-testid=\"dashboard-save-btn\" design=\"Emphasized\" (click)=\"saveEdit()\">{{\n i18n.getTranslation(i18nKeys.SAVE)\n }}</ui5-button>\n <ui5-button data-testid=\"dashboard-cancel-btn\" design=\"Transparent\" (click)=\"cancelEdit()\">{{\n i18n.getTranslation(i18nKeys.CANCEL)\n }}</ui5-button>\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 });
|
|
1911
2387
|
}
|
|
1912
2388
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: Dashboard, decorators: [{
|
|
1913
2389
|
type: Component,
|
|
@@ -1928,8 +2404,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
1928
2404
|
], providers: [DashboardI18nService], encapsulation: ViewEncapsulation.None, host: {
|
|
1929
2405
|
'[style.background-image]': 'config().backgroundImageUrl ? "url(" + config().backgroundImageUrl + ")" : null',
|
|
1930
2406
|
'[style.background-size]': 'backgroundImageHeight() ? "100% " + backgroundImageHeight() + "px" : "100% auto"',
|
|
1931
|
-
}, template: "<div class=\"mfp-dashboard\" data-testid=\"dashboard\">\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 level=\"H3\" size=\"H3\" wrapping-type=\"Normal\" data-testid=\"dashboard-title\">\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 level=\"H5\" size=\"H5\" wrapping-type=\"Normal\" data-testid=\"dashboard-description\">\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 id=\"edit-cards-btn\"\n data-testid=\"dashboard-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 [attr.data-testid]=\"'dashboard-action-' + action.action\"\n [accessibleName]=\"action.text || action.tooltip || 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 [options]=\"gridOptions()\"\n (addedCB)=\"onGridChange()\"\n (changeCB)=\"onGridChange()\"\n (removedCB)=\"onGridChange()\"\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\n</div>\n@if (editMode()) {\n <div class=\"mfp-dashboard__edit-bar\">\n <ui5-button data-testid=\"dashboard-save-btn\" design=\"Emphasized\" (click)=\"saveEdit()\">{{\n i18n.getTranslation(i18nKeys.SAVE)\n }}</ui5-button>\n <ui5-button data-testid=\"dashboard-cancel-btn\" design=\"Transparent\" (click)=\"cancelEdit()\">{{\n i18n.getTranslation(i18nKeys.CANCEL)\n }}</ui5-button>\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 .placeholder-content{border-radius:16px;height:calc(100% - 30px);top:calc(var(--gs-item-margin-top) * 2)!important;width:calc(100% - 20px);left:10px!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-sections-container{display:grid;grid-auto-rows:auto;align-content:start;gap:1rem;grid-template-columns:repeat(14,1fr)}@container mfp-dashboard (max-width: 599px){.mfp-sections-container{grid-template-columns:repeat(1,1fr)}}@container mfp-dashboard (min-width: 600px) and (max-width: 1023px){.mfp-sections-container{grid-template-columns:repeat(8,1fr)}}@container mfp-dashboard (min-width: 1024px) and (max-width: 1439px){.mfp-sections-container{grid-template-columns:repeat(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}.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"] }]
|
|
1932
|
-
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], 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 }] }], language: [{ type: i0.Input, args: [{ isSignal: true, alias: "language", required: false }] }], saved: [{ type: i0.Output, args: ["saved"] }], actionButtonClick: [{ type: i0.Output, args: ["actionButtonClick"] }], unsavedChangesChange: [{ type: i0.Output, args: ["unsavedChangesChange"] }],
|
|
2407
|
+
}, template: "<div class=\"mfp-dashboard\" data-testid=\"dashboard\" [style]=\"columnVars()\" [class.edit]=\"editMode()\">\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 data-testid=\"dashboard-title\" level=\"H3\" size=\"H3\" wrapping-type=\"Normal\">\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 data-testid=\"dashboard-description\" level=\"H5\" size=\"H5\" wrapping-type=\"Normal\">\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 class=\"mfp-dashboard__drag-origin-placeholder\" [style]=\"dragOriginStyle()\"></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\n</div>\n@if (editMode()) {\n <div class=\"mfp-dashboard__edit-bar\">\n <ui5-button data-testid=\"dashboard-save-btn\" design=\"Emphasized\" (click)=\"saveEdit()\">{{\n i18n.getTranslation(i18nKeys.SAVE)\n }}</ui5-button>\n <ui5-button data-testid=\"dashboard-cancel-btn\" design=\"Transparent\" (click)=\"cancelEdit()\">{{\n i18n.getTranslation(i18nKeys.CANCEL)\n }}</ui5-button>\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"] }]
|
|
2408
|
+
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], 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 }] }], language: [{ type: i0.Input, args: [{ isSignal: true, alias: "language", 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 }] }], addCardBtn: [{ type: i0.ViewChild, args: ['editCardsBtn', { isSignal: true }] }] } });
|
|
1933
2409
|
|
|
1934
2410
|
class VisitedServiceCard {
|
|
1935
2411
|
serviceType = input.required(...(ngDevMode ? [{ debugName: "serviceType" }] : /* istanbul ignore next */ []));
|
|
@@ -2024,9 +2500,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
2024
2500
|
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"] }]
|
|
2025
2501
|
}] });
|
|
2026
2502
|
|
|
2503
|
+
class MockCard {
|
|
2504
|
+
title = input('Card Name', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
2505
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: MockCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2506
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.12", 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: ["design", "disabled", "icon", "endIcon", "submits", "tooltip", "accessibleName", "accessibleNameRef", "accessibilityAttributes", "accessibleDescription", "type", "accessibleRole", "loading", "loadingDelay"], outputs: ["ui5Click"], exportAs: ["ui5Button"] }, { kind: "component", type: Title, selector: "ui5-title, [ui5-title]", inputs: ["wrappingType", "level", "size"], exportAs: ["ui5Title"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2507
|
+
}
|
|
2508
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: MockCard, decorators: [{
|
|
2509
|
+
type: Component,
|
|
2510
|
+
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"] }]
|
|
2511
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }] } });
|
|
2512
|
+
|
|
2027
2513
|
/**
|
|
2028
2514
|
* Generated bundle index. Do not edit.
|
|
2029
2515
|
*/
|
|
2030
2516
|
|
|
2031
|
-
export { BooleanValue, CARD_TYPES, Dashboard, DeclarativeForm, DeclarativeTable, DeclarativeTableCard, Favorites, LinkValue, ResourceField, SecretValue, ServiceStatusCard, TagListValue, VisitedServiceCard, WhatsNew };
|
|
2517
|
+
export { BooleanValue, CARD_TYPES, Dashboard, DeclarativeForm, DeclarativeTable, DeclarativeTableCard, Favorites, LinkValue, MockCard, ResourceField, SecretValue, ServiceStatusCard, TagListValue, VisitedServiceCard, WhatsNew };
|
|
2032
2518
|
//# sourceMappingURL=openmfp-ngx.mjs.map
|