Windows

Workspaces

JavaScript

Enabling Workspaces

To be able to use the Workspaces API in your Glue42 enabled applications, you have to initialize the Glue42 JavaScript library by passing the GlueWorkspaces() factory function in the configuration object. When the Glue() factory function resolves, the Workspaces API will be accessible through the workspaces property of the returned object - e.g., glue.workspaces.

const config = {
    libraries: [GlueWorkspaces]
};

window.glue = await Glue(config);

// Now you can access the Workspaces API through `glue.workspaces`.

Frame

The Frame is the topmost level window which contains all Workspaces.

Frame Reference

There are several ways to get the Frame instance that you need.

Current Window Frame

You can get the Frame of the current window by using the getMyFrame() method:

// This method will return the Frame of the current window.
// If an error is thrown, the window is not part of a Workspace.
const frame = await glue.workspaces.getMyFrame().catch(console.error);

All Frames

You can get all Frame instances by using the getAllFrames() method:

// Getting all Frames.
const allFrames = await glue.workspaces.getAllFrames();

Specific Frame

You can get a specific Frame instance by using the getFrame() method:

// Getting a specific Frame.
const specificFrame = await glue.workspaces.getFrame(frame => frame.id === "frame-id");

Frame Bounds

Once you get a Frame instance, you can manipulate its bounds using the move() and resize() methods:

const myFrame = await glue.workspaces.getMyFrame();

// Moving a Frame.
await myFrame.move({ top: 100, left: 100 });

// Resizing a Frame.
await myFrame.resize({ width: 600, height: 600 });

Focusing a Frame

To bring a Frame on focus, use the focus() method:

const frame = await glue.workspaces.getFrame(frame => frame.id === "frame-id");

// Focusing a Frame.
frame.focus();

Closing a Frame

To close a Frame, use the close() method:

const frame = await glue.workspaces.getFrame(frame => frame.id === "frame-id");

// Closing a Frame.
frame.close();

Frame Workspaces

To get all Workspace objects in a Frame, use the workspaces() method:

const myFrame = await glue.workspaces.getMyFrame();

// Getting all Workspaces in a Frame.
const frameWorkspaces = await myFrame.workspaces();

Workspace

A Workspace contains one or more application windows arranged in columns, rows or groups.

A Group is a Workspace element that holds tabbed windows. If a window is placed directly in a Column or a Row, it will be static and without a tab - the user will not be able to move it or close it and manipulating it will be possible only through the API.

You can use the frame property of a Workspace to get a reference to the Frame containing it.

To get a collection of the immediate children of a Workspace, use its children property.

Workspace Reference

There are several methods available for getting a reference to a Workspace.

Current Window Workspace

To get the Workspace of the current window, use the getMyWorkspace() method:

// This method will return the Workspace of the current window.
// If an error is thrown, the window is not part of a Workspace.
const workspace = await glue.workspaces.getMyWorkspace().catch(console.error);

All Workspaces

To get all Workspaces, use the getAllWorkspaces() method:

// Getting all Workspaces.
const allWorkspaces = await glue.workspaces.getAllWorkspaces();

Specific Workspace

To get a specific Workspace, use the getWorkspace method:

// Getting a specific Workspace.
const specificWorkspace = await glue.workspaces.getWorkspace(workspace => workspace.id === "workspace-id");

Workspace State

The Workspaces are designed to be freely modified programmatically as well as by the end user via the UI. Keeping a correct reference to a modified Workspace instance object is important in order for your code to be able to update the Workspace accordingly. For example, the user may have already closed a Workspace element that you want to update. To avoid such errors, you can either get a new reference to that element using the API, or you can use the refreshReference() method of a Workspace instance:

// Updating the reference to an already existing Workspace instance.
await myWorkspace.refreshReference();

// When this resolves, the `myWorkspace` object will be updated to reflect the current Workspace state.

Restoring Workspaces

You can restore a Workspace by using the restoreWorkspace() method which is available at top level of the API. It accepts an optional RestoreWorkspaceConfig object in which you can specify a title and a context for the restored Workspace, and also whether to restore it in a specific existing frame or in a new frame:

