@flexkit/studio 0.2.37 → 0.2.39
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/README.md +76 -7
- package/dist/{chat-page-XYQOQPMW.js → chat-page-2ES466GO.js} +3 -3
- package/dist/{chat-page-XYQOQPMW.js.map → chat-page-2ES466GO.js.map} +1 -1
- package/dist/{chunk-6NRMVVU4.js → chunk-7FYOLFHG.js} +3 -3
- package/dist/{chunk-6NRMVVU4.js.map → chunk-7FYOLFHG.js.map} +1 -1
- package/dist/{chunk-PNGPE7QM.js → chunk-CESG6WQB.js} +3 -3
- package/dist/{chunk-PNGPE7QM.js.map → chunk-CESG6WQB.js.map} +1 -1
- package/dist/{chunk-OWY5BQER.js → chunk-DQ2OVNOB.js} +2 -2
- package/dist/{chunk-OWY5BQER.js.map → chunk-DQ2OVNOB.js.map} +1 -1
- package/dist/{chunk-KOM7G7WT.js → chunk-DR36N2JC.js} +2 -2
- package/dist/{chunk-KOM7G7WT.js.map → chunk-DR36N2JC.js.map} +1 -1
- package/dist/{chunk-36YXPN42.js → chunk-DUS2CRB3.js} +2 -2
- package/dist/{chunk-36YXPN42.js.map → chunk-DUS2CRB3.js.map} +1 -1
- package/dist/{chunk-ND2RTUMM.js → chunk-JJFOUJMQ.js} +3 -3
- package/dist/{chunk-ND2RTUMM.js.map → chunk-JJFOUJMQ.js.map} +1 -1
- package/dist/chunk-KWE3LHFM.js +10 -0
- package/dist/chunk-KWE3LHFM.js.map +1 -0
- package/dist/{chunk-CRTUZ22E.js → chunk-MGCXYA2S.js} +3 -3
- package/dist/{chunk-CRTUZ22E.js.map → chunk-MGCXYA2S.js.map} +1 -1
- package/dist/{chunk-337GX2BR.js → chunk-PR3MTHFM.js} +2 -2
- package/dist/{chunk-337GX2BR.js.map → chunk-PR3MTHFM.js.map} +1 -1
- package/dist/{chunk-RX6QUDLZ.js → chunk-R7EOMV6C.js} +3 -3
- package/dist/{chunk-RX6QUDLZ.js.map → chunk-R7EOMV6C.js.map} +1 -1
- package/dist/{chunk-DO32GATF.js → chunk-SAVZBVP5.js} +3 -3
- package/dist/{chunk-DO32GATF.js.map → chunk-SAVZBVP5.js.map} +1 -1
- package/dist/{chunk-RGISZNQ2.js → chunk-SGQMQZIW.js} +2 -2
- package/dist/{chunk-RGISZNQ2.js.map → chunk-SGQMQZIW.js.map} +1 -1
- package/dist/{chunk-AQSL5HBZ.js → chunk-TOISBMRE.js} +2 -2
- package/dist/{chunk-AQSL5HBZ.js.map → chunk-TOISBMRE.js.map} +1 -1
- package/dist/{chunk-CC2U7ASG.js → chunk-TP6QGIJH.js} +3 -3
- package/dist/{chunk-CC2U7ASG.js.map → chunk-TP6QGIJH.js.map} +1 -1
- package/dist/{chunk-U4DUXPZV.js → chunk-U3PTPLSE.js} +2 -2
- package/dist/{chunk-U4DUXPZV.js.map → chunk-U3PTPLSE.js.map} +1 -1
- package/dist/{chunk-UULPCFWK.js → chunk-VR3LFFJ3.js} +3 -3
- package/dist/{chunk-UULPCFWK.js.map → chunk-VR3LFFJ3.js.map} +1 -1
- package/dist/{chunk-BHHLWGZ4.js → chunk-WSXNYZQC.js} +2 -2
- package/dist/{chunk-BHHLWGZ4.js.map → chunk-WSXNYZQC.js.map} +1 -1
- package/dist/{chunk-XV4QJKOJ.js → chunk-Z7JAN2UW.js} +2 -2
- package/dist/{chunk-XV4QJKOJ.js.map → chunk-Z7JAN2UW.js.map} +1 -1
- package/dist/{entry-6EWYXIS5.js → entry-ZYSQFFEW.js} +2 -2
- package/dist/{entry-6EWYXIS5.js.map → entry-ZYSQFFEW.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/{list-GBM53HFN.js → list-4EXGXJZA.js} +2 -2
- package/dist/{list-GBM53HFN.js.map → list-4EXGXJZA.js.map} +1 -1
- package/dist/{list-N5W7G3LD.js → list-XTC2OYA6.js} +3 -3
- package/dist/{list-N5W7G3LD.js.map → list-XTC2OYA6.js.map} +1 -1
- package/dist/{pages-HPR3UHT7.js → pages-HW4OCENA.js} +3 -3
- package/dist/{pages-HPR3UHT7.js.map → pages-HW4OCENA.js.map} +1 -1
- package/dist/{plugin-pages-VDRT7RLY.js → plugin-pages-CUTCB6NU.js} +2 -2
- package/dist/{plugin-pages-VDRT7RLY.js.map → plugin-pages-CUTCB6NU.js.map} +1 -1
- package/dist/{project-selector-RRG52TSX.js → project-selector-Z4Q6G6GM.js} +2 -2
- package/dist/{project-selector-RRG52TSX.js.map → project-selector-Z4Q6G6GM.js.map} +1 -1
- package/dist/record-links-DBU5G6ZH.js +2 -0
- package/dist/{record-links-CI4OJPWW.js.map → record-links-DBU5G6ZH.js.map} +1 -1
- package/dist/{root-IXK2ESCS.js → root-3Q44ISGQ.js} +3 -3
- package/dist/{root-IXK2ESCS.js.map → root-3Q44ISGQ.js.map} +1 -1
- package/dist/{root-DF2BNGOF.js → root-422O7YX5.js} +3 -3
- package/dist/{root-DF2BNGOF.js.map → root-422O7YX5.js.map} +1 -1
- package/dist/{root-KF6EFGM6.js → root-7FYWXLI6.js} +3 -3
- package/dist/{root-KF6EFGM6.js.map → root-7FYWXLI6.js.map} +1 -1
- package/dist/{root-LUWJS7SQ.js → root-7NZPP7IC.js} +2 -2
- package/dist/{root-LUWJS7SQ.js.map → root-7NZPP7IC.js.map} +1 -1
- package/dist/{root-RGAV2YAF.js → root-Q6SHODPG.js} +2 -2
- package/dist/{root-RGAV2YAF.js.map → root-Q6SHODPG.js.map} +1 -1
- package/dist/{root-JFYE2JRJ.js → root-SYRZ3UBN.js} +2 -2
- package/dist/{root-JFYE2JRJ.js.map → root-SYRZ3UBN.js.map} +1 -1
- package/dist/{search-DQLC3XDJ.js → search-X7F5JZOU.js} +2 -2
- package/dist/{search-DQLC3XDJ.js.map → search-X7F5JZOU.js.map} +1 -1
- package/dist/{skills-pages-Q4YUDTC2.js → skills-pages-X3DVZXY5.js} +2 -2
- package/dist/{skills-pages-Q4YUDTC2.js.map → skills-pages-X3DVZXY5.js.map} +1 -1
- package/dist/{source-J3ZCTEWZ.js → source-43PHAELP.js} +2 -2
- package/dist/{source-J3ZCTEWZ.js.map → source-43PHAELP.js.map} +1 -1
- package/package.json +6 -6
- package/dist/chunk-ZV7I5RUM.js +0 -10
- package/dist/chunk-ZV7I5RUM.js.map +0 -1
- package/dist/record-links-CI4OJPWW.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graphql-client/use-patch-entity-list.ts","../src/core/upload.ts"],"names":["usePatchEntityList","entityNameOrPlural","schema","useConfig","useCallback","patches","scheduleEntityListPatch","getEntityListQueryName","ACCEPTED_MIME_TYPES","isAcceptedMimeType","file","accept","allowed","pattern","uploadAssetFile","projectId","params","response","apiPaths","data","asset","uploadSelectedFiles","files","options","maxBytes","onUploadStart","validFiles","toast","uploads","error","openFileDialogAndUpload","multiple","input","resolve","useUploadAssets","apolloClient","useApolloClient","scheduleEntityListRefetch"],"mappings":"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","file":"chunk-RGISZNQ2.js","sourcesContent":["import { useCallback } from 'react';\nimport { useConfig } from '../core/config/config-context';\nimport {\n getEntityListQueryName,\n scheduleEntityListPatch,\n type EntityListRowPatch,\n} from './refetch-entity-lists';\n\n/**\n * Patch active list rows for an entity without a soft-refetch.\n * Prefer this after mutations that only change row fields (e.g. tag connect/disconnect).\n */\nexport function usePatchEntityList(entityNameOrPlural: string): (patches: EntityListRowPatch[]) => void {\n const { currentProjectSchema: schema } = useConfig();\n\n return useCallback(\n (patches: EntityListRowPatch[]) => {\n if (!schema) {\n return;\n }\n\n scheduleEntityListPatch(getEntityListQueryName(entityNameOrPlural, schema), patches);\n },\n [entityNameOrPlural, schema]\n );\n}\n","import { useCallback } from 'react';\nimport { toast } from 'sonner';\nimport { useApolloClient } from '@apollo/client/react';\nimport { apiPaths } from './api-paths';\nimport { scheduleEntityListRefetch } from '../graphql-client/refetch-entity-lists';\nimport type { OrderedAssetValue } from '../graphql-client/types';\n\nexport const ACCEPTED_MIME_TYPES = [\n 'image/jpeg',\n 'image/png',\n 'image/webp',\n 'image/vnd.microsoft.icon',\n 'image/bmp',\n 'image/gif',\n 'image/tiff',\n 'image/svg+xml',\n 'image/avif',\n 'image/heic',\n 'image/heif',\n 'image/heic-sequence',\n 'image/heif-sequence',\n 'image/apng',\n 'audio/aac',\n 'audio/mpeg',\n 'audio/wav',\n 'audio/webm',\n 'audio/midi',\n 'audio/x-midi',\n 'audio/ogg',\n 'video/x-msvideo',\n 'video/mp4',\n 'video/mpeg',\n 'video/webm',\n 'video/quicktime',\n 'video/ogg',\n 'video/mp2t',\n 'video/3gpp',\n 'video/3gpp2',\n 'application/x-7z-compressed',\n 'application/zip',\n 'application/vnd.amazon.ebook',\n 'application/octet-stream',\n 'application/epub+zip',\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-fontobject',\n 'application/gzip',\n 'application/x-gzip',\n 'application/java-archive',\n 'application/json',\n 'application/ld+json',\n 'text/javascript',\n 'application/vnd.oasis.opendocument.presentation',\n 'application/vnd.oasis.opendocument.spreadsheet',\n 'application/vnd.oasis.opendocument.text',\n 'application/ogg',\n 'application/vnd.ms-powerpoint',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n 'application/vnd.rar',\n 'application/x-tar',\n 'application/vnd.visio',\n 'application/xhtml+xml',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'application/xml',\n];\n\nexport type UploadedFileResult = {\n pathname: string;\n lqip?: string;\n size: number;\n mimeType: string;\n originalFilename: string;\n width?: number;\n height?: number;\n};\n\nexport type UploadedAssetResult = UploadedFileResult & {\n asset: OrderedAssetValue;\n _id: string;\n};\n\ntype AssetUploadResponse = {\n _id: string;\n path: string | null;\n mimeType: string | null;\n originalFilename: string | null;\n size: number | null;\n width: number | null;\n height: number | null;\n lqip: string | null;\n sha256: string | null;\n deduped: boolean;\n};\n\nexport type OpenFileDialogAndUploadOptions = {\n projectId: string | undefined;\n accept?: string;\n files?: File[] | FileList;\n multiple?: boolean;\n maxBytes?: number;\n onUploadStart?: () => void;\n};\n\nfunction isAcceptedMimeType(file: File, accept?: string): boolean {\n if (!file.type) {\n return true;\n }\n\n const allowed = accept\n ? accept\n .split(',')\n .map((pattern) => pattern.trim())\n .filter(Boolean)\n : ACCEPTED_MIME_TYPES;\n\n if (allowed.length === 0) {\n return true;\n }\n\n return allowed.some((pattern) => {\n if (pattern.endsWith('/*')) {\n return file.type.startsWith(pattern.slice(0, -1));\n }\n\n return file.type === pattern;\n });\n}\n\n/**\n * Uploads a single file to the one-shot /assets endpoint, which stores the\n * blob and creates the _asset node in a single request.\n */\nexport async function uploadAssetFile(file: File, projectId: string | undefined): Promise<UploadedAssetResult> {\n const params = new URLSearchParams({ filename: file.name });\n const response = await fetch(`${apiPaths(projectId).assets}?${params.toString()}`, {\n method: 'POST',\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\n body: file,\n });\n\n if (!response.ok) {\n throw new Error(`Upload failed for ${file.name}`);\n }\n\n const data = (await response.json()) as AssetUploadResponse;\n const asset: OrderedAssetValue = {\n _id: data._id,\n path: data.path ?? '',\n originalFilename: data.originalFilename ?? file.name,\n size: data.size ?? file.size,\n mimeType: data.mimeType ?? file.type,\n lqip: data.lqip ?? '',\n width: data.width ?? 0,\n height: data.height ?? 0,\n };\n\n return {\n pathname: asset.path,\n lqip: asset.lqip || undefined,\n originalFilename: asset.originalFilename,\n size: asset.size,\n mimeType: asset.mimeType,\n width: asset.width || undefined,\n height: asset.height || undefined,\n _id: asset._id,\n asset,\n };\n}\n\nasync function uploadSelectedFiles(\n files: File[] | FileList,\n options: OpenFileDialogAndUploadOptions\n): Promise<UploadedAssetResult[]> {\n const { projectId, accept, maxBytes = 4 * 1024 * 1024, onUploadStart } = options;\n const validFiles: File[] = [];\n\n for (const file of Array.from(files)) {\n if (file.size > maxBytes) {\n toast.error(`File size too big (max ${(maxBytes / (1024 * 1024)).toFixed(0)}MB): ${file.name}`);\n\n continue;\n }\n\n if (!isAcceptedMimeType(file, accept)) {\n toast.error(`Unsupported file type: ${file.name}`);\n\n continue;\n }\n\n validFiles.push(file);\n }\n\n if (validFiles.length === 0) {\n return [];\n }\n\n onUploadStart?.();\n\n try {\n const uploads = await Promise.all(validFiles.map(async (file) => uploadAssetFile(file, projectId)));\n\n if (uploads.length > 0) {\n toast.success(`Uploaded ${uploads.length} file${uploads.length > 1 ? 's' : ''}`);\n }\n\n return uploads;\n } catch (error) {\n console.error(error);\n toast.error('Upload failed. Please try again.');\n\n return [];\n }\n}\n\n/**\n * Opens a native file picker and uploads selected files to the Flexkit assets\n * endpoint, which also creates an asset node in the database.\n * Returns a list of uploaded file results. Skips files that exceed maxBytes.\n */\nasync function openFileDialogAndUpload(options: OpenFileDialogAndUploadOptions): Promise<UploadedAssetResult[]> {\n const { accept, multiple = true } = options;\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = accept ?? ACCEPTED_MIME_TYPES.join(',');\n input.multiple = multiple;\n input.style.display = 'none';\n document.body.appendChild(input);\n\n try {\n const files = await new Promise<FileList | null>((resolve) => {\n input.addEventListener('change', () => resolve(input.files), { once: true });\n input.addEventListener('cancel', () => resolve(null), { once: true });\n input.click();\n });\n\n if (!files || files.length === 0) {\n return [];\n }\n\n return uploadSelectedFiles(files, options);\n } finally {\n document.body.removeChild(input);\n }\n}\n\nexport function useUploadAssets(): (options: OpenFileDialogAndUploadOptions) => Promise<UploadedAssetResult[]> {\n const apolloClient = useApolloClient();\n\n return useCallback(\n async (options: OpenFileDialogAndUploadOptions) => {\n const uploads = options.files\n ? await uploadSelectedFiles(options.files, options)\n : await openFileDialogAndUpload(options);\n\n if (uploads.length > 0) {\n // Upload is outside Apollo; soft-refresh mounted asset lists via useEntityQuery.\n await scheduleEntityListRefetch(apolloClient, 'GetAssets').catch((error: unknown) => {\n console.error('Error refreshing asset lists after upload:', error);\n });\n }\n\n return uploads;\n },\n [apolloClient]\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/graphql-client/use-patch-entity-list.ts","../src/core/upload.ts"],"names":["usePatchEntityList","entityNameOrPlural","schema","useConfig","useCallback","patches","scheduleEntityListPatch","getEntityListQueryName","ACCEPTED_MIME_TYPES","isAcceptedMimeType","file","accept","allowed","pattern","uploadAssetFile","projectId","params","response","apiPaths","data","asset","uploadSelectedFiles","files","options","maxBytes","onUploadStart","validFiles","toast","uploads","error","openFileDialogAndUpload","multiple","input","resolve","useUploadAssets","apolloClient","useApolloClient","scheduleEntityListRefetch"],"mappings":"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","file":"chunk-SGQMQZIW.js","sourcesContent":["import { useCallback } from 'react';\nimport { useConfig } from '../core/config/config-context';\nimport {\n getEntityListQueryName,\n scheduleEntityListPatch,\n type EntityListRowPatch,\n} from './refetch-entity-lists';\n\n/**\n * Patch active list rows for an entity without a soft-refetch.\n * Prefer this after mutations that only change row fields (e.g. tag connect/disconnect).\n */\nexport function usePatchEntityList(entityNameOrPlural: string): (patches: EntityListRowPatch[]) => void {\n const { currentProjectSchema: schema } = useConfig();\n\n return useCallback(\n (patches: EntityListRowPatch[]) => {\n if (!schema) {\n return;\n }\n\n scheduleEntityListPatch(getEntityListQueryName(entityNameOrPlural, schema), patches);\n },\n [entityNameOrPlural, schema]\n );\n}\n","import { useCallback } from 'react';\nimport { toast } from 'sonner';\nimport { useApolloClient } from '@apollo/client/react';\nimport { apiPaths } from './api-paths';\nimport { scheduleEntityListRefetch } from '../graphql-client/refetch-entity-lists';\nimport type { OrderedAssetValue } from '../graphql-client/types';\n\nexport const ACCEPTED_MIME_TYPES = [\n 'image/jpeg',\n 'image/png',\n 'image/webp',\n 'image/vnd.microsoft.icon',\n 'image/bmp',\n 'image/gif',\n 'image/tiff',\n 'image/svg+xml',\n 'image/avif',\n 'image/heic',\n 'image/heif',\n 'image/heic-sequence',\n 'image/heif-sequence',\n 'image/apng',\n 'audio/aac',\n 'audio/mpeg',\n 'audio/wav',\n 'audio/webm',\n 'audio/midi',\n 'audio/x-midi',\n 'audio/ogg',\n 'video/x-msvideo',\n 'video/mp4',\n 'video/mpeg',\n 'video/webm',\n 'video/quicktime',\n 'video/ogg',\n 'video/mp2t',\n 'video/3gpp',\n 'video/3gpp2',\n 'application/x-7z-compressed',\n 'application/zip',\n 'application/vnd.amazon.ebook',\n 'application/octet-stream',\n 'application/epub+zip',\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-fontobject',\n 'application/gzip',\n 'application/x-gzip',\n 'application/java-archive',\n 'application/json',\n 'application/ld+json',\n 'text/javascript',\n 'application/vnd.oasis.opendocument.presentation',\n 'application/vnd.oasis.opendocument.spreadsheet',\n 'application/vnd.oasis.opendocument.text',\n 'application/ogg',\n 'application/vnd.ms-powerpoint',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n 'application/vnd.rar',\n 'application/x-tar',\n 'application/vnd.visio',\n 'application/xhtml+xml',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'application/xml',\n];\n\nexport type UploadedFileResult = {\n pathname: string;\n lqip?: string;\n size: number;\n mimeType: string;\n originalFilename: string;\n width?: number;\n height?: number;\n};\n\nexport type UploadedAssetResult = UploadedFileResult & {\n asset: OrderedAssetValue;\n _id: string;\n};\n\ntype AssetUploadResponse = {\n _id: string;\n path: string | null;\n mimeType: string | null;\n originalFilename: string | null;\n size: number | null;\n width: number | null;\n height: number | null;\n lqip: string | null;\n sha256: string | null;\n deduped: boolean;\n};\n\nexport type OpenFileDialogAndUploadOptions = {\n projectId: string | undefined;\n accept?: string;\n files?: File[] | FileList;\n multiple?: boolean;\n maxBytes?: number;\n onUploadStart?: () => void;\n};\n\nfunction isAcceptedMimeType(file: File, accept?: string): boolean {\n if (!file.type) {\n return true;\n }\n\n const allowed = accept\n ? accept\n .split(',')\n .map((pattern) => pattern.trim())\n .filter(Boolean)\n : ACCEPTED_MIME_TYPES;\n\n if (allowed.length === 0) {\n return true;\n }\n\n return allowed.some((pattern) => {\n if (pattern.endsWith('/*')) {\n return file.type.startsWith(pattern.slice(0, -1));\n }\n\n return file.type === pattern;\n });\n}\n\n/**\n * Uploads a single file to the one-shot /assets endpoint, which stores the\n * blob and creates the _asset node in a single request.\n */\nexport async function uploadAssetFile(file: File, projectId: string | undefined): Promise<UploadedAssetResult> {\n const params = new URLSearchParams({ filename: file.name });\n const response = await fetch(`${apiPaths(projectId).assets}?${params.toString()}`, {\n method: 'POST',\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\n body: file,\n });\n\n if (!response.ok) {\n throw new Error(`Upload failed for ${file.name}`);\n }\n\n const data = (await response.json()) as AssetUploadResponse;\n const asset: OrderedAssetValue = {\n _id: data._id,\n path: data.path ?? '',\n originalFilename: data.originalFilename ?? file.name,\n size: data.size ?? file.size,\n mimeType: data.mimeType ?? file.type,\n lqip: data.lqip ?? '',\n width: data.width ?? 0,\n height: data.height ?? 0,\n };\n\n return {\n pathname: asset.path,\n lqip: asset.lqip || undefined,\n originalFilename: asset.originalFilename,\n size: asset.size,\n mimeType: asset.mimeType,\n width: asset.width || undefined,\n height: asset.height || undefined,\n _id: asset._id,\n asset,\n };\n}\n\nasync function uploadSelectedFiles(\n files: File[] | FileList,\n options: OpenFileDialogAndUploadOptions\n): Promise<UploadedAssetResult[]> {\n const { projectId, accept, maxBytes = 4 * 1024 * 1024, onUploadStart } = options;\n const validFiles: File[] = [];\n\n for (const file of Array.from(files)) {\n if (file.size > maxBytes) {\n toast.error(`File size too big (max ${(maxBytes / (1024 * 1024)).toFixed(0)}MB): ${file.name}`);\n\n continue;\n }\n\n if (!isAcceptedMimeType(file, accept)) {\n toast.error(`Unsupported file type: ${file.name}`);\n\n continue;\n }\n\n validFiles.push(file);\n }\n\n if (validFiles.length === 0) {\n return [];\n }\n\n onUploadStart?.();\n\n try {\n const uploads = await Promise.all(validFiles.map(async (file) => uploadAssetFile(file, projectId)));\n\n if (uploads.length > 0) {\n toast.success(`Uploaded ${uploads.length} file${uploads.length > 1 ? 's' : ''}`);\n }\n\n return uploads;\n } catch (error) {\n console.error(error);\n toast.error('Upload failed. Please try again.');\n\n return [];\n }\n}\n\n/**\n * Opens a native file picker and uploads selected files to the Flexkit assets\n * endpoint, which also creates an asset node in the database.\n * Returns a list of uploaded file results. Skips files that exceed maxBytes.\n */\nasync function openFileDialogAndUpload(options: OpenFileDialogAndUploadOptions): Promise<UploadedAssetResult[]> {\n const { accept, multiple = true } = options;\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = accept ?? ACCEPTED_MIME_TYPES.join(',');\n input.multiple = multiple;\n input.style.display = 'none';\n document.body.appendChild(input);\n\n try {\n const files = await new Promise<FileList | null>((resolve) => {\n input.addEventListener('change', () => resolve(input.files), { once: true });\n input.addEventListener('cancel', () => resolve(null), { once: true });\n input.click();\n });\n\n if (!files || files.length === 0) {\n return [];\n }\n\n return uploadSelectedFiles(files, options);\n } finally {\n document.body.removeChild(input);\n }\n}\n\nexport function useUploadAssets(): (options: OpenFileDialogAndUploadOptions) => Promise<UploadedAssetResult[]> {\n const apolloClient = useApolloClient();\n\n return useCallback(\n async (options: OpenFileDialogAndUploadOptions) => {\n const uploads = options.files\n ? await uploadSelectedFiles(options.files, options)\n : await openFileDialogAndUpload(options);\n\n if (uploads.length > 0) {\n // Upload is outside Apollo; soft-refresh mounted asset lists via useEntityQuery.\n await scheduleEntityListRefetch(apolloClient, 'GetAssets').catch((error: unknown) => {\n console.error('Error refreshing asset lists after upload:', error);\n });\n }\n\n return uploads;\n },\n [apolloClient]\n );\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import'./index.css';import {c as c$3,i,j,d as d$2,l,f,b as b$1}from'./chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import'./index.css';import {c as c$3,i,j,d as d$2,l,f,b as b$1}from'./chunk-JJFOUJMQ.js';import {c as c$4}from'./chunk-MBBE4RND.js';import {e,g,a,b,c as c$1,d as d$1}from'./chunk-G5N6HEPW.js';import {a as a$1,d,c,e as e$1,g as g$1}from'./chunk-S7Z6KKIN.js';import {c as c$2,a as a$2}from'./chunk-X3SHNHHM.js';import {useId,useState}from'react';import {useNavigate}from'react-router-dom';import {ShoppingBag,MessageSquareText,Sparkles,Loader2}from'lucide-react';import ve,{mutate}from'swr';import {jsx,jsxs}from'react/jsx-runtime';function Le(e,t,o=[]){return o.find(n=>n.id===e)?.name??t.find(n=>n.projectId===e)?.title??e}function He(e,t){let o=new Map;for(let n of e){let m=t.find(c=>c.id===n),f=m?.team.id??"",s=o.get(f)??{label:m?.team.name??"",projectIds:[]};s.projectIds.push(n),o.set(f,s);}return o.size<=1?[{label:null,projectIds:e}]:[...o.values()].map(n=>({label:n.label||null,projectIds:n.projectIds}))}var se="Could not create the project. Please try again.";async function ie(e){let t=await b$1(c$4.myProjects,"POST",e,se);return t.ok?!t.project?.id||!t.team?.id?{ok:false,code:"unknown_error",message:se}:{ok:true,project:t.project,team:t.team}:t}function me(e){return e.filter(t=>t.role==="owner")}function de(e){return `/${e}/ai/agent`}var F="hosted-session";async function he(){try{let e=await fetch(c$4.me,{credentials:"same-origin"});return e.status===401?{kind:"anonymous"}:e.ok?{kind:"ready",data:await e.json()}:{kind:"error",message:`Flexkit answered ${String(e.status)} while loading your projects.`}}catch(e){return {kind:"error",message:e instanceof Error?e.message:"Flexkit is not reachable."}}}function xe(e){return e?e.kind==="anonymous"?{status:"anonymous"}:e.kind==="error"?{status:"error",message:e.message}:{status:"ready",projects:e.data.projects,teams:e.data.teams??[],user:e.data.user}:{status:"loading"}}function Ue(){let{data:e}=ve(F,he,{revalidateOnFocus:false,revalidateOnReconnect:false,shouldRetryOnError:false});return xe(e)}function Pe(e,t){if(e?.kind!=="ready"||e.data.projects.some(m=>m.id===t.project.id))return e;let o=e.data.teams??[],n={avatarUrl:null,id:t.project.id,name:t.project.name,readOnly:false,role:"owner",suspended:false,team:t.team};return {kind:"ready",data:{...e.data,projects:[...e.data.projects,n],teams:o.some(m=>m.id===t.team.id)?o:[...o,{...t.team,role:"owner"}]}}}async function x(e){await mutate(F,t=>Pe(t,e),{revalidate:false});}function we(e,t){return e?.kind!=="ready"?e:{kind:"ready",data:{...e.data,user:{...e.data.user,displayName:t}}}}async function ce(e){await mutate(F,t=>we(t,e),{revalidate:false});}function rt({askForName:e$2=false,isFirstProject:t=false,onCancel:o,onCreated:n,teams:m}){let f$1=useNavigate(),s={you:useId(),name:useId(),team:useId(),description:useId(),sample:useId()},c$2=me(m),[E,j$1]=useState(e$2?"you":"project"),[R,ue]=useState(""),[P,fe]=useState(""),[U,pe]=useState(null),w=c$2.some(a=>a.id===U)?U??"":c$2[0]?.id??"",[k,N]=useState("starter"),[B,ke]=useState(true),[C,ge]=useState(""),[O,l$1]=useState(null),[u,g$2]=useState(false),[v,ye]=useState(null);async function be(){let a=R.trim();if(!a){l$1("Tell us your name.");return}l$1(null),g$2(true);let p=await c$3(a);if(g$2(false),!p.ok){l$1(p.message);return}await ce(a),j$1("project");}function Se(){let a=i(P);l$1(a),a||j$1("start");}async function je(){if(k==="describe"&&!C.trim()){l$1("Describe your business in a sentence or two, or pick another way to start.");return}l$1(null),g$2(true);let a=v??await ie({name:P.trim(),...w?{teamId:w}:{}});if(!a.ok){l$1(a.message),g$2(false),a.code==="invalid_name"&&j$1("project");return}ye(a);let p=a.project.id,y=j(k,B,C),I={};if(y.kind==="starter"){let $=await d$2(p,{template:y.template,sampleData:y.sampleData});if(!$.ok){l$1(`${a.project.name} was created, but the starter could not be applied: ${$.message}`),g$2(false),!t&&!v&&await x(a);return}l({projectId:p});}else y.kind==="describe"&&(I={onboardingPrompt:f(y.description)});let K=de(p);t?(f$1(K,{state:I}),await x(a)):(await x(a),f$1(K,{state:I})),n?.(p);}let T=O?jsx(e,{variant:"destructive",children:jsx(g,{children:O})}):null;return E==="you"?jsxs(M,{onSubmit:()=>{be();},children:[jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx(a,{htmlFor:s.you,children:"Your name"}),jsx(b,{autoComplete:"name",autoFocus:true,disabled:u,id:s.you,maxLength:80,onChange:a=>{ue(a.target.value);},placeholder:"e.g. Ann Meyer",value:R}),jsx("p",{className:"fk:text-xs fk:text-muted-foreground",children:"Your teammates see it on changes and comments."})]}),T,jsx(A,{isSubmitting:u,submitLabel:"Continue"})]}):E==="project"?jsxs(M,{onSubmit:Se,children:[jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx(a,{htmlFor:s.name,children:"Project name"}),jsx(b,{"aria-invalid":O?true:void 0,autoComplete:"off",autoFocus:true,id:s.name,maxLength:48,onChange:a=>{fe(a.target.value);},placeholder:"e.g. Aven Living",value:P}),jsx("p",{className:"fk:text-xs fk:text-muted-foreground",children:"Usually your store or company name. You can change it later."})]}),c$2.length>1?jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx(a,{htmlFor:s.team,children:"Team"}),jsxs(a$1,{onValueChange:pe,value:w,children:[jsx(d,{id:s.team,children:jsx(c,{})}),jsx(e$1,{children:c$2.map(a=>jsx(g$1,{value:a.id,children:a.name},a.id))})]})]}):null,T,jsx(A,{onCancel:o,submitLabel:"Continue"})]}):jsxs(M,{onSubmit:()=>{je();},children:[jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx("p",{className:"fk:text-sm fk:font-medium",id:`${s.name}-start`,children:"How do you want to start?"}),jsxs("div",{"aria-labelledby":`${s.name}-start`,className:"fk:flex fk:flex-col fk:gap-2",role:"radiogroup",children:[jsx(D,{checked:k==="starter",description:"22 ready-made entities for catalog, inventory, orders, customers and marketing, with EU, UK and US markets.",disabled:u,icon:ShoppingBag,onSelect:()=>{N("starter");},recommended:true,title:"Commerce starter",children:jsxs("div",{className:"fk:flex fk:items-center fk:justify-between fk:gap-3 fk:pt-1",children:[jsx(a,{className:"fk:text-xs fk:font-normal fk:text-muted-foreground",htmlFor:s.sample,children:"Add a sample store (Aven Living) to try things out"}),jsx(c$1,{checked:B,disabled:u,id:s.sample,onCheckedChange:ke})]})}),jsx(D,{checked:k==="describe",description:"Tell the agent what you sell and how you work; it proposes a schema for you to review.",disabled:u,icon:MessageSquareText,onSelect:()=>{N("describe");},title:"Describe your business",children:jsx(d$1,{"aria-label":"Your business",autoFocus:true,disabled:u,id:s.description,maxLength:2e3,onChange:a=>{ge(a.target.value);},placeholder:"e.g. We sell handmade ceramics online and to 40 shops in Europe, with seasonal collections.",rows:3,value:C})}),jsx(D,{checked:k==="empty",description:"Start with an empty project and build the schema in the chat.",disabled:u,icon:Sparkles,onSelect:()=>{N("empty");},title:"Start from scratch"})]})]}),T,jsx(A,{isSubmitting:u,onBack:v?void 0:()=>{l$1(null),j$1("project");},submitLabel:v?"Continue":"Create project"})]})}function M({children:e,onSubmit:t}){return jsx("form",{className:"fk:flex fk:w-full fk:flex-col fk:gap-4",onSubmit:o=>{o.preventDefault(),t();},children:e})}function A({isSubmitting:e=false,onBack:t,onCancel:o,submitLabel:n}){let m=t??o;return jsxs("div",{className:"fk:flex fk:justify-end fk:gap-2",children:[m?jsx(c$2,{disabled:e,onClick:m,type:"button",variant:"outline",children:t?"Back":"Cancel"}):null,jsxs(c$2,{className:m?void 0:"fk:w-full",disabled:e,type:"submit",children:[e?jsx(Loader2,{className:"fk:h-4 fk:w-4 fk:animate-spin"}):null,n]})]})}function D({checked:e,children:t,description:o,disabled:n,icon:m,onSelect:f,recommended:s=false,title:c}){return jsxs("div",{className:a$2("fk:rounded-lg fk:border fk:p-3 fk:transition-colors",e?"fk:border-foreground/70 fk:bg-muted/50 fk:ring-1 fk:ring-foreground/20":"fk:border-border fk:hover:bg-muted/30"),children:[jsxs("button",{"aria-checked":e,className:"fk:flex fk:w-full fk:items-start fk:gap-3 fk:text-left fk:disabled:opacity-60",disabled:n,onClick:f,role:"radio",type:"button",children:[jsx(m,{className:"fk:mt-0.5 fk:h-4 fk:w-4 fk:shrink-0 fk:text-muted-foreground"}),jsxs("span",{className:"fk:flex fk:flex-col fk:gap-0.5",children:[jsxs("span",{className:"fk:flex fk:items-center fk:gap-2 fk:text-sm fk:font-medium",children:[c,s?jsx("span",{className:"fk:rounded-full fk:bg-primary/10 fk:px-2 fk:py-0.5 fk:text-[11px] fk:font-medium fk:text-primary",children:"Recommended"}):null]}),jsx("span",{className:"fk:text-xs fk:text-muted-foreground",children:o})]})]}),e&&t?jsx("div",{className:"fk:mt-2 fk:pl-7",children:t}):null]})}export{Le as a,He as b,Ue as c,rt as d};//# sourceMappingURL=chunk-TOISBMRE.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-TOISBMRE.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/components/project-label.ts","../src/core/config/create-project.ts","../src/core/config/use-hosted-session.ts","../src/ui/components/new-project-flow.tsx"],"names":["getProjectLabel","projectId","projects","projectSummaries","project","groupProjectIdsByTeam","projectIds","teams","id","summary","key","group","FALLBACK_MESSAGE","createHostedProject","input","outcome","send","userApiPaths","ownedTeams","team","newProjectPath","SESSION_KEY","fetchMe","response","error","toHostedSession","useHostedSession","data","useSWR","withCreatedProject","created","rememberCreatedProject","mutate","current","withDisplayName","displayName","rememberDisplayName","NewProjectFlow","askForName","isFirstProject","onCancel","onCreated","navigate","useNavigate","ids","useId","owned","step","setStep","useState","setDisplayName","name","setName","pickedTeamId","setPickedTeamId","selectedTeamId","startKind","setStartKind","sampleData","setSampleData","description","setDescription","setError","isSubmitting","setIsSubmitting","setCreated","submitName","trimmed","saveDisplayName","submitProjectName","invalid","validateProjectName","createProject","start","toProjectStart","state","applied","applyStarter","watchStarter","describeBusinessPrompt","path","errorAlert","jsx","Alert","AlertDescription","jsxs","StepForm","Label","Input","event","StepActions","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","StartOption","ShoppingBag","Switch","MessageSquareText","Textarea","Sparkles","children","onSubmit","onBack","submitLabel","secondary","Button","Loader2","checked","disabled","Icon","onSelect","recommended","title","cn"],"mappings":"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","file":"chunk-AQSL5HBZ.js","sourcesContent":["import type { ProjectSummary, ProjectUiConfig } from '../../core/config/types';\n\n/** Name of a project: the listed name, else the deployed schema title, else the id. */\nexport function getProjectLabel(\n projectId: string,\n projects: ProjectUiConfig[],\n projectSummaries: ProjectSummary[] = []\n): string {\n return (\n projectSummaries.find((project) => project.id === projectId)?.name ??\n projects.find((project) => project.projectId === projectId)?.title ??\n projectId\n );\n}\n\n/** Groups ids by team when the summaries span more than one team; otherwise a single unnamed group. */\nexport function groupProjectIdsByTeam(\n projectIds: string[],\n projectSummaries: ProjectSummary[]\n): { label: string | null; projectIds: string[] }[] {\n const teams = new Map<string, { label: string; projectIds: string[] }>();\n\n for (const id of projectIds) {\n const summary = projectSummaries.find((project) => project.id === id);\n const key = summary?.team.id ?? '';\n const group = teams.get(key) ?? { label: summary?.team.name ?? '', projectIds: [] };\n group.projectIds.push(id);\n teams.set(key, group);\n }\n\n if (teams.size <= 1) {\n return [{ label: null, projectIds }];\n }\n\n return [...teams.values()].map((group) => ({ label: group.label || null, projectIds: group.projectIds }));\n}\n","import { userApiPaths } from '../api-paths';\nimport { send } from './onboarding';\nimport type { HostedTeam } from './types';\n\n/** What `POST /api/me/projects` answers: the new project and the team it went to (possibly a new personal team). */\nexport type CreatedProject = { project: { id: string; name: string }; team: { id: string; name: string } };\n\nexport type CreateProjectOutcome = ({ ok: true } & CreatedProject) | { ok: false; code: string; message: string };\n\nconst FALLBACK_MESSAGE = 'Could not create the project. Please try again.';\n\n/** Hosted mode: creates a project for the signed-in user (Free plan, user as owner). */\nexport async function createHostedProject(input: { name: string; teamId?: string }): Promise<CreateProjectOutcome> {\n const outcome = await send<Partial<CreatedProject>>(userApiPaths.myProjects, 'POST', input, FALLBACK_MESSAGE);\n\n if (!outcome.ok) {\n return outcome;\n }\n\n if (!outcome.project?.id || !outcome.team?.id) {\n return { ok: false, code: 'unknown_error', message: FALLBACK_MESSAGE };\n }\n\n return { ok: true, project: outcome.project, team: outcome.team };\n}\n\n/** Teams the user may create projects in, in the order `/api/me` lists them (oldest first). */\nexport function ownedTeams(teams: HostedTeam[]): HostedTeam[] {\n return teams.filter((team) => team.role === 'owner');\n}\n\n/**\n * Where a new project opens: the AI chat, which can design its schema. The\n * chat route itself, not `/ai`: that redirect would drop the navigation state\n * carrying the onboarding prompt.\n */\nexport function newProjectPath(projectId: string): string {\n return `/${projectId}/ai/agent`;\n}\n","'use client';\n\nimport useSWR, { mutate } from 'swr';\nimport { userApiPaths } from '../api-paths';\nimport type { CreatedProject } from './create-project';\nimport type { HostedTeam, HostedUser, ProjectSummary } from './types';\n\nexport type HostedSession =\n | { status: 'loading' }\n | { status: 'anonymous' }\n | { status: 'error'; message: string }\n | { status: 'ready'; user: HostedUser; projects: ProjectSummary[]; teams: HostedTeam[] };\n\n/** `teams` is missing from backends older than Studio onboarding. */\ntype MeResponse = { projects: ProjectSummary[]; teams?: HostedTeam[]; user: HostedUser };\n\nconst SESSION_KEY = 'hosted-session';\nexport type MeOutcome =\n | { kind: 'anonymous' }\n | { kind: 'error'; message: string }\n | { kind: 'ready'; data: MeResponse };\n\nasync function fetchMe(): Promise<MeOutcome> {\n try {\n const response = await fetch(userApiPaths.me, { credentials: 'same-origin' });\n\n if (response.status === 401) {\n return { kind: 'anonymous' };\n }\n\n if (!response.ok) {\n return { kind: 'error', message: `Flexkit answered ${String(response.status)} while loading your projects.` };\n }\n\n return { kind: 'ready', data: (await response.json()) as MeResponse };\n } catch (error) {\n return { kind: 'error', message: error instanceof Error ? error.message : 'Flexkit is not reachable.' };\n }\n}\n\nexport function toHostedSession(outcome: MeOutcome | undefined): HostedSession {\n if (!outcome) {\n return { status: 'loading' };\n }\n\n if (outcome.kind === 'anonymous') {\n return { status: 'anonymous' };\n }\n\n if (outcome.kind === 'error') {\n return { status: 'error', message: outcome.message };\n }\n\n return {\n status: 'ready',\n projects: outcome.data.projects,\n teams: outcome.data.teams ?? [],\n user: outcome.data.user,\n };\n}\n\n/**\n * Hosted mode: who is signed in and which projects they can open. Fetched once\n * per page load; `rememberCreatedProject` adds a project the user just created.\n */\nexport function useHostedSession(): HostedSession {\n const { data } = useSWR(SESSION_KEY, fetchMe, {\n revalidateOnFocus: false,\n revalidateOnReconnect: false,\n shouldRetryOnError: false,\n });\n\n return toHostedSession(data);\n}\n\n/** The session with a just-created project (and its team, if new) added; the user owns both. */\nexport function withCreatedProject(outcome: MeOutcome | undefined, created: CreatedProject): MeOutcome | undefined {\n if (outcome?.kind !== 'ready' || outcome.data.projects.some((project) => project.id === created.project.id)) {\n return outcome;\n }\n\n const teams = outcome.data.teams ?? [];\n const project: ProjectSummary = {\n avatarUrl: null,\n id: created.project.id,\n name: created.project.name,\n readOnly: false,\n role: 'owner',\n suspended: false,\n team: created.team,\n };\n\n return {\n kind: 'ready',\n data: {\n ...outcome.data,\n projects: [...outcome.data.projects, project],\n teams: teams.some((team) => team.id === created.team.id) ? teams : [...teams, { ...created.team, role: 'owner' }],\n },\n };\n}\n\n/**\n * Adds a project the user just created to the session, so the Studio can open\n * it at once. No `/api/me` round trip: the create response says everything the\n * session needs, and a failed re-read must not hide a project that exists.\n */\nexport async function rememberCreatedProject(created: CreatedProject): Promise<void> {\n await mutate<MeOutcome>(SESSION_KEY, (current) => withCreatedProject(current, created), { revalidate: false });\n}\n\n/** The session with the signed-in user's new display name. */\nexport function withDisplayName(outcome: MeOutcome | undefined, displayName: string): MeOutcome | undefined {\n if (outcome?.kind !== 'ready') {\n return outcome;\n }\n\n return { kind: 'ready', data: { ...outcome.data, user: { ...outcome.data.user, displayName } } };\n}\n\n/** Shows a display name the user just saved, without re-reading `/api/me`. */\nexport async function rememberDisplayName(displayName: string): Promise<void> {\n await mutate<MeOutcome>(SESSION_KEY, (current) => withDisplayName(current, displayName), { revalidate: false });\n}\n","import { useId, useState, type JSX, type ReactNode } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Loader2, MessageSquareText, ShoppingBag, Sparkles, type LucideIcon } from 'lucide-react';\nimport { watchStarter } from '../../apps/ai/starter-watch';\nimport {\n createHostedProject,\n newProjectPath,\n ownedTeams,\n type CreateProjectOutcome,\n} from '../../core/config/create-project';\nimport {\n applyStarter,\n describeBusinessPrompt,\n saveDisplayName,\n toProjectStart,\n validateProjectName,\n type OnboardingNavigationState,\n type ProjectStart,\n} from '../../core/config/onboarding';\nimport type { HostedTeam } from '../../core/config/types';\nimport { rememberCreatedProject, rememberDisplayName } from '../../core/config/use-hosted-session';\nimport { cn } from '../lib/utils';\nimport { Alert, AlertDescription } from '../primitives/alert';\nimport { Button } from '../primitives/button';\nimport { Input } from '../primitives/input';\nimport { Label } from '../primitives/label';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../primitives/select';\nimport { Switch } from '../primitives/switch';\nimport { Textarea } from '../primitives/textarea';\n\ntype Step = 'you' | 'project' | 'start';\ntype StartKind = ProjectStart['kind'];\n\n/**\n * Hosted mode: create a project in at most three short steps. Your name (only\n * when the account has none, e.g. an email sign-up), the project name, and how\n * to start: the commerce starter (schema plus an optional sample store), a\n * description the agent turns into a schema, or an empty project. The project\n * then opens in its AI chat.\n */\nexport function NewProjectFlow({\n askForName = false,\n isFirstProject = false,\n onCancel,\n onCreated,\n teams,\n}: {\n /** Ask for the user's own name first. */\n askForName?: boolean;\n /**\n * The user has no project yet, so the Studio shows this at `/`. Leave `/`\n * before the session lists the project: there, `/` redirects to the project\n * root instead of its AI chat.\n */\n isFirstProject?: boolean;\n onCancel?: () => void;\n /** Called with the new project's id once the Studio opened it. */\n onCreated?: (projectId: string) => void;\n teams: HostedTeam[];\n}): JSX.Element {\n const navigate = useNavigate();\n const ids = { you: useId(), name: useId(), team: useId(), description: useId(), sample: useId() };\n const owned = ownedTeams(teams);\n const [step, setStep] = useState<Step>(askForName ? 'you' : 'project');\n const [displayName, setDisplayName] = useState('');\n const [name, setName] = useState('');\n const [pickedTeamId, setPickedTeamId] = useState<string | null>(null);\n // Follow the teams prop: a pick that is no longer owned falls back to the first owned team.\n const selectedTeamId = owned.some((team) => team.id === pickedTeamId) ? (pickedTeamId ?? '') : (owned[0]?.id ?? '');\n const [startKind, setStartKind] = useState<StartKind>('starter');\n const [sampleData, setSampleData] = useState(true);\n const [description, setDescription] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n // Set once the project exists, so a failed starter is retried on it instead of creating another project.\n const [created, setCreated] = useState<Extract<CreateProjectOutcome, { ok: true }> | null>(null);\n\n async function submitName(): Promise<void> {\n const trimmed = displayName.trim();\n\n if (!trimmed) {\n setError('Tell us your name.');\n\n return;\n }\n\n setError(null);\n setIsSubmitting(true);\n\n const outcome = await saveDisplayName(trimmed);\n\n setIsSubmitting(false);\n\n if (!outcome.ok) {\n setError(outcome.message);\n\n return;\n }\n\n await rememberDisplayName(trimmed);\n setStep('project');\n }\n\n function submitProjectName(): void {\n const invalid = validateProjectName(name);\n\n setError(invalid);\n\n if (!invalid) {\n setStep('start');\n }\n }\n\n async function createProject(): Promise<void> {\n if (startKind === 'describe' && !description.trim()) {\n setError('Describe your business in a sentence or two, or pick another way to start.');\n\n return;\n }\n\n setError(null);\n setIsSubmitting(true);\n\n // No owned team yet: let the backend create the personal team.\n const outcome =\n created ??\n (await createHostedProject({\n name: name.trim(),\n ...(selectedTeamId ? { teamId: selectedTeamId } : {}),\n }));\n\n if (!outcome.ok) {\n setError(outcome.message);\n setIsSubmitting(false);\n\n if (outcome.code === 'invalid_name') {\n setStep('project');\n }\n\n return;\n }\n\n setCreated(outcome);\n\n const projectId = outcome.project.id;\n const start = toProjectStart(startKind, sampleData, description);\n let state: OnboardingNavigationState = {};\n\n if (start.kind === 'starter') {\n const applied = await applyStarter(projectId, { template: start.template, sampleData: start.sampleData });\n\n if (!applied.ok) {\n setError(`${outcome.project.name} was created, but the starter could not be applied: ${applied.message}`);\n setIsSubmitting(false);\n\n // List it now, so closing the dialog does not hide the project until a reload. The welcome screen\n // (first project) would leave this flow once the session lists a project, so it waits for Continue.\n if (!isFirstProject && !created) {\n await rememberCreatedProject(outcome);\n }\n\n return;\n }\n\n watchStarter({ projectId });\n } else if (start.kind === 'describe') {\n state = { onboardingPrompt: describeBusinessPrompt(start.description) };\n }\n\n const path = newProjectPath(projectId);\n\n // Inside a project the Studio only opens ids the session lists, so add it first there.\n if (isFirstProject) {\n navigate(path, { state });\n await rememberCreatedProject(outcome);\n } else {\n await rememberCreatedProject(outcome);\n navigate(path, { state });\n }\n\n onCreated?.(projectId);\n }\n\n const errorAlert = error ? (\n <Alert variant=\"destructive\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n ) : null;\n\n if (step === 'you') {\n return (\n <StepForm onSubmit={() => void submitName()}>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <Label htmlFor={ids.you}>Your name</Label>\n <Input\n autoComplete=\"name\"\n autoFocus\n disabled={isSubmitting}\n id={ids.you}\n maxLength={80}\n onChange={(event) => {\n setDisplayName(event.target.value);\n }}\n placeholder=\"e.g. Ann Meyer\"\n value={displayName}\n />\n <p className=\"fk:text-xs fk:text-muted-foreground\">Your teammates see it on changes and comments.</p>\n </div>\n {errorAlert}\n <StepActions isSubmitting={isSubmitting} submitLabel=\"Continue\" />\n </StepForm>\n );\n }\n\n if (step === 'project') {\n return (\n <StepForm onSubmit={submitProjectName}>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <Label htmlFor={ids.name}>Project name</Label>\n <Input\n aria-invalid={error ? true : undefined}\n autoComplete=\"off\"\n autoFocus\n id={ids.name}\n maxLength={48}\n onChange={(event) => {\n setName(event.target.value);\n }}\n placeholder=\"e.g. Aven Living\"\n value={name}\n />\n <p className=\"fk:text-xs fk:text-muted-foreground\">\n Usually your store or company name. You can change it later.\n </p>\n </div>\n {owned.length > 1 ? (\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <Label htmlFor={ids.team}>Team</Label>\n <Select onValueChange={setPickedTeamId} value={selectedTeamId}>\n <SelectTrigger id={ids.team}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {owned.map((team) => (\n <SelectItem key={team.id} value={team.id}>\n {team.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n {errorAlert}\n <StepActions onCancel={onCancel} submitLabel=\"Continue\" />\n </StepForm>\n );\n }\n\n return (\n <StepForm onSubmit={() => void createProject()}>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <p className=\"fk:text-sm fk:font-medium\" id={`${ids.name}-start`}>\n How do you want to start?\n </p>\n <div aria-labelledby={`${ids.name}-start`} className=\"fk:flex fk:flex-col fk:gap-2\" role=\"radiogroup\">\n <StartOption\n checked={startKind === 'starter'}\n description=\"22 ready-made entities for catalog, inventory, orders, customers and marketing, with EU, UK and US markets.\"\n disabled={isSubmitting}\n icon={ShoppingBag}\n onSelect={() => {\n setStartKind('starter');\n }}\n recommended\n title=\"Commerce starter\"\n >\n <div className=\"fk:flex fk:items-center fk:justify-between fk:gap-3 fk:pt-1\">\n <Label className=\"fk:text-xs fk:font-normal fk:text-muted-foreground\" htmlFor={ids.sample}>\n Add a sample store (Aven Living) to try things out\n </Label>\n <Switch checked={sampleData} disabled={isSubmitting} id={ids.sample} onCheckedChange={setSampleData} />\n </div>\n </StartOption>\n <StartOption\n checked={startKind === 'describe'}\n description=\"Tell the agent what you sell and how you work; it proposes a schema for you to review.\"\n disabled={isSubmitting}\n icon={MessageSquareText}\n onSelect={() => {\n setStartKind('describe');\n }}\n title=\"Describe your business\"\n >\n <Textarea\n aria-label=\"Your business\"\n autoFocus\n disabled={isSubmitting}\n id={ids.description}\n maxLength={2000}\n onChange={(event) => {\n setDescription(event.target.value);\n }}\n placeholder=\"e.g. We sell handmade ceramics online and to 40 shops in Europe, with seasonal collections.\"\n rows={3}\n value={description}\n />\n </StartOption>\n <StartOption\n checked={startKind === 'empty'}\n description=\"Start with an empty project and build the schema in the chat.\"\n disabled={isSubmitting}\n icon={Sparkles}\n onSelect={() => {\n setStartKind('empty');\n }}\n title=\"Start from scratch\"\n />\n </div>\n </div>\n {errorAlert}\n <StepActions\n isSubmitting={isSubmitting}\n onBack={\n created\n ? undefined\n : () => {\n setError(null);\n setStep('project');\n }\n }\n submitLabel={created ? 'Continue' : 'Create project'}\n />\n </StepForm>\n );\n}\n\nfunction StepForm({ children, onSubmit }: { children: ReactNode; onSubmit: () => void }): JSX.Element {\n return (\n <form\n className=\"fk:flex fk:w-full fk:flex-col fk:gap-4\"\n onSubmit={(event) => {\n event.preventDefault();\n onSubmit();\n }}\n >\n {children}\n </form>\n );\n}\n\nfunction StepActions({\n isSubmitting = false,\n onBack,\n onCancel,\n submitLabel,\n}: {\n isSubmitting?: boolean;\n onBack?: () => void;\n onCancel?: () => void;\n submitLabel: string;\n}): JSX.Element {\n const secondary = onBack ?? onCancel;\n\n return (\n <div className=\"fk:flex fk:justify-end fk:gap-2\">\n {secondary ? (\n <Button disabled={isSubmitting} onClick={secondary} type=\"button\" variant=\"outline\">\n {onBack ? 'Back' : 'Cancel'}\n </Button>\n ) : null}\n <Button className={secondary ? undefined : 'fk:w-full'} disabled={isSubmitting} type=\"submit\">\n {isSubmitting ? <Loader2 className=\"fk:h-4 fk:w-4 fk:animate-spin\" /> : null}\n {submitLabel}\n </Button>\n </div>\n );\n}\n\nfunction StartOption({\n checked,\n children,\n description,\n disabled,\n icon: Icon,\n onSelect,\n recommended = false,\n title,\n}: {\n checked: boolean;\n children?: ReactNode;\n description: string;\n disabled: boolean;\n icon: LucideIcon;\n onSelect: () => void;\n recommended?: boolean;\n title: string;\n}): JSX.Element {\n return (\n <div\n className={cn(\n 'fk:rounded-lg fk:border fk:p-3 fk:transition-colors',\n checked\n ? 'fk:border-foreground/70 fk:bg-muted/50 fk:ring-1 fk:ring-foreground/20'\n : 'fk:border-border fk:hover:bg-muted/30'\n )}\n >\n <button\n aria-checked={checked}\n className=\"fk:flex fk:w-full fk:items-start fk:gap-3 fk:text-left fk:disabled:opacity-60\"\n disabled={disabled}\n onClick={onSelect}\n role=\"radio\"\n type=\"button\"\n >\n <Icon className=\"fk:mt-0.5 fk:h-4 fk:w-4 fk:shrink-0 fk:text-muted-foreground\" />\n <span className=\"fk:flex fk:flex-col fk:gap-0.5\">\n <span className=\"fk:flex fk:items-center fk:gap-2 fk:text-sm fk:font-medium\">\n {title}\n {recommended ? (\n <span className=\"fk:rounded-full fk:bg-primary/10 fk:px-2 fk:py-0.5 fk:text-[11px] fk:font-medium fk:text-primary\">\n Recommended\n </span>\n ) : null}\n </span>\n <span className=\"fk:text-xs fk:text-muted-foreground\">{description}</span>\n </span>\n </button>\n {checked && children ? <div className=\"fk:mt-2 fk:pl-7\">{children}</div> : null}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/ui/components/project-label.ts","../src/core/config/create-project.ts","../src/core/config/use-hosted-session.ts","../src/ui/components/new-project-flow.tsx"],"names":["getProjectLabel","projectId","projects","projectSummaries","project","groupProjectIdsByTeam","projectIds","teams","id","summary","key","group","FALLBACK_MESSAGE","createHostedProject","input","outcome","send","userApiPaths","ownedTeams","team","newProjectPath","SESSION_KEY","fetchMe","response","error","toHostedSession","useHostedSession","data","useSWR","withCreatedProject","created","rememberCreatedProject","mutate","current","withDisplayName","displayName","rememberDisplayName","NewProjectFlow","askForName","isFirstProject","onCancel","onCreated","navigate","useNavigate","ids","useId","owned","step","setStep","useState","setDisplayName","name","setName","pickedTeamId","setPickedTeamId","selectedTeamId","startKind","setStartKind","sampleData","setSampleData","description","setDescription","setError","isSubmitting","setIsSubmitting","setCreated","submitName","trimmed","saveDisplayName","submitProjectName","invalid","validateProjectName","createProject","start","toProjectStart","state","applied","applyStarter","watchStarter","describeBusinessPrompt","path","errorAlert","jsx","Alert","AlertDescription","jsxs","StepForm","Label","Input","event","StepActions","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","StartOption","ShoppingBag","Switch","MessageSquareText","Textarea","Sparkles","children","onSubmit","onBack","submitLabel","secondary","Button","Loader2","checked","disabled","Icon","onSelect","recommended","title","cn"],"mappings":"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","file":"chunk-TOISBMRE.js","sourcesContent":["import type { ProjectSummary, ProjectUiConfig } from '../../core/config/types';\n\n/** Name of a project: the listed name, else the deployed schema title, else the id. */\nexport function getProjectLabel(\n projectId: string,\n projects: ProjectUiConfig[],\n projectSummaries: ProjectSummary[] = []\n): string {\n return (\n projectSummaries.find((project) => project.id === projectId)?.name ??\n projects.find((project) => project.projectId === projectId)?.title ??\n projectId\n );\n}\n\n/** Groups ids by team when the summaries span more than one team; otherwise a single unnamed group. */\nexport function groupProjectIdsByTeam(\n projectIds: string[],\n projectSummaries: ProjectSummary[]\n): { label: string | null; projectIds: string[] }[] {\n const teams = new Map<string, { label: string; projectIds: string[] }>();\n\n for (const id of projectIds) {\n const summary = projectSummaries.find((project) => project.id === id);\n const key = summary?.team.id ?? '';\n const group = teams.get(key) ?? { label: summary?.team.name ?? '', projectIds: [] };\n group.projectIds.push(id);\n teams.set(key, group);\n }\n\n if (teams.size <= 1) {\n return [{ label: null, projectIds }];\n }\n\n return [...teams.values()].map((group) => ({ label: group.label || null, projectIds: group.projectIds }));\n}\n","import { userApiPaths } from '../api-paths';\nimport { send } from './onboarding';\nimport type { HostedTeam } from './types';\n\n/** What `POST /api/me/projects` answers: the new project and the team it went to (possibly a new personal team). */\nexport type CreatedProject = { project: { id: string; name: string }; team: { id: string; name: string } };\n\nexport type CreateProjectOutcome = ({ ok: true } & CreatedProject) | { ok: false; code: string; message: string };\n\nconst FALLBACK_MESSAGE = 'Could not create the project. Please try again.';\n\n/** Hosted mode: creates a project for the signed-in user (Free plan, user as owner). */\nexport async function createHostedProject(input: { name: string; teamId?: string }): Promise<CreateProjectOutcome> {\n const outcome = await send<Partial<CreatedProject>>(userApiPaths.myProjects, 'POST', input, FALLBACK_MESSAGE);\n\n if (!outcome.ok) {\n return outcome;\n }\n\n if (!outcome.project?.id || !outcome.team?.id) {\n return { ok: false, code: 'unknown_error', message: FALLBACK_MESSAGE };\n }\n\n return { ok: true, project: outcome.project, team: outcome.team };\n}\n\n/** Teams the user may create projects in, in the order `/api/me` lists them (oldest first). */\nexport function ownedTeams(teams: HostedTeam[]): HostedTeam[] {\n return teams.filter((team) => team.role === 'owner');\n}\n\n/**\n * Where a new project opens: the AI chat, which can design its schema. The\n * chat route itself, not `/ai`: that redirect would drop the navigation state\n * carrying the onboarding prompt.\n */\nexport function newProjectPath(projectId: string): string {\n return `/${projectId}/ai/agent`;\n}\n","'use client';\n\nimport useSWR, { mutate } from 'swr';\nimport { userApiPaths } from '../api-paths';\nimport type { CreatedProject } from './create-project';\nimport type { HostedTeam, HostedUser, ProjectSummary } from './types';\n\nexport type HostedSession =\n | { status: 'loading' }\n | { status: 'anonymous' }\n | { status: 'error'; message: string }\n | { status: 'ready'; user: HostedUser; projects: ProjectSummary[]; teams: HostedTeam[] };\n\n/** `teams` is missing from backends older than Studio onboarding. */\ntype MeResponse = { projects: ProjectSummary[]; teams?: HostedTeam[]; user: HostedUser };\n\nconst SESSION_KEY = 'hosted-session';\nexport type MeOutcome =\n | { kind: 'anonymous' }\n | { kind: 'error'; message: string }\n | { kind: 'ready'; data: MeResponse };\n\nasync function fetchMe(): Promise<MeOutcome> {\n try {\n const response = await fetch(userApiPaths.me, { credentials: 'same-origin' });\n\n if (response.status === 401) {\n return { kind: 'anonymous' };\n }\n\n if (!response.ok) {\n return { kind: 'error', message: `Flexkit answered ${String(response.status)} while loading your projects.` };\n }\n\n return { kind: 'ready', data: (await response.json()) as MeResponse };\n } catch (error) {\n return { kind: 'error', message: error instanceof Error ? error.message : 'Flexkit is not reachable.' };\n }\n}\n\nexport function toHostedSession(outcome: MeOutcome | undefined): HostedSession {\n if (!outcome) {\n return { status: 'loading' };\n }\n\n if (outcome.kind === 'anonymous') {\n return { status: 'anonymous' };\n }\n\n if (outcome.kind === 'error') {\n return { status: 'error', message: outcome.message };\n }\n\n return {\n status: 'ready',\n projects: outcome.data.projects,\n teams: outcome.data.teams ?? [],\n user: outcome.data.user,\n };\n}\n\n/**\n * Hosted mode: who is signed in and which projects they can open. Fetched once\n * per page load; `rememberCreatedProject` adds a project the user just created.\n */\nexport function useHostedSession(): HostedSession {\n const { data } = useSWR(SESSION_KEY, fetchMe, {\n revalidateOnFocus: false,\n revalidateOnReconnect: false,\n shouldRetryOnError: false,\n });\n\n return toHostedSession(data);\n}\n\n/** The session with a just-created project (and its team, if new) added; the user owns both. */\nexport function withCreatedProject(outcome: MeOutcome | undefined, created: CreatedProject): MeOutcome | undefined {\n if (outcome?.kind !== 'ready' || outcome.data.projects.some((project) => project.id === created.project.id)) {\n return outcome;\n }\n\n const teams = outcome.data.teams ?? [];\n const project: ProjectSummary = {\n avatarUrl: null,\n id: created.project.id,\n name: created.project.name,\n readOnly: false,\n role: 'owner',\n suspended: false,\n team: created.team,\n };\n\n return {\n kind: 'ready',\n data: {\n ...outcome.data,\n projects: [...outcome.data.projects, project],\n teams: teams.some((team) => team.id === created.team.id) ? teams : [...teams, { ...created.team, role: 'owner' }],\n },\n };\n}\n\n/**\n * Adds a project the user just created to the session, so the Studio can open\n * it at once. No `/api/me` round trip: the create response says everything the\n * session needs, and a failed re-read must not hide a project that exists.\n */\nexport async function rememberCreatedProject(created: CreatedProject): Promise<void> {\n await mutate<MeOutcome>(SESSION_KEY, (current) => withCreatedProject(current, created), { revalidate: false });\n}\n\n/** The session with the signed-in user's new display name. */\nexport function withDisplayName(outcome: MeOutcome | undefined, displayName: string): MeOutcome | undefined {\n if (outcome?.kind !== 'ready') {\n return outcome;\n }\n\n return { kind: 'ready', data: { ...outcome.data, user: { ...outcome.data.user, displayName } } };\n}\n\n/** Shows a display name the user just saved, without re-reading `/api/me`. */\nexport async function rememberDisplayName(displayName: string): Promise<void> {\n await mutate<MeOutcome>(SESSION_KEY, (current) => withDisplayName(current, displayName), { revalidate: false });\n}\n","import { useId, useState, type JSX, type ReactNode } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Loader2, MessageSquareText, ShoppingBag, Sparkles, type LucideIcon } from 'lucide-react';\nimport { watchStarter } from '../../apps/ai/starter-watch';\nimport {\n createHostedProject,\n newProjectPath,\n ownedTeams,\n type CreateProjectOutcome,\n} from '../../core/config/create-project';\nimport {\n applyStarter,\n describeBusinessPrompt,\n saveDisplayName,\n toProjectStart,\n validateProjectName,\n type OnboardingNavigationState,\n type ProjectStart,\n} from '../../core/config/onboarding';\nimport type { HostedTeam } from '../../core/config/types';\nimport { rememberCreatedProject, rememberDisplayName } from '../../core/config/use-hosted-session';\nimport { cn } from '../lib/utils';\nimport { Alert, AlertDescription } from '../primitives/alert';\nimport { Button } from '../primitives/button';\nimport { Input } from '../primitives/input';\nimport { Label } from '../primitives/label';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../primitives/select';\nimport { Switch } from '../primitives/switch';\nimport { Textarea } from '../primitives/textarea';\n\ntype Step = 'you' | 'project' | 'start';\ntype StartKind = ProjectStart['kind'];\n\n/**\n * Hosted mode: create a project in at most three short steps. Your name (only\n * when the account has none, e.g. an email sign-up), the project name, and how\n * to start: the commerce starter (schema plus an optional sample store), a\n * description the agent turns into a schema, or an empty project. The project\n * then opens in its AI chat.\n */\nexport function NewProjectFlow({\n askForName = false,\n isFirstProject = false,\n onCancel,\n onCreated,\n teams,\n}: {\n /** Ask for the user's own name first. */\n askForName?: boolean;\n /**\n * The user has no project yet, so the Studio shows this at `/`. Leave `/`\n * before the session lists the project: there, `/` redirects to the project\n * root instead of its AI chat.\n */\n isFirstProject?: boolean;\n onCancel?: () => void;\n /** Called with the new project's id once the Studio opened it. */\n onCreated?: (projectId: string) => void;\n teams: HostedTeam[];\n}): JSX.Element {\n const navigate = useNavigate();\n const ids = { you: useId(), name: useId(), team: useId(), description: useId(), sample: useId() };\n const owned = ownedTeams(teams);\n const [step, setStep] = useState<Step>(askForName ? 'you' : 'project');\n const [displayName, setDisplayName] = useState('');\n const [name, setName] = useState('');\n const [pickedTeamId, setPickedTeamId] = useState<string | null>(null);\n // Follow the teams prop: a pick that is no longer owned falls back to the first owned team.\n const selectedTeamId = owned.some((team) => team.id === pickedTeamId) ? (pickedTeamId ?? '') : (owned[0]?.id ?? '');\n const [startKind, setStartKind] = useState<StartKind>('starter');\n const [sampleData, setSampleData] = useState(true);\n const [description, setDescription] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n // Set once the project exists, so a failed starter is retried on it instead of creating another project.\n const [created, setCreated] = useState<Extract<CreateProjectOutcome, { ok: true }> | null>(null);\n\n async function submitName(): Promise<void> {\n const trimmed = displayName.trim();\n\n if (!trimmed) {\n setError('Tell us your name.');\n\n return;\n }\n\n setError(null);\n setIsSubmitting(true);\n\n const outcome = await saveDisplayName(trimmed);\n\n setIsSubmitting(false);\n\n if (!outcome.ok) {\n setError(outcome.message);\n\n return;\n }\n\n await rememberDisplayName(trimmed);\n setStep('project');\n }\n\n function submitProjectName(): void {\n const invalid = validateProjectName(name);\n\n setError(invalid);\n\n if (!invalid) {\n setStep('start');\n }\n }\n\n async function createProject(): Promise<void> {\n if (startKind === 'describe' && !description.trim()) {\n setError('Describe your business in a sentence or two, or pick another way to start.');\n\n return;\n }\n\n setError(null);\n setIsSubmitting(true);\n\n // No owned team yet: let the backend create the personal team.\n const outcome =\n created ??\n (await createHostedProject({\n name: name.trim(),\n ...(selectedTeamId ? { teamId: selectedTeamId } : {}),\n }));\n\n if (!outcome.ok) {\n setError(outcome.message);\n setIsSubmitting(false);\n\n if (outcome.code === 'invalid_name') {\n setStep('project');\n }\n\n return;\n }\n\n setCreated(outcome);\n\n const projectId = outcome.project.id;\n const start = toProjectStart(startKind, sampleData, description);\n let state: OnboardingNavigationState = {};\n\n if (start.kind === 'starter') {\n const applied = await applyStarter(projectId, { template: start.template, sampleData: start.sampleData });\n\n if (!applied.ok) {\n setError(`${outcome.project.name} was created, but the starter could not be applied: ${applied.message}`);\n setIsSubmitting(false);\n\n // List it now, so closing the dialog does not hide the project until a reload. The welcome screen\n // (first project) would leave this flow once the session lists a project, so it waits for Continue.\n if (!isFirstProject && !created) {\n await rememberCreatedProject(outcome);\n }\n\n return;\n }\n\n watchStarter({ projectId });\n } else if (start.kind === 'describe') {\n state = { onboardingPrompt: describeBusinessPrompt(start.description) };\n }\n\n const path = newProjectPath(projectId);\n\n // Inside a project the Studio only opens ids the session lists, so add it first there.\n if (isFirstProject) {\n navigate(path, { state });\n await rememberCreatedProject(outcome);\n } else {\n await rememberCreatedProject(outcome);\n navigate(path, { state });\n }\n\n onCreated?.(projectId);\n }\n\n const errorAlert = error ? (\n <Alert variant=\"destructive\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n ) : null;\n\n if (step === 'you') {\n return (\n <StepForm onSubmit={() => void submitName()}>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <Label htmlFor={ids.you}>Your name</Label>\n <Input\n autoComplete=\"name\"\n autoFocus\n disabled={isSubmitting}\n id={ids.you}\n maxLength={80}\n onChange={(event) => {\n setDisplayName(event.target.value);\n }}\n placeholder=\"e.g. Ann Meyer\"\n value={displayName}\n />\n <p className=\"fk:text-xs fk:text-muted-foreground\">Your teammates see it on changes and comments.</p>\n </div>\n {errorAlert}\n <StepActions isSubmitting={isSubmitting} submitLabel=\"Continue\" />\n </StepForm>\n );\n }\n\n if (step === 'project') {\n return (\n <StepForm onSubmit={submitProjectName}>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <Label htmlFor={ids.name}>Project name</Label>\n <Input\n aria-invalid={error ? true : undefined}\n autoComplete=\"off\"\n autoFocus\n id={ids.name}\n maxLength={48}\n onChange={(event) => {\n setName(event.target.value);\n }}\n placeholder=\"e.g. Aven Living\"\n value={name}\n />\n <p className=\"fk:text-xs fk:text-muted-foreground\">\n Usually your store or company name. You can change it later.\n </p>\n </div>\n {owned.length > 1 ? (\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <Label htmlFor={ids.team}>Team</Label>\n <Select onValueChange={setPickedTeamId} value={selectedTeamId}>\n <SelectTrigger id={ids.team}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {owned.map((team) => (\n <SelectItem key={team.id} value={team.id}>\n {team.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n {errorAlert}\n <StepActions onCancel={onCancel} submitLabel=\"Continue\" />\n </StepForm>\n );\n }\n\n return (\n <StepForm onSubmit={() => void createProject()}>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <p className=\"fk:text-sm fk:font-medium\" id={`${ids.name}-start`}>\n How do you want to start?\n </p>\n <div aria-labelledby={`${ids.name}-start`} className=\"fk:flex fk:flex-col fk:gap-2\" role=\"radiogroup\">\n <StartOption\n checked={startKind === 'starter'}\n description=\"22 ready-made entities for catalog, inventory, orders, customers and marketing, with EU, UK and US markets.\"\n disabled={isSubmitting}\n icon={ShoppingBag}\n onSelect={() => {\n setStartKind('starter');\n }}\n recommended\n title=\"Commerce starter\"\n >\n <div className=\"fk:flex fk:items-center fk:justify-between fk:gap-3 fk:pt-1\">\n <Label className=\"fk:text-xs fk:font-normal fk:text-muted-foreground\" htmlFor={ids.sample}>\n Add a sample store (Aven Living) to try things out\n </Label>\n <Switch checked={sampleData} disabled={isSubmitting} id={ids.sample} onCheckedChange={setSampleData} />\n </div>\n </StartOption>\n <StartOption\n checked={startKind === 'describe'}\n description=\"Tell the agent what you sell and how you work; it proposes a schema for you to review.\"\n disabled={isSubmitting}\n icon={MessageSquareText}\n onSelect={() => {\n setStartKind('describe');\n }}\n title=\"Describe your business\"\n >\n <Textarea\n aria-label=\"Your business\"\n autoFocus\n disabled={isSubmitting}\n id={ids.description}\n maxLength={2000}\n onChange={(event) => {\n setDescription(event.target.value);\n }}\n placeholder=\"e.g. We sell handmade ceramics online and to 40 shops in Europe, with seasonal collections.\"\n rows={3}\n value={description}\n />\n </StartOption>\n <StartOption\n checked={startKind === 'empty'}\n description=\"Start with an empty project and build the schema in the chat.\"\n disabled={isSubmitting}\n icon={Sparkles}\n onSelect={() => {\n setStartKind('empty');\n }}\n title=\"Start from scratch\"\n />\n </div>\n </div>\n {errorAlert}\n <StepActions\n isSubmitting={isSubmitting}\n onBack={\n created\n ? undefined\n : () => {\n setError(null);\n setStep('project');\n }\n }\n submitLabel={created ? 'Continue' : 'Create project'}\n />\n </StepForm>\n );\n}\n\nfunction StepForm({ children, onSubmit }: { children: ReactNode; onSubmit: () => void }): JSX.Element {\n return (\n <form\n className=\"fk:flex fk:w-full fk:flex-col fk:gap-4\"\n onSubmit={(event) => {\n event.preventDefault();\n onSubmit();\n }}\n >\n {children}\n </form>\n );\n}\n\nfunction StepActions({\n isSubmitting = false,\n onBack,\n onCancel,\n submitLabel,\n}: {\n isSubmitting?: boolean;\n onBack?: () => void;\n onCancel?: () => void;\n submitLabel: string;\n}): JSX.Element {\n const secondary = onBack ?? onCancel;\n\n return (\n <div className=\"fk:flex fk:justify-end fk:gap-2\">\n {secondary ? (\n <Button disabled={isSubmitting} onClick={secondary} type=\"button\" variant=\"outline\">\n {onBack ? 'Back' : 'Cancel'}\n </Button>\n ) : null}\n <Button className={secondary ? undefined : 'fk:w-full'} disabled={isSubmitting} type=\"submit\">\n {isSubmitting ? <Loader2 className=\"fk:h-4 fk:w-4 fk:animate-spin\" /> : null}\n {submitLabel}\n </Button>\n </div>\n );\n}\n\nfunction StartOption({\n checked,\n children,\n description,\n disabled,\n icon: Icon,\n onSelect,\n recommended = false,\n title,\n}: {\n checked: boolean;\n children?: ReactNode;\n description: string;\n disabled: boolean;\n icon: LucideIcon;\n onSelect: () => void;\n recommended?: boolean;\n title: string;\n}): JSX.Element {\n return (\n <div\n className={cn(\n 'fk:rounded-lg fk:border fk:p-3 fk:transition-colors',\n checked\n ? 'fk:border-foreground/70 fk:bg-muted/50 fk:ring-1 fk:ring-foreground/20'\n : 'fk:border-border fk:hover:bg-muted/30'\n )}\n >\n <button\n aria-checked={checked}\n className=\"fk:flex fk:w-full fk:items-start fk:gap-3 fk:text-left fk:disabled:opacity-60\"\n disabled={disabled}\n onClick={onSelect}\n role=\"radio\"\n type=\"button\"\n >\n <Icon className=\"fk:mt-0.5 fk:h-4 fk:w-4 fk:shrink-0 fk:text-muted-foreground\" />\n <span className=\"fk:flex fk:flex-col fk:gap-0.5\">\n <span className=\"fk:flex fk:items-center fk:gap-2 fk:text-sm fk:font-medium\">\n {title}\n {recommended ? (\n <span className=\"fk:rounded-full fk:bg-primary/10 fk:px-2 fk:py-0.5 fk:text-[11px] fk:font-medium fk:text-primary\">\n Recommended\n </span>\n ) : null}\n </span>\n <span className=\"fk:text-xs fk:text-muted-foreground\">{description}</span>\n </span>\n </button>\n {checked && children ? <div className=\"fk:mt-2 fk:pl-7\">{children}</div> : null}\n </div>\n );\n}\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import'./index.css';import {g,d}from'./chunk-MBBE4RND.js';import {b as b$1}from'./chunk-U45E5X3H.js';import w,{mutate}from'swr';import {createContext,lazy,Suspense,useMemo,useContext}from'react';import {Navigate,useParams}from'react-router-dom';import {Bot,Layout,FileStack,BookOpenText,Waypoints,SquarePlay}from'lucide-react';import {jsx,jsxs}from'react/jsx-runtime';var h={name:"_asset",plural:"_assets",display:"originalFilename",menu:{hidden:true},attributes:[{name:"path",label:"Asset",scope:"global",options:{size:140},dataType:"string",inputType:"text",previewType:"assetPreviewField",defaultValue:""},{name:"originalFilename",label:"Filename",scope:"global",options:{size:320},dataType:"string",inputType:"text",previewType:"text",defaultValue:""},{name:"size",label:"Size",scope:"global",options:{size:120},dataType:"int",inputType:"text",previewType:"text",defaultValue:""},{name:"width",label:"Width",scope:"global",options:{size:90},dataType:"int",inputType:"text",previewType:"text",defaultValue:""},{name:"height",label:"Height",scope:"global",options:{size:100},dataType:"int",inputType:"text",previewType:"text",defaultValue:""},{name:"mimeType",label:"Mime Type",scope:"global",options:{size:160},dataType:"string",inputType:"text",previewType:"text",defaultValue:""},{name:"lqip",label:"lqip",scope:"global",hidden:true,dataType:"string",inputType:"text",previewType:"text",defaultValue:""},{name:"url",label:"URL",scope:"global",hidden:true,readOnly:true,dataType:"string",inputType:"text",previewType:"text",defaultValue:""},{name:"_updatedAt",label:"Updated At",scope:"global",options:{size:220},readOnly:true,hidden:true,dataType:"datetime",inputType:"datetime",previewType:"datetime",defaultValue:""},{name:"tags",label:"Tags",scope:"relationship",dataType:"string",inputType:"relationship",defaultValue:"",previewType:"tags",options:{size:300},relationship:{mode:"multiple",field:"name",entity:"_tag"}}]};var f={name:"_tag",plural:"_tags",display:"name",menu:{hidden:true},attributes:[{name:"name",label:"Tag Name",scope:"global",options:{size:220},dataType:"string",inputType:"text",previewType:"text",defaultValue:""},{name:"_updatedAt",label:"Updated At",scope:"global",options:{size:220},readOnly:true,hidden:true,dataType:"datetime",inputType:"datetime",previewType:"datetime",defaultValue:""},{name:"assets",label:"Assets",scope:"relationship",dataType:"string",inputType:"relationship",defaultValue:"",relationship:{mode:"multiple",field:"originalFilename",entity:"_asset"}}]};async function C(e){try{let t=await fetch(d(e).schema,{credentials:"include",mode:"cors",cache:"no-cache"});if(!t.ok){let n=t.statusText||`Request failed with status ${String(t.status)}`;try{let i=await t.json();n=i.error??i.message??n;}catch{}return {ok:!1,projectId:e,error:{status:t.status,message:n}}}let a=await t.json();return {ok:!0,project:{...a,projectId:a.projectId||e}}}catch(t){return {ok:false,projectId:e,error:{status:0,message:t instanceof Error?t.message:"Network error"}}}}function b(e,t){let a=[],n={};for(let i of e??[])i.ok?a.push(i.project):n[i.projectId]=i.error;return {projects:a,errors:n,isLoading:t}}var A={revalidateOnFocus:true,focusThrottleInterval:15e3,revalidateOnReconnect:false};function L(e,t){return !t.ok&&e?.ok?e:t}function E(e,t){let a=t&&e.length>0?["project-schemas",t,...e]:null,{data:n,isLoading:i}=w(a,async()=>(await Promise.all(e.map(r=>C(r)))).map((r,m)=>L(n?.[m],r)),A);return b(n,!!a&&(i||n===void 0))}function N(e,t){return b(e?[e]:void 0,t)}function I(e,t){let a=t&&e?["project-schema",t,e]:null,{data:n,isLoading:i}=w(a,async()=>L(n,await C(e??"")),A);return N(n,!!a&&(i||n===void 0))}function _(e,t){return Array.isArray(e)&&(e[0]==="project-schema"||e[0]==="project-schemas")&&e.slice(2).includes(t)}function Oe(e){return mutate(t=>_(t,e))}function R(){let{resolvedTheme:e}=b$1();return jsx("div",{className:"fk:flex fk:w-full fk:h-full fk:justify-center fk:items-center fk:bg-background",children:jsxs("div",{className:"fk:flex fk:flex-col fk:items-center",children:[e==="dark"?jsxs("svg",{className:"fk:h-8 fk:w-8 fk:animate-bounce",fill:"none",viewBox:"0 0 48 48",xmlns:"http://www.w3.org/2000/svg",children:[jsx("path",{d:"M7 8H41V40H7V8Z",fill:"#020817"}),jsx("path",{d:"M24 0C42 0 48 6 48 24C48 42 42 48 24 48C6 48 0 42 0 24C0 6 6 0 24 0ZM17.7494 9.52381H8.7619L19.2833 23.8313L8.7619 38.7078H17.7494L21.0499 33.6639V14.2549L17.7494 9.52381ZM38.9577 9.52381H29.9542L26.2857 14.8229V33.0406L29.9542 38.7078H38.9577L28.3908 23.8313L38.9577 9.52381Z",fill:"white"})]}):jsxs("svg",{className:"fk:h-8 fk:w-8 fk:animate-bounce",fill:"none",viewBox:"0 0 48 48",xmlns:"http://www.w3.org/2000/svg",children:[jsx("path",{d:"M7 8H41V40H7V8Z",fill:"white"}),jsx("path",{d:"M24 0C42 0 48 6 48 24C48 42 42 48 24 48C6 48 0 42 0 24C0 6 6 0 24 0ZM17.7494 9.52381H8.7619L19.2833 23.8313L8.7619 38.7078H17.7494L21.0499 33.6639V14.2549L17.7494 9.52381ZM38.9577 9.52381H29.9542L26.2857 14.8229V33.0406L29.9542 38.7078H38.9577L28.3908 23.8313L38.9577 9.52381Z",fill:"#020817"})]}),jsx("div",{className:"fk:text-foreground fk:text-center fk:mt-4 fk:animate-pulse",children:"Loading..."})]})})}var $=Navigate;function o(e){let t=lazy(e);return jsx(Suspense,{fallback:jsx(R,{}),children:jsx(t,{})})}var Q=o(()=>import('./root-
|
|
2
|
-
export{R as a,h as b,f as c,Oe as d,$e as e,Qe as f};//# sourceMappingURL=chunk-
|
|
3
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import'./index.css';import {g,d}from'./chunk-MBBE4RND.js';import {b as b$1}from'./chunk-U45E5X3H.js';import w,{mutate}from'swr';import {createContext,lazy,Suspense,useMemo,useContext}from'react';import {Navigate,useParams}from'react-router-dom';import {Bot,Layout,FileStack,BookOpenText,Waypoints,SquarePlay}from'lucide-react';import {jsx,jsxs}from'react/jsx-runtime';var h={name:"_asset",plural:"_assets",display:"originalFilename",menu:{hidden:true},attributes:[{name:"path",label:"Asset",scope:"global",options:{size:140},dataType:"string",inputType:"text",previewType:"assetPreviewField",defaultValue:""},{name:"originalFilename",label:"Filename",scope:"global",options:{size:320},dataType:"string",inputType:"text",previewType:"text",defaultValue:""},{name:"size",label:"Size",scope:"global",options:{size:120},dataType:"int",inputType:"text",previewType:"text",defaultValue:""},{name:"width",label:"Width",scope:"global",options:{size:90},dataType:"int",inputType:"text",previewType:"text",defaultValue:""},{name:"height",label:"Height",scope:"global",options:{size:100},dataType:"int",inputType:"text",previewType:"text",defaultValue:""},{name:"mimeType",label:"Mime Type",scope:"global",options:{size:160},dataType:"string",inputType:"text",previewType:"text",defaultValue:""},{name:"lqip",label:"lqip",scope:"global",hidden:true,dataType:"string",inputType:"text",previewType:"text",defaultValue:""},{name:"url",label:"URL",scope:"global",hidden:true,readOnly:true,dataType:"string",inputType:"text",previewType:"text",defaultValue:""},{name:"_updatedAt",label:"Updated At",scope:"global",options:{size:220},readOnly:true,hidden:true,dataType:"datetime",inputType:"datetime",previewType:"datetime",defaultValue:""},{name:"tags",label:"Tags",scope:"relationship",dataType:"string",inputType:"relationship",defaultValue:"",previewType:"tags",options:{size:300},relationship:{mode:"multiple",field:"name",entity:"_tag"}}]};var f={name:"_tag",plural:"_tags",display:"name",menu:{hidden:true},attributes:[{name:"name",label:"Tag Name",scope:"global",options:{size:220},dataType:"string",inputType:"text",previewType:"text",defaultValue:""},{name:"_updatedAt",label:"Updated At",scope:"global",options:{size:220},readOnly:true,hidden:true,dataType:"datetime",inputType:"datetime",previewType:"datetime",defaultValue:""},{name:"assets",label:"Assets",scope:"relationship",dataType:"string",inputType:"relationship",defaultValue:"",relationship:{mode:"multiple",field:"originalFilename",entity:"_asset"}}]};async function C(e){try{let t=await fetch(d(e).schema,{credentials:"include",mode:"cors",cache:"no-cache"});if(!t.ok){let n=t.statusText||`Request failed with status ${String(t.status)}`;try{let i=await t.json();n=i.error??i.message??n;}catch{}return {ok:!1,projectId:e,error:{status:t.status,message:n}}}let a=await t.json();return {ok:!0,project:{...a,projectId:a.projectId||e}}}catch(t){return {ok:false,projectId:e,error:{status:0,message:t instanceof Error?t.message:"Network error"}}}}function b(e,t){let a=[],n={};for(let i of e??[])i.ok?a.push(i.project):n[i.projectId]=i.error;return {projects:a,errors:n,isLoading:t}}var A={revalidateOnFocus:true,focusThrottleInterval:15e3,revalidateOnReconnect:false};function L(e,t){return !t.ok&&e?.ok?e:t}function E(e,t){let a=t&&e.length>0?["project-schemas",t,...e]:null,{data:n,isLoading:i}=w(a,async()=>(await Promise.all(e.map(r=>C(r)))).map((r,m)=>L(n?.[m],r)),A);return b(n,!!a&&(i||n===void 0))}function N(e,t){return b(e?[e]:void 0,t)}function I(e,t){let a=t&&e?["project-schema",t,e]:null,{data:n,isLoading:i}=w(a,async()=>L(n,await C(e??"")),A);return N(n,!!a&&(i||n===void 0))}function _(e,t){return Array.isArray(e)&&(e[0]==="project-schema"||e[0]==="project-schemas")&&e.slice(2).includes(t)}function Oe(e){return mutate(t=>_(t,e))}function R(){let{resolvedTheme:e}=b$1();return jsx("div",{className:"fk:flex fk:w-full fk:h-full fk:justify-center fk:items-center fk:bg-background",children:jsxs("div",{className:"fk:flex fk:flex-col fk:items-center",children:[e==="dark"?jsxs("svg",{className:"fk:h-8 fk:w-8 fk:animate-bounce",fill:"none",viewBox:"0 0 48 48",xmlns:"http://www.w3.org/2000/svg",children:[jsx("path",{d:"M7 8H41V40H7V8Z",fill:"#020817"}),jsx("path",{d:"M24 0C42 0 48 6 48 24C48 42 42 48 24 48C6 48 0 42 0 24C0 6 6 0 24 0ZM17.7494 9.52381H8.7619L19.2833 23.8313L8.7619 38.7078H17.7494L21.0499 33.6639V14.2549L17.7494 9.52381ZM38.9577 9.52381H29.9542L26.2857 14.8229V33.0406L29.9542 38.7078H38.9577L28.3908 23.8313L38.9577 9.52381Z",fill:"white"})]}):jsxs("svg",{className:"fk:h-8 fk:w-8 fk:animate-bounce",fill:"none",viewBox:"0 0 48 48",xmlns:"http://www.w3.org/2000/svg",children:[jsx("path",{d:"M7 8H41V40H7V8Z",fill:"white"}),jsx("path",{d:"M24 0C42 0 48 6 48 24C48 42 42 48 24 48C6 48 0 42 0 24C0 6 6 0 24 0ZM17.7494 9.52381H8.7619L19.2833 23.8313L8.7619 38.7078H17.7494L21.0499 33.6639V14.2549L17.7494 9.52381ZM38.9577 9.52381H29.9542L26.2857 14.8229V33.0406L29.9542 38.7078H38.9577L28.3908 23.8313L38.9577 9.52381Z",fill:"#020817"})]}),jsx("div",{className:"fk:text-foreground fk:text-center fk:mt-4 fk:animate-pulse",children:"Loading..."})]})})}var $=Navigate;function o(e){let t=lazy(e);return jsx(Suspense,{fallback:jsx(R,{}),children:jsx(t,{})})}var Q=o(()=>import('./root-SYRZ3UBN.js').then(e=>({default:e.Root}))),Y=o(()=>import('./list-4EXGXJZA.js').then(e=>({default:e.List}))),ee=o(()=>import('./edit-entity-PVT34FD7.js').then(e=>({default:e.EditEntity}))),te=o(()=>import('./root-422O7YX5.js').then(e=>({default:e.Root}))),oe=o(()=>import('./root-7NZPP7IC.js').then(e=>({default:e.Root}))),ne=o(()=>import('./list-XTC2OYA6.js').then(e=>({default:e.List}))),ae=o(()=>import('./source-43PHAELP.js').then(e=>({default:e.Source}))),ie=o(()=>import('./root-3Q44ISGQ.js').then(e=>({default:e.Root}))),re=o(()=>import('./root-7FYWXLI6.js').then(e=>({default:e.Root}))),se=o(()=>import('./root-Q6SHODPG.js').then(e=>({default:e.Root}))),pe=o(()=>import('./plugin-pages-CUTCB6NU.js').then(e=>({default:e.PluginsPage}))),ce=o(()=>import('./plugin-pages-CUTCB6NU.js').then(e=>({default:e.InstalledPluginsPage}))),le=o(()=>import('./plugin-pages-CUTCB6NU.js').then(e=>({default:e.PluginDetailPage}))),O=o(()=>import('./chat-page-2ES466GO.js').then(e=>({default:e.AgentChatPage}))),me=o(()=>import('./pages-HW4OCENA.js').then(e=>({default:e.AutomationsPage}))),ue=o(()=>import('./pages-HW4OCENA.js').then(e=>({default:e.RunHistoryPage}))),de=o(()=>import('./pages-HW4OCENA.js').then(e=>({default:e.ApprovalsPage}))),he=o(()=>import('./pages-HW4OCENA.js').then(e=>({default:e.ActivityPage}))),fe=o(()=>import('./pages-HW4OCENA.js').then(e=>({default:e.ActivityItemPage}))),ge=o(()=>import('./pages-HW4OCENA.js').then(e=>({default:e.CreateAutomationPage}))),ye=o(()=>import('./pages-HW4OCENA.js').then(e=>({default:e.AutomationDetailPage}))),Pe=o(()=>import('./pages-HW4OCENA.js').then(e=>({default:e.RunsPage}))),Se=o(()=>import('./pages-HW4OCENA.js').then(e=>({default:e.RunDetailPage}))),ke=o(()=>import('./skills-pages-X3DVZXY5.js').then(e=>({default:e.SkillsPage}))),je=o(()=>import('./skills-pages-X3DVZXY5.js').then(e=>({default:e.CreateSkillPage}))),Te=o(()=>import('./skills-pages-X3DVZXY5.js').then(e=>({default:e.SkillDetailPage}))),l=[{name:"ai",icon:jsx(Bot,{strokeWidth:1.5}),title:"AI",component:se,routes:[{path:"plugins",component:pe},{path:"plugins/installed",component:ce},{path:"plugins/:pluginId",component:le},{component:jsx($,{replace:true,to:"agent"}),path:""},{component:O,path:"agent"},{component:O,path:"agent/chats/:chatId"},{component:me,path:"automations"},{component:ue,path:"runs"},{component:de,path:"approvals"},{component:he,path:"activity"},{component:fe,path:"activity/:itemId"},{component:ge,path:"automations/new"},{component:ye,path:"automations/:automationId"},{component:Pe,path:"automations/:automationId/runs"},{component:Se,path:"automations/:automationId/runs/:runId"},{component:ke,path:"skills"},{component:je,path:"skills/new"},{component:Te,path:"skills/:skillId"}]},{name:"desk",icon:jsx(Layout,{strokeWidth:1.5}),title:"Desk",component:Q,routes:[{path:"list/:entity",component:Y,children:[{path:"edit/:id",component:ee}]}]},{name:"asset-manager",icon:jsx(FileStack,{strokeWidth:1.5}),title:"Asset Manager",component:te,routes:[]},{name:"knowledge",icon:jsx(BookOpenText,{strokeWidth:1.5}),title:"Knowledge",component:oe,routes:[{component:ne,path:""},{component:ae,path:":sourceId"}]},{name:"graph",icon:jsx(Waypoints,{strokeWidth:1.5}),title:"Graph",component:ie,routes:[]},{name:"explorer",icon:jsx(SquarePlay,{strokeWidth:1.5}),title:"Explorer",component:re,routes:[]}];var H=createContext({mode:"projects",apps:l,contributions:{apps:l},currentProjectId:void 0,currentProject:void 0,currentProjectSchema:[],projects:[],projectIds:[],projectSummaries:[],teams:[],schemaErrors:{},isLoadingSchemas:false}),Ce=[];function be(e){return [...e.filter(a=>a.name!==h.name&&a.name!==f.name),h,f]}function $e({projectIds:e,projectSummaries:t=[],teams:a=Ce,mode:n="projects",userId:i,children:y}){let{projectId:r}=useParams(),[,m]=g(),P=m.user?.id??i,F=E(n==="projects"?e:[],P),M=I(n==="hosted"&&r&&e.includes(r)?r:void 0,P),{projects:S,errors:k,isLoading:j}=n==="hosted"?M:F,u=useMemo(()=>e.map(p=>S.find(d=>d.projectId===p)).filter(p=>p!==void 0).map(p=>({...p,schema:be(p.schema)})),[S,e]),z=useMemo(()=>{let p=u.find(d=>d.projectId===r);return {mode:n,apps:l,contributions:{apps:l},currentProjectId:r,currentProject:p,currentProjectSchema:p?.schema??[],projects:u,projectIds:e,projectSummaries:t,teams:a,schemaErrors:k,isLoadingSchemas:j}},[r,k,j,n,e,t,u,a]);return jsx(H.Provider,{value:z,children:y})}function Qe(){return useContext(H)}
|
|
2
|
+
export{R as a,h as b,f as c,Oe as d,$e as e,Qe as f};//# sourceMappingURL=chunk-TP6QGIJH.js.map
|
|
3
|
+
//# sourceMappingURL=chunk-TP6QGIJH.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/entities/assets-schema.ts","../src/entities/tags-schema.ts","../src/core/config/use-project-schemas.ts","../src/ui/components/loading.tsx","../src/core/apps/built-in-apps.tsx","../src/core/config/config-context.tsx"],"names":["assetSchema","tagSchema","fetchProjectSchema","projectId","response","apiPaths","message","body","project","error","toProjectSchemasState","outcomes","isLoading","projects","errors","outcome","SCHEMA_SWR_OPTIONS","keepLoadedSchema","previous","next","useProjectSchemas","projectIds","userId","key","data","useSWR","index","toProjectSchemaState","useProjectSchema","isProjectSchemaKey","revalidateProjectSchema","mutate","Loading","resolvedTheme","useTheme","jsx","jsxs","NavigateCompat","Navigate","lazyElement","loader","Component","lazy","Suspense","deskRoot","m","deskList","deskEditEntity","assetManagerRoot","knowledgeRoot","knowledgeList","knowledgeSource","graphRoot","explorerRoot","aiRoot","aiPluginsPage","aiInstalledPluginsPage","aiPluginDetailPage","aiAgentChatPage","aiAutomationsPage","aiRunHistoryPage","aiApprovalsPage","aiActivityPage","aiActivityItemPage","aiCreateAutomationPage","aiAutomationDetailPage","aiRunsPage","aiRunDetailPage","aiSkillsPage","aiCreateSkillPage","aiSkillDetailPage","builtInApps","BotIcon","LayoutIcon","FileStackIcon","BookOpenTextIcon","WaypointsIcon","SquarePlayIcon","ConfigContext","createContext","NO_TEAMS","upsertReservedEntities","schema","entity","ConfigProvider","projectSummaries","teams","mode","children","currentProjectId","useParams","auth","useAuth","schemaUserId","allSchemas","currentSchema","loadedProjects","useMemo","value","currentProject","useConfig","useContext"],"mappings":"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","file":"chunk-CC2U7ASG.js","sourcesContent":["import type { Entity } from '../core/types';\n\nexport const assetSchema: Entity = {\n name: '_asset',\n plural: '_assets',\n display: 'originalFilename',\n menu: {\n hidden: true,\n },\n attributes: [\n {\n name: 'path',\n label: 'Asset',\n scope: 'global',\n options: {\n size: 140,\n },\n dataType: 'string',\n inputType: 'text',\n previewType: 'assetPreviewField',\n defaultValue: '',\n },\n {\n name: 'originalFilename',\n label: 'Filename',\n scope: 'global',\n options: {\n size: 320,\n },\n dataType: 'string',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'size',\n label: 'Size',\n scope: 'global',\n options: {\n size: 120,\n },\n dataType: 'int',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'width',\n label: 'Width',\n scope: 'global',\n options: {\n size: 90,\n },\n dataType: 'int',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'height',\n label: 'Height',\n scope: 'global',\n options: {\n size: 100,\n },\n dataType: 'int',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'mimeType',\n label: 'Mime Type',\n scope: 'global',\n options: {\n size: 160,\n },\n dataType: 'string',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'lqip',\n label: 'lqip',\n scope: 'global',\n hidden: true,\n dataType: 'string',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'url',\n label: 'URL',\n scope: 'global',\n hidden: true,\n readOnly: true,\n dataType: 'string',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: '_updatedAt',\n label: 'Updated At',\n scope: 'global',\n options: {\n size: 220,\n },\n readOnly: true,\n hidden: true,\n dataType: 'datetime',\n inputType: 'datetime',\n previewType: 'datetime',\n defaultValue: '',\n },\n {\n name: 'tags',\n label: 'Tags',\n scope: 'relationship',\n dataType: 'string',\n inputType: 'relationship',\n defaultValue: '',\n previewType: 'tags',\n options: {\n size: 300,\n },\n relationship: {\n mode: 'multiple',\n field: 'name',\n entity: '_tag',\n },\n },\n ],\n};\n","import type { Entity } from '../core/types';\n\nexport const tagSchema: Entity = {\n name: '_tag',\n plural: '_tags',\n display: 'name',\n menu: {\n hidden: true,\n },\n attributes: [\n {\n name: 'name',\n label: 'Tag Name',\n scope: 'global',\n options: {\n size: 220,\n },\n dataType: 'string',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: '_updatedAt',\n label: 'Updated At',\n scope: 'global',\n options: {\n size: 220,\n },\n readOnly: true,\n hidden: true,\n dataType: 'datetime',\n inputType: 'datetime',\n previewType: 'datetime',\n defaultValue: '',\n },\n {\n name: 'assets',\n label: 'Assets',\n scope: 'relationship',\n dataType: 'string',\n inputType: 'relationship',\n defaultValue: '',\n relationship: {\n mode: 'multiple',\n field: 'originalFilename',\n entity: '_asset',\n },\n },\n ],\n};\n","'use client';\n\nimport useSWR, { mutate } from 'swr';\nimport { apiPaths } from '../api-paths';\nimport type { ProjectSchemaError, ProjectUiConfig } from './types';\n\nexport type ProjectSchemasState = {\n projects: ProjectUiConfig[];\n errors: { [projectId: string]: ProjectSchemaError };\n isLoading: boolean;\n};\n\nexport type FetchOutcome =\n | { ok: true; project: ProjectUiConfig }\n | { ok: false; projectId: string; error: ProjectSchemaError };\n\nasync function fetchProjectSchema(projectId: string): Promise<FetchOutcome> {\n try {\n const response = await fetch(apiPaths(projectId).schema, {\n credentials: 'include',\n mode: 'cors',\n // Revalidate with the server on every fetch (304 when unchanged), so a\n // refetch after a deploy never reads a stale HTTP-cached schema.\n cache: 'no-cache',\n });\n\n if (!response.ok) {\n let message = response.statusText || `Request failed with status ${String(response.status)}`;\n\n try {\n const body = (await response.json()) as { error?: string; message?: string };\n message = body.error ?? body.message ?? message;\n } catch {\n // keep the status text\n }\n\n return { ok: false, projectId, error: { status: response.status, message } };\n }\n\n const project = (await response.json()) as ProjectUiConfig;\n\n return { ok: true, project: { ...project, projectId: project.projectId || projectId } };\n } catch (error) {\n return {\n ok: false,\n projectId,\n error: { status: 0, message: error instanceof Error ? error.message : 'Network error' },\n };\n }\n}\n\nexport function toProjectSchemasState(outcomes: FetchOutcome[] | undefined, isLoading: boolean): ProjectSchemasState {\n const projects: ProjectUiConfig[] = [];\n const errors: { [projectId: string]: ProjectSchemaError } = {};\n\n for (const outcome of outcomes ?? []) {\n if (outcome.ok) {\n projects.push(outcome.project);\n } else {\n errors[outcome.projectId] = outcome.error;\n }\n }\n\n return { projects, errors, isLoading };\n}\n\n/**\n * Schemas change on deploy, which can happen outside this tab (the agent, the\n * CLI). Refetch when the user comes back to the tab, at most every 15s;\n * SWR compares the result, so an unchanged schema does not re-render.\n */\nconst SCHEMA_SWR_OPTIONS = {\n revalidateOnFocus: true,\n focusThrottleInterval: 15_000,\n revalidateOnReconnect: false,\n} as const;\n\n/**\n * A refetch (tab focus, reload button, watched deploy) must never replace a\n * schema that already loaded with an error: that would swap the whole app for\n * an error screen and drop an open edit drawer. Offline, an expired session or\n * revoked access still surface through the GraphQL requests themselves.\n */\nexport function keepLoadedSchema(previous: FetchOutcome | undefined, next: FetchOutcome): FetchOutcome {\n return !next.ok && previous?.ok ? previous : next;\n}\n\n/**\n * Loads the deployed schema of every project the Studio can open. Fetching\n * starts once the user is known (the endpoint needs a session). The result is\n * refetched on tab focus, on the list's reload button and after a deploy the\n * Studio watched.\n */\nexport function useProjectSchemas(projectIds: string[], userId: string | undefined): ProjectSchemasState {\n const key = userId && projectIds.length > 0 ? ['project-schemas', userId, ...projectIds] : null;\n const { data, isLoading } = useSWR(\n key,\n async (): Promise<FetchOutcome[]> => {\n const outcomes = await Promise.all(projectIds.map((projectId) => fetchProjectSchema(projectId)));\n\n // The key fixes the order of projectIds, so outcomes line up with the previous data.\n return outcomes.map((outcome, index) => keepLoadedSchema(data?.[index], outcome));\n },\n SCHEMA_SWR_OPTIONS\n );\n\n return toProjectSchemasState(data, Boolean(key) && (isLoading || data === undefined));\n}\n\n/** State of a single project's schema, in the same shape as the multi-project hook. */\nexport function toProjectSchemaState(outcome: FetchOutcome | undefined, isLoading: boolean): ProjectSchemasState {\n return toProjectSchemasState(outcome ? [outcome] : undefined, isLoading);\n}\n\n/**\n * Hosted mode: loads only the project currently open. Each project has its own\n * SWR key, so switching back to a project reuses the schema already fetched.\n */\nexport function useProjectSchema(projectId: string | undefined, userId: string | undefined): ProjectSchemasState {\n const key = userId && projectId ? ['project-schema', userId, projectId] : null;\n const { data, isLoading } = useSWR(\n key,\n async (): Promise<FetchOutcome> => keepLoadedSchema(data, await fetchProjectSchema(projectId ?? '')),\n SCHEMA_SWR_OPTIONS\n );\n\n return toProjectSchemaState(data, Boolean(key) && (isLoading || data === undefined));\n}\n\n/** True for the SWR keys that hold `projectId`'s schema (single- and multi-project hooks). */\nexport function isProjectSchemaKey(key: unknown, projectId: string): boolean {\n return (\n Array.isArray(key) &&\n (key[0] === 'project-schema' || key[0] === 'project-schemas') &&\n key.slice(2).includes(projectId)\n );\n}\n\n/** Refetches the deployed schema of `projectId`, e.g. after the agent deployed a schema change. */\nexport function revalidateProjectSchema(projectId: string): Promise<unknown> {\n return mutate((key) => isProjectSchemaKey(key, projectId));\n}\n","import type { JSX } from 'react';\nimport { useTheme } from '../theme-context';\n\nexport function Loading(): JSX.Element {\n const { resolvedTheme } = useTheme();\n\n return (\n <div className=\"fk:flex fk:w-full fk:h-full fk:justify-center fk:items-center fk:bg-background\">\n <div className=\"fk:flex fk:flex-col fk:items-center\">\n {resolvedTheme === 'dark' ? (\n <svg\n className=\"fk:h-8 fk:w-8 fk:animate-bounce\"\n fill=\"none\"\n viewBox=\"0 0 48 48\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M7 8H41V40H7V8Z\" fill=\"#020817\" />\n <path\n d=\"M24 0C42 0 48 6 48 24C48 42 42 48 24 48C6 48 0 42 0 24C0 6 6 0 24 0ZM17.7494 9.52381H8.7619L19.2833 23.8313L8.7619 38.7078H17.7494L21.0499 33.6639V14.2549L17.7494 9.52381ZM38.9577 9.52381H29.9542L26.2857 14.8229V33.0406L29.9542 38.7078H38.9577L28.3908 23.8313L38.9577 9.52381Z\"\n fill=\"white\"\n />\n </svg>\n ) : (\n <svg\n className=\"fk:h-8 fk:w-8 fk:animate-bounce\"\n fill=\"none\"\n viewBox=\"0 0 48 48\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M7 8H41V40H7V8Z\" fill=\"white\" />\n <path\n d=\"M24 0C42 0 48 6 48 24C48 42 42 48 24 48C6 48 0 42 0 24C0 6 6 0 24 0ZM17.7494 9.52381H8.7619L19.2833 23.8313L8.7619 38.7078H17.7494L21.0499 33.6639V14.2549L17.7494 9.52381ZM38.9577 9.52381H29.9542L26.2857 14.8229V33.0406L29.9542 38.7078H38.9577L28.3908 23.8313L38.9577 9.52381Z\"\n fill=\"#020817\"\n />\n </svg>\n )}\n <div className=\"fk:text-foreground fk:text-center fk:mt-4 fk:animate-pulse\">Loading...</div>\n </div>\n </div>\n );\n}\n","import { lazy, Suspense } from 'react';\nimport type { ComponentType, JSX } from 'react';\nimport {\n BookOpenText as BookOpenTextIcon,\n Bot as BotIcon,\n FileStack as FileStackIcon,\n Layout as LayoutIcon,\n SquarePlay as SquarePlayIcon,\n Waypoints as WaypointsIcon,\n} from 'lucide-react';\nimport { Navigate } from 'react-router-dom';\nimport { Loading } from '../../ui/components/loading';\nimport type { AppOptions } from '../config/types';\n\nconst NavigateCompat = Navigate as unknown as ComponentType<{\n replace?: boolean;\n to: string;\n}>;\n\n/**\n * Wraps a lazily imported component in Suspense so each built-in app (and each of its routes)\n * is only downloaded when it is first rendered.\n */\nfunction lazyElement(loader: () => Promise<{ default: ComponentType }>): JSX.Element {\n const Component = lazy(loader);\n\n return (\n <Suspense fallback={<Loading />}>\n <Component />\n </Suspense>\n );\n}\n\n// Desk\nconst deskRoot = lazyElement(() => import('../../apps/desk/root').then((m) => ({ default: m.Root })));\nconst deskList = lazyElement(() => import('../../apps/desk/list').then((m) => ({ default: m.List })));\nconst deskEditEntity = lazyElement(() =>\n import('../../apps/desk/edit-entity').then((m) => ({ default: m.EditEntity }))\n);\n\n// Asset Manager\nconst assetManagerRoot = lazyElement(() => import('../../apps/asset-manager/root').then((m) => ({ default: m.Root })));\n\n// Knowledge\nconst knowledgeRoot = lazyElement(() => import('../../apps/knowledge/root').then((m) => ({ default: m.Root })));\nconst knowledgeList = lazyElement(() => import('../../apps/knowledge/list').then((m) => ({ default: m.List })));\nconst knowledgeSource = lazyElement(() => import('../../apps/knowledge/source').then((m) => ({ default: m.Source })));\n\n// Graph\nconst graphRoot = lazyElement(() => import('../../apps/graph/root').then((m) => ({ default: m.Root })));\n\n// Explorer\nconst explorerRoot = lazyElement(() => import('../../apps/explorer/root').then((m) => ({ default: m.Root })));\n\n// AI\nconst aiRoot = lazyElement(() => import('../../apps/ai/root').then((m) => ({ default: m.Root })));\nconst aiPluginsPage = lazyElement(() => import('../../apps/ai/plugin-pages').then((m) => ({ default: m.PluginsPage })));\nconst aiInstalledPluginsPage = lazyElement(() =>\n import('../../apps/ai/plugin-pages').then((m) => ({ default: m.InstalledPluginsPage }))\n);\nconst aiPluginDetailPage = lazyElement(() =>\n import('../../apps/ai/plugin-pages').then((m) => ({ default: m.PluginDetailPage }))\n);\nconst aiAgentChatPage = lazyElement(() =>\n import('../../apps/ai/agent/chat-page').then((m) => ({ default: m.AgentChatPage }))\n);\nconst aiAutomationsPage = lazyElement(() =>\n import('../../apps/ai/pages').then((m) => ({ default: m.AutomationsPage }))\n);\nconst aiRunHistoryPage = lazyElement(() => import('../../apps/ai/pages').then((m) => ({ default: m.RunHistoryPage })));\nconst aiApprovalsPage = lazyElement(() => import('../../apps/ai/pages').then((m) => ({ default: m.ApprovalsPage })));\nconst aiActivityPage = lazyElement(() => import('../../apps/ai/pages').then((m) => ({ default: m.ActivityPage })));\nconst aiActivityItemPage = lazyElement(() =>\n import('../../apps/ai/pages').then((m) => ({ default: m.ActivityItemPage }))\n);\nconst aiCreateAutomationPage = lazyElement(() =>\n import('../../apps/ai/pages').then((m) => ({ default: m.CreateAutomationPage }))\n);\nconst aiAutomationDetailPage = lazyElement(() =>\n import('../../apps/ai/pages').then((m) => ({ default: m.AutomationDetailPage }))\n);\nconst aiRunsPage = lazyElement(() => import('../../apps/ai/pages').then((m) => ({ default: m.RunsPage })));\nconst aiRunDetailPage = lazyElement(() => import('../../apps/ai/pages').then((m) => ({ default: m.RunDetailPage })));\nconst aiSkillsPage = lazyElement(() => import('../../apps/ai/skills-pages').then((m) => ({ default: m.SkillsPage })));\nconst aiCreateSkillPage = lazyElement(() =>\n import('../../apps/ai/skills-pages').then((m) => ({ default: m.CreateSkillPage }))\n);\nconst aiSkillDetailPage = lazyElement(() =>\n import('../../apps/ai/skills-pages').then((m) => ({ default: m.SkillDetailPage }))\n);\n\nexport const builtInApps: AppOptions[] = [\n {\n name: 'ai',\n icon: <BotIcon strokeWidth={1.5} />,\n title: 'AI',\n component: aiRoot,\n routes: [\n { path: 'plugins', component: aiPluginsPage },\n { path: 'plugins/installed', component: aiInstalledPluginsPage },\n { path: 'plugins/:pluginId', component: aiPluginDetailPage },\n {\n component: <NavigateCompat replace to=\"agent\" />,\n path: '',\n },\n {\n component: aiAgentChatPage,\n path: 'agent',\n },\n {\n component: aiAgentChatPage,\n path: 'agent/chats/:chatId',\n },\n {\n component: aiAutomationsPage,\n path: 'automations',\n },\n {\n component: aiRunHistoryPage,\n path: 'runs',\n },\n {\n component: aiApprovalsPage,\n path: 'approvals',\n },\n {\n component: aiActivityPage,\n path: 'activity',\n },\n {\n component: aiActivityItemPage,\n path: 'activity/:itemId',\n },\n {\n component: aiCreateAutomationPage,\n path: 'automations/new',\n },\n {\n component: aiAutomationDetailPage,\n path: 'automations/:automationId',\n },\n {\n component: aiRunsPage,\n path: 'automations/:automationId/runs',\n },\n {\n component: aiRunDetailPage,\n path: 'automations/:automationId/runs/:runId',\n },\n {\n component: aiSkillsPage,\n path: 'skills',\n },\n {\n component: aiCreateSkillPage,\n path: 'skills/new',\n },\n {\n component: aiSkillDetailPage,\n path: 'skills/:skillId',\n },\n ],\n },\n {\n name: 'desk',\n icon: <LayoutIcon strokeWidth={1.5} />,\n title: 'Desk',\n component: deskRoot,\n routes: [\n {\n path: 'list/:entity',\n component: deskList,\n children: [\n {\n path: 'edit/:id',\n component: deskEditEntity, // Not used, left here as an example of how to nest routes in apps\n },\n ],\n },\n ],\n },\n {\n name: 'asset-manager',\n icon: <FileStackIcon strokeWidth={1.5} />,\n title: 'Asset Manager',\n component: assetManagerRoot,\n routes: [],\n },\n {\n name: 'knowledge',\n icon: <BookOpenTextIcon strokeWidth={1.5} />,\n title: 'Knowledge',\n component: knowledgeRoot,\n routes: [\n {\n component: knowledgeList,\n path: '',\n },\n {\n component: knowledgeSource,\n path: ':sourceId',\n },\n ],\n },\n {\n name: 'graph',\n icon: <WaypointsIcon strokeWidth={1.5} />,\n title: 'Graph',\n component: graphRoot,\n routes: [],\n },\n {\n name: 'explorer',\n icon: <SquarePlayIcon strokeWidth={1.5} />,\n title: 'Explorer',\n component: explorerRoot,\n routes: [],\n },\n];\n","'use client';\n\nimport { createContext, useContext, useMemo } from 'react';\nimport type { JSX } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useAuth } from '../../auth/auth-context';\nimport { assetSchema } from '../../entities/assets-schema';\nimport { tagSchema } from '../../entities/tags-schema';\nimport { builtInApps } from '../apps/built-in-apps';\nimport type { AppOptions, HostedTeam, ProjectSchemaError, ProjectSummary, ProjectUiConfig, StudioMode } from './types';\nimport type { Entity } from '../types';\nimport { useProjectSchema, useProjectSchemas } from './use-project-schemas';\n\nexport interface ConfigContext {\n /** `projects` when the host passed `projectIds`, `hosted` when the Studio listed the user's projects itself. */\n mode: StudioMode;\n /** The Studio apps shown in the app bar, in order. */\n apps: AppOptions[];\n /** Kept for callers that read `contributions.apps`; same list as `apps`. */\n contributions: {\n apps: AppOptions[];\n };\n currentProjectId?: string;\n /** The project named by the `:projectId` route param, once its schema has loaded. */\n currentProject?: ProjectUiConfig;\n currentProjectSchema: Entity[];\n /** Projects whose schema loaded, in `projectIds` order. */\n projects: ProjectUiConfig[];\n /** Every project id the Studio can open, loaded or not. */\n projectIds: string[];\n /** Hosted mode: name, avatar, role and team of each project, known before any schema loads. */\n projectSummaries: ProjectSummary[];\n /** Hosted mode: the user's teams with their role; owners can create projects in them. */\n teams: HostedTeam[];\n /** Per project id: why its schema could not be loaded. */\n schemaErrors: { [projectId: string]: ProjectSchemaError };\n isLoadingSchemas: boolean;\n}\n\nconst ConfigContext = createContext<ConfigContext>({\n mode: 'projects',\n apps: builtInApps,\n contributions: { apps: builtInApps },\n currentProjectId: undefined,\n currentProject: undefined,\n currentProjectSchema: [],\n projects: [],\n projectIds: [],\n projectSummaries: [],\n teams: [],\n schemaErrors: {},\n isLoadingSchemas: false,\n});\n\nconst NO_TEAMS: HostedTeam[] = [];\n\n/** Appends the reserved asset and tag entities to a deployed schema. */\nexport function upsertReservedEntities(schema: Entity[]): Entity[] {\n const withoutReserved = schema.filter((entity) => entity.name !== assetSchema.name && entity.name !== tagSchema.name);\n\n return [...withoutReserved, assetSchema, tagSchema];\n}\n\nexport function ConfigProvider({\n projectIds,\n projectSummaries = [],\n teams = NO_TEAMS,\n mode = 'projects',\n userId,\n children,\n}: {\n projectIds: string[];\n projectSummaries?: ProjectSummary[];\n teams?: HostedTeam[];\n mode?: StudioMode;\n /** Hosted mode: the signed-in user's id, known before the per-project `/users/me` call. */\n userId?: string;\n children: React.ReactNode;\n}): JSX.Element {\n /**\n * Getting the projectId from the URL via react-router-dom's useParams hook triggers a rerender of this Context\n * every time the URL changes.\n */\n const { projectId: currentProjectId } = useParams<{ projectId: string }>();\n const [, auth] = useAuth();\n const schemaUserId = auth.user?.id ?? userId;\n // Project mode loads every project up front (short, host-defined list); hosted mode only the one open.\n const allSchemas = useProjectSchemas(mode === 'projects' ? projectIds : [], schemaUserId);\n const currentSchema = useProjectSchema(\n mode === 'hosted' && currentProjectId && projectIds.includes(currentProjectId) ? currentProjectId : undefined,\n schemaUserId\n );\n const { projects: loadedProjects, errors, isLoading } = mode === 'hosted' ? currentSchema : allSchemas;\n const projects = useMemo(\n () =>\n projectIds\n .map((projectId) => loadedProjects.find((project) => project.projectId === projectId))\n .filter((project): project is ProjectUiConfig => project !== undefined)\n .map((project) => ({ ...project, schema: upsertReservedEntities(project.schema) })),\n [loadedProjects, projectIds]\n );\n\n const value = useMemo<ConfigContext>(() => {\n const currentProject = projects.find((project) => project.projectId === currentProjectId);\n\n return {\n mode,\n apps: builtInApps,\n contributions: { apps: builtInApps },\n currentProjectId,\n currentProject,\n currentProjectSchema: currentProject?.schema ?? [],\n projects,\n projectIds,\n projectSummaries,\n teams,\n schemaErrors: errors,\n isLoadingSchemas: isLoading,\n };\n }, [currentProjectId, errors, isLoading, mode, projectIds, projectSummaries, projects, teams]);\n\n return <ConfigContext.Provider value={value}>{children}</ConfigContext.Provider>;\n}\n\nexport function useConfig(): ConfigContext {\n return useContext(ConfigContext);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/entities/assets-schema.ts","../src/entities/tags-schema.ts","../src/core/config/use-project-schemas.ts","../src/ui/components/loading.tsx","../src/core/apps/built-in-apps.tsx","../src/core/config/config-context.tsx"],"names":["assetSchema","tagSchema","fetchProjectSchema","projectId","response","apiPaths","message","body","project","error","toProjectSchemasState","outcomes","isLoading","projects","errors","outcome","SCHEMA_SWR_OPTIONS","keepLoadedSchema","previous","next","useProjectSchemas","projectIds","userId","key","data","useSWR","index","toProjectSchemaState","useProjectSchema","isProjectSchemaKey","revalidateProjectSchema","mutate","Loading","resolvedTheme","useTheme","jsx","jsxs","NavigateCompat","Navigate","lazyElement","loader","Component","lazy","Suspense","deskRoot","m","deskList","deskEditEntity","assetManagerRoot","knowledgeRoot","knowledgeList","knowledgeSource","graphRoot","explorerRoot","aiRoot","aiPluginsPage","aiInstalledPluginsPage","aiPluginDetailPage","aiAgentChatPage","aiAutomationsPage","aiRunHistoryPage","aiApprovalsPage","aiActivityPage","aiActivityItemPage","aiCreateAutomationPage","aiAutomationDetailPage","aiRunsPage","aiRunDetailPage","aiSkillsPage","aiCreateSkillPage","aiSkillDetailPage","builtInApps","BotIcon","LayoutIcon","FileStackIcon","BookOpenTextIcon","WaypointsIcon","SquarePlayIcon","ConfigContext","createContext","NO_TEAMS","upsertReservedEntities","schema","entity","ConfigProvider","projectSummaries","teams","mode","children","currentProjectId","useParams","auth","useAuth","schemaUserId","allSchemas","currentSchema","loadedProjects","useMemo","value","currentProject","useConfig","useContext"],"mappings":"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","file":"chunk-TP6QGIJH.js","sourcesContent":["import type { Entity } from '../core/types';\n\nexport const assetSchema: Entity = {\n name: '_asset',\n plural: '_assets',\n display: 'originalFilename',\n menu: {\n hidden: true,\n },\n attributes: [\n {\n name: 'path',\n label: 'Asset',\n scope: 'global',\n options: {\n size: 140,\n },\n dataType: 'string',\n inputType: 'text',\n previewType: 'assetPreviewField',\n defaultValue: '',\n },\n {\n name: 'originalFilename',\n label: 'Filename',\n scope: 'global',\n options: {\n size: 320,\n },\n dataType: 'string',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'size',\n label: 'Size',\n scope: 'global',\n options: {\n size: 120,\n },\n dataType: 'int',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'width',\n label: 'Width',\n scope: 'global',\n options: {\n size: 90,\n },\n dataType: 'int',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'height',\n label: 'Height',\n scope: 'global',\n options: {\n size: 100,\n },\n dataType: 'int',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'mimeType',\n label: 'Mime Type',\n scope: 'global',\n options: {\n size: 160,\n },\n dataType: 'string',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'lqip',\n label: 'lqip',\n scope: 'global',\n hidden: true,\n dataType: 'string',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: 'url',\n label: 'URL',\n scope: 'global',\n hidden: true,\n readOnly: true,\n dataType: 'string',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: '_updatedAt',\n label: 'Updated At',\n scope: 'global',\n options: {\n size: 220,\n },\n readOnly: true,\n hidden: true,\n dataType: 'datetime',\n inputType: 'datetime',\n previewType: 'datetime',\n defaultValue: '',\n },\n {\n name: 'tags',\n label: 'Tags',\n scope: 'relationship',\n dataType: 'string',\n inputType: 'relationship',\n defaultValue: '',\n previewType: 'tags',\n options: {\n size: 300,\n },\n relationship: {\n mode: 'multiple',\n field: 'name',\n entity: '_tag',\n },\n },\n ],\n};\n","import type { Entity } from '../core/types';\n\nexport const tagSchema: Entity = {\n name: '_tag',\n plural: '_tags',\n display: 'name',\n menu: {\n hidden: true,\n },\n attributes: [\n {\n name: 'name',\n label: 'Tag Name',\n scope: 'global',\n options: {\n size: 220,\n },\n dataType: 'string',\n inputType: 'text',\n previewType: 'text',\n defaultValue: '',\n },\n {\n name: '_updatedAt',\n label: 'Updated At',\n scope: 'global',\n options: {\n size: 220,\n },\n readOnly: true,\n hidden: true,\n dataType: 'datetime',\n inputType: 'datetime',\n previewType: 'datetime',\n defaultValue: '',\n },\n {\n name: 'assets',\n label: 'Assets',\n scope: 'relationship',\n dataType: 'string',\n inputType: 'relationship',\n defaultValue: '',\n relationship: {\n mode: 'multiple',\n field: 'originalFilename',\n entity: '_asset',\n },\n },\n ],\n};\n","'use client';\n\nimport useSWR, { mutate } from 'swr';\nimport { apiPaths } from '../api-paths';\nimport type { ProjectSchemaError, ProjectUiConfig } from './types';\n\nexport type ProjectSchemasState = {\n projects: ProjectUiConfig[];\n errors: { [projectId: string]: ProjectSchemaError };\n isLoading: boolean;\n};\n\nexport type FetchOutcome =\n | { ok: true; project: ProjectUiConfig }\n | { ok: false; projectId: string; error: ProjectSchemaError };\n\nasync function fetchProjectSchema(projectId: string): Promise<FetchOutcome> {\n try {\n const response = await fetch(apiPaths(projectId).schema, {\n credentials: 'include',\n mode: 'cors',\n // Revalidate with the server on every fetch (304 when unchanged), so a\n // refetch after a deploy never reads a stale HTTP-cached schema.\n cache: 'no-cache',\n });\n\n if (!response.ok) {\n let message = response.statusText || `Request failed with status ${String(response.status)}`;\n\n try {\n const body = (await response.json()) as { error?: string; message?: string };\n message = body.error ?? body.message ?? message;\n } catch {\n // keep the status text\n }\n\n return { ok: false, projectId, error: { status: response.status, message } };\n }\n\n const project = (await response.json()) as ProjectUiConfig;\n\n return { ok: true, project: { ...project, projectId: project.projectId || projectId } };\n } catch (error) {\n return {\n ok: false,\n projectId,\n error: { status: 0, message: error instanceof Error ? error.message : 'Network error' },\n };\n }\n}\n\nexport function toProjectSchemasState(outcomes: FetchOutcome[] | undefined, isLoading: boolean): ProjectSchemasState {\n const projects: ProjectUiConfig[] = [];\n const errors: { [projectId: string]: ProjectSchemaError } = {};\n\n for (const outcome of outcomes ?? []) {\n if (outcome.ok) {\n projects.push(outcome.project);\n } else {\n errors[outcome.projectId] = outcome.error;\n }\n }\n\n return { projects, errors, isLoading };\n}\n\n/**\n * Schemas change on deploy, which can happen outside this tab (the agent, the\n * CLI). Refetch when the user comes back to the tab, at most every 15s;\n * SWR compares the result, so an unchanged schema does not re-render.\n */\nconst SCHEMA_SWR_OPTIONS = {\n revalidateOnFocus: true,\n focusThrottleInterval: 15_000,\n revalidateOnReconnect: false,\n} as const;\n\n/**\n * A refetch (tab focus, reload button, watched deploy) must never replace a\n * schema that already loaded with an error: that would swap the whole app for\n * an error screen and drop an open edit drawer. Offline, an expired session or\n * revoked access still surface through the GraphQL requests themselves.\n */\nexport function keepLoadedSchema(previous: FetchOutcome | undefined, next: FetchOutcome): FetchOutcome {\n return !next.ok && previous?.ok ? previous : next;\n}\n\n/**\n * Loads the deployed schema of every project the Studio can open. Fetching\n * starts once the user is known (the endpoint needs a session). The result is\n * refetched on tab focus, on the list's reload button and after a deploy the\n * Studio watched.\n */\nexport function useProjectSchemas(projectIds: string[], userId: string | undefined): ProjectSchemasState {\n const key = userId && projectIds.length > 0 ? ['project-schemas', userId, ...projectIds] : null;\n const { data, isLoading } = useSWR(\n key,\n async (): Promise<FetchOutcome[]> => {\n const outcomes = await Promise.all(projectIds.map((projectId) => fetchProjectSchema(projectId)));\n\n // The key fixes the order of projectIds, so outcomes line up with the previous data.\n return outcomes.map((outcome, index) => keepLoadedSchema(data?.[index], outcome));\n },\n SCHEMA_SWR_OPTIONS\n );\n\n return toProjectSchemasState(data, Boolean(key) && (isLoading || data === undefined));\n}\n\n/** State of a single project's schema, in the same shape as the multi-project hook. */\nexport function toProjectSchemaState(outcome: FetchOutcome | undefined, isLoading: boolean): ProjectSchemasState {\n return toProjectSchemasState(outcome ? [outcome] : undefined, isLoading);\n}\n\n/**\n * Hosted mode: loads only the project currently open. Each project has its own\n * SWR key, so switching back to a project reuses the schema already fetched.\n */\nexport function useProjectSchema(projectId: string | undefined, userId: string | undefined): ProjectSchemasState {\n const key = userId && projectId ? ['project-schema', userId, projectId] : null;\n const { data, isLoading } = useSWR(\n key,\n async (): Promise<FetchOutcome> => keepLoadedSchema(data, await fetchProjectSchema(projectId ?? '')),\n SCHEMA_SWR_OPTIONS\n );\n\n return toProjectSchemaState(data, Boolean(key) && (isLoading || data === undefined));\n}\n\n/** True for the SWR keys that hold `projectId`'s schema (single- and multi-project hooks). */\nexport function isProjectSchemaKey(key: unknown, projectId: string): boolean {\n return (\n Array.isArray(key) &&\n (key[0] === 'project-schema' || key[0] === 'project-schemas') &&\n key.slice(2).includes(projectId)\n );\n}\n\n/** Refetches the deployed schema of `projectId`, e.g. after the agent deployed a schema change. */\nexport function revalidateProjectSchema(projectId: string): Promise<unknown> {\n return mutate((key) => isProjectSchemaKey(key, projectId));\n}\n","import type { JSX } from 'react';\nimport { useTheme } from '../theme-context';\n\nexport function Loading(): JSX.Element {\n const { resolvedTheme } = useTheme();\n\n return (\n <div className=\"fk:flex fk:w-full fk:h-full fk:justify-center fk:items-center fk:bg-background\">\n <div className=\"fk:flex fk:flex-col fk:items-center\">\n {resolvedTheme === 'dark' ? (\n <svg\n className=\"fk:h-8 fk:w-8 fk:animate-bounce\"\n fill=\"none\"\n viewBox=\"0 0 48 48\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M7 8H41V40H7V8Z\" fill=\"#020817\" />\n <path\n d=\"M24 0C42 0 48 6 48 24C48 42 42 48 24 48C6 48 0 42 0 24C0 6 6 0 24 0ZM17.7494 9.52381H8.7619L19.2833 23.8313L8.7619 38.7078H17.7494L21.0499 33.6639V14.2549L17.7494 9.52381ZM38.9577 9.52381H29.9542L26.2857 14.8229V33.0406L29.9542 38.7078H38.9577L28.3908 23.8313L38.9577 9.52381Z\"\n fill=\"white\"\n />\n </svg>\n ) : (\n <svg\n className=\"fk:h-8 fk:w-8 fk:animate-bounce\"\n fill=\"none\"\n viewBox=\"0 0 48 48\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M7 8H41V40H7V8Z\" fill=\"white\" />\n <path\n d=\"M24 0C42 0 48 6 48 24C48 42 42 48 24 48C6 48 0 42 0 24C0 6 6 0 24 0ZM17.7494 9.52381H8.7619L19.2833 23.8313L8.7619 38.7078H17.7494L21.0499 33.6639V14.2549L17.7494 9.52381ZM38.9577 9.52381H29.9542L26.2857 14.8229V33.0406L29.9542 38.7078H38.9577L28.3908 23.8313L38.9577 9.52381Z\"\n fill=\"#020817\"\n />\n </svg>\n )}\n <div className=\"fk:text-foreground fk:text-center fk:mt-4 fk:animate-pulse\">Loading...</div>\n </div>\n </div>\n );\n}\n","import { lazy, Suspense } from 'react';\nimport type { ComponentType, JSX } from 'react';\nimport {\n BookOpenText as BookOpenTextIcon,\n Bot as BotIcon,\n FileStack as FileStackIcon,\n Layout as LayoutIcon,\n SquarePlay as SquarePlayIcon,\n Waypoints as WaypointsIcon,\n} from 'lucide-react';\nimport { Navigate } from 'react-router-dom';\nimport { Loading } from '../../ui/components/loading';\nimport type { AppOptions } from '../config/types';\n\nconst NavigateCompat = Navigate as unknown as ComponentType<{\n replace?: boolean;\n to: string;\n}>;\n\n/**\n * Wraps a lazily imported component in Suspense so each built-in app (and each of its routes)\n * is only downloaded when it is first rendered.\n */\nfunction lazyElement(loader: () => Promise<{ default: ComponentType }>): JSX.Element {\n const Component = lazy(loader);\n\n return (\n <Suspense fallback={<Loading />}>\n <Component />\n </Suspense>\n );\n}\n\n// Desk\nconst deskRoot = lazyElement(() => import('../../apps/desk/root').then((m) => ({ default: m.Root })));\nconst deskList = lazyElement(() => import('../../apps/desk/list').then((m) => ({ default: m.List })));\nconst deskEditEntity = lazyElement(() =>\n import('../../apps/desk/edit-entity').then((m) => ({ default: m.EditEntity }))\n);\n\n// Asset Manager\nconst assetManagerRoot = lazyElement(() => import('../../apps/asset-manager/root').then((m) => ({ default: m.Root })));\n\n// Knowledge\nconst knowledgeRoot = lazyElement(() => import('../../apps/knowledge/root').then((m) => ({ default: m.Root })));\nconst knowledgeList = lazyElement(() => import('../../apps/knowledge/list').then((m) => ({ default: m.List })));\nconst knowledgeSource = lazyElement(() => import('../../apps/knowledge/source').then((m) => ({ default: m.Source })));\n\n// Graph\nconst graphRoot = lazyElement(() => import('../../apps/graph/root').then((m) => ({ default: m.Root })));\n\n// Explorer\nconst explorerRoot = lazyElement(() => import('../../apps/explorer/root').then((m) => ({ default: m.Root })));\n\n// AI\nconst aiRoot = lazyElement(() => import('../../apps/ai/root').then((m) => ({ default: m.Root })));\nconst aiPluginsPage = lazyElement(() => import('../../apps/ai/plugin-pages').then((m) => ({ default: m.PluginsPage })));\nconst aiInstalledPluginsPage = lazyElement(() =>\n import('../../apps/ai/plugin-pages').then((m) => ({ default: m.InstalledPluginsPage }))\n);\nconst aiPluginDetailPage = lazyElement(() =>\n import('../../apps/ai/plugin-pages').then((m) => ({ default: m.PluginDetailPage }))\n);\nconst aiAgentChatPage = lazyElement(() =>\n import('../../apps/ai/agent/chat-page').then((m) => ({ default: m.AgentChatPage }))\n);\nconst aiAutomationsPage = lazyElement(() =>\n import('../../apps/ai/pages').then((m) => ({ default: m.AutomationsPage }))\n);\nconst aiRunHistoryPage = lazyElement(() => import('../../apps/ai/pages').then((m) => ({ default: m.RunHistoryPage })));\nconst aiApprovalsPage = lazyElement(() => import('../../apps/ai/pages').then((m) => ({ default: m.ApprovalsPage })));\nconst aiActivityPage = lazyElement(() => import('../../apps/ai/pages').then((m) => ({ default: m.ActivityPage })));\nconst aiActivityItemPage = lazyElement(() =>\n import('../../apps/ai/pages').then((m) => ({ default: m.ActivityItemPage }))\n);\nconst aiCreateAutomationPage = lazyElement(() =>\n import('../../apps/ai/pages').then((m) => ({ default: m.CreateAutomationPage }))\n);\nconst aiAutomationDetailPage = lazyElement(() =>\n import('../../apps/ai/pages').then((m) => ({ default: m.AutomationDetailPage }))\n);\nconst aiRunsPage = lazyElement(() => import('../../apps/ai/pages').then((m) => ({ default: m.RunsPage })));\nconst aiRunDetailPage = lazyElement(() => import('../../apps/ai/pages').then((m) => ({ default: m.RunDetailPage })));\nconst aiSkillsPage = lazyElement(() => import('../../apps/ai/skills-pages').then((m) => ({ default: m.SkillsPage })));\nconst aiCreateSkillPage = lazyElement(() =>\n import('../../apps/ai/skills-pages').then((m) => ({ default: m.CreateSkillPage }))\n);\nconst aiSkillDetailPage = lazyElement(() =>\n import('../../apps/ai/skills-pages').then((m) => ({ default: m.SkillDetailPage }))\n);\n\nexport const builtInApps: AppOptions[] = [\n {\n name: 'ai',\n icon: <BotIcon strokeWidth={1.5} />,\n title: 'AI',\n component: aiRoot,\n routes: [\n { path: 'plugins', component: aiPluginsPage },\n { path: 'plugins/installed', component: aiInstalledPluginsPage },\n { path: 'plugins/:pluginId', component: aiPluginDetailPage },\n {\n component: <NavigateCompat replace to=\"agent\" />,\n path: '',\n },\n {\n component: aiAgentChatPage,\n path: 'agent',\n },\n {\n component: aiAgentChatPage,\n path: 'agent/chats/:chatId',\n },\n {\n component: aiAutomationsPage,\n path: 'automations',\n },\n {\n component: aiRunHistoryPage,\n path: 'runs',\n },\n {\n component: aiApprovalsPage,\n path: 'approvals',\n },\n {\n component: aiActivityPage,\n path: 'activity',\n },\n {\n component: aiActivityItemPage,\n path: 'activity/:itemId',\n },\n {\n component: aiCreateAutomationPage,\n path: 'automations/new',\n },\n {\n component: aiAutomationDetailPage,\n path: 'automations/:automationId',\n },\n {\n component: aiRunsPage,\n path: 'automations/:automationId/runs',\n },\n {\n component: aiRunDetailPage,\n path: 'automations/:automationId/runs/:runId',\n },\n {\n component: aiSkillsPage,\n path: 'skills',\n },\n {\n component: aiCreateSkillPage,\n path: 'skills/new',\n },\n {\n component: aiSkillDetailPage,\n path: 'skills/:skillId',\n },\n ],\n },\n {\n name: 'desk',\n icon: <LayoutIcon strokeWidth={1.5} />,\n title: 'Desk',\n component: deskRoot,\n routes: [\n {\n path: 'list/:entity',\n component: deskList,\n children: [\n {\n path: 'edit/:id',\n component: deskEditEntity, // Not used, left here as an example of how to nest routes in apps\n },\n ],\n },\n ],\n },\n {\n name: 'asset-manager',\n icon: <FileStackIcon strokeWidth={1.5} />,\n title: 'Asset Manager',\n component: assetManagerRoot,\n routes: [],\n },\n {\n name: 'knowledge',\n icon: <BookOpenTextIcon strokeWidth={1.5} />,\n title: 'Knowledge',\n component: knowledgeRoot,\n routes: [\n {\n component: knowledgeList,\n path: '',\n },\n {\n component: knowledgeSource,\n path: ':sourceId',\n },\n ],\n },\n {\n name: 'graph',\n icon: <WaypointsIcon strokeWidth={1.5} />,\n title: 'Graph',\n component: graphRoot,\n routes: [],\n },\n {\n name: 'explorer',\n icon: <SquarePlayIcon strokeWidth={1.5} />,\n title: 'Explorer',\n component: explorerRoot,\n routes: [],\n },\n];\n","'use client';\n\nimport { createContext, useContext, useMemo } from 'react';\nimport type { JSX } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useAuth } from '../../auth/auth-context';\nimport { assetSchema } from '../../entities/assets-schema';\nimport { tagSchema } from '../../entities/tags-schema';\nimport { builtInApps } from '../apps/built-in-apps';\nimport type { AppOptions, HostedTeam, ProjectSchemaError, ProjectSummary, ProjectUiConfig, StudioMode } from './types';\nimport type { Entity } from '../types';\nimport { useProjectSchema, useProjectSchemas } from './use-project-schemas';\n\nexport interface ConfigContext {\n /** `projects` when the host passed `projectIds`, `hosted` when the Studio listed the user's projects itself. */\n mode: StudioMode;\n /** The Studio apps shown in the app bar, in order. */\n apps: AppOptions[];\n /** Kept for callers that read `contributions.apps`; same list as `apps`. */\n contributions: {\n apps: AppOptions[];\n };\n currentProjectId?: string;\n /** The project named by the `:projectId` route param, once its schema has loaded. */\n currentProject?: ProjectUiConfig;\n currentProjectSchema: Entity[];\n /** Projects whose schema loaded, in `projectIds` order. */\n projects: ProjectUiConfig[];\n /** Every project id the Studio can open, loaded or not. */\n projectIds: string[];\n /** Hosted mode: name, avatar, role and team of each project, known before any schema loads. */\n projectSummaries: ProjectSummary[];\n /** Hosted mode: the user's teams with their role; owners can create projects in them. */\n teams: HostedTeam[];\n /** Per project id: why its schema could not be loaded. */\n schemaErrors: { [projectId: string]: ProjectSchemaError };\n isLoadingSchemas: boolean;\n}\n\nconst ConfigContext = createContext<ConfigContext>({\n mode: 'projects',\n apps: builtInApps,\n contributions: { apps: builtInApps },\n currentProjectId: undefined,\n currentProject: undefined,\n currentProjectSchema: [],\n projects: [],\n projectIds: [],\n projectSummaries: [],\n teams: [],\n schemaErrors: {},\n isLoadingSchemas: false,\n});\n\nconst NO_TEAMS: HostedTeam[] = [];\n\n/** Appends the reserved asset and tag entities to a deployed schema. */\nexport function upsertReservedEntities(schema: Entity[]): Entity[] {\n const withoutReserved = schema.filter((entity) => entity.name !== assetSchema.name && entity.name !== tagSchema.name);\n\n return [...withoutReserved, assetSchema, tagSchema];\n}\n\nexport function ConfigProvider({\n projectIds,\n projectSummaries = [],\n teams = NO_TEAMS,\n mode = 'projects',\n userId,\n children,\n}: {\n projectIds: string[];\n projectSummaries?: ProjectSummary[];\n teams?: HostedTeam[];\n mode?: StudioMode;\n /** Hosted mode: the signed-in user's id, known before the per-project `/users/me` call. */\n userId?: string;\n children: React.ReactNode;\n}): JSX.Element {\n /**\n * Getting the projectId from the URL via react-router-dom's useParams hook triggers a rerender of this Context\n * every time the URL changes.\n */\n const { projectId: currentProjectId } = useParams<{ projectId: string }>();\n const [, auth] = useAuth();\n const schemaUserId = auth.user?.id ?? userId;\n // Project mode loads every project up front (short, host-defined list); hosted mode only the one open.\n const allSchemas = useProjectSchemas(mode === 'projects' ? projectIds : [], schemaUserId);\n const currentSchema = useProjectSchema(\n mode === 'hosted' && currentProjectId && projectIds.includes(currentProjectId) ? currentProjectId : undefined,\n schemaUserId\n );\n const { projects: loadedProjects, errors, isLoading } = mode === 'hosted' ? currentSchema : allSchemas;\n const projects = useMemo(\n () =>\n projectIds\n .map((projectId) => loadedProjects.find((project) => project.projectId === projectId))\n .filter((project): project is ProjectUiConfig => project !== undefined)\n .map((project) => ({ ...project, schema: upsertReservedEntities(project.schema) })),\n [loadedProjects, projectIds]\n );\n\n const value = useMemo<ConfigContext>(() => {\n const currentProject = projects.find((project) => project.projectId === currentProjectId);\n\n return {\n mode,\n apps: builtInApps,\n contributions: { apps: builtInApps },\n currentProjectId,\n currentProject,\n currentProjectSchema: currentProject?.schema ?? [],\n projects,\n projectIds,\n projectSummaries,\n teams,\n schemaErrors: errors,\n isLoadingSchemas: isLoading,\n };\n }, [currentProjectId, errors, isLoading, mode, projectIds, projectSummaries, projects, teams]);\n\n return <ConfigContext.Provider value={value}>{children}</ConfigContext.Provider>;\n}\n\nexport function useConfig(): ConfigContext {\n return useContext(ConfigContext);\n}\n"]}
|