@strapi/content-type-builder 5.54.0 → 5.55.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/admin/components/AIChat/hooks/useAIFetch.js +6 -2
- package/dist/admin/components/AIChat/hooks/useAIFetch.js.map +1 -1
- package/dist/admin/components/AIChat/hooks/useAIFetch.mjs +7 -3
- package/dist/admin/components/AIChat/hooks/useAIFetch.mjs.map +1 -1
- package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.js +20 -0
- package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.js.map +1 -0
- package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.mjs +18 -0
- package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.mjs.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.js +83 -59
- package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.js.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.mjs +86 -62
- package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.mjs.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.js +112 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.js.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.mjs +110 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.mjs.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.js +159 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.js.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.mjs +157 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.mjs.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.js +311 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.js.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.mjs +309 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.mjs.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.js +379 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.js.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.mjs +376 -0
- package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.mjs.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.js +172 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.js.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.mjs +166 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.mjs.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.js +62 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.js.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.mjs +60 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.mjs.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.js +145 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.js.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.mjs +143 -0
- package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.mjs.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.js +176 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.js.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.mjs +169 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.mjs.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.js +277 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.js.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.mjs +273 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.mjs.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.js +62 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.js.map +1 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.mjs +58 -0
- package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.mjs.map +1 -0
- package/dist/admin/components/DataManager/DataManagerContext.js.map +1 -1
- package/dist/admin/components/DataManager/DataManagerContext.mjs.map +1 -1
- package/dist/admin/components/DataManager/DataManagerProvider.js +70 -8
- package/dist/admin/components/DataManager/DataManagerProvider.js.map +1 -1
- package/dist/admin/components/DataManager/DataManagerProvider.mjs +70 -8
- package/dist/admin/components/DataManager/DataManagerProvider.mjs.map +1 -1
- package/dist/admin/components/DataManager/reducer.js +411 -33
- package/dist/admin/components/DataManager/reducer.js.map +1 -1
- package/dist/admin/components/DataManager/reducer.mjs +411 -33
- package/dist/admin/components/DataManager/reducer.mjs.map +1 -1
- package/dist/admin/components/DataManager/utils/cleanData.js +11 -2
- package/dist/admin/components/DataManager/utils/cleanData.js.map +1 -1
- package/dist/admin/components/DataManager/utils/cleanData.mjs +11 -2
- package/dist/admin/components/DataManager/utils/cleanData.mjs.map +1 -1
- package/dist/admin/components/DataManager/utils/contentStructure.js +150 -0
- package/dist/admin/components/DataManager/utils/contentStructure.js.map +1 -0
- package/dist/admin/components/DataManager/utils/contentStructure.mjs +133 -0
- package/dist/admin/components/DataManager/utils/contentStructure.mjs.map +1 -0
- package/dist/admin/components/FolderSelect.js +200 -0
- package/dist/admin/components/FolderSelect.js.map +1 -0
- package/dist/admin/components/FolderSelect.mjs +198 -0
- package/dist/admin/components/FolderSelect.mjs.map +1 -0
- package/dist/admin/components/FormModal/FormModal.js +23 -2
- package/dist/admin/components/FormModal/FormModal.js.map +1 -1
- package/dist/admin/components/FormModal/FormModal.mjs +23 -2
- package/dist/admin/components/FormModal/FormModal.mjs.map +1 -1
- package/dist/admin/components/FormModal/contentType/contentTypeForm.js +15 -18
- package/dist/admin/components/FormModal/contentType/contentTypeForm.js.map +1 -1
- package/dist/admin/components/FormModal/contentType/contentTypeForm.mjs +15 -18
- package/dist/admin/components/FormModal/contentType/contentTypeForm.mjs.map +1 -1
- package/dist/admin/components/FormModal/reducer.js +6 -0
- package/dist/admin/components/FormModal/reducer.js.map +1 -1
- package/dist/admin/components/FormModal/reducer.mjs +6 -0
- package/dist/admin/components/FormModal/reducer.mjs.map +1 -1
- package/dist/admin/pages/App/index.js +2 -5
- package/dist/admin/pages/App/index.js.map +1 -1
- package/dist/admin/pages/App/index.mjs +2 -5
- package/dist/admin/pages/App/index.mjs.map +1 -1
- package/dist/admin/src/components/AIChat/hooks/usePrefetchAIToken.d.ts +1 -0
- package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.d.ts +16 -0
- package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.d.ts +12 -0
- package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.d.ts +14 -0
- package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.d.ts +38 -0
- package/dist/admin/src/components/ContentTypeBuilderNav/{useContentTypeBuilderMenu.d.ts → hooks/useContentTypeBuilderMenu.d.ts} +17 -7
- package/dist/admin/src/components/ContentTypeBuilderNav/hooks/useFolderActions.d.ts +42 -0
- package/dist/admin/src/components/ContentTypeBuilderNav/hooks/useSortableTree.d.ts +53 -0
- package/dist/admin/src/components/ContentTypeBuilderNav/lib/buildFolderTree.d.ts +42 -0
- package/dist/admin/src/components/ContentTypeBuilderNav/lib/dropProjection.d.ts +58 -0
- package/dist/admin/src/components/ContentTypeBuilderNav/lib/flatModel.d.ts +18 -0
- package/dist/admin/src/components/DataManager/DataManagerContext.d.ts +41 -0
- package/dist/admin/src/components/DataManager/reducer.d.ts +105 -1
- package/dist/admin/src/components/DataManager/utils/cleanData.d.ts +5 -1
- package/dist/admin/src/components/DataManager/utils/contentStructure.d.ts +68 -0
- package/dist/admin/src/components/FolderSelect.d.ts +18 -0
- package/dist/admin/src/components/FormModal/contentType/contentTypeForm.d.ts +0 -21
- package/dist/admin/src/components/FormModal/forms/forms.d.ts +0 -10
- package/dist/admin/src/components/FormModal/reducer.d.ts +7 -0
- package/dist/admin/src/utils/folderTelemetry.d.ts +5 -0
- package/dist/admin/translations/en.json.js +23 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +23 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/utils/folderTelemetry.js +19 -0
- package/dist/admin/utils/folderTelemetry.js.map +1 -0
- package/dist/admin/utils/folderTelemetry.mjs +16 -0
- package/dist/admin/utils/folderTelemetry.mjs.map +1 -0
- package/dist/server/controllers/schema.js +1 -1
- package/dist/server/controllers/schema.js.map +1 -1
- package/dist/server/controllers/schema.mjs +1 -1
- package/dist/server/controllers/schema.mjs.map +1 -1
- package/dist/server/controllers/validation/common.js +3 -0
- package/dist/server/controllers/validation/common.js.map +1 -1
- package/dist/server/controllers/validation/common.mjs +3 -1
- package/dist/server/controllers/validation/common.mjs.map +1 -1
- package/dist/server/controllers/validation/content-structure.js +177 -0
- package/dist/server/controllers/validation/content-structure.js.map +1 -0
- package/dist/server/controllers/validation/content-structure.mjs +173 -0
- package/dist/server/controllers/validation/content-structure.mjs.map +1 -0
- package/dist/server/controllers/validation/schema.js +3 -1
- package/dist/server/controllers/validation/schema.js.map +1 -1
- package/dist/server/controllers/validation/schema.mjs +3 -1
- package/dist/server/controllers/validation/schema.mjs.map +1 -1
- package/dist/server/register.js +1 -1
- package/dist/server/register.js.map +1 -1
- package/dist/server/register.mjs +1 -1
- package/dist/server/register.mjs.map +1 -1
- package/dist/server/routes/content-api.js +4 -4
- package/dist/server/routes/content-api.js.map +1 -1
- package/dist/server/routes/content-api.mjs +4 -4
- package/dist/server/routes/content-api.mjs.map +1 -1
- package/dist/server/services/api-handler.js +37 -4
- package/dist/server/services/api-handler.js.map +1 -1
- package/dist/server/services/api-handler.mjs +36 -5
- package/dist/server/services/api-handler.mjs.map +1 -1
- package/dist/server/services/content-structure.js +174 -0
- package/dist/server/services/content-structure.js.map +1 -0
- package/dist/server/services/content-structure.mjs +172 -0
- package/dist/server/services/content-structure.mjs.map +1 -0
- package/dist/server/services/content-types.js +196 -44
- package/dist/server/services/content-types.js.map +1 -1
- package/dist/server/services/content-types.mjs +195 -45
- package/dist/server/services/content-types.mjs.map +1 -1
- package/dist/server/services/index.js +3 -1
- package/dist/server/services/index.js.map +1 -1
- package/dist/server/services/index.mjs +3 -1
- package/dist/server/services/index.mjs.map +1 -1
- package/dist/server/services/schema-builder/index.js +4 -2
- package/dist/server/services/schema-builder/index.js.map +1 -1
- package/dist/server/services/schema-builder/index.mjs +4 -2
- package/dist/server/services/schema-builder/index.mjs.map +1 -1
- package/dist/server/services/schema-builder/schema-handler.js +16 -16
- package/dist/server/services/schema-builder/schema-handler.js.map +1 -1
- package/dist/server/services/schema-builder/schema-handler.mjs +16 -16
- package/dist/server/services/schema-builder/schema-handler.mjs.map +1 -1
- package/dist/server/services/schema-mutation.js +46 -0
- package/dist/server/services/schema-mutation.js.map +1 -0
- package/dist/server/services/schema-mutation.mjs +43 -0
- package/dist/server/services/schema-mutation.mjs.map +1 -0
- package/dist/server/services/schema.js +134 -79
- package/dist/server/services/schema.js.map +1 -1
- package/dist/server/services/schema.mjs +135 -80
- package/dist/server/services/schema.mjs.map +1 -1
- package/dist/server/src/controllers/schema.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/common.d.ts +1 -0
- package/dist/server/src/controllers/validation/common.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/content-structure.d.ts +56 -0
- package/dist/server/src/controllers/validation/content-structure.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/schema.d.ts +35 -0
- package/dist/server/src/controllers/validation/schema.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +3 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/routes/content-api.d.ts.map +1 -1
- package/dist/server/src/services/api-handler.d.ts +13 -1
- package/dist/server/src/services/api-handler.d.ts.map +1 -1
- package/dist/server/src/services/content-structure.d.ts +37 -0
- package/dist/server/src/services/content-structure.d.ts.map +1 -0
- package/dist/server/src/services/content-types.d.ts +4 -0
- package/dist/server/src/services/content-types.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -0
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/schema-builder/index.d.ts +3 -1
- package/dist/server/src/services/schema-builder/index.d.ts.map +1 -1
- package/dist/server/src/services/schema-builder/schema-handler.d.ts.map +1 -1
- package/dist/server/src/services/schema-mutation.d.ts +26 -0
- package/dist/server/src/services/schema-mutation.d.ts.map +1 -0
- package/dist/server/src/services/schema.d.ts +1 -0
- package/dist/server/src/services/schema.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/server/utils/index.js.map +1 -1
- package/dist/server/utils/index.mjs.map +1 -1
- package/package.json +6 -6
- package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.js +0 -157
- package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.js.map +0 -1
- package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.mjs +0 -151
- package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.mjs.map +0 -1
|
@@ -22,8 +22,10 @@ const CHAT_TOO_LONG_ERROR = 'Chat too long';
|
|
|
22
22
|
const strapiVersion = strapiAdmin.useAppInfo('useAIFetch', (state)=>state.strapiVersion);
|
|
23
23
|
const projectId = strapiAdmin.useAppInfo('useAIFetch', (state)=>state.projectId);
|
|
24
24
|
const userId = strapiAdmin.useAppInfo('useAIFetch-user', (state)=>state.userId);
|
|
25
|
+
const isAiAvailable = ee.useAIAvailability();
|
|
25
26
|
const aiUsage = ee.useGetAiUsageQuery(undefined, {
|
|
26
|
-
refetchOnMountOrArgChange: true
|
|
27
|
+
refetchOnMountOrArgChange: true,
|
|
28
|
+
skip: !isAiAvailable
|
|
27
29
|
});
|
|
28
30
|
const [isPending, setIsPending] = React.useState(false);
|
|
29
31
|
const [error, setError] = React.useState(null);
|
|
@@ -49,7 +51,9 @@ const CHAT_TOO_LONG_ERROR = 'Chat too long';
|
|
|
49
51
|
}
|
|
50
52
|
});
|
|
51
53
|
// refetch ai usage data on every successful request
|
|
52
|
-
|
|
54
|
+
if (isAiAvailable) {
|
|
55
|
+
aiUsage.refetch();
|
|
56
|
+
}
|
|
53
57
|
const body = await aiClient.safeParseJson(response);
|
|
54
58
|
if (!response.ok) {
|
|
55
59
|
throw new Error(`Error: ${response.statusText}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAIFetch.js","sources":["../../../../../admin/src/components/AIChat/hooks/useAIFetch.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-namespace */\n\n/**\n * In charge of fetching data from Strapi AI endpoints\n */\n\nimport { useState } from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAppInfo } from '@strapi/admin/strapi-admin';\nimport { useGetAiUsageQuery } from '@strapi/admin/strapi-admin/ee';\nimport { DefaultChatTransport } from 'ai';\n\nimport { fetchAI, makeChatFetch, safeParseJson } from '../lib/aiClient';\nimport { STRAPI_AI_CHAT_URL, STRAPI_AI_URL } from '../lib/constants';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Chat title\n */\nexport namespace GenerateTitle {\n export interface Request {\n body: {\n chatId: string;\n message: string;\n };\n }\n export interface Response {\n data: {\n title: string;\n };\n error?: string;\n }\n}\n\n/**\n * Upload a project to the chat\n */\nexport namespace UploadProject {\n export interface Request {\n body: {\n chatId: string;\n name: string;\n type: 'code';\n files: {\n path: string;\n content: string;\n }[];\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Send chat feedback\n */\nexport type FeedbackReasonIds =\n | 'invalid_schema'\n | 'bad_recommendation'\n | 'slow'\n | 'instructions_ignored'\n | 'being_lazy'\n | 'other';\n\nnamespace SendFeedback {\n export interface Request {\n body: {\n chatId: string;\n type: 'upvote' | 'downvote';\n feedback?: string;\n reasons?: FeedbackReasonIds[];\n messageId: string;\n messages: UIMessage[];\n schemas: Schema[];\n };\n }\n}\n\n/**\n * Upload media\n */\nexport namespace UploadMedia {\n export interface Request {\n body: {\n url: string; // base64 image\n filename: string;\n chatId: string;\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Collection of API endpoints and their corresponding request/response types\n */\ntype AIEndpoints = {\n '/schemas/chat/generate-title': {\n request: GenerateTitle.Request;\n response: GenerateTitle.Response;\n };\n '/schemas/chat/attachment': {\n request: UploadProject.Request;\n response: UploadProject.Response;\n };\n '/schemas/chat/feedback': {\n request: SendFeedback.Request;\n response: void;\n };\n '/media/upload': {\n request: UploadMedia.Request;\n response: UploadMedia.Response;\n };\n};\n\n// Helper type to extract the request type for a given endpoint\ntype RequestType<T extends keyof AIEndpoints> = AIEndpoints[T]['request'];\n\n// Helper type to extract the response type for a given endpoint\ntype ResponseType<T extends keyof AIEndpoints> = AIEndpoints[T]['response'];\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\nexport const TOO_MANY_REQUESTS_ERROR = 'Too many requests';\nexport const LICENSE_LIMIT_REACHED_ERROR = 'License limit';\nexport const LICENSE_LIMIT_EXCEEDED_ERROR = 'AI credit limit exceeded';\nexport const CHAT_TOO_LONG_ERROR = 'Chat too long';\nexport const ATTACHMENT_TOO_BIG_ERROR = 'Attachment too big';\nexport const ATTACHMENT_NOT_FOUND_ERROR = 'Attachment not found';\nexport const INVALID_REQUEST_ERROR = 'Invalid request';\n\n/**\n * Base hook factory for making type-safe API calls to Strapi AI endpoints.\n * Creates a hook specific to a single endpoint.\n */\nexport const createAIFetchHook = <T extends keyof AIEndpoints>(endpoint: T) => {\n return () => {\n const strapiVersion = useAppInfo('useAIFetch', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIFetch-user', (state) => state.userId);\n const aiUsage = useGetAiUsageQuery(undefined, { refetchOnMountOrArgChange: true });\n\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * Make a type-safe API call to the specified Strapi AI endpoint with retry logic\n */\n const fetchData = async (\n options: Omit<RequestInit, 'body'> & Partial<RequestType<T>> & { formData?: FormData } = {}\n ): Promise<ResponseType<T> | null> => {\n setIsPending(true);\n setError(null);\n\n try {\n const fullUrl = `${STRAPI_AI_URL}${endpoint}`;\n const isJson = !!options.body && !options.formData;\n\n const response = await fetchAI(fullUrl, {\n method: 'POST',\n headers: isJson\n ? { 'Content-Type': 'application/json', ...options.headers }\n : options.headers,\n body: options.formData\n ? options.formData\n : isJson\n ? JSON.stringify(options.body || {})\n : undefined,\n ctx: { strapiVersion, projectId, userId },\n });\n // refetch ai usage data on every successful request\n aiUsage.refetch();\n\n const body = await safeParseJson(response);\n\n if (!response.ok) {\n throw new Error(`Error: ${response.statusText}`);\n }\n return body as ResponseType<T>;\n } catch (err) {\n setError(err instanceof Error ? err.message : `Failed to fetch data from ${endpoint}`);\n return null;\n } finally {\n setIsPending(false);\n }\n };\n\n return {\n isPending,\n error,\n fetch: fetchData,\n };\n };\n};\n\n// Create specific hooks for each endpoint\nexport const useFetchGenerateTitle = createAIFetchHook('/schemas/chat/generate-title');\nexport const useFetchUploadProject = createAIFetchHook('/schemas/chat/attachment');\nexport const useFetchSendFeedback = createAIFetchHook('/schemas/chat/feedback');\nexport const useFetchUploadMedia = createAIFetchHook('/media/upload');\n\n/**\n * Hook wrapper for AI SDK's useChat with Strapi-specific configuration\n */\nexport const useAIChat: typeof useChat = (props) => {\n const strapiVersion = useAppInfo('useAIChat', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIChat-user', (state) => state.userId);\n\n const customFetch = makeChatFetch({ strapiVersion, projectId, userId });\n\n return useChat({\n ...props,\n transport: new DefaultChatTransport({\n api: STRAPI_AI_CHAT_URL,\n fetch: customFetch,\n }),\n });\n};\n"],"names":["TOO_MANY_REQUESTS_ERROR","LICENSE_LIMIT_REACHED_ERROR","LICENSE_LIMIT_EXCEEDED_ERROR","CHAT_TOO_LONG_ERROR","createAIFetchHook","endpoint","strapiVersion","useAppInfo","state","projectId","userId","aiUsage","useGetAiUsageQuery","undefined","refetchOnMountOrArgChange","isPending","setIsPending","useState","error","setError","fetchData","options","fullUrl","STRAPI_AI_URL","isJson","body","formData","response","fetchAI","method","headers","JSON","stringify","ctx","refetch","safeParseJson","ok","Error","statusText","err","message","fetch","useFetchGenerateTitle","useFetchUploadProject","useFetchSendFeedback","useFetchUploadMedia","useAIChat","props","customFetch","makeChatFetch","useChat","transport","DefaultChatTransport","api","STRAPI_AI_CHAT_URL"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useAIFetch.js","sources":["../../../../../admin/src/components/AIChat/hooks/useAIFetch.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-namespace */\n\n/**\n * In charge of fetching data from Strapi AI endpoints\n */\n\nimport { useState } from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAppInfo } from '@strapi/admin/strapi-admin';\nimport { useAIAvailability, useGetAiUsageQuery } from '@strapi/admin/strapi-admin/ee';\nimport { DefaultChatTransport } from 'ai';\n\nimport { fetchAI, makeChatFetch, safeParseJson } from '../lib/aiClient';\nimport { STRAPI_AI_CHAT_URL, STRAPI_AI_URL } from '../lib/constants';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Chat title\n */\nexport namespace GenerateTitle {\n export interface Request {\n body: {\n chatId: string;\n message: string;\n };\n }\n export interface Response {\n data: {\n title: string;\n };\n error?: string;\n }\n}\n\n/**\n * Upload a project to the chat\n */\nexport namespace UploadProject {\n export interface Request {\n body: {\n chatId: string;\n name: string;\n type: 'code';\n files: {\n path: string;\n content: string;\n }[];\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Send chat feedback\n */\nexport type FeedbackReasonIds =\n | 'invalid_schema'\n | 'bad_recommendation'\n | 'slow'\n | 'instructions_ignored'\n | 'being_lazy'\n | 'other';\n\nnamespace SendFeedback {\n export interface Request {\n body: {\n chatId: string;\n type: 'upvote' | 'downvote';\n feedback?: string;\n reasons?: FeedbackReasonIds[];\n messageId: string;\n messages: UIMessage[];\n schemas: Schema[];\n };\n }\n}\n\n/**\n * Upload media\n */\nexport namespace UploadMedia {\n export interface Request {\n body: {\n url: string; // base64 image\n filename: string;\n chatId: string;\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Collection of API endpoints and their corresponding request/response types\n */\ntype AIEndpoints = {\n '/schemas/chat/generate-title': {\n request: GenerateTitle.Request;\n response: GenerateTitle.Response;\n };\n '/schemas/chat/attachment': {\n request: UploadProject.Request;\n response: UploadProject.Response;\n };\n '/schemas/chat/feedback': {\n request: SendFeedback.Request;\n response: void;\n };\n '/media/upload': {\n request: UploadMedia.Request;\n response: UploadMedia.Response;\n };\n};\n\n// Helper type to extract the request type for a given endpoint\ntype RequestType<T extends keyof AIEndpoints> = AIEndpoints[T]['request'];\n\n// Helper type to extract the response type for a given endpoint\ntype ResponseType<T extends keyof AIEndpoints> = AIEndpoints[T]['response'];\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\nexport const TOO_MANY_REQUESTS_ERROR = 'Too many requests';\nexport const LICENSE_LIMIT_REACHED_ERROR = 'License limit';\nexport const LICENSE_LIMIT_EXCEEDED_ERROR = 'AI credit limit exceeded';\nexport const CHAT_TOO_LONG_ERROR = 'Chat too long';\nexport const ATTACHMENT_TOO_BIG_ERROR = 'Attachment too big';\nexport const ATTACHMENT_NOT_FOUND_ERROR = 'Attachment not found';\nexport const INVALID_REQUEST_ERROR = 'Invalid request';\n\n/**\n * Base hook factory for making type-safe API calls to Strapi AI endpoints.\n * Creates a hook specific to a single endpoint.\n */\nexport const createAIFetchHook = <T extends keyof AIEndpoints>(endpoint: T) => {\n return () => {\n const strapiVersion = useAppInfo('useAIFetch', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIFetch-user', (state) => state.userId);\n const isAiAvailable = useAIAvailability();\n const aiUsage = useGetAiUsageQuery(undefined, {\n refetchOnMountOrArgChange: true,\n skip: !isAiAvailable,\n });\n\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * Make a type-safe API call to the specified Strapi AI endpoint with retry logic\n */\n const fetchData = async (\n options: Omit<RequestInit, 'body'> & Partial<RequestType<T>> & { formData?: FormData } = {}\n ): Promise<ResponseType<T> | null> => {\n setIsPending(true);\n setError(null);\n\n try {\n const fullUrl = `${STRAPI_AI_URL}${endpoint}`;\n const isJson = !!options.body && !options.formData;\n\n const response = await fetchAI(fullUrl, {\n method: 'POST',\n headers: isJson\n ? { 'Content-Type': 'application/json', ...options.headers }\n : options.headers,\n body: options.formData\n ? options.formData\n : isJson\n ? JSON.stringify(options.body || {})\n : undefined,\n ctx: { strapiVersion, projectId, userId },\n });\n // refetch ai usage data on every successful request\n if (isAiAvailable) {\n aiUsage.refetch();\n }\n\n const body = await safeParseJson(response);\n\n if (!response.ok) {\n throw new Error(`Error: ${response.statusText}`);\n }\n return body as ResponseType<T>;\n } catch (err) {\n setError(err instanceof Error ? err.message : `Failed to fetch data from ${endpoint}`);\n return null;\n } finally {\n setIsPending(false);\n }\n };\n\n return {\n isPending,\n error,\n fetch: fetchData,\n };\n };\n};\n\n// Create specific hooks for each endpoint\nexport const useFetchGenerateTitle = createAIFetchHook('/schemas/chat/generate-title');\nexport const useFetchUploadProject = createAIFetchHook('/schemas/chat/attachment');\nexport const useFetchSendFeedback = createAIFetchHook('/schemas/chat/feedback');\nexport const useFetchUploadMedia = createAIFetchHook('/media/upload');\n\n/**\n * Hook wrapper for AI SDK's useChat with Strapi-specific configuration\n */\nexport const useAIChat: typeof useChat = (props) => {\n const strapiVersion = useAppInfo('useAIChat', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIChat-user', (state) => state.userId);\n\n const customFetch = makeChatFetch({ strapiVersion, projectId, userId });\n\n return useChat({\n ...props,\n transport: new DefaultChatTransport({\n api: STRAPI_AI_CHAT_URL,\n fetch: customFetch,\n }),\n });\n};\n"],"names":["TOO_MANY_REQUESTS_ERROR","LICENSE_LIMIT_REACHED_ERROR","LICENSE_LIMIT_EXCEEDED_ERROR","CHAT_TOO_LONG_ERROR","createAIFetchHook","endpoint","strapiVersion","useAppInfo","state","projectId","userId","isAiAvailable","useAIAvailability","aiUsage","useGetAiUsageQuery","undefined","refetchOnMountOrArgChange","skip","isPending","setIsPending","useState","error","setError","fetchData","options","fullUrl","STRAPI_AI_URL","isJson","body","formData","response","fetchAI","method","headers","JSON","stringify","ctx","refetch","safeParseJson","ok","Error","statusText","err","message","fetch","useFetchGenerateTitle","useFetchUploadProject","useFetchSendFeedback","useFetchUploadMedia","useAIChat","props","customFetch","makeChatFetch","useChat","transport","DefaultChatTransport","api","STRAPI_AI_CHAT_URL"],"mappings":";;;;;;;;;;AAkIA;;qGAIO,MAAMA,uBAAAA,GAA0B;AAChC,MAAMC,8BAA8B;AACpC,MAAMC,+BAA+B;AACrC,MAAMC,sBAAsB;AAKnC;;;IAIO,MAAMC,iBAAAA,GAAoB,CAA8BC,QAAAA,GAAAA;IAC7D,OAAO,IAAA;AACL,QAAA,MAAMC,gBAAgBC,sBAAAA,CAAW,YAAA,EAAc,CAACC,KAAAA,GAAUA,MAAMF,aAAa,CAAA;AAC7E,QAAA,MAAMG,YAAYF,sBAAAA,CAAW,YAAA,EAAc,CAACC,KAAAA,GAAUA,MAAMC,SAAS,CAAA;AACrE,QAAA,MAAMC,SAASH,sBAAAA,CAAW,iBAAA,EAAmB,CAACC,KAAAA,GAAUA,MAAME,MAAM,CAAA;AACpE,QAAA,MAAMC,aAAAA,GAAgBC,oBAAAA,EAAAA;QACtB,MAAMC,OAAAA,GAAUC,sBAAmBC,SAAAA,EAAW;YAC5CC,yBAAAA,EAA2B,IAAA;AAC3BC,YAAAA,IAAAA,EAAM,CAACN;AACT,SAAA,CAAA;AAEA,QAAA,MAAM,CAACO,SAAAA,EAAWC,YAAAA,CAAa,GAAGC,cAAAA,CAAS,KAAA,CAAA;AAC3C,QAAA,MAAM,CAACC,KAAAA,EAAOC,QAAAA,CAAS,GAAGF,cAAAA,CAAwB,IAAA,CAAA;AAElD;;AAEC,QACD,MAAMG,SAAAA,GAAY,OAChBC,OAAAA,GAAyF,EAAE,GAAA;YAE3FL,YAAAA,CAAa,IAAA,CAAA;YACbG,QAAAA,CAAS,IAAA,CAAA;YAET,IAAI;gBACF,MAAMG,OAAAA,GAAU,CAAA,EAAGC,uBAAAA,CAAAA,EAAgBrB,QAAAA,CAAAA,CAAU;gBAC7C,MAAMsB,MAAAA,GAAS,CAAC,CAACH,OAAAA,CAAQI,IAAI,IAAI,CAACJ,QAAQK,QAAQ;gBAElD,MAAMC,QAAAA,GAAW,MAAMC,gBAAAA,CAAQN,OAAAA,EAAS;oBACtCO,MAAAA,EAAQ,MAAA;AACRC,oBAAAA,OAAAA,EAASN,MAAAA,GACL;wBAAE,cAAA,EAAgB,kBAAA;AAAoB,wBAAA,GAAGH,QAAQS;AAAQ,qBAAA,GACzDT,QAAQS,OAAO;AACnBL,oBAAAA,IAAAA,EAAMJ,OAAAA,CAAQK,QAAQ,GAClBL,OAAAA,CAAQK,QAAQ,GAChBF,MAAAA,GACEO,IAAAA,CAAKC,SAAS,CAACX,OAAAA,CAAQI,IAAI,IAAI,EAAC,CAAA,GAChCb,SAAAA;oBACNqB,GAAAA,EAAK;AAAE9B,wBAAAA,aAAAA;AAAeG,wBAAAA,SAAAA;AAAWC,wBAAAA;AAAO;AAC1C,iBAAA,CAAA;;AAEA,gBAAA,IAAIC,aAAAA,EAAe;AACjBE,oBAAAA,OAAAA,CAAQwB,OAAO,EAAA;AACjB,gBAAA;gBAEA,MAAMT,IAAAA,GAAO,MAAMU,sBAAAA,CAAcR,QAAAA,CAAAA;gBAEjC,IAAI,CAACA,QAAAA,CAASS,EAAE,EAAE;AAChB,oBAAA,MAAM,IAAIC,KAAAA,CAAM,CAAC,OAAO,EAAEV,QAAAA,CAASW,UAAU,CAAA,CAAE,CAAA;AACjD,gBAAA;gBACA,OAAOb,IAAAA;AACT,YAAA,CAAA,CAAE,OAAOc,GAAAA,EAAK;gBACZpB,QAAAA,CAASoB,GAAAA,YAAeF,QAAQE,GAAAA,CAAIC,OAAO,GAAG,CAAC,0BAA0B,EAAEtC,QAAAA,CAAAA,CAAU,CAAA;gBACrF,OAAO,IAAA;YACT,CAAA,QAAU;gBACRc,YAAAA,CAAa,KAAA,CAAA;AACf,YAAA;AACF,QAAA,CAAA;QAEA,OAAO;AACLD,YAAAA,SAAAA;AACAG,YAAAA,KAAAA;YACAuB,KAAAA,EAAOrB;AACT,SAAA;AACF,IAAA,CAAA;AACF;AAEA;AACO,MAAMsB,qBAAAA,GAAwBzC,iBAAAA,CAAkB,8BAAA;AAChD,MAAM0C,qBAAAA,GAAwB1C,iBAAAA,CAAkB,0BAAA;AAChD,MAAM2C,oBAAAA,GAAuB3C,iBAAAA,CAAkB,wBAAA;AAC/C,MAAM4C,mBAAAA,GAAsB5C,iBAAAA,CAAkB,eAAA;AAErD;;IAGO,MAAM6C,SAAAA,GAA4B,CAACC,KAAAA,GAAAA;AACxC,IAAA,MAAM5C,gBAAgBC,sBAAAA,CAAW,WAAA,EAAa,CAACC,KAAAA,GAAUA,MAAMF,aAAa,CAAA;AAC5E,IAAA,MAAMG,YAAYF,sBAAAA,CAAW,YAAA,EAAc,CAACC,KAAAA,GAAUA,MAAMC,SAAS,CAAA;AACrE,IAAA,MAAMC,SAASH,sBAAAA,CAAW,gBAAA,EAAkB,CAACC,KAAAA,GAAUA,MAAME,MAAM,CAAA;AAEnE,IAAA,MAAMyC,cAAcC,sBAAAA,CAAc;AAAE9C,QAAAA,aAAAA;AAAeG,QAAAA,SAAAA;AAAWC,QAAAA;AAAO,KAAA,CAAA;AAErE,IAAA,OAAO2C,aAAAA,CAAQ;AACb,QAAA,GAAGH,KAAK;AACRI,QAAAA,SAAAA,EAAW,IAAIC,uBAAAA,CAAqB;YAClCC,GAAAA,EAAKC,4BAAAA;YACLb,KAAAA,EAAOO;AACT,SAAA;AACF,KAAA,CAAA;AACF;;;;;;;;;;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import { useChat } from '@ai-sdk/react';
|
|
3
3
|
import { useAppInfo } from '@strapi/admin/strapi-admin';
|
|
4
|
-
import { useGetAiUsageQuery } from '@strapi/admin/strapi-admin/ee';
|
|
4
|
+
import { useAIAvailability, useGetAiUsageQuery } from '@strapi/admin/strapi-admin/ee';
|
|
5
5
|
import { DefaultChatTransport } from 'ai';
|
|
6
6
|
import { makeChatFetch, fetchAI, safeParseJson } from '../lib/aiClient.mjs';
|
|
7
7
|
import { STRAPI_AI_CHAT_URL, STRAPI_AI_URL } from '../lib/constants.mjs';
|
|
@@ -20,8 +20,10 @@ const CHAT_TOO_LONG_ERROR = 'Chat too long';
|
|
|
20
20
|
const strapiVersion = useAppInfo('useAIFetch', (state)=>state.strapiVersion);
|
|
21
21
|
const projectId = useAppInfo('useAIFetch', (state)=>state.projectId);
|
|
22
22
|
const userId = useAppInfo('useAIFetch-user', (state)=>state.userId);
|
|
23
|
+
const isAiAvailable = useAIAvailability();
|
|
23
24
|
const aiUsage = useGetAiUsageQuery(undefined, {
|
|
24
|
-
refetchOnMountOrArgChange: true
|
|
25
|
+
refetchOnMountOrArgChange: true,
|
|
26
|
+
skip: !isAiAvailable
|
|
25
27
|
});
|
|
26
28
|
const [isPending, setIsPending] = useState(false);
|
|
27
29
|
const [error, setError] = useState(null);
|
|
@@ -47,7 +49,9 @@ const CHAT_TOO_LONG_ERROR = 'Chat too long';
|
|
|
47
49
|
}
|
|
48
50
|
});
|
|
49
51
|
// refetch ai usage data on every successful request
|
|
50
|
-
|
|
52
|
+
if (isAiAvailable) {
|
|
53
|
+
aiUsage.refetch();
|
|
54
|
+
}
|
|
51
55
|
const body = await safeParseJson(response);
|
|
52
56
|
if (!response.ok) {
|
|
53
57
|
throw new Error(`Error: ${response.statusText}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAIFetch.mjs","sources":["../../../../../admin/src/components/AIChat/hooks/useAIFetch.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-namespace */\n\n/**\n * In charge of fetching data from Strapi AI endpoints\n */\n\nimport { useState } from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAppInfo } from '@strapi/admin/strapi-admin';\nimport { useGetAiUsageQuery } from '@strapi/admin/strapi-admin/ee';\nimport { DefaultChatTransport } from 'ai';\n\nimport { fetchAI, makeChatFetch, safeParseJson } from '../lib/aiClient';\nimport { STRAPI_AI_CHAT_URL, STRAPI_AI_URL } from '../lib/constants';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Chat title\n */\nexport namespace GenerateTitle {\n export interface Request {\n body: {\n chatId: string;\n message: string;\n };\n }\n export interface Response {\n data: {\n title: string;\n };\n error?: string;\n }\n}\n\n/**\n * Upload a project to the chat\n */\nexport namespace UploadProject {\n export interface Request {\n body: {\n chatId: string;\n name: string;\n type: 'code';\n files: {\n path: string;\n content: string;\n }[];\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Send chat feedback\n */\nexport type FeedbackReasonIds =\n | 'invalid_schema'\n | 'bad_recommendation'\n | 'slow'\n | 'instructions_ignored'\n | 'being_lazy'\n | 'other';\n\nnamespace SendFeedback {\n export interface Request {\n body: {\n chatId: string;\n type: 'upvote' | 'downvote';\n feedback?: string;\n reasons?: FeedbackReasonIds[];\n messageId: string;\n messages: UIMessage[];\n schemas: Schema[];\n };\n }\n}\n\n/**\n * Upload media\n */\nexport namespace UploadMedia {\n export interface Request {\n body: {\n url: string; // base64 image\n filename: string;\n chatId: string;\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Collection of API endpoints and their corresponding request/response types\n */\ntype AIEndpoints = {\n '/schemas/chat/generate-title': {\n request: GenerateTitle.Request;\n response: GenerateTitle.Response;\n };\n '/schemas/chat/attachment': {\n request: UploadProject.Request;\n response: UploadProject.Response;\n };\n '/schemas/chat/feedback': {\n request: SendFeedback.Request;\n response: void;\n };\n '/media/upload': {\n request: UploadMedia.Request;\n response: UploadMedia.Response;\n };\n};\n\n// Helper type to extract the request type for a given endpoint\ntype RequestType<T extends keyof AIEndpoints> = AIEndpoints[T]['request'];\n\n// Helper type to extract the response type for a given endpoint\ntype ResponseType<T extends keyof AIEndpoints> = AIEndpoints[T]['response'];\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\nexport const TOO_MANY_REQUESTS_ERROR = 'Too many requests';\nexport const LICENSE_LIMIT_REACHED_ERROR = 'License limit';\nexport const LICENSE_LIMIT_EXCEEDED_ERROR = 'AI credit limit exceeded';\nexport const CHAT_TOO_LONG_ERROR = 'Chat too long';\nexport const ATTACHMENT_TOO_BIG_ERROR = 'Attachment too big';\nexport const ATTACHMENT_NOT_FOUND_ERROR = 'Attachment not found';\nexport const INVALID_REQUEST_ERROR = 'Invalid request';\n\n/**\n * Base hook factory for making type-safe API calls to Strapi AI endpoints.\n * Creates a hook specific to a single endpoint.\n */\nexport const createAIFetchHook = <T extends keyof AIEndpoints>(endpoint: T) => {\n return () => {\n const strapiVersion = useAppInfo('useAIFetch', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIFetch-user', (state) => state.userId);\n const aiUsage = useGetAiUsageQuery(undefined, { refetchOnMountOrArgChange: true });\n\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * Make a type-safe API call to the specified Strapi AI endpoint with retry logic\n */\n const fetchData = async (\n options: Omit<RequestInit, 'body'> & Partial<RequestType<T>> & { formData?: FormData } = {}\n ): Promise<ResponseType<T> | null> => {\n setIsPending(true);\n setError(null);\n\n try {\n const fullUrl = `${STRAPI_AI_URL}${endpoint}`;\n const isJson = !!options.body && !options.formData;\n\n const response = await fetchAI(fullUrl, {\n method: 'POST',\n headers: isJson\n ? { 'Content-Type': 'application/json', ...options.headers }\n : options.headers,\n body: options.formData\n ? options.formData\n : isJson\n ? JSON.stringify(options.body || {})\n : undefined,\n ctx: { strapiVersion, projectId, userId },\n });\n // refetch ai usage data on every successful request\n aiUsage.refetch();\n\n const body = await safeParseJson(response);\n\n if (!response.ok) {\n throw new Error(`Error: ${response.statusText}`);\n }\n return body as ResponseType<T>;\n } catch (err) {\n setError(err instanceof Error ? err.message : `Failed to fetch data from ${endpoint}`);\n return null;\n } finally {\n setIsPending(false);\n }\n };\n\n return {\n isPending,\n error,\n fetch: fetchData,\n };\n };\n};\n\n// Create specific hooks for each endpoint\nexport const useFetchGenerateTitle = createAIFetchHook('/schemas/chat/generate-title');\nexport const useFetchUploadProject = createAIFetchHook('/schemas/chat/attachment');\nexport const useFetchSendFeedback = createAIFetchHook('/schemas/chat/feedback');\nexport const useFetchUploadMedia = createAIFetchHook('/media/upload');\n\n/**\n * Hook wrapper for AI SDK's useChat with Strapi-specific configuration\n */\nexport const useAIChat: typeof useChat = (props) => {\n const strapiVersion = useAppInfo('useAIChat', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIChat-user', (state) => state.userId);\n\n const customFetch = makeChatFetch({ strapiVersion, projectId, userId });\n\n return useChat({\n ...props,\n transport: new DefaultChatTransport({\n api: STRAPI_AI_CHAT_URL,\n fetch: customFetch,\n }),\n });\n};\n"],"names":["TOO_MANY_REQUESTS_ERROR","LICENSE_LIMIT_REACHED_ERROR","LICENSE_LIMIT_EXCEEDED_ERROR","CHAT_TOO_LONG_ERROR","createAIFetchHook","endpoint","strapiVersion","useAppInfo","state","projectId","userId","aiUsage","useGetAiUsageQuery","undefined","refetchOnMountOrArgChange","isPending","setIsPending","useState","error","setError","fetchData","options","fullUrl","STRAPI_AI_URL","isJson","body","formData","response","fetchAI","method","headers","JSON","stringify","ctx","refetch","safeParseJson","ok","Error","statusText","err","message","fetch","useFetchGenerateTitle","useFetchUploadProject","useFetchSendFeedback","useFetchUploadMedia","useAIChat","props","customFetch","makeChatFetch","useChat","transport","DefaultChatTransport","api","STRAPI_AI_CHAT_URL"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useAIFetch.mjs","sources":["../../../../../admin/src/components/AIChat/hooks/useAIFetch.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-namespace */\n\n/**\n * In charge of fetching data from Strapi AI endpoints\n */\n\nimport { useState } from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAppInfo } from '@strapi/admin/strapi-admin';\nimport { useAIAvailability, useGetAiUsageQuery } from '@strapi/admin/strapi-admin/ee';\nimport { DefaultChatTransport } from 'ai';\n\nimport { fetchAI, makeChatFetch, safeParseJson } from '../lib/aiClient';\nimport { STRAPI_AI_CHAT_URL, STRAPI_AI_URL } from '../lib/constants';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n/**\n * Chat title\n */\nexport namespace GenerateTitle {\n export interface Request {\n body: {\n chatId: string;\n message: string;\n };\n }\n export interface Response {\n data: {\n title: string;\n };\n error?: string;\n }\n}\n\n/**\n * Upload a project to the chat\n */\nexport namespace UploadProject {\n export interface Request {\n body: {\n chatId: string;\n name: string;\n type: 'code';\n files: {\n path: string;\n content: string;\n }[];\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Send chat feedback\n */\nexport type FeedbackReasonIds =\n | 'invalid_schema'\n | 'bad_recommendation'\n | 'slow'\n | 'instructions_ignored'\n | 'being_lazy'\n | 'other';\n\nnamespace SendFeedback {\n export interface Request {\n body: {\n chatId: string;\n type: 'upvote' | 'downvote';\n feedback?: string;\n reasons?: FeedbackReasonIds[];\n messageId: string;\n messages: UIMessage[];\n schemas: Schema[];\n };\n }\n}\n\n/**\n * Upload media\n */\nexport namespace UploadMedia {\n export interface Request {\n body: {\n url: string; // base64 image\n filename: string;\n chatId: string;\n };\n }\n export interface Response {\n data: Attachment;\n error?: string;\n }\n}\n\n/**\n * Collection of API endpoints and their corresponding request/response types\n */\ntype AIEndpoints = {\n '/schemas/chat/generate-title': {\n request: GenerateTitle.Request;\n response: GenerateTitle.Response;\n };\n '/schemas/chat/attachment': {\n request: UploadProject.Request;\n response: UploadProject.Response;\n };\n '/schemas/chat/feedback': {\n request: SendFeedback.Request;\n response: void;\n };\n '/media/upload': {\n request: UploadMedia.Request;\n response: UploadMedia.Response;\n };\n};\n\n// Helper type to extract the request type for a given endpoint\ntype RequestType<T extends keyof AIEndpoints> = AIEndpoints[T]['request'];\n\n// Helper type to extract the response type for a given endpoint\ntype ResponseType<T extends keyof AIEndpoints> = AIEndpoints[T]['response'];\n\n/* -------------------------------------------------------------------------------------------------\n * Hooks\n * -----------------------------------------------------------------------------------------------*/\n\nexport const TOO_MANY_REQUESTS_ERROR = 'Too many requests';\nexport const LICENSE_LIMIT_REACHED_ERROR = 'License limit';\nexport const LICENSE_LIMIT_EXCEEDED_ERROR = 'AI credit limit exceeded';\nexport const CHAT_TOO_LONG_ERROR = 'Chat too long';\nexport const ATTACHMENT_TOO_BIG_ERROR = 'Attachment too big';\nexport const ATTACHMENT_NOT_FOUND_ERROR = 'Attachment not found';\nexport const INVALID_REQUEST_ERROR = 'Invalid request';\n\n/**\n * Base hook factory for making type-safe API calls to Strapi AI endpoints.\n * Creates a hook specific to a single endpoint.\n */\nexport const createAIFetchHook = <T extends keyof AIEndpoints>(endpoint: T) => {\n return () => {\n const strapiVersion = useAppInfo('useAIFetch', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIFetch-user', (state) => state.userId);\n const isAiAvailable = useAIAvailability();\n const aiUsage = useGetAiUsageQuery(undefined, {\n refetchOnMountOrArgChange: true,\n skip: !isAiAvailable,\n });\n\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * Make a type-safe API call to the specified Strapi AI endpoint with retry logic\n */\n const fetchData = async (\n options: Omit<RequestInit, 'body'> & Partial<RequestType<T>> & { formData?: FormData } = {}\n ): Promise<ResponseType<T> | null> => {\n setIsPending(true);\n setError(null);\n\n try {\n const fullUrl = `${STRAPI_AI_URL}${endpoint}`;\n const isJson = !!options.body && !options.formData;\n\n const response = await fetchAI(fullUrl, {\n method: 'POST',\n headers: isJson\n ? { 'Content-Type': 'application/json', ...options.headers }\n : options.headers,\n body: options.formData\n ? options.formData\n : isJson\n ? JSON.stringify(options.body || {})\n : undefined,\n ctx: { strapiVersion, projectId, userId },\n });\n // refetch ai usage data on every successful request\n if (isAiAvailable) {\n aiUsage.refetch();\n }\n\n const body = await safeParseJson(response);\n\n if (!response.ok) {\n throw new Error(`Error: ${response.statusText}`);\n }\n return body as ResponseType<T>;\n } catch (err) {\n setError(err instanceof Error ? err.message : `Failed to fetch data from ${endpoint}`);\n return null;\n } finally {\n setIsPending(false);\n }\n };\n\n return {\n isPending,\n error,\n fetch: fetchData,\n };\n };\n};\n\n// Create specific hooks for each endpoint\nexport const useFetchGenerateTitle = createAIFetchHook('/schemas/chat/generate-title');\nexport const useFetchUploadProject = createAIFetchHook('/schemas/chat/attachment');\nexport const useFetchSendFeedback = createAIFetchHook('/schemas/chat/feedback');\nexport const useFetchUploadMedia = createAIFetchHook('/media/upload');\n\n/**\n * Hook wrapper for AI SDK's useChat with Strapi-specific configuration\n */\nexport const useAIChat: typeof useChat = (props) => {\n const strapiVersion = useAppInfo('useAIChat', (state) => state.strapiVersion);\n const projectId = useAppInfo('useAIFetch', (state) => state.projectId);\n const userId = useAppInfo('useAIChat-user', (state) => state.userId);\n\n const customFetch = makeChatFetch({ strapiVersion, projectId, userId });\n\n return useChat({\n ...props,\n transport: new DefaultChatTransport({\n api: STRAPI_AI_CHAT_URL,\n fetch: customFetch,\n }),\n });\n};\n"],"names":["TOO_MANY_REQUESTS_ERROR","LICENSE_LIMIT_REACHED_ERROR","LICENSE_LIMIT_EXCEEDED_ERROR","CHAT_TOO_LONG_ERROR","createAIFetchHook","endpoint","strapiVersion","useAppInfo","state","projectId","userId","isAiAvailable","useAIAvailability","aiUsage","useGetAiUsageQuery","undefined","refetchOnMountOrArgChange","skip","isPending","setIsPending","useState","error","setError","fetchData","options","fullUrl","STRAPI_AI_URL","isJson","body","formData","response","fetchAI","method","headers","JSON","stringify","ctx","refetch","safeParseJson","ok","Error","statusText","err","message","fetch","useFetchGenerateTitle","useFetchUploadProject","useFetchSendFeedback","useFetchUploadMedia","useAIChat","props","customFetch","makeChatFetch","useChat","transport","DefaultChatTransport","api","STRAPI_AI_CHAT_URL"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var ee = require('@strapi/admin/strapi-admin/ee');
|
|
5
|
+
var aiClient = require('../lib/aiClient.js');
|
|
6
|
+
|
|
7
|
+
const usePrefetchAIToken = ()=>{
|
|
8
|
+
const isAIAvailable = ee.useAIAvailability();
|
|
9
|
+
React.useEffect(()=>{
|
|
10
|
+
if (!isAIAvailable) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
aiClient.prefetchAIToken();
|
|
14
|
+
}, [
|
|
15
|
+
isAIAvailable
|
|
16
|
+
]);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
exports.usePrefetchAIToken = usePrefetchAIToken;
|
|
20
|
+
//# sourceMappingURL=usePrefetchAIToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePrefetchAIToken.js","sources":["../../../../../admin/src/components/AIChat/hooks/usePrefetchAIToken.ts"],"sourcesContent":["import { useEffect } from 'react';\n\nimport { useAIAvailability } from '@strapi/admin/strapi-admin/ee';\n\nimport { prefetchAIToken } from '../lib/aiClient';\n\nexport const usePrefetchAIToken = () => {\n const isAIAvailable = useAIAvailability();\n\n useEffect(() => {\n if (!isAIAvailable) {\n return;\n }\n\n prefetchAIToken();\n }, [isAIAvailable]);\n};\n"],"names":["usePrefetchAIToken","isAIAvailable","useAIAvailability","useEffect","prefetchAIToken"],"mappings":";;;;;;MAMaA,kBAAAA,GAAqB,IAAA;AAChC,IAAA,MAAMC,aAAAA,GAAgBC,oBAAAA,EAAAA;IAEtBC,eAAAA,CAAU,IAAA;AACR,QAAA,IAAI,CAACF,aAAAA,EAAe;AAClB,YAAA;AACF,QAAA;AAEAG,QAAAA,wBAAAA,EAAAA;IACF,CAAA,EAAG;AAACH,QAAAA;AAAc,KAAA,CAAA;AACpB;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useAIAvailability } from '@strapi/admin/strapi-admin/ee';
|
|
3
|
+
import { prefetchAIToken } from '../lib/aiClient.mjs';
|
|
4
|
+
|
|
5
|
+
const usePrefetchAIToken = ()=>{
|
|
6
|
+
const isAIAvailable = useAIAvailability();
|
|
7
|
+
useEffect(()=>{
|
|
8
|
+
if (!isAIAvailable) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
prefetchAIToken();
|
|
12
|
+
}, [
|
|
13
|
+
isAIAvailable
|
|
14
|
+
]);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export { usePrefetchAIToken };
|
|
18
|
+
//# sourceMappingURL=usePrefetchAIToken.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePrefetchAIToken.mjs","sources":["../../../../../admin/src/components/AIChat/hooks/usePrefetchAIToken.ts"],"sourcesContent":["import { useEffect } from 'react';\n\nimport { useAIAvailability } from '@strapi/admin/strapi-admin/ee';\n\nimport { prefetchAIToken } from '../lib/aiClient';\n\nexport const usePrefetchAIToken = () => {\n const isAIAvailable = useAIAvailability();\n\n useEffect(() => {\n if (!isAIAvailable) {\n return;\n }\n\n prefetchAIToken();\n }, [isAIAvailable]);\n};\n"],"names":["usePrefetchAIToken","isAIAvailable","useAIAvailability","useEffect","prefetchAIToken"],"mappings":";;;;MAMaA,kBAAAA,GAAqB,IAAA;AAChC,IAAA,MAAMC,aAAAA,GAAgBC,iBAAAA,EAAAA;IAEtBC,SAAAA,CAAU,IAAA;AACR,QAAA,IAAI,CAACF,aAAAA,EAAe;AAClB,YAAA;AACF,QAAA;AAEAG,QAAAA,eAAAA,EAAAA;IACF,CAAA,EAAG;AAACH,QAAAA;AAAc,KAAA,CAAA;AACpB;;;;"}
|
|
@@ -10,7 +10,8 @@ var styledComponents = require('styled-components');
|
|
|
10
10
|
var getTrad = require('../../utils/getTrad.js');
|
|
11
11
|
var useDataManager = require('../DataManager/useDataManager.js');
|
|
12
12
|
var Status = require('../Status.js');
|
|
13
|
-
var
|
|
13
|
+
var FolderNavSection = require('./components/FolderNav/FolderNavSection.js');
|
|
14
|
+
var useContentTypeBuilderMenu = require('./hooks/useContentTypeBuilderMenu.js');
|
|
14
15
|
|
|
15
16
|
const ArrowCounterClockwise = styledComponents.styled(Icons.ArrowClockwise)`
|
|
16
17
|
transform: scaleX(-1);
|
|
@@ -23,7 +24,7 @@ const DiscardAllMenuItem = styledComponents.styled(designSystem.Menu.Item)`
|
|
|
23
24
|
}
|
|
24
25
|
`;
|
|
25
26
|
const ContentTypeBuilderNav = ()=>{
|
|
26
|
-
const {
|
|
27
|
+
const { flatSections, search, folderSections } = useContentTypeBuilderMenu.useContentTypeBuilderMenu();
|
|
27
28
|
const { saveSchema, isModified, history, isInDevelopmentMode } = useDataManager.useDataManager();
|
|
28
29
|
const { formatMessage } = reactIntl.useIntl();
|
|
29
30
|
const [menuIsOpen, setMenuIsOpen] = React.useState(false);
|
|
@@ -71,6 +72,85 @@ const ContentTypeBuilderNav = ()=>{
|
|
|
71
72
|
id: getTrad.getTrad('plugin.name'),
|
|
72
73
|
defaultMessage: 'Content-Type Builder'
|
|
73
74
|
});
|
|
75
|
+
const subNavSections = React.useMemo(()=>{
|
|
76
|
+
const sections = []; // SubNav.Sections wraps its children in a <li>, and multiple {x.maps()} produce multiple react fragments. So we need to collect sections into a single array of children.
|
|
77
|
+
for (const section of folderSections){
|
|
78
|
+
sections.push(/*#__PURE__*/ jsxRuntime.jsx(FolderNavSection.FolderNavSection, {
|
|
79
|
+
section: section.section,
|
|
80
|
+
sectionId: section.sectionId,
|
|
81
|
+
title: section.title,
|
|
82
|
+
links: section.links,
|
|
83
|
+
createTypeLabel: section.createTypeLabel,
|
|
84
|
+
onCreateContentType: section.onCreateContentType,
|
|
85
|
+
searchValue: search.value
|
|
86
|
+
}, section.section));
|
|
87
|
+
}
|
|
88
|
+
for (const section of flatSections){
|
|
89
|
+
if (section.name === 'components') {
|
|
90
|
+
sections.push(/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Section, {
|
|
91
|
+
label: formatMessage({
|
|
92
|
+
id: section.title.id,
|
|
93
|
+
defaultMessage: section.title.defaultMessage
|
|
94
|
+
}),
|
|
95
|
+
link: section.customLink && {
|
|
96
|
+
label: formatMessage({
|
|
97
|
+
id: section.customLink?.id,
|
|
98
|
+
defaultMessage: section.customLink?.defaultMessage
|
|
99
|
+
}),
|
|
100
|
+
onClick: section.customLink?.onClick
|
|
101
|
+
},
|
|
102
|
+
sectionId: section.name,
|
|
103
|
+
children: section.links.map((link)=>{
|
|
104
|
+
const linkLabel = formatMessage({
|
|
105
|
+
id: link.name,
|
|
106
|
+
defaultMessage: link.title
|
|
107
|
+
});
|
|
108
|
+
if ('links' in link) {
|
|
109
|
+
return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.SubSection, {
|
|
110
|
+
label: link.title,
|
|
111
|
+
children: link.links.map((subLink)=>{
|
|
112
|
+
const label = formatMessage({
|
|
113
|
+
id: subLink.name,
|
|
114
|
+
defaultMessage: subLink.title
|
|
115
|
+
});
|
|
116
|
+
return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Link, {
|
|
117
|
+
to: subLink.to,
|
|
118
|
+
label: label,
|
|
119
|
+
endAction: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
|
|
120
|
+
tag: "span",
|
|
121
|
+
textAlign: "center",
|
|
122
|
+
width: '24px',
|
|
123
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(Status.Status, {
|
|
124
|
+
status: subLink.status
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
}, subLink.name);
|
|
128
|
+
})
|
|
129
|
+
}, link.name);
|
|
130
|
+
}
|
|
131
|
+
return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Link, {
|
|
132
|
+
to: link.to,
|
|
133
|
+
label: linkLabel,
|
|
134
|
+
endAction: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
|
|
135
|
+
tag: "span",
|
|
136
|
+
textAlign: "center",
|
|
137
|
+
width: '24px',
|
|
138
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(Status.Status, {
|
|
139
|
+
status: link.status
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
}, link.name);
|
|
143
|
+
})
|
|
144
|
+
}, section.name));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return sections;
|
|
148
|
+
}, [
|
|
149
|
+
folderSections,
|
|
150
|
+
flatSections,
|
|
151
|
+
formatMessage,
|
|
152
|
+
search.value
|
|
153
|
+
]);
|
|
74
154
|
return /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.SubNav.Main, {
|
|
75
155
|
"aria-label": pluginName,
|
|
76
156
|
children: [
|
|
@@ -201,63 +281,7 @@ const ContentTypeBuilderNav = ()=>{
|
|
|
201
281
|
}),
|
|
202
282
|
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Content, {
|
|
203
283
|
children: /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Sections, {
|
|
204
|
-
children:
|
|
205
|
-
children: /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Section, {
|
|
206
|
-
label: formatMessage({
|
|
207
|
-
id: section.title.id,
|
|
208
|
-
defaultMessage: section.title.defaultMessage
|
|
209
|
-
}),
|
|
210
|
-
link: section.customLink && {
|
|
211
|
-
label: formatMessage({
|
|
212
|
-
id: section.customLink?.id,
|
|
213
|
-
defaultMessage: section.customLink?.defaultMessage
|
|
214
|
-
}),
|
|
215
|
-
onClick: section.customLink?.onClick
|
|
216
|
-
},
|
|
217
|
-
sectionId: section.name,
|
|
218
|
-
children: section.links.map((link)=>{
|
|
219
|
-
const linkLabel = formatMessage({
|
|
220
|
-
id: link.name,
|
|
221
|
-
defaultMessage: link.title
|
|
222
|
-
});
|
|
223
|
-
if ('links' in link) {
|
|
224
|
-
return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.SubSection, {
|
|
225
|
-
label: link.title,
|
|
226
|
-
children: link.links.map((subLink)=>{
|
|
227
|
-
const label = formatMessage({
|
|
228
|
-
id: subLink.name,
|
|
229
|
-
defaultMessage: subLink.title
|
|
230
|
-
});
|
|
231
|
-
return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Link, {
|
|
232
|
-
to: subLink.to,
|
|
233
|
-
label: label,
|
|
234
|
-
endAction: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
|
|
235
|
-
tag: "span",
|
|
236
|
-
textAlign: "center",
|
|
237
|
-
width: '24px',
|
|
238
|
-
children: /*#__PURE__*/ jsxRuntime.jsx(Status.Status, {
|
|
239
|
-
status: subLink.status
|
|
240
|
-
})
|
|
241
|
-
})
|
|
242
|
-
}, subLink.name);
|
|
243
|
-
})
|
|
244
|
-
}, link.name);
|
|
245
|
-
}
|
|
246
|
-
return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Link, {
|
|
247
|
-
to: link.to,
|
|
248
|
-
label: linkLabel,
|
|
249
|
-
endAction: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
|
|
250
|
-
tag: "span",
|
|
251
|
-
textAlign: "center",
|
|
252
|
-
width: '24px',
|
|
253
|
-
children: /*#__PURE__*/ jsxRuntime.jsx(Status.Status, {
|
|
254
|
-
status: link.status
|
|
255
|
-
})
|
|
256
|
-
})
|
|
257
|
-
}, link.name);
|
|
258
|
-
})
|
|
259
|
-
})
|
|
260
|
-
}, section.name))
|
|
284
|
+
children: subNavSections
|
|
261
285
|
})
|
|
262
286
|
}),
|
|
263
287
|
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Root, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentTypeBuilderNav.js","sources":["../../../../admin/src/components/ContentTypeBuilderNav/ContentTypeBuilderNav.tsx"],"sourcesContent":["import { Fragment, useState, useEffect } from 'react';\n\nimport { ConfirmDialog, SubNav, tours } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Searchbar,\n Button,\n Flex,\n Typography,\n Divider,\n Menu,\n VisuallyHidden,\n Dialog,\n} from '@strapi/design-system';\nimport { ArrowClockwise, Cross, More } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTrad } from '../../utils/getTrad';\nimport { useDataManager } from '../DataManager/useDataManager';\nimport { Status } from '../Status';\n\nimport { useContentTypeBuilderMenu } from './useContentTypeBuilderMenu';\n\nconst ArrowCounterClockwise = styled(ArrowClockwise)`\n transform: scaleX(-1);\n`;\n\nconst DiscardAllMenuItem = styled(Menu.Item)`\n color: ${({ theme }) => theme.colors.danger600};\n\n &:hover {\n background: ${({ theme, disabled }) => !disabled && theme.colors.danger100};\n }\n`;\n\nexport const ContentTypeBuilderNav = () => {\n const { menu, search } = useContentTypeBuilderMenu();\n const { saveSchema, isModified, history, isInDevelopmentMode } = useDataManager();\n\n const { formatMessage } = useIntl();\n\n const [menuIsOpen, setMenuIsOpen] = useState(false);\n const [discardConfirmationModalIsOpen, setDiscardConfirmationModalIsOpen] = useState(false);\n\n useEffect(() => {\n if (!isInDevelopmentMode) {\n return;\n }\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.ctrlKey || e.metaKey) {\n if (e.key === 'Enter') {\n if (isModified) {\n e.preventDefault();\n saveSchema();\n }\n } else if (e.key === 'z' && !e.shiftKey) {\n e.preventDefault(); // Prevent browser default undo (e.g., in input fields)\n history.undo();\n } else if (e.key === 'y' || (e.shiftKey && e.key === 'z') || e.key === 'Z') {\n e.preventDefault(); // Prevent browser default redo (e.g., in input fields)\n history.redo();\n }\n }\n };\n\n document.addEventListener('keydown', onKeyDown);\n\n return () => {\n document.removeEventListener('keydown', onKeyDown);\n };\n });\n\n const discardHandler = () => {\n setDiscardConfirmationModalIsOpen(true);\n };\n\n const discardChanges = () => {\n setMenuIsOpen(false);\n setDiscardConfirmationModalIsOpen(false);\n history.discardAllChanges();\n };\n\n const undoHandler = () => {\n history.undo();\n };\n\n const redoHandler = () => {\n history.redo();\n };\n\n const pluginName = formatMessage({\n id: getTrad('plugin.name'),\n defaultMessage: 'Content-Type Builder',\n });\n\n return (\n <SubNav.Main aria-label={pluginName}>\n <SubNav.Header label={pluginName} />\n <Divider background=\"neutral150\" />\n <Flex padding={5} gap={3} direction={'column'} alignItems={'stretch'}>\n <tours.contentTypeBuilder.Save>\n <Flex gap={2}>\n <Button\n flex={1}\n onClick={(e) => {\n e.preventDefault();\n saveSchema();\n }}\n type=\"submit\"\n disabled={!isModified || !isInDevelopmentMode}\n fullWidth\n size=\"S\"\n >\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n <Menu.Root open={menuIsOpen} onOpenChange={setMenuIsOpen}>\n <Menu.Trigger\n size=\"S\"\n endIcon={null}\n paddingTop=\"4px\"\n paddingLeft=\"7px\"\n paddingRight=\"7px\"\n variant=\"tertiary\"\n >\n <More fill=\"neutral500\" aria-hidden focusable={false} />\n <VisuallyHidden tag=\"span\">\n {formatMessage({\n id: 'global.more.actions',\n defaultMessage: 'More actions',\n })}\n </VisuallyHidden>\n </Menu.Trigger>\n <Menu.Content zIndex={1}>\n <Menu.Item\n disabled={!history.canUndo || !isInDevelopmentMode}\n onSelect={undoHandler}\n startIcon={<ArrowCounterClockwise />}\n >\n {formatMessage({\n id: 'global.last-change.undo',\n defaultMessage: 'Undo last change',\n })}\n </Menu.Item>\n <Menu.Item\n disabled={!history.canRedo || !isInDevelopmentMode}\n onSelect={redoHandler}\n startIcon={<ArrowClockwise />}\n >\n {formatMessage({\n id: 'global.last-change.redo',\n defaultMessage: 'Redo last change',\n })}\n </Menu.Item>\n <Menu.Separator />\n <DiscardAllMenuItem\n disabled={!history.canDiscardAll || !isInDevelopmentMode}\n onSelect={discardHandler}\n >\n <Flex gap={2}>\n <Cross />\n <Typography>\n {formatMessage({\n id: 'global.last-changes.discard',\n defaultMessage: 'Discard last changes',\n })}\n </Typography>\n </Flex>\n </DiscardAllMenuItem>\n </Menu.Content>\n </Menu.Root>\n </Flex>\n </tours.contentTypeBuilder.Save>\n\n <Searchbar\n value={search.value}\n onChange={(e) => search.onChange(e.target.value)}\n onClear={() => search.onChange('')}\n placeholder={formatMessage({\n id: getTrad('search.placeholder'),\n defaultMessage: 'Search',\n })}\n size=\"S\"\n // eslint-disable-next-line react/no-children-prop\n children={undefined}\n name={'search_contentType'}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n aria-label={formatMessage({\n id: getTrad('search.placeholder'),\n defaultMessage: 'Search',\n })}\n />\n </Flex>\n <SubNav.Content>\n <SubNav.Sections>\n {menu.map((section) => (\n <Fragment key={section.name}>\n <SubNav.Section\n label={formatMessage({\n id: section.title.id,\n defaultMessage: section.title.defaultMessage,\n })}\n link={\n section.customLink && {\n label: formatMessage({\n id: section.customLink?.id,\n defaultMessage: section.customLink?.defaultMessage,\n }),\n onClick: section.customLink?.onClick,\n }\n }\n sectionId={section.name}\n >\n {section.links.map((link) => {\n const linkLabel = formatMessage({ id: link.name, defaultMessage: link.title });\n\n if ('links' in link) {\n return (\n <SubNav.SubSection key={link.name} label={link.title}>\n {link.links.map((subLink) => {\n const label = formatMessage({\n id: subLink.name,\n defaultMessage: subLink.title,\n });\n\n return (\n <SubNav.Link\n to={subLink.to}\n key={subLink.name}\n label={label}\n endAction={\n <Box tag=\"span\" textAlign=\"center\" width={'24px'}>\n <Status status={subLink.status} />\n </Box>\n }\n />\n );\n })}\n </SubNav.SubSection>\n );\n }\n\n return (\n <SubNav.Link\n to={link.to}\n key={link.name}\n label={linkLabel}\n endAction={\n <Box tag=\"span\" textAlign=\"center\" width={'24px'}>\n <Status status={link.status} />\n </Box>\n }\n />\n );\n })}\n </SubNav.Section>\n </Fragment>\n ))}\n </SubNav.Sections>\n </SubNav.Content>\n <Dialog.Root\n open={discardConfirmationModalIsOpen}\n onOpenChange={setDiscardConfirmationModalIsOpen}\n >\n <ConfirmDialog onConfirm={discardChanges}>\n {formatMessage({\n id: getTrad('popUpWarning.discardAll.message'),\n defaultMessage: 'Are you sure you want to discard all changes?',\n })}\n </ConfirmDialog>\n </Dialog.Root>\n </SubNav.Main>\n );\n};\n"],"names":["ArrowCounterClockwise","styled","ArrowClockwise","DiscardAllMenuItem","Menu","Item","theme","colors","danger600","disabled","danger100","ContentTypeBuilderNav","menu","search","useContentTypeBuilderMenu","saveSchema","isModified","history","isInDevelopmentMode","useDataManager","formatMessage","useIntl","menuIsOpen","setMenuIsOpen","useState","discardConfirmationModalIsOpen","setDiscardConfirmationModalIsOpen","useEffect","onKeyDown","e","ctrlKey","metaKey","key","preventDefault","shiftKey","undo","redo","document","addEventListener","removeEventListener","discardHandler","discardChanges","discardAllChanges","undoHandler","redoHandler","pluginName","id","getTrad","defaultMessage","_jsxs","SubNav","Main","aria-label","_jsx","Header","label","Divider","background","Flex","padding","gap","direction","alignItems","tours","contentTypeBuilder","Save","Button","flex","onClick","type","fullWidth","size","Root","open","onOpenChange","Trigger","endIcon","paddingTop","paddingLeft","paddingRight","variant","More","fill","aria-hidden","focusable","VisuallyHidden","tag","Content","zIndex","canUndo","onSelect","startIcon","canRedo","Separator","canDiscardAll","Cross","Typography","Searchbar","value","onChange","target","onClear","placeholder","children","undefined","name","clearLabel","Sections","map","section","Fragment","Section","title","link","customLink","sectionId","links","linkLabel","SubSection","subLink","Link","to","endAction","Box","textAlign","width","Status","status","Dialog","ConfirmDialog","onConfirm"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ContentTypeBuilderNav.js","sources":["../../../../admin/src/components/ContentTypeBuilderNav/ContentTypeBuilderNav.tsx"],"sourcesContent":["import { useState, useEffect, useMemo, ReactNode } from 'react';\n\nimport { ConfirmDialog, SubNav, tours } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Searchbar,\n Button,\n Flex,\n Typography,\n Divider,\n Menu,\n VisuallyHidden,\n Dialog,\n} from '@strapi/design-system';\nimport { ArrowClockwise, Cross, More } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTrad } from '../../utils/getTrad';\nimport { useDataManager } from '../DataManager/useDataManager';\nimport { Status } from '../Status';\n\nimport { FolderNavSection } from './components/FolderNav/FolderNavSection';\nimport { useContentTypeBuilderMenu } from './hooks/useContentTypeBuilderMenu';\n\nconst ArrowCounterClockwise = styled(ArrowClockwise)`\n transform: scaleX(-1);\n`;\n\nconst DiscardAllMenuItem = styled(Menu.Item)`\n color: ${({ theme }) => theme.colors.danger600};\n\n &:hover {\n background: ${({ theme, disabled }) => !disabled && theme.colors.danger100};\n }\n`;\n\nexport const ContentTypeBuilderNav = () => {\n const { flatSections, search, folderSections } = useContentTypeBuilderMenu();\n const { saveSchema, isModified, history, isInDevelopmentMode } = useDataManager();\n\n const { formatMessage } = useIntl();\n\n const [menuIsOpen, setMenuIsOpen] = useState(false);\n const [discardConfirmationModalIsOpen, setDiscardConfirmationModalIsOpen] = useState(false);\n\n useEffect(() => {\n if (!isInDevelopmentMode) {\n return;\n }\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.ctrlKey || e.metaKey) {\n if (e.key === 'Enter') {\n if (isModified) {\n e.preventDefault();\n saveSchema();\n }\n } else if (e.key === 'z' && !e.shiftKey) {\n e.preventDefault(); // Prevent browser default undo (e.g., in input fields)\n history.undo();\n } else if (e.key === 'y' || (e.shiftKey && e.key === 'z') || e.key === 'Z') {\n e.preventDefault(); // Prevent browser default redo (e.g., in input fields)\n history.redo();\n }\n }\n };\n\n document.addEventListener('keydown', onKeyDown);\n\n return () => {\n document.removeEventListener('keydown', onKeyDown);\n };\n });\n\n const discardHandler = () => {\n setDiscardConfirmationModalIsOpen(true);\n };\n\n const discardChanges = () => {\n setMenuIsOpen(false);\n setDiscardConfirmationModalIsOpen(false);\n history.discardAllChanges();\n };\n\n const undoHandler = () => {\n history.undo();\n };\n\n const redoHandler = () => {\n history.redo();\n };\n\n const pluginName = formatMessage({\n id: getTrad('plugin.name'),\n defaultMessage: 'Content-Type Builder',\n });\n\n const subNavSections = useMemo(() => {\n const sections: ReactNode[] = []; // SubNav.Sections wraps its children in a <li>, and multiple {x.maps()} produce multiple react fragments. So we need to collect sections into a single array of children.\n\n for (const section of folderSections) {\n sections.push(\n <FolderNavSection\n key={section.section}\n section={section.section}\n sectionId={section.sectionId}\n title={section.title}\n links={section.links}\n createTypeLabel={section.createTypeLabel}\n onCreateContentType={section.onCreateContentType}\n searchValue={search.value}\n />\n );\n }\n\n for (const section of flatSections) {\n if (section.name === 'components') {\n sections.push(\n <SubNav.Section\n key={section.name}\n label={formatMessage({\n id: section.title.id,\n defaultMessage: section.title.defaultMessage,\n })}\n link={\n section.customLink && {\n label: formatMessage({\n id: section.customLink?.id,\n defaultMessage: section.customLink?.defaultMessage,\n }),\n onClick: section.customLink?.onClick,\n }\n }\n sectionId={section.name}\n >\n {section.links.map((link) => {\n const linkLabel = formatMessage({\n id: link.name,\n defaultMessage: link.title,\n });\n\n if ('links' in link) {\n return (\n <SubNav.SubSection key={link.name} label={link.title}>\n {link.links.map((subLink) => {\n const label = formatMessage({\n id: subLink.name,\n defaultMessage: subLink.title,\n });\n\n return (\n <SubNav.Link\n to={subLink.to}\n key={subLink.name}\n label={label}\n endAction={\n <Box tag=\"span\" textAlign=\"center\" width={'24px'}>\n <Status status={subLink.status} />\n </Box>\n }\n />\n );\n })}\n </SubNav.SubSection>\n );\n }\n\n return (\n <SubNav.Link\n to={link.to}\n key={link.name}\n label={linkLabel}\n endAction={\n <Box tag=\"span\" textAlign=\"center\" width={'24px'}>\n <Status status={link.status} />\n </Box>\n }\n />\n );\n })}\n </SubNav.Section>\n );\n }\n }\n\n return sections;\n }, [folderSections, flatSections, formatMessage, search.value]);\n\n return (\n <SubNav.Main aria-label={pluginName}>\n <SubNav.Header label={pluginName} />\n <Divider background=\"neutral150\" />\n <Flex padding={5} gap={3} direction={'column'} alignItems={'stretch'}>\n <tours.contentTypeBuilder.Save>\n <Flex gap={2}>\n <Button\n flex={1}\n onClick={(e) => {\n e.preventDefault();\n saveSchema();\n }}\n type=\"submit\"\n disabled={!isModified || !isInDevelopmentMode}\n fullWidth\n size=\"S\"\n >\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n <Menu.Root open={menuIsOpen} onOpenChange={setMenuIsOpen}>\n <Menu.Trigger\n size=\"S\"\n endIcon={null}\n paddingTop=\"4px\"\n paddingLeft=\"7px\"\n paddingRight=\"7px\"\n variant=\"tertiary\"\n >\n <More fill=\"neutral500\" aria-hidden focusable={false} />\n <VisuallyHidden tag=\"span\">\n {formatMessage({\n id: 'global.more.actions',\n defaultMessage: 'More actions',\n })}\n </VisuallyHidden>\n </Menu.Trigger>\n <Menu.Content zIndex={1}>\n <Menu.Item\n disabled={!history.canUndo || !isInDevelopmentMode}\n onSelect={undoHandler}\n startIcon={<ArrowCounterClockwise />}\n >\n {formatMessage({\n id: 'global.last-change.undo',\n defaultMessage: 'Undo last change',\n })}\n </Menu.Item>\n <Menu.Item\n disabled={!history.canRedo || !isInDevelopmentMode}\n onSelect={redoHandler}\n startIcon={<ArrowClockwise />}\n >\n {formatMessage({\n id: 'global.last-change.redo',\n defaultMessage: 'Redo last change',\n })}\n </Menu.Item>\n <Menu.Separator />\n <DiscardAllMenuItem\n disabled={!history.canDiscardAll || !isInDevelopmentMode}\n onSelect={discardHandler}\n >\n <Flex gap={2}>\n <Cross />\n <Typography>\n {formatMessage({\n id: 'global.last-changes.discard',\n defaultMessage: 'Discard last changes',\n })}\n </Typography>\n </Flex>\n </DiscardAllMenuItem>\n </Menu.Content>\n </Menu.Root>\n </Flex>\n </tours.contentTypeBuilder.Save>\n\n <Searchbar\n value={search.value}\n onChange={(e) => search.onChange(e.target.value)}\n onClear={() => search.onChange('')}\n placeholder={formatMessage({\n id: getTrad('search.placeholder'),\n defaultMessage: 'Search',\n })}\n size=\"S\"\n // eslint-disable-next-line react/no-children-prop\n children={undefined}\n name={'search_contentType'}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n aria-label={formatMessage({\n id: getTrad('search.placeholder'),\n defaultMessage: 'Search',\n })}\n />\n </Flex>\n <SubNav.Content>\n <SubNav.Sections>{subNavSections}</SubNav.Sections>\n </SubNav.Content>\n <Dialog.Root\n open={discardConfirmationModalIsOpen}\n onOpenChange={setDiscardConfirmationModalIsOpen}\n >\n <ConfirmDialog onConfirm={discardChanges}>\n {formatMessage({\n id: getTrad('popUpWarning.discardAll.message'),\n defaultMessage: 'Are you sure you want to discard all changes?',\n })}\n </ConfirmDialog>\n </Dialog.Root>\n </SubNav.Main>\n );\n};\n"],"names":["ArrowCounterClockwise","styled","ArrowClockwise","DiscardAllMenuItem","Menu","Item","theme","colors","danger600","disabled","danger100","ContentTypeBuilderNav","flatSections","search","folderSections","useContentTypeBuilderMenu","saveSchema","isModified","history","isInDevelopmentMode","useDataManager","formatMessage","useIntl","menuIsOpen","setMenuIsOpen","useState","discardConfirmationModalIsOpen","setDiscardConfirmationModalIsOpen","useEffect","onKeyDown","e","ctrlKey","metaKey","key","preventDefault","shiftKey","undo","redo","document","addEventListener","removeEventListener","discardHandler","discardChanges","discardAllChanges","undoHandler","redoHandler","pluginName","id","getTrad","defaultMessage","subNavSections","useMemo","sections","section","push","_jsx","FolderNavSection","sectionId","title","links","createTypeLabel","onCreateContentType","searchValue","value","name","SubNav","Section","label","link","customLink","onClick","map","linkLabel","SubSection","subLink","Link","to","endAction","Box","tag","textAlign","width","Status","status","_jsxs","Main","aria-label","Header","Divider","background","Flex","padding","gap","direction","alignItems","tours","contentTypeBuilder","Save","Button","flex","type","fullWidth","size","Root","open","onOpenChange","Trigger","endIcon","paddingTop","paddingLeft","paddingRight","variant","More","fill","aria-hidden","focusable","VisuallyHidden","Content","zIndex","canUndo","onSelect","startIcon","canRedo","Separator","canDiscardAll","Cross","Typography","Searchbar","onChange","target","onClear","placeholder","children","undefined","clearLabel","Sections","Dialog","ConfirmDialog","onConfirm"],"mappings":"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"}
|