跳到主要内容

ONES Wiki

适用环境私有部署
SaaS

要求

ONES
v3.14.0+

概述

我们为「知识库管理」-「页面组」-「Wiki 页面」提供了一些插槽,以便于为该应用定制化页面模块。

当前支持的插槽:

插槽

ones:wiki:space:header:title

模块路径: 知识库管理 / 页面组 / Wiki 页面 / 标题

个数限制: 一个插件中最多可声明 1 个该插槽,系统中最多同时存在 1 个该插槽

ones:wiki:page:header:action:new

ONES 要求: v3.14.0+

模块路径: 知识库管理 / 页面组 / Wiki 页面 / 顶部操作模块 / 新模块

个数限制: 一个插件中最多可声明 10 个该插槽,系统中最多同时存在 10 个该插槽

使用

- id: ones-wiki-space-header-title-oU6k
title: wiki
moduleType: ones:wiki:space:header:title
entry: modules/ones-wiki-space-header-title-oU6k/index.html

可访问的上下文数据

import { useWikiSpaceInfo } from '@ones-op/store'

const spaceInfo = useWikiSpaceInfo()
import { useWikiPageInfo } from '@ones-op/store'

const pageInfo = useWikiPageInfo()

v6.12.0+ 新增 功能

ONES 要求: v6.12.0+

可以将模块添加到wiki编辑页面,支持wiki 协同编辑页面,wps编辑页面和旧的wiki编辑页面。 也可以在页面阅读模块更多按钮的下拉菜单中添加新的菜单项。

- id: ones-wiki-space-header-title-oU6k
title: wiki
moduleType: ones:wiki:page:header:action:new
actionType:
- edit
- view
pageType:
- wps
- wiki
- wiz

- id: ones-wiki-page-header-action-new-vDxA
title: more-menu-action
moduleType: ones:wiki:page:header:action:new
enableMemoryRouter: true
entry: modules/ones-wiki-page-header-action-new-vDxA/index.html
actionType: viewMore
preload: true,
manual: true,
  • 如果没有指定actionType,则默认仅支持阅读页面。
  • 如果没有指定pageType,则默认支持全部的页面类型。pageType仅用于wiki编辑页面,阅读页面会忽略该字段。
  • 如果添加到更多按钮的下拉菜单,那么preload和manual都需要设置为true。当点击菜单项的时候,会只执行该模块代码,当用户处理之后,需要插件代码调用lifecycle.onDestroy来卸载模块。 否则当用户再次点击菜单项的时候,插件系统会报错。

获取WPS WebOffice SDK(可以支持WPS阅读和编辑页面)

import React from 'react'
import ReactDOM from 'react-dom'
import { Button, ConfigProvider } from '@ones-design/core'
import { lifecycle, OPProvider } from '@ones-op/bridge'
import { useStoreInfo } from '@ones-op/store'

import './index.css'


function ActionButton() {

const store: any = useStoreInfo().store;
console.log('store info:', store);

async function clickHandler() {
const instance = store?.wpsPageInfo?.instance;
if (!instance) {
return;
}
//
const app = instance.Application

// 返回一个 Range 对象
const Range = await app.ActiveDocument.Content

// 获取 range 内文本内容信息
const text = await Range.Text
alert(text)
}

return (
<Button onClick={clickHandler} size='small' style={{
marginRight: '20px',
}}>
View & Edit Action (WPS only)
</Button>
);
}

ReactDOM.render(
<ConfigProvider>
<OPProvider>
<ActionButton />
</OPProvider>
</ConfigProvider>,
document.getElementById('ones-mf-root')
)

lifecycle.onDestroy(() => {
ReactDOM.unmountComponentAtNode(document.getElementById('ones-mf-root'))
})

获取协同编辑器对象(可以支持协同阅读和编辑页面)

import React from 'react'
import ReactDOM from 'react-dom'
import { Button, ConfigProvider } from '@ones-design/core'
import { lifecycle, OPProvider } from '@ones-op/bridge'
import { useStoreInfo } from '@ones-op/store'

import './index.css'

