plugin-build-guide-block 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +74 -74
  2. package/dist/client/index.js +1 -1
  3. package/dist/externalVersion.js +7 -7
  4. package/dist/locale/en-US.json +28 -27
  5. package/dist/locale/vi-VN.json +28 -27
  6. package/dist/locale/zh-CN.json +28 -27
  7. package/dist/server/actions/build.js +3 -0
  8. package/dist/server/index.js +10 -3
  9. package/dist/server/plugin.js +14 -0
  10. package/package.json +31 -31
  11. package/src/client/UserGuideBlock.tsx +53 -53
  12. package/src/client/UserGuideBlockInitializer.tsx +26 -26
  13. package/src/client/UserGuideBlockProvider.tsx +12 -12
  14. package/src/client/UserGuideManager.tsx +127 -107
  15. package/src/client/components/BuildButton.tsx +78 -43
  16. package/src/client/components/LLMServiceSelect.tsx +44 -44
  17. package/src/client/components/ModelSelect.tsx +41 -41
  18. package/src/client/components/StatusTag.tsx +17 -17
  19. package/src/client/models/UserGuideBlockModel.ts +54 -54
  20. package/src/client/models/index.ts +1 -3
  21. package/src/client/plugin.tsx +30 -30
  22. package/src/client/schemas/spacesSchema.ts +316 -316
  23. package/src/locale/en-US.json +28 -27
  24. package/src/locale/vi-VN.json +28 -27
  25. package/src/locale/zh-CN.json +28 -27
  26. package/src/server/actions/build.ts +176 -171
  27. package/src/server/actions/getHtml.ts +26 -26
  28. package/src/server/collections/ai-build-guide-spaces.ts +50 -50
  29. package/src/server/index.ts +2 -0
  30. package/src/server/plugin.ts +76 -60
  31. package/dist/client/UserGuideBlock.d.ts +0 -2
  32. package/dist/client/UserGuideBlockInitializer.d.ts +0 -2
  33. package/dist/client/UserGuideBlockProvider.d.ts +0 -2
  34. package/dist/client/UserGuideManager.d.ts +0 -2
  35. package/dist/client/components/BuildButton.d.ts +0 -2
  36. package/dist/client/components/LLMServiceSelect.d.ts +0 -2
  37. package/dist/client/components/ModelSelect.d.ts +0 -2
  38. package/dist/client/components/StatusTag.d.ts +0 -2
  39. package/dist/client/index.d.ts +0 -1
  40. package/dist/client/models/UserGuideBlockModel.d.ts +0 -9
  41. package/dist/client/models/index.d.ts +0 -11
  42. package/dist/client/plugin.d.ts +0 -5
  43. package/dist/client/schemas/spacesSchema.d.ts +0 -315
  44. package/dist/index.d.ts +0 -2
  45. package/dist/server/actions/build.d.ts +0 -2
  46. package/dist/server/actions/getHtml.d.ts +0 -2
  47. package/dist/server/collections/ai-build-guide-spaces.d.ts +0 -2
  48. package/dist/server/index.d.ts +0 -1
  49. package/dist/server/plugin.d.ts +0 -12
