From 920b73a8a3edbda89c6fe445bb79db7a70f805f4 Mon Sep 17 00:00:00 2001 From: bsteinbk <65047615+bsteinbk@users.noreply.github.com> Date: Wed, 9 Mar 2022 08:14:51 -0500 Subject: [PATCH 1/3] Allow initial UI version to be set when UIFramework is initialized --- common/api/appui-react.api.md | 4 +-- test-apps/ui-test-app/src/frontend/index.tsx | 29 +++++++++++-------- ui/appui-react/src/appui-react/UiFramework.ts | 11 +++++-- ui/appui-react/src/test/UiFramework.test.ts | 18 ++++++++++-- 4 files changed, 43 insertions(+), 19 deletions(-) diff --git a/common/api/appui-react.api.md b/common/api/appui-react.api.md index 5a60bb855538..ff59b9a8a629 100644 --- a/common/api/appui-react.api.md +++ b/common/api/appui-react.api.md @@ -6779,10 +6779,10 @@ export class UiFramework { static getWidgetOpacity(): number; // @alpha (undocumented) static get hideIsolateEmphasizeActionHandler(): HideIsolateEmphasizeActionHandler; - static initialize(store: Store | undefined, frameworkStateKey?: string): Promise; + static initialize(store: Store | undefined, frameworkStateKey?: string, startInUi1Mode?: boolean): Promise; static get initialized(): boolean; // @internal - static initializeEx(store: Store | undefined, frameworkStateKey?: string): Promise; + static initializeEx(store: Store | undefined, frameworkStateKey?: string, startInUi1Mode?: boolean): Promise; static initializeStateFromUserSettingsProviders(immediateSync?: boolean): Promise; // @alpha static get isContextMenuOpen(): boolean; diff --git a/test-apps/ui-test-app/src/frontend/index.tsx b/test-apps/ui-test-app/src/frontend/index.tsx index 133dfc352642..1660dc97a2fc 100644 --- a/test-apps/ui-test-app/src/frontend/index.tsx +++ b/test-apps/ui-test-app/src/frontend/index.tsx @@ -14,7 +14,7 @@ import { RealityDataAccessClient, RealityDataClientOptions } from "@itwin/realit import { getClassName } from "@itwin/appui-abstract"; import { SafeAreaInsets } from "@itwin/appui-layout-react"; import { - ActionsUnion, AppNotificationManager, AppUiSettings, ConfigurableUiContent, createAction, DeepReadonly, FrameworkAccuDraw, FrameworkReducer, + ActionsUnion, AppNotificationManager, AppUiSettings, ConfigurableUiActionId, ConfigurableUiContent, createAction, DeepReadonly, FrameworkAccuDraw, FrameworkReducer, FrameworkRootState, FrameworkToolAdmin, FrameworkUiAdmin, FrameworkVersion, FrontstageDeactivatedEventArgs, FrontstageDef, FrontstageManager, InitialAppUiSettings, ModalFrontstageClosedEventArgs, SafeAreaContext, StateManager, SyncUiEventDispatcher, SYSTEM_PREFERRED_COLOR_THEME, ThemeManager, @@ -85,6 +85,8 @@ export enum SampleAppUiActionId { setInitialViewIds = "sampleapp:setInitialViewIds", } +const useUi1Mode = false; + export interface SampleAppState { testProperty: string; animationViewId: string; @@ -260,7 +262,7 @@ export class SampleAppIModelApp { } public static async initialize() { - await UiFramework.initialize(undefined); + await UiFramework.initialize(undefined, undefined, useUi1Mode); // initialize Presentation await Presentation.initialize({ @@ -323,16 +325,19 @@ export class SampleAppIModelApp { // Create and register the AppUiSettings instance to provide default for ui settings in Redux store const lastTheme = (window.localStorage && window.localStorage.getItem("uifw:defaultTheme")) ?? SYSTEM_PREFERRED_COLOR_THEME; - const defaults: InitialAppUiSettings = { - colorTheme: lastTheme ?? SYSTEM_PREFERRED_COLOR_THEME, - dragInteraction: false, - frameworkVersion: "2", - widgetOpacity: 0.8, - showWidgetIcon: true, - }; - - // initialize any settings providers that may need to have defaults set by iModelApp - UiFramework.registerUserSettingsProvider(new AppUiSettings(defaults)); + if (!useUi1Mode) { + const defaults: InitialAppUiSettings = { + colorTheme: lastTheme ?? SYSTEM_PREFERRED_COLOR_THEME, + dragInteraction: false, + frameworkVersion: "2", + widgetOpacity: 0.8, + showWidgetIcon: true }; + + // initialize any settings providers that may need to have defaults set by iModelApp + UiFramework.registerUserSettingsProvider(new AppUiSettings(defaults)); + } else { + window.localStorage.removeItem("AppUiSettings.ShowWidgetIcon"); + } UiFramework.useDefaultPopoutUrl = true; diff --git a/ui/appui-react/src/appui-react/UiFramework.ts b/ui/appui-react/src/appui-react/UiFramework.ts index 86d81eb89c49..28265c5ce23a 100644 --- a/ui/appui-react/src/appui-react/UiFramework.ts +++ b/ui/appui-react/src/appui-react/UiFramework.ts @@ -132,19 +132,21 @@ export class UiFramework { * Called by the application to initialize the UiFramework. Also initializes UIIModelComponents, UiComponents, UiCore. * @param store The single Redux store created by the host application. If this is `undefined` then it is assumed that the [[StateManager]] is being used to provide the Redux store. * @param frameworkStateKey The name of the key used by the app when adding the UiFramework state into the Redux store. If not defined "frameworkState" is assumed. This value is ignored if [[StateManager]] is being used. The StateManager use "frameworkState". + * @param startInUi1Mode Used for legacy applications to start up in the deprecated UI 1 mode. This should not set by newer applications. */ - public static async initialize(store: Store | undefined, frameworkStateKey?: string): Promise { - return this.initializeEx(store, frameworkStateKey); + public static async initialize(store: Store | undefined, frameworkStateKey?: string, startInUi1Mode?: boolean): Promise { + return this.initializeEx(store, frameworkStateKey, startInUi1Mode); } /** * Called by the application to initialize the UiFramework. Also initializes UIIModelComponents, UiComponents, UiCore. * @param store The single Redux store created by the host application. If this is `undefined` then it is assumed that the [[StateManager]] is being used to provide the Redux store. * @param frameworkStateKey The name of the key used by the app when adding the UiFramework state into the Redux store. If not defined "frameworkState" is assumed. This value is ignored if [[StateManager]] is being used. The StateManager use "frameworkState". + * @param startInUi1Mode Used for legacy applications to start up in the deprecated UI 1 mode. This should not set by newer applications. * * @internal */ - public static async initializeEx(store: Store | undefined, frameworkStateKey?: string): Promise { + public static async initializeEx(store: Store | undefined, frameworkStateKey?: string, startInUi1Mode?: boolean): Promise { if (UiFramework._initialized) { Logger.logInfo(UiFramework.loggerCategory(UiFramework), `UiFramework.initialize already called`); return; @@ -160,6 +162,9 @@ export class UiFramework { if (frameworkStateKey && store) UiFramework._frameworkStateKeyInStore = frameworkStateKey; + if (startInUi1Mode) + UiFramework.store.dispatch({ type: ConfigurableUiActionId.SetFrameworkVersion, payload: "1" }); + // set up namespace and register all tools from package const frameworkNamespace = IModelApp.localization?.registerNamespace(UiFramework.localizationNamespace); [ diff --git a/ui/appui-react/src/test/UiFramework.test.ts b/ui/appui-react/src/test/UiFramework.test.ts index 620c7a39d620..365265b20986 100644 --- a/ui/appui-react/src/test/UiFramework.test.ts +++ b/ui/appui-react/src/test/UiFramework.test.ts @@ -35,13 +35,27 @@ describe("UiFramework localStorage Wrapper", () => { }); describe("UiFramework basic Initialization", () => { - it("should initialize default StateManager", async () => { + it("should initialize redux to UI 2", async () => { await UiFramework.initialize(undefined); - const uiVersion = "2"; + expect(UiFramework.uiVersion).to.eql("2"); + UiFramework.terminate(); + }); + + it("should allow initialize to UI 1", async () => { + await UiFramework.initialize(undefined, undefined, true); + expect(UiFramework.uiVersion).to.eql("1"); + UiFramework.terminate(); + }); + + it("should initialize default StateManager to 2 and change to 1", async () => { + await UiFramework.initialize(undefined); + expect(UiFramework.uiVersion).to.eql("2"); + const uiVersion = "1"; UiFramework.setUiVersion(uiVersion); expect(UiFramework.uiVersion).to.eql(uiVersion); UiFramework.terminate(); }); + }); describe("UiFramework", () => { From cd28c4afcba282d81b8c1ca7fa2629a783635d2c Mon Sep 17 00:00:00 2001 From: bsteinbk <65047615+bsteinbk@users.noreply.github.com> Date: Wed, 9 Mar 2022 08:22:40 -0500 Subject: [PATCH 2/3] Rush change and add note about testing 1.0 mode. --- .../@itwin/appui-react/master_2022-03-09-13-16.json | 10 ++++++++++ test-apps/ui-test-app/src/frontend/index.tsx | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 common/changes/@itwin/appui-react/master_2022-03-09-13-16.json diff --git a/common/changes/@itwin/appui-react/master_2022-03-09-13-16.json b/common/changes/@itwin/appui-react/master_2022-03-09-13-16.json new file mode 100644 index 000000000000..144ba5ccc80b --- /dev/null +++ b/common/changes/@itwin/appui-react/master_2022-03-09-13-16.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@itwin/appui-react", + "comment": "Allow initial UI version to be set when UIFramework is initialized.", + "type": "none" + } + ], + "packageName": "@itwin/appui-react" +} \ No newline at end of file diff --git a/test-apps/ui-test-app/src/frontend/index.tsx b/test-apps/ui-test-app/src/frontend/index.tsx index 1660dc97a2fc..e9881a4d7b0d 100644 --- a/test-apps/ui-test-app/src/frontend/index.tsx +++ b/test-apps/ui-test-app/src/frontend/index.tsx @@ -14,7 +14,7 @@ import { RealityDataAccessClient, RealityDataClientOptions } from "@itwin/realit import { getClassName } from "@itwin/appui-abstract"; import { SafeAreaInsets } from "@itwin/appui-layout-react"; import { - ActionsUnion, AppNotificationManager, AppUiSettings, ConfigurableUiActionId, ConfigurableUiContent, createAction, DeepReadonly, FrameworkAccuDraw, FrameworkReducer, + ActionsUnion, AppNotificationManager, AppUiSettings, ConfigurableUiContent, createAction, DeepReadonly, FrameworkAccuDraw, FrameworkReducer, FrameworkRootState, FrameworkToolAdmin, FrameworkUiAdmin, FrameworkVersion, FrontstageDeactivatedEventArgs, FrontstageDef, FrontstageManager, InitialAppUiSettings, ModalFrontstageClosedEventArgs, SafeAreaContext, StateManager, SyncUiEventDispatcher, SYSTEM_PREFERRED_COLOR_THEME, ThemeManager, @@ -85,6 +85,11 @@ export enum SampleAppUiActionId { setInitialViewIds = "sampleapp:setInitialViewIds", } +/* ---------------------------------------------------------------------------- +* The following variable is used to test initializing UiFramework to use UI 1.0 +* and using that initial value in ui-test-app. By default UiFramework initializes +* the Redux state to UI 2.0 mode. +----------------------------------------------------------------------------- */ const useUi1Mode = false; export interface SampleAppState { From 3ebe148caf04f3b217e81b9b23c2f83b5ebfe42f Mon Sep 17 00:00:00 2001 From: bsteinbk <65047615+bsteinbk@users.noreply.github.com> Date: Wed, 9 Mar 2022 08:32:22 -0500 Subject: [PATCH 3/3] fix typo in ui-test-app --- test-apps/ui-test-app/src/frontend/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-apps/ui-test-app/src/frontend/index.tsx b/test-apps/ui-test-app/src/frontend/index.tsx index e9881a4d7b0d..c8fc81139f86 100644 --- a/test-apps/ui-test-app/src/frontend/index.tsx +++ b/test-apps/ui-test-app/src/frontend/index.tsx @@ -341,7 +341,7 @@ export class SampleAppIModelApp { // initialize any settings providers that may need to have defaults set by iModelApp UiFramework.registerUserSettingsProvider(new AppUiSettings(defaults)); } else { - window.localStorage.removeItem("AppUiSettings.ShowWidgetIcon"); + window.localStorage.removeItem("AppUiSettings.FrameworkVersion"); } UiFramework.useDefaultPopoutUrl = true;