function textBlockToText(editor: any, ops: any, doc: any): string {
let text = '';
ops.forEach((op) => {
if (op.attributes && op.attributes.box === true) {
//
const box = op.attributes;
const boxClass = editor.editorBoxes.getBoxClass(box.type);
if (boxClass?.convertTo) {
text += boxClass.convertTo(editor, box, doc, 'text');
return;
}
//
if (op.attributes.text) {
text += op.attributes.text;
return;
}
//
text += `[${box.type}]`;
}
text += op.insert;
});
return text;
}

function blockToText(editor: any, blockData: any, doc: any, path: any) {
const blockClass = editor.editorBlocks.getBlockClass(blockData.type);
if (blockClass.convertTo) {
return blockClass.convertTo(editor, blockData, doc, 'text', path);
}
//
if (blockClass.blockKind !== 'text') {
return `[${blockData.type}]`;
}
//
const plainText = textBlockToText(editor, blockData.text, doc);
return plainText;
}

function docToText(editor: any, doc: any): string {
const lines = doc.blocks.root.map((b, blockIndex) => blockToText(editor, b, doc, [{ containerId: 'root', blockIndex }]));
const html = lines.join('\n');
return html;
}


function ActionButton() {
const store: any = useStoreInfo().store;

function clickHandler() {
const editor = store?.wizPageEditor?.editor;
if (editor) {
const text = docToText(editor, editor.doc.toJSON());
alert(text);
}
}

return (
<Button onClick={clickHandler} size='small' style={{
marginRight: '20px',
}}>
Edit Action Only
</Button>
);
}

ReactDOM.render(
<ConfigProvider>
<OPProvider>
<ActionButton />
</OPProvider>
</ConfigProvider>,
document.getElementById('ones-mf-root')
)

lifecycle.onDestroy(() => {
ReactDOM.unmountComponentAtNode(document.getElementById('ones-mf-root'))
})

更多按钮下拉菜单模块示例

import React from 'react'
import ReactDOM from 'react-dom'
import { ConfigProvider } from '@ones-design/core'
import { lifecycle, OPProvider } from '@ones-op/bridge'
import { useStoreInfo } from '@ones-op/store'

import './index.css'
import { docToText } from '../../utils/doc-to-text'


function RunAction() {
const store: any = useStoreInfo().store;
console.log('store info:', store);

React.useEffect(() => {

async function clickHandler() {
const instance = store?.wpsPageInfo?.instance;
if (instance) {
const app = instance.Application
if (app.ActiveDocument) {
// wps 文档
const Range = await app.ActiveDocument.Content
const text = await Range.Text
alert(text)
}
if (app.ActiveSheet) {
// wps 表格
const activeSheet = await app.ActiveSheet
// 活动工作表名称
const name = await activeSheet.Name
alert(name)
}
return;
}
//
const editor = store?.wizPageEditor?.editor;
if (editor) {
// 协同编辑页面
const text = docToText(editor, editor.doc.toJSON());
alert(text);
}
lifecycle.destroy();
}
//
clickHandler();
}, [store]);

return (
<div />
);
}

ReactDOM.render(
<ConfigProvider>
<OPProvider>
<RunAction />
</OPProvider>
</ConfigProvider>,
document.getElementById('ones-mf-root')
)

lifecycle.onDestroy(() => {
ReactDOM.unmountComponentAtNode(document.getElementById('ones-mf-root'))
})

ones:wiki:space:nav:new

页面组导航栏扩展插槽

- id: ones-wiki-space-nav-new-w0Wg
title: test nav plugin
moduleType: ones:wiki:space:nav:new
enableMemoryRouter: true
entry: modules/ones-wiki-space-nav-new-w0Wg/index.html
icon: logo.svg

可以通过useWikiSpaceInfo获取当前页面组信息。

import React from 'react'
import ReactDOM from 'react-dom'
import { ConfigProvider } from '@ones-design/core'
import { lifecycle, OPProvider } from '@ones-op/bridge'
import { useWikiSpaceInfo } from '@ones-op/store';
import './index.css'

function Content() {
const spaceInfo = useWikiSpaceInfo();
return (
<div>
test nav plugin ({spaceInfo?.name})
</div>
)
}

ReactDOM.render(
<ConfigProvider>
<OPProvider>
<Content />
</OPProvider>
</ConfigProvider>,
document.getElementById('ones-mf-root')
)