[]
        
(Showing Draft Content)

Presence

spread-sheets-collaboration, based on js-collaboration-presence, provides a Presence feature specifically designed for SpreadJS Sheets Collaborative editing scenarios. It supports real-time display of user presence states (e.g., cursor position, selection areas), helping users understand the activity status of other collaborators and improving collaboration efficiency. You can associate workbook and Presence using setPresences/getPresences or bindPresence.

Core Feature: Real-Time User State Sharing

Functionality Description

In the active worksheet, real-time rendering of selection areas or selected cells for all collaborating users working on the current active sheet.

  • Each user is assigned a unique color, with the username displayed in the top-right corner of the selection area.

  • User Color Sources (in order of priority, high to low):

    • Color specified in User info

    • Custom colorScheme

    • Default color scheme (['#0000ff', '#008000', '#9900cc', '#800000', '#00cc33', '#cc6600', '#cc0099'])

use-presence

Application Scenarios

  • During multi-user editing, users can clearly see the cells or areas others are working on to avoid conflicts.

  • Facilitates team coordination, such as real-time visibility of other collaborators’ editing positions in financial spreadsheets.

Interfaces

ISelections

The ISelections interface defines the structure of an object representing specific selection area information in workbook.

//* typedef GC.Spread.Sheets.Collaboration.ISelections
/**
 * @property {GC.Spread.Sheets.Range[]} [selections]
 * @property {string} [sheetId]
 */
export interface ISelections {
    selections?: GC.Spread.Sheets.Range[];
    sheetId?: string;
}

Property Descriptions

Property Name

Type

Description

selections (optional)

GC.Spread.Sheets.Range[]

All selection areas in SpreadSheets.

sheetId (optional)

string

The Sheet ID where the selection areas reside.

IStatus

The IStatus interface defines the structure of all status objects.

//* typedef GC.Spread.Sheets.Collaboration.IStatus
/**
 * @property {GC.Spread.Sheets.Collaboration.ISelections} [selections]
 */
export interface IStatus {
    selections?: GC.Spread.Sheets.Collaboration.ISelections;
}

Property Descriptions

Property Name

Type

Description

selections

GC.SpreadSheets.Collaboration.ISelections

All selection states.

IPresence

The IPresence interface defines the structure of a user presence state object in workbook.

//* typedef GC.Spread.Sheets.Collaboration.IPresence
/**
 * @property {GC.Spread.Sheets.Collaboration.IUser} [user]
 * @property {GC.Spread.Sheets.Collaboration.IStatus} [status]
 */
export interface IPresence {
    user: GC.Spread.Sheets.Collaboration.IUser;
    status: GC.Spread.Sheets.Collaboration.IStatus;
}

Property Descriptions

Property Name

Type

Description

user (optional)

GC.Spread.Sheets.Collaboration.IUser

User object information.

status (optional)

GC.Spread.Sheets.Collaboration.IStatus

Presence state information.

IBindPresenceOptions

The IBindPresenceOptions interface defines the configuration options for bindPresences.

export interface IBindPresenceOptions {
    onPresencesUpdate?: (presences?: IPresence[]) => void;
    colorScheme?: string[];
}

Property Descriptions

Property Name

Type

Description

onPresencesUpdate (optional)

(presences?: IPresence[]) => void

Callback method triggered after presence updates via bindPresences.

colorScheme (optional)

string[]

User-defined color scheme.

Methods

setPresences

The setPresences method updates user presence state information.

function setPresences(presences: GC.Spread.Sheets.Collaboration.IPresence[]): void

Parameter

  • presences (GC.Spread.Sheets.Collaboration.IPresence[]): The user presence states to be set.

Example

let presences = [{
	user: {
		id: '1',
		name: 'User1',
		color: '#FF0000',
		permission: {
			mode: GC.Spread.Sheets.Collaboration.BrowsingMode.edit,
		}
	},
	status: {
		selections: {
			selections: [new GC.Spread.Sheets.Range(0, 0, 1, 1)],
			sheetId: 'sheet1'
		}
	}
}];
spread.collaboration.setPresences(presences);

getPresences

The getPresences method get current presences

function getPresences(): GC.Spread.Sheets.Collaboration.IPresence[]

Return

  • presences(GC.Spread.Sheets.Collaboration.IPresence[]): the current presences

Example

const presences = spread.collaboration.getPresences();

bindPresence

The bindPresence method binds presence and user information to the current workbook, providing a simpler way to simultaneously bind both presence and user info to the workbook.

export declare function bindPresence(workbook: any, presence: Presence<IPresence>, user: IUser, options?: IBindPresenceOptions): Promise<void>;

Parameters

  • workbook (GC.Spread.Sheets.Workbook): The Workbook instance.

  • presence (GC.Spread.Sheets.Collaboration.IPresence): The Presence instance.

  • user (GC.Spread.Sheets.Collaboration.IUser): User information.

  • options (IBindPresenceOptions): Configuration options for binding user presence states.

