1 TypeScript definition of the GCMSUI interface
In editor and tagfill IFrames a global object for communicating with GCMS UI is available. It is available as window.GCMSUI and it’s definition is defined in the @gentics/cms-integration-api-models package.
If you cannot use the package for some reason, there’s a weakly typed interface below, which is however not recommended.
type ExposedPartialState = any;
type StateChangedHandler = any;
type Construct = any;
type GCMSRestClient = any;
type Image<T> = any;
type FileOrImage = any;
type Raw = any;
type Tag = any;
type TagType = any;
type Page<T> = any;
type Folder = any;
type TagEditorOptions = any;
type TagEditorResult = any;
type ImageEditorOptions = any;
type ItemInNode = any;
type TagInContainer = any;
type AllowedSelectionType = 'page' | 'folder' | 'form' | 'image' | 'file' | 'template' | 'contenttag' | 'templatetag';
type AllowedSelectionTypeMap = Record<AllowedSelectionType, any>;
type RepositoryBrowserOptions = any;
type DynamicFormModalConfiguration<T> = any;
type DynamicDropdownConfiguration<T> = any;
type DynamicDialogConfiguration<T> = any;
type OverlayElementControl<T> = any;
type AlohaComponent = any;
declare class ModalCloseError extends Error {}
interface GcmsUiBridge {
// Internal implementation
// --------------------------------------------
/**
* Internal function, do not use by yourself!
* Executes the pre-load script in the context of the IFrame.
* This method is called by the code inside the IFrame when the `DOMContentLoaded` event is fired.
*/
runPreLoadScript: () => void;
/**
* Internal function, do not use by yourself!
* Executes the post-load script in the context of the IFrame.
* This method is called by the code inside the IFrame when the `load` event is fired.
*/
runPostLoadScript: () => void;
// General purpose
// --------------------------------------------
/**
* The URL of the styles of the GCMS UI.
* @deprecated The styles should be placed in the respective projects and loaded
* from there instead from this url.
*/
gcmsUiStylesUrl: string;
/** An object containing useful information about the current state of the UI */
appState: ExposedPartialState;
/** Paths to various endpoints in use by the UI */
paths: {
apiBaseUrl: string;
alohapageUrl: string;
imagestoreUrl: string;
};
/** Registers a callback which is invoked whenever the contents of the appState change */
onStateChange: (handler: StateChangedHandler) => void;
/**
* Tells the editor whether the page content has been modified. When set to `true`, the
* "save" button will be enabled.
*/
setContentModified: (modified: boolean) => void;
/**
* Opens the debug-tool which allows the dumping of the current application state
* and other information to be able to debug errors.
* This should only be used in emergencies and only, if you know what you're doing.
*/
callDebugTool: () => void;
/**
* Returns a record of the Constructs which are available for the editor in this page.
* The key of the Record is {@link Construct.keyword}.
*/
getConstructs(): Promise<Record<string, Construct>>;
// REST API
// --------------------------------------------
/**
* Client for interacting with all the GCMS APIs.
*/
restClient: GCMSRestClient;
// UI Actions
// --------------------------------------------
/**
* Opens the image editor for the specified image.
* @returns a promise, which will resolve to either the edited image
* (this may be a copy of the original image as well) or to void if the
* user canceled the edit or an error occurred.
* @deprecated Use `openImageEditor` instead.
*/
editImage: (nodeId: number, imageId: number) => Promise<Image<Raw> | void>;
/**
* Opens the image editor for the specified image.
* @returns a promise, which will resolve to either the edited image
* (this may be a copy of the original image as well) or to void if the
* user canceled the edit or an error occurred.
*/
openImageEditor: (options: ImageEditorOptions) => Promise<Image<Raw> | void>;
/**
* Opens the repository browser window.
* Returns Promise which resolves to `ItemInNode | TagInContainer` if `selectMultiple` is false and
* to `(ItemInNode | TagInContainer)[]` if `selectMultiple` is true.
* The Promise resolves to null if user clicks on cancel button.
*/
openRepositoryBrowser<T extends AllowedSelectionType, R = AllowedSelectionTypeMap[T]>(
options: RepositoryBrowserOptions & { allowedSelection: T; selectMultiple: false }
): Promise<R | null>;
openRepositoryBrowser<T extends AllowedSelectionType, R = AllowedSelectionTypeMap[T]>(
options: RepositoryBrowserOptions & { allowedSelection: T; selectMultiple: true }
): Promise<R[] | null>;
openRepositoryBrowser<R = ItemInNode | TagInContainer>(
options: RepositoryBrowserOptions & { allowedSelection: AllowedSelectionType[]; selectMultiple: false }
): Promise<R | null>;
openRepositoryBrowser<R = ItemInNode | TagInContainer>(
options: RepositoryBrowserOptions & { allowedSelection: AllowedSelectionType[]; selectMultiple: true }
): Promise<R[] | null>;
openRepositoryBrowser<R = ItemInNode | TagInContainer>(options: RepositoryBrowserOptions): Promise<R | R[] | null>;
/**
* Opens a tag editor for the specified tag.
* Based on the configuration of the TagType, either the GenticsTagEditor or
* a custom tag editor is used.
* @param tag The tag to be edited - the property tag.tagType must be set.
* @param context The current context.
* @returns A promise, which when the user clicks OK, resolves and returns a copy of the edited tag
* and when the user clicks Cancel, rejects.
*/
openTagEditor: (tag: Tag, tagType: TagType, page: Page<Raw>, options?: TagEditorOptions) => Promise<TagEditorResult>;
/**
* Opens an the upload modal to allow the user to upload files/images to a specified folder.
* @param uploadType The type the user should be allowed to upload. Either 'image' or 'file'.
* @param destinationFolder The folder to where the file/image should be uploaded to.
* @param allowFolderSelection If the user should be allowed to change the destination folder.
* @returns A Promise for the uploaded file/image.
*/
openUploadModal: (uploadType: 'image' | 'file', destinationFolder?: Folder, allowFolderSelection?: boolean) => Promise<FileOrImage>;
/**
* Opens a modal with a dynamic form configuration.
* @param configuration The configuration to create and handle the modal/form.
* @returns A Promise which resolves once the Modal has been successfully closed.
* A rejection (`ModalCloseError`) is being thrown when the user cancels the modal.
*/
openDynamicModal: <T>(configuration: DynamicFormModalConfiguration<T>) => Promise<OverlayElementControl<T>>;
/**
* Opens a dropdown with a dynamic component.
* @param configuration The configuration to create the dropdown.
* @param componentSlot The slot where the dropdown should be opened to.
* @returns A Promise which resolves once the Dropdown has been successfully closed.
* A rejection (`ModalCloseError`) is being thrown when the user cancels the modal.
*/
openDynamicDropdown: <T>(configuration: DynamicDropdownConfiguration<T>, componentSlot?: string) => Promise<OverlayElementControl<T>>;
/**
* Displays a Dialog to the user to interact with.
* @param configuration The configuration for the dialog.
* @returns A Promise which resolves/rejects once the User clicks one of the configured buttons.
*/
openDialog: <T>(configuration: DynamicDialogConfiguration<T>) => Promise<OverlayElementControl<T>>;
/**
* Attempts to focus the specified editor-tab. If it should not be found, it'll do nothing.
* @param tabId The id of the tab that should be focused.
*/
focusEditorTab: (tabId: string) => void;
/**
* Class of the error which is thrown when a overlay element has been closed.
*/
closeErrorClass: typeof ModalCloseError;
// Aloha Surface Integration
// --------------------------------------------
/**
* Registers/Binds a component to the specified slot.
* Will override any component previously bound to it.
* @param slot The slot where the component should be registered as
* @param component The component definition
*/
registerComponent: (slot: string, component: AlohaComponent) => void;
/**
* Unregisters a component from the given slot.
* @param slot The slot which has been registered
*/
unregisterComponent: (slot: string) => void;
}
We will now explain few functions better to understand how to use them.
2 Method to open the Repository Browser
GCMSUI.openRepositoryBrowser(options)
.then(page => useSelectedPage(page));
This method opens a repository browser window that allows selecting items / an item from multichannelling nodes and their subfolders. It can be used for single or multiple selection and limit the type of the allowed selection.
All possible options:
allowedSelection: ['file', 'image'], // valid options: 'page' | 'folder' | 'image' | 'file' | 'template' | 'contenttag' | 'templatetag' | 'form' multiple: true, // optional, default: false startNode: 7, // optional, default: current Node startFolder: 10, // optional, default current Folder onlyInCurrentNode: true, // optional, default false title: 'Select a file or image that should be linked in the article', // optional, default text will be displayed submitLabel: 'Add to article' // optional, default text will be displayed
The method returns a Promise, which resolves to the selected item if selectMultiple is false and to an array of selected items if selectMultiple is true. If user clicks on the cancel button, the promise neither resolves nor rejects.
3 Method to open the Image editor
GCMSUI.editImage(nodeId, imageId)
This method opens the image editor for the specified image.
The method returns a promise, which will resolve to either the edited image (this may be a copy of the original image as well) or to void if the user canceled the edit or an error occurred.
4 Method to open the Tag Editor
GCMSUI.openTagEditor(tag, tagType, page);
This method opens a tag editor for the specified tag. Based on the configuration of the TagType, either the GenticsTagEditor or a custom tag editor is used.
The method returns a promise, which when the user clicks OK, resolves and returns a copy of the edited tag and when the user clicks Cancel, rejects.