plugin-build-guide-block 1.0.2 → 1.0.3

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 (105) hide show
  1. package/dist/node_modules/sanitize-html/LICENSE +7 -0
  2. package/dist/node_modules/sanitize-html/index.js +7 -0
  3. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.browser.cjs +34 -0
  4. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.browser.js +34 -0
  5. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.cjs +35 -0
  6. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.d.ts +56 -0
  7. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.js +35 -0
  8. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.native.js +26 -0
  9. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/package.json +12 -0
  10. package/dist/node_modules/sanitize-html/node_modules/nanoid/bin/nanoid.cjs +55 -0
  11. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.browser.cjs +34 -0
  12. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.browser.js +34 -0
  13. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.cjs +45 -0
  14. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.d.cts +91 -0
  15. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.d.ts +91 -0
  16. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.js +45 -0
  17. package/dist/node_modules/sanitize-html/node_modules/nanoid/nanoid.js +1 -0
  18. package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/index.cjs +21 -0
  19. package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/index.d.ts +33 -0
  20. package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/index.js +21 -0
  21. package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/package.json +6 -0
  22. package/dist/node_modules/sanitize-html/node_modules/nanoid/package.json +88 -0
  23. package/dist/node_modules/sanitize-html/node_modules/nanoid/url-alphabet/index.cjs +3 -0
  24. package/dist/node_modules/sanitize-html/node_modules/nanoid/url-alphabet/index.js +3 -0
  25. package/dist/node_modules/sanitize-html/node_modules/nanoid/url-alphabet/package.json +6 -0
  26. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/at-rule.d.ts +115 -0
  27. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/at-rule.js +25 -0
  28. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/comment.d.ts +67 -0
  29. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/comment.js +13 -0
  30. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/container.d.ts +452 -0
  31. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/container.js +439 -0
  32. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/css-syntax-error.d.ts +248 -0
  33. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/css-syntax-error.js +100 -0
  34. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/declaration.d.ts +148 -0
  35. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/declaration.js +24 -0
  36. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/document.d.ts +68 -0
  37. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/document.js +33 -0
  38. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/fromJSON.d.ts +9 -0
  39. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/fromJSON.js +54 -0
  40. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/input.d.ts +194 -0
  41. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/input.js +248 -0
  42. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/lazy-result.d.ts +190 -0
  43. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/lazy-result.js +550 -0
  44. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/list.d.ts +57 -0
  45. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/list.js +58 -0
  46. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/map-generator.js +359 -0
  47. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/no-work-result.d.ts +46 -0
  48. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/no-work-result.js +135 -0
  49. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/node.d.ts +536 -0
  50. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/node.js +381 -0
  51. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/parse.d.ts +9 -0
  52. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/parse.js +42 -0
  53. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/parser.js +610 -0
  54. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/postcss.d.mts +72 -0
  55. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/postcss.d.ts +441 -0
  56. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/postcss.js +101 -0
  57. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/previous-map.d.ts +81 -0
  58. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/previous-map.js +142 -0
  59. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/processor.d.ts +115 -0
  60. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/processor.js +67 -0
  61. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/result.d.ts +206 -0
  62. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/result.js +42 -0
  63. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/root.d.ts +86 -0
  64. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/root.js +61 -0
  65. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/rule.d.ts +113 -0
  66. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/rule.js +27 -0
  67. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringifier.d.ts +46 -0
  68. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringifier.js +353 -0
  69. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringify.d.ts +9 -0
  70. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringify.js +11 -0
  71. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/symbols.js +5 -0
  72. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/terminal-highlight.js +70 -0
  73. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/tokenize.js +266 -0
  74. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/warn-once.js +13 -0
  75. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/warning.d.ts +147 -0
  76. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/warning.js +37 -0
  77. package/dist/node_modules/sanitize-html/node_modules/postcss/node_modules/.bin/nanoid +15 -0
  78. package/dist/node_modules/sanitize-html/node_modules/postcss/node_modules/.bin/nanoid.cmd +7 -0
  79. package/dist/node_modules/sanitize-html/node_modules/postcss/package.json +88 -0
  80. package/dist/node_modules/sanitize-html/package.json +1 -0
  81. package/package.json +9 -1
  82. package/src/client/UserGuideBlock.tsx +53 -0
  83. package/src/client/UserGuideBlockInitializer.tsx +26 -0
  84. package/src/client/UserGuideBlockProvider.tsx +12 -0
  85. package/src/client/UserGuideManager.tsx +133 -0
  86. package/src/client/client.d.ts +249 -0
  87. package/src/client/components/BuildButton.tsx +43 -0
  88. package/src/client/components/LLMServiceSelect.tsx +44 -0
  89. package/src/client/components/ModelSelect.tsx +41 -0
  90. package/src/client/components/StatusTag.tsx +17 -0
  91. package/src/client/index.tsx +1 -0
  92. package/src/client/models/UserGuideBlockModel.ts +47 -0
  93. package/src/client/models/index.ts +12 -0
  94. package/src/client/plugin.tsx +30 -0
  95. package/src/client/schemas/spacesSchema.ts +305 -0
  96. package/src/index.ts +2 -0
  97. package/src/locale/en-US.json +27 -0
  98. package/src/locale/vi-VN.json +27 -0
  99. package/src/locale/zh-CN.json +27 -0
  100. package/src/server/actions/build.ts +171 -0
  101. package/src/server/actions/getHtml.ts +26 -0
  102. package/src/server/collections/.gitkeep +0 -0
  103. package/src/server/collections/ai-build-guide-spaces.ts +49 -0
  104. package/src/server/index.ts +1 -0
  105. package/src/server/plugin.ts +42 -0
