@btst/stack 2.2.0 → 2.4.0
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.
- package/dist/packages/stack/src/client/components/compose.cjs +1 -2
- package/dist/packages/stack/src/client/components/compose.mjs +1 -2
- package/dist/packages/stack/src/plugins/ai-chat/api/page-tools.cjs +71 -0
- package/dist/packages/stack/src/plugins/ai-chat/api/page-tools.mjs +68 -0
- package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +54 -7
- package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +54 -7
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.cjs +2 -2
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.mjs +2 -2
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.cjs +89 -22
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.mjs +90 -23
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.cjs +110 -33
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.mjs +112 -35
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.cjs +1 -1
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.mjs +1 -1
- package/dist/packages/stack/src/plugins/ai-chat/schemas.cjs +17 -1
- package/dist/packages/stack/src/plugins/ai-chat/schemas.mjs +17 -1
- package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +52 -1
- package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +52 -1
- package/dist/packages/stack/src/plugins/blog/api/query-key-defs.cjs +18 -0
- package/dist/packages/stack/src/plugins/blog/api/query-key-defs.mjs +15 -0
- package/dist/packages/stack/src/plugins/blog/api/serializers.cjs +21 -0
- package/dist/packages/stack/src/plugins/blog/api/serializers.mjs +18 -0
- package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.cjs +15 -2
- package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.mjs +16 -3
- package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.cjs +24 -1
- package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.mjs +24 -1
- package/dist/packages/stack/src/plugins/blog/client/components/pages/fill-blog-form-handler.cjs +26 -0
- package/dist/packages/stack/src/plugins/blog/client/components/pages/fill-blog-form-handler.mjs +24 -0
- package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.cjs +30 -1
- package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.mjs +30 -1
- package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.cjs +18 -0
- package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.mjs +18 -0
- package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +15 -0
- package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +16 -1
- package/dist/packages/stack/src/plugins/cms/api/getters.cjs +10 -0
- package/dist/packages/stack/src/plugins/cms/api/getters.mjs +10 -1
- package/dist/packages/stack/src/plugins/cms/api/mutations.cjs +48 -0
- package/dist/packages/stack/src/plugins/cms/api/mutations.mjs +46 -0
- package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +75 -0
- package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +76 -1
- package/dist/packages/stack/src/plugins/cms/api/query-key-defs.cjs +29 -0
- package/dist/packages/stack/src/plugins/cms/api/query-key-defs.mjs +26 -0
- package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +15 -0
- package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +16 -1
- package/dist/packages/stack/src/plugins/form-builder/api/getters.cjs +9 -0
- package/dist/packages/stack/src/plugins/form-builder/api/getters.mjs +9 -1
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +62 -1
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +63 -2
- package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.cjs +37 -0
- package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.mjs +33 -0
- package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +15 -0
- package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +16 -1
- package/dist/packages/stack/src/plugins/kanban/api/mutations.cjs +91 -0
- package/dist/packages/stack/src/plugins/kanban/api/mutations.mjs +87 -0
- package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +34 -1
- package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +34 -1
- package/dist/packages/stack/src/plugins/kanban/api/query-key-defs.cjs +26 -0
- package/dist/packages/stack/src/plugins/kanban/api/query-key-defs.mjs +23 -0
- package/dist/packages/stack/src/plugins/kanban/api/serializers.cjs +30 -0
- package/dist/packages/stack/src/plugins/kanban/api/serializers.mjs +26 -0
- package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-hooks.cjs +7 -3
- package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-hooks.mjs +7 -3
- package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +10 -0
- package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +11 -1
- package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.cjs +89 -0
- package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.mjs +89 -0
- package/dist/packages/stack/src/plugins/utils.cjs +6 -0
- package/dist/packages/stack/src/plugins/utils.mjs +6 -1
- package/dist/plugins/ai-chat/api/index.d.cts +1 -1
- package/dist/plugins/ai-chat/api/index.d.mts +1 -1
- package/dist/plugins/ai-chat/api/index.d.ts +1 -1
- package/dist/plugins/ai-chat/client/components/index.d.cts +1 -1
- package/dist/plugins/ai-chat/client/components/index.d.mts +1 -1
- package/dist/plugins/ai-chat/client/components/index.d.ts +1 -1
- package/dist/plugins/ai-chat/client/context/page-ai-context.cjs +92 -0
- package/dist/plugins/ai-chat/client/context/page-ai-context.d.cts +84 -0
- package/dist/plugins/ai-chat/client/context/page-ai-context.d.mts +84 -0
- package/dist/plugins/ai-chat/client/context/page-ai-context.d.ts +84 -0
- package/dist/plugins/ai-chat/client/context/page-ai-context.mjs +88 -0
- package/dist/plugins/ai-chat/client/hooks/index.d.cts +1 -1
- package/dist/plugins/ai-chat/client/hooks/index.d.mts +1 -1
- package/dist/plugins/ai-chat/client/hooks/index.d.ts +1 -1
- package/dist/plugins/ai-chat/client/index.d.cts +2 -2
- package/dist/plugins/ai-chat/client/index.d.mts +2 -2
- package/dist/plugins/ai-chat/client/index.d.ts +2 -2
- package/dist/plugins/ai-chat/query-keys.d.cts +1 -1
- package/dist/plugins/ai-chat/query-keys.d.mts +1 -1
- package/dist/plugins/ai-chat/query-keys.d.ts +1 -1
- package/dist/plugins/blog/api/index.cjs +5 -0
- package/dist/plugins/blog/api/index.d.cts +19 -4
- package/dist/plugins/blog/api/index.d.mts +19 -4
- package/dist/plugins/blog/api/index.d.ts +19 -4
- package/dist/plugins/blog/api/index.mjs +2 -0
- package/dist/plugins/blog/client/hooks/index.d.cts +3 -3
- package/dist/plugins/blog/client/hooks/index.d.mts +3 -3
- package/dist/plugins/blog/client/hooks/index.d.ts +3 -3
- package/dist/plugins/blog/client/index.d.cts +1 -1
- package/dist/plugins/blog/client/index.d.mts +1 -1
- package/dist/plugins/blog/client/index.d.ts +1 -1
- package/dist/plugins/blog/query-keys.cjs +6 -5
- package/dist/plugins/blog/query-keys.d.cts +8 -387
- package/dist/plugins/blog/query-keys.d.mts +8 -387
- package/dist/plugins/blog/query-keys.d.ts +8 -387
- package/dist/plugins/blog/query-keys.mjs +6 -5
- package/dist/plugins/client/index.cjs +1 -0
- package/dist/plugins/client/index.d.cts +8 -1
- package/dist/plugins/client/index.d.mts +8 -1
- package/dist/plugins/client/index.d.ts +8 -1
- package/dist/plugins/client/index.mjs +1 -1
- package/dist/plugins/cms/api/index.cjs +8 -0
- package/dist/plugins/cms/api/index.d.cts +7 -219
- package/dist/plugins/cms/api/index.d.mts +7 -219
- package/dist/plugins/cms/api/index.d.ts +7 -219
- package/dist/plugins/cms/api/index.mjs +3 -1
- package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
- package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
- package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
- package/dist/plugins/cms/query-keys.cjs +2 -1
- package/dist/plugins/cms/query-keys.d.cts +5 -9
- package/dist/plugins/cms/query-keys.d.mts +5 -9
- package/dist/plugins/cms/query-keys.d.ts +5 -9
- package/dist/plugins/cms/query-keys.mjs +2 -1
- package/dist/plugins/form-builder/api/index.cjs +6 -0
- package/dist/plugins/form-builder/api/index.d.cts +7 -211
- package/dist/plugins/form-builder/api/index.d.mts +7 -211
- package/dist/plugins/form-builder/api/index.d.ts +7 -211
- package/dist/plugins/form-builder/api/index.mjs +2 -1
- package/dist/plugins/form-builder/client/components/index.d.cts +1 -1
- package/dist/plugins/form-builder/client/components/index.d.mts +1 -1
- package/dist/plugins/form-builder/client/components/index.d.ts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.cts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.mts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.ts +1 -1
- package/dist/plugins/form-builder/query-keys.cjs +3 -2
- package/dist/plugins/form-builder/query-keys.d.cts +6 -6
- package/dist/plugins/form-builder/query-keys.d.mts +6 -6
- package/dist/plugins/form-builder/query-keys.d.ts +6 -6
- package/dist/plugins/form-builder/query-keys.mjs +3 -2
- package/dist/plugins/kanban/api/index.cjs +10 -0
- package/dist/plugins/kanban/api/index.d.cts +17 -392
- package/dist/plugins/kanban/api/index.d.mts +17 -392
- package/dist/plugins/kanban/api/index.d.ts +17 -392
- package/dist/plugins/kanban/api/index.mjs +3 -0
- package/dist/plugins/kanban/client/components/index.d.cts +1 -1
- package/dist/plugins/kanban/client/components/index.d.mts +1 -1
- package/dist/plugins/kanban/client/components/index.d.ts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.cts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.mts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.ts +1 -1
- package/dist/plugins/kanban/client/index.d.cts +1 -1
- package/dist/plugins/kanban/client/index.d.mts +1 -1
- package/dist/plugins/kanban/client/index.d.ts +1 -1
- package/dist/plugins/kanban/query-keys.cjs +2 -9
- package/dist/plugins/kanban/query-keys.d.cts +4 -16
- package/dist/plugins/kanban/query-keys.d.mts +4 -16
- package/dist/plugins/kanban/query-keys.d.ts +4 -16
- package/dist/plugins/kanban/query-keys.mjs +2 -9
- package/dist/plugins/ui-builder/index.d.cts +1 -1
- package/dist/plugins/ui-builder/index.d.mts +1 -1
- package/dist/plugins/ui-builder/index.d.ts +1 -1
- package/dist/shared/stack.B7ONvlD_.d.mts +293 -0
- package/dist/shared/{stack.BeSm90va.d.ts → stack.BEn34wW6.d.ts} +60 -2
- package/dist/shared/stack.BUkC2EsZ.d.cts +327 -0
- package/dist/shared/{stack.DaOcgmrM.d.ts → stack.BV9hnvu4.d.cts} +31 -7
- package/dist/shared/{stack.DaOcgmrM.d.cts → stack.BV9hnvu4.d.mts} +31 -7
- package/dist/shared/{stack.DaOcgmrM.d.mts → stack.BV9hnvu4.d.ts} +31 -7
- package/dist/shared/stack.BepFXT3w.d.mts +500 -0
- package/dist/shared/stack.CL8ts1Mu.d.ts +419 -0
- package/dist/shared/{stack.CXjzTMsb.d.cts → stack.CVDTkMoO.d.cts} +7 -1
- package/dist/shared/{stack.CXjzTMsb.d.mts → stack.CVDTkMoO.d.mts} +7 -1
- package/dist/shared/{stack.CXjzTMsb.d.ts → stack.CVDTkMoO.d.ts} +7 -1
- package/dist/shared/stack.CczspVn2.d.mts +327 -0
- package/dist/shared/stack.CgWzG5jH.d.ts +500 -0
- package/dist/shared/stack.D3GB6wKv.d.cts +500 -0
- package/dist/shared/stack.DASmUVjX.d.ts +327 -0
- package/dist/shared/{stack.QD1y_7NY.d.cts → stack.DJaKVY7v.d.cts} +1 -1
- package/dist/shared/{stack.QD1y_7NY.d.mts → stack.DJaKVY7v.d.mts} +1 -1
- package/dist/shared/{stack.QD1y_7NY.d.ts → stack.DJaKVY7v.d.ts} +1 -1
- package/dist/shared/{stack.Dg09R0oB.d.mts → stack.DTDxgFj8.d.mts} +60 -2
- package/dist/shared/{stack.CMh_EdxW.d.cts → stack.DWoCZff7.d.cts} +60 -2
- package/dist/shared/{stack.CIrIsc-A.d.cts → stack.DdI5W6MB.d.cts} +7 -1
- package/dist/shared/{stack.CIrIsc-A.d.mts → stack.DdI5W6MB.d.mts} +7 -1
- package/dist/shared/{stack.CIrIsc-A.d.ts → stack.DdI5W6MB.d.ts} +7 -1
- package/dist/shared/stack.Dk5r4W1F.d.mts +419 -0
- package/dist/shared/stack.Kq2-QzOC.d.ts +293 -0
- package/dist/shared/stack.heOA9gzA.d.cts +419 -0
- package/dist/shared/stack.kcdnD4gA.d.cts +293 -0
- package/package.json +16 -3
- package/src/client/components/compose.tsx +7 -4
- package/src/plugins/ai-chat/api/page-tools.ts +111 -0
- package/src/plugins/ai-chat/api/plugin.ts +180 -9
- package/src/plugins/ai-chat/client/components/chat-input.tsx +2 -2
- package/src/plugins/ai-chat/client/components/chat-interface.tsx +154 -58
- package/src/plugins/ai-chat/client/components/chat-layout.tsx +166 -32
- package/src/plugins/ai-chat/client/components/chat-sidebar.tsx +1 -1
- package/src/plugins/ai-chat/client/context/page-ai-context.tsx +240 -0
- package/src/plugins/ai-chat/schemas.ts +16 -0
- package/src/plugins/blog/api/index.ts +2 -0
- package/src/plugins/blog/api/plugin.ts +85 -0
- package/src/plugins/blog/api/query-key-defs.ts +46 -0
- package/src/plugins/blog/api/serializers.ts +27 -0
- package/src/plugins/blog/client/components/forms/post-forms.tsx +29 -2
- package/src/plugins/blog/client/components/pages/edit-post-page.internal.tsx +28 -0
- package/src/plugins/blog/client/components/pages/fill-blog-form-handler.ts +38 -0
- package/src/plugins/blog/client/components/pages/new-post-page.internal.tsx +33 -1
- package/src/plugins/blog/client/components/pages/post-page.internal.tsx +20 -0
- package/src/plugins/blog/client/plugin.tsx +19 -0
- package/src/plugins/blog/query-keys.ts +5 -7
- package/src/plugins/client/index.ts +1 -1
- package/src/plugins/cms/api/getters.ts +24 -0
- package/src/plugins/cms/api/index.ts +14 -1
- package/src/plugins/cms/api/mutations.ts +84 -0
- package/src/plugins/cms/api/plugin.ts +114 -0
- package/src/plugins/cms/api/query-key-defs.ts +53 -0
- package/src/plugins/cms/api/serializers.ts +12 -0
- package/src/plugins/cms/client/plugin.tsx +19 -0
- package/src/plugins/cms/query-keys.ts +2 -1
- package/src/plugins/form-builder/api/getters.ts +23 -0
- package/src/plugins/form-builder/api/index.ts +15 -2
- package/src/plugins/form-builder/api/plugin.ts +91 -0
- package/src/plugins/form-builder/api/query-key-defs.ts +79 -0
- package/src/plugins/form-builder/api/serializers.ts +12 -0
- package/src/plugins/form-builder/client/plugin.tsx +19 -0
- package/src/plugins/form-builder/query-keys.ts +6 -2
- package/src/plugins/kanban/api/index.ts +9 -0
- package/src/plugins/kanban/api/mutations.ts +169 -0
- package/src/plugins/kanban/api/plugin.ts +61 -0
- package/src/plugins/kanban/api/query-key-defs.ts +54 -0
- package/src/plugins/kanban/api/serializers.ts +49 -0
- package/src/plugins/kanban/client/hooks/kanban-hooks.tsx +4 -0
- package/src/plugins/kanban/client/plugin.tsx +13 -0
- package/src/plugins/kanban/query-keys.ts +2 -9
- package/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.tsx +132 -0
- package/src/plugins/utils.ts +19 -0
- package/dist/shared/{stack.BkYlUT_8.d.cts → stack.BQmuNl5p.d.cts} +6 -6
- package/dist/shared/{stack.BkYlUT_8.d.mts → stack.BQmuNl5p.d.mts} +6 -6
- package/dist/shared/{stack.BkYlUT_8.d.ts → stack.BQmuNl5p.d.ts} +6 -6
|
@@ -6,7 +6,57 @@ const db = require('../db.cjs');
|
|
|
6
6
|
const utils = require('../utils.cjs');
|
|
7
7
|
const schemas = require('../schemas.cjs');
|
|
8
8
|
const getters = require('./getters.cjs');
|
|
9
|
+
const queryKeyDefs = require('./query-key-defs.cjs');
|
|
10
|
+
const serializers = require('./serializers.cjs');
|
|
9
11
|
|
|
12
|
+
function createBlogPrefetchForRoute(adapter) {
|
|
13
|
+
return async function prefetchForRoute(key, qc, params) {
|
|
14
|
+
switch (key) {
|
|
15
|
+
case "posts":
|
|
16
|
+
case "drafts": {
|
|
17
|
+
const published = key === "posts";
|
|
18
|
+
const [result, tags] = await Promise.all([
|
|
19
|
+
getters.getAllPosts(adapter, { published, limit: 10 }),
|
|
20
|
+
getters.getAllTags(adapter)
|
|
21
|
+
]);
|
|
22
|
+
qc.setQueryData(queryKeyDefs.BLOG_QUERY_KEYS.postsList({ published, limit: 10 }), {
|
|
23
|
+
pages: [result.items.map(serializers.serializePost)],
|
|
24
|
+
pageParams: [0]
|
|
25
|
+
});
|
|
26
|
+
qc.setQueryData(queryKeyDefs.BLOG_QUERY_KEYS.tagsList(), tags.map(serializers.serializeTag));
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
case "post":
|
|
30
|
+
case "editPost": {
|
|
31
|
+
const slug = params?.slug ?? "";
|
|
32
|
+
if (slug) {
|
|
33
|
+
const post = await getters.getPostBySlug(adapter, slug);
|
|
34
|
+
qc.setQueryData(
|
|
35
|
+
queryKeyDefs.BLOG_QUERY_KEYS.postDetail(slug),
|
|
36
|
+
post ? serializers.serializePost(post) : null
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case "tag": {
|
|
42
|
+
const tagSlug = params?.tagSlug ?? "";
|
|
43
|
+
const [result, tags] = await Promise.all([
|
|
44
|
+
getters.getAllPosts(adapter, { published: true, limit: 10, tagSlug }),
|
|
45
|
+
getters.getAllTags(adapter)
|
|
46
|
+
]);
|
|
47
|
+
qc.setQueryData(
|
|
48
|
+
queryKeyDefs.BLOG_QUERY_KEYS.postsList({ published: true, limit: 10, tagSlug }),
|
|
49
|
+
{
|
|
50
|
+
pages: [result.items.map(serializers.serializePost)],
|
|
51
|
+
pageParams: [0]
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
qc.setQueryData(queryKeyDefs.BLOG_QUERY_KEYS.tagsList(), tags.map(serializers.serializeTag));
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
10
60
|
const PostListQuerySchema = z.z.object({
|
|
11
61
|
slug: z.z.string().optional(),
|
|
12
62
|
tagSlug: z.z.string().optional(),
|
|
@@ -29,7 +79,8 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
29
79
|
api: (adapter) => ({
|
|
30
80
|
getAllPosts: (params) => getters.getAllPosts(adapter, params),
|
|
31
81
|
getPostBySlug: (slug) => getters.getPostBySlug(adapter, slug),
|
|
32
|
-
getAllTags: () => getters.getAllTags(adapter)
|
|
82
|
+
getAllTags: () => getters.getAllTags(adapter),
|
|
83
|
+
prefetchForRoute: createBlogPrefetchForRoute(adapter)
|
|
33
84
|
}),
|
|
34
85
|
routes: (adapter) => {
|
|
35
86
|
const findOrCreateTags = async (tagInputs) => {
|
|
@@ -4,7 +4,57 @@ import { blogSchema } from '../db.mjs';
|
|
|
4
4
|
import { slugify } from '../utils.mjs';
|
|
5
5
|
import { createPostSchema, updatePostSchema } from '../schemas.mjs';
|
|
6
6
|
import { getAllTags, getPostBySlug, getAllPosts } from './getters.mjs';
|
|
7
|
+
import { BLOG_QUERY_KEYS } from './query-key-defs.mjs';
|
|
8
|
+
import { serializePost, serializeTag } from './serializers.mjs';
|
|
7
9
|
|
|
10
|
+
function createBlogPrefetchForRoute(adapter) {
|
|
11
|
+
return async function prefetchForRoute(key, qc, params) {
|
|
12
|
+
switch (key) {
|
|
13
|
+
case "posts":
|
|
14
|
+
case "drafts": {
|
|
15
|
+
const published = key === "posts";
|
|
16
|
+
const [result, tags] = await Promise.all([
|
|
17
|
+
getAllPosts(adapter, { published, limit: 10 }),
|
|
18
|
+
getAllTags(adapter)
|
|
19
|
+
]);
|
|
20
|
+
qc.setQueryData(BLOG_QUERY_KEYS.postsList({ published, limit: 10 }), {
|
|
21
|
+
pages: [result.items.map(serializePost)],
|
|
22
|
+
pageParams: [0]
|
|
23
|
+
});
|
|
24
|
+
qc.setQueryData(BLOG_QUERY_KEYS.tagsList(), tags.map(serializeTag));
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
case "post":
|
|
28
|
+
case "editPost": {
|
|
29
|
+
const slug = params?.slug ?? "";
|
|
30
|
+
if (slug) {
|
|
31
|
+
const post = await getPostBySlug(adapter, slug);
|
|
32
|
+
qc.setQueryData(
|
|
33
|
+
BLOG_QUERY_KEYS.postDetail(slug),
|
|
34
|
+
post ? serializePost(post) : null
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
case "tag": {
|
|
40
|
+
const tagSlug = params?.tagSlug ?? "";
|
|
41
|
+
const [result, tags] = await Promise.all([
|
|
42
|
+
getAllPosts(adapter, { published: true, limit: 10, tagSlug }),
|
|
43
|
+
getAllTags(adapter)
|
|
44
|
+
]);
|
|
45
|
+
qc.setQueryData(
|
|
46
|
+
BLOG_QUERY_KEYS.postsList({ published: true, limit: 10, tagSlug }),
|
|
47
|
+
{
|
|
48
|
+
pages: [result.items.map(serializePost)],
|
|
49
|
+
pageParams: [0]
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
qc.setQueryData(BLOG_QUERY_KEYS.tagsList(), tags.map(serializeTag));
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
8
58
|
const PostListQuerySchema = z.object({
|
|
9
59
|
slug: z.string().optional(),
|
|
10
60
|
tagSlug: z.string().optional(),
|
|
@@ -27,7 +77,8 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
27
77
|
api: (adapter) => ({
|
|
28
78
|
getAllPosts: (params) => getAllPosts(adapter, params),
|
|
29
79
|
getPostBySlug: (slug) => getPostBySlug(adapter, slug),
|
|
30
|
-
getAllTags: () => getAllTags(adapter)
|
|
80
|
+
getAllTags: () => getAllTags(adapter),
|
|
81
|
+
prefetchForRoute: createBlogPrefetchForRoute(adapter)
|
|
31
82
|
}),
|
|
32
83
|
routes: (adapter) => {
|
|
33
84
|
const findOrCreateTags = async (tagInputs) => {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function postsListDiscriminator(params) {
|
|
4
|
+
return {
|
|
5
|
+
query: params.query !== void 0 && params.query.trim() === "" ? void 0 : params.query,
|
|
6
|
+
limit: params.limit ?? 10,
|
|
7
|
+
published: params.published,
|
|
8
|
+
tagSlug: params.tagSlug
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
const BLOG_QUERY_KEYS = {
|
|
12
|
+
postsList: (params) => ["posts", "list", postsListDiscriminator(params)],
|
|
13
|
+
postDetail: (slug) => ["posts", "detail", slug],
|
|
14
|
+
tagsList: () => ["tags", "list", "tags"]
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
exports.BLOG_QUERY_KEYS = BLOG_QUERY_KEYS;
|
|
18
|
+
exports.postsListDiscriminator = postsListDiscriminator;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function postsListDiscriminator(params) {
|
|
2
|
+
return {
|
|
3
|
+
query: params.query !== void 0 && params.query.trim() === "" ? void 0 : params.query,
|
|
4
|
+
limit: params.limit ?? 10,
|
|
5
|
+
published: params.published,
|
|
6
|
+
tagSlug: params.tagSlug
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
const BLOG_QUERY_KEYS = {
|
|
10
|
+
postsList: (params) => ["posts", "list", postsListDiscriminator(params)],
|
|
11
|
+
postDetail: (slug) => ["posts", "detail", slug],
|
|
12
|
+
tagsList: () => ["tags", "list", "tags"]
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { BLOG_QUERY_KEYS, postsListDiscriminator };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function serializeTag(tag) {
|
|
4
|
+
return {
|
|
5
|
+
...tag,
|
|
6
|
+
createdAt: tag.createdAt.toISOString(),
|
|
7
|
+
updatedAt: tag.updatedAt.toISOString()
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function serializePost(post) {
|
|
11
|
+
return {
|
|
12
|
+
...post,
|
|
13
|
+
createdAt: post.createdAt.toISOString(),
|
|
14
|
+
updatedAt: post.updatedAt.toISOString(),
|
|
15
|
+
publishedAt: post.publishedAt?.toISOString(),
|
|
16
|
+
tags: post.tags.map(serializeTag)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.serializePost = serializePost;
|
|
21
|
+
exports.serializeTag = serializeTag;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
function serializeTag(tag) {
|
|
2
|
+
return {
|
|
3
|
+
...tag,
|
|
4
|
+
createdAt: tag.createdAt.toISOString(),
|
|
5
|
+
updatedAt: tag.updatedAt.toISOString()
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function serializePost(post) {
|
|
9
|
+
return {
|
|
10
|
+
...post,
|
|
11
|
+
createdAt: post.createdAt.toISOString(),
|
|
12
|
+
updatedAt: post.updatedAt.toISOString(),
|
|
13
|
+
publishedAt: post.publishedAt?.toISOString(),
|
|
14
|
+
tags: post.tags.map(serializeTag)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { serializePost, serializeTag };
|
|
@@ -250,9 +250,14 @@ const CustomPostUpdateSchema = schemas.updatePostSchema.omit({
|
|
|
250
250
|
const addPostFormPropsAreEqual = (prevProps, nextProps) => {
|
|
251
251
|
if (prevProps.onClose !== nextProps.onClose) return false;
|
|
252
252
|
if (prevProps.onSuccess !== nextProps.onSuccess) return false;
|
|
253
|
+
if (prevProps.onFormReady !== nextProps.onFormReady) return false;
|
|
253
254
|
return true;
|
|
254
255
|
};
|
|
255
|
-
const AddPostFormComponent = ({
|
|
256
|
+
const AddPostFormComponent = ({
|
|
257
|
+
onClose,
|
|
258
|
+
onSuccess,
|
|
259
|
+
onFormReady
|
|
260
|
+
}) => {
|
|
256
261
|
const [featuredImageUploading, setFeaturedImageUploading] = React.useState(false);
|
|
257
262
|
const { localization } = context.usePluginOverrides("blog", {
|
|
258
263
|
localization: index.BLOG_LOCALIZATION
|
|
@@ -290,6 +295,9 @@ const AddPostFormComponent = ({ onClose, onSuccess }) => {
|
|
|
290
295
|
tags: []
|
|
291
296
|
}
|
|
292
297
|
});
|
|
298
|
+
React.useEffect(() => {
|
|
299
|
+
onFormReady?.(form);
|
|
300
|
+
}, []);
|
|
293
301
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
294
302
|
PostFormBody,
|
|
295
303
|
{
|
|
@@ -309,13 +317,15 @@ const editPostFormPropsAreEqual = (prevProps, nextProps) => {
|
|
|
309
317
|
if (prevProps.onClose !== nextProps.onClose) return false;
|
|
310
318
|
if (prevProps.onSuccess !== nextProps.onSuccess) return false;
|
|
311
319
|
if (prevProps.onDelete !== nextProps.onDelete) return false;
|
|
320
|
+
if (prevProps.onFormReady !== nextProps.onFormReady) return false;
|
|
312
321
|
return true;
|
|
313
322
|
};
|
|
314
323
|
const EditPostFormComponent = ({
|
|
315
324
|
postSlug,
|
|
316
325
|
onClose,
|
|
317
326
|
onSuccess,
|
|
318
|
-
onDelete
|
|
327
|
+
onDelete,
|
|
328
|
+
onFormReady
|
|
319
329
|
}) => {
|
|
320
330
|
const [featuredImageUploading, setFeaturedImageUploading] = React.useState(false);
|
|
321
331
|
const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);
|
|
@@ -391,6 +401,9 @@ const EditPostFormComponent = ({
|
|
|
391
401
|
},
|
|
392
402
|
values: initialData
|
|
393
403
|
});
|
|
404
|
+
React.useEffect(() => {
|
|
405
|
+
onFormReady?.(form);
|
|
406
|
+
}, []);
|
|
394
407
|
if (!post) {
|
|
395
408
|
return /* @__PURE__ */ jsxRuntime.jsx(emptyList.EmptyList, { message: localization.BLOG_PAGE_NOT_FOUND_DESCRIPTION });
|
|
396
409
|
}
|
|
@@ -11,7 +11,7 @@ import { slugify } from '../../../utils.mjs';
|
|
|
11
11
|
import { AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction } from '../../../../../../../ui/src/components/alert-dialog.mjs';
|
|
12
12
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
13
13
|
import { Loader2 } from 'lucide-react';
|
|
14
|
-
import { memo, useState, useMemo, Suspense, lazy } from 'react';
|
|
14
|
+
import { memo, useState, useEffect, useMemo, Suspense, lazy } from 'react';
|
|
15
15
|
import { useForm } from 'react-hook-form';
|
|
16
16
|
import { toast } from 'sonner';
|
|
17
17
|
import { FeaturedImageField } from './image-field.mjs';
|
|
@@ -248,9 +248,14 @@ const CustomPostUpdateSchema = updatePostSchema.omit({
|
|
|
248
248
|
const addPostFormPropsAreEqual = (prevProps, nextProps) => {
|
|
249
249
|
if (prevProps.onClose !== nextProps.onClose) return false;
|
|
250
250
|
if (prevProps.onSuccess !== nextProps.onSuccess) return false;
|
|
251
|
+
if (prevProps.onFormReady !== nextProps.onFormReady) return false;
|
|
251
252
|
return true;
|
|
252
253
|
};
|
|
253
|
-
const AddPostFormComponent = ({
|
|
254
|
+
const AddPostFormComponent = ({
|
|
255
|
+
onClose,
|
|
256
|
+
onSuccess,
|
|
257
|
+
onFormReady
|
|
258
|
+
}) => {
|
|
254
259
|
const [featuredImageUploading, setFeaturedImageUploading] = useState(false);
|
|
255
260
|
const { localization } = usePluginOverrides("blog", {
|
|
256
261
|
localization: BLOG_LOCALIZATION
|
|
@@ -288,6 +293,9 @@ const AddPostFormComponent = ({ onClose, onSuccess }) => {
|
|
|
288
293
|
tags: []
|
|
289
294
|
}
|
|
290
295
|
});
|
|
296
|
+
useEffect(() => {
|
|
297
|
+
onFormReady?.(form);
|
|
298
|
+
}, []);
|
|
291
299
|
return /* @__PURE__ */ jsx(
|
|
292
300
|
PostFormBody,
|
|
293
301
|
{
|
|
@@ -307,13 +315,15 @@ const editPostFormPropsAreEqual = (prevProps, nextProps) => {
|
|
|
307
315
|
if (prevProps.onClose !== nextProps.onClose) return false;
|
|
308
316
|
if (prevProps.onSuccess !== nextProps.onSuccess) return false;
|
|
309
317
|
if (prevProps.onDelete !== nextProps.onDelete) return false;
|
|
318
|
+
if (prevProps.onFormReady !== nextProps.onFormReady) return false;
|
|
310
319
|
return true;
|
|
311
320
|
};
|
|
312
321
|
const EditPostFormComponent = ({
|
|
313
322
|
postSlug,
|
|
314
323
|
onClose,
|
|
315
324
|
onSuccess,
|
|
316
|
-
onDelete
|
|
325
|
+
onDelete,
|
|
326
|
+
onFormReady
|
|
317
327
|
}) => {
|
|
318
328
|
const [featuredImageUploading, setFeaturedImageUploading] = useState(false);
|
|
319
329
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
|
@@ -389,6 +399,9 @@ const EditPostFormComponent = ({
|
|
|
389
399
|
},
|
|
390
400
|
values: initialData
|
|
391
401
|
});
|
|
402
|
+
useEffect(() => {
|
|
403
|
+
onFormReady?.(form);
|
|
404
|
+
}, []);
|
|
392
405
|
if (!post) {
|
|
393
406
|
return /* @__PURE__ */ jsx(EmptyList, { message: localization.BLOG_PAGE_NOT_FOUND_DESCRIPTION });
|
|
394
407
|
}
|
package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.cjs
CHANGED
|
@@ -8,6 +8,9 @@ const pageHeader = require('../shared/page-header.cjs');
|
|
|
8
8
|
const pageWrapper = require('../shared/page-wrapper.cjs');
|
|
9
9
|
const index = require('../../localization/index.cjs');
|
|
10
10
|
const useRouteLifecycle = require('../../../../../../../ui/src/hooks/use-route-lifecycle.cjs');
|
|
11
|
+
const context$1 = require('@btst/stack/plugins/ai-chat/client/context');
|
|
12
|
+
const React = require('react');
|
|
13
|
+
const fillBlogFormHandler = require('./fill-blog-form-handler.cjs');
|
|
11
14
|
|
|
12
15
|
function EditPostPage({ slug }) {
|
|
13
16
|
const overrides = context.usePluginOverrides("blog", {
|
|
@@ -30,6 +33,25 @@ function EditPostPage({ slug }) {
|
|
|
30
33
|
return true;
|
|
31
34
|
}
|
|
32
35
|
});
|
|
36
|
+
const formRef = React.useRef(null);
|
|
37
|
+
const handleFormReady = React.useCallback((form) => {
|
|
38
|
+
formRef.current = form;
|
|
39
|
+
}, []);
|
|
40
|
+
context$1.useRegisterPageAIContext({
|
|
41
|
+
routeName: "blog-edit-post",
|
|
42
|
+
pageDescription: `User is editing a blog post (slug: "${slug}") in the admin editor.`,
|
|
43
|
+
suggestions: [
|
|
44
|
+
"Improve this post's title",
|
|
45
|
+
"Rewrite the intro paragraph",
|
|
46
|
+
"Suggest better tags"
|
|
47
|
+
],
|
|
48
|
+
clientTools: {
|
|
49
|
+
fillBlogForm: fillBlogFormHandler.createFillBlogFormHandler(
|
|
50
|
+
formRef,
|
|
51
|
+
"Form updated successfully"
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
});
|
|
33
55
|
const handleClose = () => {
|
|
34
56
|
navigate(`${basePath}/blog`);
|
|
35
57
|
};
|
|
@@ -53,7 +75,8 @@ function EditPostPage({ slug }) {
|
|
|
53
75
|
postSlug: slug,
|
|
54
76
|
onClose: handleClose,
|
|
55
77
|
onSuccess: handleSuccess,
|
|
56
|
-
onDelete: handleDelete
|
|
78
|
+
onDelete: handleDelete,
|
|
79
|
+
onFormReady: handleFormReady
|
|
57
80
|
}
|
|
58
81
|
)
|
|
59
82
|
] });
|
package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.mjs
CHANGED
|
@@ -6,6 +6,9 @@ import { PageHeader } from '../shared/page-header.mjs';
|
|
|
6
6
|
import { PageWrapper } from '../shared/page-wrapper.mjs';
|
|
7
7
|
import { BLOG_LOCALIZATION } from '../../localization/index.mjs';
|
|
8
8
|
import { useRouteLifecycle } from '../../../../../../../ui/src/hooks/use-route-lifecycle.mjs';
|
|
9
|
+
import { useRegisterPageAIContext } from '@btst/stack/plugins/ai-chat/client/context';
|
|
10
|
+
import { useRef, useCallback } from 'react';
|
|
11
|
+
import { createFillBlogFormHandler } from './fill-blog-form-handler.mjs';
|
|
9
12
|
|
|
10
13
|
function EditPostPage({ slug }) {
|
|
11
14
|
const overrides = usePluginOverrides("blog", {
|
|
@@ -28,6 +31,25 @@ function EditPostPage({ slug }) {
|
|
|
28
31
|
return true;
|
|
29
32
|
}
|
|
30
33
|
});
|
|
34
|
+
const formRef = useRef(null);
|
|
35
|
+
const handleFormReady = useCallback((form) => {
|
|
36
|
+
formRef.current = form;
|
|
37
|
+
}, []);
|
|
38
|
+
useRegisterPageAIContext({
|
|
39
|
+
routeName: "blog-edit-post",
|
|
40
|
+
pageDescription: `User is editing a blog post (slug: "${slug}") in the admin editor.`,
|
|
41
|
+
suggestions: [
|
|
42
|
+
"Improve this post's title",
|
|
43
|
+
"Rewrite the intro paragraph",
|
|
44
|
+
"Suggest better tags"
|
|
45
|
+
],
|
|
46
|
+
clientTools: {
|
|
47
|
+
fillBlogForm: createFillBlogFormHandler(
|
|
48
|
+
formRef,
|
|
49
|
+
"Form updated successfully"
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
});
|
|
31
53
|
const handleClose = () => {
|
|
32
54
|
navigate(`${basePath}/blog`);
|
|
33
55
|
};
|
|
@@ -51,7 +73,8 @@ function EditPostPage({ slug }) {
|
|
|
51
73
|
postSlug: slug,
|
|
52
74
|
onClose: handleClose,
|
|
53
75
|
onSuccess: handleSuccess,
|
|
54
|
-
onDelete: handleDelete
|
|
76
|
+
onDelete: handleDelete,
|
|
77
|
+
onFormReady: handleFormReady
|
|
55
78
|
}
|
|
56
79
|
)
|
|
57
80
|
] });
|
package/dist/packages/stack/src/plugins/blog/client/components/pages/fill-blog-form-handler.cjs
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function createFillBlogFormHandler(formRef, successMessage) {
|
|
4
|
+
return async ({
|
|
5
|
+
title,
|
|
6
|
+
content,
|
|
7
|
+
excerpt,
|
|
8
|
+
tags
|
|
9
|
+
}) => {
|
|
10
|
+
const form = formRef.current;
|
|
11
|
+
if (!form) return { success: false, message: "Form not ready" };
|
|
12
|
+
if (title !== void 0)
|
|
13
|
+
form.setValue("title", title, { shouldValidate: true });
|
|
14
|
+
if (content !== void 0)
|
|
15
|
+
form.setValue("content", content, { shouldValidate: true });
|
|
16
|
+
if (excerpt !== void 0) form.setValue("excerpt", excerpt);
|
|
17
|
+
if (tags !== void 0)
|
|
18
|
+
form.setValue(
|
|
19
|
+
"tags",
|
|
20
|
+
tags.map((name) => ({ name }))
|
|
21
|
+
);
|
|
22
|
+
return { success: true, message: successMessage };
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
exports.createFillBlogFormHandler = createFillBlogFormHandler;
|
package/dist/packages/stack/src/plugins/blog/client/components/pages/fill-blog-form-handler.mjs
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
function createFillBlogFormHandler(formRef, successMessage) {
|
|
2
|
+
return async ({
|
|
3
|
+
title,
|
|
4
|
+
content,
|
|
5
|
+
excerpt,
|
|
6
|
+
tags
|
|
7
|
+
}) => {
|
|
8
|
+
const form = formRef.current;
|
|
9
|
+
if (!form) return { success: false, message: "Form not ready" };
|
|
10
|
+
if (title !== void 0)
|
|
11
|
+
form.setValue("title", title, { shouldValidate: true });
|
|
12
|
+
if (content !== void 0)
|
|
13
|
+
form.setValue("content", content, { shouldValidate: true });
|
|
14
|
+
if (excerpt !== void 0) form.setValue("excerpt", excerpt);
|
|
15
|
+
if (tags !== void 0)
|
|
16
|
+
form.setValue(
|
|
17
|
+
"tags",
|
|
18
|
+
tags.map((name) => ({ name }))
|
|
19
|
+
);
|
|
20
|
+
return { success: true, message: successMessage };
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { createFillBlogFormHandler };
|
package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.cjs
CHANGED
|
@@ -8,6 +8,9 @@ const pageHeader = require('../shared/page-header.cjs');
|
|
|
8
8
|
const pageWrapper = require('../shared/page-wrapper.cjs');
|
|
9
9
|
const index = require('../../localization/index.cjs');
|
|
10
10
|
const useRouteLifecycle = require('../../../../../../../ui/src/hooks/use-route-lifecycle.cjs');
|
|
11
|
+
const context$1 = require('@btst/stack/plugins/ai-chat/client/context');
|
|
12
|
+
const React = require('react');
|
|
13
|
+
const fillBlogFormHandler = require('./fill-blog-form-handler.cjs');
|
|
11
14
|
|
|
12
15
|
function NewPostPage() {
|
|
13
16
|
const overrides = context.usePluginOverrides("blog", {
|
|
@@ -29,6 +32,25 @@ function NewPostPage() {
|
|
|
29
32
|
return true;
|
|
30
33
|
}
|
|
31
34
|
});
|
|
35
|
+
const formRef = React.useRef(null);
|
|
36
|
+
const handleFormReady = React.useCallback((form) => {
|
|
37
|
+
formRef.current = form;
|
|
38
|
+
}, []);
|
|
39
|
+
context$1.useRegisterPageAIContext({
|
|
40
|
+
routeName: "blog-new-post",
|
|
41
|
+
pageDescription: "User is creating a new blog post in the admin editor. IMPORTANT: When asked to write, draft, or create a blog post, you MUST call the fillBlogForm tool to populate the form fields directly \u2014 do NOT just output the text in your response.",
|
|
42
|
+
suggestions: [
|
|
43
|
+
"Write a post about AI trends",
|
|
44
|
+
"Draft an intro paragraph",
|
|
45
|
+
"Suggest 5 tags for this post"
|
|
46
|
+
],
|
|
47
|
+
clientTools: {
|
|
48
|
+
fillBlogForm: fillBlogFormHandler.createFillBlogFormHandler(
|
|
49
|
+
formRef,
|
|
50
|
+
"Form filled successfully"
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
});
|
|
32
54
|
const handleClose = () => {
|
|
33
55
|
navigate(`${basePath}/blog`);
|
|
34
56
|
};
|
|
@@ -47,7 +69,14 @@ function NewPostPage() {
|
|
|
47
69
|
description: localization.BLOG_POST_ADD_DESCRIPTION
|
|
48
70
|
}
|
|
49
71
|
),
|
|
50
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
72
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
73
|
+
postForms.AddPostForm,
|
|
74
|
+
{
|
|
75
|
+
onClose: handleClose,
|
|
76
|
+
onSuccess: handleSuccess,
|
|
77
|
+
onFormReady: handleFormReady
|
|
78
|
+
}
|
|
79
|
+
)
|
|
51
80
|
] });
|
|
52
81
|
}
|
|
53
82
|
|
package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.mjs
CHANGED
|
@@ -6,6 +6,9 @@ import { PageHeader } from '../shared/page-header.mjs';
|
|
|
6
6
|
import { PageWrapper } from '../shared/page-wrapper.mjs';
|
|
7
7
|
import { BLOG_LOCALIZATION } from '../../localization/index.mjs';
|
|
8
8
|
import { useRouteLifecycle } from '../../../../../../../ui/src/hooks/use-route-lifecycle.mjs';
|
|
9
|
+
import { useRegisterPageAIContext } from '@btst/stack/plugins/ai-chat/client/context';
|
|
10
|
+
import { useRef, useCallback } from 'react';
|
|
11
|
+
import { createFillBlogFormHandler } from './fill-blog-form-handler.mjs';
|
|
9
12
|
|
|
10
13
|
function NewPostPage() {
|
|
11
14
|
const overrides = usePluginOverrides("blog", {
|
|
@@ -27,6 +30,25 @@ function NewPostPage() {
|
|
|
27
30
|
return true;
|
|
28
31
|
}
|
|
29
32
|
});
|
|
33
|
+
const formRef = useRef(null);
|
|
34
|
+
const handleFormReady = useCallback((form) => {
|
|
35
|
+
formRef.current = form;
|
|
36
|
+
}, []);
|
|
37
|
+
useRegisterPageAIContext({
|
|
38
|
+
routeName: "blog-new-post",
|
|
39
|
+
pageDescription: "User is creating a new blog post in the admin editor. IMPORTANT: When asked to write, draft, or create a blog post, you MUST call the fillBlogForm tool to populate the form fields directly \u2014 do NOT just output the text in your response.",
|
|
40
|
+
suggestions: [
|
|
41
|
+
"Write a post about AI trends",
|
|
42
|
+
"Draft an intro paragraph",
|
|
43
|
+
"Suggest 5 tags for this post"
|
|
44
|
+
],
|
|
45
|
+
clientTools: {
|
|
46
|
+
fillBlogForm: createFillBlogFormHandler(
|
|
47
|
+
formRef,
|
|
48
|
+
"Form filled successfully"
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
});
|
|
30
52
|
const handleClose = () => {
|
|
31
53
|
navigate(`${basePath}/blog`);
|
|
32
54
|
};
|
|
@@ -45,7 +67,14 @@ function NewPostPage() {
|
|
|
45
67
|
description: localization.BLOG_POST_ADD_DESCRIPTION
|
|
46
68
|
}
|
|
47
69
|
),
|
|
48
|
-
/* @__PURE__ */ jsx(
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
AddPostForm,
|
|
72
|
+
{
|
|
73
|
+
onClose: handleClose,
|
|
74
|
+
onSuccess: handleSuccess,
|
|
75
|
+
onFormReady: handleFormReady
|
|
76
|
+
}
|
|
77
|
+
)
|
|
49
78
|
] });
|
|
50
79
|
}
|
|
51
80
|
|
|
@@ -16,6 +16,7 @@ const recentPostsCarousel = require('../shared/recent-posts-carousel.cjs');
|
|
|
16
16
|
const badge = require('../../../../../../../ui/src/components/badge.cjs');
|
|
17
17
|
const useRouteLifecycle = require('../../../../../../../ui/src/hooks/use-route-lifecycle.cjs');
|
|
18
18
|
const onThisPage = require('../shared/on-this-page.cjs');
|
|
19
|
+
const context$1 = require('@btst/stack/plugins/ai-chat/client/context');
|
|
19
20
|
|
|
20
21
|
function PostPage({ slug }) {
|
|
21
22
|
const overrides = context.usePluginOverrides("blog", {
|
|
@@ -50,6 +51,23 @@ function PostPage({ slug }) {
|
|
|
50
51
|
excludeSlug: slug,
|
|
51
52
|
enabled: !!post
|
|
52
53
|
});
|
|
54
|
+
context$1.useRegisterPageAIContext(
|
|
55
|
+
post ? {
|
|
56
|
+
routeName: "blog-post",
|
|
57
|
+
pageDescription: `Blog post: "${post.title}"
|
|
58
|
+
Author: ${post.authorId ?? "Unknown"}
|
|
59
|
+
|
|
60
|
+
${post.content ?? ""}`.slice(
|
|
61
|
+
0,
|
|
62
|
+
16e3
|
|
63
|
+
),
|
|
64
|
+
suggestions: [
|
|
65
|
+
"Summarize this post",
|
|
66
|
+
"What are the key takeaways?",
|
|
67
|
+
"Explain this in simpler terms"
|
|
68
|
+
]
|
|
69
|
+
} : null
|
|
70
|
+
);
|
|
53
71
|
if (!slug || !post) {
|
|
54
72
|
return /* @__PURE__ */ jsxRuntime.jsx(pageWrapper.PageWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(emptyList.EmptyList, { message: localization.BLOG_PAGE_NOT_FOUND_DESCRIPTION }) });
|
|
55
73
|
}
|
|
@@ -14,6 +14,7 @@ import { RecentPostsCarousel } from '../shared/recent-posts-carousel.mjs';
|
|
|
14
14
|
import { Badge } from '../../../../../../../ui/src/components/badge.mjs';
|
|
15
15
|
import { useRouteLifecycle } from '../../../../../../../ui/src/hooks/use-route-lifecycle.mjs';
|
|
16
16
|
import { OnThisPageSelect, OnThisPage } from '../shared/on-this-page.mjs';
|
|
17
|
+
import { useRegisterPageAIContext } from '@btst/stack/plugins/ai-chat/client/context';
|
|
17
18
|
|
|
18
19
|
function PostPage({ slug }) {
|
|
19
20
|
const overrides = usePluginOverrides("blog", {
|
|
@@ -48,6 +49,23 @@ function PostPage({ slug }) {
|
|
|
48
49
|
excludeSlug: slug,
|
|
49
50
|
enabled: !!post
|
|
50
51
|
});
|
|
52
|
+
useRegisterPageAIContext(
|
|
53
|
+
post ? {
|
|
54
|
+
routeName: "blog-post",
|
|
55
|
+
pageDescription: `Blog post: "${post.title}"
|
|
56
|
+
Author: ${post.authorId ?? "Unknown"}
|
|
57
|
+
|
|
58
|
+
${post.content ?? ""}`.slice(
|
|
59
|
+
0,
|
|
60
|
+
16e3
|
|
61
|
+
),
|
|
62
|
+
suggestions: [
|
|
63
|
+
"Summarize this post",
|
|
64
|
+
"What are the key takeaways?",
|
|
65
|
+
"Explain this in simpler terms"
|
|
66
|
+
]
|
|
67
|
+
} : null
|
|
68
|
+
);
|
|
51
69
|
if (!slug || !post) {
|
|
52
70
|
return /* @__PURE__ */ jsx(PageWrapper, { children: /* @__PURE__ */ jsx(EmptyList, { message: localization.BLOG_PAGE_NOT_FOUND_DESCRIPTION }) });
|
|
53
71
|
}
|
|
@@ -64,6 +64,11 @@ function createPostsLoader(published, config) {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
} catch (error) {
|
|
67
|
+
if (client.isConnectionError(error)) {
|
|
68
|
+
console.warn(
|
|
69
|
+
"[btst/blog] route.loader() failed \u2014 no server running at build time. Use myStack.api.blog.prefetchForRoute() for SSG data prefetching."
|
|
70
|
+
);
|
|
71
|
+
}
|
|
67
72
|
if (hooks?.onLoadError) {
|
|
68
73
|
await hooks.onLoadError(error, context);
|
|
69
74
|
}
|
|
@@ -112,6 +117,11 @@ function createPostLoader(slug, config, path) {
|
|
|
112
117
|
}
|
|
113
118
|
}
|
|
114
119
|
} catch (error) {
|
|
120
|
+
if (client.isConnectionError(error)) {
|
|
121
|
+
console.warn(
|
|
122
|
+
"[btst/blog] route.loader() failed \u2014 no server running at build time. Use myStack.api.blog.prefetchForRoute() for SSG data prefetching."
|
|
123
|
+
);
|
|
124
|
+
}
|
|
115
125
|
if (hooks?.onLoadError) {
|
|
116
126
|
await hooks.onLoadError(error, context);
|
|
117
127
|
}
|
|
@@ -190,6 +200,11 @@ function createTagLoader(tagSlug, config) {
|
|
|
190
200
|
await hooks.onLoadError(error, context);
|
|
191
201
|
}
|
|
192
202
|
} catch (error) {
|
|
203
|
+
if (client.isConnectionError(error)) {
|
|
204
|
+
console.warn(
|
|
205
|
+
"[btst/blog] route.loader() failed \u2014 no server running at build time. Use myStack.api.blog.prefetchForRoute() for SSG data prefetching."
|
|
206
|
+
);
|
|
207
|
+
}
|
|
193
208
|
if (hooks?.onLoadError) {
|
|
194
209
|
await hooks.onLoadError(error, context);
|
|
195
210
|
}
|