@@ -1,27 +1,28 @@
1
- {
2
- "Build Guide Block": "生成指南区块",
3
- "User guide block setting": "用户指南区块设置",
4
- "Edit user guide settings": "编辑用户指南设置",
5
- "Space": "空间",
6
- "User Guide": "用户指南",
7
- "Create space": "创建空间",
8
- "Title": "标题",
9
- "LLM Service": "大语言模型服务",
10
- "Model": "模型",
11
- "System Prompt": "系统提示词",
12
- "Documents": "文档",
13
- "Cancel": "取消",
14
- "Submit": "提交",
15
- "Actions": "操作",
16
- "Edit": "编辑",
17
- "Edit space": "编辑空间",
18
- "Generated HTML": "生成的 HTML",
19
- "Build Log": "构建日志",
20
- "Delete": "删除",
21
- "Saved successfully": "保存成功",
22
- "Please select a User Guide Space in block settings": "请在区块设置中选择一个用户指南空间",
23
- "Build": "构建",
24
- "Build started": "构建已开始",
25
- "Build failed": "构建失败",
26
- "Are you sure you want to delete this space?": "确定要删除此空间吗?"
27
- }
1
+ {
2
+ "Build Guide Block": "生成指南区块",
3
+ "User guide block setting": "用户指南区块设置",
4
+ "Edit user guide settings": "编辑用户指南设置",
5
+ "Space": "空间",
6
+ "User Guide": "用户指南",
7
+ "Create space": "创建空间",
8
+ "Title": "标题",
9
+ "LLM Service": "大语言模型服务",
10
+ "Model": "模型",
11
+ "System Prompt": "系统提示词",
12
+ "Documents": "文档",
13
+ "Cancel": "取消",
14
+ "Submit": "提交",
15
+ "Actions": "操作",
16
+ "Edit": "编辑",
17
+ "Edit space": "编辑空间",
18
+ "Generated HTML": "生成的 HTML",
19
+ "Build Log": "构建日志",
20
+ "Delete": "删除",
21
+ "Saved successfully": "保存成功",
22
+ "Please select a User Guide Space in block settings": "请在区块设置中选择一个用户指南空间",
23
+ "Build": "构建",
24
+ "Build started": "构建已开始",
25
+ "Build failed": "构建失败",
26
+ "Are you sure you want to delete this space?": "确定要删除此空间吗?",
27
+ "Build completed": "构建完成"
28
+ }
@@ -73,6 +73,9 @@ async function build(ctx, next) {
73
73
  if (!space) {
74
74
  ctx.throw(404, "Space not found");
75
75
  }
76
+ if (space.get("status") === "building") {
77
+ ctx.throw(409, "A build is already in progress for this space");
78
+ }
76
79
  const app = ctx.app;
77
80
  const db = ctx.db;
78
81
  try {
@@ -14,8 +14,8 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
14
14
  var __getProtoOf = Object.getPrototypeOf;
15
15
  var __hasOwnProp = Object.prototype.hasOwnProperty;
16
16
  var __export = (target, all) => {
17
- for (var name in all)
18
- __defProp(target, name, { get: all[name], enumerable: true });
17
+ for (var name2 in all)
18
+ __defProp(target, name2, { get: all[name2], enumerable: true });
19
19
  };
20
20
  var __copyProps = (to, from, except, desc) => {
21
21
  if (from && typeof from === "object" || typeof from === "function") {
@@ -36,7 +36,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
36
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
37
  var server_exports = {};
38
38
  __export(server_exports, {
39
- default: () => import_plugin.default
39
+ default: () => import_plugin.default,
40
+ namespace: () => namespace
40
41
  });
41
42
  module.exports = __toCommonJS(server_exports);
43
+ var import_package = require("../../package.json");
42
44
  var import_plugin = __toESM(require("./plugin"));
45
+ const namespace = import_package.name;
46
+ // Annotate the CommonJS export names for ESM import in node:
47
+ 0 && (module.exports = {
48
+ namespace
49
+ });
@@ -55,6 +55,20 @@ class PluginBuildGuideBlockServer extends import_server.Plugin {
55
55
  "aiBuildGuideSpaces:build"
56
56
  ]
57
57
  });
58
+ this.app.on("afterStart", async () => {
59
+ try {
60
+ const repo = this.db.getRepository("aiBuildGuideSpaces");
61
+ await repo.update({
62
+ filter: { status: "building" },
63
+ values: {
64
+ status: "error",
65
+ buildLog: "Build interrupted by server restart"
66
+ }
67
+ });
68
+ } catch (err) {
69
+ this.app.logger.warn("[plugin-build-guide-block] Failed to recover stale builds", err);
70
+ }
71
+ });
58
72
  }
59
73
  async install(options) {
60
74
  const collection = this.db.getCollection("aiBuildGuideSpaces");
package/package.json CHANGED
@@ -1,31 +1,31 @@
1
- {
2
- "name": "plugin-build-guide-block",
3
- "version": "1.0.9",
4
- "main": "dist/server/index.js",
5
- "files": [
6
- "dist",
7
- "src",
8
- "client.js",
9
- "server.js",
10
- "client.d.ts",
11
- "server.d.ts"
12
- ],
13
- "dependencies": {
14
- "dompurify": "^3.1.2",
15
- "sanitize-html": "^2.13.0"
16
- },
17
- "devDependencies": {
18
- "@types/dompurify": "^3.0.4",
19
- "@types/sanitize-html": "^2.9.5"
20
- },
21
- "peerDependencies": {
22
- "@nocobase/client": "2.x",
23
- "@nocobase/server": "2.x",
24
- "@nocobase/database": "2.x",
25
- "@nocobase/test": "2.x",
26
- "@nocobase/plugin-ai": "2.x",
27
- "@nocobase/plugin-file-manager": "2.x",
28
- "@langchain/core": "*",
29
- "axios": "*"
30
- }
31
- }
1
+ {
2
+ "name": "plugin-build-guide-block",
3
+ "version": "1.0.10",
4
+ "main": "dist/server/index.js",
5
+ "files": [
6
+ "dist",
7
+ "src",
8
+ "client.js",
9
+ "server.js",
10
+ "client.d.ts",
11
+ "server.d.ts"
12
+ ],
13
+ "dependencies": {
14
+ "dompurify": "^3.1.2",
15
+ "sanitize-html": "^2.13.0"
16
+ },
17
+ "devDependencies": {
18
+ "@types/dompurify": "^3.0.4",
19
+ "@types/sanitize-html": "^2.9.5"
20
+ },
21
+ "peerDependencies": {
22
+ "@nocobase/client": "2.x",
23
+ "@nocobase/server": "2.x",
24
+ "@nocobase/database": "2.x",
25
+ "@nocobase/test": "2.x",
26
+ "@nocobase/plugin-ai": "2.x",
27
+ "@nocobase/plugin-file-manager": "2.x",
28
+ "@langchain/core": "*",
29
+ "axios": "*"
30
+ }
31
+ }
@@ -1,53 +1,53 @@
1
- import React from 'react';
2
- import { Card, Spin } from 'antd';
3
- import { useRequest } from '@nocobase/client';
4
- import { observer } from '@formily/react';
5
- import { useTranslation } from 'react-i18next';
6
- import DOMPurify from 'dompurify';
7
-
8
- export const UserGuideBlock = observer(
9
- (props: any) => {
10
- const { spaceId } = props;
11
- const { t } = useTranslation();
12
-
13
- const { loading, data: htmlContent } = useRequest(
14
- {
15
- url: `aiBuildGuideSpaces:getHtml/${spaceId}`,
16
- },
17
- {
18
- refreshDeps: [spaceId],
19
- ready: !!spaceId,
20
- }
21
- );
22
-
23
- if (!spaceId) {
24
- return (
25
- <Card style={{ padding: 24, textAlign: 'center', color: '#888' }}>
26
- {t('Please select a User Guide Space in block settings')}
27
- </Card>
28
- );
29
- }
30
-
31
- if (loading) {
32
- return (
33
- <Card style={{ padding: 24, textAlign: 'center' }}>
34
- <Spin size="large" />
35
- </Card>
36
- );
37
- }
38
-
39
- return (
40
- <Card
41
- bordered={false}
42
- className="user-guide-block"
43
- style={{ width: '100%', minHeight: 300 }}
44
- >
45
- <div
46
- className="user-guide-content"
47
- dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize((htmlContent as any)?.data || '') }}
48
- />
49
- </Card>
50
- );
51
- },
52
- { displayName: 'UserGuideBlock' }
53
- );
1
+ import React from 'react';
2
+ import { Card, Spin } from 'antd';
3
+ import { useRequest } from '@nocobase/client';
4
+ import { observer } from '@formily/react';
5
+ import { useTranslation } from 'react-i18next';
6
+ import DOMPurify from 'dompurify';
7
+
8
+ export const UserGuideBlock = observer(
9
+ (props: any) => {
10
+ const { spaceId } = props;
11
+ const { t } = useTranslation();
12
+
13
+ const { loading, data: htmlContent } = useRequest(
14
+ {
15
+ url: `aiBuildGuideSpaces:getHtml/${spaceId}`,
16
+ },
17
+ {
18
+ refreshDeps: [spaceId],
19
+ ready: !!spaceId,
20
+ }
21
+ );
22
+
23
+ if (!spaceId) {
24
+ return (
25
+ <Card style={{ padding: 24, textAlign: 'center', color: '#888' }}>
26
+ {t('Please select a User Guide Space in block settings')}
27
+ </Card>
28
+ );
29
+ }
30
+
31
+ if (loading) {
32
+ return (
33
+ <Card style={{ padding: 24, textAlign: 'center' }}>
34
+ <Spin size="large" />
35
+ </Card>
36
+ );
37
+ }
38
+
39
+ return (
40
+ <Card
41
+ bordered={false}
42
+ className="user-guide-block"
43
+ style={{ width: '100%', minHeight: 300 }}
44
+ >
45
+ <div
46
+ className="user-guide-content"
47
+ dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize((htmlContent as any)?.data || '') }}
48
+ />
49
+ </Card>
50
+ );
51
+ },
52
+ { displayName: 'UserGuideBlock' }
53
+ );
@@ -1,26 +1,26 @@
1
- import React from 'react';
2
- import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '@nocobase/client';
3
- import { ReadOutlined } from '@ant-design/icons';
4
-
5
- export const UserGuideBlockInitializer = () => {
6
- const { insert } = useSchemaInitializer();
7
- const itemConfig = useSchemaInitializerItem();
8
- return (
9
- <SchemaInitializerItem
10
- {...itemConfig}
11
- icon={<ReadOutlined />}
12
- onClick={() => {
13
- insert({
14
- type: 'void',
15
- 'x-settings': 'userGuideBlockSettings',
16
- 'x-decorator': 'BlockItem',
17
- 'x-decorator-props': {
18
- name: 'userGuide',
19
- },
20
- 'x-component': 'UserGuideBlock',
21
- 'x-component-props': {},
22
- });
23
- }}
24
- />
25
- );
26
- };
1
+ import React from 'react';
2
+ import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '@nocobase/client';
3
+ import { ReadOutlined } from '@ant-design/icons';
4
+
5
+ export const UserGuideBlockInitializer = () => {
6
+ const { insert } = useSchemaInitializer();
7
+ const itemConfig = useSchemaInitializerItem();
8
+ return (
9
+ <SchemaInitializerItem
10
+ {...itemConfig}
11
+ icon={<ReadOutlined />}
12
+ onClick={() => {
13
+ insert({
14
+ type: 'void',
15
+ 'x-settings': 'userGuideBlockSettings',
16
+ 'x-decorator': 'BlockItem',
17
+ 'x-decorator-props': {
18
+ name: 'userGuide',
19
+ },
20
+ 'x-component': 'UserGuideBlock',
21
+ 'x-component-props': {},
22
+ });
23
+ }}
24
+ />
25
+ );
26
+ };
@@ -1,12 +1,12 @@
1
- import React from 'react';
2
- import { SchemaComponentOptions } from '@nocobase/client';
3
- import { UserGuideBlock } from './UserGuideBlock';
4
- import { UserGuideBlockInitializer } from './UserGuideBlockInitializer';
5
-
6
- export const UserGuideBlockProvider = (props: any) => {
7
- return (
8
- <SchemaComponentOptions components={{ UserGuideBlock, UserGuideBlockInitializer }}>
9
- {props.children}
10
- </SchemaComponentOptions>
11
- );
12
- };
1
+ import React from 'react';
2
+ import { SchemaComponentOptions } from '@nocobase/client';
3
+ import { UserGuideBlock } from './UserGuideBlock';
4
+ import { UserGuideBlockInitializer } from './UserGuideBlockInitializer';
5
+
6
+ export const UserGuideBlockProvider = (props: any) => {
7
+ return (
8
+ <SchemaComponentOptions components={{ UserGuideBlock, UserGuideBlockInitializer }}>
9
+ {props.children}
10
+ </SchemaComponentOptions>
11
+ );
12
+ };
@@ -1,107 +1,127 @@
1
- import React, { useMemo } from 'react';
2
- import {
3
- SchemaComponent,
4
- useActionContext,
5
- useCollectionRecordData,
6
- useDataBlockRequest,
7
- useDataBlockResource,
8
- useDestroyActionProps,
9
- useTableBlockProps,
10
- } from '@nocobase/client';
11
- import { createForm } from '@formily/core';
12
- import { App } from 'antd';
13
- import { useTranslation } from 'react-i18next';
14
- import { spacesSchema } from './schemas/spacesSchema';
15
- import { LLMServiceSelect } from './components/LLMServiceSelect';
16
- import { ModelSelect } from './components/ModelSelect';
17
- import { StatusTag } from './components/StatusTag';
18
- import { BuildButton } from './components/BuildButton';
19
-
20
- export const UserGuideManager = () => {
21
- const { t } = useTranslation();
22
-
23
- const useCreateFormProps = () => {
24
- const form = useMemo(() => createForm(), []);
25
- return { form };
26
- };
27
-
28
- const useEditFormProps = () => {
29
- const record = useCollectionRecordData();
30
- const form = useMemo(() => createForm({ initialValues: record }), [record]);
31
- return { form };
32
- };
33
-
34
- const useCancelActionProps = () => {
35
- const { setVisible } = useActionContext();
36
- return {
37
- type: 'default',
38
- onClick() {
39
- setVisible(false);
40
- },
41
- };
42
- };
43
-
44
- const useCreateActionProps = () => {
45
- const { setVisible } = useActionContext();
46
- const { message } = App.useApp();
47
- const resource = useDataBlockResource();
48
- const { refresh } = useDataBlockRequest();
49
-
50
- return {
51
- type: 'primary',
52
- async onClick() {
53
- const form = (this as any).form;
54
- await form.submit();
55
- await resource.create({ values: form.values });
56
- refresh();
57
- message.success(t('Saved successfully'));
58
- setVisible(false);
59
- },
60
- };
61
- };
62
-
63
- const useUpdateActionProps = () => {
64
- const { setVisible } = useActionContext();
65
- const { message } = App.useApp();
66
- const resource = useDataBlockResource();
67
- const { refresh } = useDataBlockRequest();
68
- const record = useCollectionRecordData();
69
-
70
- return {
71
- type: 'primary',
72
- async onClick() {
73
- const form = (this as any).form;
74
- await form.submit();
75
- await resource.update({
76
- filterByTk: record.id,
77
- values: form.values,
78
- });
79
- refresh();
80
- message.success(t('Saved successfully'));
81
- setVisible(false);
82
- },
83
- };
84
- };
85
-
86
- return (
87
- <SchemaComponent
88
- schema={spacesSchema}
89
- components={{
90
- LLMServiceSelect,
91
- ModelSelect,
92
- StatusTag,
93
- BuildButton,
94
- }}
95
- scope={{
96
- t,
97
- useCreateFormProps,
98
- useEditFormProps,
99
- useCancelActionProps,
100
- useCreateActionProps,
101
- useUpdateActionProps,
102
- useDestroyActionProps,
103
- useTableBlockProps,
104
- }}
105
- />
106
- );
107
- };
1
+ import React, { useMemo } from 'react';
2
+ import {
3
+ SchemaComponent,
4
+ useActionContext,
5
+ useCollectionRecordData,
6
+ useDataBlockRequest,
7
+ useDataBlockResource,
8
+ useDestroyActionProps,
9
+ useTableBlockProps,
10
+ } from '@nocobase/client';
11
+ import { createForm } from '@formily/core';
12
+ import { App } from 'antd';
13
+ import { useTranslation } from 'react-i18next';
14
+ import { spacesSchema } from './schemas/spacesSchema';
15
+ import { LLMServiceSelect } from './components/LLMServiceSelect';
16
+ import { ModelSelect } from './components/ModelSelect';
17
+ import { StatusTag } from './components/StatusTag';
18
+ import { BuildButton } from './components/BuildButton';
19
+
20
+ export const UserGuideManager = () => {
21
+ const { t } = useTranslation();
22
+
23
+ const useCreateFormProps = () => {
24
+ const form = useMemo(() => createForm(), []);
25
+ return { form };
26
+ };
27
+
28
+ const useEditFormProps = () => {
29
+ const record = useCollectionRecordData();
30
+ const form = useMemo(() => createForm({ initialValues: record }), [record]);
31
+ return { form };
32
+ };
33
+
34
+ const useCancelActionProps = () => {
35
+ const { setVisible } = useActionContext();
36
+ return {
37
+ type: 'default',
38
+ onClick() {
39
+ setVisible(false);
40
+ },
41
+ };
42
+ };
43
+
44
+ const normalizeValues = (values: any) => {
45
+ const { documents, ...rest } = values;
46
+ if (Array.isArray(documents)) {
47
+ rest.documents = documents.map((doc: any) => (typeof doc === 'object' && doc?.id ? { id: doc.id } : doc));
48
+ }
49
+ return rest;
50
+ };
51
+
52
+ const useCreateActionProps = () => {
53
+ const { setVisible } = useActionContext();
54
+ const { message } = App.useApp();
55
+ const resource = useDataBlockResource();
56
+ const { refresh } = useDataBlockRequest();
57
+
58
+ return {
59
+ type: 'primary',
60
+ async onClick() {
61
+ const form = (this as any).form;
62
+ try {
63
+ await form.submit();
64
+ await resource.create({ values: normalizeValues(form.values) });
65
+ refresh();
66
+ message.success(t('Saved successfully'));
67
+ setVisible(false);
68
+ } catch (err: any) {
69
+ if (err?.name !== 'ValidateError') {
70
+ message.error(err?.message || t('Save failed'));
71
+ }
72
+ }
73
+ },
74
+ };
75
+ };
76
+
77
+ const useUpdateActionProps = () => {
78
+ const { setVisible } = useActionContext();
79
+ const { message } = App.useApp();
80
+ const resource = useDataBlockResource();
81
+ const { refresh } = useDataBlockRequest();
82
+ const record = useCollectionRecordData();
83
+
84
+ return {
85
+ type: 'primary',
86
+ async onClick() {
87
+ const form = (this as any).form;
88
+ try {
89
+ await form.submit();
90
+ await resource.update({
91
+ filterByTk: record.id,
92
+ values: normalizeValues(form.values),
93
+ });
94
+ refresh();
95
+ message.success(t('Saved successfully'));
96
+ setVisible(false);
97
+ } catch (err: any) {
98
+ if (err?.name !== 'ValidateError') {
99
+ message.error(err?.message || t('Save failed'));
100
+ }
101
+ }
102
+ },
103
+ };
104
+ };
105
+
106
+ return (
107
+ <SchemaComponent
108
+ schema={spacesSchema}
109
+ components={{
110
+ LLMServiceSelect,
111
+ ModelSelect,
112
+ StatusTag,
113
+ BuildButton,
114
+ }}
115
+ scope={{
116
+ t,
117
+ useCreateFormProps,
118
+ useEditFormProps,
119
+ useCancelActionProps,
120
+ useCreateActionProps,
121
+ useUpdateActionProps,
122
+ useDestroyActionProps,
123
+ useTableBlockProps,
124
+ }}
125
+ />
126
+ );
127
+ };