diff --git a/packages/fiori/cypress/specs/UserSettingsDialog.cy.tsx b/packages/fiori/cypress/specs/UserSettingsDialog.cy.tsx index 7c06af057480e..ae1948cfb570b 100644 --- a/packages/fiori/cypress/specs/UserSettingsDialog.cy.tsx +++ b/packages/fiori/cypress/specs/UserSettingsDialog.cy.tsx @@ -1498,3 +1498,97 @@ describe("F6 Navigation", () => { .should("be.focused"); }); }); + +describe("Save mode", () => { + it("renders the default single Close button when saveMode is not set", () => { + cy.mount( + + + + + ); + cy.get("[ui5-user-settings-dialog]").shadow().find("[ui5-toolbar]").as("toolbar"); + cy.get("@toolbar").find("[ui5-toolbar-button]").should("have.length", 1); + cy.get("@toolbar").find("[ui5-toolbar-button]").should("have.attr", "design", "Transparent"); + }); + + it("renders Save (Emphasized) + Cancel buttons when saveMode is set", () => { + cy.mount( + + + + + ); + cy.get("[ui5-user-settings-dialog]").shadow().find("[ui5-toolbar]").as("toolbar"); + cy.get("@toolbar").find("[ui5-toolbar-button]").should("have.length", 2); + cy.get("@toolbar").find("[ui5-toolbar-button]").eq(0).should("have.attr", "design", "Emphasized"); + cy.get("@toolbar").find("[ui5-toolbar-button]").eq(1).should("have.attr", "design", "Transparent"); + }); + + it("fires the save event when the Save button is clicked", () => { + cy.mount( + + + + + ); + cy.get("[ui5-user-settings-dialog]").as("dialog"); + cy.get("@dialog").then($d => { + $d.get(0).addEventListener("save", cy.stub().as("saveEv")); + }); + cy.get("@dialog").shadow().find("[ui5-toolbar]") + .find("[ui5-toolbar-button]").eq(0) + .shadow().find("[ui5-button]").click(); + cy.get("@saveEv").should("have.been.calledOnce"); + }); + + it("fires the cancel event when the Cancel button is clicked", () => { + cy.mount( + + + + + ); + cy.get("[ui5-user-settings-dialog]").as("dialog"); + cy.get("@dialog").then($d => { + $d.get(0).addEventListener("cancel", cy.stub().as("cancelEv")); + }); + cy.get("@dialog").shadow().find("[ui5-toolbar]") + .find("[ui5-toolbar-button]").eq(1) + .shadow().find("[ui5-button]").click(); + cy.get("@cancelEv").should("have.been.calledOnce"); + }); + + it("does not close the dialog automatically on Save or Cancel", () => { + cy.mount( + + + + + ); + cy.get("[ui5-user-settings-dialog]").as("dialog"); + cy.get("@dialog").shadow().find("[ui5-toolbar]") + .find("[ui5-toolbar-button]").eq(0) + .shadow().find("[ui5-button]").click(); + cy.get("@dialog").should("have.attr", "open"); + cy.get("@dialog").shadow().find("[ui5-toolbar]") + .find("[ui5-toolbar-button]").eq(1) + .shadow().find("[ui5-button]").click(); + cy.get("@dialog").should("have.attr", "open"); + }); + + it("still fires before-close on ESC in saveMode", () => { + cy.mount( + + + + + ); + cy.get("[ui5-user-settings-dialog]").as("dialog"); + cy.get("@dialog").then($d => { + $d.get(0).addEventListener("before-close", cy.stub().as("beforeClose")); + }); + cy.realPress("Escape"); + cy.get("@beforeClose").should("have.been.calledOnce"); + }); +}); diff --git a/packages/fiori/src/UserSettingsDialog.ts b/packages/fiori/src/UserSettingsDialog.ts index 50833bb02c9f5..0304137b0604d 100644 --- a/packages/fiori/src/UserSettingsDialog.ts +++ b/packages/fiori/src/UserSettingsDialog.ts @@ -22,6 +22,8 @@ import { USER_SETTINGS_DIALOG_ACCESSIBLE_NAME, USER_SETTINGS_LIST_ARIA_ROLE_DESC, USER_SETTINGS_DIALOG_CLOSE_BUTTON_TEXT, + USER_SETTINGS_DIALOG_SAVE_BUTTON_TEXT, + USER_SETTINGS_DIALOG_CANCEL_BUTTON_TEXT, USER_SETTINGS_DIALOG_NO_SEARCH_RESULTS_TEXT, } from "./generated/i18n/i18n-defaults.js"; @@ -63,13 +65,16 @@ type UserSettingsBeforeCloseEventDetail = PopupBeforeCloseEventDetail; }) /** - * Fired when a settings dialog is open. + * Fired when the settings dialog is opened. * @public */ @event("open") /** * Fired before the settings dialog is closed. + * + * **Note:** This event is cancelable via `preventDefault()`, allowing the application to keep the + * dialog open — for example, to prompt the user about unsaved changes before dismissal. * @public */ @event("before-close", { @@ -77,17 +82,35 @@ type UserSettingsBeforeCloseEventDetail = PopupBeforeCloseEventDetail; }) /** - * Fired when a settings dialog is closed. + * Fired when the settings dialog is closed. * @public */ @event("close") +/** + * Fired when the Save button in the footer is clicked. + * The dialog does not close automatically — the application is responsible + * for closing it after persisting the changes. + * @public + */ +@event("save") + +/** + * Fired when the Cancel button in the footer is clicked. + * The dialog does not close automatically — the application is responsible + * for closing it after discarding the changes. + * @public + */ +@event("cancel") + class UserSettingsDialog extends UI5Element { eventDetails!: { "selection-change": UserSettingsItemSelectEventDetail, "open": void, "before-close": UserSettingsBeforeCloseEventDetail, "close": void, + "save": void, + "cancel": void, }; /** * Defines, if the User Settings Dialog is opened. @@ -117,6 +140,20 @@ class UserSettingsDialog extends UI5Element { @property({ type: Boolean }) showSearchField = false; + /** + * Defines whether the dialog offers Save and Cancel actions in its footer. + * + * When true, the footer renders a Save (Emphasized) and a Cancel button + * instead of the default Close button. Save and Cancel each fire a + * corresponding event; the application is responsible for closing the + * dialog (typically after persisting or discarding the changes). + * + * @default false + * @public + */ + @property({ type: Boolean }) + saveMode = false; + /** * Defines the user settings items. * @@ -295,6 +332,12 @@ class UserSettingsDialog extends UI5Element { get closeButtonText() { return UserSettingsDialog.i18nBundle.getText(USER_SETTINGS_DIALOG_CLOSE_BUTTON_TEXT); } + get saveButtonText() { + return UserSettingsDialog.i18nBundle.getText(USER_SETTINGS_DIALOG_SAVE_BUTTON_TEXT); + } + get cancelButtonText() { + return UserSettingsDialog.i18nBundle.getText(USER_SETTINGS_DIALOG_CANCEL_BUTTON_TEXT); + } get noSearchResultsText() { return UserSettingsDialog.i18nBundle.getText(USER_SETTINGS_DIALOG_NO_SEARCH_RESULTS_TEXT); } @@ -315,6 +358,14 @@ class UserSettingsDialog extends UI5Element { } } + _handleSaveButtonClick() { + this.fireDecoratorEvent("save"); + } + + _handleCancelButtonClick() { + this.fireDecoratorEvent("cancel"); + } + _handleCollapseClick() { this._collapsed = false; } diff --git a/packages/fiori/src/UserSettingsDialogTemplate.tsx b/packages/fiori/src/UserSettingsDialogTemplate.tsx index a2dfa2124a2a2..279a1f92ea71e 100644 --- a/packages/fiori/src/UserSettingsDialogTemplate.tsx +++ b/packages/fiori/src/UserSettingsDialogTemplate.tsx @@ -53,7 +53,14 @@ export default function UserSettingsDialogTemplate(this: UserSettingsDialog) { - + {this.saveMode ? ( + <> + + + + ) : ( + + )} ); diff --git a/packages/fiori/src/i18n/messagebundle.properties b/packages/fiori/src/i18n/messagebundle.properties index 908a451d9edf4..2397251013b95 100644 --- a/packages/fiori/src/i18n/messagebundle.properties +++ b/packages/fiori/src/i18n/messagebundle.properties @@ -605,6 +605,12 @@ USER_SETTINGS_LIST_ARIA_ROLE_DESC=User settings Item #XTXT: User settings dialog close button USER_SETTINGS_DIALOG_CLOSE_BUTTON_TEXT=Close +#XTXT: User settings dialog save button +USER_SETTINGS_DIALOG_SAVE_BUTTON_TEXT=Save + +#XTXT: User settings dialog cancel button +USER_SETTINGS_DIALOG_CANCEL_BUTTON_TEXT=Cancel + #XTXT: User settings dialog not result text USER_SETTINGS_DIALOG_NO_SEARCH_RESULTS_TEXT=No search results diff --git a/packages/fiori/test/pages/UserSettingsDialog.html b/packages/fiori/test/pages/UserSettingsDialog.html index 828ab5be1944b..8a8f0a7ee375c 100644 --- a/packages/fiori/test/pages/UserSettingsDialog.html +++ b/packages/fiori/test/pages/UserSettingsDialog.html @@ -79,6 +79,7 @@
User settings +User settings (Save mode) @@ -507,6 +508,117 @@ + + + + + + + + + Reset your personalization settings for the launchpad (such as theme, language, user activities, and home page content). + + + + + + + +
+ + +
+ + + + + + + + + + + + +
+
+ + + +
+ Display Language: + + + + + + + + Region: + + + + + + Date Format: + + + + + + Time Format: + + + + +
+
+
+ + + + Reset Personalization content + + + Reset All Settings content + + +
+ + + + Do you want to save your changes and close the dialog? + + + + + + + + Changing the display language to [New Language] will update the language across the user interface. + + + + + + + + Text Direction \ No newline at end of file diff --git a/packages/website/docs/_components_pages/fiori/UserSettingsDialog/UserSettingsDialog.mdx b/packages/website/docs/_components_pages/fiori/UserSettingsDialog/UserSettingsDialog.mdx index 37a08073b6502..cbcc66d9b502d 100644 --- a/packages/website/docs/_components_pages/fiori/UserSettingsDialog/UserSettingsDialog.mdx +++ b/packages/website/docs/_components_pages/fiori/UserSettingsDialog/UserSettingsDialog.mdx @@ -3,10 +3,20 @@ slug: ../UserSettingsDialog --- import Basic from "../../../_samples/fiori/UserSettingsDialog/Basic/Basic.md"; +import SaveMode from "../../../_samples/fiori/UserSettingsDialog/SaveMode/SaveMode.md"; <%COMPONENT_OVERVIEW%> ## Basic Sample -<%COMPONENT_METADATA%> \ No newline at end of file +<%COMPONENT_METADATA%> + +## More Samples + +### Save Mode +By default the dialog shows a single Close button in its footer and follows an implicit-save flow — changes are applied as the user interacts with each view. + +Setting the saveMode property replaces the footer with Save (Emphasized) and Cancel buttons. Clicks fire the corresponding save and cancel events; the dialog does not close itself, so the application is responsible for persisting or discarding the changes and closing the dialog afterwards (typically after a successful backend call). + + diff --git a/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/SaveMode.md b/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/SaveMode.md new file mode 100644 index 0000000000000..92d575f55b63c --- /dev/null +++ b/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/SaveMode.md @@ -0,0 +1,6 @@ +import html from '!!raw-loader!./sample.html'; +import js from '!!raw-loader!./main.js'; +import css from '!!raw-loader!./main.css'; +import react from '!!raw-loader!./sample.tsx'; + + diff --git a/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/main.css b/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/main.css new file mode 100644 index 0000000000000..f66a7f73206fe --- /dev/null +++ b/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/main.css @@ -0,0 +1,73 @@ +.ua-name{ + display:inline; + margin:0.5rem +} +.container{ + display: flex; + flex-direction: column; + gap: 1rem; + margin: 3rem; +} + +.ua-info-item{ + display: grid; + grid-template-columns: 50px 1fr; + align-items: center; + gap: 16px; +} + +.ua-panel{ + border-top: 2px solid lightgrey; + margin: 1rem 0; +} + +.save-btn{ + position: absolute; + bottom: 1rem; +} + +.lr-item{ + display: grid; + grid-template-columns: 150px 1fr; + align-items: center; + gap: 16px; +} + +.lt-time-format{ + display: flex; + align-items: center; + margin: 0 1rem 0 1rem; +} + +.language-region-container{ + display: flex; + min-height: 2.5rem; + align-item:flex-start; + flex-direction: column; + gap: 0.563rem; +} + +.language-region-label{ + display: flex; + flex: 1 0 0; + width: 100%; +} + +.language-region-control{ + display: flex; + gap: 0.188rem; + width: 100%; +} + +.ui5-user-settings-appearance-view-additional-content-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0.5rem; + width: 100%; +} +.ui5-user-settings-appearance-view-additional-content-description { + display: block; + color: var(--sapContent_LabelColor); + font-size: var(--sapFontSmallSize); +} \ No newline at end of file diff --git a/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/main.js b/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/main.js new file mode 100644 index 0000000000000..0c8861036438e --- /dev/null +++ b/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/main.js @@ -0,0 +1,173 @@ +import "@ui5/webcomponents-fiori/dist/UserSettingsAccountView.js"; +import "@ui5/webcomponents-fiori/dist/UserSettingsAppearanceView.js"; +import "@ui5/webcomponents-fiori/dist/UserSettingsAppearanceViewItem.js"; +import "@ui5/webcomponents-fiori/dist/UserSettingsAppearanceViewGroup.js"; +import "@ui5/webcomponents-fiori/dist/UserSettingsView.js"; +import "@ui5/webcomponents-fiori/dist/UserSettingsItem.js"; +import "@ui5/webcomponents-fiori/dist/UserSettingsDialog.js"; +import { setTheme } from "@ui5/webcomponents-base/dist/config/Theme.js"; + +import "@ui5/webcomponents-fiori/dist/ShellBar.js"; +import "@ui5/webcomponents-fiori/dist/ShellBarBranding.js"; +import "@ui5/webcomponents-fiori/dist/UserMenu.js" +import "@ui5/webcomponents-fiori/dist/UserMenuItem.js"; +import "@ui5/webcomponents-fiori/dist/UserMenuAccount.js"; +import "@ui5/webcomponents/dist/Avatar.js"; +import "@ui5/webcomponents/dist/Label.js"; +import "@ui5/webcomponents/dist/Button.js"; +import "@ui5/webcomponents/dist/Panel.js"; +import "@ui5/webcomponents/dist/ComboBox.js"; +import "@ui5/webcomponents/dist/ComboBoxItem.js"; +import "@ui5/webcomponents/dist/Text.js"; +import "@ui5/webcomponents/dist/Switch.js"; +import "@ui5/webcomponents/dist/Toast.js"; + +import "@ui5/webcomponents-icons/dist/action-settings.js"; +import "@ui5/webcomponents-icons/dist/user-settings.js"; +import "@ui5/webcomponents-icons/dist/person-placeholder.js"; +import "@ui5/webcomponents-icons/dist/palette.js"; +import "@ui5/webcomponents-icons/dist/reset.js"; + +const shellbar = document.getElementById("shellbar"); +const menuShellBar = document.getElementById("userMenuShellBar"); +const settingsDialog = document.getElementById("settings"); +const settingsDialogItems = [...document.getElementsByTagName("ui5-user-settings-item")]; +const account = document.getElementById("account"); +const resetAllButton = document.getElementById("reset-all-button"); +// Theme change +const appearanceView = document.querySelector("ui5-user-settings-appearance-view"); +//Language and Region +const languageRegion = document.getElementById("language-region-container"); +const language = document.getElementById("language"); +const regionSettings = [...languageRegion.querySelectorAll(".language-region-control")]; +const additionalDialog = document.getElementById("additionalDialog"); +const dialogClosers = [...additionalDialog.querySelectorAll(".dialogCloser")]; + +const resetAll = document.getElementById("resetAll"); +const resetPersonalization = document.getElementById("resetPersonalization"); +const toastReset = document.getElementById("toastReset"); +const toastResetAll = document.getElementById("toastResetAll"); + +shellbar.addEventListener("ui5-profile-click", (event) => { + console.log(" menuShellBar ui5-profile-click") + + menuShellBar.opener = event.detail.targetRef; + if (menuShellBar.open) { + menuShellBar.open = false; + } else { + menuShellBar.open = true; + } +}); + +menuShellBar.addEventListener("item-click", function (event) { + console.log(" menuShellBar item-click") + const item = event.detail.item.getAttribute("data-id"); + + switch (item) { + case "setting": + settingsDialog.open = true; + } +}); + +account.addEventListener("edit-accounts-click", function () { + console.log("Avatar clicked"); +}); + +account.addEventListener("manage-account-click", function () { + console.log("Manage account clicked"); +}); + +resetAllButton.addEventListener("click", function () { + additionalDialog.open = true; +}); + +//Language and Region +language.addEventListener("selection-change", function (event) { + additionalDialog.open = true; +}); + +// Theme change +appearanceView.addEventListener("selection-change", (e) => { + const selectedItem = e.detail.item; + + if (selectedItem?.itemKey) { + setTheme(selectedItem.itemKey); + } +}); + +dialogClosers.forEach(btn => { + btn.addEventListener("click", () => { + additionalDialog.open = false; + }); +}); + +regionSettings.forEach((settingsItem) => { + settingsItem.addEventListener("selection-change", function (event) { + console.log(`Selection change: ${event?.detail.item?.text}`, event.detail); + }); +}); + +resetPersonalization.addEventListener("click", function () { + toastReset.open = true; +}); + +resetAll.addEventListener("click", function () { + toastResetAll.open = true; +}); + +settingsDialog.addEventListener("selection-change", function (event) { + console.log(`Selection change: ${event.detail.item.text}`, event.detail); + if(event.detail.item.text ==="Language and Region"){ + event.detail.item.loading=true; + event.detail.item.loadingReason="Language & Region loading data..."; + setTimeout(function(){ + event.detail.item.loading=false; + }, 500); + } +}); + +settingsDialogItems.forEach((settingsDialogItem) => { + settingsDialogItem.addEventListener("selection-change", function (event) { + console.log(`Selection change: ${event.detail.view.text}`, event.detail); + }); +}); + +settingsDialog.addEventListener("open", function (event) { + console.log("Settings dialog opened", event); +}); + +settingsDialog.addEventListener("before-close", function (event) { + console.log("Settings dialog before close", event.detail); + if (!confirm("Are you sure you want to close the dialog?")) { + event.preventDefault(); + } +}); + +settingsDialog.addEventListener("close", function (event) { + console.log("Settings dialog closed", event); +}); + +// Save-mode demo: Save opens a confirmation dialog; Yes closes the settings dialog, No returns to it. +// Cancel closes the settings dialog directly. In a real application the Save flow would trigger +// the backend persistence and close after success. +const confirmSaveDialog = document.getElementById("confirmSaveDialog"); +const confirmSaveYes = document.getElementById("confirmSaveYes"); +const confirmSaveNo = document.getElementById("confirmSaveNo"); + +settingsDialog.addEventListener("save", function () { + console.log("Save clicked"); + confirmSaveDialog.open = true; +}); + +settingsDialog.addEventListener("cancel", function () { + console.log("Cancel clicked — closing dialog"); + settingsDialog.open = false; +}); + +confirmSaveYes.addEventListener("click", function () { + confirmSaveDialog.open = false; + settingsDialog.open = false; +}); +confirmSaveNo.addEventListener("click", function () { + confirmSaveDialog.open = false; +}); diff --git a/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/sample.html b/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/sample.html new file mode 100644 index 0000000000000..ba65298c77a27 --- /dev/null +++ b/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/sample.html @@ -0,0 +1,242 @@ + + + + + + + Settings sample + + + + + + + + + + Corporate Portal + + + + + + + + + + + + + + + + + + Personalization
+ Reset All Personalization + + + Reset your personalization settings for the launchpad (such as theme, language, user activities, and home page content). + + + +
+
+ + + +
+ + +
+ + + + + + + + + + + + +
+
+ + + +
+ Display Language + + + + + + + + + + + + + + + Region + + + + + + + + + + + + + + Date Format + + + + + + + + + + + + Time Format + + + + + + + + Time Zone + + + + + + + + + + + + + + + + + + + + + + + + + + + Currency + + + + + + + + + + + + + + + + + + + + + + + Number Format + + + + + + + +
+
+
+ + + + + Reset Personalization content + Changes Reset. + + + Reset All Settings content + All changes Reset. + + +
+ + + Changing the display language to [New Language] will update the language across the user interface. + + + + + + + + + + Do you want to save your changes and close the dialog? + + + + + + + + + + + + diff --git a/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/sample.tsx b/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/sample.tsx new file mode 100644 index 0000000000000..5e3abb366410d --- /dev/null +++ b/packages/website/docs/_samples/fiori/UserSettingsDialog/SaveMode/sample.tsx @@ -0,0 +1,734 @@ +import createReactComponent from "@ui5/webcomponents-base/dist/createReactComponent.js"; +import { type UI5CustomEvent } from "@ui5/webcomponents-base"; +import { useRef, useCallback } from "react"; +import { setTheme } from "@ui5/webcomponents-base/dist/config/Theme.js"; +import ShellBarClass from "@ui5/webcomponents-fiori/dist/ShellBar.js"; +import ShellBarBrandingClass from "@ui5/webcomponents-fiori/dist/ShellBarBranding.js"; +import UserMenuClass from "@ui5/webcomponents-fiori/dist/UserMenu.js"; +import UserMenuAccountClass from "@ui5/webcomponents-fiori/dist/UserMenuAccount.js"; +import UserMenuItemClass from "@ui5/webcomponents-fiori/dist/UserMenuItem.js"; +import UserSettingsAccountViewClass from "@ui5/webcomponents-fiori/dist/UserSettingsAccountView.js"; +import UserSettingsAppearanceViewClass from "@ui5/webcomponents-fiori/dist/UserSettingsAppearanceView.js"; +import UserSettingsAppearanceViewGroupClass from "@ui5/webcomponents-fiori/dist/UserSettingsAppearanceViewGroup.js"; +import UserSettingsAppearanceViewItemClass from "@ui5/webcomponents-fiori/dist/UserSettingsAppearanceViewItem.js"; +import UserSettingsDialogClass from "@ui5/webcomponents-fiori/dist/UserSettingsDialog.js"; +import UserSettingsItemClass from "@ui5/webcomponents-fiori/dist/UserSettingsItem.js"; +import UserSettingsViewClass from "@ui5/webcomponents-fiori/dist/UserSettingsView.js"; +import AvatarClass from "@ui5/webcomponents/dist/Avatar.js"; +import ButtonClass from "@ui5/webcomponents/dist/Button.js"; +import ComboBoxClass from "@ui5/webcomponents/dist/ComboBox.js"; +import ComboBoxItemClass from "@ui5/webcomponents/dist/ComboBoxItem.js"; +import DialogClass from "@ui5/webcomponents/dist/Dialog.js"; +import LabelClass from "@ui5/webcomponents/dist/Label.js"; +import PanelClass from "@ui5/webcomponents/dist/Panel.js"; +import SwitchClass from "@ui5/webcomponents/dist/Switch.js"; +import TextClass from "@ui5/webcomponents/dist/Text.js"; +import ToastClass from "@ui5/webcomponents/dist/Toast.js"; +import ToolbarClass from "@ui5/webcomponents/dist/Toolbar.js"; +import ToolbarButtonClass from "@ui5/webcomponents/dist/ToolbarButton.js"; +import "@ui5/webcomponents-icons/dist/action-settings.js"; +import "@ui5/webcomponents-icons/dist/user-settings.js"; +import "@ui5/webcomponents-icons/dist/person-placeholder.js"; +import "@ui5/webcomponents-icons/dist/palette.js"; +import "@ui5/webcomponents-icons/dist/reset.js"; + +const ShellBar = createReactComponent(ShellBarClass); +const ShellBarBranding = createReactComponent(ShellBarBrandingClass); +const UserMenu = createReactComponent(UserMenuClass); +const UserMenuAccount = createReactComponent(UserMenuAccountClass); +const UserMenuItem = createReactComponent(UserMenuItemClass); +const UserSettingsAccountView = createReactComponent(UserSettingsAccountViewClass); +const UserSettingsAppearanceView = createReactComponent( + UserSettingsAppearanceViewClass, +); +const UserSettingsAppearanceViewGroup = createReactComponent( + UserSettingsAppearanceViewGroupClass, +); +const UserSettingsAppearanceViewItem = createReactComponent( + UserSettingsAppearanceViewItemClass, +); +const UserSettingsDialog = createReactComponent(UserSettingsDialogClass); +const UserSettingsItem = createReactComponent(UserSettingsItemClass); +const UserSettingsView = createReactComponent(UserSettingsViewClass); +const Avatar = createReactComponent(AvatarClass); +const Button = createReactComponent(ButtonClass); +const ComboBox = createReactComponent(ComboBoxClass); +const ComboBoxItem = createReactComponent(ComboBoxItemClass); +const Dialog = createReactComponent(DialogClass); +const Label = createReactComponent(LabelClass); +const Panel = createReactComponent(PanelClass); +const Switch = createReactComponent(SwitchClass); +const Text = createReactComponent(TextClass); +const Toast = createReactComponent(ToastClass); +const Toolbar = createReactComponent(ToolbarClass); +const ToolbarButton = createReactComponent(ToolbarButtonClass); + +function App() { + const additionalDialogRef = useRef(null); + const confirmSaveDialogRef = useRef(null); + const toastResetRef = useRef(null); + const toastResetAllRef = useRef(null); + const userMenuRef = useRef(null); + const settingsDialogRef = useRef(null); + + const handleShellbarUi5ProfileClick = useCallback( + (e: UI5CustomEvent) => { + const menu = userMenuRef.current; + if (menu) { + menu.opener = e.detail.targetRef; + menu.open = !menu.open; + } + }, + [], + ); + + const handleUserMenuShellBarItemClick = useCallback( + (e: UI5CustomEvent) => { + const item = e.detail.item.getAttribute("data-id"); + if (item === "setting" && settingsDialogRef.current) { + settingsDialogRef.current.open = true; + } + }, + [], + ); + + const handleAccountEditAccountsClick = useCallback(() => { + console.log("Avatar clicked"); + }, []); + + const handleAccountManageAccountClick = useCallback(() => { + console.log("Manage account clicked"); + }, []); + + const handleResetAllButtonClick = useCallback(() => { + if (additionalDialogRef.current) { + additionalDialogRef.current.open = true; + } + }, []); + + const handleLanguageSelectionChange = useCallback(() => { + if (additionalDialogRef.current) { + additionalDialogRef.current.open = true; + } + }, []); + + const handleAppearanceViewSelectionChange = useCallback( + ( + e: UI5CustomEvent, + ) => { + const selectedItem = e.detail.item; + if (selectedItem?.itemKey) { + setTheme(selectedItem.itemKey); + } + }, + [], + ); + + const handleDialogCloserClick = useCallback(() => { + if (additionalDialogRef.current) { + additionalDialogRef.current.open = false; + } + }, []); + + const handleResetPersonalizationClick = useCallback(() => { + if (toastResetRef.current) { + toastResetRef.current.open = true; + } + }, []); + + const handleResetAllClick = useCallback(() => { + if (toastResetAllRef.current) { + toastResetAllRef.current.open = true; + } + }, []); + + // Save-mode demo: Save opens a confirmation dialog; Yes closes the settings dialog, No returns to it. + // Cancel closes the settings dialog directly. In a real application the Save flow would trigger + // the backend persistence and close after success. + const handleSettingsSave = useCallback(() => { + if (confirmSaveDialogRef.current) { + confirmSaveDialogRef.current.open = true; + } + }, []); + + const handleSettingsCancel = useCallback(() => { + if (settingsDialogRef.current) { + settingsDialogRef.current.open = false; + } + }, []); + + const handleConfirmSaveYes = useCallback(() => { + if (confirmSaveDialogRef.current) { + confirmSaveDialogRef.current.open = false; + } + if (settingsDialogRef.current) { + settingsDialogRef.current.open = false; + } + }, []); + + const handleConfirmSaveNo = useCallback(() => { + if (confirmSaveDialogRef.current) { + confirmSaveDialogRef.current.open = false; + } + }, []); + + return ( + <> + + + + Corporate Portal + SAP Logo + + + Profile + + + + + + + + + + + + +
+ + + + Reset your personalization settings for the launchpad (such as + theme, language, user activities, and home page content). + + +
+
+ + + +
+
+ Optimize for Touch Input + +
+ +
+ + + + + + + + + + + + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + Changes Reset. + + + + + + All changes Reset. + + + +
+ + + Do you want to save your changes and close the dialog? + + + + + + + + + Changing the display language to [New Language] will update the + language across the user interface. + + + + + + + + ); +} + +export default App;