UNPKG

@openui5/sap.m

Version:

OpenUI5 UI Library sap.m

1,789 lines (1,546 loc) 98.7 kB
/*! * OpenUI5 * (c) Copyright 2026 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ // Provides control sap.m.VariantManagement. sap.ui.define([ "sap/ui/core/Element", "sap/ui/core/Lib", "sap/ui/core/ShortcutHintsMixin", "sap/ui/dom/containsOrEquals", "sap/ui/model/json/JSONModel", "sap/ui/model/base/ManagedObjectModel", "sap/ui/model/Filter", "sap/ui/model/FilterOperator", "sap/ui/model/BindingMode", "sap/ui/base/ManagedObjectObserver", "sap/ui/Device", "sap/ui/core/InvisibleText", "sap/ui/core/Control", "sap/ui/core/Icon", "sap/ui/core/Item", "sap/ui/layout/HorizontalLayout", "sap/ui/layout/Grid", "sap/m/SearchField", "sap/m/RadioButton", "sap/m/ColumnListItem", "sap/m/Column", "sap/m/Text", "sap/m/Bar", "sap/m/Table", "sap/m/Page", "sap/m/Toolbar", "sap/m/ToolbarSpacer", "sap/m/Button", "sap/m/CheckBox", "sap/m/Dialog", "sap/m/Input", "sap/m/Label", "sap/m/Title", "sap/m/ResponsivePopover", "sap/m/SelectList", "sap/m/ObjectIdentifier", "sap/m/OverflowToolbar", "sap/m/OverflowToolbarLayoutData", "sap/m/VBox", "sap/m/HBox", "sap/m/IllustratedMessage", "sap/ui/events/KeyCodes", "sap/base/Log", "sap/ui/core/library", "sap/base/util/merge", "sap/m/library" ], function( Element, Library, ShortcutHintsMixin, containsOrEquals, JSONModel, ManagedObjectModel, Filter, FilterOperator, BindingMode, ManagedObjectObserver, Device, InvisibleText, Control, Icon, Item, HorizontalLayout, Grid, SearchField, RadioButton, ColumnListItem, Column, Text, Bar, Table, Page, Toolbar, ToolbarSpacer, Button, CheckBox, Dialog, Input, Label, Title, ResponsivePopover, SelectList, ObjectIdentifier, OverflowToolbar, OverflowToolbarLayoutData, VBox, HBox, IllustratedMessage, KeyCodes, Log, coreLibrary, merge, mobileLibrary ) { "use strict"; // shortcut for sap.m.OverflowToolbarPriority var OverflowToolbarPriority = mobileLibrary.OverflowToolbarPriority; // shortcut for sap.m.ButtonType var ButtonType = mobileLibrary.ButtonType; // shortcut for sap.m.FlexAlignItems var FlexAlignItems = mobileLibrary.FlexAlignItems; // shortcut for sap.m.PlacementType var PlacementType = mobileLibrary.PlacementType; // shortcut for sap.m.PopinDisplay var PopinDisplay = mobileLibrary.PopinDisplay; // shortcut for sap.m.ScreenSize var ScreenSize = mobileLibrary.ScreenSize; // shortcut for sap.m.ListKeyboardMode var ListKeyboardMode = mobileLibrary.ListKeyboardMode; // shortcut for sap.m.Sticky var Sticky = mobileLibrary.Sticky; // shortcut for sap.ui.core.ValueState var ValueState = coreLibrary.ValueState; // shortcut for sap.ui.core.TextAlign var TextAlign = coreLibrary.TextAlign; // shortcut for sap.ui.core.TitleLevel var TitleLevel = coreLibrary.TitleLevel; // shortcut for sap.m.IllustratedMessageSize const IllustratedMessageSize = mobileLibrary.IllustratedMessageSize; /** * Constructor for a new <code>VariantManagement</code>. * @param {string} [sId] - ID for the new control, generated automatically if no ID is given * @param {object} [mSettings] - Initial settings for the new control * @class Can be used to manage variants. You can use this control to create and maintain personalization changes. * The persistency and retrieval of such changes has to be handled by the hosting application.<br> * <b>Note:</b> * On the user interface, variants are generally referred to as "views". * @extends sap.ui.core.Control * @constructor * @public * @since 1.103 * @alias sap.m.VariantManagement */ var VariantManagement = Control.extend("sap.m.VariantManagement", /** @lends sap.m.VariantManagement.prototype */ { metadata: { interfaces: [ "sap.ui.core.IShrinkable", "sap.m.IOverflowToolbarContent", "sap.m.IToolbarInteractiveControl" ], library: "sap.m", designtime: "sap/m/designtime/VariantManagement.designtime", properties: { /** * Indicates that default of variants is supported */ supportDefault: { type: "boolean", group: "Misc", defaultValue: true }, /** * Indicates that favorite handling is supported */ supportFavorites: { type: "boolean", group: "Misc", defaultValue: true }, /** * Indicates that apply automatically functionality is supported */ supportApplyAutomatically: { type: "boolean", group: "Misc", defaultValue: true }, /** * Indicates that public functionality is supported */ supportPublic: { type: "boolean", group: "Misc", defaultValue: true }, /** * Indicates that contexts functionality is supported.<br> * <b>Note:</b> This property is used internally by the SAPUI5 flexibility layer. * @restricted sap.ui.fl, sap.ui.comp */ supportContexts: { type: "boolean", group: "Misc", defaultValue: false }, /** * Identifies the currently selected item */ selectedKey: { type: "string", group: "Misc", defaultValue: "" }, /** * Identifies the defaulted item */ defaultKey: { type: "string", group: "Misc", defaultValue: "" }, /** * Controls the visibility of the Save As button. */ showSaveAs: { type: "boolean", group: "Misc", defaultValue: true }, /** * If set to <code>false</code>, neither the Save As nor the Save button in the My Views dialog is visible. */ creationAllowed: { type: "boolean", group: "Misc", defaultValue: true }, /** * Indicates if the buttons and the complete footer in the My Views dialog are visible. */ showFooter: { type: "boolean", group: "Misc", defaultValue: true }, /** * Indicates if the current variant is modified. */ modified: { type: "boolean", group: "Misc", defaultValue: false }, /** * The title in the My Views popover. */ popoverTitle: { type: "string", group: "Misc", defaultValue: "" }, /** * Indicates that the control is in error state. If set to <code>true</code>, an error message will be displayed whenever the variant is * opened. */ inErrorState: { type: "boolean", group: "Misc", defaultValue: false }, /** * Semantic level of the header. * For more information, see {@link sap.m.Title#setLevel}. */ level: { type: "sap.ui.core.TitleLevel", group: "Appearance", defaultValue: TitleLevel.Auto }, /** * Defines the style of the title. * For more information, see {@link sap.m.Title#setTitleStyle}. * * @since 1.109 */ titleStyle: { type: "sap.ui.core.TitleLevel", group: "Appearance", defaultValue: TitleLevel.Auto }, /** * Sets the maximum width of the control. * * @since 1.109 */ maxWidth: { type: "sap.ui.core.CSSSize", group: "Dimension", defaultValue: "100%" }, /** * Defines the Apply Automatically text for the standard variant in the Manage Views dialog if the application controls this behavior. */ _displayTextForExecuteOnSelectionForStandardVariant: { type: "string", group: "Misc", defaultValue: "", visibility: "hidden" }, /** * Renders the name of the variant as a text. * The name of the variant is usually rendered as {@link sap.m.Title} * but there are use cases - related to accessibility requirements - where the * rendering should be done using {@link sap.m.Text} instead.<br> * <b>Note:</b> * If the name of the variant is rendered as <code>sap.m.Text</code>, all the <code>sap.m.Title</code> * specific information like <code>level</code> and <code>titleStyle</code> is ignored. * * @since 1.118 */ _showAsText: { type: "boolean", group: "Misc", defaultValue: false, visibility: "hidden" }, /** * Defines the behavior, when the same list item is selected * If set to <code>false</code> the <code>select</code> event will be omitted. */ _selectStategyForSameItem: { type: "boolean", group: "Misc", defaultValue: true, visibility: "hidden" }, /** * Defines the standard variant key. */ _standardKey: { type: "string", group: "Misc", defaultValue: "", visibility: "hidden" } }, defaultAggregation: "items", aggregations: { /** * Items displayed by the <code>VariantManagement</code> control. */ items: { type: "sap.m.VariantItem", multiple: true, singularName: "item" } }, events: { /** * This event is fired when the Save View dialog or the Save As dialog is closed with the Save button. */ save: { parameters: { /** * Variant title */ name: { type: "string" }, /** * Indicates if an existing variant is updated or if a new variant is created. */ overwrite: { type: "boolean" }, /** * Variant key. This property is only set, when <code>overwrite</code> is set to <code>true</code>. */ key: { type: "string" }, /** * <i>Apply Automatically</i> indicator */ execute: { type: "boolean" }, /** * The default variant indicator */ def: { type: "boolean" }, /** * Indicates the check box state for 'Public'. */ 'public': { type: "boolean" }, /** * Array describing the contexts.<br> * <b>Note:</b> This property is used internally by the SAPUI5 flexibility layer. * @restricted sap.ui.fl, sap.ui.comp */ contexts: { type: "object[]" }, /** * Indicates the check box state for 'Create Tile'.<br> * <b>Note:</b> * This event parameter is used only internally. */ tile: { type: "boolean" } } }, /** * This event is fired when users presses the cancel button inside <i>Save As</i> dialog. */ cancel: {}, /** * This event is fired when users presses the cancel button inside <i>Manage Views</i> dialog. */ manageCancel: {}, /** * This event is fired when users opens the <i>Manage Views</i> dialog. */ manageOpen: {}, /** * This event is fired when users apply changes variant information in the <i>Manage Views</i> dialog. * Some of the parameters may be ommitted, depending on user selection. */ manage: { parameters: { /** * List of changed variants. */ renamed: { type: "sap.m.VariantManagementRename[]" }, /** * List of deleted variant keys */ deleted: { type: "string[]" }, /** * List of variant keys and the associated Execute on Selection indicator. */ exe: { type: "sap.m.VariantManagementExe[]" }, /** * List of variant keys and the associated favorite indicator. */ fav: { type: "sap.m.VariantManagementFav[]" }, /** * The default variant key */ def: { type: "string" }, /** * List of variant keys and the associated contexts array. * Each entry contains a <code>key</code> (the variant key) and a <code>contexts</code> array describing the contexts.<br> * <b>Note:</b> This property is used internally by the SAPUI5 flexibility layer. * @restricted sap.ui.fl, sap.ui.comp */ contexts: { type: "object[]" } } }, /** * This event is fired when a new variant is selected. */ select: { parameters: { /** * Variant key */ key: { type: "string" } } } } }, /** * Renders the HTML for the given control, using the provided {@link sap.ui.core.RenderManager}. * @param {sap.ui.core.RenderManager} oRm - <code>RenderManager</code> that can be used for writing to the render output buffer * @param {sap.ui.core.Control} oControl - Object representation of the control that should be rendered */ renderer: { apiVersion: 2, render: function(oRm, oControl) { oRm.openStart("div", oControl) .style("max-width", oControl.getMaxWidth()) .class("sapMVarMngmt") .openEnd(); oRm.renderControl(oControl.oVariantLayout); oRm.close("div"); } } }); const AriaHasPopup = coreLibrary.aria.HasPopup; VariantManagement.INNER_MODEL_NAME = "$sapMInnerVariants"; VariantManagement.MAX_NAME_LEN = 100; VariantManagement.COLUMN_FAV_IDX = 0; VariantManagement.COLUMN_NAME_IDX = 1; VariantManagement.COLUMN_DEFAULT_IDX = 3; VariantManagement.COLUMN_ROLES_IDX = 5; /* * Constructs and initializes the <code>VariantManagement</code> control. */ VariantManagement.prototype.init = function() { Control.prototype.init.apply(this, arguments); this._oRb = Library.getResourceBundleFor("sap.m"); // Check whether device is Macintosh this.deviceIsMac = Device.os.macintosh; this._oManagedObjectModel = new ManagedObjectModel(this); this.setModel(this._oManagedObjectModel, "$mVariants"); this._oObserver = new ManagedObjectObserver(this._observeChanges.bind(this)); this._oObserver.observe(this, { aggregations: [ "items" ] }); }; VariantManagement.prototype._observeChanges = function(oChanges) { var oVariantItem; if (oChanges.type === "aggregation") { if (oChanges.name === "items") { oVariantItem = oChanges.child; switch (oChanges.mutation) { case "insert": if (!this._oObserver.isObserved(oVariantItem, {properties: ["title", "favorite", "executeOnSelect", "contexts"]})) { this._oObserver.observe(oVariantItem, {properties: ["title", "favorite", "executeOnSelect", "contexts"]}); } if (this.getSelectedKey() === oVariantItem.getKey()) { this.refreshTitle(); } break; case "remove": if (this._oObserver.isObserved(oVariantItem, {properties: ["title", "favorite", "executeOnSelect", "contexts"]})) { this._oObserver.unobserve(oVariantItem, {properties: ["title", "favorite", "executeOnSelect", "contexts"]}); } break; default: Log.error("operation " + oChanges.mutation + " not yet implemented"); } } } else if (oChanges.type === "property") { if (oChanges.object?.isA?.("sap.m.VariantItem")) { oVariantItem = oChanges.object; if (this.getSelectedKey() === oVariantItem.getKey()) { this.refreshTitle(); } if (!this.oManagementTable || (this.oManagementTable.getItems && this.oManagementTable.getItems().length === 0)) { if (oChanges.name === "title") { oVariantItem._setOriginalTitle(oChanges.current); } else if (oChanges.name === "favorite") { oVariantItem._setOriginalFavorite(oChanges.current); } else if (oChanges.name === "executeOnSelect") { oVariantItem._setOriginalExecuteOnSelect(oChanges.current); } else if (oChanges.name === "contexts") { oVariantItem._setOriginalContexts(oChanges.current); } } else { const oRow = this.oManagementTable.getItems().find((oListItem) => { const oItem = this._findVariantItem(oListItem.getBindingContext(this._sModelName)); return oItem.getKey() === oVariantItem.getKey(); }); if (oChanges.name === "contexts") { this._updateContextsDependencies(oRow); } } } } }; VariantManagement.prototype.applySettings = function(mSettings, oScope) { Control.prototype.applySettings.apply(this, arguments); this._createInnerModel(); this._initializeControl(); }; /** * Special handling of the rendering the apply automatically control in <i>Manage Views</i> * @returns {string} Value of the private property * @private * @restricted sap.ui.fl, sap.ui.comp */ VariantManagement.prototype.getDisplayTextForExecuteOnSelectionForStandardVariant = function() { return this.getProperty("_displayTextForExecuteOnSelectionForStandardVariant"); }; /** * Special handling of the rendering the apply automatically control in <i>Manage Views</i> * @param {string} sValue to be displayed * @returns {string} the current instance * @private * @restricted sap.ui.fl, sap.ui.comp */ VariantManagement.prototype.setDisplayTextForExecuteOnSelectionForStandardVariant = function(sValue) { this.setProperty("_displayTextForExecuteOnSelectionForStandardVariant", sValue); return this; }; /** * Special handling of the rendering of this control. * @param {boolean} bValue defines the intended rendering * @returns {sap.m.VariantManagement} the current instance * @private * @restricted sap.ui.fl, sap.ui.comp */ VariantManagement.prototype.setShowAsText = function(bValue) { this.setProperty("_showAsText", bValue); this._reCreateVariantTextControl(); return this; }; /** * Special handling of the rendering of this control. * @returns {boolean} the current intend * @private * @restricted sap.ui.fl, sap.ui.comp */ VariantManagement.prototype.getShowAsText = function() { return this.getProperty("_showAsText"); }; VariantManagement.prototype.setShowFooter = function(bValue) { this.setProperty("showFooter", bValue); return this; }; VariantManagement.prototype.setDefaultKey = function(sValue) { this.setProperty("defaultKey", sValue); return this; }; VariantManagement.prototype.setPopoverTitle = function(sValue) { this.setProperty("popoverTitle", sValue); return this; }; VariantManagement.prototype._createVariantTextControl = function() { var FnVariantRenderType = this.getShowAsText() ? Text : Title; var oVariantText = new FnVariantRenderType(this.getId() + "-text", { text: { path: '/selectedKey', model: "$mVariants", formatter: function(sKey) { var sText = ""; if (sKey) { sText = this.getSelectedVariantText(sKey); this._setInvisibleText(sText, this.getModified()); } return sText; }.bind(this) } }); if (oVariantText.isA("sap.m.Title")) { oVariantText.bindProperty("level", { path: '/level', model: "$mVariants" }); oVariantText.bindProperty("titleStyle", { path: '/titleStyle', model: "$mVariants" }); } oVariantText.addStyleClass("sapMVarMngmtClickable"); oVariantText.addStyleClass("sapMVarMngmtTitle"); return oVariantText; }; VariantManagement.prototype._initializeControl = function() { if (this.oVariantInvisibleText) { return; } this.oVariantInvisibleText = new InvisibleText(this.getId() + "-invText"); this.oVariantText = this._createVariantTextControl(); var oVariantModifiedText = new Text(this.getId() + "-modified", { text: "*", visible: { path: "/modified", model: "$mVariants", formatter: function(bValue) { var sKey = this.getSelectedKey(); if (sKey) { this._setInvisibleText(this.getSelectedVariantText(sKey), bValue); } return ((bValue === null) || (bValue === undefined)) ? false : bValue; }.bind(this) } }); oVariantModifiedText.setVisible(false); oVariantModifiedText.addStyleClass("sapMVarMngmtModified"); oVariantModifiedText.addStyleClass("sapMVarMngmtClickable"); this.oVariantPopoverTrigger = new Button(this.getId() + "-trigger", { icon: "sap-icon://slim-arrow-down", type: ButtonType.Transparent, tooltip: this._oRb.getText("VARIANT_MANAGEMENT_TRIGGER_TT"), enabled: { path: "/isDesignMode", model: VariantManagement.INNER_MODEL_NAME, formatter: function(bValue) { return !bValue; } }, ariaHasPopup: AriaHasPopup.Dialog }); this.oVariantPopoverTrigger.addAriaLabelledBy(this.oVariantInvisibleText); this.oVariantPopoverTrigger.addStyleClass("sapMVarMngmtClickable"); this.oVariantLayout = new HorizontalLayout(this.getId() + "-content", { content: [ this.oVariantText, oVariantModifiedText, this.oVariantPopoverTrigger ] }); this.oVariantLayout.addStyleClass("sapMVarMngmtLayout"); this.oVariantLayout.addStyleClass("sapMVarMngmtLayoutModifiedHidden"); oVariantModifiedText.setVisible(false); this.oVariantModifiedText = oVariantModifiedText; this.oVariantInvisibleText.toStatic(); this.addDependent(this.oVariantLayout); }; VariantManagement.prototype._reCreateVariantTextControl = function() { if (!this.getShowAsText() && this.oVariantText && this.oVariantText.isA("sap.m.Title)")) { return; } if (!this.getShowAsText() && this.oVariantText && this.oVariantText.isA("sap.m.Text)")) { return; } if (this.oVariantText) { this.oVariantLayout.removeContent(0); this.oVariantText.destroy(); } var oVariantText = this._createVariantTextControl(); this.oVariantLayout.insertContent(oVariantText, 0); this.oVariantText = oVariantText; }; /** * Required by the {@link sap.m.IOverflowToolbarContent} interface. * Registers invalidations event which is fired when width of the control is changed. * * @protected * @returns {{canOverflow: boolean, invalidationEvents: string[]}} Configuration information for the <code>sap.m.IOverflowToolbarContent</code> interface */ VariantManagement.prototype.getOverflowToolbarConfig = function() { return { canOverflow: false, invalidationEvents: ["save", "manage", "select"] }; }; /** * Returns the title control of the <code>VariantManagement</code>. This is used in the key user scenario. * @protected * @returns {sap.m.Title} Title part of the <code>VariantManagement</code> control. */ VariantManagement.prototype.getTitle = function() { return this.oVariantText; }; VariantManagement.prototype.refreshTitle = function() { if (this.oVariantText) { this.oVariantText.getBinding("text").refresh(true); } }; VariantManagement.prototype._setInvisibleText = function(sText, bFlag) { var sInvisibleTextKey; if (sText) { if (bFlag) { sInvisibleTextKey = "VARIANT_MANAGEMENT_SEL_VARIANT_MOD"; this.oVariantLayout.removeStyleClass("sapMVarMngmtLayoutModifiedHidden"); } else { sInvisibleTextKey = "VARIANT_MANAGEMENT_SEL_VARIANT"; this.oVariantLayout.addStyleClass("sapMVarMngmtLayoutModifiedHidden"); } this.oVariantInvisibleText.setText(this._oRb.getText(sInvisibleTextKey, [sText])); } }; VariantManagement.prototype._createInnerModel = function() { var oModel = new JSONModel({ showCreateTile: false, isDesignMode: false, hasNoData: false }); this.setModel(oModel, VariantManagement.INNER_MODEL_NAME); }; VariantManagement.prototype._getShowCreateTile = function() { return this._getInnerModelProperty("/showCreateTile"); }; VariantManagement.prototype._setShowCreateTile = function(bValue) { this._setInnerModelProperty("/showCreateTile", bValue); }; VariantManagement.prototype.getDesignMode = function() { return this._getInnerModelProperty("/isDesignMode"); }; VariantManagement.prototype.setDesignMode = function(bValue) { this._setInnerModelProperty("/isDesignMode", bValue); }; VariantManagement.prototype.setHasNoData = function(bValue) { this._setInnerModelProperty("/hasNoData", bValue); }; VariantManagement.prototype._setInnerModelProperty = function(sPropertyPath, vValue) { var oInnerModel = this.getModel(VariantManagement.INNER_MODEL_NAME); if (oInnerModel) { oInnerModel.setProperty(sPropertyPath, vValue); } }; VariantManagement.prototype._getInnerModelProperty = function(sPropertyPath) { var oInnerModel = this.getModel(VariantManagement.INNER_MODEL_NAME); if (oInnerModel) { return oInnerModel.getProperty(sPropertyPath); } return null; }; /** * Gets all the variants * @private * @returns {array} Of variants */ VariantManagement.prototype._getItems = function() { return this.getItems(); }; VariantManagement.prototype.getSelectedVariantText = function(sKey) { var oItem = this._getItemByKey(sKey); if (oItem) { return oItem.getTitle(); } return ""; }; /** * Retrieves for the controls {@link sap.ui.comp.smartvariants.SmartVariantManagement} and {@link sap.ui.fl.variants.VariantManagement} the <i>Standard</i> variant. * For all other scenarios the first visible variant will be returned, or <code>null</code> if there are none. * @public * @returns {(string | null)} The key of either the standard variant or the first visible variant or <code>null</code>. */ VariantManagement.prototype.getStandardVariantKey = function() { var sKey = this.getProperty("_standardKey"); if (!sKey) { return this._getFirstVisibleVariant(); } return sKey; }; /** * Assignes the key of the <i>Standard</i> variant. * * @private * @restricted sap.ui.fl, sap.ui.comp * @param {string} sValue describing the key of the standard variant */ VariantManagement.prototype.setStandardVariantKey = function(sValue) { this.setProperty("_standardKey", sValue); }; VariantManagement.prototype._getFirstVisibleVariant = function() { var aItems = this._getItems(); for (var i = 0; i < aItems.length; i++) { if (!this._isItemDeleted(aItems[i])) { if (this.getSupportFavorites()) { if (aItems[i].getFavorite()) { return aItems[i].getKey(); } } else { return aItems[i].getKey(); } } } return null; }; VariantManagement.prototype._clearDeletedItems = function() { this._aDeletedItems = []; }; VariantManagement.prototype._addDeletedItem = function(oItem) { var sKey = oItem.getKey(); if (this._aDeletedItems.indexOf(sKey) < 0) { this._aDeletedItems.push(sKey); } }; VariantManagement.prototype._getDeletedItems = function() { return this._aDeletedItems; }; VariantManagement.prototype._clearRenamedItems = function() { this._aRenamedItems = []; }; VariantManagement.prototype._addRenamedItem = function(oItem) { var sKey = oItem.getKey(); if (this._aRenamedItems.indexOf(sKey) < 0) { this._aRenamedItems.push(sKey); } }; VariantManagement.prototype._removeRenamedItem = function(oItem) { var sKey = oItem.getKey(); var nIdx = this._aRenamedItems.indexOf(sKey); if ( nIdx >= 0) { this._aRenamedItems.splice(nIdx, 1); } }; VariantManagement.prototype._getRenamedItems = function() { return this._aRenamedItems; }; /** * Retrieves a variant item by its key. * @public * @param {string} sKey of the item * @returns {(sap.m.VariantItem|null)} For a specific key; <code>null</code> if no matching item was found */ VariantManagement.prototype.getItemByKey = function(sKey) { return this._getItemByKey(sKey); }; VariantManagement.prototype._getItemByKey = function(sKey) { var oItem = null; var aItems = this._getItems(); if (aItems) { aItems.some(function(oEntry) { if (oEntry.getKey() === sKey) { oItem = oEntry; } return (oItem !== null); }); } return oItem; }; VariantManagement.prototype._obtainControl = function(oEvent) { if (oEvent && oEvent.target && oEvent.target.id) { var sId = oEvent.target.id; var nPos = sId.indexOf("-inner"); if (nPos > 0) { sId = sId.substring(0, nPos); } return Element.getElementById(sId); } return null; }; // clickable area VariantManagement.prototype.handleOpenCloseVariantPopover = function(oEvent) { if (!this.bPopoverOpen) { this._oCtrlRef = this._obtainControl(oEvent); this._openVariantList(); } else if (this.oVariantPopOver && this.oVariantPopOver.isOpen()) { this.oVariantPopOver.close(); } else if (this.getInErrorState() && this.oErrorVariantPopOver && this.oErrorVariantPopOver.isOpen()) { this.oErrorVariantPopOver.close(); } }; VariantManagement.prototype.getFocusDomRef = function() { return this.oVariantPopoverTrigger.getFocusDomRef(); }; VariantManagement.prototype.onclick = function(oEvent) { if (this.getDesignMode()) { return; } if (this.oVariantPopoverTrigger && !this.bPopoverOpen) { this.oVariantPopoverTrigger.focus(); } this.handleOpenCloseVariantPopover(oEvent); }; VariantManagement.prototype.onkeyup = function(oEvent) { if (oEvent.keyCode === KeyCodes.F4 || oEvent.keyCode === KeyCodes.SPACE || oEvent.altKey === true && oEvent.keyCode === KeyCodes.ARROW_UP || oEvent.altKey === true && oEvent.keyCode === KeyCodes.ARROW_DOWN) { this._oCtrlRef = this._obtainControl(oEvent); this._openVariantList(); } }; VariantManagement.prototype.onAfterRendering = function() { if (this.oVariantText) { this.oVariantText.$().off("mouseover").on("mouseover", function() { this.oVariantPopoverTrigger.addStyleClass("sapMVarMngmtTriggerBtnHover"); }.bind(this)); this.oVariantText.$().off("mouseout").on("mouseout", function() { this.oVariantPopoverTrigger.removeStyleClass("sapMVarMngmtTriggerBtnHover"); }.bind(this)); } // Set initial aria-expanded state after rendering if (this.oVariantPopoverTrigger && this.oVariantPopoverTrigger.$().length > 0) { this.oVariantPopoverTrigger.$().attr("aria-expanded", "false"); } }; // ERROR LIST VariantManagement.prototype._openInErrorState = function() { var oVBox; if (!this.oErrorVariantPopOver) { oVBox = new VBox(this.getId() + "-errorContent", { fitContainer: true, alignItems: FlexAlignItems.Center, items: [ new Icon(this.getId() + "-errorIcon", { size: "4rem", color: "lightgray", src: "sap-icon://message-error" }), new Title(this.getId() + "-errorTitle", { titleStyle: TitleLevel.H2, text: this._oRb.getText("VARIANT_MANAGEMENT_ERROR_TEXT1") }), new Text(this.getId() + "-errorText", { textAlign: TextAlign.Center, text: this._oRb.getText("VARIANT_MANAGEMENT_ERROR_TEXT2") }) ] }); oVBox.addStyleClass("sapMVarMngmtErrorPopover"); this.oErrorVariantPopOver = new ResponsivePopover(this.getId() + "-errorpopover", { title: { path: "/popoverTitle", model: "$mVariants" }, contentWidth: "400px", placement: PlacementType.VerticalPreferredBottom, content: [ new Page(this.getId() + "-errorselpage", { showSubHeader: false, showNavButton: false, showHeader: false, content: [ oVBox ] }) ], afterOpen: function() { this.bPopoverOpen = true; }.bind(this), afterClose: function() { if (this.bPopoverOpen) { setTimeout(function() { this.bPopoverOpen = false; }.bind(this), 200); } }.bind(this), beforeClose: function() { this.oVariantPopoverTrigger?.$().attr("aria-expanded", "false"); }.bind(this), contentHeight: "300px" }); this.oErrorVariantPopOver.attachBrowserEvent("keyup", function(e) { if (e.which === 32) { // UP this.oErrorVariantPopOver.close(); } }.bind(this)); } if (this.bPopoverOpen) { return; } this.oErrorVariantPopOver.openBy(this.oVariantLayout); }; VariantManagement.prototype._createIllustratedMessages = function() { if (!this._oNoDataIllustratedMessage || this._oNoDataIllustratedMessage.bIsDestroyed) { this._oNoDataIllustratedMessage = new IllustratedMessage(this.getId() + "-noData", { title: this._oRb.getText("VARIANT_MANAGEMENT_NODATA"), description: this._oRb.getText("VARIANT_MANAGEMENT_NODATA_DESCR"), enableVerticalResponsiveness: true, illustrationSize: IllustratedMessageSize.Auto, illustrationType: mobileLibrary.IllustratedMessageType.NoEntries }); } if (!this._oNoDataFoundIllustratedMessage || this._oNoDataFoundIllustratedMessage.bIsDestroyed) { this._oNoDataFoundIllustratedMessage = new IllustratedMessage(this.getId() + "-noDataFound", { title: this._oRb.getText("VARIANT_MANAGEMENT_NODATA_FOUND"), description: this._oRb.getText("VARIANT_MANAGEMENT_NODATA_FOUND_DESCR"), enableVerticalResponsiveness: true, illustrationSize: IllustratedMessageSize.Auto, illustrationType: mobileLibrary.IllustratedMessageType.NoSearchResults }); this._oNoDataFoundIllustratedMessage.addStyleClass("sapMVarMngmtIllustratedMessage"); } }; // My Views List VariantManagement.prototype._createVariantList = function() { if (this.oVariantPopOver) { return; } this._createIllustratedMessages(); this.oVariantManageBtn = new Button(this.getId() + "-manage", { text: this._oRb.getText("VARIANT_MANAGEMENT_MANAGE"), enabled: true, press: function() { this._openManagementDialog(); }.bind(this), layoutData: new OverflowToolbarLayoutData(this.getId() + "-manage-layoutData", { priority: OverflowToolbarPriority.Low }) }); this.oVariantSaveBtn = new Button(this.getId() + "-mainsave", { text: this._oRb.getText("VARIANT_MANAGEMENT_SAVE"), press: function() { this._handleVariantSave(); }.bind(this), visible: { parts: [{ path: '$mVariants>/creationAllowed' },{ path: '$mVariants>/modified' },{ path: '$mVariants>/selectedKey' } ], formatter: function(bCreationAllowed, bModified, sSelectedKey) { var bItemChangeable = false; var oItem = this._getItemByKey(sSelectedKey); if (oItem) { bItemChangeable = oItem.getChangeable(); } return bCreationAllowed && bModified && bItemChangeable; }.bind(this) }, type: ButtonType.Emphasized, layoutData: new OverflowToolbarLayoutData(this.getId() + "-mainsave-layoutData", { priority: OverflowToolbarPriority.Low }) }); ShortcutHintsMixin.addConfig(this.oVariantSaveBtn, { addAccessibilityLabel: true, message: this._getSaveTooltipText("SAVE_MAIN") }, this); this.oVariantSaveAsBtn = new Button(this.getId() + "-saveas", { text: this._oRb.getText("VARIANT_MANAGEMENT_SAVEAS"), press: function() { this._openSaveAsDialog(); }.bind(this), layoutData: new OverflowToolbarLayoutData(this.getId() + "-saveas-layoutData", { priority: OverflowToolbarPriority.Low }), visible: { parts: [{ path: '$mVariants>/creationAllowed' },{ path: '$mVariants>/showSaveAs' }], formatter: function(bCreationAllowed, bShowSaveAs) { return bCreationAllowed && bShowSaveAs; } } }); this.oVariantList = new SelectList(this.getId() + "-list", { selectedKey: { path: "/selectedKey", model: "$mVariants" }, visible: { path: "/hasNoData", model: VariantManagement.INNER_MODEL_NAME, formatter: function(bValue) { return !bValue; } }, itemPress: function(oEvent) { var sSelectionKey = null; if (oEvent && oEvent.getParameters()) { var oItemPressed = oEvent.getParameters().item; if (oItemPressed) { sSelectionKey = oItemPressed.getKey(); } } if (sSelectionKey) { this.setCurrentVariantKey(sSelectionKey); this.oVariantPopOver.close(); } }.bind(this) }); this.oVariantListInvisibleText = new InvisibleText(this.getId() + "-listInvisibleText", { text: this._oRb.getText("VARIANT_MANAGEMENT_VIEW_LIST") }); this.oVariantListInvisibleText.toStatic(); this.oVariantList.addAriaLabelledBy(this.oVariantListInvisibleText); this.oNodataTextLayout = new VBox(this.getId() + "-no-data", { visible: { path: "/hasNoData", model: VariantManagement.INNER_MODEL_NAME }, fitContainer: true, items: [this._oNoDataFoundIllustratedMessage] }); var oItemTemplate = new Item(this.getId() + "-list-item", { key: "{$mVariants>key}", text: "{$mVariants>title}" }); this.oVariantList.bindAggregation("items", { path: "/items", model: "$mVariants", template: oItemTemplate }); this._oSearchField = new SearchField(this.getId() + "-search"); this._oSearchField.attachLiveChange(function(oEvent) { this._triggerSearch(oEvent, this.oVariantList); }.bind(this)); this.oVariantSelectionPage = new Page(this.getId() + "-selpage", { subHeader: new Toolbar(this.getId() + "-selpage-header", { content: [ this._oSearchField ] }), content: [ this.oVariantList, this.oNodataTextLayout ], footer: new OverflowToolbar(this.getId() + "-selpage-footer", { content: [ new ToolbarSpacer(this.getId() + "-selpage-footer-spacer"), this.oVariantSaveBtn, this.oVariantSaveAsBtn, this.oVariantManageBtn ] }), showNavButton: false, showHeader: false }); this.oVariantSelectionPage.bindProperty("showFooter", { path: "/showFooter", model: "$mVariants" }); this.oVariantPopOver = new ResponsivePopover(this.getId() + "-popover", { title: { path: "/popoverTitle", model: "$mVariants" }, titleAlignment: "Auto", contentWidth: "400px", placement: PlacementType.VerticalPreferredBottom, resizable: true, content: [ this.oVariantSelectionPage ], afterOpen: function() { this.bPopoverOpen = true; }.bind(this), afterClose: function() { if (this.bPopoverOpen) { setTimeout(function() { this.bPopoverOpen = false; }.bind(this), 200); } }.bind(this), beforeClose: function() { this.oVariantPopoverTrigger?.$().attr("aria-expanded", "false"); }.bind(this), contentHeight: "300px" }); this.oVariantPopOver.addEventDelegate({ onkeydown: function(oEvent) { const bCtrlKey = this.deviceIsMac ? oEvent.metaKey : oEvent.ctrlKey; // Use CTRL / CMD + S to trigger the Save action if ( oEvent.keyCode == KeyCodes.S && (oEvent.shiftKey === false) && (oEvent.altKey === false) && (bCtrlKey === true)) { if (this.oVariantSaveBtn?.getVisible() && this.oVariantSaveBtn?.getEnabled()) { oEvent.preventDefault(); oEvent.stopPropagation(); this._handleVariantSave(); } } } }, this); this.oVariantPopOver.addStyleClass("sapMVarMngmtPopover"); if (this.oVariantLayout.$().closest(".sapUiSizeCompact").length > 0) { this.oVariantPopOver.addStyleClass("sapUiSizeCompact"); } this.addDependent(this.oVariantPopOver); this.oVariantPopOver.isPopupAdaptationAllowed = function() { return false; }; }; /** * Enables the programmatic selection of a variant. * @public * @param {string} sKey of variant to be selected. If the passed key doesn't identify a variant, it will be ignored * * @since 1.121 */ VariantManagement.prototype.setCurrentVariantKey = function(sKey) { var oItem = this.getItemByKey(sKey); if (oItem) { var bTriggerForSameItem = this.getProperty("_selectStategyForSameItem"); if (bTriggerForSameItem || (!bTriggerForSameItem && (this.getSelectedKey() !== sKey))) { this.setSelectedKey(sKey); this.fireSelect({ key: sKey }); } } else { Log.error("setCurrentVariantKey called with unknown key:'" + sKey + "'"); } }; VariantManagement.prototype._determineEmphasizedFooterButton = function() { if (this.oVariantSaveBtn.getVisible()) { this.oVariantSaveBtn.setType(ButtonType.Emphasized); this.oVariantSaveAsBtn.setType(ButtonType.Default); } else { this.oVariantSaveAsBtn.setType(ButtonType.Emphasized); } }; VariantManagement.prototype.setModified = function(bValue) { this.setProperty("modified", bValue); return this; }; VariantManagement.prototype._openVariantList = function() { if (this.getInErrorState()) { this._openInErrorState(); return; } this.oVariantPopoverTrigger.$().attr("aria-expanded", "true"); if (this.bPopoverOpen || this.iOpenTimer) { return; } this._createVariantList(); this._oSearchField.setValue(""); const oListBinding = this.oVariantList.getBinding("items"); oListBinding.attachChange(function(oEvent) { this.setHasNoData(this.oVariantList.getItems().length === 0); }.bind(this)); oListBinding.filter(this._getFilters()); if (this.oVariantList.getItems().length < 1) { this.oNodataTextLayout.removeAllItems(); this.oNodataTextLayout.addItem(this._oNoDataIllustratedMessage); } this.oVariantSelectionPage.setShowSubHeader(this.oVariantList.getItems().length > 9); this._determineEmphasizedFooterButton(); var oSelectedItem = this.oVariantList.getSelectedItem(); if (oSelectedItem) { this.oVariantPopOver.setInitialFocus(oSelectedItem.getId()); } var oControlRef = this._oCtrlRef ? this._oCtrlRef : this.oVariantLayout; this._oCtrlRef = null; this.iOpenTimer = setTimeout(() => { // otherwise screenreader would not announce the expanded-state of the button delete this.iOpenTimer; if (!this.isDestroyed()) { this.oVariantPopOver.openBy(oControlRef); } }, 100); }; VariantManagement.prototype._triggerSearch = function(oEvent, oVariantList) { if (!oEvent) { return; } var parameters = oEvent.getParameters(); if (!parameters) { return; } var sValue = parameters.newValue ? parameters.newValue : ""; var oFilter = new Filter({ path: "title", operator: FilterOperator.Contains, value1: sValue }); oVariantList.getBinding("items").filter(this._getFilters(oFilter)); if (oVariantList.getItems().length < 1) { if ((this.oNodataTextLayout.getItems().length === 0) || (this.oNodataTextLayout.getItems().length > 0) && (this.oNodataTextLayout.getItems()[0] !== this._oNoDataFoundIllustratedMessage)) { if (!this._oNoDataFoundIllustratedMessage.hasStyleClass("sapMVarMngmtIllustratedMessage")) { this._oNoDataFoundIllustratedMessage.toggleStyleClass("sapMVarMngmtIllustratedMessage"); } this.oNodataTextLayout.removeAllItems(); this.oNodataTextLayout.addItem(this._oNoDataFoundIllustratedMessage); } } }; // Save View dialog VariantManagement.prototype._createSaveAsDialog = function() { if (!this.oSaveAsDialog) { this.oInputName = new Input(this.getId() + "-name", { liveChange: function() { this._checkVariantNameConstraints(this.oInputName); }.bind(this) }); var oLabelName = new Label(this.getId() + "-namelabel", { text: this._oRb.getText("VARIANT_MANAGEMENT_NAME") }); oLabelName.setLabelFor(this.oInputName); oLabelName.addStyleClass("sapMVarMngmtSaveDialogLabel"); this.oDefault = new CheckBox(this.getId() + "-default", { text: this._oRb.getText("VARIANT_MANAGEMENT_SETASDEFAULT"), visible: { path: "/supportDefault", model: "$mVariants" }, select: function(oEvent) { if (this._sStyleClass) { if (oEvent.getParameter("selected")) { var mContexts = this._getContextInfoChanges(); if (this._isRestricted(mContexts)) { this.oDefault.setValueState(ValueState.Error); this.oDefault.setValueStateText(this._oRb.getText("VARIANT_MANAGEMENT_NO_DEFAULT_ON_RESTRICTED_VIEWS")); this.oDefault.focus(); } else { this.oDefault.setValueState(ValueState.None); this.oDefault.setValueStateText(""); } } else if (this.oDefault.getValueState() != ValueState.None){ this.oDefault.setValueState(ValueState.None); this.oDefault.setValueStateText(""); } } }.bind(this), width: "100%" }); this.oPublic = new CheckBox(this.getId() + "-public", { text: this._oRb.getText("VARIANT_MANAGEMENT_SETASPUBLIC"), visible: { path: "/supportPublic", model: "$mVariants" }, width: "100%" }); this.oExecuteOnSelect = new CheckBox(this.getId() + "-execute", { text: this._oRb.getText("VARIANT_MANAGEMENT_EXECUTEONSELECT"), visible: { path: "/supportApplyAutomatically", model: "$mVariants" }, width: "100%" }); this.oCreateTile = new CheckBox(this.getId() + "-tile", { text: this._oRb.getText("VARIANT_MANAGEMENT_CREATETILE"), enabled: true, visible: { path: "/showCreateTile", model: VariantManagement.INNER_MODEL_NAME }, width: "100%" }); this.oSaveSave = new Button(this.getId() + "-variantsave", { text: this._oRb.getText("VARIANT_MANAGEMENT_SAVE"), type: ButtonType.Emphasized, press: this._fireVariantSaveAsEvent.bind(this), enabled: true }); this.oSaveAsCancel = new Button(this.getId() + "-variantcancel", { text: this._oRb.getText("VARIANT_MANAGEMENT_CANCEL"), press: this._cancelPressed.bind(this) }); ShortcutHintsMixin.addConfig(this.oSaveSave, { addAccessibilityLabel: true, message: this._getSaveTooltipText("SAVE") }, this); var oSaveAsDialogOptionsGrid = new Grid(this.getId() + "-savedialog-options", { defaultSpan: "L12 M12 S12" }); oSaveAsDialogOptionsGrid.addContent(this.oDefault); oSaveAsDialogOptionsGrid.addContent(this.oPublic); oSaveAsDialogOptionsGrid.addContent(this.oExecuteOnSelect); oSaveAsDialogOptionsGrid.addContent(this.oCreateTile); this.oSaveAsDialog = new Dialog(this.getId() + "-savedialog", { title: this._oRb.getText("VARIANT_MANAGEMENT_SAVEDIALOG"), afterClose: function() { this._bSaveOngoing = false; if (this._sStyleClass) { this.setSupportPublic(this._bShowPublic); this.oSaveAsDialog.removeStyleClass(this._sStyleClass); if (this._oRolesComponentContainer) { this.oSaveAsDialog.removeContent(this._oRolesComponentContainer); } this._sStyleClass = undefined; this._oRolesComponentContainer = null; } }.bind(this), beginButton: this.oSaveSave, endButton: this.oSaveAsCancel, content: [ oLabelName, this.oInputName, oSaveAsDialogOptionsGrid ], stretch: Device.system.phone }); this.oSaveAsDialog.isPopupAdaptationAllowed = function() { return false; }; this.oSaveAsDialog.addStyleClass("sapUiContentPadding"); this.oSaveAsDialog.addStyleClass("sapMVarMngmtSaveDialog"); if (this.oVariantLayout.$().closest(".sapUiSizeCompact").length > 0) { this.oSaveAsDialog.addStyleClass("sapUiSizeCompact"); } this.addDependent(this.oSaveAsDialog); // Use submit event to allow enter pressing for save this.oInputName.attachSubmit(this._fireVariantSaveAsEvent, this); } }; VariantManagement.prototype._fireVariantSaveAsEvent = function() { if (!this._bSaveOngoing) { this._checkVariantNameConstraints(this.oInputName); if (this.oInputName.getValueState() === ValueState.Error) { this.oInputName.focus(); return; } this._bSaveOngoing = true; this._bSaveCanceled = false; const bReturn = this._handleVariantSaveAs(this.oInputName.getValue()); if (!bReturn) { this._bSaveOngoing = false; } } }; VariantManagement.prototype._cancelPressed = function() { this._bSaveCanceled = true; this.fireCancel(); this.oSaveAsDialog.close(); }; VariantManagement.prototype._getSelectedContexts = function() { return this._oRolesComponentContainer.getComponentInstance().getSelectedContexts(); }; VariantManagement.prototype._setSelectedContexts = function(mContexts) { if (!mContexts || (Object.keys(mContexts).length === 0)) { mContexts = { role: []}; } this._oRolesComponentContainer.getComponentInstance().setSelectedContexts(mContexts); }; VariantManagement.prototype._isInErrorContexts = function() { return this._oRolesComponentContainer.getComponentInstance().hasErrorsAndShowErrorMessage(); }; VariantManagement.prototype._isRestricted = function(mContexts) { if (!mContexts) { mContexts = { role: []}; } return (mContexts.role && mContexts.role.length > 0); }; VariantManagement.prototype._determineRolesSpecificText = function(oItem, oTextControl) { if (oTextControl) { oTextControl.setText(this._oRb.getText((this._isRestricted(oItem.getContexts())) ? "VARIANT_MANAGEMENT_VISIBILITY_RESTRICTED" : "VARIANT_MANAGEMENT_VISIBILITY_NON_RESTRICTED")); } }; VariantManagement.prototype._checkAndAddRolesContainerToManageDialog = function() { if (this._oRolesComponentContainer && this._oRolesDialog) { var oRolesComponentContainer = null; this._oRolesDialog.getContent().some(function(oContent) { if (oContent === this._oRolesComponentContainer) { oRolesComponentContainer = oContent; return true; } return false; }.bind(this)); if (!oRolesComponentContainer) { this._oRolesDialog.addContent(this._oRolesComponentContainer); } } }; VariantManagement.prototype._createRolesDialog = function() { if (!this._oRolesDialog) { this._oRolesDialog = new Dialog(this.getId() + "-roledialog", { draggable: true, resizable: true, contentWidth: "40%", title: this._oRb.getText("VARIANT_MANAGEMENT_SELECTROLES_DIALOG"), beginButton: new Button(this.getId() + "-rolesave", { text: this._oRb.getText("VARIANT_MANAGEMENT_SAVE"), type: ButtonType.Emphasized, press: function() { if (!this._checkAndCreateContextInfoChanges(this._oCurrentContextsKey, this._oTextControl)) { return; } this._oRolesDialog.close(); }.bind(this) }), endButton: new Button(this.getId() + "-rolecancel", { text: this._oRb.getText("VARIANT_MANAGEMENT_CANCEL"), press: function() { this._oRolesDialog.close(); }.bind(this) }), content: [this._oRolesComponentContainer], stretch: Device.system.phone }); this._oRolesDialog.setParent(this); this._oRolesDialog.addStyleClass("sapUiContentPadding"); this._oRolesDialog.addStyleClass(this._sStyleClass); this._oRolesDialog.isPopupAdaptationAllowed = function() { return false; }; } this._checkAndAddRolesContainerToManageDialog(); }; VariantManagement.prototype._openRolesDialog = function(oItem, oTextControl) { this._createRolesDialog(); this._oCurrentContextsKey = oItem.getKey(); this._oTextControl = oTextControl; this._setSelectedContexts(oItem.getContexts()); this._oRolesDialog.open(); }; Va