// Specify the Frame in which to restore the Workspace.
const restoreOptions = {
    frameId: "frame-id"
};

glue.workspaces.restoreWorkspace("myWorkspace", restoreOptions);

This method is also available on the frame instance:

const myFrame = await glue.workspaces.getMyFrame();

// You don't have to specify a Frame in which to restore the Workspace.
await myFrame.restoreWorkspace("myWorkspace");

Creating Workspaces

You can create Workspaces runtime by using the createWorkspace() method available at top level of the API and on a Frame instance. Using the createWorkspace() method, however, may often be quite inconvenient as every time you want to create a Workspace you will have to pass a JSON object describing a full Workspace Layout. This layout can quickly become very complex depending on the number and arrangement of applications participating in it. Below is an example of creating a Workspace by passing a WorkspaceDefinition with only two applications arranged in a single column:

// Workspace definition.
const definition = {
    // Define all Workspace elements (children).
    children: [
        {
            type: "column",
            children: [
                {
                    type: "window",
                    appName: "app-one"
                },
                {
                    type: "window",
                    appName: "app-two"
                }
            ]
        }
    ],
    // Confugartion for the Workspace.
    config: {
        title: "My Workspace"
    }
}

// Creating a Workspace.
const workspace = await glue.workspaces.createWorkspace(definition);

If you insert an empty Column, Row or Group element in a Workspace (without a window as its content), it will be visually represented in the Workspace as an empty space with a grey background and a button in the middle from which the user will be able to add an application. The user will not be able to move or close this empty element.

Workspaces Builder API

An easier solution is to use the Workspaces Builder API. The builder allows you to compose entire Workspaces as well as different Workspace elements (rows, column or groups) depending on the builder type you set.

You can define a builder with the getBuilder() method. It accepts a BuilderConfig object as a parameter in which you should specify the type of the builder (workspace, row, colum or group) and provide either a Workspace definition or a definition for the element (row, column or group) you want to build. You can then use the methods of the builder instance to add rows, columns, groups or windows.

Here is how you can create the same Workspace as above using a builder:

// Configuration for the builder.
const builderConfig = {
    // Type of the builder.
    type: "workspace",
    definition: {
        // This time pass only the the Workspace configuration without defining Workspace children.
        config: {
            title: "My Workspace"
        }
    }
}

// Access the Workspaces Builder API and define a builder.
const builder = glue.workspaces.getBuilder(builderConfig);

// Use the builder methods to add a column and two windows in it.
builder.addColumn()
    .addWindow({ appName: "app-one" })
    .addWindow({ appName: "app-two" });

// Finally, use the `create()` method of the builder instance to create the Workspace.
const workspace = await builder.create();

Finding Workspace Elements

The Workspaces API offers various methods for finding elements in a Workspace - Row, Column, Group and WorkspaceWindow. All methods for querying Workspaces accept a predicate function as a parameter which you can use to find the desired Workspace element(s).

Box Elements

Box elements are Workspace elements that can contain other Workspace elements - Row, Column and Group. These elements are the building blocks of a Workspace layout, while the actual windows (applications) can be viewed as their content.

To get all box elements in a Workspace, use the getAllBoxes() method of a Workspace instance:

const myWorkspace = await glue.workspaces.getMyWorkspace();

// This will return all `Row`, `Column` and `Group` elements in the Workspace.
const allBoxElements = myWorkspace.getAllBoxes();

The Workspace instance also offers methods for specific types of box elements. For example, to get all rows in a Workspace, use the getAllRows() method:

const myWorkspace = await glue.workspaces.getMyWorkspace();

const allRows = myWorkspace.getAllRows();

To get all columns or groups, use the getAllColumns() or getAllGroups() method respectively.

You can also get a specific box element using the getBox() method available on top level of the API as well as on a Workspace instance. Below is an example of getting the immediate parent element of a window using the window ID:

const myWorkspace = await glue.workspaces.getMyWorkspace();

