Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WS10 Add support for new themes format #273

Merged
merged 21 commits into from Dec 8, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions how-to/common/public/icons/light/page.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions how-to/common/public/icons/light/workspaces.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 0 additions & 4 deletions how-to/common/public/icons/pin-solid.svg

This file was deleted.

5 changes: 1 addition & 4 deletions how-to/customize-home-templates/client/src/themes.ts
@@ -1,7 +1,4 @@
import type {
CustomPaletteSet,
CustomThemeOptions
} from "@openfin/workspace-platform/common/src/api/theming";
import type { CustomPaletteSet, CustomThemeOptions } from "@openfin/workspace/common/src/api/theming";
import { getSettings } from "./settings";

const DEFAULT_PALETTES = {
Expand Down
7 changes: 7 additions & 0 deletions how-to/customize-workspace/CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog

## v10

- Added support for new themes format with light and dark schemes
- Added example of using setSearchQuery API for home integration
- Use Notifications now uses Show/Hide APIs instead of toggle
- Shim randomUUID so that it can be used in non secure contexts

## v9.2

- Added `dev` npm script which live build and reloads code for customize-workspace sample
Expand Down
88 changes: 63 additions & 25 deletions how-to/customize-workspace/client/src/framework/buttons.ts
@@ -1,39 +1,26 @@
import {
BrowserButtonType,
BrowserCreateWindowRequest,
BrowserWindowModule,
CustomBrowserButtonConfig,
getCurrentSync,
ToolbarButton
} from "@openfin/workspace-platform";
import { checkConditions } from "./conditions";
import { getSettings } from "./settings";
import type { ToolbarButtonDefinition } from "./shapes/browser-shapes";
import { getCurrentTheme } from "./themes";
import { getCurrentColorSchemeMode } from "./themes";

let allToolbarButtons: ToolbarButtonDefinition[];
let configToolbarButtons: ToolbarButtonDefinition[];
let defaultToolbarButtons: ToolbarButton[];

async function getAvailableToolbarButtons(): Promise<ToolbarButtonDefinition[]> {
if (Array.isArray(allToolbarButtons)) {
return allToolbarButtons;
async function getConfigToolbarButtons(): Promise<ToolbarButtonDefinition[]> {
if (Array.isArray(configToolbarButtons)) {
return configToolbarButtons;
}
const settings = await getSettings();
const theme = await getCurrentTheme();
const availableToolbarButtons = settings?.browserProvider?.toolbarButtons || [];
const validatedToolbarButtons: ToolbarButtonDefinition[] = [];

for (const entry of availableToolbarButtons) {
if (
entry.button.iconUrl !== undefined &&
theme?.label !== undefined &&
entry.themes !== undefined &&
entry.themes[theme.label] !== undefined
) {
entry.button.iconUrl = entry.themes[theme.label];
}
validatedToolbarButtons.push(entry);
}
allToolbarButtons = validatedToolbarButtons;
return validatedToolbarButtons;
configToolbarButtons = settings?.browserProvider?.toolbarButtons || [];
return configToolbarButtons;
}

export async function getDefaultToolbarButtons(): Promise<ToolbarButton[]> {
Expand All @@ -42,12 +29,22 @@ export async function getDefaultToolbarButtons(): Promise<ToolbarButton[]> {
}

const defaultButtons: ToolbarButton[] = [];
const availableToolbarButtons = await getAvailableToolbarButtons();
const availableToolbarButtons = await getConfigToolbarButtons();
const platform = getCurrentSync();

const colorSchemeMode = await getCurrentColorSchemeMode();

for (const entry of availableToolbarButtons) {
if (entry.include && (await checkConditions(platform, entry.conditions))) {
defaultButtons.push(entry.button);
// We need to duplicate the button, as we don't want to lose
// any placeholders in the iconUrl
const buttonCopy = JSON.parse(JSON.stringify(entry.button)) as ToolbarButton & { iconUrl?: string };

if (buttonCopy.iconUrl) {
buttonCopy.iconUrl = buttonCopy.iconUrl.replace(/{theme}/g, colorSchemeMode);
}

defaultButtons.push(buttonCopy);
}
}
defaultToolbarButtons = defaultButtons;
Expand All @@ -70,7 +67,7 @@ export async function updateToolbarButtons(
});

if (index !== -1) {
const availableToolbarButtons = await getAvailableToolbarButtons();
const availableToolbarButtons = await getConfigToolbarButtons();
const replacement = availableToolbarButtons.find((entry) => {
if (entry.button.type === BrowserButtonType.Custom) {
const customButton = entry.button as CustomBrowserButtonConfig;
Expand All @@ -84,3 +81,44 @@ export async function updateToolbarButtons(

return buttons;
}

export async function updateButtonColorScheme(): Promise<void> {
const platform = getCurrentSync();

const browserWindows = await platform.Browser.getAllWindows();

for (const browserWindow of browserWindows) {
await updateBrowserWindowButtonsColorScheme(browserWindow);
}
}

export async function updateBrowserWindowButtonsColorScheme(
browserWindow: BrowserWindowModule
): Promise<void> {
const options = await browserWindow.openfinWindow.getOptions();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like it should be part of the button definition with v10 sdk. i.e. provide two sets of icons and the workspace code does this work. We can catch up tomorrow on whether we should propose it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the syntax in the definition, you dont need to declare a separate themes section, just use {theme} in the path

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does that break backwards compatibility? Do we need to make a note of that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add to changelog

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm this might break sales studio as well so we might need v10 logic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see anything themed icon paths in Sales Studio

const currentToolbarOptions = (options as BrowserCreateWindowRequest).workspacePlatform.toolbarOptions;

if (Array.isArray(currentToolbarOptions.buttons)) {
const updatedButtons = [];
const colorSchemeMode = await getCurrentColorSchemeMode();

for (const button of currentToolbarOptions.buttons) {
if (button.type === BrowserButtonType.Custom) {
const buttonId = (button as CustomBrowserButtonConfig).action?.id;
if (buttonId) {
// Find the original button from config so that we can use the original
// iconUrl with any schema placeholders
const configButton = configToolbarButtons.find(
(b) => (b.button as CustomBrowserButtonConfig).action?.id === buttonId
);
if (configButton?.button.iconUrl) {
button.iconUrl = configButton.button.iconUrl.replace(/{theme}/g, colorSchemeMode);
}
}
}
updatedButtons.push(button);
}

await browserWindow.replaceToolbarOptions({ buttons: updatedButtons });
}
}
11 changes: 6 additions & 5 deletions how-to/customize-workspace/client/src/framework/modules.ts
Expand Up @@ -2,15 +2,15 @@ import { createLogger } from "./logger-provider";
import type { CustomSettings } from "./shapes";
import type {
Module,
ModuleDefinition,
ModuleEntry,
ModuleEntryTypes,
ModuleDefinition,
ModuleHelpers,
ModuleImplementation,
ModuleList,
ModuleTypes,
ModuleHelpers
ModuleTypes
} from "./shapes/module-shapes";
import { getCurrentTheme, getDefaultPalettes } from "./themes";
import { getCurrentColorSchemeMode, getCurrentPalette, getDefaultPalettes } from "./themes";

const logger = createLogger("Modules");

Expand Down Expand Up @@ -199,6 +199,7 @@ export function getDefaultHelpers(settings: CustomSettings): ModuleHelpers {
return {
rootUrl: settings?.platformProvider?.rootUrl,
getDefaultPalettes,
getCurrentTheme
getCurrentPalette,
getCurrentColorSchemeMode
};
}
@@ -1,4 +1,5 @@
import {
ColorSchemeOptionType,
CreateSavedPageRequest,
CreateSavedWorkspaceRequest,
getCurrentSync,
Expand All @@ -11,11 +12,14 @@ import {
Workspace,
WorkspacePlatformOverrideCallback
} from "@openfin/workspace-platform";
import { updateBrowserWindowButtonsColorScheme, updateButtonColorScheme } from "../buttons";
import * as endpointProvider from "../endpoint";
import { fireLifecycleEvent } from "../lifecycle";
import { createLogger } from "../logger-provider";
import { getGlobalMenu, getPageMenu, getViewMenu } from "../menu";
import { applyClientSnapshot, decorateSnapshot } from "../snapshot-source";
import { setCurrentColorSchemeMode } from "../themes";
import { updateDockColorScheme } from "../workspace/dock";
import { deletePageBounds, savePageBounds } from "./browser";
import { closedown as closedownPlatform } from "./platform";

Expand Down Expand Up @@ -292,6 +296,36 @@ export const overrideCallback: WorkspacePlatformOverrideCallback = async (Worksp
return super.quit(payload, callerIdentity);
}
}

public async createWindow(
options: OpenFin.PlatformWindowCreationOptions,
identity?: OpenFin.Identity
): Promise<OpenFin.Window> {
const window = await super.createWindow(options, identity);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this get triggered by classic windows?


try {
const platform = getCurrentSync();
const browserWindow = platform.Browser.wrapSync(window.identity);
await updateBrowserWindowButtonsColorScheme(browserWindow);
} catch {
// Probably not a browser window
}

return window;
}

public async setSelectedScheme(schemeType: ColorSchemeOptionType) {
// The color scheme has been updated, so update the theme
await setCurrentColorSchemeMode(schemeType);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than adding more and more logic here over time...could we not update the theme.ts via setCurrentColorScheme and that triggers a lifecycle event of theme changed? That way dock, and browser could register an action against that lifecycle event and if a platform dev wanted to hook into they could define a module and register it against the event as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we could certainly do it that way as well

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that way if we have a custom button it just cares about telling theme.ts to switch and the lifecycle event will trigger everything else (rather than all the logic being in the override).


// Also update toolbar buttons
await updateButtonColorScheme();

// And relaunch the dock as we currently can't dynamically update buttons
await updateDockColorScheme();

return super.setSelectedScheme(schemeType);
}
}
return new Override();
};
Expand Up @@ -7,6 +7,7 @@ import { getActions } from "../actions";
import * as appProvider from "../apps";
import * as authProvider from "../auth";
import { isAuthenticationEnabled } from "../auth";
import { updateButtonColorScheme } from "../buttons";
import * as conditionsProvider from "../conditions";
import * as connectionProvider from "../connections";
import * as endpointProvider from "../endpoint";
Expand Down Expand Up @@ -98,6 +99,8 @@ async function setupPlatform() {
overrideCallback
});

await updateButtonColorScheme();

platformInitialized = true;
}

Expand Down
Expand Up @@ -8,7 +8,6 @@ import type {
export interface ToolbarButtonDefinition {
id: string;
include: boolean;
themes?: { [key: string]: string };
button: ToolbarButton & { iconUrl?: string };
conditions?: string[];
}
Expand Down
@@ -1,8 +1,6 @@
import type {
CustomPaletteSet,
CustomThemeOptions
} from "@openfin/workspace-platform/common/src/api/theming";
import type { CustomPaletteSet } from "@openfin/workspace/common/src/api/theming";
import type { LoggerCreator } from "./logger-shapes";
import type { ColorSchemeMode } from "./theme-shapes";

/**
* List of modules.
Expand Down Expand Up @@ -74,9 +72,14 @@ export interface ModuleHelpers {
getDefaultPalettes(): Promise<{ [id: string]: CustomPaletteSet }>;

/**
* Get the current theme.
* Get the current palette.
*/
getCurrentTheme(): Promise<CustomThemeOptions>;
getCurrentPalette(): Promise<CustomPaletteSet>;

/**
* Get the current color scheme.
*/
getCurrentColorSchemeMode(): Promise<ColorSchemeMode>;
}

/**
Expand Down
Expand Up @@ -3,3 +3,8 @@ import type { CustomThemeOptions } from "@openfin/workspace/common/src/api/themi
export interface ThemeProviderOptions {
themes: CustomThemeOptions[];
}

export enum ColorSchemeMode {
Light = "light",
Dark = "dark"
}