@strapi/content-type-builder 5.58.0 → 5.60.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/FeedbackModal.js +13 -7
- package/dist/admin/components/AIChat/FeedbackModal.js.map +1 -1
- package/dist/admin/components/AIChat/FeedbackModal.mjs +14 -8
- package/dist/admin/components/AIChat/FeedbackModal.mjs.map +1 -1
- package/dist/admin/components/AIChat/UploadCodeModal.js +12 -6
- package/dist/admin/components/AIChat/UploadCodeModal.js.map +1 -1
- package/dist/admin/components/AIChat/UploadCodeModal.mjs +13 -7
- package/dist/admin/components/AIChat/UploadCodeModal.mjs.map +1 -1
- package/dist/admin/components/AIChat/UploadFigmaModal.js +12 -6
- package/dist/admin/components/AIChat/UploadFigmaModal.js.map +1 -1
- package/dist/admin/components/AIChat/UploadFigmaModal.mjs +13 -7
- package/dist/admin/components/AIChat/UploadFigmaModal.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/Attachments/components/Attachment.js +6 -3
- package/dist/admin/components/AIChat/components/Attachments/components/Attachment.js.map +1 -1
- package/dist/admin/components/AIChat/components/Attachments/components/Attachment.mjs +7 -4
- package/dist/admin/components/AIChat/components/Attachments/components/Attachment.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/Collapsible.js +9 -4
- package/dist/admin/components/AIChat/components/Collapsible.js.map +1 -1
- package/dist/admin/components/AIChat/components/Collapsible.mjs +10 -5
- package/dist/admin/components/AIChat/components/Collapsible.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/Dropzone.js +13 -6
- package/dist/admin/components/AIChat/components/Dropzone.js.map +1 -1
- package/dist/admin/components/AIChat/components/Dropzone.mjs +14 -7
- package/dist/admin/components/AIChat/components/Dropzone.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/FloatingPanel.js +11 -4
- package/dist/admin/components/AIChat/components/FloatingPanel.js.map +1 -1
- package/dist/admin/components/AIChat/components/FloatingPanel.mjs +12 -5
- package/dist/admin/components/AIChat/components/FloatingPanel.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/FullScreenImage.js +16 -8
- package/dist/admin/components/AIChat/components/FullScreenImage.js.map +1 -1
- package/dist/admin/components/AIChat/components/FullScreenImage.mjs +17 -9
- package/dist/admin/components/AIChat/components/FullScreenImage.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/Input.js +6 -3
- package/dist/admin/components/AIChat/components/Input.js.map +1 -1
- package/dist/admin/components/AIChat/components/Input.mjs +7 -4
- package/dist/admin/components/AIChat/components/Input.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/Messages/Message.js +88 -12
- package/dist/admin/components/AIChat/components/Messages/Message.js.map +1 -1
- package/dist/admin/components/AIChat/components/Messages/Message.mjs +87 -13
- package/dist/admin/components/AIChat/components/Messages/Message.mjs.map +1 -1
- package/dist/admin/components/AIChat/components/StepModal.js +44 -17
- package/dist/admin/components/AIChat/components/StepModal.js.map +1 -1
- package/dist/admin/components/AIChat/components/StepModal.mjs +45 -18
- package/dist/admin/components/AIChat/components/StepModal.mjs.map +1 -1
- package/dist/admin/components/AIChat/providers/ChatProvider.js +79 -27
- package/dist/admin/components/AIChat/providers/ChatProvider.js.map +1 -1
- package/dist/admin/components/AIChat/providers/ChatProvider.mjs +80 -28
- package/dist/admin/components/AIChat/providers/ChatProvider.mjs.map +1 -1
- package/dist/admin/components/AIChat/providers/SchemaProvider.js +6 -3
- package/dist/admin/components/AIChat/providers/SchemaProvider.js.map +1 -1
- package/dist/admin/components/AIChat/providers/SchemaProvider.mjs +7 -4
- package/dist/admin/components/AIChat/providers/SchemaProvider.mjs.map +1 -1
- package/dist/admin/components/AttributeOptions/AttributeOption.js +2 -2
- package/dist/admin/components/AttributeOptions/AttributeOption.js.map +1 -1
- package/dist/admin/components/AttributeOptions/AttributeOption.mjs +2 -2
- package/dist/admin/components/AttributeOptions/AttributeOption.mjs.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.js.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.mjs.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.js.map +1 -1
- package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.mjs.map +1 -1
- package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.js +2 -1
- package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.js.map +1 -1
- package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.mjs +2 -1
- package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.mjs.map +1 -1
- package/dist/admin/components/DataManager/DataManagerProvider.js +317 -275
- package/dist/admin/components/DataManager/DataManagerProvider.js.map +1 -1
- package/dist/admin/components/DataManager/DataManagerProvider.mjs +319 -277
- package/dist/admin/components/DataManager/DataManagerProvider.mjs.map +1 -1
- package/dist/admin/components/DataManager/RenameMigrationModal.js.map +1 -1
- package/dist/admin/components/DataManager/RenameMigrationModal.mjs.map +1 -1
- package/dist/admin/components/DataManager/reducer.js +31 -4
- package/dist/admin/components/DataManager/reducer.js.map +1 -1
- package/dist/admin/components/DataManager/reducer.mjs +31 -4
- package/dist/admin/components/DataManager/reducer.mjs.map +1 -1
- package/dist/admin/components/DynamicZoneList.js +2 -1
- package/dist/admin/components/DynamicZoneList.js.map +1 -1
- package/dist/admin/components/DynamicZoneList.mjs +2 -1
- package/dist/admin/components/DynamicZoneList.mjs.map +1 -1
- package/dist/admin/components/FormModal/attributes/ConditionForm.js +2 -1
- package/dist/admin/components/FormModal/attributes/ConditionForm.js.map +1 -1
- package/dist/admin/components/FormModal/attributes/ConditionForm.mjs +2 -1
- package/dist/admin/components/FormModal/attributes/ConditionForm.mjs.map +1 -1
- package/dist/admin/components/FormModal/attributes/types.js +2 -2
- package/dist/admin/components/FormModal/attributes/types.js.map +1 -1
- package/dist/admin/components/FormModal/attributes/types.mjs +2 -2
- package/dist/admin/components/FormModal/attributes/types.mjs.map +1 -1
- package/dist/admin/components/FormModal/forms/forms.js +1 -1
- package/dist/admin/components/FormModal/forms/forms.js.map +1 -1
- package/dist/admin/components/FormModal/forms/forms.mjs +1 -1
- package/dist/admin/components/FormModal/forms/forms.mjs.map +1 -1
- package/dist/admin/components/GenericInputs.js +2 -1
- package/dist/admin/components/GenericInputs.js.map +1 -1
- package/dist/admin/components/GenericInputs.mjs +2 -1
- package/dist/admin/components/GenericInputs.mjs.map +1 -1
- package/dist/admin/components/TabForm.js.map +1 -1
- package/dist/admin/components/TabForm.mjs.map +1 -1
- package/dist/admin/src/components/AIChat/components/FullScreenImage.d.ts +8 -0
- package/dist/admin/src/components/AIChat/components/Messages/Message.d.ts +20 -0
- package/dist/admin/utils/folderTelemetry.js.map +1 -1
- package/dist/admin/utils/folderTelemetry.mjs.map +1 -1
- package/dist/admin/utils/formAPI.js.map +1 -1
- package/dist/admin/utils/formAPI.mjs.map +1 -1
- package/dist/server/controllers/validation/common.js +1 -1
- package/dist/server/controllers/validation/common.js.map +1 -1
- package/dist/server/controllers/validation/common.mjs +1 -1
- package/dist/server/controllers/validation/common.mjs.map +1 -1
- package/dist/server/controllers/validation/schema.js +3 -2
- package/dist/server/controllers/validation/schema.js.map +1 -1
- package/dist/server/controllers/validation/schema.mjs +4 -3
- package/dist/server/controllers/validation/schema.mjs.map +1 -1
- package/dist/server/register.js.map +1 -1
- package/dist/server/register.mjs.map +1 -1
- package/dist/server/services/migration-builder/index.js.map +1 -1
- package/dist/server/services/migration-builder/index.mjs.map +1 -1
- package/dist/server/services/schema.js +34 -1
- package/dist/server/services/schema.js.map +1 -1
- package/dist/server/services/schema.mjs +34 -1
- package/dist/server/services/schema.mjs.map +1 -1
- package/dist/server/src/controllers/validation/schema.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/services/migration-builder/index.d.ts.map +1 -1
- package/dist/server/src/services/schema-builder/types.d.ts.map +1 -1
- package/dist/server/src/services/schema.d.ts.map +1 -1
- package/dist/server/src/utils/uid-target.d.ts +18 -0
- package/dist/server/src/utils/uid-target.d.ts.map +1 -0
- package/dist/server/utils/uid-target.js +34 -0
- package/dist/server/utils/uid-target.js.map +1 -0
- package/dist/server/utils/uid-target.mjs +31 -0
- package/dist/server/utils/uid-target.mjs.map +1 -0
- package/package.json +6 -6
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { useId, useRef } from 'react';
|
|
2
3
|
import { Flex, Box, IconButton, Typography } from '@strapi/design-system';
|
|
3
4
|
import { ThumbUp, ThumbDown } from '@strapi/icons';
|
|
4
5
|
import Markdown from 'react-markdown';
|
|
@@ -81,6 +82,77 @@ const isSchemaToolPart = (part)=>{
|
|
|
81
82
|
}
|
|
82
83
|
return part.type === 'tool-schemaGenerationTool';
|
|
83
84
|
};
|
|
85
|
+
/**
|
|
86
|
+
* Exported for unit tests only. The AI chat needs a live AI backend, so no E2E
|
|
87
|
+
* run can reach this logic.
|
|
88
|
+
*/ const getPartFingerprint = (part)=>{
|
|
89
|
+
if (part.type === 'text') {
|
|
90
|
+
return `text:${part.text}`;
|
|
91
|
+
}
|
|
92
|
+
if (part.type === 'file') {
|
|
93
|
+
return `file:${part.filename ?? ''}:${part.mediaType}:${part.url}`;
|
|
94
|
+
}
|
|
95
|
+
if ('toolCallId' in part && typeof part.toolCallId === 'string') {
|
|
96
|
+
return `${part.type}:${part.toolCallId}`;
|
|
97
|
+
}
|
|
98
|
+
return part.type;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Gives each part a key that survives across renders. A key derived from the
|
|
102
|
+
* part content alone cannot work: a streaming text part changes on every chunk,
|
|
103
|
+
* so its fingerprint would change on every tick and remount the node mid
|
|
104
|
+
* stream. Hence the fallback chain below: exact fingerprint match first, then
|
|
105
|
+
* object identity, then same slot and same type for the streaming case.
|
|
106
|
+
*
|
|
107
|
+
* Exported for unit tests only. The AI chat needs a live AI backend, so no E2E
|
|
108
|
+
* run can reach this logic.
|
|
109
|
+
*/ const usePartsWithKeys = (parts)=>{
|
|
110
|
+
const keyPrefix = useId();
|
|
111
|
+
const nextKey = useRef(0);
|
|
112
|
+
const previousParts = useRef([]);
|
|
113
|
+
const matchedParts = new Set();
|
|
114
|
+
const exactMatches = parts.map((part)=>{
|
|
115
|
+
const fingerprint = getPartFingerprint(part);
|
|
116
|
+
const exactMatch = previousParts.current.find((candidate)=>candidate.fingerprint === fingerprint && !matchedParts.has(candidate));
|
|
117
|
+
const sameObject = previousParts.current.find((candidate)=>candidate.part === part && !matchedParts.has(candidate));
|
|
118
|
+
const previousPart = exactMatch ?? sameObject;
|
|
119
|
+
if (previousPart) {
|
|
120
|
+
matchedParts.add(previousPart);
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
fingerprint,
|
|
124
|
+
part,
|
|
125
|
+
previousPart
|
|
126
|
+
};
|
|
127
|
+
});
|
|
128
|
+
const keyedParts = exactMatches.map(({ fingerprint, part, previousPart }, index)=>{
|
|
129
|
+
const sameSlot = previousParts.current[index];
|
|
130
|
+
const streamingMatch = !previousPart && sameSlot && sameSlot.part.type === part.type && !matchedParts.has(sameSlot) ? sameSlot : undefined;
|
|
131
|
+
const matchedPart = previousPart ?? streamingMatch;
|
|
132
|
+
const key = matchedPart?.key ?? `${keyPrefix}-${nextKey.current}`;
|
|
133
|
+
if (streamingMatch) {
|
|
134
|
+
matchedParts.add(streamingMatch);
|
|
135
|
+
}
|
|
136
|
+
if (matchedPart) {
|
|
137
|
+
matchedParts.add(matchedPart);
|
|
138
|
+
} else {
|
|
139
|
+
nextKey.current += 1;
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
fingerprint,
|
|
143
|
+
key,
|
|
144
|
+
part
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
/**
|
|
148
|
+
* Both refs are written during render. The outcome depends only on the parts
|
|
149
|
+
* passed in, so re-invoking the render function is harmless: on the second
|
|
150
|
+
* pass of a StrictMode double render every part exact-matches the record the
|
|
151
|
+
* first pass stored here, the same keys come back out and `nextKey` does not
|
|
152
|
+
* advance.
|
|
153
|
+
*/ previousParts.current = keyedParts;
|
|
154
|
+
return keyedParts;
|
|
155
|
+
};
|
|
84
156
|
const capitalize = (s)=>s ? s.charAt(0).toUpperCase() + s.slice(1) : '';
|
|
85
157
|
const getSchemaLink = (schema)=>{
|
|
86
158
|
const isComponent = (schema.kind ?? schema.modelType) === 'component';
|
|
@@ -131,8 +203,9 @@ const MessageContent = ({ part })=>{
|
|
|
131
203
|
return null;
|
|
132
204
|
};
|
|
133
205
|
const UserMessage = ({ message })=>{
|
|
134
|
-
const
|
|
135
|
-
const
|
|
206
|
+
const partsWithKeys = usePartsWithKeys(message.parts);
|
|
207
|
+
const hasText = partsWithKeys.some(({ part })=>part.type === 'text' && part.text.trim() !== '');
|
|
208
|
+
const attachments = partsWithKeys.filter(({ part })=>part.type === 'file');
|
|
136
209
|
return /*#__PURE__*/ jsxs(AnimatedBox, {
|
|
137
210
|
as: Flex,
|
|
138
211
|
direction: "column",
|
|
@@ -151,35 +224,36 @@ const UserMessage = ({ message })=>{
|
|
|
151
224
|
'16px'
|
|
152
225
|
],
|
|
153
226
|
hasRadius: true,
|
|
154
|
-
children:
|
|
155
|
-
if (
|
|
227
|
+
children: partsWithKeys.map(({ key, part })=>{
|
|
228
|
+
if (part.type !== 'text') return null;
|
|
156
229
|
return /*#__PURE__*/ jsx(UserMessageTypography, {
|
|
157
|
-
children:
|
|
158
|
-
},
|
|
230
|
+
children: part.text
|
|
231
|
+
}, key);
|
|
159
232
|
})
|
|
160
233
|
}) : null,
|
|
161
|
-
attachments.map((
|
|
234
|
+
attachments.map(({ key, part })=>/*#__PURE__*/ jsx(AttachmentPreview, {
|
|
162
235
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
163
236
|
attachment: {
|
|
164
|
-
...
|
|
237
|
+
...part,
|
|
165
238
|
status: 'ready'
|
|
166
239
|
}
|
|
167
|
-
},
|
|
240
|
+
}, key))
|
|
168
241
|
]
|
|
169
242
|
});
|
|
170
243
|
};
|
|
171
244
|
const AssistantMessage = ({ message, isLoading })=>{
|
|
172
245
|
const { upvoteMessage } = useFeedback();
|
|
173
246
|
const { openFeedbackModal } = useFeedbackModal();
|
|
247
|
+
const partsWithKeys = usePartsWithKeys(message.parts);
|
|
174
248
|
return /*#__PURE__*/ jsxs(Box, {
|
|
175
249
|
style: {
|
|
176
250
|
alignSelf: 'flex-start'
|
|
177
251
|
},
|
|
178
252
|
maxWidth: "90%",
|
|
179
253
|
children: [
|
|
180
|
-
|
|
181
|
-
part:
|
|
182
|
-
},
|
|
254
|
+
partsWithKeys.map(({ key, part })=>/*#__PURE__*/ jsx(MessageContent, {
|
|
255
|
+
part: part
|
|
256
|
+
}, key)),
|
|
183
257
|
isLoading ? /*#__PURE__*/ jsxs(Flex, {
|
|
184
258
|
gap: 1,
|
|
185
259
|
children: [
|
|
@@ -219,5 +293,5 @@ const ChatMessage = ({ message })=>{
|
|
|
219
293
|
});
|
|
220
294
|
};
|
|
221
295
|
|
|
222
|
-
export { ChatMessage };
|
|
296
|
+
export { ChatMessage, getPartFingerprint, usePartsWithKeys };
|
|
223
297
|
//# sourceMappingURL=Message.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Message.mjs","sources":["../../../../../../admin/src/components/AIChat/components/Messages/Message.tsx"],"sourcesContent":["import { Typography, Box, IconButton, Flex } from '@strapi/design-system';\nimport { ThumbUp, ThumbDown } from '@strapi/icons';\nimport Markdown from 'react-markdown';\nimport { styled } from 'styled-components';\n\nimport { useFeedbackModal } from '../../FeedbackModal';\nimport { useFeedback } from '../../hooks/useFeedback';\nimport {\n AIMessage,\n type UserMessage as UserMessageType,\n AssistantMessage as AssistantMessageType,\n type MarkerContent as MarkerContentType,\n} from '../../lib/types/messages';\nimport { AnimatedBox } from '../AnimatedBox';\nimport { AttachmentPreview } from '../Attachments/AttachmentPreview';\n\nimport { Marker } from './Marker';\n\nconst MarkdownStyles = styled(Typography)`\n max-width: 65ch;\n margin: 0 auto;\n overflow-wrap: anywhere;\n word-break: break-word;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-top: 1.25em;\n margin-bottom: 0.5em;\n font-weight: bold;\n }\n\n p {\n margin-bottom: 1em;\n }\n\n ul,\n ol {\n padding-left: 1.5em; /* indentation for bullet points */\n margin-bottom: 1em;\n }\n\n li {\n margin-bottom: 0.5em;\n list-style-type: disc; /* or whatever style you prefer */\n }\n\n strong {\n font-weight: bold;\n }\n\n /* code blocks, blockquotes, etc. */\n code {\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n font-family:\n 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas, monospace;\n }\n\n /* links */\n a {\n color: ${({ theme }) => theme.colors.primary500};\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n text-decoration: none;\n\n &:hover {\n text-decoration: underline;\n }\n }\n`;\n\nconst UserMessageTypography = styled(Typography)`\n overflow-wrap: anywhere;\n word-break: break-word;\n`;\n\n// ---------------------------\n// Tool: schemaGenerationTool helpers\n// ---------------------------\n\ntype SchemaToolSchema = {\n action?: 'create' | 'update' | 'remove';\n uid?: string;\n name?: string;\n category?: string;\n kind?: 'collectionType' | 'singleType' | 'component';\n modelType?: 'component' | 'collectionType' | 'singleType';\n};\n\ntype SchemaToolPart = {\n type: 'tool-schemaGenerationTool';\n input?: { schemas?: SchemaToolSchema[] };\n output?: { schemas?: SchemaToolSchema[]; error?: unknown };\n toolCallId?: string;\n};\n\nconst isSchemaToolPart = (part: unknown): part is SchemaToolPart => {\n if (typeof part !== 'object' || part === null || !('type' in part)) {\n return false;\n }\n\n return part.type === 'tool-schemaGenerationTool';\n};\n\nconst capitalize = (s?: string) => (s ? s.charAt(0).toUpperCase() + s.slice(1) : '');\n\nconst getSchemaLink = (schema: SchemaToolSchema): string | undefined => {\n const isComponent = (schema.kind ?? schema.modelType) === 'component';\n if (!schema.uid) return undefined;\n return isComponent\n ? `/plugins/content-type-builder/component-categories/${schema.category ?? ''}/${schema.uid}`\n : `/plugins/content-type-builder/content-types/${schema.uid}`;\n};\n\nconst toMarkerFromSchemaTool = (part: SchemaToolPart): MarkerContentType => {\n const outSchemas = part.output?.schemas ?? [];\n const inSchemas = part.input?.schemas ?? [];\n\n const schemas = (outSchemas.length ? outSchemas : inSchemas) as SchemaToolSchema[];\n const numSchemas = schemas.length;\n\n const state: 'loading' | 'success' | 'error' = part.output\n ? part.output.error\n ? 'error'\n : 'success'\n : 'loading';\n\n const steps = schemas.map((schema, index) => ({\n id: `${part.toolCallId ?? 'schemaGenerationTool'}-${schema.uid ?? schema.name ?? index}`,\n description: capitalize(schema.name ?? schema.uid ?? 'Schema'),\n status:\n schema.action === 'create' || schema.action === 'update' || schema.action === 'remove'\n ? schema.action\n : ('update' as const),\n link: getSchemaLink(schema),\n }));\n\n const title =\n state === 'success'\n ? `Updated ${numSchemas} schema${numSchemas === 1 ? '' : 's'}`\n : state === 'error'\n ? `Failed to update schema${numSchemas === 1 ? '' : 's'}`\n : 'Updating schemas';\n\n return {\n type: 'marker',\n title,\n state,\n steps,\n };\n};\n\nconst MessageContent = ({\n part,\n}: {\n part: AIMessage['parts'][number];\n status?: 'loading' | 'success' | 'error';\n}) => {\n if (part.type === 'text') {\n return (\n <MarkdownStyles>\n <Markdown\n components={{\n a: ({ node: _node, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props} />\n ),\n }}\n >\n {part.text}\n </Markdown>\n </MarkdownStyles>\n );\n }\n\n if (isSchemaToolPart(part)) {\n const marker = toMarkerFromSchemaTool(part);\n return <Marker {...marker} />;\n }\n\n return null;\n};\n\nconst UserMessage = ({ message }: { message: UserMessageType }) => {\n const hasText = message.parts.some(\n (content) => content.type === 'text' && content.text.trim() !== ''\n );\n const attachments = message.parts.filter((content) => content.type === 'file');\n\n return (\n <AnimatedBox\n as={Flex}\n direction=\"column\"\n alignItems=\"flex-end\"\n style={{ alignSelf: 'flex-end' }}\n gap={2}\n maxWidth=\"80%\"\n >\n {hasText ? (\n <Box background=\"neutral150\" borderStyle=\"none\" padding={['10px', '16px']} hasRadius>\n {message.parts.map((content, index) => {\n if (content.type !== 'text') return null;\n return <UserMessageTypography key={index}>{content.text}</UserMessageTypography>;\n })}\n </Box>\n ) : null}\n\n {/* Attachments */}\n {attachments.map((attachment, idx) => (\n <AttachmentPreview\n key={`${attachment.type === 'file' ? attachment.filename : attachment.type}-${idx}`}\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n attachment={{ ...attachment, status: 'ready' } as any}\n />\n ))}\n </AnimatedBox>\n );\n};\n\nconst AssistantMessage = ({\n message,\n isLoading,\n}: {\n message: AssistantMessageType;\n isLoading?: boolean;\n}) => {\n const { upvoteMessage } = useFeedback();\n const { openFeedbackModal } = useFeedbackModal();\n\n return (\n <Box style={{ alignSelf: 'flex-start' }} maxWidth=\"90%\">\n {message.parts.map((content, index) => (\n <MessageContent key={index} part={content} />\n ))}\n {isLoading ? (\n <Flex gap={1}>\n <IconButton\n label=\"Upvote\"\n size=\"XS\"\n variant=\"ghost\"\n onClick={() => upvoteMessage(message.id)}\n >\n <ThumbUp />\n </IconButton>\n <IconButton\n label=\"Downvote\"\n size=\"XS\"\n variant=\"ghost\"\n // For downvoting, user must provide specific feedback\n onClick={() => openFeedbackModal(message.id)}\n >\n <ThumbDown />\n </IconButton>\n </Flex>\n ) : null}\n </Box>\n );\n};\n\nexport const ChatMessage = ({ message }: { message: AIMessage }) => {\n /**\n * IMPORTANT: Messages are rendered using react-markdown (heavy compute)\n * Component re-renders on each message update, but AI SDK v5 provides\n * throttling (experimental_throttle: 100ms) which batches updates and reduces\n * re-render frequency during streaming.\n */\n if (message.role === 'user') {\n return <UserMessage message={message as UserMessageType} />;\n }\n return <AssistantMessage message={message as AssistantMessageType} />;\n};\n"],"names":["MarkdownStyles","styled","Typography","theme","colors","neutral100","borderRadius","neutral150","primary500","UserMessageTypography","isSchemaToolPart","part","type","capitalize","s","charAt","toUpperCase","slice","getSchemaLink","schema","isComponent","kind","modelType","uid","undefined","category","toMarkerFromSchemaTool","outSchemas","output","schemas","inSchemas","input","length","numSchemas","state","error","steps","map","index","id","toolCallId","name","description","status","action","link","title","MessageContent","_jsx","Markdown","components","a","node","_node","props","target","rel","text","marker","Marker","UserMessage","message","hasText","parts","some","content","trim","attachments","filter","_jsxs","AnimatedBox","as","Flex","direction","alignItems","style","alignSelf","gap","maxWidth","Box","background","borderStyle","padding","hasRadius","attachment","idx","AttachmentPreview","filename","AssistantMessage","isLoading","upvoteMessage","useFeedback","openFeedbackModal","useFeedbackModal","IconButton","label","size","variant","onClick","ThumbUp","ThumbDown","ChatMessage","role"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Message.mjs","sources":["../../../../../../admin/src/components/AIChat/components/Messages/Message.tsx"],"sourcesContent":["import { useId, useRef } from 'react';\n\nimport { Typography, Box, IconButton, Flex } from '@strapi/design-system';\nimport { ThumbUp, ThumbDown } from '@strapi/icons';\nimport Markdown from 'react-markdown';\nimport { styled } from 'styled-components';\n\nimport { useFeedbackModal } from '../../FeedbackModal';\nimport { useFeedback } from '../../hooks/useFeedback';\nimport {\n AIMessage,\n type UserMessage as UserMessageType,\n AssistantMessage as AssistantMessageType,\n type MarkerContent as MarkerContentType,\n} from '../../lib/types/messages';\nimport { AnimatedBox } from '../AnimatedBox';\nimport { AttachmentPreview } from '../Attachments/AttachmentPreview';\n\nimport { Marker } from './Marker';\n\nconst MarkdownStyles = styled(Typography)`\n max-width: 65ch;\n margin: 0 auto;\n overflow-wrap: anywhere;\n word-break: break-word;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-top: 1.25em;\n margin-bottom: 0.5em;\n font-weight: bold;\n }\n\n p {\n margin-bottom: 1em;\n }\n\n ul,\n ol {\n padding-left: 1.5em; /* indentation for bullet points */\n margin-bottom: 1em;\n }\n\n li {\n margin-bottom: 0.5em;\n list-style-type: disc; /* or whatever style you prefer */\n }\n\n strong {\n font-weight: bold;\n }\n\n /* code blocks, blockquotes, etc. */\n code {\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n font-family:\n 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas, monospace;\n }\n\n /* links */\n a {\n color: ${({ theme }) => theme.colors.primary500};\n background-color: ${({ theme }) => theme.colors.neutral100};\n padding: 0.2em 0.4em;\n border-radius: ${({ theme }) => theme.borderRadius};\n border-color: ${({ theme }) => theme.colors.neutral150};\n border-style: solid;\n text-decoration: none;\n\n &:hover {\n text-decoration: underline;\n }\n }\n`;\n\nconst UserMessageTypography = styled(Typography)`\n overflow-wrap: anywhere;\n word-break: break-word;\n`;\n\n// ---------------------------\n// Tool: schemaGenerationTool helpers\n// ---------------------------\n\ntype SchemaToolSchema = {\n action?: 'create' | 'update' | 'remove';\n uid?: string;\n name?: string;\n category?: string;\n kind?: 'collectionType' | 'singleType' | 'component';\n modelType?: 'component' | 'collectionType' | 'singleType';\n};\n\ntype SchemaToolPart = {\n type: 'tool-schemaGenerationTool';\n input?: { schemas?: SchemaToolSchema[] };\n output?: { schemas?: SchemaToolSchema[]; error?: unknown };\n toolCallId?: string;\n};\n\nconst isSchemaToolPart = (part: unknown): part is SchemaToolPart => {\n if (typeof part !== 'object' || part === null || !('type' in part)) {\n return false;\n }\n\n return part.type === 'tool-schemaGenerationTool';\n};\n\n/**\n * Exported for unit tests only. The AI chat needs a live AI backend, so no E2E\n * run can reach this logic.\n */\nexport const getPartFingerprint = (part: AIMessage['parts'][number]) => {\n if (part.type === 'text') {\n return `text:${part.text}`;\n }\n\n if (part.type === 'file') {\n return `file:${part.filename ?? ''}:${part.mediaType}:${part.url}`;\n }\n\n if ('toolCallId' in part && typeof part.toolCallId === 'string') {\n return `${part.type}:${part.toolCallId}`;\n }\n\n return part.type;\n};\n\ntype PartRecord = {\n fingerprint: string;\n key: string;\n part: AIMessage['parts'][number];\n};\n\n/**\n * Gives each part a key that survives across renders. A key derived from the\n * part content alone cannot work: a streaming text part changes on every chunk,\n * so its fingerprint would change on every tick and remount the node mid\n * stream. Hence the fallback chain below: exact fingerprint match first, then\n * object identity, then same slot and same type for the streaming case.\n *\n * Exported for unit tests only. The AI chat needs a live AI backend, so no E2E\n * run can reach this logic.\n */\nexport const usePartsWithKeys = (parts: AIMessage['parts']) => {\n const keyPrefix = useId();\n const nextKey = useRef(0);\n const previousParts = useRef<PartRecord[]>([]);\n const matchedParts = new Set<PartRecord>();\n\n const exactMatches = parts.map((part) => {\n const fingerprint = getPartFingerprint(part);\n const exactMatch = previousParts.current.find(\n (candidate) => candidate.fingerprint === fingerprint && !matchedParts.has(candidate)\n );\n const sameObject = previousParts.current.find(\n (candidate) => candidate.part === part && !matchedParts.has(candidate)\n );\n const previousPart = exactMatch ?? sameObject;\n\n if (previousPart) {\n matchedParts.add(previousPart);\n }\n\n return { fingerprint, part, previousPart };\n });\n\n const keyedParts = exactMatches.map(({ fingerprint, part, previousPart }, index) => {\n const sameSlot = previousParts.current[index];\n const streamingMatch =\n !previousPart && sameSlot && sameSlot.part.type === part.type && !matchedParts.has(sameSlot)\n ? sameSlot\n : undefined;\n const matchedPart = previousPart ?? streamingMatch;\n const key = matchedPart?.key ?? `${keyPrefix}-${nextKey.current}`;\n\n if (streamingMatch) {\n matchedParts.add(streamingMatch);\n }\n\n if (matchedPart) {\n matchedParts.add(matchedPart);\n } else {\n nextKey.current += 1;\n }\n\n return { fingerprint, key, part };\n });\n\n /**\n * Both refs are written during render. The outcome depends only on the parts\n * passed in, so re-invoking the render function is harmless: on the second\n * pass of a StrictMode double render every part exact-matches the record the\n * first pass stored here, the same keys come back out and `nextKey` does not\n * advance.\n */\n previousParts.current = keyedParts;\n\n return keyedParts;\n};\n\nconst capitalize = (s?: string) => (s ? s.charAt(0).toUpperCase() + s.slice(1) : '');\n\nconst getSchemaLink = (schema: SchemaToolSchema): string | undefined => {\n const isComponent = (schema.kind ?? schema.modelType) === 'component';\n if (!schema.uid) return undefined;\n return isComponent\n ? `/plugins/content-type-builder/component-categories/${schema.category ?? ''}/${schema.uid}`\n : `/plugins/content-type-builder/content-types/${schema.uid}`;\n};\n\nconst toMarkerFromSchemaTool = (part: SchemaToolPart): MarkerContentType => {\n const outSchemas = part.output?.schemas ?? [];\n const inSchemas = part.input?.schemas ?? [];\n\n const schemas = (outSchemas.length ? outSchemas : inSchemas) as SchemaToolSchema[];\n const numSchemas = schemas.length;\n\n const state: 'loading' | 'success' | 'error' = part.output\n ? part.output.error\n ? 'error'\n : 'success'\n : 'loading';\n\n const steps = schemas.map((schema, index) => ({\n id: `${part.toolCallId ?? 'schemaGenerationTool'}-${schema.uid ?? schema.name ?? index}`,\n description: capitalize(schema.name ?? schema.uid ?? 'Schema'),\n status:\n schema.action === 'create' || schema.action === 'update' || schema.action === 'remove'\n ? schema.action\n : ('update' as const),\n link: getSchemaLink(schema),\n }));\n\n const title =\n state === 'success'\n ? `Updated ${numSchemas} schema${numSchemas === 1 ? '' : 's'}`\n : state === 'error'\n ? `Failed to update schema${numSchemas === 1 ? '' : 's'}`\n : 'Updating schemas';\n\n return {\n type: 'marker',\n title,\n state,\n steps,\n };\n};\n\nconst MessageContent = ({\n part,\n}: {\n part: AIMessage['parts'][number];\n status?: 'loading' | 'success' | 'error';\n}) => {\n if (part.type === 'text') {\n return (\n <MarkdownStyles>\n <Markdown\n components={{\n a: ({ node: _node, ...props }) => (\n <a target=\"_blank\" rel=\"noopener noreferrer\" {...props} />\n ),\n }}\n >\n {part.text}\n </Markdown>\n </MarkdownStyles>\n );\n }\n\n if (isSchemaToolPart(part)) {\n const marker = toMarkerFromSchemaTool(part);\n return <Marker {...marker} />;\n }\n\n return null;\n};\n\nconst UserMessage = ({ message }: { message: UserMessageType }) => {\n const partsWithKeys = usePartsWithKeys(message.parts);\n const hasText = partsWithKeys.some(({ part }) => part.type === 'text' && part.text.trim() !== '');\n const attachments = partsWithKeys.filter(({ part }) => part.type === 'file');\n\n return (\n <AnimatedBox\n as={Flex}\n direction=\"column\"\n alignItems=\"flex-end\"\n style={{ alignSelf: 'flex-end' }}\n gap={2}\n maxWidth=\"80%\"\n >\n {hasText ? (\n <Box background=\"neutral150\" borderStyle=\"none\" padding={['10px', '16px']} hasRadius>\n {partsWithKeys.map(({ key, part }) => {\n if (part.type !== 'text') return null;\n return <UserMessageTypography key={key}>{part.text}</UserMessageTypography>;\n })}\n </Box>\n ) : null}\n\n {/* Attachments */}\n {attachments.map(({ key, part }) => (\n <AttachmentPreview\n key={key}\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n attachment={{ ...part, status: 'ready' } as any}\n />\n ))}\n </AnimatedBox>\n );\n};\n\nconst AssistantMessage = ({\n message,\n isLoading,\n}: {\n message: AssistantMessageType;\n isLoading?: boolean;\n}) => {\n const { upvoteMessage } = useFeedback();\n const { openFeedbackModal } = useFeedbackModal();\n const partsWithKeys = usePartsWithKeys(message.parts);\n\n return (\n <Box style={{ alignSelf: 'flex-start' }} maxWidth=\"90%\">\n {partsWithKeys.map(({ key, part }) => (\n <MessageContent key={key} part={part} />\n ))}\n {isLoading ? (\n <Flex gap={1}>\n <IconButton\n label=\"Upvote\"\n size=\"XS\"\n variant=\"ghost\"\n onClick={() => upvoteMessage(message.id)}\n >\n <ThumbUp />\n </IconButton>\n <IconButton\n label=\"Downvote\"\n size=\"XS\"\n variant=\"ghost\"\n // For downvoting, user must provide specific feedback\n onClick={() => openFeedbackModal(message.id)}\n >\n <ThumbDown />\n </IconButton>\n </Flex>\n ) : null}\n </Box>\n );\n};\n\nexport const ChatMessage = ({ message }: { message: AIMessage }) => {\n /**\n * IMPORTANT: Messages are rendered using react-markdown (heavy compute)\n * Component re-renders on each message update, but AI SDK v5 provides\n * throttling (experimental_throttle: 100ms) which batches updates and reduces\n * re-render frequency during streaming.\n */\n if (message.role === 'user') {\n return <UserMessage message={message as UserMessageType} />;\n }\n return <AssistantMessage message={message as AssistantMessageType} />;\n};\n"],"names":["MarkdownStyles","styled","Typography","theme","colors","neutral100","borderRadius","neutral150","primary500","UserMessageTypography","isSchemaToolPart","part","type","getPartFingerprint","text","filename","mediaType","url","toolCallId","usePartsWithKeys","parts","keyPrefix","useId","nextKey","useRef","previousParts","matchedParts","Set","exactMatches","map","fingerprint","exactMatch","current","find","candidate","has","sameObject","previousPart","add","keyedParts","index","sameSlot","streamingMatch","undefined","matchedPart","key","capitalize","s","charAt","toUpperCase","slice","getSchemaLink","schema","isComponent","kind","modelType","uid","category","toMarkerFromSchemaTool","outSchemas","output","schemas","inSchemas","input","length","numSchemas","state","error","steps","id","name","description","status","action","link","title","MessageContent","_jsx","Markdown","components","a","node","_node","props","target","rel","marker","Marker","UserMessage","message","partsWithKeys","hasText","some","trim","attachments","filter","_jsxs","AnimatedBox","as","Flex","direction","alignItems","style","alignSelf","gap","maxWidth","Box","background","borderStyle","padding","hasRadius","AttachmentPreview","attachment","AssistantMessage","isLoading","upvoteMessage","useFeedback","openFeedbackModal","useFeedbackModal","IconButton","label","size","variant","onClick","ThumbUp","ThumbDown","ChatMessage","role"],"mappings":"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"}
|
|
@@ -16,7 +16,9 @@ const StepModal = ({ open, onOpenChange, title, children, onComplete, onCancel }
|
|
|
16
16
|
const [currentStep, setCurrentStep] = React.useState(0);
|
|
17
17
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
18
18
|
const [error, setError] = React.useState(null);
|
|
19
|
-
const childrenArray = React.Children.toArray(children).filter((child)=>/*#__PURE__*/ React.isValidElement(child)).map((child)=>child.props)
|
|
19
|
+
const childrenArray = React.useMemo(()=>React.Children.toArray(children).filter((child)=>/*#__PURE__*/ React.isValidElement(child)).map((child)=>child.props), [
|
|
20
|
+
children
|
|
21
|
+
]);
|
|
20
22
|
const totalSteps = childrenArray.length;
|
|
21
23
|
const isFirstStep = currentStep === 0;
|
|
22
24
|
const isLastStep = currentStep === totalSteps - 1;
|
|
@@ -31,21 +33,25 @@ const StepModal = ({ open, onOpenChange, title, children, onComplete, onCancel }
|
|
|
31
33
|
}, [
|
|
32
34
|
open
|
|
33
35
|
]);
|
|
34
|
-
const resetStates = ()=>{
|
|
36
|
+
const resetStates = React.useCallback(()=>{
|
|
35
37
|
setCurrentStep(0);
|
|
36
38
|
setIsLoading(false);
|
|
37
39
|
setError(null);
|
|
38
|
-
};
|
|
39
|
-
const handleCancel = ()=>{
|
|
40
|
+
}, []);
|
|
41
|
+
const handleCancel = React.useCallback(()=>{
|
|
40
42
|
onCancel?.();
|
|
41
43
|
resetStates();
|
|
42
44
|
onOpenChange(false);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
+
}, [
|
|
46
|
+
onCancel,
|
|
47
|
+
onOpenChange,
|
|
48
|
+
resetStates
|
|
49
|
+
]);
|
|
50
|
+
const handleBack = React.useCallback(()=>{
|
|
45
51
|
setCurrentStep((prev)=>Math.max(0, prev - 1));
|
|
46
52
|
setError(null);
|
|
47
|
-
};
|
|
48
|
-
const nextStep = async ()=>{
|
|
53
|
+
}, []);
|
|
54
|
+
const nextStep = React.useCallback(async ()=>{
|
|
49
55
|
const currentStepProps = childrenArray[currentStep];
|
|
50
56
|
if (currentStepProps.onNext) {
|
|
51
57
|
setIsLoading(true);
|
|
@@ -77,26 +83,47 @@ const StepModal = ({ open, onOpenChange, title, children, onComplete, onCancel }
|
|
|
77
83
|
}
|
|
78
84
|
return true;
|
|
79
85
|
}
|
|
80
|
-
}
|
|
86
|
+
}, [
|
|
87
|
+
childrenArray,
|
|
88
|
+
currentStep,
|
|
89
|
+
isLastStep,
|
|
90
|
+
onComplete,
|
|
91
|
+
onOpenChange,
|
|
92
|
+
resetStates
|
|
93
|
+
]);
|
|
81
94
|
// Handle form submission (triggered by Enter key)
|
|
82
|
-
const handleFormSubmit = (e)=>{
|
|
95
|
+
const handleFormSubmit = React.useCallback((e)=>{
|
|
83
96
|
e.preventDefault();
|
|
84
97
|
if (!isLoading && !childrenArray[currentStep]?.disableNext) {
|
|
85
98
|
nextStep();
|
|
86
99
|
}
|
|
87
|
-
}
|
|
88
|
-
|
|
100
|
+
}, [
|
|
101
|
+
childrenArray,
|
|
102
|
+
currentStep,
|
|
103
|
+
isLoading,
|
|
104
|
+
nextStep
|
|
105
|
+
]);
|
|
106
|
+
const contextValue = React.useMemo(()=>({
|
|
107
|
+
currentStep,
|
|
108
|
+
goToStep: setCurrentStep,
|
|
109
|
+
nextStep,
|
|
110
|
+
prevStep: handleBack,
|
|
111
|
+
isFirstStep,
|
|
112
|
+
isLastStep,
|
|
113
|
+
totalSteps,
|
|
114
|
+
isLoading,
|
|
115
|
+
error,
|
|
116
|
+
setError
|
|
117
|
+
}), [
|
|
89
118
|
currentStep,
|
|
90
|
-
goToStep: setCurrentStep,
|
|
91
119
|
nextStep,
|
|
92
|
-
|
|
120
|
+
handleBack,
|
|
93
121
|
isFirstStep,
|
|
94
122
|
isLastStep,
|
|
95
123
|
totalSteps,
|
|
96
124
|
isLoading,
|
|
97
|
-
error
|
|
98
|
-
|
|
99
|
-
};
|
|
125
|
+
error
|
|
126
|
+
]);
|
|
100
127
|
const currentChild = childrenArray[currentStep];
|
|
101
128
|
return /*#__PURE__*/ jsxRuntime.jsx(StepModalContext.Provider, {
|
|
102
129
|
value: contextValue,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StepModal.js","sources":["../../../../../admin/src/components/AIChat/components/StepModal.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n useState,\n ReactNode,\n Children,\n isValidElement,\n FormEvent,\n useEffect,\n} from 'react';\n\nimport { Modal, Box, Button, Typography } from '@strapi/design-system';\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface StepModalContextType {\n currentStep: number;\n goToStep: (step: number) => void;\n nextStep: () => Promise<boolean>;\n prevStep: () => void;\n isFirstStep: boolean;\n isLastStep: boolean;\n totalSteps: number;\n isLoading: boolean;\n error: Error | null;\n setError: (error: Error | null) => void;\n}\n\nconst StepModalContext = createContext<StepModalContextType | null>(null);\n\nexport const useStepModal = () => {\n const context = useContext(StepModalContext);\n if (!context) {\n throw new Error('useStepModal must be used within a StepModal');\n }\n return context;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * StepModal\n * -----------------------------------------------------------------------------------------------*/\n\ninterface StepModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title?: string;\n children: ReactNode;\n onComplete?: () => void;\n onCancel?: () => void;\n}\n\ninterface StepProps {\n title?: string;\n children: ReactNode;\n nextLabel?: string;\n cancelLabel?: string;\n backLabel?: string;\n disableNext?: boolean;\n onNext?: () => Promise<boolean> | boolean;\n}\n\nconst StepModal = ({\n open,\n onOpenChange,\n title,\n children,\n onComplete,\n onCancel,\n}: StepModalProps) => {\n const [currentStep, setCurrentStep] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const childrenArray = Children.toArray(children)\n .filter((child): child is React.ReactElement => isValidElement(child))\n .map((child) => child.props);\n\n const totalSteps = childrenArray.length;\n const isFirstStep = currentStep === 0;\n const isLastStep = currentStep === totalSteps - 1;\n\n // Reset states when modal opens/closes\n useEffect(() => {\n if (!open) {\n // Reset states when modal is closed\n setCurrentStep(0);\n setIsLoading(false);\n setError(null);\n }\n }, [open]);\n\n const resetStates = () => {\n setCurrentStep(0);\n setIsLoading(false);\n setError(null);\n };\n\n const handleCancel = () => {\n onCancel?.();\n resetStates();\n onOpenChange(false);\n };\n\n const handleBack = () => {\n setCurrentStep((prev) => Math.max(0, prev - 1));\n setError(null);\n };\n\n const nextStep = async () => {\n const currentStepProps = childrenArray[currentStep];\n\n if (currentStepProps.onNext) {\n setIsLoading(true);\n setError(null);\n\n try {\n if (isLastStep) {\n onComplete?.();\n resetStates();\n onOpenChange(false);\n } else {\n await currentStepProps.onNext();\n setCurrentStep((prev) => prev + 1);\n }\n return true;\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n return false;\n } finally {\n setIsLoading(false);\n }\n } else {\n // Default behavior: just move to next step\n if (isLastStep) {\n onComplete?.();\n resetStates();\n onOpenChange(false);\n } else {\n setCurrentStep((prev) => prev + 1);\n }\n return true;\n }\n };\n\n // Handle form submission (triggered by Enter key)\n const handleFormSubmit = (e: FormEvent) => {\n e.preventDefault();\n if (!isLoading && !childrenArray[currentStep]?.disableNext) {\n nextStep();\n }\n };\n\n const contextValue = {\n currentStep,\n goToStep: setCurrentStep,\n nextStep,\n prevStep: handleBack,\n isFirstStep,\n isLastStep,\n totalSteps,\n isLoading,\n error,\n setError,\n };\n\n const currentChild = childrenArray[currentStep];\n\n return (\n <StepModalContext.Provider value={contextValue}>\n {open && (\n <Modal.Root open onOpenChange={handleCancel}>\n <Modal.Content>\n <Modal.Header>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {currentChild?.title || title}\n </Typography>\n </Modal.Header>\n\n <form onSubmit={handleFormSubmit}>\n <Modal.Body>\n {Children.toArray(children)[currentStep]}\n\n {error && (\n <Box\n marginTop={4}\n padding={3}\n background=\"danger100\"\n color=\"danger600\"\n borderRadius=\"4px\"\n >\n <Typography variant=\"pi\">{error.message}</Typography>\n </Box>\n )}\n </Modal.Body>\n\n <Modal.Footer>\n {isFirstStep ? (\n <Button variant=\"tertiary\" onClick={handleCancel} type=\"button\">\n {currentChild?.cancelLabel || 'Cancel'}\n </Button>\n ) : (\n <Button variant=\"tertiary\" onClick={handleBack} type=\"button\">\n {currentChild?.backLabel || 'Back'}\n </Button>\n )}\n\n <Button\n variant=\"default\"\n type=\"submit\"\n disabled={isLoading || currentChild?.disableNext}\n loading={isLoading}\n >\n {currentChild?.nextLabel || (isLastStep ? 'Complete' : 'Next')}\n </Button>\n </Modal.Footer>\n </form>\n </Modal.Content>\n </Modal.Root>\n )}\n </StepModalContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step\n * -----------------------------------------------------------------------------------------------*/\n\nconst Step = ({ children }: StepProps) => {\n return <>{children}</>;\n};\n\nStepModal.Step = Step;\n\nexport { StepModal, Step };\n"],"names":["StepModalContext","createContext","useStepModal","context","useContext","Error","StepModal","open","onOpenChange","title","children","onComplete","onCancel","currentStep","setCurrentStep","useState","isLoading","setIsLoading","error","setError","childrenArray","Children","toArray","filter","child","isValidElement","map","props","totalSteps","length","isFirstStep","isLastStep","useEffect","resetStates","handleCancel","handleBack","prev","Math","max","nextStep","currentStepProps","onNext","err","String","handleFormSubmit","e","preventDefault","disableNext","contextValue","goToStep","prevStep","currentChild","_jsx","Provider","value","Modal","Root","_jsxs","Content","Header","Typography","variant","fontWeight","form","onSubmit","Body","Box","marginTop","padding","background","color","borderRadius","message","Footer","Button","onClick","type","cancelLabel","backLabel","disabled","loading","nextLabel","Step","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StepModal.js","sources":["../../../../../admin/src/components/AIChat/components/StepModal.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n useState,\n ReactNode,\n Children,\n isValidElement,\n FormEvent,\n useCallback,\n useEffect,\n useMemo,\n} from 'react';\n\nimport { Modal, Box, Button, Typography } from '@strapi/design-system';\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface StepModalContextType {\n currentStep: number;\n goToStep: (step: number) => void;\n nextStep: () => Promise<boolean>;\n prevStep: () => void;\n isFirstStep: boolean;\n isLastStep: boolean;\n totalSteps: number;\n isLoading: boolean;\n error: Error | null;\n setError: (error: Error | null) => void;\n}\n\nconst StepModalContext = createContext<StepModalContextType | null>(null);\n\nexport const useStepModal = () => {\n const context = useContext(StepModalContext);\n if (!context) {\n throw new Error('useStepModal must be used within a StepModal');\n }\n return context;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * StepModal\n * -----------------------------------------------------------------------------------------------*/\n\ninterface StepModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title?: string;\n children: ReactNode;\n onComplete?: () => void;\n onCancel?: () => void;\n}\n\ninterface StepProps {\n title?: string;\n children: ReactNode;\n nextLabel?: string;\n cancelLabel?: string;\n backLabel?: string;\n disableNext?: boolean;\n onNext?: () => Promise<boolean> | boolean;\n}\n\nconst StepModal = ({\n open,\n onOpenChange,\n title,\n children,\n onComplete,\n onCancel,\n}: StepModalProps) => {\n const [currentStep, setCurrentStep] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const childrenArray = useMemo(\n () =>\n Children.toArray(children)\n .filter((child): child is React.ReactElement => isValidElement(child))\n .map((child) => child.props),\n [children]\n );\n\n const totalSteps = childrenArray.length;\n const isFirstStep = currentStep === 0;\n const isLastStep = currentStep === totalSteps - 1;\n\n // Reset states when modal opens/closes\n useEffect(() => {\n if (!open) {\n // Reset states when modal is closed\n setCurrentStep(0);\n setIsLoading(false);\n setError(null);\n }\n }, [open]);\n\n const resetStates = useCallback(() => {\n setCurrentStep(0);\n setIsLoading(false);\n setError(null);\n }, []);\n\n const handleCancel = useCallback(() => {\n onCancel?.();\n resetStates();\n onOpenChange(false);\n }, [onCancel, onOpenChange, resetStates]);\n\n const handleBack = useCallback(() => {\n setCurrentStep((prev) => Math.max(0, prev - 1));\n setError(null);\n }, []);\n\n const nextStep = useCallback(async () => {\n const currentStepProps = childrenArray[currentStep];\n\n if (currentStepProps.onNext) {\n setIsLoading(true);\n setError(null);\n\n try {\n if (isLastStep) {\n onComplete?.();\n resetStates();\n onOpenChange(false);\n } else {\n await currentStepProps.onNext();\n setCurrentStep((prev) => prev + 1);\n }\n return true;\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n return false;\n } finally {\n setIsLoading(false);\n }\n } else {\n // Default behavior: just move to next step\n if (isLastStep) {\n onComplete?.();\n resetStates();\n onOpenChange(false);\n } else {\n setCurrentStep((prev) => prev + 1);\n }\n return true;\n }\n }, [childrenArray, currentStep, isLastStep, onComplete, onOpenChange, resetStates]);\n\n // Handle form submission (triggered by Enter key)\n const handleFormSubmit = useCallback(\n (e: FormEvent) => {\n e.preventDefault();\n if (!isLoading && !childrenArray[currentStep]?.disableNext) {\n nextStep();\n }\n },\n [childrenArray, currentStep, isLoading, nextStep]\n );\n\n const contextValue = useMemo(\n () => ({\n currentStep,\n goToStep: setCurrentStep,\n nextStep,\n prevStep: handleBack,\n isFirstStep,\n isLastStep,\n totalSteps,\n isLoading,\n error,\n setError,\n }),\n [currentStep, nextStep, handleBack, isFirstStep, isLastStep, totalSteps, isLoading, error]\n );\n\n const currentChild = childrenArray[currentStep];\n\n return (\n <StepModalContext.Provider value={contextValue}>\n {open && (\n <Modal.Root open onOpenChange={handleCancel}>\n <Modal.Content>\n <Modal.Header>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {currentChild?.title || title}\n </Typography>\n </Modal.Header>\n\n <form onSubmit={handleFormSubmit}>\n <Modal.Body>\n {Children.toArray(children)[currentStep]}\n\n {error && (\n <Box\n marginTop={4}\n padding={3}\n background=\"danger100\"\n color=\"danger600\"\n borderRadius=\"4px\"\n >\n <Typography variant=\"pi\">{error.message}</Typography>\n </Box>\n )}\n </Modal.Body>\n\n <Modal.Footer>\n {isFirstStep ? (\n <Button variant=\"tertiary\" onClick={handleCancel} type=\"button\">\n {currentChild?.cancelLabel || 'Cancel'}\n </Button>\n ) : (\n <Button variant=\"tertiary\" onClick={handleBack} type=\"button\">\n {currentChild?.backLabel || 'Back'}\n </Button>\n )}\n\n <Button\n variant=\"default\"\n type=\"submit\"\n disabled={isLoading || currentChild?.disableNext}\n loading={isLoading}\n >\n {currentChild?.nextLabel || (isLastStep ? 'Complete' : 'Next')}\n </Button>\n </Modal.Footer>\n </form>\n </Modal.Content>\n </Modal.Root>\n )}\n </StepModalContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step\n * -----------------------------------------------------------------------------------------------*/\n\nconst Step = ({ children }: StepProps) => {\n return <>{children}</>;\n};\n\nStepModal.Step = Step;\n\nexport { StepModal, Step };\n"],"names":["StepModalContext","createContext","useStepModal","context","useContext","Error","StepModal","open","onOpenChange","title","children","onComplete","onCancel","currentStep","setCurrentStep","useState","isLoading","setIsLoading","error","setError","childrenArray","useMemo","Children","toArray","filter","child","isValidElement","map","props","totalSteps","length","isFirstStep","isLastStep","useEffect","resetStates","useCallback","handleCancel","handleBack","prev","Math","max","nextStep","currentStepProps","onNext","err","String","handleFormSubmit","e","preventDefault","disableNext","contextValue","goToStep","prevStep","currentChild","_jsx","Provider","value","Modal","Root","_jsxs","Content","Header","Typography","variant","fontWeight","form","onSubmit","Body","Box","marginTop","padding","background","color","borderRadius","message","Footer","Button","onClick","type","cancelLabel","backLabel","disabled","loading","nextLabel","Step","_Fragment"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { useState, Children, isValidElement, useEffect, createContext, useContext } from 'react';
|
|
2
|
+
import { useState, useMemo, Children, isValidElement, useEffect, useCallback, createContext, useContext } from 'react';
|
|
3
3
|
import { Modal, Typography, Box, Button } from '@strapi/design-system';
|
|
4
4
|
|
|
5
5
|
const StepModalContext = /*#__PURE__*/ createContext(null);
|
|
@@ -14,7 +14,9 @@ const StepModal = ({ open, onOpenChange, title, children, onComplete, onCancel }
|
|
|
14
14
|
const [currentStep, setCurrentStep] = useState(0);
|
|
15
15
|
const [isLoading, setIsLoading] = useState(false);
|
|
16
16
|
const [error, setError] = useState(null);
|
|
17
|
-
const childrenArray = Children.toArray(children).filter((child)=>/*#__PURE__*/ isValidElement(child)).map((child)=>child.props)
|
|
17
|
+
const childrenArray = useMemo(()=>Children.toArray(children).filter((child)=>/*#__PURE__*/ isValidElement(child)).map((child)=>child.props), [
|
|
18
|
+
children
|
|
19
|
+
]);
|
|
18
20
|
const totalSteps = childrenArray.length;
|
|
19
21
|
const isFirstStep = currentStep === 0;
|
|
20
22
|
const isLastStep = currentStep === totalSteps - 1;
|
|
@@ -29,21 +31,25 @@ const StepModal = ({ open, onOpenChange, title, children, onComplete, onCancel }
|
|
|
29
31
|
}, [
|
|
30
32
|
open
|
|
31
33
|
]);
|
|
32
|
-
const resetStates = ()=>{
|
|
34
|
+
const resetStates = useCallback(()=>{
|
|
33
35
|
setCurrentStep(0);
|
|
34
36
|
setIsLoading(false);
|
|
35
37
|
setError(null);
|
|
36
|
-
};
|
|
37
|
-
const handleCancel = ()=>{
|
|
38
|
+
}, []);
|
|
39
|
+
const handleCancel = useCallback(()=>{
|
|
38
40
|
onCancel?.();
|
|
39
41
|
resetStates();
|
|
40
42
|
onOpenChange(false);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
+
}, [
|
|
44
|
+
onCancel,
|
|
45
|
+
onOpenChange,
|
|
46
|
+
resetStates
|
|
47
|
+
]);
|
|
48
|
+
const handleBack = useCallback(()=>{
|
|
43
49
|
setCurrentStep((prev)=>Math.max(0, prev - 1));
|
|
44
50
|
setError(null);
|
|
45
|
-
};
|
|
46
|
-
const nextStep = async ()=>{
|
|
51
|
+
}, []);
|
|
52
|
+
const nextStep = useCallback(async ()=>{
|
|
47
53
|
const currentStepProps = childrenArray[currentStep];
|
|
48
54
|
if (currentStepProps.onNext) {
|
|
49
55
|
setIsLoading(true);
|
|
@@ -75,26 +81,47 @@ const StepModal = ({ open, onOpenChange, title, children, onComplete, onCancel }
|
|
|
75
81
|
}
|
|
76
82
|
return true;
|
|
77
83
|
}
|
|
78
|
-
}
|
|
84
|
+
}, [
|
|
85
|
+
childrenArray,
|
|
86
|
+
currentStep,
|
|
87
|
+
isLastStep,
|
|
88
|
+
onComplete,
|
|
89
|
+
onOpenChange,
|
|
90
|
+
resetStates
|
|
91
|
+
]);
|
|
79
92
|
// Handle form submission (triggered by Enter key)
|
|
80
|
-
const handleFormSubmit = (e)=>{
|
|
93
|
+
const handleFormSubmit = useCallback((e)=>{
|
|
81
94
|
e.preventDefault();
|
|
82
95
|
if (!isLoading && !childrenArray[currentStep]?.disableNext) {
|
|
83
96
|
nextStep();
|
|
84
97
|
}
|
|
85
|
-
}
|
|
86
|
-
|
|
98
|
+
}, [
|
|
99
|
+
childrenArray,
|
|
100
|
+
currentStep,
|
|
101
|
+
isLoading,
|
|
102
|
+
nextStep
|
|
103
|
+
]);
|
|
104
|
+
const contextValue = useMemo(()=>({
|
|
105
|
+
currentStep,
|
|
106
|
+
goToStep: setCurrentStep,
|
|
107
|
+
nextStep,
|
|
108
|
+
prevStep: handleBack,
|
|
109
|
+
isFirstStep,
|
|
110
|
+
isLastStep,
|
|
111
|
+
totalSteps,
|
|
112
|
+
isLoading,
|
|
113
|
+
error,
|
|
114
|
+
setError
|
|
115
|
+
}), [
|
|
87
116
|
currentStep,
|
|
88
|
-
goToStep: setCurrentStep,
|
|
89
117
|
nextStep,
|
|
90
|
-
|
|
118
|
+
handleBack,
|
|
91
119
|
isFirstStep,
|
|
92
120
|
isLastStep,
|
|
93
121
|
totalSteps,
|
|
94
122
|
isLoading,
|
|
95
|
-
error
|
|
96
|
-
|
|
97
|
-
};
|
|
123
|
+
error
|
|
124
|
+
]);
|
|
98
125
|
const currentChild = childrenArray[currentStep];
|
|
99
126
|
return /*#__PURE__*/ jsx(StepModalContext.Provider, {
|
|
100
127
|
value: contextValue,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StepModal.mjs","sources":["../../../../../admin/src/components/AIChat/components/StepModal.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n useState,\n ReactNode,\n Children,\n isValidElement,\n FormEvent,\n useEffect,\n} from 'react';\n\nimport { Modal, Box, Button, Typography } from '@strapi/design-system';\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface StepModalContextType {\n currentStep: number;\n goToStep: (step: number) => void;\n nextStep: () => Promise<boolean>;\n prevStep: () => void;\n isFirstStep: boolean;\n isLastStep: boolean;\n totalSteps: number;\n isLoading: boolean;\n error: Error | null;\n setError: (error: Error | null) => void;\n}\n\nconst StepModalContext = createContext<StepModalContextType | null>(null);\n\nexport const useStepModal = () => {\n const context = useContext(StepModalContext);\n if (!context) {\n throw new Error('useStepModal must be used within a StepModal');\n }\n return context;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * StepModal\n * -----------------------------------------------------------------------------------------------*/\n\ninterface StepModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title?: string;\n children: ReactNode;\n onComplete?: () => void;\n onCancel?: () => void;\n}\n\ninterface StepProps {\n title?: string;\n children: ReactNode;\n nextLabel?: string;\n cancelLabel?: string;\n backLabel?: string;\n disableNext?: boolean;\n onNext?: () => Promise<boolean> | boolean;\n}\n\nconst StepModal = ({\n open,\n onOpenChange,\n title,\n children,\n onComplete,\n onCancel,\n}: StepModalProps) => {\n const [currentStep, setCurrentStep] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const childrenArray = Children.toArray(children)\n .filter((child): child is React.ReactElement => isValidElement(child))\n .map((child) => child.props);\n\n const totalSteps = childrenArray.length;\n const isFirstStep = currentStep === 0;\n const isLastStep = currentStep === totalSteps - 1;\n\n // Reset states when modal opens/closes\n useEffect(() => {\n if (!open) {\n // Reset states when modal is closed\n setCurrentStep(0);\n setIsLoading(false);\n setError(null);\n }\n }, [open]);\n\n const resetStates = () => {\n setCurrentStep(0);\n setIsLoading(false);\n setError(null);\n };\n\n const handleCancel = () => {\n onCancel?.();\n resetStates();\n onOpenChange(false);\n };\n\n const handleBack = () => {\n setCurrentStep((prev) => Math.max(0, prev - 1));\n setError(null);\n };\n\n const nextStep = async () => {\n const currentStepProps = childrenArray[currentStep];\n\n if (currentStepProps.onNext) {\n setIsLoading(true);\n setError(null);\n\n try {\n if (isLastStep) {\n onComplete?.();\n resetStates();\n onOpenChange(false);\n } else {\n await currentStepProps.onNext();\n setCurrentStep((prev) => prev + 1);\n }\n return true;\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n return false;\n } finally {\n setIsLoading(false);\n }\n } else {\n // Default behavior: just move to next step\n if (isLastStep) {\n onComplete?.();\n resetStates();\n onOpenChange(false);\n } else {\n setCurrentStep((prev) => prev + 1);\n }\n return true;\n }\n };\n\n // Handle form submission (triggered by Enter key)\n const handleFormSubmit = (e: FormEvent) => {\n e.preventDefault();\n if (!isLoading && !childrenArray[currentStep]?.disableNext) {\n nextStep();\n }\n };\n\n const contextValue = {\n currentStep,\n goToStep: setCurrentStep,\n nextStep,\n prevStep: handleBack,\n isFirstStep,\n isLastStep,\n totalSteps,\n isLoading,\n error,\n setError,\n };\n\n const currentChild = childrenArray[currentStep];\n\n return (\n <StepModalContext.Provider value={contextValue}>\n {open && (\n <Modal.Root open onOpenChange={handleCancel}>\n <Modal.Content>\n <Modal.Header>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {currentChild?.title || title}\n </Typography>\n </Modal.Header>\n\n <form onSubmit={handleFormSubmit}>\n <Modal.Body>\n {Children.toArray(children)[currentStep]}\n\n {error && (\n <Box\n marginTop={4}\n padding={3}\n background=\"danger100\"\n color=\"danger600\"\n borderRadius=\"4px\"\n >\n <Typography variant=\"pi\">{error.message}</Typography>\n </Box>\n )}\n </Modal.Body>\n\n <Modal.Footer>\n {isFirstStep ? (\n <Button variant=\"tertiary\" onClick={handleCancel} type=\"button\">\n {currentChild?.cancelLabel || 'Cancel'}\n </Button>\n ) : (\n <Button variant=\"tertiary\" onClick={handleBack} type=\"button\">\n {currentChild?.backLabel || 'Back'}\n </Button>\n )}\n\n <Button\n variant=\"default\"\n type=\"submit\"\n disabled={isLoading || currentChild?.disableNext}\n loading={isLoading}\n >\n {currentChild?.nextLabel || (isLastStep ? 'Complete' : 'Next')}\n </Button>\n </Modal.Footer>\n </form>\n </Modal.Content>\n </Modal.Root>\n )}\n </StepModalContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step\n * -----------------------------------------------------------------------------------------------*/\n\nconst Step = ({ children }: StepProps) => {\n return <>{children}</>;\n};\n\nStepModal.Step = Step;\n\nexport { StepModal, Step };\n"],"names":["StepModalContext","createContext","useStepModal","context","useContext","Error","StepModal","open","onOpenChange","title","children","onComplete","onCancel","currentStep","setCurrentStep","useState","isLoading","setIsLoading","error","setError","childrenArray","Children","toArray","filter","child","isValidElement","map","props","totalSteps","length","isFirstStep","isLastStep","useEffect","resetStates","handleCancel","handleBack","prev","Math","max","nextStep","currentStepProps","onNext","err","String","handleFormSubmit","e","preventDefault","disableNext","contextValue","goToStep","prevStep","currentChild","_jsx","Provider","value","Modal","Root","_jsxs","Content","Header","Typography","variant","fontWeight","form","onSubmit","Body","Box","marginTop","padding","background","color","borderRadius","message","Footer","Button","onClick","type","cancelLabel","backLabel","disabled","loading","nextLabel","Step","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StepModal.mjs","sources":["../../../../../admin/src/components/AIChat/components/StepModal.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n useState,\n ReactNode,\n Children,\n isValidElement,\n FormEvent,\n useCallback,\n useEffect,\n useMemo,\n} from 'react';\n\nimport { Modal, Box, Button, Typography } from '@strapi/design-system';\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\ninterface StepModalContextType {\n currentStep: number;\n goToStep: (step: number) => void;\n nextStep: () => Promise<boolean>;\n prevStep: () => void;\n isFirstStep: boolean;\n isLastStep: boolean;\n totalSteps: number;\n isLoading: boolean;\n error: Error | null;\n setError: (error: Error | null) => void;\n}\n\nconst StepModalContext = createContext<StepModalContextType | null>(null);\n\nexport const useStepModal = () => {\n const context = useContext(StepModalContext);\n if (!context) {\n throw new Error('useStepModal must be used within a StepModal');\n }\n return context;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * StepModal\n * -----------------------------------------------------------------------------------------------*/\n\ninterface StepModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title?: string;\n children: ReactNode;\n onComplete?: () => void;\n onCancel?: () => void;\n}\n\ninterface StepProps {\n title?: string;\n children: ReactNode;\n nextLabel?: string;\n cancelLabel?: string;\n backLabel?: string;\n disableNext?: boolean;\n onNext?: () => Promise<boolean> | boolean;\n}\n\nconst StepModal = ({\n open,\n onOpenChange,\n title,\n children,\n onComplete,\n onCancel,\n}: StepModalProps) => {\n const [currentStep, setCurrentStep] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const childrenArray = useMemo(\n () =>\n Children.toArray(children)\n .filter((child): child is React.ReactElement => isValidElement(child))\n .map((child) => child.props),\n [children]\n );\n\n const totalSteps = childrenArray.length;\n const isFirstStep = currentStep === 0;\n const isLastStep = currentStep === totalSteps - 1;\n\n // Reset states when modal opens/closes\n useEffect(() => {\n if (!open) {\n // Reset states when modal is closed\n setCurrentStep(0);\n setIsLoading(false);\n setError(null);\n }\n }, [open]);\n\n const resetStates = useCallback(() => {\n setCurrentStep(0);\n setIsLoading(false);\n setError(null);\n }, []);\n\n const handleCancel = useCallback(() => {\n onCancel?.();\n resetStates();\n onOpenChange(false);\n }, [onCancel, onOpenChange, resetStates]);\n\n const handleBack = useCallback(() => {\n setCurrentStep((prev) => Math.max(0, prev - 1));\n setError(null);\n }, []);\n\n const nextStep = useCallback(async () => {\n const currentStepProps = childrenArray[currentStep];\n\n if (currentStepProps.onNext) {\n setIsLoading(true);\n setError(null);\n\n try {\n if (isLastStep) {\n onComplete?.();\n resetStates();\n onOpenChange(false);\n } else {\n await currentStepProps.onNext();\n setCurrentStep((prev) => prev + 1);\n }\n return true;\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n return false;\n } finally {\n setIsLoading(false);\n }\n } else {\n // Default behavior: just move to next step\n if (isLastStep) {\n onComplete?.();\n resetStates();\n onOpenChange(false);\n } else {\n setCurrentStep((prev) => prev + 1);\n }\n return true;\n }\n }, [childrenArray, currentStep, isLastStep, onComplete, onOpenChange, resetStates]);\n\n // Handle form submission (triggered by Enter key)\n const handleFormSubmit = useCallback(\n (e: FormEvent) => {\n e.preventDefault();\n if (!isLoading && !childrenArray[currentStep]?.disableNext) {\n nextStep();\n }\n },\n [childrenArray, currentStep, isLoading, nextStep]\n );\n\n const contextValue = useMemo(\n () => ({\n currentStep,\n goToStep: setCurrentStep,\n nextStep,\n prevStep: handleBack,\n isFirstStep,\n isLastStep,\n totalSteps,\n isLoading,\n error,\n setError,\n }),\n [currentStep, nextStep, handleBack, isFirstStep, isLastStep, totalSteps, isLoading, error]\n );\n\n const currentChild = childrenArray[currentStep];\n\n return (\n <StepModalContext.Provider value={contextValue}>\n {open && (\n <Modal.Root open onOpenChange={handleCancel}>\n <Modal.Content>\n <Modal.Header>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {currentChild?.title || title}\n </Typography>\n </Modal.Header>\n\n <form onSubmit={handleFormSubmit}>\n <Modal.Body>\n {Children.toArray(children)[currentStep]}\n\n {error && (\n <Box\n marginTop={4}\n padding={3}\n background=\"danger100\"\n color=\"danger600\"\n borderRadius=\"4px\"\n >\n <Typography variant=\"pi\">{error.message}</Typography>\n </Box>\n )}\n </Modal.Body>\n\n <Modal.Footer>\n {isFirstStep ? (\n <Button variant=\"tertiary\" onClick={handleCancel} type=\"button\">\n {currentChild?.cancelLabel || 'Cancel'}\n </Button>\n ) : (\n <Button variant=\"tertiary\" onClick={handleBack} type=\"button\">\n {currentChild?.backLabel || 'Back'}\n </Button>\n )}\n\n <Button\n variant=\"default\"\n type=\"submit\"\n disabled={isLoading || currentChild?.disableNext}\n loading={isLoading}\n >\n {currentChild?.nextLabel || (isLastStep ? 'Complete' : 'Next')}\n </Button>\n </Modal.Footer>\n </form>\n </Modal.Content>\n </Modal.Root>\n )}\n </StepModalContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Step\n * -----------------------------------------------------------------------------------------------*/\n\nconst Step = ({ children }: StepProps) => {\n return <>{children}</>;\n};\n\nStepModal.Step = Step;\n\nexport { StepModal, Step };\n"],"names":["StepModalContext","createContext","useStepModal","context","useContext","Error","StepModal","open","onOpenChange","title","children","onComplete","onCancel","currentStep","setCurrentStep","useState","isLoading","setIsLoading","error","setError","childrenArray","useMemo","Children","toArray","filter","child","isValidElement","map","props","totalSteps","length","isFirstStep","isLastStep","useEffect","resetStates","useCallback","handleCancel","handleBack","prev","Math","max","nextStep","currentStepProps","onNext","err","String","handleFormSubmit","e","preventDefault","disableNext","contextValue","goToStep","prevStep","currentChild","_jsx","Provider","value","Modal","Root","_jsxs","Content","Header","Typography","variant","fontWeight","form","onSubmit","Body","Box","marginTop","padding","background","color","borderRadius","message","Footer","Button","onClick","type","cancelLabel","backLabel","disabled","loading","nextLabel","Step","_Fragment"],"mappings":"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"}
|