// The `getBox()` method (as most methods for querying Workspaces)
// accepts a predicate function used to find the desired elements.
const targetElement = myWorkspace.getBox((boxElement) => {
    return boxElement.children.some(child => child.type === "window" && child.id === "target-id");
});

The Workspace instance also offers methods for finding specific rows, columns or groups - getRow(), getColumn() and getGroup().

Workspace Windows

To get all windows in a Workspace, use the getAllWindows() method of a Workspace instance:

const myWorkspace = await glue.workspaces.getMyWorkspace();

const allWorkspaceWindows = myWorkspace.getAllWindows();

To get a specific window, use the getWindow() method available on top level of the API as well as on a Workspace instance:

const specificWindow = await glue.workspaces.getWindow(window => window.id === "target-id");

Editing Workspaces

Workspace instances and Box element instances offer methods for adding and removing Workspace elements. This, combined with the powerful querying methods, gives you full programmatic control over a Workspaces.

Below is an example of adding a new window as a sibling to another window in a Workspace using the addWindow() method of a box element:

const myWorkspace = await glue.workspaces.getMyWorkspace();

const targetElement = myWorkspace.getBox((boxElement) => {
    return boxElement.children.some(child => child.type === "window" && child.id === "targetId");
});

await targetElement.addWindow({ appName: "app-three" });

Workspace Layouts

Workspace layouts are JSON objects that describe the content and arrangement of a Workspace. Workspace layouts can be saved (locally or remotely, depending on how your Glue42 Enterprise has been setup), deleted, exported and imported.

Workspace Layout Summaries

You can get the summaries of all Workspace layouts without the extensive JSON objects describing their structure. For example, you may need only the names of the available layouts to list them in the UI:

const layoutSummaries = await glue.workspaces.layouts.getSummaries();
const allLayoutNames = layoutSummaries.map(summary => summary.name);

Saving Workspace Layouts

You can save the layout of a Workspace after you create it by using the saveLayout() method of a Workspace instance:

// Saving the layout of a previously created Workspace instance.
await workspace.saveLayout("my-workspace");

You can also save the layout of any opened Workspace using the Workspaces Layouts API and the ID of the Workspace:

await glue.workspaces.layouts.save({ name: "workspace-two", workspaceId: "workspace-id" });

Deleting Workspace Layouts

Deleting a layout by name:

await glue.workspaces.layouts.delete("workspace-one");

Events

The Workspaces API exposes events at different levels allowing you to listen only for the events you are interested in.

Events are not yet supported in Glue42 Core.

Global Events

Global events are accessible at top level of the API. Below is an example for an event which will fire every time a window has been added to any Workspace in any Frame:

glue.workspaces.onWindowAdded((window) => {
    console.log(`Window added: ${window.id}`);
});

All event methods return an unsubscribe function which you can use to stop receiving notifications about the event:

const unsubscribe = await glue.workspaces.onWindowAdded((window) => {
    console.log(`Window added: ${window.id}`);
});

unsubscribe();

Frame Events

The Frame events provide notifications when a certain action has occurred within the Frame. Below is an example for an event which will fire every time a window has been added to the specified Frame instance:

const myFrame = await glue.workspaces.getMyFrame();

myFrame.onWindowAdded((window) => {
    console.log(`Window added to Frame: ${window.id}`);
});

Workspace Events

The Workspace events provide notifications when a certain action has occurred within the Workspace. Below is an example for an event which will fire every time a window has been added to the specified Workspace instance:

const workspace = await glue.workspaces.getMyWorkspace();

workspace.onWindowAdded((window) => {
    console.log(`Window added to Workspace: ${window.id}`);
});

Window Events

The window level events provide notifications when a certain action related to the window has occurred. Below is an example for an event which will fire when the window has been removed from the Workspace:

const workspaceWindow = await glue.workspaces.getWindow(window => window.id === "my-window-id");

workspaceWindow.onRemoved((window) => {
    console.log(`Window removed from Workspace: ${window.id}`);
});