@revealui/core 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -30
- package/dist/api/compression.d.ts.map +1 -1
- package/dist/api/payload-optimization.d.ts.map +1 -1
- package/dist/api/rate-limit.d.ts +30 -29
- package/dist/api/rate-limit.d.ts.map +1 -1
- package/dist/api/rate-limit.js +79 -4
- package/dist/api/response-cache.d.ts.map +1 -1
- package/dist/api/response-cache.js +1 -1
- package/dist/api/rest.d.ts.map +1 -1
- package/dist/api/rest.js +5 -4
- package/dist/auth/access.d.ts.map +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/cache/query-cache.d.ts +12 -10
- package/dist/cache/query-cache.d.ts.map +1 -1
- package/dist/cache/query-cache.js +38 -42
- package/dist/caching/app-cache.d.ts +5 -0
- package/dist/caching/app-cache.d.ts.map +1 -1
- package/dist/caching/app-cache.js +9 -1
- package/dist/caching/cdn-config.d.ts +2 -2
- package/dist/caching/cdn-config.d.ts.map +1 -1
- package/dist/caching/cdn-config.js +5 -15
- package/dist/caching/edge-cache.d.ts +1 -1
- package/dist/caching/edge-cache.d.ts.map +1 -1
- package/dist/caching/edge-cache.js +44 -11
- package/dist/caching/index.d.ts +6 -0
- package/dist/caching/index.d.ts.map +1 -0
- package/dist/caching/index.js +5 -0
- package/dist/caching/service-worker.d.ts +10 -18
- package/dist/caching/service-worker.d.ts.map +1 -1
- package/dist/caching/service-worker.js +5 -4
- package/dist/client/admin/RichText.d.ts +1 -1
- package/dist/client/admin/RichText.d.ts.map +1 -1
- package/dist/client/admin/components/AdminDashboard.d.ts.map +1 -1
- package/dist/client/admin/components/AdminDashboard.js +178 -205
- package/dist/client/admin/components/CollectionList.d.ts.map +1 -1
- package/dist/client/admin/components/DocumentForm.d.ts.map +1 -1
- package/dist/client/admin/components/DocumentForm.js +130 -6
- package/dist/client/admin/components/GlobalForm.d.ts.map +1 -1
- package/dist/client/admin/context/ServerFunctionContext.d.ts +8 -0
- package/dist/client/admin/context/ServerFunctionContext.d.ts.map +1 -0
- package/dist/client/admin/context/ServerFunctionContext.js +15 -0
- package/dist/client/admin/i18n/en.d.ts.map +1 -1
- package/dist/client/admin/index.d.ts +1 -0
- package/dist/client/admin/index.d.ts.map +1 -1
- package/dist/client/admin/index.js +1 -0
- package/dist/client/admin/layout.d.ts +1 -1
- package/dist/client/admin/layout.d.ts.map +1 -1
- package/dist/client/admin/layout.js +3 -2
- package/dist/client/admin/page.d.ts.map +1 -1
- package/dist/client/admin/utils/apiClient.d.ts.map +1 -1
- package/dist/client/admin/utils/apiClient.js +0 -4
- package/dist/client/admin/utils/auth.d.ts +0 -4
- package/dist/client/admin/utils/auth.d.ts.map +1 -1
- package/dist/client/admin/utils/auth.js +0 -6
- package/dist/client/admin/utils/index.d.ts +0 -1
- package/dist/client/admin/utils/index.d.ts.map +1 -1
- package/dist/client/admin/utils/index.js +0 -1
- package/dist/client/admin/utils/serializeConfig.d.ts.map +1 -1
- package/dist/client/hooks.d.ts.map +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +0 -2
- package/dist/client/richtext/RichTextEditor.d.ts.map +1 -1
- package/dist/client/richtext/components/ImageNodeComponent.d.ts.map +1 -1
- package/dist/client/richtext/components/ImageNodeComponent.js +0 -1
- package/dist/client/richtext/components/ImageUploadButton.d.ts +2 -0
- package/dist/client/richtext/components/ImageUploadButton.d.ts.map +1 -1
- package/dist/client/richtext/components/ImageUploadButton.js +30 -15
- package/dist/client/richtext/index.d.ts.map +1 -1
- package/dist/client/richtext/nodes/DecoratorBlockNode.d.ts.map +1 -1
- package/dist/client/richtext/nodes/ImageNode.d.ts.map +1 -1
- package/dist/client/richtext/plugins/CollaborationPlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/CursorsOverlayPlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/FloatingToolbarPlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/ImagePlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/ToolbarPlugin.d.ts.map +1 -1
- package/dist/client/ui/index.d.ts.map +1 -1
- package/dist/client/ui/index.js +1 -1
- package/dist/collections/CollectionOperations.d.ts +7 -7
- package/dist/collections/CollectionOperations.d.ts.map +1 -1
- package/dist/collections/CollectionOperations.js +15 -1
- package/dist/collections/hooks.d.ts.map +1 -1
- package/dist/collections/index.d.ts.map +1 -1
- package/dist/collections/operations/create.d.ts +2 -4
- package/dist/collections/operations/create.d.ts.map +1 -1
- package/dist/collections/operations/create.js +9 -7
- package/dist/collections/operations/createMany.d.ts +12 -0
- package/dist/collections/operations/createMany.d.ts.map +1 -0
- package/dist/collections/operations/createMany.js +43 -0
- package/dist/collections/operations/delete.d.ts +1 -1
- package/dist/collections/operations/delete.d.ts.map +1 -1
- package/dist/collections/operations/delete.js +31 -2
- package/dist/collections/operations/deleteMany.d.ts +11 -0
- package/dist/collections/operations/deleteMany.d.ts.map +1 -0
- package/dist/collections/operations/deleteMany.js +50 -0
- package/dist/collections/operations/fieldHooks.d.ts +2 -2
- package/dist/collections/operations/fieldHooks.d.ts.map +1 -1
- package/dist/collections/operations/fieldHooks.js +4 -4
- package/dist/collections/operations/find.d.ts +2 -4
- package/dist/collections/operations/find.d.ts.map +1 -1
- package/dist/collections/operations/find.js +115 -8
- package/dist/collections/operations/findById.d.ts +3 -4
- package/dist/collections/operations/findById.d.ts.map +1 -1
- package/dist/collections/operations/findById.js +53 -1
- package/dist/collections/operations/sqlAdapter.d.ts +23 -0
- package/dist/collections/operations/sqlAdapter.d.ts.map +1 -0
- package/dist/collections/operations/sqlAdapter.js +76 -0
- package/dist/collections/operations/update.d.ts +3 -5
- package/dist/collections/operations/update.d.ts.map +1 -1
- package/dist/collections/operations/update.js +103 -11
- package/dist/collections/operations/updateMany.d.ts +11 -0
- package/dist/collections/operations/updateMany.d.ts.map +1 -0
- package/dist/collections/operations/updateMany.js +52 -0
- package/dist/collections/registry.d.ts +12 -0
- package/dist/collections/registry.d.ts.map +1 -0
- package/dist/collections/registry.js +38 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/runtime.d.ts.map +1 -1
- package/dist/config/utils.d.ts +0 -10
- package/dist/config/utils.d.ts.map +1 -1
- package/dist/config/utils.js +18 -17
- package/dist/database/index.d.ts +3 -0
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/index.js +1 -5
- package/dist/database/safe-parse.d.ts +26 -0
- package/dist/database/safe-parse.d.ts.map +1 -0
- package/dist/database/safe-parse.js +42 -0
- package/dist/database/ssl-config.d.ts.map +1 -1
- package/dist/database/type-adapter.d.ts.map +1 -1
- package/dist/database/universal-postgres.d.ts.map +1 -1
- package/dist/database/universal-postgres.js +18 -13
- package/dist/dataloader.d.ts.map +1 -1
- package/dist/dataloader.js +16 -2
- package/dist/error-handling/circuit-breaker.d.ts +1 -1
- package/dist/error-handling/circuit-breaker.d.ts.map +1 -1
- package/dist/error-handling/circuit-breaker.js +11 -3
- package/dist/error-handling/error-boundary.d.ts.map +1 -1
- package/dist/error-handling/error-reporter.d.ts +6 -5
- package/dist/error-handling/error-reporter.d.ts.map +1 -1
- package/dist/error-handling/error-reporter.js +26 -41
- package/dist/error-handling/fallback-components.d.ts.map +1 -1
- package/dist/error-handling/fallback-components.js +1 -1
- package/dist/error-handling/index.d.ts +3 -5
- package/dist/error-handling/index.d.ts.map +1 -1
- package/dist/error-handling/index.js +2 -5
- package/dist/error-handling/retry.d.ts.map +1 -1
- package/dist/error-handling/retry.js +13 -8
- package/dist/factories/builders.d.ts.map +1 -1
- package/dist/factories/index.d.ts.map +1 -1
- package/dist/features.d.ts +5 -5
- package/dist/features.d.ts.map +1 -1
- package/dist/features.js +6 -5
- package/dist/fieldTraversal.d.ts.map +1 -1
- package/dist/fields/config/types.d.ts.map +1 -1
- package/dist/fields/getDefaultValue.d.ts.map +1 -1
- package/dist/fields/getFieldPaths.d.ts.map +1 -1
- package/dist/fields/hooks/afterRead/index.d.ts.map +1 -1
- package/dist/fields/hooks/afterRead/promise.d.ts.map +1 -1
- package/dist/fields/hooks/afterRead/traverseFields.d.ts.map +1 -1
- package/dist/generated/types/cms.d.ts.map +1 -1
- package/dist/generated/types/cms.js +0 -1
- package/dist/generated/types/index.d.ts +0 -3
- package/dist/generated/types/index.d.ts.map +1 -1
- package/dist/generated/types/index.js +0 -7
- package/dist/generated/types/neon.d.ts.map +1 -1
- package/dist/generated/types/neon.js +4 -2
- package/dist/globals/GlobalOperations.d.ts.map +1 -1
- package/dist/globals/GlobalOperations.js +4 -2
- package/dist/globals/index.d.ts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -6
- package/dist/instance/RevealUIInstance.d.ts.map +1 -1
- package/dist/instance/RevealUIInstance.js +50 -69
- package/dist/instance/index.d.ts.map +1 -1
- package/dist/instance/logger.d.ts.map +1 -1
- package/dist/instance/methods/create.d.ts.map +1 -1
- package/dist/instance/methods/create.js +4 -4
- package/dist/instance/methods/delete.d.ts.map +1 -1
- package/dist/instance/methods/delete.js +5 -5
- package/dist/instance/methods/find.d.ts.map +1 -1
- package/dist/instance/methods/find.js +0 -3
- package/dist/instance/methods/findById.d.ts.map +1 -1
- package/dist/instance/methods/findById.js +0 -3
- package/dist/instance/methods/hooks.d.ts.map +1 -1
- package/dist/instance/methods/hooks.js +3 -1
- package/dist/instance/methods/update.d.ts.map +1 -1
- package/dist/instance/methods/update.js +4 -4
- package/dist/jobs/index.d.ts +16 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +14 -0
- package/dist/jobs/queue.d.ts +57 -0
- package/dist/jobs/queue.d.ts.map +1 -0
- package/dist/jobs/queue.js +134 -0
- package/dist/license-encryption.d.ts +21 -0
- package/dist/license-encryption.d.ts.map +1 -0
- package/dist/license-encryption.js +74 -0
- package/dist/license.d.ts +33 -7
- package/dist/license.d.ts.map +1 -1
- package/dist/license.js +119 -16
- package/dist/monitoring/alerts.d.ts.map +1 -1
- package/dist/monitoring/cleanup-manager.d.ts.map +1 -1
- package/dist/monitoring/health-monitor.d.ts.map +1 -1
- package/dist/monitoring/index.d.ts.map +1 -1
- package/dist/monitoring/process-registry.d.ts.map +1 -1
- package/dist/monitoring/query-monitor.d.ts.map +1 -1
- package/dist/monitoring/types.d.ts.map +1 -1
- package/dist/monitoring/zombie-detector.d.ts.map +1 -1
- package/dist/monitoring/zombie-detector.js +5 -0
- package/dist/nextjs/index.d.ts.map +1 -1
- package/dist/nextjs/utilities.d.ts.map +1 -1
- package/dist/nextjs/withRevealUI.d.ts.map +1 -1
- package/dist/observability/alerts.d.ts.map +1 -1
- package/dist/observability/alerts.js +1 -2
- package/dist/observability/health-check.d.ts +1 -5
- package/dist/observability/health-check.d.ts.map +1 -1
- package/dist/observability/health-check.js +37 -43
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/logger.d.ts.map +1 -1
- package/dist/observability/logger.js +1 -1
- package/dist/observability/metrics.d.ts.map +1 -1
- package/dist/observability/tracing.d.ts.map +1 -1
- package/dist/observability/tracing.js +0 -1
- package/dist/optimization/asset-optimizer.d.ts +6 -2
- package/dist/optimization/asset-optimizer.d.ts.map +1 -1
- package/dist/optimization/asset-optimizer.js +31 -7
- package/dist/optimization/bundle-analyzer.d.ts +1 -1
- package/dist/optimization/bundle-analyzer.d.ts.map +1 -1
- package/dist/optimization/bundle-analyzer.js +29 -5
- package/dist/optimization/code-splitting.d.ts +0 -23
- package/dist/optimization/code-splitting.d.ts.map +1 -1
- package/dist/optimization/code-splitting.js +0 -29
- package/dist/plugins/form-builder.d.ts.map +1 -1
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/nested-docs.d.ts +4 -0
- package/dist/plugins/nested-docs.d.ts.map +1 -1
- package/dist/plugins/nested-docs.js +50 -5
- package/dist/plugins/redirects.d.ts.map +1 -1
- package/dist/queries/index.d.ts.map +1 -1
- package/dist/queries/queryBuilder.d.ts.map +1 -1
- package/dist/queries/queryBuilder.js +15 -5
- package/dist/relationships/analyzer.d.ts.map +1 -1
- package/dist/relationships/analyzer.js +8 -0
- package/dist/relationships/index.d.ts.map +1 -1
- package/dist/relationships/populate-core.d.ts +57 -0
- package/dist/relationships/populate-core.d.ts.map +1 -0
- package/dist/relationships/populate-core.js +116 -0
- package/dist/relationships/populate-helpers.d.ts +5 -51
- package/dist/relationships/populate-helpers.d.ts.map +1 -1
- package/dist/relationships/populate-helpers.js +4 -109
- package/dist/relationships/population.d.ts +1 -9
- package/dist/relationships/population.d.ts.map +1 -1
- package/dist/relationships/population.js +8 -3
- package/dist/revealui.d.ts.map +1 -1
- package/dist/richtext/exports/client/rcc.d.ts.map +1 -1
- package/dist/richtext/exports/client/rcc.js +1 -1
- package/dist/richtext/exports/server/rsc.d.ts +17 -0
- package/dist/richtext/exports/server/rsc.d.ts.map +1 -1
- package/dist/richtext/exports/server/rsc.js +61 -5
- package/dist/richtext/index.d.ts.map +1 -1
- package/dist/richtext/lexical.d.ts.map +1 -1
- package/dist/security/audit.d.ts +1 -1
- package/dist/security/audit.d.ts.map +1 -1
- package/dist/security/audit.js +4 -2
- package/dist/security/auth.d.ts +29 -160
- package/dist/security/auth.d.ts.map +1 -1
- package/dist/security/auth.js +150 -367
- package/dist/security/authorization.d.ts +7 -31
- package/dist/security/authorization.d.ts.map +1 -1
- package/dist/security/authorization.js +72 -14
- package/dist/security/encryption.d.ts +56 -44
- package/dist/security/encryption.d.ts.map +1 -1
- package/dist/security/encryption.js +128 -100
- package/dist/security/gdpr-storage.d.ts +102 -0
- package/dist/security/gdpr-storage.d.ts.map +1 -0
- package/dist/security/gdpr-storage.js +65 -0
- package/dist/security/gdpr.d.ts +57 -37
- package/dist/security/gdpr.d.ts.map +1 -1
- package/dist/security/gdpr.js +155 -94
- package/dist/security/headers.d.ts +4 -2
- package/dist/security/headers.d.ts.map +1 -1
- package/dist/security/headers.js +35 -17
- package/dist/security/index.d.ts +3 -16
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +3 -16
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/renderPage.d.ts.map +1 -1
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +2 -4
- package/dist/storage/vercel-blob.d.ts.map +1 -1
- package/dist/translations/index.d.ts.map +1 -1
- package/dist/types/access.d.ts.map +1 -1
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/cms.d.ts.map +1 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/extensions.d.ts.map +1 -1
- package/dist/types/frontend.d.ts.map +1 -1
- package/dist/types/generated.d.ts +0 -2
- package/dist/types/generated.d.ts.map +1 -1
- package/dist/types/generated.js +0 -1
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/interfaces/app.d.ts.map +1 -1
- package/dist/types/jobs.d.ts.map +1 -1
- package/dist/types/legacy.d.ts.map +1 -1
- package/dist/types/plugins.d.ts.map +1 -1
- package/dist/types/query.d.ts.map +1 -1
- package/dist/types/request.d.ts.map +1 -1
- package/dist/types/richtext.d.ts.map +1 -1
- package/dist/types/runtime.d.ts +59 -1
- package/dist/types/runtime.d.ts.map +1 -1
- package/dist/types/schema.d.ts.map +1 -1
- package/dist/types/user.d.ts.map +1 -1
- package/dist/utils/access-conversion.d.ts.map +1 -1
- package/dist/utils/api-wrapper.d.ts.map +1 -1
- package/dist/utils/api-wrapper.js +1 -1
- package/dist/utils/block-conversion.d.ts.map +1 -1
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/deep-clone.js +0 -1
- package/dist/utils/error-responses.d.ts.map +1 -1
- package/dist/utils/errors.d.ts +36 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +103 -0
- package/dist/utils/field-conversion.d.ts +1 -1
- package/dist/utils/field-conversion.d.ts.map +1 -1
- package/dist/utils/flattenResult.d.ts.map +1 -1
- package/dist/utils/flattenResult.js +0 -1
- package/dist/utils/getBlockSelect.d.ts.map +1 -1
- package/dist/utils/getSelectMode.d.ts.map +1 -1
- package/dist/utils/isValidID.d.ts.map +1 -1
- package/dist/utils/json-parsing.d.ts.map +1 -1
- package/dist/utils/logger-client.d.ts.map +1 -1
- package/dist/utils/logger-server.d.ts.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/request-context.d.ts.map +1 -1
- package/dist/utils/stripUnselectedFields.d.ts.map +1 -1
- package/dist/utils/type-guards.d.ts.map +1 -1
- package/package.json +39 -16
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from 'react';
|
|
4
|
-
|
|
3
|
+
import { lazy, Suspense, useCallback, useState } from 'react';
|
|
4
|
+
// Lazy-loaded so Lexical (~1.2MB) is only bundled for edit pages with richText
|
|
5
|
+
// fields — list/dashboard pages skip the entire Lexical chunk.
|
|
6
|
+
const RichTextEditor = lazy(() => import('../../richtext/RichTextEditor.js').then((m) => ({ default: m.RichTextEditor })));
|
|
5
7
|
function getFieldLabel(field) {
|
|
6
8
|
const { label } = field;
|
|
7
9
|
if (typeof label === 'function') {
|
|
@@ -70,11 +72,105 @@ export function DocumentForm({ collection, document, onSave, onCancel, isLoading
|
|
|
70
72
|
};
|
|
71
73
|
return (_jsx("div", { className: "bg-white shadow overflow-hidden sm:rounded-lg", children: _jsxs("div", { className: "px-4 py-5 sm:p-6", children: [_jsxs("h3", { className: "text-lg leading-6 font-medium text-gray-900 mb-4", children: [document ? 'Edit' : 'Create', " ", collection.slug.slice(0, -1)] }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [visibleFields.map((field) => (_jsxs("div", { children: [_jsxs("label", { htmlFor: field.name, className: "block text-sm font-medium text-gray-700", children: [getFieldLabel(field), field.required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), _jsx("div", { className: "mt-1", children: _jsx(FieldInput, { field: field, value: field.name ? formData[field.name] : undefined, onChange: (value) => field.name && handleFieldChange(field.name, value) }) })] }, field.name || 'layout'))), _jsxs("div", { className: "flex justify-end space-x-3 pt-6", children: [_jsx("button", { type: "button", onClick: onCancel, className: "bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500", children: "Cancel" }), _jsx("button", { type: "submit", disabled: isLoading, className: "inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed", children: isLoading ? 'Saving...' : 'Save' })] })] })] }) }));
|
|
72
74
|
}
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Array field: repeatable list of sub-fields
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
function ArrayFieldRenderer({ field, value, onChange, }) {
|
|
79
|
+
const rows = Array.isArray(value) ? value : [];
|
|
80
|
+
const subFields = field.fields ?? [];
|
|
81
|
+
const addRow = () => onChange([...rows, {}]);
|
|
82
|
+
const removeRow = (idx) => onChange(rows.filter((_, i) => i !== idx));
|
|
83
|
+
const updateRow = (idx, key, val) => {
|
|
84
|
+
const updated = rows.map((row, i) => (i === idx ? { ...row, [key]: val } : row));
|
|
85
|
+
onChange(updated);
|
|
86
|
+
};
|
|
87
|
+
return (_jsxs("div", { className: "space-y-3", children: [rows.map((row, idx) => (_jsxs("div", { className: "border border-gray-200 rounded-md p-3 space-y-2 relative", children: [_jsx("button", { type: "button", onClick: () => removeRow(idx), className: "absolute top-2 right-2 text-red-400 hover:text-red-600 text-sm", children: "Remove" }), subFields.map((sf) => (_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-${idx}-${sf.name}`, className: "block text-xs font-medium text-gray-600", children: getFieldLabel(sf) }), _jsx(FieldInput, { field: sf, value: row[sf.name ?? ''], onChange: (v) => updateRow(idx, sf.name ?? '', v) })] }, sf.name)))] }, `${field.name}-row-${idx.toString()}`))), _jsx("button", { type: "button", onClick: addRow, className: "text-sm text-indigo-600 hover:text-indigo-800 font-medium", children: "+ Add item" })] }));
|
|
88
|
+
}
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
// Group field: named group of sub-fields (single object, not repeatable)
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
function GroupFieldRenderer({ field, value, onChange, }) {
|
|
93
|
+
const data = (typeof value === 'object' && value !== null ? value : {});
|
|
94
|
+
const subFields = field.fields ?? [];
|
|
95
|
+
const handleChange = (key, val) => {
|
|
96
|
+
onChange({ ...data, [key]: val });
|
|
97
|
+
};
|
|
98
|
+
return (_jsx("div", { className: "border border-gray-200 rounded-md p-3 space-y-3", children: subFields.map((sf) => (_jsxs("div", { children: [_jsxs("label", { htmlFor: `${field.name}-${sf.name}`, className: "block text-xs font-medium text-gray-600", children: [getFieldLabel(sf), sf.required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), _jsx(FieldInput, { field: sf, value: data[sf.name ?? ''], onChange: (v) => handleChange(sf.name ?? '', v) })] }, sf.name))) }));
|
|
99
|
+
}
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
// Blocks field: polymorphic list of typed blocks
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
function BlocksFieldRenderer({ field, value, onChange, }) {
|
|
104
|
+
const blocks = Array.isArray(value) ? value : [];
|
|
105
|
+
const blockTypes = field.blocks ??
|
|
106
|
+
[];
|
|
107
|
+
const addBlock = (slug) => {
|
|
108
|
+
onChange([...blocks, { blockType: slug }]);
|
|
109
|
+
};
|
|
110
|
+
const removeBlock = (idx) => onChange(blocks.filter((_, i) => i !== idx));
|
|
111
|
+
const updateBlock = (idx, key, val) => {
|
|
112
|
+
const updated = blocks.map((b, i) => (i === idx ? { ...b, [key]: val } : b));
|
|
113
|
+
onChange(updated);
|
|
114
|
+
};
|
|
115
|
+
return (_jsxs("div", { className: "space-y-3", children: [blocks.map((block, idx) => {
|
|
116
|
+
const blockDef = blockTypes.find((bt) => bt.slug === block.blockType);
|
|
117
|
+
return (_jsxs("div", { className: "border border-gray-200 rounded-md p-3 space-y-2 relative", children: [_jsxs("div", { className: "flex items-center justify-between mb-1", children: [_jsx("span", { className: "text-xs font-semibold text-gray-500 uppercase", children: String(block.blockType) }), _jsx("button", { type: "button", onClick: () => removeBlock(idx), className: "text-red-400 hover:text-red-600 text-sm", children: "Remove" })] }), (blockDef?.fields ?? []).map((sf) => (_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-${idx}-${sf.name}`, className: "block text-xs font-medium text-gray-600", children: getFieldLabel(sf) }), _jsx(FieldInput, { field: sf, value: block[sf.name ?? ''], onChange: (v) => updateBlock(idx, sf.name ?? '', v) })] }, sf.name)))] }, `${field.name}-block-${idx.toString()}`));
|
|
118
|
+
}), blockTypes.length > 0 && (_jsx("div", { className: "flex gap-2 flex-wrap", children: blockTypes.map((bt) => (_jsxs("button", { type: "button", onClick: () => addBlock(bt.slug), className: "text-sm text-indigo-600 hover:text-indigo-800 font-medium", children: ["+ ", bt.slug] }, bt.slug))) }))] }));
|
|
119
|
+
}
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// Collapsible field: expandable section of sub-fields
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
function CollapsibleFieldRenderer({ field, value, onChange, }) {
|
|
124
|
+
const [open, setOpen] = useState(true);
|
|
125
|
+
const data = (typeof value === 'object' && value !== null ? value : {});
|
|
126
|
+
const subFields = field.fields ?? [];
|
|
127
|
+
const handleChange = (key, val) => {
|
|
128
|
+
onChange({ ...data, [key]: val });
|
|
129
|
+
};
|
|
130
|
+
return (_jsxs("div", { className: "border border-gray-200 rounded-md", children: [_jsxs("button", { type: "button", onClick: () => setOpen(!open), className: "w-full text-left px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 flex items-center justify-between", children: [getFieldLabel(field), _jsx("span", { className: "text-gray-400", children: open ? '\u25B2' : '\u25BC' })] }), open && (_jsx("div", { className: "px-3 pb-3 space-y-3", children: subFields.map((sf) => (_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-${sf.name}`, className: "block text-xs font-medium text-gray-600", children: getFieldLabel(sf) }), _jsx(FieldInput, { field: sf, value: data[sf.name ?? ''], onChange: (v) => handleChange(sf.name ?? '', v) })] }, sf.name))) }))] }));
|
|
131
|
+
}
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// JSON field: raw JSON editor with syntax-highlighted textarea
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
function JsonFieldRenderer({ field, value, onChange, }) {
|
|
136
|
+
const [error, setError] = useState(null);
|
|
137
|
+
const formatted = typeof value === 'string' ? value : value != null ? JSON.stringify(value, null, 2) : '';
|
|
138
|
+
const handleChange = useCallback((e) => {
|
|
139
|
+
const raw = e.target.value;
|
|
140
|
+
try {
|
|
141
|
+
const parsed = JSON.parse(raw);
|
|
142
|
+
setError(null);
|
|
143
|
+
onChange(parsed);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
setError('Invalid JSON');
|
|
147
|
+
onChange(raw);
|
|
148
|
+
}
|
|
149
|
+
}, [onChange]);
|
|
150
|
+
return (_jsxs("div", { children: [_jsx("textarea", { id: field.name, value: formatted, onChange: handleChange, rows: 8, className: "mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm font-mono text-xs", spellCheck: false }), error && _jsx("p", { className: "mt-1 text-xs text-red-500", children: error })] }));
|
|
151
|
+
}
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// Point field: latitude/longitude pair
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
function PointFieldRenderer({ field, value, onChange, }) {
|
|
156
|
+
const point = (typeof value === 'object' && value !== null ? value : { lat: 0, lng: 0 });
|
|
157
|
+
const baseClasses = 'mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm';
|
|
158
|
+
return (_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-lat`, className: "block text-xs font-medium text-gray-600", children: "Latitude" }), _jsx("input", { type: "number", id: `${field.name}-lat`, value: point.lat, onChange: (e) => onChange({ ...point, lat: Number(e.target.value) }), className: baseClasses, step: "any", min: -90, max: 90 })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-lng`, className: "block text-xs font-medium text-gray-600", children: "Longitude" }), _jsx("input", { type: "number", id: `${field.name}-lng`, value: point.lng, onChange: (e) => onChange({ ...point, lng: Number(e.target.value) }), className: baseClasses, step: "any", min: -180, max: 180 })] })] }));
|
|
159
|
+
}
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
// Main FieldInput — renders the appropriate control for each field type
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
73
163
|
function FieldInput({ field, value, onChange }) {
|
|
74
164
|
const baseClasses = 'mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm';
|
|
75
165
|
switch (field.type) {
|
|
76
166
|
case 'text':
|
|
77
167
|
return (_jsx("input", { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required }));
|
|
168
|
+
case 'email':
|
|
169
|
+
return (_jsx("input", { type: "email", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, placeholder: field.admin?.placeholder }));
|
|
170
|
+
case 'password':
|
|
171
|
+
return (_jsx("input", { type: "password", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, autoComplete: "new-password" }));
|
|
172
|
+
case 'code':
|
|
173
|
+
return (_jsx("textarea", { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), rows: 8, className: `${baseClasses} font-mono text-xs`, required: field.required, spellCheck: false }));
|
|
78
174
|
case 'textarea':
|
|
79
175
|
return (_jsx("textarea", { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), rows: 4, className: baseClasses, required: field.required }));
|
|
80
176
|
case 'number':
|
|
@@ -83,16 +179,44 @@ function FieldInput({ field, value, onChange }) {
|
|
|
83
179
|
return (_jsx("input", { type: "checkbox", id: field.name, checked: Boolean(value), onChange: (e) => onChange(e.target.checked), className: "h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded" }));
|
|
84
180
|
case 'select':
|
|
85
181
|
return (_jsxs("select", { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, children: [_jsx("option", { value: "", children: "Select an option" }), field.options?.map((option) => {
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
return (_jsx("option", { value:
|
|
182
|
+
const optValue = typeof option === 'string' ? option : option.value;
|
|
183
|
+
const optLabel = typeof option === 'string' ? option : option.label;
|
|
184
|
+
return (_jsx("option", { value: optValue, children: optLabel }, optValue));
|
|
89
185
|
})] }));
|
|
186
|
+
case 'radio':
|
|
187
|
+
return (_jsx("div", { className: "space-y-2 mt-1", children: field.options?.map((option) => {
|
|
188
|
+
const optValue = typeof option === 'string' ? option : option.value;
|
|
189
|
+
const optLabel = typeof option === 'string' ? option : option.label;
|
|
190
|
+
return (_jsxs("label", { className: "flex items-center gap-2 text-sm text-gray-700 cursor-pointer", children: [_jsx("input", { type: "radio", name: field.name, value: optValue, checked: formatTextValue(value) === optValue, onChange: () => onChange(optValue), className: "h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300" }), optLabel] }, optValue));
|
|
191
|
+
}) }));
|
|
192
|
+
case 'relationship':
|
|
193
|
+
return (_jsxs("div", { children: [_jsx("input", { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, placeholder: `Enter ${field.relationTo ?? 'related'} ID` }), _jsxs("p", { className: "mt-1 text-xs text-gray-400", children: ["Related to: ", field.relationTo ?? 'unknown'] })] }));
|
|
194
|
+
case 'upload':
|
|
195
|
+
return (_jsxs("div", { children: [_jsx("input", { type: "file", id: field.name, onChange: (e) => {
|
|
196
|
+
const file = e.target.files?.[0];
|
|
197
|
+
if (file)
|
|
198
|
+
onChange(file);
|
|
199
|
+
}, className: "block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-medium file:bg-indigo-50 file:text-indigo-700 hover:file:bg-indigo-100" }), typeof value === 'string' && value !== '' && (_jsxs("p", { className: "mt-1 text-xs text-gray-500", children: ["Current: ", value] }))] }));
|
|
90
200
|
case 'date':
|
|
91
201
|
return (_jsx("input", { type: "datetime-local", id: field.name, value: formatDateInputValue(value), onChange: (e) => onChange(e.target.value ? new Date(e.target.value) : null), className: baseClasses, required: field.required }));
|
|
92
202
|
case 'richText': {
|
|
93
203
|
const editorConfig = field.editor;
|
|
94
|
-
return (_jsx(RichTextEditor, { namespace: String(field.name), editorConfig: editorConfig, initialValue: value, onSerializedChange: (json) => onChange(json), className: "border border-gray-300 rounded-md" }));
|
|
204
|
+
return (_jsx(Suspense, { fallback: _jsx("div", { className: "border border-gray-300 rounded-md h-40 flex items-center justify-center text-sm text-gray-400", children: "Loading editor\u2026" }), children: _jsx(RichTextEditor, { namespace: String(field.name), editorConfig: editorConfig, initialValue: value, onSerializedChange: (json) => onChange(json), className: "border border-gray-300 rounded-md" }) }));
|
|
95
205
|
}
|
|
206
|
+
case 'array':
|
|
207
|
+
return _jsx(ArrayFieldRenderer, { field: field, value: value, onChange: onChange });
|
|
208
|
+
case 'group':
|
|
209
|
+
return _jsx(GroupFieldRenderer, { field: field, value: value, onChange: onChange });
|
|
210
|
+
case 'blocks':
|
|
211
|
+
return _jsx(BlocksFieldRenderer, { field: field, value: value, onChange: onChange });
|
|
212
|
+
case 'collapsible':
|
|
213
|
+
return _jsx(CollapsibleFieldRenderer, { field: field, value: value, onChange: onChange });
|
|
214
|
+
case 'json':
|
|
215
|
+
return _jsx(JsonFieldRenderer, { field: field, value: value, onChange: onChange });
|
|
216
|
+
case 'point':
|
|
217
|
+
return _jsx(PointFieldRenderer, { field: field, value: value, onChange: onChange });
|
|
218
|
+
case 'ui':
|
|
219
|
+
return (_jsxs("div", { className: "border border-dashed border-gray-300 rounded-md p-3 text-sm text-gray-400 text-center", children: ["Custom UI field: ", field.name] }));
|
|
96
220
|
default:
|
|
97
221
|
return (_jsx("input", { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required }));
|
|
98
222
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GlobalForm.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/GlobalForm.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAiB,MAAM,yBAAyB,
|
|
1
|
+
{"version":3,"file":"GlobalForm.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/GlobalForm.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAiB,MAAM,yBAAyB,CAAC;AAsCjG,UAAU,eAAe;IACvB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAAiB,GAClB,EAAE,eAAe,2CA4DjB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type ServerFunction = (name: string, args: unknown) => Promise<unknown>;
|
|
2
|
+
export declare function ServerFunctionProvider({ children, serverFunction, }: {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
serverFunction?: ServerFunction;
|
|
5
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function useServerFunction(): ServerFunction;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=ServerFunctionContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServerFunctionContext.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/context/ServerFunctionContext.tsx"],"names":[],"mappings":"AAIA,KAAK,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAIxE,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,cAAc,GACf,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,2CAEA;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CASlD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext } from 'react';
|
|
4
|
+
const ServerFunctionContext = createContext(null);
|
|
5
|
+
export function ServerFunctionProvider({ children, serverFunction, }) {
|
|
6
|
+
return _jsx(ServerFunctionContext, { value: serverFunction ?? null, children: children });
|
|
7
|
+
}
|
|
8
|
+
export function useServerFunction() {
|
|
9
|
+
const fn = useContext(ServerFunctionContext);
|
|
10
|
+
if (!fn) {
|
|
11
|
+
throw new Error('useServerFunction must be used within a ServerFunctionProvider. ' +
|
|
12
|
+
'Pass serverFunction prop to RootLayout.');
|
|
13
|
+
}
|
|
14
|
+
return fn;
|
|
15
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/i18n/en.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;CAuBd,
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/i18n/en.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;CAuBd,CAAC"}
|
|
@@ -2,6 +2,7 @@ export { AdminDashboard } from './components/AdminDashboard.js';
|
|
|
2
2
|
export { CollectionList } from './components/CollectionList.js';
|
|
3
3
|
export { DocumentForm } from './components/DocumentForm.js';
|
|
4
4
|
export { GlobalForm } from './components/GlobalForm.js';
|
|
5
|
+
export { ServerFunctionProvider, useServerFunction, } from './context/ServerFunctionContext.js';
|
|
5
6
|
export { en } from './i18n/en.js';
|
|
6
7
|
export { RootLayout } from './layout.js';
|
|
7
8
|
export { generatePageMetadata, NotFoundPage, RootPage } from './page.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/admin/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/admin/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EACL,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACzE,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -3,6 +3,7 @@ export { AdminDashboard } from './components/AdminDashboard.js';
|
|
|
3
3
|
export { CollectionList } from './components/CollectionList.js';
|
|
4
4
|
export { DocumentForm } from './components/DocumentForm.js';
|
|
5
5
|
export { GlobalForm } from './components/GlobalForm.js';
|
|
6
|
+
export { ServerFunctionProvider, useServerFunction, } from './context/ServerFunctionContext.js';
|
|
6
7
|
export { en } from './i18n/en.js';
|
|
7
8
|
export { RootLayout } from './layout.js';
|
|
8
9
|
export { generatePageMetadata, NotFoundPage, RootPage } from './page.js';
|
|
@@ -6,5 +6,5 @@ export interface RootLayoutProps {
|
|
|
6
6
|
importMap?: Record<string, unknown>;
|
|
7
7
|
serverFunction?: (name: string, args: unknown) => Promise<unknown>;
|
|
8
8
|
}
|
|
9
|
-
export declare function RootLayout({ children }: RootLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function RootLayout({ children, serverFunction }: RootLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
10
10
|
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/client/admin/layout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/client/admin/layout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAGnD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE;AAED,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,eAAe,2CAiBvE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// RevealUI Admin Layout - Local implementation
|
|
3
3
|
import Head from 'next/head';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import { ServerFunctionProvider } from './context/ServerFunctionContext.js';
|
|
5
|
+
export function RootLayout({ children, serverFunction }) {
|
|
6
|
+
return (_jsxs("html", { lang: "en", children: [_jsxs(Head, { children: [_jsx("meta", { charSet: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: "RevealUI Admin" })] }), _jsx("body", { className: "antialiased", children: _jsx(ServerFunctionProvider, { serverFunction: serverFunction, children: _jsx("div", { id: "revealui-admin", className: "min-h-screen", children: children }) }) })] }));
|
|
6
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/client/admin/page.tsx"],"names":[],"mappings":"AACA,UAAU,QAAQ;IAChB,KAAK,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/client/admin/page.tsx"],"names":[],"mappings":"AACA,UAAU,QAAQ;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzC,YAAY,EAAE,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QACN,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzC,YAAY,EAAE,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,aAAa,2CAoKjD;AAED,wBAAgB,YAAY,4CAO3B;AAED,wBAAgB,oBAAoB,IAAI,QAAQ,CAK/C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/apiClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,
|
|
1
|
+
{"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/apiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* API Client for RevealUI Admin Dashboard
|
|
3
3
|
* Handles all API communication with authentication and error handling
|
|
4
4
|
*/
|
|
5
|
-
import { getAuthHeader } from './auth.js';
|
|
6
5
|
export var APIErrorType;
|
|
7
6
|
(function (APIErrorType) {
|
|
8
7
|
APIErrorType["Network"] = "network";
|
|
@@ -64,11 +63,8 @@ export class APIClient {
|
|
|
64
63
|
* Make an authenticated API request
|
|
65
64
|
*/
|
|
66
65
|
async request(endpoint, options = {}) {
|
|
67
|
-
const authHeader = getAuthHeader();
|
|
68
66
|
const headers = {
|
|
69
67
|
'Content-Type': 'application/json',
|
|
70
|
-
// biome-ignore lint/style/useNamingConvention: HTTP header key.
|
|
71
|
-
...(authHeader && { Authorization: authHeader }),
|
|
72
68
|
...options.headers,
|
|
73
69
|
};
|
|
74
70
|
const url = `${this.baseURL}${endpoint}`;
|
|
@@ -20,8 +20,4 @@ export declare function clearAuthToken(): void;
|
|
|
20
20
|
* Get Authorization header value
|
|
21
21
|
*/
|
|
22
22
|
export declare function getAuthHeader(): string | null;
|
|
23
|
-
/**
|
|
24
|
-
* Check if user is authenticated
|
|
25
|
-
*/
|
|
26
|
-
export declare function isAuthenticated(): boolean;
|
|
27
23
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAoB5C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIhD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAKrC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAG7C
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAoB5C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIhD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAKrC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAG7C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,gBAAgB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializeConfig.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/serializeConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,
|
|
1
|
+
{"version":3,"file":"serializeConfig.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/serializeConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAmC5D;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAElE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/client/hooks.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,KAAK,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/client/hooks.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,WAAW,IAAI,eAAe,CAM7C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EACjD,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EACxC,mBAAmB,EAAE,MAAM,EAAE,GAC5B,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAMxB"}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export * from './admin/index.js';
|
|
7
7
|
export { useRevealUI, withRevealUIAccess } from './hooks.js';
|
|
8
|
-
export * from './http/index.js';
|
|
9
8
|
export type { FloatingToolbarPluginProps, ImageNodeData, RichTextEditorProps, SerializedImageNode, ToolbarPluginProps, } from './richtext/index.js';
|
|
10
9
|
export { $createImageNode, $isImageNode, FloatingToolbarPlugin, ImageNode, ImageNodeComponent, ImagePlugin, ImageUploadButton, INSERT_IMAGE_COMMAND, OPEN_IMAGE_UPLOAD_COMMAND, richTextEditorStyles, ToolbarPlugin, } from './richtext/index.js';
|
|
11
10
|
export * from './ui/index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAI7D,YAAY,EACV,0BAA0B,EAC1B,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,qBAAqB,EACrB,SAAS,EACT,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,yBAAyB,EACzB,oBAAoB,EACpB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAE7B,cAAc,eAAe,CAAC"}
|
package/dist/client/index.js
CHANGED
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
export * from './admin/index.js';
|
|
8
8
|
// React hooks
|
|
9
9
|
export { useRevealUI, withRevealUIAccess } from './hooks.js';
|
|
10
|
-
// HTTP fetch utilities
|
|
11
|
-
export * from './http/index.js';
|
|
12
10
|
// Re-export specific items that don't conflict
|
|
13
11
|
export { $createImageNode, $isImageNode, FloatingToolbarPlugin, ImageNode, ImageNodeComponent, ImagePlugin, ImageUploadButton, INSERT_IMAGE_COMMAND, OPEN_IMAGE_UPLOAD_COMMAND, richTextEditorStyles, ToolbarPlugin, } from './richtext/index.js';
|
|
14
12
|
// UI components
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RichTextEditor.d.ts","sourceRoot":"","sources":["../../../src/client/richtext/RichTextEditor.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"RichTextEditor.d.ts","sourceRoot":"","sources":["../../../src/client/richtext/RichTextEditor.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EACV,WAAW,EAEX,aAAa,EAEb,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,KAAK,EACV,cAAc,IAAI,oBAAoB,EAEvC,MAAM,yBAAyB,CAAC;AAWjC,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,8CAA8C;IAC9C,YAAY,CAAC,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAAC;IACrD,oCAAoC;IACpC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/D,8CAA8C;IAC9C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC3D,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IACxD,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,QAAQ,CAAC;IACxE,+DAA+D;IAC/D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC/B,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA+ID,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AA2B3D,wBAAgB,cAAc,CAAC,EAC7B,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,WAA+B,EAC/B,SAAc,EACd,QAAe,EACf,SAAiB,EACjB,OAAO,EACP,SAA4B,EAC5B,aAAqB,EACrB,UAAU,EACV,eAAe,EACf,eAAuB,EACvB,QAAQ,EACR,WAAW,EACX,UAAU,EACV,UAAU,GACX,EAAE,mBAAmB,2CA+GrB;AAMD,eAAO,MAAM,oBAAoB,0+FAmIhC,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageNodeComponent.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageNodeComponent.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"ImageNodeComponent.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageNodeComponent.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CA0J9C,CAAC"}
|
|
@@ -5,6 +5,8 @@ interface ImageUploadButtonProps {
|
|
|
5
5
|
onUploadError?: (error: Error) => void;
|
|
6
6
|
uploadEndpoint?: string;
|
|
7
7
|
acceptedFileTypes?: string;
|
|
8
|
+
/** Maximum allowed file size in bytes (default: 10 MB) */
|
|
9
|
+
maxFileSizeBytes?: number;
|
|
8
10
|
}
|
|
9
11
|
export declare const ImageUploadButton: React.FC<ImageUploadButtonProps>;
|
|
10
12
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageUploadButton.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageUploadButton.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"ImageUploadButton.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageUploadButton.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,UAAU,sBAAsB;IAC9B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAqBD,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA0I9D,CAAC"}
|
|
@@ -9,6 +9,8 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
|
|
|
9
9
|
import { logger } from '@revealui/core/utils/logger';
|
|
10
10
|
import { useCallback, useRef, useState } from 'react';
|
|
11
11
|
import { INSERT_IMAGE_COMMAND } from '../nodes/ImageNode.js';
|
|
12
|
+
/** Default maximum file size: 10 MB */
|
|
13
|
+
const DEFAULT_MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
|
12
14
|
const getUploadUrl = (payload) => {
|
|
13
15
|
if (!payload || typeof payload !== 'object') {
|
|
14
16
|
return null;
|
|
@@ -22,7 +24,7 @@ const getUploadUrl = (payload) => {
|
|
|
22
24
|
return result.data.url;
|
|
23
25
|
return null;
|
|
24
26
|
};
|
|
25
|
-
export const ImageUploadButton = ({ onUploadStart, onUploadComplete, onUploadError, uploadEndpoint = '/api/media', acceptedFileTypes = 'image/jpeg,image/jpg,image/png,image/webp,image/gif', }) => {
|
|
27
|
+
export const ImageUploadButton = ({ onUploadStart, onUploadComplete, onUploadError, uploadEndpoint = '/api/media', acceptedFileTypes = 'image/jpeg,image/jpg,image/png,image/webp,image/gif', maxFileSizeBytes = DEFAULT_MAX_FILE_SIZE_BYTES, }) => {
|
|
26
28
|
const [editor] = useLexicalComposerContext();
|
|
27
29
|
const fileInputRef = useRef(null);
|
|
28
30
|
const [isUploading, setIsUploading] = useState(false);
|
|
@@ -35,10 +37,10 @@ export const ImageUploadButton = ({ onUploadStart, onUploadComplete, onUploadErr
|
|
|
35
37
|
onUploadError?.(new Error('File must be an image'));
|
|
36
38
|
return;
|
|
37
39
|
}
|
|
38
|
-
// Validate file size
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
onUploadError?.(new Error(
|
|
40
|
+
// Validate file size
|
|
41
|
+
if (file.size > maxFileSizeBytes) {
|
|
42
|
+
const limitMB = Math.round(maxFileSizeBytes / (1024 * 1024));
|
|
43
|
+
onUploadError?.(new Error(`Image size must be less than ${limitMB}MB`));
|
|
42
44
|
return;
|
|
43
45
|
}
|
|
44
46
|
setIsUploading(true);
|
|
@@ -56,13 +58,21 @@ export const ImageUploadButton = ({ onUploadStart, onUploadComplete, onUploadErr
|
|
|
56
58
|
// Upload file
|
|
57
59
|
const formData = new FormData();
|
|
58
60
|
formData.append('file', file);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
// Scale timeout with file size: 30s base + 10s per MB
|
|
62
|
+
const timeoutMs = 30_000 + Math.ceil(file.size / (1024 * 1024)) * 10_000;
|
|
63
|
+
const controller = new AbortController();
|
|
64
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
65
|
+
let response;
|
|
66
|
+
try {
|
|
67
|
+
response = await fetch(uploadEndpoint, {
|
|
68
|
+
method: 'POST',
|
|
69
|
+
body: formData,
|
|
70
|
+
signal: controller.signal,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
clearTimeout(timeoutId);
|
|
75
|
+
}
|
|
66
76
|
if (!response.ok) {
|
|
67
77
|
throw new Error(`Upload failed: ${response.statusText}`);
|
|
68
78
|
}
|
|
@@ -82,8 +92,13 @@ export const ImageUploadButton = ({ onUploadStart, onUploadComplete, onUploadErr
|
|
|
82
92
|
onUploadComplete?.(imageUrl);
|
|
83
93
|
}
|
|
84
94
|
catch (error) {
|
|
85
|
-
|
|
86
|
-
|
|
95
|
+
const uploadError = error instanceof DOMException && error.name === 'AbortError'
|
|
96
|
+
? new Error('Upload timed out')
|
|
97
|
+
: error instanceof Error
|
|
98
|
+
? error
|
|
99
|
+
: new Error('Upload failed');
|
|
100
|
+
logger.error('Image upload error', { error: uploadError });
|
|
101
|
+
onUploadError?.(uploadError);
|
|
87
102
|
}
|
|
88
103
|
finally {
|
|
89
104
|
setIsUploading(false);
|
|
@@ -92,7 +107,7 @@ export const ImageUploadButton = ({ onUploadStart, onUploadComplete, onUploadErr
|
|
|
92
107
|
fileInputRef.current.value = '';
|
|
93
108
|
}
|
|
94
109
|
}
|
|
95
|
-
}, [editor, uploadEndpoint, onUploadStart, onUploadComplete, onUploadError]);
|
|
110
|
+
}, [editor, uploadEndpoint, maxFileSizeBytes, onUploadStart, onUploadComplete, onUploadError]);
|
|
96
111
|
const triggerFileSelect = useCallback(() => {
|
|
97
112
|
fileInputRef.current?.click();
|
|
98
113
|
}, []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/richtext/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/richtext/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAEtE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE/E,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,YAAY,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAI3E,eAAO,MAAM,iBAAiB,YAAa,CAAC;AAC5C,eAAO,MAAM,mBAAmB,YAAa,CAAC;AAC9C,eAAO,MAAM,sBAAsB,YAAa,CAAC;AACjD,eAAO,MAAM,0BAA0B,YAAa,CAAC;AACrD,eAAO,MAAM,sBAAsB,YAAa,CAAC;AACjD,eAAO,MAAM,wBAAwB,YAAa,CAAC;AACnD,eAAO,MAAM,uBAAuB,YAAa,CAAC;AAElD,eAAO,MAAM,oBAAoB,YAAa,CAAC;AAC/C,eAAO,MAAM,sBAAsB,YAAa,CAAC;AACjD,eAAO,MAAM,kBAAkB,YAAa,CAAC;AAC7C,eAAO,MAAM,mBAAmB,YAAa,CAAC;AAE9C,eAAO,MAAM,0BAA0B,YAAa,CAAC;AACrD,eAAO,MAAM,wBAAwB,YAAa,CAAC;AACnD,eAAO,MAAM,sBAAsB,YAAa,CAAC;AAEjD,eAAO,MAAM,iBAAiB,YAAa,CAAC;AAC5C,eAAO,MAAM,yBAAyB,YAAa,CAAC;AACpD,eAAO,MAAM,uBAAuB,YAAa,CAAC;AAClD,eAAO,MAAM,mBAAmB,YAAa,CAAC;AAC9C,eAAO,MAAM,2BAA2B,YAAa,CAAC;AAEtD,eAAO,MAAM,0BAA0B,YAAa,CAAC;AACrD,eAAO,MAAM,yBAAyB,YAAa,CAAC;AACpD,eAAO,MAAM,qBAAqB,YAAa,CAAC;AAChD,eAAO,MAAM,mBAAmB,YAAa,CAAC;AAG9C,eAAO,MAAM,4BAA4B,GAAI,OAAO,OAAO,EAAE;;CAAgB,CAAC;AAC9E,eAAO,MAAM,gCAAgC,GAAI,OAAO,OAAO,EAAE;;CAE/D,CAAC;AAGH,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,KAAK,CAAC;QAEd,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACxC,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;KACxC,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,YAAY,CAAC,EAAE;QACb,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;KACpB,CAAC;IACF,aAAa,CAAC,EAAE;QACd,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;KACpB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;KACpB,CAAC;CACH;AAED,eAAO,MAAM,mBAAmB,GAAI,QAAQ,mBAAmB,wBAE9D,CAAC;AAGF,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;CACnB;AAGD,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C,MAAM,MAAM,eAAe,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAIvE,OAAO,EACL,kBAAkB,EAClB,KAAK,4BAA4B,GAClC,MAAM,+BAA+B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DecoratorBlockNode.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/nodes/DecoratorBlockNode.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACZ,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"DecoratorBlockNode.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/nodes/DecoratorBlockNode.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACZ,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,MAAM,4BAA4B,CACtC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACzD,MAAM,CACR;IACE,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,CAAC,CAAC;CACX,EACD,qBAAqB,CACtB,CAAC;AAEF,8BAAsB,kBAAkB,CACtC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC3D,SAAQ,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC;IAClC,QAAQ,EAAE,iBAAiB,CAAC;gBAEhB,MAAM,CAAC,EAAE,iBAAiB,EAAE,GAAG,CAAC,EAAE,OAAO;IAKrD,SAAS,IAAI,iBAAiB;IAI9B,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAK1C,UAAU,IAAI,4BAA4B,CAAC,CAAC,CAAC;CAO9C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageNode.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/nodes/ImageNode.tsx"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,OAAO,EACP,MAAM,EACP,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"ImageNode.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/nodes/ImageNode.tsx"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,OAAO,EACP,MAAM,EACP,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,KAAK,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AAQhG,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,MAAM,CACtC;IACE,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,aAAa,CAAC;CACvB,EACD,4BAA4B,CAC7B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,cAAc,CAAC,aAAa,CACxB,CAAC;AAExC,eAAO,MAAM,yBAAyB,EAAE,cAAc,CAAC;IACrD,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAA8C,CAAC;AAEhD,qBAAa,SAAU,SAAQ,kBAAkB;IAC/C,MAAM,EAAE,aAAa,CAAC;gBAEV,EACV,IAAI,EACJ,MAAM,EACN,GAAG,GACJ,EAAE;QACD,IAAI,EAAE,aAAa,CAAC;QACpB,MAAM,CAAC,EAAE,iBAAiB,CAAC;QAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;KACf;IAKD,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS;IAQxC,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,mBAAmB,GAAG,SAAS;IAajE;;OAEG;IACH,QAAQ,IAAI,KAAK,CAAC,YAAY;IAI9B,SAAS,IAAI,eAAe;IAsB5B,UAAU,IAAI,mBAAmB;IASjC,OAAO,IAAI,aAAa;IAIxB,OAAO,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAKlC,cAAc,IAAI,MAAM;CAGzB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,CAM/D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,IAAI,SAAS,CAEpF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CollaborationPlugin.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/plugins/CollaborationPlugin.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"CollaborationPlugin.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/plugins/CollaborationPlugin.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE/B,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,QAAQ,CAAC;IACvE,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,EAClC,EAAE,EACF,eAAe,EACf,eAAe,EACf,QAAQ,EACR,WAAW,EACX,UAAoB,EACpB,UAAU,GACX,EAAE,wBAAwB,2CAiB1B"}
|