Settings
The SettingsManager allows the registration of SettingsTabsProvider classes to provide the settings to display with the SettingsContainer component. In an application that employs App UI, the SettingsModalFrontstage frontstage will display the SettingsContainer and its entries.
SettingsTabEntry
Registered SettingsTabsProvider instance will implement the method getSettingEntries
to return an array of SettingsTabsProvider items. Each SettingsTabEntry will populate a Tab entry in the SettingsContainer component. The tabId
property is a string and must be unique across all registered SettingsProviders. A common practice is to prefix the tabId with the package name to ensure uniqueness. The page
property holds the React.Element that will be used to construct the component to edit settings for this entry. It is the page's
responsibility to persist and retrieve persisted settings. If the page
contains multiple properties that must be saved together the SettingsTabEntry can set the pageWillHandleCloseRequest
property to true
. The page's
control should then register to be notified when the setting container is closing or when the active SettingsEnty is changing so that any unsaved data can be saved. Two React hooks are provided to assist: settingsManager.onProcessSettingsTabActivation
and settingsManager.onProcessSettingsContainerClose
.
Example
Example SettingsTabsProvider
Example below shows a settings provide that provides two settings pages. The first one depicts a page that has properties that cannot be saved immediately as individual properties are changed. It must be treated as a modal where once all values are define a save button is used the save the changes. The second settings page handles settings that can be immediately saved when changed and does not require any special processing when the page is closed.
// Sample UI items provider that dynamically adds ui items
export class ExampleSettingsProvider implements SettingsTabsProvider {
public readonly id = "myApp:ExampleSettingsProvider";
public getSettingEntries(stageId: string, stageUsage: string): ReadonlyArray<SettingsTabEntry> | undefined {
// It is possible to use arguments stageId and stageUsage to determine if a settings entry is to be provided for display. In this example
// we will just assume to always provide this SettingsTabEntry.
return [
{
itemPriority: 60,
tabId: "myApp:ExampleModalSettingsPage",
label:"Modal Feature",
page: <ExampleModalSettingsPage />,
icon: "icon-paintbrush",
tooltip: "My Example Modal Feature Settings",
pageWillHandleCloseRequest: true,
},
{
itemPriority: 70,
tabId: "myApp:ExampleSimpleSettingsPage",
label:"Simple Feature",
page: <ExampleSimpleSettingsPage />,
tooltip: "My Example Simple Feature Settings",
},
];
}
public static initializeAppSettingProvider() {
// Assuming running in App UI based application the SettingsManager instance is available via UiFramework.settingsManager
UiFramework.settingsManager.addSettingsProvider(new AppSettingsProvider());
}
}
Example Page Definition
Below is an example of a settings page component that has pageWillHandleCloseRequest
set to true so it can save its data before unmounting. When setting pageWillHandleCloseRequest
it is the page component's responsibility to call the afterSaveFunction
to allow the processing that prompted the settings to be saved to continue.
export function ExampleModalSettingsPage() {
const [mySettingsData, setMySettingsData] = React.useState(getInitialSettingsData());
const [saveEnabled, setSaveEnabled] = React.useState(false);
const persistMyChanges = React.useCallback((newSettings: any) => {
// do the work to persist here
console.log (`Data Persisted`);
}, []);
// callback passed to hooks to prompt user to save data before unmounting. This technique allows use to ignore the request sent to close the page.
const saveChanges = React.useCallback((afterSaveFunction: (args: any) => void, args?: any) => {
if (saveEnabled) {
ModalDialogManager.openDialog(<SaveFormatModalDialog persistChangesFunc={persistMyChanges} persistChangesFuncArg={mySettingsData}
onDialogCloseArgs={args} onDialogClose={afterSaveFunction} />);
return;
}
afterSaveFunction(args);
}, [saveEnabled, persistMyChanges, persistChangesFuncArg]);
// use provided hooks to allow saving before this page is unloaded
useSaveBeforeActivatingNewSettingsTab(UiFramework.settingsManager, saveChanges);
useSaveBeforeClosingSettingsContainer(UiFramework.settingsManager, saveChanges);
const handleSaveChange = React.useCallback((newSettings: any) => {
persistMyChanges(newSettings);
setSaveEnabled(false);
}, []);
const handleValueChange = React.useCallback((newSettings: any) => {
setMySettingsData(new);
setSaveEnabled(true);
}, []);
return (
<div>
<MyDataPanel onValueChange={handleValueChange} value={mySettingsData} />
<div className="components-button-panel">
<Button buttonType={ButtonType.Blue} onClick={handleSaveChange} disabled={!saveEnabled}>Save</Button>
</div>
</div>
);
}
function SaveFormatModalDialog({ persistChangesFunc, persistChangesFuncArg, onDialogCloseArgs, onDialogClose }:
{ persistChangesFunc, persistChangesFuncArg, onDialogCloseArgs?: any, onDialogClose: (args?: any) => void }) {
const [isOpen, setIsOpen] = React.useState(true);
const handleClose = React.useCallback(() => {
setIsOpen(false);
ModalDialogManager.closeDialog();
if (onDialogClose)
onDialogClose(onDialogCloseArgs);
}, [onDialogClose, onDialogCloseArgs]);
const handleOK = React.useCallback(() => {
persistChangesFunc(persistChangesFuncArg)
handleClose();
}, [handleClose, persistChangesFunc, persistChangesFuncArg]);
const handleCancel = React.useCallback(() => {
handleClose();
}, [handleClose]);
return (
<Dialog
title={"Save Changes"}
opened={isOpen}
resizable={false}
movable={false}
modal={true}
buttonCluster={[
{ type: DialogButtonType.Yes, onClick: handleOK },
{ type: DialogButtonType.No, onClick: handleCancel },
]}
onEscape={handleCancel}
onClose={handleCancel}
onOutsideClick={handleCancel}
minHeight={150}
maxHeight={400}
maxWidth={400}
minWidth={200}
>
<div className="modal-dialog2">
Do you want to save changes?
</div>
</Dialog >
);
}
API Reference
Last Updated: 02 February, 2022