diff --git a/content/guides/sheets/features/collaboration.ja-JP.mdx b/content/guides/sheets/features/collaboration.ja-JP.mdx index 28b69fa..b7e52aa 100644 --- a/content/guides/sheets/features/collaboration.ja-JP.mdx +++ b/content/guides/sheets/features/collaboration.ja-JP.mdx @@ -287,12 +287,49 @@ async function run(): Promise { await univerAPI.getCollaboration().loadSheetAsync('your-unit-id') + await TestSheetsPermissionAPI(univerAPI) TestSheetsFacadeAPI(univerAPI) TestSheetsConditionalFormattingAPI(univerAPI) + await TestSheetsDrawingAPI(univerAPI) + await TestSheetsChartFacadeAPI(univerAPI) + await TestSheetsShapeFacadeAPI(univerAPI) + await TestSheetsOutlineAPI(univerAPI) } run() +async function TestSheetsPermissionAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Add some collaborators to the workbook + const workbookPermission = fWorkbook.getWorkbookPermission() + await workbookPermission.setCollaborators([ + { + user: { userID: 'systemUser1', name: 'System User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Owner, + }, + { + user: { userID: 'editorUser1', name: 'Editor User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Editor, + }, + { + user: { userID: 'readerUser1', name: 'Reader User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Reader, + }, + ]) + + const fRange = fWorksheet.getRange('A1:B2') + const rangePermission = fRange.getRangePermission() + await rangePermission.protect({ + name: 'Test Protection Rule', + allowedUsers: ['editorUser1'], + allowViewByOthers: true, + }) +} + async function TestSheetsFacadeAPI(univerAPI: FUniver) { const fWorkbook = univerAPI.getActiveWorkbook() if (!fWorkbook) return @@ -313,11 +350,11 @@ async function TestSheetsFacadeAPI(univerAPI: FUniver) { fRange2.merge().setValue(1234).setNumberFormat('#,##0.00') // Create a defined name for cell A1 and use it in cell A6 - const definedNameParam = fWorkbook.newDefinedNameBuilder() + const definedNameBuilder = fWorkbook.newDefinedNameBuilder() .setRef(`${fWorksheet.getSheetName()}!$A$1`) .setName('MyDefinedName') .build() - fWorkbook.insertDefinedNameBuilder(definedNameParam) + fWorkbook.insertDefinedNameBuilder(definedNameBuilder) fWorksheet.getRange('A6').setValue('=MyDefinedName') // Insert a new sheet @@ -372,7 +409,7 @@ async function TestSheetsFacadeAPI(univerAPI: FUniver) { } } -async function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { +function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { const fWorkbook = univerAPI.getActiveWorkbook() if (!fWorkbook) return @@ -417,6 +454,99 @@ async function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { .build() newSheet.addConditionalFormattingRule(rule) } + +async function TestSheetsOutlineAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Add an outline for rows 2-6 and rows 3-4 (0-based index). + fWorksheet.addRowOutline(1, 5).addRowOutline(2, 2) + // Add an outline for columns B-E and columns C-D (0-based index). + fWorksheet.addColumnOutline(1, 2) + + await new Promise(resolve => setTimeout(resolve, 4000)) + + const rowOutlines = fWorksheet.getDimensionOutlines(univerAPI.Enum.DimensionOutlineAxis.ROW) + console.warn('rowOutlines', rowOutlines) + + fWorksheet.setDimensionOutlineCollapsed(rowOutlines[0].id, true) + + await new Promise(resolve => setTimeout(resolve, 4000)) + + fWorksheet.removeDimensionOutline(rowOutlines[1].id) + fWorksheet.clearDimensionOutlines(univerAPI.Enum.DimensionOutlineAxis.COLUMN, 1, 3) +} + +async function TestSheetsDrawingAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + const images = fWorksheet.getImages() + console.warn(`Current sheet has ${images.length} images.`) + + const activeImages = fWorksheet.getActiveImages() + console.warn(`Current sheet has ${activeImages.length} active images.`) + + const image = await fWorksheet.newOverGridImage() + .setSource('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', univerAPI.Enum.ImageSourceType.URL) + .setColumn(5) + .setRow(5) + .setWidth(500) + .setHeight(300) + .buildAsync() + fWorksheet.insertImages([image]) + + // Update the image width to 100px and height to 50px. + await new Promise(resolve => setTimeout(resolve, 4000)) + + const insertedImage = fWorksheet.getImageById(image.drawingId)! + const newImage = await insertedImage.toBuilder() + .setWidth(100) + .setHeight(50) + .buildAsync() + fWorksheet.updateImages([newImage]) + + // Delete the image after 4 seconds. + await new Promise(resolve => setTimeout(resolve, 4000)) + fWorksheet.deleteImages([insertedImage]) +} + +async function TestSheetsChartFacadeAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Create a column chart with data source A1:D6. + // The starting position is upper-left corner of cell B2. + const chartInfo = fWorksheet.newChart() + .setChartType(univerAPI.Enum.ChartType.Column) + .addRange('A1:D6') + .setPosition(1, 1, 0, 0) + .build() + await fWorksheet.insertChart(chartInfo) +} + +async function TestSheetsShapeFacadeAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Create a rectangle shape at cell B2. + const shapeInfo = fWorksheet.newShape() + .setShapeType(univerAPI.Enum.ShapeTypeEnum.Rect) + .setPosition(1, 1, 0, 0) + .setWidth(200) + .setHeight(200) + .setStrokeColor('#000000') + .build() + await fWorksheet.insertShape(shapeInfo) +} ``` ```typescript title="examples/sheets-node/univer.ts" @@ -424,15 +554,19 @@ import path from 'node:path' import { UniverCollaborationPlugin } from '@univerjs-pro/collaboration' import { UniverCollaborationClientPlugin } from '@univerjs-pro/collaboration-client' import { NodeCollaborationSocketService, UniverCollaborationClientNodePlugin } from '@univerjs-pro/collaboration-client-node' +import { UniverLicensePlugin } from '@univerjs-pro/license' import { UniverSheetsChartPlugin } from '@univerjs-pro/sheets-chart' +import { UniverSheetsOutlinePlugin } from '@univerjs-pro/sheets-outline' import { UniverSheetsPivotTablePlugin } from '@univerjs-pro/sheets-pivot' +import { UniverSheetsShapePlugin } from '@univerjs-pro/sheets-shape' import { UniverSheetSparklinePlugin } from '@univerjs-pro/sheets-sparkline' import { IAuthzIoService, IUndoRedoService, LocaleType, Univer } from '@univerjs/core' import { UniverDataValidationPlugin } from '@univerjs/data-validation' import { UniverDocsPlugin } from '@univerjs/docs' import { UniverDocsDrawingPlugin } from '@univerjs/docs-drawing' -import { UniverDrawingPlugin } from '@univerjs/drawing' +import { IImageIoService, UniverDrawingPlugin } from '@univerjs/drawing' import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula' +import { UniverRenderEnginePlugin } from '@univerjs/engine-render' import { UniverNetworkPlugin } from '@univerjs/network' import { UniverRPCNodeMainPlugin } from '@univerjs/rpc-node' import { UniverSheetsPlugin } from '@univerjs/sheets' @@ -458,9 +592,13 @@ import '@univerjs/sheets-filter/facade' import '@univerjs/sheets-hyper-link/facade' import '@univerjs/sheets-note/facade' import '@univerjs/sheets-table/facade' +import '@univerjs/sheets-drawing/facade' import '@univerjs/sheets-thread-comment/facade' import '@univerjs-pro/sheets-pivot/facade' import '@univerjs-pro/sheets-sparkline/facade' +import '@univerjs-pro/sheets-chart/facade' +import '@univerjs-pro/sheets-shape/facade' +import '@univerjs-pro/sheets-outline/facade' import '@univerjs-pro/collaboration-client/facade' export interface ICreateUniverOnNodeOptions { @@ -471,7 +609,7 @@ export function createUniverOnNode(options: ICreateUniverOnNodeOptions = {}): Un const { useComputingWorker = false } = options const univer = new Univer({ - locale: LocaleType.ZH_CN, + locale: LocaleType.JA_JP, locales: {}, override: [ [IAuthzIoService, null], @@ -479,6 +617,10 @@ export function createUniverOnNode(options: ICreateUniverOnNodeOptions = {}): Un ], }) + univer.registerPlugin(UniverLicensePlugin, { + license: 'your-license', + }) + registerBasicPlugins(univer, useComputingWorker) registerSharedPlugins(univer) @@ -498,8 +640,11 @@ function registerBasicPlugins(univer: Univer, useComputingWorker: boolean): void } function registerSharedPlugins(univer: Univer): void { + univer.registerPlugin(UniverRenderEnginePlugin) univer.registerPlugin(UniverThreadCommentPlugin) - univer.registerPlugin(UniverDrawingPlugin) + univer.registerPlugin(UniverDrawingPlugin, { + override: [[IImageIoService, null]], + }) } function registerDocPlugins(univer: Univer): void { @@ -521,8 +666,10 @@ function registerSheetPlugins(univer: Univer): void { univer.registerPlugin(UniverSheetsSortPlugin) univer.registerPlugin(UniverSheetsTablePlugin) univer.registerPlugin(UniverSheetsChartPlugin) + univer.registerPlugin(UniverSheetsShapePlugin) univer.registerPlugin(UniverSheetsPivotTablePlugin) univer.registerPlugin(UniverSheetSparklinePlugin) + univer.registerPlugin(UniverSheetsOutlinePlugin) } function registerRPCPlugin(univer: Univer): void { @@ -541,11 +688,15 @@ function registerCollaborationPlugins(univer: Univer): void { collabSubmitChangesetUrl: 'https://dev.univer.plus/universer-api/comb', collabWebSocketUrl: 'http://dev.univer.plus/universer-api/comb/connect', wsSessionTicketUrl: 'http://dev.univer.plus/universer-api/user/session-ticket', + uploadFileServerUrl: 'https://dev.univer.plus/universer-api/stream/file/upload', + signUrlServerUrl: 'https://dev.univer.plus/universer-api/file/{fileID}/sign-url', + downloadEndpointUrl: 'https://dev.univer.plus', + authzUrl: 'https://dev.univer.plus/universer-api/authz', sendChangesetTimeout: 200, retryConnectingInterval: 1000, customHeaders: { // Example: If your Univer server requires authentication via cookies, you can set the 'cookie' header here. - cookie: '_univer=GY3WYUTBIJ2FEVDRI5FFI6SONN2XONDGGJAW2', + cookie: 'your-cookie', // ... more headers }, }) @@ -560,7 +711,7 @@ import { UniverRPCNodeWorkerPlugin } from '@univerjs/rpc-node' import { UniverSheetsPlugin } from '@univerjs/sheets' const univer = new Univer({ - locale: LocaleType.ZH_CN, + locale: LocaleType.JA_JP, }) univer.registerPlugin(UniverSheetsPlugin, { onlyRegisterFormulaRelatedMutations: true }) diff --git a/content/guides/sheets/features/collaboration.mdx b/content/guides/sheets/features/collaboration.mdx index d7f2da7..17de6f3 100644 --- a/content/guides/sheets/features/collaboration.mdx +++ b/content/guides/sheets/features/collaboration.mdx @@ -287,12 +287,49 @@ async function run(): Promise { await univerAPI.getCollaboration().loadSheetAsync('your-unit-id') + await TestSheetsPermissionAPI(univerAPI) TestSheetsFacadeAPI(univerAPI) TestSheetsConditionalFormattingAPI(univerAPI) + await TestSheetsDrawingAPI(univerAPI) + await TestSheetsChartFacadeAPI(univerAPI) + await TestSheetsShapeFacadeAPI(univerAPI) + await TestSheetsOutlineAPI(univerAPI) } run() +async function TestSheetsPermissionAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Add some collaborators to the workbook + const workbookPermission = fWorkbook.getWorkbookPermission() + await workbookPermission.setCollaborators([ + { + user: { userID: 'systemUser1', name: 'System User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Owner, + }, + { + user: { userID: 'editorUser1', name: 'Editor User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Editor, + }, + { + user: { userID: 'readerUser1', name: 'Reader User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Reader, + }, + ]) + + const fRange = fWorksheet.getRange('A1:B2') + const rangePermission = fRange.getRangePermission() + await rangePermission.protect({ + name: 'Test Protection Rule', + allowedUsers: ['editorUser1'], + allowViewByOthers: true, + }) +} + async function TestSheetsFacadeAPI(univerAPI: FUniver) { const fWorkbook = univerAPI.getActiveWorkbook() if (!fWorkbook) return @@ -313,11 +350,11 @@ async function TestSheetsFacadeAPI(univerAPI: FUniver) { fRange2.merge().setValue(1234).setNumberFormat('#,##0.00') // Create a defined name for cell A1 and use it in cell A6 - const definedNameParam = fWorkbook.newDefinedNameBuilder() + const definedNameBuilder = fWorkbook.newDefinedNameBuilder() .setRef(`${fWorksheet.getSheetName()}!$A$1`) .setName('MyDefinedName') .build() - fWorkbook.insertDefinedNameBuilder(definedNameParam) + fWorkbook.insertDefinedNameBuilder(definedNameBuilder) fWorksheet.getRange('A6').setValue('=MyDefinedName') // Insert a new sheet @@ -372,7 +409,7 @@ async function TestSheetsFacadeAPI(univerAPI: FUniver) { } } -async function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { +function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { const fWorkbook = univerAPI.getActiveWorkbook() if (!fWorkbook) return @@ -417,6 +454,99 @@ async function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { .build() newSheet.addConditionalFormattingRule(rule) } + +async function TestSheetsOutlineAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Add an outline for rows 2-6 and rows 3-4 (0-based index). + fWorksheet.addRowOutline(1, 5).addRowOutline(2, 2) + // Add an outline for columns B-E and columns C-D (0-based index). + fWorksheet.addColumnOutline(1, 2) + + await new Promise(resolve => setTimeout(resolve, 4000)) + + const rowOutlines = fWorksheet.getDimensionOutlines(univerAPI.Enum.DimensionOutlineAxis.ROW) + console.warn('rowOutlines', rowOutlines) + + fWorksheet.setDimensionOutlineCollapsed(rowOutlines[0].id, true) + + await new Promise(resolve => setTimeout(resolve, 4000)) + + fWorksheet.removeDimensionOutline(rowOutlines[1].id) + fWorksheet.clearDimensionOutlines(univerAPI.Enum.DimensionOutlineAxis.COLUMN, 1, 3) +} + +async function TestSheetsDrawingAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + const images = fWorksheet.getImages() + console.warn(`Current sheet has ${images.length} images.`) + + const activeImages = fWorksheet.getActiveImages() + console.warn(`Current sheet has ${activeImages.length} active images.`) + + const image = await fWorksheet.newOverGridImage() + .setSource('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', univerAPI.Enum.ImageSourceType.URL) + .setColumn(5) + .setRow(5) + .setWidth(500) + .setHeight(300) + .buildAsync() + fWorksheet.insertImages([image]) + + // Update the image width to 100px and height to 50px. + await new Promise(resolve => setTimeout(resolve, 4000)) + + const insertedImage = fWorksheet.getImageById(image.drawingId)! + const newImage = await insertedImage.toBuilder() + .setWidth(100) + .setHeight(50) + .buildAsync() + fWorksheet.updateImages([newImage]) + + // Delete the image after 4 seconds. + await new Promise(resolve => setTimeout(resolve, 4000)) + fWorksheet.deleteImages([insertedImage]) +} + +async function TestSheetsChartFacadeAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Create a column chart with data source A1:D6. + // The starting position is upper-left corner of cell B2. + const chartInfo = fWorksheet.newChart() + .setChartType(univerAPI.Enum.ChartType.Column) + .addRange('A1:D6') + .setPosition(1, 1, 0, 0) + .build() + await fWorksheet.insertChart(chartInfo) +} + +async function TestSheetsShapeFacadeAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Create a rectangle shape at cell B2. + const shapeInfo = fWorksheet.newShape() + .setShapeType(univerAPI.Enum.ShapeTypeEnum.Rect) + .setPosition(1, 1, 0, 0) + .setWidth(200) + .setHeight(200) + .setStrokeColor('#000000') + .build() + await fWorksheet.insertShape(shapeInfo) +} ``` ```typescript title="examples/sheets-node/univer.ts" @@ -424,15 +554,19 @@ import path from 'node:path' import { UniverCollaborationPlugin } from '@univerjs-pro/collaboration' import { UniverCollaborationClientPlugin } from '@univerjs-pro/collaboration-client' import { NodeCollaborationSocketService, UniverCollaborationClientNodePlugin } from '@univerjs-pro/collaboration-client-node' +import { UniverLicensePlugin } from '@univerjs-pro/license' import { UniverSheetsChartPlugin } from '@univerjs-pro/sheets-chart' +import { UniverSheetsOutlinePlugin } from '@univerjs-pro/sheets-outline' import { UniverSheetsPivotTablePlugin } from '@univerjs-pro/sheets-pivot' +import { UniverSheetsShapePlugin } from '@univerjs-pro/sheets-shape' import { UniverSheetSparklinePlugin } from '@univerjs-pro/sheets-sparkline' import { IAuthzIoService, IUndoRedoService, LocaleType, Univer } from '@univerjs/core' import { UniverDataValidationPlugin } from '@univerjs/data-validation' import { UniverDocsPlugin } from '@univerjs/docs' import { UniverDocsDrawingPlugin } from '@univerjs/docs-drawing' -import { UniverDrawingPlugin } from '@univerjs/drawing' +import { IImageIoService, UniverDrawingPlugin } from '@univerjs/drawing' import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula' +import { UniverRenderEnginePlugin } from '@univerjs/engine-render' import { UniverNetworkPlugin } from '@univerjs/network' import { UniverRPCNodeMainPlugin } from '@univerjs/rpc-node' import { UniverSheetsPlugin } from '@univerjs/sheets' @@ -458,9 +592,13 @@ import '@univerjs/sheets-filter/facade' import '@univerjs/sheets-hyper-link/facade' import '@univerjs/sheets-note/facade' import '@univerjs/sheets-table/facade' +import '@univerjs/sheets-drawing/facade' import '@univerjs/sheets-thread-comment/facade' import '@univerjs-pro/sheets-pivot/facade' import '@univerjs-pro/sheets-sparkline/facade' +import '@univerjs-pro/sheets-chart/facade' +import '@univerjs-pro/sheets-shape/facade' +import '@univerjs-pro/sheets-outline/facade' import '@univerjs-pro/collaboration-client/facade' export interface ICreateUniverOnNodeOptions { @@ -471,7 +609,7 @@ export function createUniverOnNode(options: ICreateUniverOnNodeOptions = {}): Un const { useComputingWorker = false } = options const univer = new Univer({ - locale: LocaleType.ZH_CN, + locale: LocaleType.En_US, locales: {}, override: [ [IAuthzIoService, null], @@ -479,6 +617,10 @@ export function createUniverOnNode(options: ICreateUniverOnNodeOptions = {}): Un ], }) + univer.registerPlugin(UniverLicensePlugin, { + license: 'your-license', + }) + registerBasicPlugins(univer, useComputingWorker) registerSharedPlugins(univer) @@ -498,8 +640,11 @@ function registerBasicPlugins(univer: Univer, useComputingWorker: boolean): void } function registerSharedPlugins(univer: Univer): void { + univer.registerPlugin(UniverRenderEnginePlugin) univer.registerPlugin(UniverThreadCommentPlugin) - univer.registerPlugin(UniverDrawingPlugin) + univer.registerPlugin(UniverDrawingPlugin, { + override: [[IImageIoService, null]], + }) } function registerDocPlugins(univer: Univer): void { @@ -521,8 +666,10 @@ function registerSheetPlugins(univer: Univer): void { univer.registerPlugin(UniverSheetsSortPlugin) univer.registerPlugin(UniverSheetsTablePlugin) univer.registerPlugin(UniverSheetsChartPlugin) + univer.registerPlugin(UniverSheetsShapePlugin) univer.registerPlugin(UniverSheetsPivotTablePlugin) univer.registerPlugin(UniverSheetSparklinePlugin) + univer.registerPlugin(UniverSheetsOutlinePlugin) } function registerRPCPlugin(univer: Univer): void { @@ -541,11 +688,15 @@ function registerCollaborationPlugins(univer: Univer): void { collabSubmitChangesetUrl: 'https://dev.univer.plus/universer-api/comb', collabWebSocketUrl: 'http://dev.univer.plus/universer-api/comb/connect', wsSessionTicketUrl: 'http://dev.univer.plus/universer-api/user/session-ticket', + uploadFileServerUrl: 'https://dev.univer.plus/universer-api/stream/file/upload', + signUrlServerUrl: 'https://dev.univer.plus/universer-api/file/{fileID}/sign-url', + downloadEndpointUrl: 'https://dev.univer.plus', + authzUrl: 'https://dev.univer.plus/universer-api/authz', sendChangesetTimeout: 200, retryConnectingInterval: 1000, customHeaders: { // Example: If your Univer server requires authentication via cookies, you can set the 'cookie' header here. - cookie: '_univer=GY3WYUTBIJ2FEVDRI5FFI6SONN2XONDGGJAW2', + cookie: 'your-cookie', // ... more headers }, }) @@ -560,7 +711,7 @@ import { UniverRPCNodeWorkerPlugin } from '@univerjs/rpc-node' import { UniverSheetsPlugin } from '@univerjs/sheets' const univer = new Univer({ - locale: LocaleType.ZH_CN, + locale: LocaleType.En_US, }) univer.registerPlugin(UniverSheetsPlugin, { onlyRegisterFormulaRelatedMutations: true }) diff --git a/content/guides/sheets/features/collaboration.zh-CN.mdx b/content/guides/sheets/features/collaboration.zh-CN.mdx index 7162368..0f1559b 100644 --- a/content/guides/sheets/features/collaboration.zh-CN.mdx +++ b/content/guides/sheets/features/collaboration.zh-CN.mdx @@ -287,12 +287,49 @@ async function run(): Promise { await univerAPI.getCollaboration().loadSheetAsync('your-unit-id') + await TestSheetsPermissionAPI(univerAPI) TestSheetsFacadeAPI(univerAPI) TestSheetsConditionalFormattingAPI(univerAPI) + await TestSheetsDrawingAPI(univerAPI) + await TestSheetsChartFacadeAPI(univerAPI) + await TestSheetsShapeFacadeAPI(univerAPI) + await TestSheetsOutlineAPI(univerAPI) } run() +async function TestSheetsPermissionAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Add some collaborators to the workbook + const workbookPermission = fWorkbook.getWorkbookPermission() + await workbookPermission.setCollaborators([ + { + user: { userID: 'systemUser1', name: 'System User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Owner, + }, + { + user: { userID: 'editorUser1', name: 'Editor User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Editor, + }, + { + user: { userID: 'readerUser1', name: 'Reader User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Reader, + }, + ]) + + const fRange = fWorksheet.getRange('A1:B2') + const rangePermission = fRange.getRangePermission() + await rangePermission.protect({ + name: 'Test Protection Rule', + allowedUsers: ['editorUser1'], + allowViewByOthers: true, + }) +} + async function TestSheetsFacadeAPI(univerAPI: FUniver) { const fWorkbook = univerAPI.getActiveWorkbook() if (!fWorkbook) return @@ -313,11 +350,11 @@ async function TestSheetsFacadeAPI(univerAPI: FUniver) { fRange2.merge().setValue(1234).setNumberFormat('#,##0.00') // Create a defined name for cell A1 and use it in cell A6 - const definedNameParam = fWorkbook.newDefinedNameBuilder() + const definedNameBuilder = fWorkbook.newDefinedNameBuilder() .setRef(`${fWorksheet.getSheetName()}!$A$1`) .setName('MyDefinedName') .build() - fWorkbook.insertDefinedNameBuilder(definedNameParam) + fWorkbook.insertDefinedNameBuilder(definedNameBuilder) fWorksheet.getRange('A6').setValue('=MyDefinedName') // Insert a new sheet @@ -372,7 +409,7 @@ async function TestSheetsFacadeAPI(univerAPI: FUniver) { } } -async function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { +function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { const fWorkbook = univerAPI.getActiveWorkbook() if (!fWorkbook) return @@ -417,6 +454,99 @@ async function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { .build() newSheet.addConditionalFormattingRule(rule) } + +async function TestSheetsOutlineAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Add an outline for rows 2-6 and rows 3-4 (0-based index). + fWorksheet.addRowOutline(1, 5).addRowOutline(2, 2) + // Add an outline for columns B-E and columns C-D (0-based index). + fWorksheet.addColumnOutline(1, 2) + + await new Promise(resolve => setTimeout(resolve, 4000)) + + const rowOutlines = fWorksheet.getDimensionOutlines(univerAPI.Enum.DimensionOutlineAxis.ROW) + console.warn('rowOutlines', rowOutlines) + + fWorksheet.setDimensionOutlineCollapsed(rowOutlines[0].id, true) + + await new Promise(resolve => setTimeout(resolve, 4000)) + + fWorksheet.removeDimensionOutline(rowOutlines[1].id) + fWorksheet.clearDimensionOutlines(univerAPI.Enum.DimensionOutlineAxis.COLUMN, 1, 3) +} + +async function TestSheetsDrawingAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + const images = fWorksheet.getImages() + console.warn(`Current sheet has ${images.length} images.`) + + const activeImages = fWorksheet.getActiveImages() + console.warn(`Current sheet has ${activeImages.length} active images.`) + + const image = await fWorksheet.newOverGridImage() + .setSource('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', univerAPI.Enum.ImageSourceType.URL) + .setColumn(5) + .setRow(5) + .setWidth(500) + .setHeight(300) + .buildAsync() + fWorksheet.insertImages([image]) + + // Update the image width to 100px and height to 50px. + await new Promise(resolve => setTimeout(resolve, 4000)) + + const insertedImage = fWorksheet.getImageById(image.drawingId)! + const newImage = await insertedImage.toBuilder() + .setWidth(100) + .setHeight(50) + .buildAsync() + fWorksheet.updateImages([newImage]) + + // Delete the image after 4 seconds. + await new Promise(resolve => setTimeout(resolve, 4000)) + fWorksheet.deleteImages([insertedImage]) +} + +async function TestSheetsChartFacadeAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Create a column chart with data source A1:D6. + // The starting position is upper-left corner of cell B2. + const chartInfo = fWorksheet.newChart() + .setChartType(univerAPI.Enum.ChartType.Column) + .addRange('A1:D6') + .setPosition(1, 1, 0, 0) + .build() + await fWorksheet.insertChart(chartInfo) +} + +async function TestSheetsShapeFacadeAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Create a rectangle shape at cell B2. + const shapeInfo = fWorksheet.newShape() + .setShapeType(univerAPI.Enum.ShapeTypeEnum.Rect) + .setPosition(1, 1, 0, 0) + .setWidth(200) + .setHeight(200) + .setStrokeColor('#000000') + .build() + await fWorksheet.insertShape(shapeInfo) +} ``` ```typescript title="examples/sheets-node/univer.ts" @@ -424,15 +554,19 @@ import path from 'node:path' import { UniverCollaborationPlugin } from '@univerjs-pro/collaboration' import { UniverCollaborationClientPlugin } from '@univerjs-pro/collaboration-client' import { NodeCollaborationSocketService, UniverCollaborationClientNodePlugin } from '@univerjs-pro/collaboration-client-node' +import { UniverLicensePlugin } from '@univerjs-pro/license' import { UniverSheetsChartPlugin } from '@univerjs-pro/sheets-chart' +import { UniverSheetsOutlinePlugin } from '@univerjs-pro/sheets-outline' import { UniverSheetsPivotTablePlugin } from '@univerjs-pro/sheets-pivot' +import { UniverSheetsShapePlugin } from '@univerjs-pro/sheets-shape' import { UniverSheetSparklinePlugin } from '@univerjs-pro/sheets-sparkline' import { IAuthzIoService, IUndoRedoService, LocaleType, Univer } from '@univerjs/core' import { UniverDataValidationPlugin } from '@univerjs/data-validation' import { UniverDocsPlugin } from '@univerjs/docs' import { UniverDocsDrawingPlugin } from '@univerjs/docs-drawing' -import { UniverDrawingPlugin } from '@univerjs/drawing' +import { IImageIoService, UniverDrawingPlugin } from '@univerjs/drawing' import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula' +import { UniverRenderEnginePlugin } from '@univerjs/engine-render' import { UniverNetworkPlugin } from '@univerjs/network' import { UniverRPCNodeMainPlugin } from '@univerjs/rpc-node' import { UniverSheetsPlugin } from '@univerjs/sheets' @@ -458,9 +592,13 @@ import '@univerjs/sheets-filter/facade' import '@univerjs/sheets-hyper-link/facade' import '@univerjs/sheets-note/facade' import '@univerjs/sheets-table/facade' +import '@univerjs/sheets-drawing/facade' import '@univerjs/sheets-thread-comment/facade' import '@univerjs-pro/sheets-pivot/facade' import '@univerjs-pro/sheets-sparkline/facade' +import '@univerjs-pro/sheets-chart/facade' +import '@univerjs-pro/sheets-shape/facade' +import '@univerjs-pro/sheets-outline/facade' import '@univerjs-pro/collaboration-client/facade' export interface ICreateUniverOnNodeOptions { @@ -479,6 +617,10 @@ export function createUniverOnNode(options: ICreateUniverOnNodeOptions = {}): Un ], }) + univer.registerPlugin(UniverLicensePlugin, { + license: 'your-license', + }) + registerBasicPlugins(univer, useComputingWorker) registerSharedPlugins(univer) @@ -498,8 +640,11 @@ function registerBasicPlugins(univer: Univer, useComputingWorker: boolean): void } function registerSharedPlugins(univer: Univer): void { + univer.registerPlugin(UniverRenderEnginePlugin) univer.registerPlugin(UniverThreadCommentPlugin) - univer.registerPlugin(UniverDrawingPlugin) + univer.registerPlugin(UniverDrawingPlugin, { + override: [[IImageIoService, null]], + }) } function registerDocPlugins(univer: Univer): void { @@ -521,8 +666,10 @@ function registerSheetPlugins(univer: Univer): void { univer.registerPlugin(UniverSheetsSortPlugin) univer.registerPlugin(UniverSheetsTablePlugin) univer.registerPlugin(UniverSheetsChartPlugin) + univer.registerPlugin(UniverSheetsShapePlugin) univer.registerPlugin(UniverSheetsPivotTablePlugin) univer.registerPlugin(UniverSheetSparklinePlugin) + univer.registerPlugin(UniverSheetsOutlinePlugin) } function registerRPCPlugin(univer: Univer): void { @@ -541,11 +688,15 @@ function registerCollaborationPlugins(univer: Univer): void { collabSubmitChangesetUrl: 'https://dev.univer.plus/universer-api/comb', collabWebSocketUrl: 'http://dev.univer.plus/universer-api/comb/connect', wsSessionTicketUrl: 'http://dev.univer.plus/universer-api/user/session-ticket', + uploadFileServerUrl: 'https://dev.univer.plus/universer-api/stream/file/upload', + signUrlServerUrl: 'https://dev.univer.plus/universer-api/file/{fileID}/sign-url', + downloadEndpointUrl: 'https://dev.univer.plus', + authzUrl: 'https://dev.univer.plus/universer-api/authz', sendChangesetTimeout: 200, retryConnectingInterval: 1000, customHeaders: { // Example: If your Univer server requires authentication via cookies, you can set the 'cookie' header here. - cookie: '_univer=GY3WYUTBIJ2FEVDRI5FFI6SONN2XONDGGJAW2', + cookie: 'your-cookie', // ... more headers }, }) diff --git a/content/guides/sheets/features/collaboration.zh-TW.mdx b/content/guides/sheets/features/collaboration.zh-TW.mdx index cf41fcf..80c7cc3 100644 --- a/content/guides/sheets/features/collaboration.zh-TW.mdx +++ b/content/guides/sheets/features/collaboration.zh-TW.mdx @@ -287,12 +287,49 @@ async function run(): Promise { await univerAPI.getCollaboration().loadSheetAsync('your-unit-id') + await TestSheetsPermissionAPI(univerAPI) TestSheetsFacadeAPI(univerAPI) TestSheetsConditionalFormattingAPI(univerAPI) + await TestSheetsDrawingAPI(univerAPI) + await TestSheetsChartFacadeAPI(univerAPI) + await TestSheetsShapeFacadeAPI(univerAPI) + await TestSheetsOutlineAPI(univerAPI) } run() +async function TestSheetsPermissionAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Add some collaborators to the workbook + const workbookPermission = fWorkbook.getWorkbookPermission() + await workbookPermission.setCollaborators([ + { + user: { userID: 'systemUser1', name: 'System User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Owner, + }, + { + user: { userID: 'editorUser1', name: 'Editor User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Editor, + }, + { + user: { userID: 'readerUser1', name: 'Reader User 1', avatar: '' }, + role: univerAPI.Enum.UnitRole.Reader, + }, + ]) + + const fRange = fWorksheet.getRange('A1:B2') + const rangePermission = fRange.getRangePermission() + await rangePermission.protect({ + name: 'Test Protection Rule', + allowedUsers: ['editorUser1'], + allowViewByOthers: true, + }) +} + async function TestSheetsFacadeAPI(univerAPI: FUniver) { const fWorkbook = univerAPI.getActiveWorkbook() if (!fWorkbook) return @@ -313,11 +350,11 @@ async function TestSheetsFacadeAPI(univerAPI: FUniver) { fRange2.merge().setValue(1234).setNumberFormat('#,##0.00') // Create a defined name for cell A1 and use it in cell A6 - const definedNameParam = fWorkbook.newDefinedNameBuilder() + const definedNameBuilder = fWorkbook.newDefinedNameBuilder() .setRef(`${fWorksheet.getSheetName()}!$A$1`) .setName('MyDefinedName') .build() - fWorkbook.insertDefinedNameBuilder(definedNameParam) + fWorkbook.insertDefinedNameBuilder(definedNameBuilder) fWorksheet.getRange('A6').setValue('=MyDefinedName') // Insert a new sheet @@ -372,7 +409,7 @@ async function TestSheetsFacadeAPI(univerAPI: FUniver) { } } -async function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { +function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { const fWorkbook = univerAPI.getActiveWorkbook() if (!fWorkbook) return @@ -417,6 +454,99 @@ async function TestSheetsConditionalFormattingAPI(univerAPI: FUniver) { .build() newSheet.addConditionalFormattingRule(rule) } + +async function TestSheetsOutlineAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Add an outline for rows 2-6 and rows 3-4 (0-based index). + fWorksheet.addRowOutline(1, 5).addRowOutline(2, 2) + // Add an outline for columns B-E and columns C-D (0-based index). + fWorksheet.addColumnOutline(1, 2) + + await new Promise(resolve => setTimeout(resolve, 4000)) + + const rowOutlines = fWorksheet.getDimensionOutlines(univerAPI.Enum.DimensionOutlineAxis.ROW) + console.warn('rowOutlines', rowOutlines) + + fWorksheet.setDimensionOutlineCollapsed(rowOutlines[0].id, true) + + await new Promise(resolve => setTimeout(resolve, 4000)) + + fWorksheet.removeDimensionOutline(rowOutlines[1].id) + fWorksheet.clearDimensionOutlines(univerAPI.Enum.DimensionOutlineAxis.COLUMN, 1, 3) +} + +async function TestSheetsDrawingAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + const images = fWorksheet.getImages() + console.warn(`Current sheet has ${images.length} images.`) + + const activeImages = fWorksheet.getActiveImages() + console.warn(`Current sheet has ${activeImages.length} active images.`) + + const image = await fWorksheet.newOverGridImage() + .setSource('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', univerAPI.Enum.ImageSourceType.URL) + .setColumn(5) + .setRow(5) + .setWidth(500) + .setHeight(300) + .buildAsync() + fWorksheet.insertImages([image]) + + // Update the image width to 100px and height to 50px. + await new Promise(resolve => setTimeout(resolve, 4000)) + + const insertedImage = fWorksheet.getImageById(image.drawingId)! + const newImage = await insertedImage.toBuilder() + .setWidth(100) + .setHeight(50) + .buildAsync() + fWorksheet.updateImages([newImage]) + + // Delete the image after 4 seconds. + await new Promise(resolve => setTimeout(resolve, 4000)) + fWorksheet.deleteImages([insertedImage]) +} + +async function TestSheetsChartFacadeAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Create a column chart with data source A1:D6. + // The starting position is upper-left corner of cell B2. + const chartInfo = fWorksheet.newChart() + .setChartType(univerAPI.Enum.ChartType.Column) + .addRange('A1:D6') + .setPosition(1, 1, 0, 0) + .build() + await fWorksheet.insertChart(chartInfo) +} + +async function TestSheetsShapeFacadeAPI(univerAPI: FUniver) { + const fWorkbook = univerAPI.getActiveWorkbook() + if (!fWorkbook) return + + const fWorksheet = fWorkbook.getActiveSheet() + + // Create a rectangle shape at cell B2. + const shapeInfo = fWorksheet.newShape() + .setShapeType(univerAPI.Enum.ShapeTypeEnum.Rect) + .setPosition(1, 1, 0, 0) + .setWidth(200) + .setHeight(200) + .setStrokeColor('#000000') + .build() + await fWorksheet.insertShape(shapeInfo) +} ``` ```typescript title="examples/sheets-node/univer.ts" @@ -424,15 +554,19 @@ import path from 'node:path' import { UniverCollaborationPlugin } from '@univerjs-pro/collaboration' import { UniverCollaborationClientPlugin } from '@univerjs-pro/collaboration-client' import { NodeCollaborationSocketService, UniverCollaborationClientNodePlugin } from '@univerjs-pro/collaboration-client-node' +import { UniverLicensePlugin } from '@univerjs-pro/license' import { UniverSheetsChartPlugin } from '@univerjs-pro/sheets-chart' +import { UniverSheetsOutlinePlugin } from '@univerjs-pro/sheets-outline' import { UniverSheetsPivotTablePlugin } from '@univerjs-pro/sheets-pivot' +import { UniverSheetsShapePlugin } from '@univerjs-pro/sheets-shape' import { UniverSheetSparklinePlugin } from '@univerjs-pro/sheets-sparkline' import { IAuthzIoService, IUndoRedoService, LocaleType, Univer } from '@univerjs/core' import { UniverDataValidationPlugin } from '@univerjs/data-validation' import { UniverDocsPlugin } from '@univerjs/docs' import { UniverDocsDrawingPlugin } from '@univerjs/docs-drawing' -import { UniverDrawingPlugin } from '@univerjs/drawing' +import { IImageIoService, UniverDrawingPlugin } from '@univerjs/drawing' import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula' +import { UniverRenderEnginePlugin } from '@univerjs/engine-render' import { UniverNetworkPlugin } from '@univerjs/network' import { UniverRPCNodeMainPlugin } from '@univerjs/rpc-node' import { UniverSheetsPlugin } from '@univerjs/sheets' @@ -458,9 +592,13 @@ import '@univerjs/sheets-filter/facade' import '@univerjs/sheets-hyper-link/facade' import '@univerjs/sheets-note/facade' import '@univerjs/sheets-table/facade' +import '@univerjs/sheets-drawing/facade' import '@univerjs/sheets-thread-comment/facade' import '@univerjs-pro/sheets-pivot/facade' import '@univerjs-pro/sheets-sparkline/facade' +import '@univerjs-pro/sheets-chart/facade' +import '@univerjs-pro/sheets-shape/facade' +import '@univerjs-pro/sheets-outline/facade' import '@univerjs-pro/collaboration-client/facade' export interface ICreateUniverOnNodeOptions { @@ -479,6 +617,10 @@ export function createUniverOnNode(options: ICreateUniverOnNodeOptions = {}): Un ], }) + univer.registerPlugin(UniverLicensePlugin, { + license: 'your-license', + }) + registerBasicPlugins(univer, useComputingWorker) registerSharedPlugins(univer) @@ -498,8 +640,11 @@ function registerBasicPlugins(univer: Univer, useComputingWorker: boolean): void } function registerSharedPlugins(univer: Univer): void { + univer.registerPlugin(UniverRenderEnginePlugin) univer.registerPlugin(UniverThreadCommentPlugin) - univer.registerPlugin(UniverDrawingPlugin) + univer.registerPlugin(UniverDrawingPlugin, { + override: [[IImageIoService, null]], + }) } function registerDocPlugins(univer: Univer): void { @@ -521,8 +666,10 @@ function registerSheetPlugins(univer: Univer): void { univer.registerPlugin(UniverSheetsSortPlugin) univer.registerPlugin(UniverSheetsTablePlugin) univer.registerPlugin(UniverSheetsChartPlugin) + univer.registerPlugin(UniverSheetsShapePlugin) univer.registerPlugin(UniverSheetsPivotTablePlugin) univer.registerPlugin(UniverSheetSparklinePlugin) + univer.registerPlugin(UniverSheetsOutlinePlugin) } function registerRPCPlugin(univer: Univer): void { @@ -541,11 +688,15 @@ function registerCollaborationPlugins(univer: Univer): void { collabSubmitChangesetUrl: 'https://dev.univer.plus/universer-api/comb', collabWebSocketUrl: 'http://dev.univer.plus/universer-api/comb/connect', wsSessionTicketUrl: 'http://dev.univer.plus/universer-api/user/session-ticket', + uploadFileServerUrl: 'https://dev.univer.plus/universer-api/stream/file/upload', + signUrlServerUrl: 'https://dev.univer.plus/universer-api/file/{fileID}/sign-url', + downloadEndpointUrl: 'https://dev.univer.plus', + authzUrl: 'https://dev.univer.plus/universer-api/authz', sendChangesetTimeout: 200, retryConnectingInterval: 1000, customHeaders: { // Example: If your Univer server requires authentication via cookies, you can set the 'cookie' header here. - cookie: '_univer=GY3WYUTBIJ2FEVDRI5FFI6SONN2XONDGGJAW2', + cookie: 'your-cookie', // ... more headers }, })