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

Add support for duplicating a page #684

Merged
merged 1 commit into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions how-to/workspace-platform-starter/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Fixed an issue where the order of Workspace component entries within dock may change when toggling between light and dark theme.
- FDC3 2.0 Open improvement - You can now specify instance id if you wish to open an existing instance of an app and optionally pass it context.
- Add option to allow specific modules to get unrestricted notificationClients if they want to implement custom platform logic without importing notifications directly via the npm package. The notification client options in the notification provider now has a 'restricted' setting which can be set to false.
- Update Save Page As and Duplicate Page logic using the copyPage platform override introduced in 16.1. When a page is duplicated we generated a copy of the page but generate the instance id associated with a view's name while retaining the app Id (previously you would get a new randomly generated name for the app). If your app is a singleton then the name remains unique. So you will have two pages referencing the same instance. When you switch between them it will be displaying the same instance. However, please note if you move a page to a new window then the single instance view will move with it and leave the other page's layout (a single instance can only exist on one window if you need multiple instances then instanceMode should not be set to single). Duplicate view (view context menu) currently generates a new unlinked id for a view so if you do not want this behavior you can remove Duplicate View from the View Context Menu. Feedback on this behavior is of interest.

## v16.1.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import {
type Workspace,
type WorkspacePlatformProvider,
type HandleSaveModalOnPageClosePayload,
type SaveModalOnPageCloseResult
type SaveModalOnPageCloseResult,
type CopyPagePayload
} from "@openfin/workspace-platform";
import type { DockProviderConfigWithIdentity } from "@openfin/workspace-platform/client-api/src";
import type { PopupMenuStyles } from "workspace-platform-starter/shapes/menu-shapes";
Expand Down Expand Up @@ -61,7 +62,7 @@ import type { VersionInfo } from "../shapes/version-shapes";
import * as snapProvider from "../snap";
import { applyClientSnapshot, decorateSnapshot } from "../snapshot-source";
import { setCurrentColorSchemeMode } from "../themes";
import { deepMerge, isEmpty } from "../utils";
import { deepMerge, isEmpty, isStringValue, randomUUID } from "../utils";
import { loadConfig, saveConfig } from "../workspace/dock";
import { getPageBounds } from "./browser";
import { closedown as closedownPlatform } from "./platform";
Expand Down Expand Up @@ -890,6 +891,27 @@ export function overrideCallback(
logger.warn("Unsaved page prompt strategy is not valid. Using default.");
return super.handleSaveModalOnPageClose(payload);
}

/**
* Copies a page, respecting conventions for page and panel names.
* @param payload The payload for the copy page request.
* @returns The copied page.
*/
public async copyPage(payload: CopyPagePayload): Promise<Page> {
const panels = isEmpty(payload?.page?.panels)
? payload?.page?.panels
: duplicateLayout(payload.page.panels);

const layout = duplicateLayout(payload.page.layout);

return {
...payload.page,
panels,
layout,
pageId: randomUUID(),
isReadOnly: false
};
}
}
return new Override();
}
Expand Down Expand Up @@ -920,3 +942,28 @@ async function buildDefaultOptions(browserProvider?: BrowserProviderOptions): Pr
view: deepMerge({}, manifest.platform?.defaultViewOptions, browserProvider?.defaultViewOptions)
};
}

/**
* Takes a layout and walks through all the nodes and applies logic to nodes that have
* a url and a name that matches a pattern. Updates the name to make it unique (if applicable)
* while retaining information related to an application's identity if present.
* @param layout The layout to duplicate
* @returns The duplicated layout.
*/
function duplicateLayout<T>(layout: T): T {
return JSON.parse(
JSON.stringify(layout, (_, nestedValue) => {
// check to ensure that we have a name field and that we also have a url field in this object (in case name was added to a random part of the layout)
if (isStringValue(nestedValue?.name) && !isEmpty(nestedValue.url)) {
if (/\/[\d,a-z-]{36}$/.test(nestedValue.name)) {
nestedValue.name = nestedValue.name.replace(/([\d,a-z-]{36}$)/, randomUUID());
}
// case: internal-generated-view-<uuid>
if (/-[\d,a-z-]{36}$/.test(nestedValue.name)) {
nestedValue.name = nestedValue.name.replace(/(-[\d,a-z-]{36}$)/, randomUUID());
}
}
return nestedValue as unknown;
})
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@
"position": "Top",
"height": "40px",
"viewOptions": {
"name": "manager-portal-header-panel",
"url": "http://localhost:8080/common/panels/header-panel.html",
"preloadScripts": [
{
Expand All @@ -200,7 +199,6 @@
"width": "40px",
"extendToTop": true,
"viewOptions": {
"name": "manager-portal-nav-panel",
"url": "http://localhost:8080/common/panels/nav-panel.html",
"preloadScripts": [
{
Expand All @@ -213,7 +211,6 @@
"position": "Bottom",
"height": "40px",
"viewOptions": {
"name": "manager-portal-footer-panel",
"url": "http://localhost:8080/common/panels/footer-panel.html",
"preloadScripts": [
{
Expand Down
Loading