@onlyoffice/docspace-plugin-sdk
Version:
Simple plugin system for onlyoffice docspace
294 lines (293 loc) • 10.3 kB
TypeScript
/**
* (c) Copyright Ascensio System SIA 2026
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @license
*/
import { Devices, FilesExst, FilesType, FilesSecurity, Security, UsersType } from "../../enums";
import { IMessage } from "../utils";
/**
* Describes an item that will be embedded in the context menu.
*
* @category ContextMenuItem
*
* @example
*
* File analysis with progress reporting
*
* ```typescript
* const analyzeFile: IContextMenuItem = {
* key: "analyze-file",
* label: "Analyze File",
* icon: "analysis-icon.svg",
* onItemClick: async (fileId) => {
* try {
* const analysis = await analyzeFile(fileId);
* return {
* actions: [Actions.showToast],
* toastProps: [{
* type: "success",
* title: "File Analysis Complete",
* message: "Analysis completed successfully | Report generated | Ready to view"
* }]
* };
* } catch (error) {
* return {
* actions: [Actions.showToast],
* toastProps: [{
* type: "error",
* title: "Analysis Failed",
* message: "Unable to analyze file | Check file access"
* }]
* };
* }
* }
* };
* ```
*
* @example
*
* Secure file sharing with clipboard integration
*
* ```typescript
* const shareFile: IContextMenuItem = {
* key: "share-file",
* label: "Share File",
* icon: "share-icon.svg",
* onItemClick: async (fileId) => {
* try {
* const shareInfo = await generateShareLink(fileId);
* return {
* actions: [Actions.showToast],
* toastProps: [{
* type: "success",
* title: "Share Link Generated",
* message: "Link generated successfully | Ready to share | Copied to clipboard"
* }]
* };
* } catch (error) {
* return {
* actions: [Actions.showToast],
* toastProps: [{
* type: "error",
* title: "Share Failed",
* message: "Unable to generate share link | Check permissions"
* }]
* };
* }
* }
* };
*```
*
* @example
*
* Nested context menu items from previous examples
*
* ```typescript
* const manageFile: IContextMenuItem = {
* key: "manage-file",
* label: "Manage File",
* icon: "manage-file-icon.svg",
* items: [
* shareFile,
* analyzeFile
* ]
* };
* ```
*
* @example
*
* Group action for multiple selected items
*
* ```typescript
* const exportFiles: IContextMenuItem = {
* key: "export-files",
* label: "Export Selected",
* icon: "export-icon.svg",
* isGroupAction: true,
* fileType: [FilesType.file, FilesType.folder],
* onGroupClick: async (items) => {
* // The `items` array includes only selected files and folders.
* Rooms are not included, as their `fileType` value does not include `room`.
* const count = items.length;
*
* const filesIds = items
* .filter((item) => item.itemType === "file")
* .map((item) => item.id);
*
* const foldersIds = items
* .filter((item) => item.itemType === "folder")
* .map((item) => item.id);
*
*
* // Process selected items
* console.log(`Exporting ${count} items:`, items);
* console.log(`Files IDs:`, filesIds);
* console.log(`Folders IDs:`, foldersIds);
*
* return {
* actions: [Actions.showToast],
* toastProps: [{
* type: "success",
* title: "Export Started",
* message: `Exporting ${count} items...`
* }]
* };
* }
* };
* ```
*/
type GroupItem = {
/**
* The id of the selected entity (files/folders/rooms)
*/
id: number | string;
/**
* The type of selected entity.
* Can be used to recognize entities in a group of selected files/folders/rooms.
*/
itemType: "file" | "folder" | "room";
};
export interface IContextMenuItem {
/**
* The unique item identifier used by the service to recognize the item
*
*/
key: string;
/**
* The item display name
*
*/
label: string;
/**
* The item display icon. The icon image must be uploaded to the "assets" folder.
* Only the image name with the extension must be specified in this field. The required icon size is 16x16 px.
* Otherwise, it will be compressed to this size.
*
*/
icon: string;
/**
* Callback invoked when the action is triggered for a single selected
* file, folder, or room.
*
* @param id The identifier of the selected item (number only for backward compatibility).
*
* @remarks
* This callback is executed only for single selection.
* If `isGroupAction` is set to `true`, this callback will not be triggered.
*
* @deprecated Use `onItemClick` instead to support both string and number IDs.
* This method will be removed in a future major version.
*/
onClick?: (id: number) => Promise<IMessage> | Promise<void> | IMessage | void;
/**
* Callback invoked when the action is triggered for a single selected
* file, folder, or room. Supports both string and number identifiers.
*
* @param id The identifier of the selected item (string or number).
*
* @remarks
* This callback is executed only for single selection.
* If `isGroupAction` is set to `true`, this callback will not be triggered.
* This is the preferred method over the deprecated `onClick`.
*/
onItemClick?: (id: string | number) => Promise<IMessage> | Promise<void> | IMessage | void;
/**
* Callback invoked when the action is triggered for multiple selected
* files, folders, or rooms.
*
* @param items Receives the selected file, folder, or room items as an argument.
*
* @remarks
* To make the action appear in the group actions menu, set `isGroupAction` to `true`.
* When `isGroupAction` is `true`, the action will not be shown for single selected items.
*/
onGroupClick?: (items: GroupItem[]) => Promise<IMessage> | Promise<void> | IMessage | void;
/**
* Indicates whether this item should be displayed in the group actions
* context menu when multiple files, folders, or rooms are selected.
*
*/
isGroupAction?: boolean;
/**
* Whether to add the action state to the item in the file list when the onClick event is triggered
*
*/
withActiveItem?: boolean;
/**
* The extensions of files where the current item will be displayed in the context menu.
* It only works if the FilesType.Files is specified in the fileType parameter.
* If this parameter is not specified, then the current context menu item will be displayed in any file extension.
*
*/
fileExt?: (FilesExst | string)[];
/**
* The types of files where the current item will be displayed in the context menu.
* Presently the following file types are available: room, file, folder, image, video.
* If this parameter is not specified, then the current context menu item will be displayed in any file type.
*
*/
fileType?: FilesType[];
/**
* Specifies elements as submenus.
* If specified, onClick on the parent will not work.
* If none of the child elements are displayed, for example due to security or itemSecurity, the parent will also be hidden.
* Max level of the menu is 2.
*/
items?: Omit<IContextMenuItem, "items" | "placement">[];
/**
* The types of users who will see the current item in the context menu.
* Currently the following user types are available: owner, docSpaceAdmin, roomAdmin, collaborator, user.
* If this parameter is not specified, then the current context menu item will be displayed for all user types.
*
*/
usersTypes?: UsersType[];
/**
* The types of devices where the current item will be displayed in the context menu.
* At the moment the following device types are available: mobile, tablet, desktop.
* If this parameter is not specified, then the current context menu item will be displayed in any device types.
*
*/
devices?: Devices[];
/**
* The security parameters of the parent folder or room that will be checked.
* If all the parameters are true, the current item will be displayed in the context menu.
* If this parameter is undefined, it will be ignored.
*
*/
security?: Security[];
/**
* The security parameters of the file or folder or room that will be checked.
* If all the parameters are true, the current item will be displayed in the context menu.
* If this parameter is undefined, it will be ignored.
*
*/
itemSecurity?: (FilesSecurity | Security)[];
/**
* Defines where the item appears in the context menu (top block only).
* - `top` — inserted at the very beginning of the menu, before all other items in the top block.
* - `topLast` — inserted at the end of the top block, just before the first separator.
* - If not specified, the item is placed inside the "More Options" submenu (default behavior).
*
* Only applies to root-level items. Nested items (`items[]`) ignore this property.
*/
placement?: "top" | "topLast";
/**
* The identifiers of specific files, folders, or rooms where this item will be displayed in the context menu.
* If specified, the item is shown only for entities whose ID is included in this list.
* If this parameter is not specified, the item will be displayed for all entities (subject to other filters).
*/
itemId?: (number | string)[];
}
export {};