Return

  • Promise<void>: Will return a promise, which will resolve when the bind is complete.

Example

import { Client } from "@mescius/js-collaboration-client";
import { Presence } from "@mescius/js-collaboration-presence-client";
import { bindPresence } from 'spread-sheets-collaboration-client';

const conn = new Client('ws://localhost:8080/').connect('room1');
const presence = new Presence(conn);

const user: IUser = {
    id: '1',
    name: "user1"
}

bindPresence(workbook, presence, user);

Usage

Client Side

  1. Install Npm Packages

    npm install @mescius/js-collaboration-client @mescius/js-collaboration-presence-client @mescius/spread-sheets-collaboration-client
  2. Create Presence Instance

    import { Client } from "@mescius/js-collaboration-client";
    import { Presence } from "@mescius/js-collaboration-presence-client";
    
    const conn = new Client('ws://localhost:8080/').connect('room1');
    const presence = new Presence(conn);
  3. Bind Workbook and Presence (without user info)


    This method does not include user information. If user info is needed, use the approach in Step 4.

    const presences: IPresence[] = Object.values(presence.otherStates);
    workbook.collaboration.setPresences(presences.map(p => ({ user: p.user, status: p.status })));
  4. Get User Instance and Bind Workbook, Presence, and User

    type=note

    This is an example only. Replace user with actual user info from your production environment.

    import { bindPresence } from 'spread-sheets-collaboration-client';
    const Color_Scheme = ['#0000ff', '#008000', '#9900cc', '#800000', '#00cc33', '#cc6600', '#cc0099'];
    var seed = new Date().valueOf() + "";
    const user: IUser = {
        id: seed,
        name: "user" + seed,
        color: Color_Scheme[Math.floor(Math.random() * Color_Scheme.length)]
    }
    bindPresence(workbook, presence, user);

Server Side

The server-side usage aligns with Presence Server.

API

  • spread-sheets-collaboration-client

    /**
     * Represents a user in the collaboration system.
     */
    export interface IUser {
        id: string;
        name: string;
        color?: string;
        permission?: IPermission;
    }
    /**
     * Represents selection data for a worksheet.
     */
    export interface ISelections {
        selections?: Range[];
        sheetId?: string;
    }
    /**
     * Represents presence information for a user.
     */
    export interface IPresence {
        user: IUser;
        status: { selections?: ISelections };
    }
    /**
     * Binds a workbook to a presence instance.
     * @param {any} workbook - The instance of GC.Spread.Sheets.Workbook.
     * @param {Presence<IPresence>} presence - The presence instance.
     * @param {IUser} user - The user information.
     * @param {IBindPresenceOptions} [options] - Optional binding options.
     * @returns {Promise<void>} A promise that resolves when the binding is complete.
     */
    export declare function bindPresence(workbook: any, presence: Presence<IPresence>, user: IUser, options?: IBindPresenceOptions): void;
    /**
     * Options for binding presence to a workbook.
     */
    export interface IBindPresenceOptions {
        onPresencesUpdate?: (presences?: IPresence[]) => void;
        colorScheme?: string[];
    }
  • GC.Spread.Sheets.@Workbook

    ///* function setPresences(presences: GC.Spread.Sheets.Collaboration.IPresence[]): void
    /**
      * Set the presences info.
      * @param {GC.Spread.Sheets.Collaboration.IPresence[]} presences - The presences info.
      * @example
      * //This example updates the current presences.
      * let presences = [{
      *     user: {
      *         id: '1',
      *         name: 'User1',
      *         color: '#FF0000',
      *         permission: {
      *             mode: GC.Spread.Sheets.Collaboration.BrowsingMode.edit,
      *         }
      *     },
      *     status: {
      *         selections: {
      *              selections: [new GC.Spread.Sheets.Range(0, 0, 1, 1)],
      *              sheetId: 'sheet1'
      *         }
      *     }
      * }, {
      *     user: {
      *         id: '2',
      *         name: 'User2',
      *         permission: {
      *             mode: GC.Spread.Sheets.Collaboration.BrowsingMode.edit,
      *         }
      *     },
      *     status: {
      *         selections: {
      *              selections: [new GC.Spread.Sheets.Range(2, 2, 3, 5)],
      *              sheetId: 'sheet1'
      *         }
      *     }
      * }]
      * spread.collaboration.setPresences(presences);
      */
    setPresences (presences: IPresence[]): void;
    
    ///* function getPresences(): GC.Spread.Sheets.Collaboration.IPresence[]
    /**
      * Get presences for workbook
      * @returns {GC.Spread.Sheets.Collaboration.IPresence[]} presences - The presences info.
      * @example
      * ```typescript
      * // This example gets presences.
      * const presences = spread.collaboration.getPresences();
      */
    getPresences (): GC.Spread.Sheets.Collaboration.IPresence[];