UNPKG

@onlyoffice/docspace-plugin-sdk

Version:

Simple plugin system for onlyoffice docspace

289 lines (288 loc) 9.96 kB
/** * (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 { IMessage, TReturnMessage } from "../utils"; /** * @example * * Demonstrates a floating operations in button with simulated upload progress, * allowing users to cancel the process or remove individual operations while * preventing a new upload until the current one finishes. * * ```typescript * import { * IFloatingOperationsButton, * FloatingOperationType, * Actions, * IContextMenuItem, * FilesType, * } from "@onlyoffice/docspace-plugin-sdk"; * * const operations = [ * { * id: "upload-document", * label: "Uploading document.pdf", * operation: FloatingOperationType.Upload, * alert: false, * completed: false, * percent: 0, * // custom icon from assets * icon: "upload.svg", * }, * { * id: "convert-image", * label: "Converting image.jpg", * operation: FloatingOperationType.Convert, * alert: false, * completed: false, * percent: 0, * } * ] * * // flag to check if upload is in progress * let isUpload = false; * let intervalId: NodeJS.Timeout | null = null; * * export const uploadButton: IFloatingOperationsButton = { * id: "upload-button", * operationsCompleted: false, * operationsAlert: false, * // show cancel button when there is only one operation left * showCancelButton: true, * * cancelOperation: () => { * // reset interval and flags * intervalId && clearInterval(intervalId); * isUpload = false; * intervalId = null; * // send message to remove floating operations from button * return { * actions: [Actions.removeFloatingOperationsButton], * floatingOperationsButtonPropsId: uploadButton.id, * }; * }, * * onCancelOperationFromList: (id) => { * // remove operation from list * const filteredOps = uploadButton.operations?.filter( * (op) => op.id !== id * ) ?? []; * * // update operations * uploadButton.operations = filteredOps; * * // send message to update floating operations button * return { * actions: [Actions.updateFloatingOperationsButton], * floatingOperationsButtonProps: uploadButton, * }; * }, * * // event on add floating operations in button * onLoad: (dispatchMessage) => { * let progress = 0; * isUpload = true; * * // update progress every 400ms * intervalId = setInterval(() => { * progress += 5; * * // update progress for each operation * const operations = uploadButton.operations?.map((op) => ({ * ...op, * percent: progress, * completed: progress >= 100, * })) ?? []; * * uploadButton.operations = operations; * * // update operations completed * uploadButton.operationsCompleted = progress >= 100; * * // send message to update floating operations button * dispatchMessage({ * actions: [Actions.updateFloatingOperationsButton], * floatingOperationsButtonProps: uploadButton, * }); * * // stop interval if progress is 100 * if (progress >= 100) { * // reset interval and flags * intervalId && clearInterval(intervalId); * isUpload = false; * intervalId = null; * } * }, 400); * }, * }; * * export const uploadMenuItem: IContextMenuItem = { * key: "upload-files", * label: "Upload with progress", * icon: "upload.svg", * fileType: [FilesType.file], * onClick: () => { * // if upload is in progress, do not allow to start new upload * if (isUpload) { * return; * } * * // Reset operations from previous upload * uploadButton.operations = structuredClone(operations); * uploadButton.operationsCompleted = false; * uploadButton.operationsAlert = false; * * // send message to add floating operations in button * return { * actions: [Actions.addFloatingOperationsButton], * floatingOperationsButtonProps: uploadButton, * }; * }, * }; * ``` */ /** * Determines the icon and visual representation of the operation. */ export declare enum FloatingOperationType { /** File download operation */ Download = "download", /** File conversion operation */ Convert = "convert", /** File copy operation */ Copy = "copy", /** File duplication operation */ Duplicate = "duplicate", /** Mark as read operation */ MarkAsRead = "markAsRead", /** Permanent deletion operation */ DeletePermanently = "deletePermanently", /** Export index operation */ ExportIndex = "exportIndex", /** File move operation */ Move = "move", /** Move to trash operation */ Trash = "trash", /** Other custom operation */ Other = "other", /** File upload operation */ Upload = "upload", /** Delete file version operation */ DeleteVersionFile = "deleteVersionFile", /** Backup operation */ Backup = "backup" } /** * Represents a single operation in the floating operations button. * Each operation displays as a row with icon, label, and progress indicator. */ export interface IFloatingOperation { /** * Unique identifier for the operation. */ id: string; /** * Text label displayed to the user describing the operation. * Example: "Uploading document.pdf" or "Converting 5 files" */ label: string; /** * Type of operation - determines the default icon and visual representation. * Use predefined types (Upload, Convert, etc.). */ operation: FloatingOperationType; /** * Error flag - if true, the operation is displayed with a warning/error state. * Shows red icon. */ alert: boolean; /** * Completion flag - if true, the operation is marked as completed. * Shows checkmark icon and allows user to dismiss the operation. */ completed: boolean; /** * Progress percentage of the operation (0-100). * If undefined, displays an infinite loader animation instead of percentage. */ percent?: number; /** * Custom icon for the operation (overrides default operation icon). * The icon image must be uploaded to the "assets" folder. * Only specify the filename here, e.g., "upload.svg" or "custom-icon.png". */ icon?: string; } /** * Configuration for the floating operations button. * Used to display progress of long-running operations (upload, conversion, backup, etc.) * The button appears as a floating action button in the bottom-right corner of DocSpace. * * **Multiple Plugins Support:** * Multiple plugins can show floating operations simultaneously. * When you call Actions.addFloatingOperationsButton, operations from all plugins are aggregated * and displayed together in a single FAB button. * * Use Actions.updateFloatingOperationsButton to update progress without replacing the entire configuration. */ export interface IFloatingOperationsButton { /** * Unique identifier for floating operations. * Used to track and update operations from the same plugin. * When Actions.addFloatingOperationsButton is called again with the same identifier, operations in the button will not be replaced as long as there are operations in the button. * Use Actions.updateFloatingOperationsButton to update the state. */ id: string; /** * Array of operations to display in the floating button. * Each operation shows as a row with icon, label, and progress indicator. Operations from multiple plugins are aggregated and displayed together. */ operations?: IFloatingOperation[]; /** * Flag indicating all operations are completed. * When true, the button shows a green checkmark and "completed" status. * User can then dismiss the button or review completed operations. */ operationsCompleted?: boolean; /** * Flag indicating at least one operation has an error. * When true, the button shows a red warning indicator. */ operationsAlert?: boolean; /** * Controls the visibility of the cancel button. * Cancel button is displayed only if the floating button contains only one operation from the plugin and this flag is set to true. */ showCancelButton?: boolean; /** * Callback executed when user clicks the cancel button in the floating button. * */ cancelOperation?: () => TReturnMessage; /** * Callback executed when user closes a specific operation from the operations list. * Receives the operation ID. * Typically returns Actions.updateFloatingOperationsButton with the updated operations list. */ onCancelOperationFromList?: (operationId: string) => TReturnMessage; /** * Lifecycle callback executed once when the floating operations button is first displayed. * Receives a dispatchMessage function to send updates back to DocSpace. * Use this to initialize progress tracking. */ onLoad?: (dispatchMessage: (message: IMessage) => void) => TReturnMessage; }