@samanhappy/mcphub 1.0.32 → 1.0.34
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.fr.md +12 -6
- package/README.md +23 -7
- package/README.zh.md +24 -8
- package/dist/clients/openapi.js +439 -72
- package/dist/clients/openapi.js.map +1 -1
- package/dist/config/index.js +24 -2
- package/dist/config/index.js.map +1 -1
- package/dist/constants/oauthServerDefaults.js +5 -0
- package/dist/constants/oauthServerDefaults.js.map +1 -1
- package/dist/controllers/activityController.js +11 -0
- package/dist/controllers/activityController.js.map +1 -1
- package/dist/controllers/logController.js +10 -3
- package/dist/controllers/logController.js.map +1 -1
- package/dist/controllers/mcpbController.js +6 -13
- package/dist/controllers/mcpbController.js.map +1 -1
- package/dist/controllers/oauthCallbackController.js +26 -0
- package/dist/controllers/oauthCallbackController.js.map +1 -1
- package/dist/controllers/oauthServerController.js +40 -4
- package/dist/controllers/oauthServerController.js.map +1 -1
- package/dist/controllers/serverController.js +122 -31
- package/dist/controllers/serverController.js.map +1 -1
- package/dist/controllers/templateController.js +1 -1
- package/dist/controllers/templateController.js.map +1 -1
- package/dist/routes/index.js +2 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/services/authorizationService.js +28 -0
- package/dist/services/authorizationService.js.map +1 -0
- package/dist/services/cimdClientService.js +195 -0
- package/dist/services/cimdClientService.js.map +1 -0
- package/dist/services/mcpOAuthProvider.js +2 -2
- package/dist/services/mcpOAuthProvider.js.map +1 -1
- package/dist/services/mcpService.js +108 -11
- package/dist/services/mcpService.js.map +1 -1
- package/dist/services/oauthClientRegistration.js +27 -9
- package/dist/services/oauthClientRegistration.js.map +1 -1
- package/dist/services/oauthServerService.js +17 -1
- package/dist/services/oauthServerService.js.map +1 -1
- package/dist/services/openApiToolStatsService.js +37 -0
- package/dist/services/openApiToolStatsService.js.map +1 -0
- package/dist/services/serverConfigPresenter.js +85 -0
- package/dist/services/serverConfigPresenter.js.map +1 -0
- package/dist/services/templateService.js +48 -11
- package/dist/services/templateService.js.map +1 -1
- package/dist/services/vectorSearchService.js +31 -6
- package/dist/services/vectorSearchService.js.map +1 -1
- package/dist/utils/oauthIssuer.js +57 -0
- package/dist/utils/oauthIssuer.js.map +1 -0
- package/dist/utils/openApiRequestBody.js +220 -0
- package/dist/utils/openApiRequestBody.js.map +1 -0
- package/dist/utils/processTree.js +47 -0
- package/dist/utils/processTree.js.map +1 -0
- package/dist/utils/serverConfigPersistence.js +3 -0
- package/dist/utils/serverConfigPersistence.js.map +1 -1
- package/dist/utils/serverConfigValidation.js +13 -0
- package/dist/utils/serverConfigValidation.js.map +1 -0
- package/dist/utils/serverNameValidation.js +56 -0
- package/dist/utils/serverNameValidation.js.map +1 -0
- package/dist/utils/smartRouting.js +9 -4
- package/dist/utils/smartRouting.js.map +1 -1
- package/dist/utils/ssrf.js +6 -5
- package/dist/utils/ssrf.js.map +1 -1
- package/dist/utils/systemConfigCache.js +40 -2
- package/dist/utils/systemConfigCache.js.map +1 -1
- package/frontend/dist/assets/{ActivityPage-C6m1hGLq.js → ActivityPage-BYoyi-IG.js} +2 -2
- package/frontend/dist/assets/{ActivityPage-C6m1hGLq.js.map → ActivityPage-BYoyi-IG.js.map} +1 -1
- package/frontend/dist/assets/ConfirmDialog-3APts2Y9.js +2 -0
- package/frontend/dist/assets/ConfirmDialog-3APts2Y9.js.map +1 -0
- package/frontend/dist/assets/Dashboard-BOHkLPxE.js +2 -0
- package/frontend/dist/assets/{Dashboard-DFKfjPff.js.map → Dashboard-BOHkLPxE.js.map} +1 -1
- package/frontend/dist/assets/{EndpointCopy-CP_Fb1To.js → EndpointCopy-DDVLhiUy.js} +2 -2
- package/frontend/dist/assets/{EndpointCopy-CP_Fb1To.js.map → EndpointCopy-DDVLhiUy.js.map} +1 -1
- package/frontend/dist/assets/GroupsPage-B3bHSWmT.js +33 -0
- package/frontend/dist/assets/{GroupsPage-Cwfm5q-a.js.map → GroupsPage-B3bHSWmT.js.map} +1 -1
- package/frontend/dist/assets/{LoginPage-CnF44h_n.js → LoginPage-CfAnFIbQ.js} +2 -2
- package/frontend/dist/assets/{LoginPage-CnF44h_n.js.map → LoginPage-CfAnFIbQ.js.map} +1 -1
- package/frontend/dist/assets/{LogsPage-BFIpICsM.js → LogsPage-DT2VotXH.js} +2 -2
- package/frontend/dist/assets/{LogsPage-BFIpICsM.js.map → LogsPage-DT2VotXH.js.map} +1 -1
- package/frontend/dist/assets/MarketPage-Cn0J7UNX.js +3 -0
- package/frontend/dist/assets/MarketPage-Cn0J7UNX.js.map +1 -0
- package/frontend/dist/assets/{OAuthConsentPage-zqXUvKMF.js → OAuthConsentPage-DnKLaKDH.js} +2 -2
- package/frontend/dist/assets/{OAuthConsentPage-zqXUvKMF.js.map → OAuthConsentPage-DnKLaKDH.js.map} +1 -1
- package/frontend/dist/assets/{PromptsPage-Cm8ykiI4.js → PromptsPage-Ccg3fJWt.js} +2 -2
- package/frontend/dist/assets/{PromptsPage-Cm8ykiI4.js.map → PromptsPage-Ccg3fJWt.js.map} +1 -1
- package/frontend/dist/assets/{ResourcesPage-UMyO6mQ4.js → ResourcesPage-V45CxfvA.js} +2 -2
- package/frontend/dist/assets/{ResourcesPage-UMyO6mQ4.js.map → ResourcesPage-V45CxfvA.js.map} +1 -1
- package/frontend/dist/assets/{ServersPage-B0RoM8ez.js → ServersPage-DA_nkhLB.js} +5 -5
- package/frontend/dist/assets/{ServersPage-B0RoM8ez.js.map → ServersPage-DA_nkhLB.js.map} +1 -1
- package/frontend/dist/assets/SettingsPage-BJjO5cte.js +12 -0
- package/frontend/dist/assets/SettingsPage-BJjO5cte.js.map +1 -0
- package/frontend/dist/assets/{StatusDot-BAMXeT2x.js → StatusDot-DcjrhMNI.js} +2 -2
- package/frontend/dist/assets/{StatusDot-BAMXeT2x.js.map → StatusDot-DcjrhMNI.js.map} +1 -1
- package/frontend/dist/assets/{ToggleGroup-Cfgt5lJo.js → ToggleGroup-BSLtGF--.js} +2 -2
- package/frontend/dist/assets/{ToggleGroup-Cfgt5lJo.js.map → ToggleGroup-BSLtGF--.js.map} +1 -1
- package/frontend/dist/assets/UsersPage-DKdCe4GT.js +2 -0
- package/frontend/dist/assets/UsersPage-DKdCe4GT.js.map +1 -0
- package/frontend/dist/assets/contextCost-CilWqGWT.js +2 -0
- package/frontend/dist/assets/contextCost-CilWqGWT.js.map +1 -0
- package/frontend/dist/assets/index-DjExFs33.js +3 -0
- package/frontend/dist/assets/index-DjExFs33.js.map +1 -0
- package/frontend/dist/assets/index-DtrCVU1h.css +1 -0
- package/frontend/dist/assets/passwordValidation-DTLWgUy9.js +2 -0
- package/frontend/dist/assets/passwordValidation-DTLWgUy9.js.map +1 -0
- package/frontend/dist/assets/{resourceService-D2QmlFby.js → resourceService-DIUK5vbC.js} +2 -2
- package/frontend/dist/assets/{resourceService-D2QmlFby.js.map → resourceService-DIUK5vbC.js.map} +1 -1
- package/frontend/dist/assets/useCostData-CSeCIQmM.js +2 -0
- package/frontend/dist/assets/useCostData-CSeCIQmM.js.map +1 -0
- package/frontend/dist/assets/useSettingsData-CvAOhPaX.js +2 -0
- package/frontend/dist/assets/{useSettingsData-CeCvZ2nU.js.map → useSettingsData-CvAOhPaX.js.map} +1 -1
- package/frontend/dist/assets/variableDetection-BeF9gp9K.js +16 -0
- package/frontend/dist/assets/variableDetection-BeF9gp9K.js.map +1 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +7 -7
- package/frontend/dist/assets/ConfirmDialog-BCMNzi21.js +0 -2
- package/frontend/dist/assets/ConfirmDialog-BCMNzi21.js.map +0 -1
- package/frontend/dist/assets/Dashboard-DFKfjPff.js +0 -2
- package/frontend/dist/assets/GroupsPage-Cwfm5q-a.js +0 -33
- package/frontend/dist/assets/MarketPage-Du-NqiEl.js +0 -3
- package/frontend/dist/assets/MarketPage-Du-NqiEl.js.map +0 -1
- package/frontend/dist/assets/SettingsPage-BTB-36-n.js +0 -12
- package/frontend/dist/assets/SettingsPage-BTB-36-n.js.map +0 -1
- package/frontend/dist/assets/UsersPage-DlzYf7Su.js +0 -2
- package/frontend/dist/assets/UsersPage-DlzYf7Su.js.map +0 -1
- package/frontend/dist/assets/contextCost-kp2vZYp7.js +0 -2
- package/frontend/dist/assets/contextCost-kp2vZYp7.js.map +0 -1
- package/frontend/dist/assets/index-CGvImZ3F.css +0 -1
- package/frontend/dist/assets/index-CvXw771N.js +0 -3
- package/frontend/dist/assets/index-CvXw771N.js.map +0 -1
- package/frontend/dist/assets/useSettingsData-CeCvZ2nU.js +0 -2
- package/frontend/dist/assets/variableDetection-DKPiHkxr.js +0 -16
- package/frontend/dist/assets/variableDetection-DKPiHkxr.js.map +0 -1
package/frontend/dist/assets/{ResourcesPage-UMyO6mQ4.js.map → ResourcesPage-V45CxfvA.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResourcesPage-UMyO6mQ4.js","sources":["../../src/services/builtinResourceService.ts","../../src/hooks/useBuiltinResourceData.ts","../../src/pages/ResourcesPage.tsx"],"sourcesContent":["import { BuiltinResource, ApiResponse } from '@/types';\nimport { apiGet, apiPost, apiPut, apiDelete } from '../utils/fetchInterceptor';\n\n/**\n * Get all built-in resources\n */\nexport const getBuiltinResources = async (): Promise<BuiltinResource[]> => {\n const response: ApiResponse<BuiltinResource[]> = await apiGet('/resources');\n if (!response.success) {\n throw new Error(response.message || 'Failed to fetch built-in resources');\n }\n return response.data || [];\n};\n\n/**\n * Get a single built-in resource by ID\n */\nexport const getBuiltinResourceById = async (id: string): Promise<BuiltinResource> => {\n const response: ApiResponse<BuiltinResource> = await apiGet(`/resources/${id}`);\n if (!response.success) {\n throw new Error(response.message || 'Failed to fetch built-in resource');\n }\n return response.data!;\n};\n\n/**\n * Create a new built-in resource\n */\nexport const createBuiltinResource = async (\n resource: Omit<BuiltinResource, 'id'>,\n): Promise<BuiltinResource> => {\n const response: ApiResponse<BuiltinResource> = await apiPost('/resources', resource);\n if (!response.success) {\n throw new Error(response.message || 'Failed to create built-in resource');\n }\n return response.data!;\n};\n\n/**\n * Update an existing built-in resource\n */\nexport const updateBuiltinResource = async (\n id: string,\n resource: Partial<BuiltinResource>,\n): Promise<BuiltinResource> => {\n const response: ApiResponse<BuiltinResource> = await apiPut(`/resources/${id}`, resource);\n if (!response.success) {\n throw new Error(response.message || 'Failed to update built-in resource');\n }\n return response.data!;\n};\n\n/**\n * Delete a built-in resource\n */\nexport const deleteBuiltinResource = async (id: string): Promise<void> => {\n const response: ApiResponse = await apiDelete(`/resources/${id}`);\n if (!response.success) {\n throw new Error(response.message || 'Failed to delete built-in resource');\n }\n};\n","import { useState, useEffect, useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { BuiltinResource } from '@/types';\nimport {\n getBuiltinResources,\n createBuiltinResource,\n updateBuiltinResource,\n deleteBuiltinResource,\n} from '@/services/builtinResourceService';\n\nexport const useBuiltinResourceData = () => {\n const { t } = useTranslation();\n const [resources, setResources] = useState<BuiltinResource[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [refreshKey, setRefreshKey] = useState(0);\n\n const fetchResources = useCallback(async () => {\n try {\n setLoading(true);\n const data = await getBuiltinResources();\n setResources(data);\n setError(null);\n } catch (err) {\n console.error('Error fetching built-in resources:', err);\n setError(err instanceof Error ? err.message : t('builtinResources.fetchError'));\n setResources([]);\n } finally {\n setLoading(false);\n }\n }, [t]);\n\n const triggerRefresh = useCallback(() => {\n setRefreshKey((prev) => prev + 1);\n }, []);\n\n const addResource = async (resource: Omit<BuiltinResource, 'id'>) => {\n try {\n const result = await createBuiltinResource(resource);\n triggerRefresh();\n return { success: true, data: result };\n } catch (err) {\n const message = err instanceof Error ? err.message : t('builtinResources.createError');\n setError(message);\n return { success: false, message };\n }\n };\n\n const editResource = async (id: string, resource: Partial<BuiltinResource>) => {\n try {\n const result = await updateBuiltinResource(id, resource);\n triggerRefresh();\n return { success: true, data: result };\n } catch (err) {\n const message = err instanceof Error ? err.message : t('builtinResources.updateError');\n setError(message);\n return { success: false, message };\n }\n };\n\n const removeResource = async (id: string) => {\n try {\n await deleteBuiltinResource(id);\n triggerRefresh();\n return { success: true };\n } catch (err) {\n const message = err instanceof Error ? err.message : t('builtinResources.deleteError');\n setError(message);\n return { success: false, message };\n }\n };\n\n useEffect(() => {\n fetchResources();\n }, [fetchResources, refreshKey]);\n\n return {\n resources,\n loading,\n error,\n setError,\n triggerRefresh,\n addResource,\n editResource,\n removeResource,\n };\n};\n","import React, { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { BuiltinResource } from '@/types';\nimport { useBuiltinResourceData } from '@/hooks/useBuiltinResourceData';\nimport { useAuth } from '@/contexts/AuthContext';\nimport { Edit, Trash, Plus, FileText, X, ChevronDown } from 'lucide-react';\nimport ConfirmDialog from '@/components/ui/ConfirmDialog';\nimport { StatusDot } from '@/components/ui/StatusDot';\n\n// Form dialog for creating/editing a built-in resource\ninterface ResourceFormDialogProps {\n resource?: BuiltinResource | null;\n onSave: (data: Omit<BuiltinResource, 'id'>) => Promise<{ success: boolean; message?: string }>;\n onCancel: () => void;\n}\n\nconst ResourceFormDialog: React.FC<ResourceFormDialogProps> = ({ resource, onSave, onCancel }) => {\n const { t } = useTranslation();\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const [uri, setUri] = useState(resource?.uri || '');\n const [name, setName] = useState(resource?.name || '');\n const [description, setDescription] = useState(resource?.description || '');\n const [mimeType, setMimeType] = useState(resource?.mimeType || 'text/plain');\n const [content, setContent] = useState(resource?.content || '');\n const [enabled, setEnabled] = useState(resource?.enabled !== false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n\n if (!uri.trim()) {\n setError(t('builtinResources.uriRequired'));\n return;\n }\n if (!content.trim()) {\n setError(t('builtinResources.contentRequired'));\n return;\n }\n\n setIsSubmitting(true);\n try {\n const result = await onSave({\n uri: uri.trim(),\n name: name.trim() || undefined,\n description: description.trim() || undefined,\n mimeType: mimeType.trim() || 'text/plain',\n content,\n enabled,\n });\n if (!result.success) {\n setError(result.message || t('builtinResources.saveError'));\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : t('builtinResources.saveError'));\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <div className=\"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4\">\n <div className=\"bg-white dark:bg-gray-800 p-8 rounded-xl shadow-2xl max-w-3xl w-full mx-4 border border-gray-100 dark:border-gray-700 max-h-[90vh] overflow-y-auto\">\n <form onSubmit={handleSubmit}>\n <h2 className=\"text-xl font-bold text-gray-900 dark:text-gray-100 mb-6\">\n {resource ? t('builtinResources.edit') : t('builtinResources.addNew')}\n </h2>\n\n {error && (\n <div className=\"bg-red-50 border-l-4 border-red-500 text-red-700 p-4 mb-6 rounded-md\">\n <p className=\"text-sm font-medium\">{error}</p>\n </div>\n )}\n\n <div className=\"space-y-5\">\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {t('builtinResources.uri')} <span className=\"text-red-500\">*</span>\n </label>\n <input\n type=\"text\"\n value={uri}\n onChange={(e) => setUri(e.target.value)}\n placeholder={t('builtinResources.uriPlaceholder')}\n className=\"w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 font-mono text-sm transition-all duration-200\"\n required\n disabled={isSubmitting}\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {t('builtinResources.name')}\n </label>\n <input\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={t('builtinResources.namePlaceholder')}\n className=\"w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 transition-all duration-200\"\n disabled={isSubmitting}\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {t('builtinResources.description')}\n </label>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={t('builtinResources.descriptionPlaceholder')}\n className=\"w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 transition-all duration-200\"\n disabled={isSubmitting}\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {t('builtinResources.mimeType')}\n </label>\n <input\n type=\"text\"\n value={mimeType}\n onChange={(e) => setMimeType(e.target.value)}\n placeholder=\"text/plain\"\n className=\"w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 transition-all duration-200\"\n disabled={isSubmitting}\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {t('builtinResources.content')} <span className=\"text-red-500\">*</span>\n </label>\n <textarea\n value={content}\n onChange={(e) => setContent(e.target.value)}\n placeholder={t('builtinResources.contentPlaceholder')}\n rows={8}\n className=\"w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 font-mono text-sm transition-all duration-200\"\n required\n disabled={isSubmitting}\n />\n </div>\n\n <div className=\"flex items-center pt-2\">\n <input\n type=\"checkbox\"\n id=\"enabled\"\n checked={enabled}\n onChange={(e) => setEnabled(e.target.checked)}\n className=\"h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500\"\n disabled={isSubmitting}\n />\n <label htmlFor=\"enabled\" className=\"ml-2 block text-sm text-gray-700 dark:text-gray-300\">\n {t('builtinResources.enabled')}\n </label>\n </div>\n </div>\n\n <div className=\"flex justify-end space-x-2 mt-6\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"hub-btn\"\n disabled={isSubmitting}\n >\n {t('common.cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={isSubmitting}\n className=\"hub-btn primary\"\n >\n {isSubmitting ? t('common.saving') : t('common.save')}\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n};\n\nconst ResourcesPage: React.FC = () => {\n const { t } = useTranslation();\n const { auth } = useAuth();\n const {\n resources,\n loading,\n error,\n setError,\n addResource,\n editResource,\n removeResource,\n } = useBuiltinResourceData();\n\n const [showForm, setShowForm] = useState(false);\n const [editingResource, setEditingResource] = useState<BuiltinResource | null>(null);\n const [resourceToDelete, setResourceToDelete] = useState<BuiltinResource | null>(null);\n const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set());\n\n const isAdmin = auth.user?.isAdmin;\n\n const toggleExpand = (id: string) => {\n setExpandedIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const handleCreate = async (data: Omit<BuiltinResource, 'id'>) => {\n const result = await addResource(data);\n if (result.success) {\n setShowForm(false);\n }\n return result;\n };\n\n const handleEdit = async (data: Omit<BuiltinResource, 'id'>) => {\n if (!editingResource) return { success: false, message: 'No resource selected' };\n const result = await editResource(editingResource.id, data);\n if (result.success) {\n setEditingResource(null);\n }\n return result;\n };\n\n const handleConfirmDelete = async () => {\n if (resourceToDelete) {\n await removeResource(resourceToDelete.id);\n setResourceToDelete(null);\n }\n };\n\n return (\n <div>\n <div className=\"flex items-end justify-between gap-4 mb-6\">\n <div>\n <h1 className=\"hub-h1\">{t('pages.resources.title')}</h1>\n <p className=\"hub-sub\">\n <span className=\"hub-num\">{resources.length}</span> {t('nav.resources').toLowerCase()}\n </p>\n </div>\n {isAdmin && (\n <button onClick={() => setShowForm(true)} className=\"hub-btn primary\">\n <Plus size={13} /> {t('builtinResources.add')}\n </button>\n )}\n </div>\n\n {error && (\n <div\n className=\"hub-card flex items-center justify-between gap-3 mb-4\"\n style={{\n padding: '10px 14px',\n borderColor: 'oklch(0.85 0.1 25)',\n background: 'oklch(0.97 0.03 25)',\n color: 'oklch(0.4 0.18 25)',\n }}\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <X size={14} className=\"flex-shrink-0\" />\n <span className=\"truncate text-[13px]\">{error}</span>\n </div>\n <button className=\"hub-icon-btn sm\" onClick={() => setError(null)}>\n <X size={13} />\n </button>\n </div>\n )}\n\n {loading ? (\n <div className=\"hub-card p-10 text-center\" style={{ color: 'var(--hub-ink-3)' }}>\n {t('app.loading')}\n </div>\n ) : resources.length === 0 ? (\n <div className=\"hub-card p-10 text-center\" style={{ color: 'var(--hub-ink-3)' }}>\n <div className=\"flex flex-col items-center gap-3\">\n <div\n className=\"grid place-items-center\"\n style={{\n width: 40,\n height: 40,\n borderRadius: 10,\n border: '1px solid var(--hub-line)',\n background: 'var(--hub-bg-2)',\n }}\n >\n <FileText size={18} />\n </div>\n <div className=\"font-medium\" style={{ color: 'var(--hub-ink-2)', fontSize: 13 }}>\n {t('builtinResources.noResources')}\n </div>\n {isAdmin && (\n <button\n onClick={() => setShowForm(true)}\n className=\"hub-btn ghost sm\"\n style={{ color: 'var(--hub-accent)' }}\n >\n {t('builtinResources.addFirst')}\n </button>\n )}\n </div>\n </div>\n ) : (\n <div className=\"hub-card overflow-hidden\">\n {resources.map((resource, idx) => {\n const isExpanded = expandedIds.has(resource.id);\n const enabled = resource.enabled !== false;\n return (\n <div\n key={resource.id}\n style={{ borderTop: idx === 0 ? 0 : '1px solid var(--hub-line-2)' }}\n >\n <div\n className=\"flex items-center justify-between cursor-pointer transition-colors hover:bg-[var(--hub-surface-hover)]\"\n style={{ padding: '12px 16px' }}\n onClick={() => toggleExpand(resource.id)}\n >\n <div className=\"flex items-center gap-2.5 flex-1 min-w-0\">\n <ChevronDown\n size={12}\n style={{\n color: 'var(--hub-ink-3)',\n transform: isExpanded ? 'rotate(0deg)' : 'rotate(-90deg)',\n transition: 'transform 0.15s',\n flexShrink: 0,\n }}\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span\n className=\"font-medium truncate\"\n style={{\n fontSize: 13.5,\n color: enabled ? 'var(--hub-ink)' : 'var(--hub-ink-3)',\n }}\n >\n {resource.name || resource.uri}\n </span>\n {resource.name && (\n <span\n className=\"hub-mono truncate\"\n style={{ fontSize: 11.5, color: 'var(--hub-ink-3)' }}\n >\n {resource.uri}\n </span>\n )}\n <StatusDot\n kind={enabled ? 'ok' : 'muted'}\n label={\n enabled\n ? t('builtinResources.active')\n : t('builtinResources.inactive')\n }\n />\n {resource.mimeType && (\n <span className=\"hub-tag accent\" style={{ fontSize: 10 }}>\n {resource.mimeType}\n </span>\n )}\n </div>\n {resource.description && (\n <div\n className=\"truncate mt-0.5\"\n style={{ fontSize: 12, color: 'var(--hub-ink-3)' }}\n >\n {resource.description}\n </div>\n )}\n </div>\n </div>\n {isAdmin && (\n <div className=\"flex items-center gap-1 ml-3\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n setEditingResource(resource);\n }}\n className=\"hub-icon-btn sm\"\n title={t('builtinResources.edit')}\n >\n <Edit size={13} />\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n setResourceToDelete(resource);\n }}\n className=\"hub-icon-btn sm\"\n title={t('builtinResources.delete')}\n style={{ color: 'var(--hub-err)' }}\n >\n <Trash size={13} />\n </button>\n </div>\n )}\n </div>\n {isExpanded && (\n <div\n style={{\n padding: '12px 16px 14px 38px',\n background: 'var(--hub-bg-2)',\n borderTop: '1px solid var(--hub-line-2)',\n }}\n >\n <div className=\"hub-sect\" style={{ marginBottom: 5 }}>\n {t('builtinResources.content')}\n </div>\n <pre\n className=\"hub-mono\"\n style={{\n fontSize: 12,\n color: 'var(--hub-ink-2)',\n background: 'var(--hub-surface)',\n border: '1px solid var(--hub-line)',\n borderRadius: 7,\n padding: 10,\n overflowX: 'auto',\n overflowY: 'auto',\n whiteSpace: 'pre-wrap',\n maxHeight: 260,\n margin: 0,\n }}\n >\n {resource.content}\n </pre>\n </div>\n )}\n </div>\n );\n })}\n </div>\n )}\n\n {/* Add form dialog */}\n {showForm && (\n <ResourceFormDialog onSave={handleCreate} onCancel={() => setShowForm(false)} />\n )}\n\n {/* Edit form dialog */}\n {editingResource && (\n <ResourceFormDialog\n resource={editingResource}\n onSave={handleEdit}\n onCancel={() => setEditingResource(null)}\n />\n )}\n\n {/* Delete confirmation */}\n <ConfirmDialog\n isOpen={!!resourceToDelete}\n onClose={() => setResourceToDelete(null)}\n onConfirm={handleConfirmDelete}\n title={t('builtinResources.confirmDelete')}\n message={t('builtinResources.deleteWarning', { name: resourceToDelete?.name || resourceToDelete?.uri || '' })}\n variant=\"danger\"\n />\n </div>\n );\n};\n\nexport default ResourcesPage;\n"],"names":["getBuiltinResources","response","apiGet","createBuiltinResource","resource","apiPost","updateBuiltinResource","id","apiPut","deleteBuiltinResource","apiDelete","useBuiltinResourceData","t","useTranslation","resources","setResources","useState","loading","setLoading","error","setError","refreshKey","setRefreshKey","fetchResources","useCallback","data","err","triggerRefresh","prev","addResource","result","message","editResource","removeResource","useEffect","ResourceFormDialog","onSave","onCancel","isSubmitting","setIsSubmitting","uri","setUri","name","setName","description","setDescription","mimeType","setMimeType","content","setContent","enabled","setEnabled","handleSubmit","e","jsx","jsxs","ResourcesPage","auth","useAuth","showForm","setShowForm","editingResource","setEditingResource","resourceToDelete","setResourceToDelete","expandedIds","setExpandedIds","isAdmin","_a","toggleExpand","next","handleCreate","handleEdit","handleConfirmDelete","Plus","X","FileText","idx","isExpanded","ChevronDown","StatusDot","Edit","Trash","ConfirmDialog"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ResourcesPage-V45CxfvA.js","sources":["../../src/services/builtinResourceService.ts","../../src/hooks/useBuiltinResourceData.ts","../../src/pages/ResourcesPage.tsx"],"sourcesContent":["import { BuiltinResource, ApiResponse } from '@/types';\nimport { apiGet, apiPost, apiPut, apiDelete } from '../utils/fetchInterceptor';\n\n/**\n * Get all built-in resources\n */\nexport const getBuiltinResources = async (): Promise<BuiltinResource[]> => {\n const response: ApiResponse<BuiltinResource[]> = await apiGet('/resources');\n if (!response.success) {\n throw new Error(response.message || 'Failed to fetch built-in resources');\n }\n return response.data || [];\n};\n\n/**\n * Get a single built-in resource by ID\n */\nexport const getBuiltinResourceById = async (id: string): Promise<BuiltinResource> => {\n const response: ApiResponse<BuiltinResource> = await apiGet(`/resources/${id}`);\n if (!response.success) {\n throw new Error(response.message || 'Failed to fetch built-in resource');\n }\n return response.data!;\n};\n\n/**\n * Create a new built-in resource\n */\nexport const createBuiltinResource = async (\n resource: Omit<BuiltinResource, 'id'>,\n): Promise<BuiltinResource> => {\n const response: ApiResponse<BuiltinResource> = await apiPost('/resources', resource);\n if (!response.success) {\n throw new Error(response.message || 'Failed to create built-in resource');\n }\n return response.data!;\n};\n\n/**\n * Update an existing built-in resource\n */\nexport const updateBuiltinResource = async (\n id: string,\n resource: Partial<BuiltinResource>,\n): Promise<BuiltinResource> => {\n const response: ApiResponse<BuiltinResource> = await apiPut(`/resources/${id}`, resource);\n if (!response.success) {\n throw new Error(response.message || 'Failed to update built-in resource');\n }\n return response.data!;\n};\n\n/**\n * Delete a built-in resource\n */\nexport const deleteBuiltinResource = async (id: string): Promise<void> => {\n const response: ApiResponse = await apiDelete(`/resources/${id}`);\n if (!response.success) {\n throw new Error(response.message || 'Failed to delete built-in resource');\n }\n};\n","import { useState, useEffect, useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { BuiltinResource } from '@/types';\nimport {\n getBuiltinResources,\n createBuiltinResource,\n updateBuiltinResource,\n deleteBuiltinResource,\n} from '@/services/builtinResourceService';\n\nexport const useBuiltinResourceData = () => {\n const { t } = useTranslation();\n const [resources, setResources] = useState<BuiltinResource[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [refreshKey, setRefreshKey] = useState(0);\n\n const fetchResources = useCallback(async () => {\n try {\n setLoading(true);\n const data = await getBuiltinResources();\n setResources(data);\n setError(null);\n } catch (err) {\n console.error('Error fetching built-in resources:', err);\n setError(err instanceof Error ? err.message : t('builtinResources.fetchError'));\n setResources([]);\n } finally {\n setLoading(false);\n }\n }, [t]);\n\n const triggerRefresh = useCallback(() => {\n setRefreshKey((prev) => prev + 1);\n }, []);\n\n const addResource = async (resource: Omit<BuiltinResource, 'id'>) => {\n try {\n const result = await createBuiltinResource(resource);\n triggerRefresh();\n return { success: true, data: result };\n } catch (err) {\n const message = err instanceof Error ? err.message : t('builtinResources.createError');\n setError(message);\n return { success: false, message };\n }\n };\n\n const editResource = async (id: string, resource: Partial<BuiltinResource>) => {\n try {\n const result = await updateBuiltinResource(id, resource);\n triggerRefresh();\n return { success: true, data: result };\n } catch (err) {\n const message = err instanceof Error ? err.message : t('builtinResources.updateError');\n setError(message);\n return { success: false, message };\n }\n };\n\n const removeResource = async (id: string) => {\n try {\n await deleteBuiltinResource(id);\n triggerRefresh();\n return { success: true };\n } catch (err) {\n const message = err instanceof Error ? err.message : t('builtinResources.deleteError');\n setError(message);\n return { success: false, message };\n }\n };\n\n useEffect(() => {\n fetchResources();\n }, [fetchResources, refreshKey]);\n\n return {\n resources,\n loading,\n error,\n setError,\n triggerRefresh,\n addResource,\n editResource,\n removeResource,\n };\n};\n","import React, { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { BuiltinResource } from '@/types';\nimport { useBuiltinResourceData } from '@/hooks/useBuiltinResourceData';\nimport { useAuth } from '@/contexts/AuthContext';\nimport { Edit, Trash, Plus, FileText, X, ChevronDown } from 'lucide-react';\nimport ConfirmDialog from '@/components/ui/ConfirmDialog';\nimport { StatusDot } from '@/components/ui/StatusDot';\n\n// Form dialog for creating/editing a built-in resource\ninterface ResourceFormDialogProps {\n resource?: BuiltinResource | null;\n onSave: (data: Omit<BuiltinResource, 'id'>) => Promise<{ success: boolean; message?: string }>;\n onCancel: () => void;\n}\n\nconst ResourceFormDialog: React.FC<ResourceFormDialogProps> = ({ resource, onSave, onCancel }) => {\n const { t } = useTranslation();\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const [uri, setUri] = useState(resource?.uri || '');\n const [name, setName] = useState(resource?.name || '');\n const [description, setDescription] = useState(resource?.description || '');\n const [mimeType, setMimeType] = useState(resource?.mimeType || 'text/plain');\n const [content, setContent] = useState(resource?.content || '');\n const [enabled, setEnabled] = useState(resource?.enabled !== false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n\n if (!uri.trim()) {\n setError(t('builtinResources.uriRequired'));\n return;\n }\n if (!content.trim()) {\n setError(t('builtinResources.contentRequired'));\n return;\n }\n\n setIsSubmitting(true);\n try {\n const result = await onSave({\n uri: uri.trim(),\n name: name.trim() || undefined,\n description: description.trim() || undefined,\n mimeType: mimeType.trim() || 'text/plain',\n content,\n enabled,\n });\n if (!result.success) {\n setError(result.message || t('builtinResources.saveError'));\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : t('builtinResources.saveError'));\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <div className=\"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4\">\n <div className=\"bg-white dark:bg-gray-800 p-8 rounded-xl shadow-2xl max-w-3xl w-full mx-4 border border-gray-100 dark:border-gray-700 max-h-[90vh] overflow-y-auto\">\n <form onSubmit={handleSubmit}>\n <h2 className=\"text-xl font-bold text-gray-900 dark:text-gray-100 mb-6\">\n {resource ? t('builtinResources.edit') : t('builtinResources.addNew')}\n </h2>\n\n {error && (\n <div className=\"bg-red-50 border-l-4 border-red-500 text-red-700 p-4 mb-6 rounded-md\">\n <p className=\"text-sm font-medium\">{error}</p>\n </div>\n )}\n\n <div className=\"space-y-5\">\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {t('builtinResources.uri')} <span className=\"text-red-500\">*</span>\n </label>\n <input\n type=\"text\"\n value={uri}\n onChange={(e) => setUri(e.target.value)}\n placeholder={t('builtinResources.uriPlaceholder')}\n className=\"w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 font-mono text-sm transition-all duration-200\"\n required\n disabled={isSubmitting}\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {t('builtinResources.name')}\n </label>\n <input\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={t('builtinResources.namePlaceholder')}\n className=\"w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 transition-all duration-200\"\n disabled={isSubmitting}\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {t('builtinResources.description')}\n </label>\n <input\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={t('builtinResources.descriptionPlaceholder')}\n className=\"w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 transition-all duration-200\"\n disabled={isSubmitting}\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {t('builtinResources.mimeType')}\n </label>\n <input\n type=\"text\"\n value={mimeType}\n onChange={(e) => setMimeType(e.target.value)}\n placeholder=\"text/plain\"\n className=\"w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 transition-all duration-200\"\n disabled={isSubmitting}\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\n {t('builtinResources.content')} <span className=\"text-red-500\">*</span>\n </label>\n <textarea\n value={content}\n onChange={(e) => setContent(e.target.value)}\n placeholder={t('builtinResources.contentPlaceholder')}\n rows={8}\n className=\"w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 font-mono text-sm transition-all duration-200\"\n required\n disabled={isSubmitting}\n />\n </div>\n\n <div className=\"flex items-center pt-2\">\n <input\n type=\"checkbox\"\n id=\"enabled\"\n checked={enabled}\n onChange={(e) => setEnabled(e.target.checked)}\n className=\"h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500\"\n disabled={isSubmitting}\n />\n <label htmlFor=\"enabled\" className=\"ml-2 block text-sm text-gray-700 dark:text-gray-300\">\n {t('builtinResources.enabled')}\n </label>\n </div>\n </div>\n\n <div className=\"flex justify-end space-x-2 mt-6\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"hub-btn\"\n disabled={isSubmitting}\n >\n {t('common.cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={isSubmitting}\n className=\"hub-btn primary\"\n >\n {isSubmitting ? t('common.saving') : t('common.save')}\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n};\n\nconst ResourcesPage: React.FC = () => {\n const { t } = useTranslation();\n const { auth } = useAuth();\n const {\n resources,\n loading,\n error,\n setError,\n addResource,\n editResource,\n removeResource,\n } = useBuiltinResourceData();\n\n const [showForm, setShowForm] = useState(false);\n const [editingResource, setEditingResource] = useState<BuiltinResource | null>(null);\n const [resourceToDelete, setResourceToDelete] = useState<BuiltinResource | null>(null);\n const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set());\n\n const isAdmin = auth.user?.isAdmin;\n\n const toggleExpand = (id: string) => {\n setExpandedIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const handleCreate = async (data: Omit<BuiltinResource, 'id'>) => {\n const result = await addResource(data);\n if (result.success) {\n setShowForm(false);\n }\n return result;\n };\n\n const handleEdit = async (data: Omit<BuiltinResource, 'id'>) => {\n if (!editingResource) return { success: false, message: 'No resource selected' };\n const result = await editResource(editingResource.id, data);\n if (result.success) {\n setEditingResource(null);\n }\n return result;\n };\n\n const handleConfirmDelete = async () => {\n if (resourceToDelete) {\n await removeResource(resourceToDelete.id);\n setResourceToDelete(null);\n }\n };\n\n return (\n <div>\n <div className=\"flex items-end justify-between gap-4 mb-6\">\n <div>\n <h1 className=\"hub-h1\">{t('pages.resources.title')}</h1>\n <p className=\"hub-sub\">\n <span className=\"hub-num\">{resources.length}</span> {t('nav.resources').toLowerCase()}\n </p>\n </div>\n {isAdmin && (\n <button onClick={() => setShowForm(true)} className=\"hub-btn primary\">\n <Plus size={13} /> {t('builtinResources.add')}\n </button>\n )}\n </div>\n\n {error && (\n <div\n className=\"hub-card flex items-center justify-between gap-3 mb-4\"\n style={{\n padding: '10px 14px',\n borderColor: 'oklch(0.85 0.1 25)',\n background: 'oklch(0.97 0.03 25)',\n color: 'oklch(0.4 0.18 25)',\n }}\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <X size={14} className=\"flex-shrink-0\" />\n <span className=\"truncate text-[13px]\">{error}</span>\n </div>\n <button className=\"hub-icon-btn sm\" onClick={() => setError(null)}>\n <X size={13} />\n </button>\n </div>\n )}\n\n {loading ? (\n <div className=\"hub-card p-10 text-center\" style={{ color: 'var(--hub-ink-3)' }}>\n {t('app.loading')}\n </div>\n ) : resources.length === 0 ? (\n <div className=\"hub-card p-10 text-center\" style={{ color: 'var(--hub-ink-3)' }}>\n <div className=\"flex flex-col items-center gap-3\">\n <div\n className=\"grid place-items-center\"\n style={{\n width: 40,\n height: 40,\n borderRadius: 10,\n border: '1px solid var(--hub-line)',\n background: 'var(--hub-bg-2)',\n }}\n >\n <FileText size={18} />\n </div>\n <div className=\"font-medium\" style={{ color: 'var(--hub-ink-2)', fontSize: 13 }}>\n {t('builtinResources.noResources')}\n </div>\n {isAdmin && (\n <button\n onClick={() => setShowForm(true)}\n className=\"hub-btn ghost sm\"\n style={{ color: 'var(--hub-accent)' }}\n >\n {t('builtinResources.addFirst')}\n </button>\n )}\n </div>\n </div>\n ) : (\n <div className=\"hub-card overflow-hidden\">\n {resources.map((resource, idx) => {\n const isExpanded = expandedIds.has(resource.id);\n const enabled = resource.enabled !== false;\n return (\n <div\n key={resource.id}\n style={{ borderTop: idx === 0 ? 0 : '1px solid var(--hub-line-2)' }}\n >\n <div\n className=\"flex items-center justify-between cursor-pointer transition-colors hover:bg-[var(--hub-surface-hover)]\"\n style={{ padding: '12px 16px' }}\n onClick={() => toggleExpand(resource.id)}\n >\n <div className=\"flex items-center gap-2.5 flex-1 min-w-0\">\n <ChevronDown\n size={12}\n style={{\n color: 'var(--hub-ink-3)',\n transform: isExpanded ? 'rotate(0deg)' : 'rotate(-90deg)',\n transition: 'transform 0.15s',\n flexShrink: 0,\n }}\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span\n className=\"font-medium truncate\"\n style={{\n fontSize: 13.5,\n color: enabled ? 'var(--hub-ink)' : 'var(--hub-ink-3)',\n }}\n >\n {resource.name || resource.uri}\n </span>\n {resource.name && (\n <span\n className=\"hub-mono truncate\"\n style={{ fontSize: 11.5, color: 'var(--hub-ink-3)' }}\n >\n {resource.uri}\n </span>\n )}\n <StatusDot\n kind={enabled ? 'ok' : 'muted'}\n label={\n enabled\n ? t('builtinResources.active')\n : t('builtinResources.inactive')\n }\n />\n {resource.mimeType && (\n <span className=\"hub-tag accent\" style={{ fontSize: 10 }}>\n {resource.mimeType}\n </span>\n )}\n </div>\n {resource.description && (\n <div\n className=\"truncate mt-0.5\"\n style={{ fontSize: 12, color: 'var(--hub-ink-3)' }}\n >\n {resource.description}\n </div>\n )}\n </div>\n </div>\n {isAdmin && (\n <div className=\"flex items-center gap-1 ml-3\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n setEditingResource(resource);\n }}\n className=\"hub-icon-btn sm\"\n title={t('builtinResources.edit')}\n >\n <Edit size={13} />\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n setResourceToDelete(resource);\n }}\n className=\"hub-icon-btn sm\"\n title={t('builtinResources.delete')}\n style={{ color: 'var(--hub-err)' }}\n >\n <Trash size={13} />\n </button>\n </div>\n )}\n </div>\n {isExpanded && (\n <div\n style={{\n padding: '12px 16px 14px 38px',\n background: 'var(--hub-bg-2)',\n borderTop: '1px solid var(--hub-line-2)',\n }}\n >\n <div className=\"hub-sect\" style={{ marginBottom: 5 }}>\n {t('builtinResources.content')}\n </div>\n <pre\n className=\"hub-mono\"\n style={{\n fontSize: 12,\n color: 'var(--hub-ink-2)',\n background: 'var(--hub-surface)',\n border: '1px solid var(--hub-line)',\n borderRadius: 7,\n padding: 10,\n overflowX: 'auto',\n overflowY: 'auto',\n whiteSpace: 'pre-wrap',\n maxHeight: 260,\n margin: 0,\n }}\n >\n {resource.content}\n </pre>\n </div>\n )}\n </div>\n );\n })}\n </div>\n )}\n\n {/* Add form dialog */}\n {showForm && (\n <ResourceFormDialog onSave={handleCreate} onCancel={() => setShowForm(false)} />\n )}\n\n {/* Edit form dialog */}\n {editingResource && (\n <ResourceFormDialog\n resource={editingResource}\n onSave={handleEdit}\n onCancel={() => setEditingResource(null)}\n />\n )}\n\n {/* Delete confirmation */}\n <ConfirmDialog\n isOpen={!!resourceToDelete}\n onClose={() => setResourceToDelete(null)}\n onConfirm={handleConfirmDelete}\n title={t('builtinResources.confirmDelete')}\n message={t('builtinResources.deleteWarning', { name: resourceToDelete?.name || resourceToDelete?.uri || '' })}\n variant=\"danger\"\n />\n </div>\n );\n};\n\nexport default ResourcesPage;\n"],"names":["getBuiltinResources","response","apiGet","createBuiltinResource","resource","apiPost","updateBuiltinResource","id","apiPut","deleteBuiltinResource","apiDelete","useBuiltinResourceData","t","useTranslation","resources","setResources","useState","loading","setLoading","error","setError","refreshKey","setRefreshKey","fetchResources","useCallback","data","err","triggerRefresh","prev","addResource","result","message","editResource","removeResource","useEffect","ResourceFormDialog","onSave","onCancel","isSubmitting","setIsSubmitting","uri","setUri","name","setName","description","setDescription","mimeType","setMimeType","content","setContent","enabled","setEnabled","handleSubmit","e","jsx","jsxs","ResourcesPage","auth","useAuth","showForm","setShowForm","editingResource","setEditingResource","resourceToDelete","setResourceToDelete","expandedIds","setExpandedIds","isAdmin","_a","toggleExpand","next","handleCreate","handleEdit","handleConfirmDelete","Plus","X","FileText","idx","isExpanded","ChevronDown","StatusDot","Edit","Trash","ConfirmDialog"],"mappings":"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"}
|