@@ -0,0 +1,133 @@
1
+ import React, { useMemo } from 'react';
2
+ import {
3
+ SchemaComponent,
4
+ ActionContextProvider,
5
+ useActionContext,
6
+ useCollectionRecordData,
7
+ useDataBlockRequest,
8
+ useDataBlockResource,
9
+ useDestroyActionProps,
10
+ ExtendCollectionsProvider,
11
+ } from '@nocobase/client';
12
+ import { createForm } from '@formily/core';
13
+ import { App } from 'antd';
14
+ import { useTranslation } from 'react-i18next';
15
+ import { spacesSchema } from './schemas/spacesSchema';
16
+ import { LLMServiceSelect } from './components/LLMServiceSelect';
17
+ import { ModelSelect } from './components/ModelSelect';
18
+ import { StatusTag } from './components/StatusTag';
19
+ import { BuildButton } from './components/BuildButton';
20
+
21
+ export const UserGuideManager = () => {
22
+ const { t } = useTranslation();
23
+
24
+ const useCreateFormProps = () => {
25
+ const form = useMemo(() => createForm(), []);
26
+ return { form };
27
+ };
28
+
29
+ const useEditFormProps = () => {
30
+ const record = useCollectionRecordData();
31
+ const form = useMemo(() => createForm({ initialValues: record }), [record]);
32
+ return { form };
33
+ };
34
+
35
+ const useCancelActionProps = () => {
36
+ const { setVisible } = useActionContext();
37
+ return {
38
+ type: 'default',
39
+ onClick() {
40
+ setVisible(false);
41
+ },
42
+ };
43
+ };
44
+
45
+ const useCreateActionProps = () => {
46
+ const { setVisible } = useActionContext();
47
+ const { message } = App.useApp();
48
+ const resource = useDataBlockResource();
49
+ const { refresh } = useDataBlockRequest();
50
+
51
+ return {
52
+ type: 'primary',
53
+ async onClick() {
54
+ const form = (this as any).form;
55
+ await form.submit();
56
+ await resource.create({ values: form.values });
57
+ refresh();
58
+ message.success(t('Saved successfully'));
59
+ setVisible(false);
60
+ },
61
+ };
62
+ };
63
+
64
+ const useUpdateActionProps = () => {
65
+ const { setVisible } = useActionContext();
66
+ const { message } = App.useApp();
67
+ const resource = useDataBlockResource();
68
+ const { refresh } = useDataBlockRequest();
69
+ const record = useCollectionRecordData();
70
+
71
+ return {
72
+ type: 'primary',
73
+ async onClick() {
74
+ const form = (this as any).form;
75
+ await form.submit();
76
+ await resource.update({
77
+ filterByTk: record.id,
78
+ values: form.values,
79
+ });
80
+ refresh();
81
+ message.success(t('Saved successfully'));
82
+ setVisible(false);
83
+ },
84
+ };
85
+ };
86
+
87
+ const useTableBlockProps = () => {
88
+ return {
89
+ collection: 'aiBuildGuideSpaces',
90
+ request: {
91
+ resource: 'aiBuildGuideSpaces',
92
+ action: 'list',
93
+ params: {
94
+ appends: ['documents'],
95
+ sort: ['-createdAt'],
96
+ },
97
+ },
98
+ };
99
+ };
100
+
101
+ return (
102
+ <ExtendCollectionsProvider collections={[{
103
+ name: 'aiBuildGuideSpaces',
104
+ fields: [
105
+ { name: 'title', type: 'string' },
106
+ { name: 'llmService', type: 'string' },
107
+ { name: 'model', type: 'string' },
108
+ { name: 'status', type: 'string' },
109
+ { name: 'buildLog', type: 'string' },
110
+ ],
111
+ }]}>
112
+ <SchemaComponent
113
+ schema={spacesSchema}
114
+ components={{
115
+ LLMServiceSelect,
116
+ ModelSelect,
117
+ StatusTag,
118
+ BuildButton,
119
+ }}
120
+ scope={{
121
+ t,
122
+ useCreateFormProps,
123
+ useEditFormProps,
124
+ useCancelActionProps,
125
+ useCreateActionProps,
126
+ useUpdateActionProps,
127
+ useDestroyActionProps,
128
+ useTableBlockProps,
129
+ }}
130
+ />
131
+ </ExtendCollectionsProvider>
132
+ );
133
+ };
@@ -0,0 +1,249 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ // CSS modules
11
+ type CSSModuleClasses = { readonly [key: string]: string };
12
+
13
+ declare module '*.module.css' {
14
+ const classes: CSSModuleClasses;
15
+ export default classes;
16
+ }
17
+ declare module '*.module.scss' {
18
+ const classes: CSSModuleClasses;
19
+ export default classes;
20
+ }
21
+ declare module '*.module.sass' {
22
+ const classes: CSSModuleClasses;
23
+ export default classes;
24
+ }
25
+ declare module '*.module.less' {
26
+ const classes: CSSModuleClasses;
27
+ export default classes;
28
+ }
29
+ declare module '*.module.styl' {
30
+ const classes: CSSModuleClasses;
31
+ export default classes;
32
+ }
33
+ declare module '*.module.stylus' {
34
+ const classes: CSSModuleClasses;
35
+ export default classes;
36
+ }
37
+ declare module '*.module.pcss' {
38
+ const classes: CSSModuleClasses;
39
+ export default classes;
40
+ }
41
+ declare module '*.module.sss' {
42
+ const classes: CSSModuleClasses;
43
+ export default classes;
44
+ }
45
+
46
+ // CSS
47
+ declare module '*.css' { }
48
+ declare module '*.scss' { }
49
+ declare module '*.sass' { }
50
+ declare module '*.less' { }
51
+ declare module '*.styl' { }
52
+ declare module '*.stylus' { }
53
+ declare module '*.pcss' { }
54
+ declare module '*.sss' { }
55
+
56
+ // Built-in asset types
57
+ // see `src/node/constants.ts`
58
+
59
+ // images
60
+ declare module '*.apng' {
61
+ const src: string;
62
+ export default src;
63
+ }
64
+ declare module '*.png' {
65
+ const src: string;
66
+ export default src;
67
+ }
68
+ declare module '*.jpg' {
69
+ const src: string;
70
+ export default src;
71
+ }
72
+ declare module '*.jpeg' {
73
+ const src: string;
74
+ export default src;
75
+ }
76
+ declare module '*.jfif' {
77
+ const src: string;
78
+ export default src;
79
+ }
80
+ declare module '*.pjpeg' {
81
+ const src: string;
82
+ export default src;
83
+ }
84
+ declare module '*.pjp' {
85
+ const src: string;
86
+ export default src;
87
+ }
88
+ declare module '*.gif' {
89
+ const src: string;
90
+ export default src;
91
+ }
92
+ declare module '*.svg' {
93
+ const src: string;
94
+ export default src;
95
+ }
96
+ declare module '*.ico' {
97
+ const src: string;
98
+ export default src;
99
+ }
100
+ declare module '*.webp' {
101
+ const src: string;
102
+ export default src;
103
+ }
104
+ declare module '*.avif' {
105
+ const src: string;
106
+ export default src;
107
+ }
108
+
109
+ // media
110
+ declare module '*.mp4' {
111
+ const src: string;
112
+ export default src;
113
+ }
114
+ declare module '*.webm' {
115
+ const src: string;
116
+ export default src;
117
+ }
118
+ declare module '*.ogg' {
119
+ const src: string;
120
+ export default src;
121
+ }
122
+ declare module '*.mp3' {
123
+ const src: string;
124
+ export default src;
125
+ }
126
+ declare module '*.wav' {
127
+ const src: string;
128
+ export default src;
129
+ }
130
+ declare module '*.flac' {
131
+ const src: string;
132
+ export default src;
133
+ }
134
+ declare module '*.aac' {
135
+ const src: string;
136
+ export default src;
137
+ }
138
+ declare module '*.opus' {
139
+ const src: string;
140
+ export default src;
141
+ }
142
+ declare module '*.mov' {
143
+ const src: string;
144
+ export default src;
145
+ }
146
+ declare module '*.m4a' {
147
+ const src: string;
148
+ export default src;
149
+ }
150
+ declare module '*.vtt' {
151
+ const src: string;
152
+ export default src;
153
+ }
154
+
155
+ // fonts
156
+ declare module '*.woff' {
157
+ const src: string;
158
+ export default src;
159
+ }
160
+ declare module '*.woff2' {
161
+ const src: string;
162
+ export default src;
163
+ }
164
+ declare module '*.eot' {
165
+ const src: string;
166
+ export default src;
167
+ }
168
+ declare module '*.ttf' {
169
+ const src: string;
170
+ export default src;
171
+ }
172
+ declare module '*.otf' {
173
+ const src: string;
174
+ export default src;
175
+ }
176
+
177
+ // other
178
+ declare module '*.webmanifest' {
179
+ const src: string;
180
+ export default src;
181
+ }
182
+ declare module '*.pdf' {
183
+ const src: string;
184
+ export default src;
185
+ }
186
+ declare module '*.txt' {
187
+ const src: string;
188
+ export default src;
189
+ }
190
+
191
+ // wasm?init
192
+ declare module '*.wasm?init' {
193
+ const initWasm: (options?: WebAssembly.Imports) => Promise<WebAssembly.Instance>;
194
+ export default initWasm;
195
+ }
196
+
197
+ // web worker
198
+ declare module '*?worker' {
199
+ const workerConstructor: {
200
+ new(options?: { name?: string }): Worker;
201
+ };
202
+ export default workerConstructor;
203
+ }
204
+
205
+ declare module '*?worker&inline' {
206
+ const workerConstructor: {
207
+ new(options?: { name?: string }): Worker;
208
+ };
209
+ export default workerConstructor;
210
+ }
211
+
212
+ declare module '*?worker&url' {
213
+ const src: string;
214
+ export default src;
215
+ }
216
+
217
+ declare module '*?sharedworker' {
218
+ const sharedWorkerConstructor: {
219
+ new(options?: { name?: string }): SharedWorker;
220
+ };
221
+ export default sharedWorkerConstructor;
222
+ }
223
+
224
+ declare module '*?sharedworker&inline' {
225
+ const sharedWorkerConstructor: {
226
+ new(options?: { name?: string }): SharedWorker;
227
+ };
228
+ export default sharedWorkerConstructor;
229
+ }
230
+
231
+ declare module '*?sharedworker&url' {
232
+ const src: string;
233
+ export default src;
234
+ }
235
+
236
+ declare module '*?raw' {
237
+ const src: string;
238
+ export default src;
239
+ }
240
+
241
+ declare module '*?url' {
242
+ const src: string;
243
+ export default src;
244
+ }
245
+
246
+ declare module '*?inline' {
247
+ const src: string;
248
+ export default src;
249
+ }
@@ -0,0 +1,43 @@
1
+ import React, { useState } from 'react';
2
+ import { Button, App } from 'antd';
3
+ import { useAPIClient, useCollectionRecordData, useDataBlockRequest } from '@nocobase/client';
4
+ import { PlayCircleOutlined } from '@ant-design/icons';
5
+ import { useTranslation } from 'react-i18next';
6
+
7
+ export const BuildButton = () => {
8
+ const [loading, setLoading] = useState(false);
9
+ const api = useAPIClient();
10
+ const { message } = App.useApp();
11
+ const { t } = useTranslation();
12
+ const record = useCollectionRecordData();
13
+ const { refresh } = useDataBlockRequest();
14
+
15
+ const handleBuild = async () => {
16
+ if (!record?.id) return;
17
+ setLoading(true);
18
+ try {
19
+ await api.resource('aiBuildGuideSpaces').build({
20
+ filterByTk: record.id,
21
+ });
22
+ message.success(t('Build started'));
23
+ // Delay slightly to allow background status update to propagate
24
+ setTimeout(() => refresh?.(), 1500);
25
+ } catch (err: any) {
26
+ console.error(err);
27
+ message.error(err?.response?.data?.error?.message || t('Build failed'));
28
+ } finally {
29
+ setLoading(false);
30
+ }
31
+ };
32
+
33
+ return (
34
+ <Button
35
+ type="primary"
36
+ icon={<PlayCircleOutlined />}
37
+ loading={loading}
38
+ onClick={handleBuild}
39
+ >
40
+ {t('Build')}
41
+ </Button>
42
+ );
43
+ };
@@ -0,0 +1,44 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { useAPIClient } from '@nocobase/client';
3
+ import { Select } from 'antd';
4
+ import { useField } from '@formily/react';
5
+ import { Field } from '@formily/core';
6
+
7
+ export const LLMServiceSelect = (props: any) => {
8
+ const [options, setOptions] = useState([]);
9
+ const [loading, setLoading] = useState(false);
10
+ const api = useAPIClient();
11
+ const field = useField<Field>();
12
+
13
+ useEffect(() => {
14
+ let active = true;
15
+ setLoading(true);
16
+ api.resource('ai').listLLMServices()
17
+ .then((res) => {
18
+ if (!active) return;
19
+ const data = res?.data?.data || [];
20
+ setOptions(
21
+ data.map((item: any) => ({
22
+ label: item.title || item.name,
23
+ value: item.name,
24
+ }))
25
+ );
26
+ })
27
+ .catch((err) => {
28
+ if (!active) return;
29
+ console.error('Failed to load LLM services:', err);
30
+ })
31
+ .finally(() => {
32
+ if (active) setLoading(false);
33
+ });
34
+ return () => {
35
+ active = false;
36
+ };
37
+ }, [api]);
38
+
39
+ return <Select {...props} options={options} loading={loading} value={field.value} onChange={(v) => {
40
+ field.setValue(v);
41
+ // Reset model when service changes
42
+ (field.query('.model').take() as any)?.setValue(undefined);
43
+ }} />;
44
+ };
@@ -0,0 +1,41 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { useAPIClient } from '@nocobase/client';
3
+ import { Select } from 'antd';
4
+ import { useField, useForm } from '@formily/react';
5
+ import { Field } from '@formily/core';
6
+
7
+ export const ModelSelect = (props: any) => {
8
+ const [options, setOptions] = useState([]);
9
+ const api = useAPIClient();
10
+ const field = useField<Field>();
11
+ const form = useForm();
12
+
13
+ const llmService = form.values.llmService;
14
+
15
+ useEffect(() => {
16
+ let active = true;
17
+ if (!llmService) {
18
+ setOptions([]);
19
+ return;
20
+ }
21
+
22
+ api.resource('ai').listModels({ llmService }).then((res) => {
23
+ if (!active) return;
24
+ const data = res?.data?.data || [];
25
+ setOptions(
26
+ data.map((item: any) => ({
27
+ label: item.id || item.name,
28
+ value: item.id || item.name,
29
+ }))
30
+ );
31
+ }).catch(console.error);
32
+
33
+ return () => {
34
+ active = false;
35
+ };
36
+ }, [api, llmService]);
37
+
38
+ return <Select {...props} options={options} value={field.value} onChange={(v) => {
39
+ field.setValue(v);
40
+ }} disabled={!llmService} />;
41
+ };
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { Tag } from 'antd';
3
+ import { useField } from '@formily/react';
4
+
5
+ const colors = {
6
+ draft: 'default',
7
+ building: 'blue',
8
+ completed: 'success',
9
+ error: 'error',
10
+ };
11
+
12
+ export const StatusTag = (props: any) => {
13
+ const field = useField();
14
+ const value = props.value || (field as any).value;
15
+ if (!value) return null;
16
+ return <Tag color={colors[value] || 'default'}>{String(value).toUpperCase()}</Tag>;
17
+ };
@@ -0,0 +1 @@
1
+ export { default } from './plugin';
@@ -0,0 +1,47 @@
1
+ import { BlockModel } from '@nocobase/client';
2
+ import { escapeT } from '@nocobase/flow-engine';
3
+
4
+ export class UserGuideBlockModel extends BlockModel {}
5
+
6
+ UserGuideBlockModel.registerFlow({
7
+ key: 'userGuideBlockSettings',
8
+ title: escapeT('User guide block setting', { ns: 'build-guide-block' }),
9
+ steps: {
10
+ editUserGuide: {
11
+ title: escapeT('Edit user guide settings', { ns: 'build-guide-block' }),
12
+ uiSchema(ctx) {
13
+ const t = ctx.t;
14
+ return {
15
+ spaceId: {
16
+ title: t('Space'),
17
+ type: 'string',
18
+ 'x-decorator': 'FormItem',
19
+ 'x-component': 'RemoteSelect',
20
+ 'x-component-props': {
21
+ showSearch: true,
22
+ fieldNames: { label: 'title', value: 'id' },
23
+ service: {
24
+ resource: 'aiBuildGuideSpaces',
25
+ action: 'list',
26
+ params: {
27
+ filter: { status: 'completed' },
28
+ },
29
+ },
30
+ },
31
+ required: true,
32
+ },
33
+ };
34
+ },
35
+ async handler(ctx, params) {
36
+ const { spaceId } = params;
37
+ ctx.model.setProps({
38
+ spaceId,
39
+ });
40
+ },
41
+ },
42
+ },
43
+ });
44
+
45
+ UserGuideBlockModel.define({
46
+ label: escapeT('User Guide'),
47
+ });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { ModelConstructor } from '@nocobase/flow-engine';
11
+
12
+ export default {} as Record<string, ModelConstructor>;
@@ -0,0 +1,30 @@
1
+ import { Plugin } from '@nocobase/client';
2
+ import { UserGuideManager } from './UserGuideManager';
3
+ import { UserGuideBlockProvider } from './UserGuideBlockProvider';
4
+ import { UserGuideBlockInitializer } from './UserGuideBlockInitializer';
5
+ import { UserGuideBlockModel } from './models/UserGuideBlockModel';
6
+
7
+ export class PluginBuildGuideBlockClient extends Plugin {
8
+ async load() {
9
+ this.app.pluginSettingsManager.add('ai-build-guide', {
10
+ icon: 'ReadOutlined',
11
+ title: '{{t("Build Guide Block", { ns: "build-guide-block" })}}',
12
+ Component: UserGuideManager,
13
+ aclSnippet: 'pm.ai-build-guide',
14
+ });
15
+
16
+ this.app.use(UserGuideBlockProvider);
17
+
18
+ const blocksInit = this.app.schemaInitializerManager.get('page:addBlock');
19
+ blocksInit?.add('otherBlocks.aiUserGuide', {
20
+ title: '{{t("User Guide", { ns: "build-guide-block" })}}',
21
+ Component: 'UserGuideBlockInitializer',
22
+ });
23
+
24
+ this.flowEngine.registerModels({
25
+ UserGuideBlockModel,
26
+ });
27
+ }
28
+ }
29
+
30
+ export default PluginBuildGuideBlockClient;