@aphexcms/cms-core 0.2.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/api-keys.d.ts +37 -0
- package/dist/api/api-keys.d.ts.map +1 -0
- package/dist/api/api-keys.js +20 -0
- package/dist/api/assets.d.ts +27 -0
- package/dist/api/assets.d.ts.map +1 -1
- package/dist/api/assets.js +22 -1
- package/dist/api/index.d.ts +8 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +4 -0
- package/dist/api/instance.d.ts +17 -0
- package/dist/api/instance.d.ts.map +1 -0
- package/dist/api/instance.js +21 -0
- package/dist/api/invitations.d.ts +37 -0
- package/dist/api/invitations.d.ts.map +1 -0
- package/dist/api/invitations.js +27 -0
- package/dist/api/organizations.d.ts +7 -0
- package/dist/api/organizations.d.ts.map +1 -1
- package/dist/api/organizations.js +7 -0
- package/dist/api/types.d.ts +1 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/user.d.ts +23 -0
- package/dist/api/user.d.ts.map +1 -0
- package/dist/api/user.js +20 -0
- package/dist/auth/auth-errors.d.ts +1 -1
- package/dist/auth/auth-errors.d.ts.map +1 -1
- package/dist/auth/auth-hooks.d.ts.map +1 -1
- package/dist/auth/auth-hooks.js +39 -23
- package/dist/auth/provider.d.ts +2 -2
- package/dist/auth/provider.d.ts.map +1 -1
- package/dist/cli/generate-types.d.ts +14 -0
- package/dist/cli/generate-types.d.ts.map +1 -0
- package/dist/cli/generate-types.js +15 -7
- package/dist/cli/generate-types.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +1 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -0
- package/dist/components/AdminApp.svelte +160 -63
- package/dist/components/AdminApp.svelte.d.ts +1 -1
- package/dist/components/AdminApp.svelte.d.ts.map +1 -1
- package/dist/components/admin/AdminLayout.svelte.d.ts +3 -3
- package/dist/components/admin/AssetBrowserModal.svelte +66 -0
- package/dist/components/admin/AssetBrowserModal.svelte.d.ts +15 -0
- package/dist/components/admin/AssetBrowserModal.svelte.d.ts.map +1 -0
- package/dist/components/admin/DocumentEditor.svelte +137 -69
- package/dist/components/admin/DocumentEditor.svelte.d.ts +1 -1
- package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
- package/dist/components/admin/DocumentsSkeleton.svelte +40 -0
- package/dist/components/admin/DocumentsSkeleton.svelte.d.ts +7 -0
- package/dist/components/admin/DocumentsSkeleton.svelte.d.ts.map +1 -0
- package/dist/components/admin/MediaBrowser.svelte +1398 -0
- package/dist/components/admin/MediaBrowser.svelte.d.ts +23 -0
- package/dist/components/admin/MediaBrowser.svelte.d.ts.map +1 -0
- package/dist/components/admin/ObjectModal.svelte +3 -4
- package/dist/components/admin/ObjectModal.svelte.d.ts +1 -1
- package/dist/components/admin/ObjectModal.svelte.d.ts.map +1 -1
- package/dist/components/admin/SchemaField.svelte +109 -81
- package/dist/components/admin/SchemaField.svelte.d.ts +1 -1
- package/dist/components/admin/SchemaField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ArrayField.svelte +611 -277
- package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/DateField.svelte +3 -2
- package/dist/components/admin/fields/DateField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/DateTimeField.svelte +3 -2
- package/dist/components/admin/fields/DateTimeField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ImageField.svelte +217 -120
- package/dist/components/admin/fields/ImageField.svelte.d.ts +1 -0
- package/dist/components/admin/fields/ImageField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ReferenceField.svelte +11 -6
- package/dist/components/admin/fields/ReferenceField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/StringField.svelte +2 -1
- package/dist/components/admin/fields/StringField.svelte.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -0
- package/dist/components/layout/OrganizationSwitcher.svelte +109 -45
- package/dist/components/layout/OrganizationSwitcher.svelte.d.ts.map +1 -1
- package/dist/components/layout/Sidebar.svelte +36 -14
- package/dist/components/layout/Sidebar.svelte.d.ts +2 -1
- package/dist/components/layout/Sidebar.svelte.d.ts.map +1 -1
- package/dist/components/layout/sidebar/AppSidebar.svelte +1 -1
- package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts +8 -1
- package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts.map +1 -1
- package/dist/components/layout/sidebar/NavMain.svelte +1 -1
- package/dist/components/layout/sidebar/NavMain.svelte.d.ts +1 -1
- package/dist/components/layout/sidebar/NavMain.svelte.d.ts.map +1 -1
- package/dist/components/layout/sidebar/NavSecondary.svelte +3 -3
- package/dist/components/layout/sidebar/NavUser.svelte +22 -10
- package/dist/components/layout/sidebar/NavUser.svelte.d.ts +2 -2
- package/dist/components/layout/sidebar/NavUser.svelte.d.ts.map +1 -1
- package/dist/db/interfaces/document.d.ts +20 -0
- package/dist/db/interfaces/document.d.ts.map +1 -1
- package/dist/db/interfaces/index.d.ts +3 -1
- package/dist/db/interfaces/index.d.ts.map +1 -1
- package/dist/db/interfaces/instance.d.ts +7 -0
- package/dist/db/interfaces/instance.d.ts.map +1 -0
- package/dist/db/interfaces/instance.js +1 -0
- package/dist/db/interfaces/organization.d.ts +1 -0
- package/dist/db/interfaces/organization.d.ts.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +4 -3
- package/dist/field-validation/date-utils.d.ts.map +1 -1
- package/dist/field-validation/date-utils.js +12 -11
- package/dist/field-validation/rule.d.ts.map +1 -1
- package/dist/field-validation/rule.js +11 -10
- package/dist/field-validation/utils.d.ts.map +1 -1
- package/dist/field-validation/utils.js +16 -15
- package/dist/graphql/index.d.ts +23 -0
- package/dist/graphql/index.d.ts.map +1 -0
- package/dist/graphql/index.js +85 -0
- package/dist/graphql/resolvers.d.ts +4 -0
- package/dist/graphql/resolvers.d.ts.map +1 -0
- package/dist/graphql/resolvers.js +542 -0
- package/dist/graphql/schema.d.ts +3 -0
- package/dist/graphql/schema.d.ts.map +1 -0
- package/dist/graphql/schema.js +356 -0
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +62 -9
- package/dist/lib/api/api-keys.d.ts +37 -0
- package/dist/lib/api/api-keys.d.ts.map +1 -0
- package/dist/lib/api/api-keys.js +21 -0
- package/dist/lib/api/api-keys.js.map +1 -0
- package/dist/lib/api/assets.d.ts +75 -0
- package/dist/lib/api/assets.d.ts.map +1 -0
- package/dist/lib/api/assets.js +74 -0
- package/dist/lib/api/assets.js.map +1 -0
- package/dist/lib/api/client.d.ts +37 -0
- package/dist/lib/api/client.d.ts.map +1 -0
- package/dist/lib/api/client.js +132 -0
- package/dist/lib/api/client.js.map +1 -0
- package/dist/lib/api/documents.d.ts +57 -0
- package/dist/lib/api/documents.d.ts.map +1 -0
- package/dist/lib/api/documents.js +86 -0
- package/dist/lib/api/documents.js.map +1 -0
- package/dist/lib/api/index.d.ts +15 -0
- package/dist/lib/api/index.d.ts.map +1 -0
- package/dist/lib/api/index.js +10 -0
- package/dist/lib/api/index.js.map +1 -0
- package/dist/lib/api/instance.d.ts +17 -0
- package/dist/lib/api/instance.d.ts.map +1 -0
- package/dist/lib/api/instance.js +22 -0
- package/dist/lib/api/instance.js.map +1 -0
- package/dist/lib/api/invitations.d.ts +37 -0
- package/dist/lib/api/invitations.d.ts.map +1 -0
- package/dist/lib/api/invitations.js +28 -0
- package/dist/lib/api/invitations.js.map +1 -0
- package/dist/lib/api/organizations.d.ts +108 -0
- package/dist/lib/api/organizations.d.ts.map +1 -0
- package/dist/lib/api/organizations.js +100 -0
- package/dist/lib/api/organizations.js.map +1 -0
- package/dist/lib/api/types.d.ts +47 -0
- package/dist/lib/api/types.d.ts.map +1 -0
- package/dist/lib/api/types.js +2 -0
- package/dist/lib/api/types.js.map +1 -0
- package/dist/lib/api/user.d.ts +23 -0
- package/dist/lib/api/user.d.ts.map +1 -0
- package/dist/lib/api/user.js +21 -0
- package/dist/lib/api/user.js.map +1 -0
- package/dist/lib/auth/auth-errors.d.ts +7 -0
- package/dist/lib/auth/auth-errors.d.ts.map +1 -0
- package/dist/lib/auth/auth-errors.js +14 -0
- package/dist/lib/auth/auth-errors.js.map +1 -0
- package/dist/lib/auth/auth-hooks.d.ts +6 -0
- package/dist/lib/auth/auth-hooks.d.ts.map +1 -0
- package/dist/lib/auth/auth-hooks.js +139 -0
- package/dist/lib/auth/auth-hooks.js.map +1 -0
- package/dist/lib/auth/provider.d.ts +17 -0
- package/dist/lib/auth/provider.d.ts.map +1 -0
- package/dist/lib/auth/provider.js +1 -0
- package/dist/lib/auth/provider.js.map +1 -0
- package/dist/lib/client/index.d.ts +24 -0
- package/dist/lib/client/index.d.ts.map +1 -0
- package/dist/lib/client/index.js +33 -0
- package/dist/lib/client/index.js.map +1 -0
- package/dist/lib/components/fields/index.d.ts +9 -0
- package/dist/lib/components/fields/index.d.ts.map +1 -0
- package/dist/lib/components/fields/index.js +10 -0
- package/dist/lib/components/fields/index.js.map +1 -0
- package/dist/lib/components/index.d.ts +8 -0
- package/dist/lib/components/index.d.ts.map +1 -0
- package/dist/lib/components/index.js +14 -0
- package/dist/lib/components/index.js.map +1 -0
- package/dist/lib/config.d.ts +3 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +16 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/db/adapters/index.d.ts +1 -0
- package/dist/lib/db/adapters/index.d.ts.map +1 -0
- package/dist/lib/db/adapters/index.js +5 -0
- package/dist/lib/db/adapters/index.js.map +1 -0
- package/dist/lib/db/index.d.ts +2 -0
- package/dist/lib/db/index.d.ts.map +1 -0
- package/dist/lib/db/index.js +1 -0
- package/dist/lib/db/index.js.map +1 -0
- package/dist/lib/db/interfaces/asset.d.ts +73 -0
- package/dist/lib/db/interfaces/asset.d.ts.map +1 -0
- package/dist/lib/db/interfaces/asset.js +1 -0
- package/dist/lib/db/interfaces/asset.js.map +1 -0
- package/dist/lib/db/interfaces/document.d.ts +79 -0
- package/dist/lib/db/interfaces/document.d.ts.map +1 -0
- package/dist/lib/db/interfaces/document.js +1 -0
- package/dist/lib/db/interfaces/document.js.map +1 -0
- package/dist/lib/db/interfaces/index.d.ts +76 -0
- package/dist/lib/db/interfaces/index.d.ts.map +1 -0
- package/dist/lib/db/interfaces/index.js +1 -0
- package/dist/lib/db/interfaces/index.js.map +1 -0
- package/dist/lib/db/interfaces/instance.d.ts +7 -0
- package/dist/lib/db/interfaces/instance.d.ts.map +1 -0
- package/dist/lib/db/interfaces/instance.js +2 -0
- package/dist/lib/db/interfaces/instance.js.map +1 -0
- package/dist/lib/db/interfaces/organization.d.ts +28 -0
- package/dist/lib/db/interfaces/organization.d.ts.map +1 -0
- package/dist/lib/db/interfaces/organization.js +1 -0
- package/dist/lib/db/interfaces/organization.js.map +1 -0
- package/dist/lib/db/interfaces/schema.d.ts +21 -0
- package/dist/lib/db/interfaces/schema.d.ts.map +1 -0
- package/dist/lib/db/interfaces/schema.js +1 -0
- package/dist/lib/db/interfaces/schema.js.map +1 -0
- package/dist/lib/db/interfaces/user.d.ts +17 -0
- package/dist/lib/db/interfaces/user.d.ts.map +1 -0
- package/dist/lib/db/interfaces/user.js +1 -0
- package/dist/lib/db/interfaces/user.js.map +1 -0
- package/dist/lib/db/utils/reference-resolver.d.ts +18 -0
- package/dist/lib/db/utils/reference-resolver.d.ts.map +1 -0
- package/dist/lib/db/utils/reference-resolver.js +81 -0
- package/dist/lib/db/utils/reference-resolver.js.map +1 -0
- package/dist/lib/define.d.ts +3 -0
- package/dist/lib/define.d.ts.map +1 -0
- package/dist/lib/define.js +5 -0
- package/dist/lib/define.js.map +1 -0
- package/dist/lib/email/index.d.ts +2 -0
- package/dist/lib/email/index.d.ts.map +1 -0
- package/dist/lib/email/index.js +1 -0
- package/dist/lib/email/index.js.map +1 -0
- package/dist/lib/email/interfaces/email.d.ts +42 -0
- package/dist/lib/email/interfaces/email.d.ts.map +1 -0
- package/dist/lib/email/interfaces/email.js +1 -0
- package/dist/lib/email/interfaces/email.js.map +1 -0
- package/dist/lib/engine.d.ts +26 -0
- package/dist/lib/engine.d.ts.map +1 -0
- package/dist/lib/engine.js +71 -0
- package/dist/lib/engine.js.map +1 -0
- package/dist/lib/field-validation/date-utils.d.ts +30 -0
- package/dist/lib/field-validation/date-utils.d.ts.map +1 -0
- package/dist/lib/field-validation/date-utils.js +13 -11
- package/dist/lib/field-validation/date-utils.js.map +1 -0
- package/dist/lib/field-validation/rule.d.ts +55 -0
- package/dist/lib/field-validation/rule.d.ts.map +1 -0
- package/dist/lib/field-validation/rule.js +12 -10
- package/dist/lib/field-validation/rule.js.map +1 -0
- package/dist/lib/field-validation/utils.d.ts +43 -0
- package/dist/lib/field-validation/utils.d.ts.map +1 -0
- package/dist/lib/field-validation/utils.js +17 -15
- package/dist/lib/field-validation/utils.js.map +1 -0
- package/dist/lib/graphql/index.d.ts +23 -0
- package/dist/lib/graphql/index.d.ts.map +1 -0
- package/dist/lib/graphql/index.js +86 -0
- package/dist/lib/graphql/index.js.map +1 -0
- package/dist/lib/graphql/resolvers.d.ts +4 -0
- package/dist/lib/graphql/resolvers.d.ts.map +1 -0
- package/dist/lib/graphql/resolvers.js +543 -0
- package/dist/lib/graphql/resolvers.js.map +1 -0
- package/dist/lib/graphql/schema.d.ts +3 -0
- package/dist/lib/graphql/schema.d.ts.map +1 -0
- package/dist/lib/graphql/schema.js +357 -0
- package/dist/lib/graphql/schema.js.map +1 -0
- package/dist/lib/hooks.d.ts +27 -0
- package/dist/lib/hooks.d.ts.map +1 -0
- package/dist/lib/hooks.js +235 -0
- package/dist/lib/hooks.js.map +1 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +5 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/is-mobile.svelte.d.ts +5 -0
- package/dist/lib/is-mobile.svelte.d.ts.map +1 -0
- package/dist/lib/is-mobile.svelte.js +8 -0
- package/dist/lib/is-mobile.svelte.js.map +1 -0
- package/dist/lib/local-api/auth-helpers.d.ts +65 -0
- package/dist/lib/local-api/auth-helpers.d.ts.map +1 -0
- package/dist/lib/local-api/auth-helpers.js +103 -0
- package/dist/lib/local-api/auth-helpers.js.map +1 -0
- package/dist/lib/local-api/collection-api.d.ts +150 -0
- package/dist/lib/local-api/collection-api.d.ts.map +1 -0
- package/dist/lib/local-api/collection-api.js +311 -0
- package/dist/lib/local-api/collection-api.js.map +1 -0
- package/dist/lib/local-api/index.d.ts +108 -0
- package/dist/lib/local-api/index.d.ts.map +1 -0
- package/dist/lib/local-api/index.js +158 -0
- package/dist/lib/local-api/index.js.map +1 -0
- package/dist/lib/local-api/permissions.d.ts +45 -0
- package/dist/lib/local-api/permissions.d.ts.map +1 -0
- package/dist/lib/local-api/permissions.js +117 -0
- package/dist/lib/local-api/permissions.js.map +1 -0
- package/dist/lib/local-api/types.d.ts +65 -0
- package/dist/lib/local-api/types.d.ts.map +1 -0
- package/dist/lib/local-api/types.js +5 -0
- package/dist/lib/local-api/types.js.map +1 -0
- package/dist/lib/routes/assets-bulk.d.ts +3 -0
- package/dist/lib/routes/assets-bulk.d.ts.map +1 -0
- package/dist/lib/routes/assets-bulk.js +49 -0
- package/dist/lib/routes/assets-bulk.js.map +1 -0
- package/dist/lib/routes/assets-by-id.d.ts +5 -0
- package/dist/lib/routes/assets-by-id.d.ts.map +1 -0
- package/dist/lib/routes/assets-by-id.js +106 -0
- package/dist/lib/routes/assets-by-id.js.map +1 -0
- package/dist/lib/routes/assets-cdn.d.ts +3 -0
- package/dist/lib/routes/assets-cdn.d.ts.map +1 -0
- package/dist/lib/routes/assets-cdn.js +125 -0
- package/dist/lib/routes/assets-cdn.js.map +1 -0
- package/dist/lib/routes/assets-references-counts.d.ts +7 -0
- package/dist/lib/routes/assets-references-counts.d.ts.map +1 -0
- package/dist/lib/routes/assets-references-counts.js +32 -0
- package/dist/lib/routes/assets-references-counts.js.map +1 -0
- package/dist/lib/routes/assets-references.d.ts +7 -0
- package/dist/lib/routes/assets-references.d.ts.map +1 -0
- package/dist/lib/routes/assets-references.js +35 -0
- package/dist/lib/routes/assets-references.js.map +1 -0
- package/dist/lib/routes/assets.d.ts +4 -0
- package/dist/lib/routes/assets.d.ts.map +1 -0
- package/dist/lib/routes/assets.js +121 -0
- package/dist/lib/routes/assets.js.map +1 -0
- package/dist/lib/routes/documents-by-id.d.ts +5 -0
- package/dist/lib/routes/documents-by-id.d.ts.map +1 -0
- package/dist/lib/routes/documents-by-id.js +176 -0
- package/dist/lib/routes/documents-by-id.js.map +1 -0
- package/dist/lib/routes/documents-publish.d.ts +4 -0
- package/dist/lib/routes/documents-publish.d.ts.map +1 -0
- package/dist/lib/routes/documents-publish.js +138 -0
- package/dist/lib/routes/documents-publish.js.map +1 -0
- package/dist/lib/routes/documents-query.d.ts +26 -0
- package/dist/lib/routes/documents-query.d.ts.map +1 -0
- package/dist/lib/routes/documents-query.js +101 -0
- package/dist/lib/routes/documents-query.js.map +1 -0
- package/dist/lib/routes/documents.d.ts +4 -0
- package/dist/lib/routes/documents.d.ts.map +1 -0
- package/dist/lib/routes/documents.js +154 -0
- package/dist/lib/routes/documents.js.map +1 -0
- package/dist/lib/routes/index.d.ts +9 -0
- package/dist/lib/routes/index.d.ts.map +1 -0
- package/dist/lib/routes/index.js +15 -0
- package/dist/lib/routes/index.js.map +1 -0
- package/dist/lib/routes/organizations-by-id.d.ts +5 -0
- package/dist/lib/routes/organizations-by-id.d.ts.map +1 -0
- package/dist/lib/routes/organizations-by-id.js +189 -0
- package/dist/lib/routes/organizations-by-id.js.map +1 -0
- package/dist/lib/routes/organizations-invitations.d.ts +4 -0
- package/dist/lib/routes/organizations-invitations.d.ts.map +1 -0
- package/dist/lib/routes/organizations-invitations.js +127 -0
- package/dist/lib/routes/organizations-invitations.js.map +1 -0
- package/dist/lib/routes/organizations-members.d.ts +5 -0
- package/dist/lib/routes/organizations-members.d.ts.map +1 -0
- package/dist/lib/routes/organizations-members.js +208 -0
- package/dist/lib/routes/organizations-members.js.map +1 -0
- package/dist/lib/routes/organizations-switch.d.ts +3 -0
- package/dist/lib/routes/organizations-switch.d.ts.map +1 -0
- package/dist/lib/routes/organizations-switch.js +55 -0
- package/dist/lib/routes/organizations-switch.js.map +1 -0
- package/dist/lib/routes/organizations.d.ts +4 -0
- package/dist/lib/routes/organizations.d.ts.map +1 -0
- package/dist/lib/routes/organizations.js +111 -0
- package/dist/lib/routes/organizations.js.map +1 -0
- package/dist/lib/routes/schemas-by-type.d.ts +3 -0
- package/dist/lib/routes/schemas-by-type.d.ts.map +1 -0
- package/dist/lib/routes/schemas-by-type.js +27 -0
- package/dist/lib/routes/schemas-by-type.js.map +1 -0
- package/dist/lib/routes/schemas.d.ts +3 -0
- package/dist/lib/routes/schemas.d.ts.map +1 -0
- package/dist/lib/routes/schemas.js +12 -0
- package/dist/lib/routes/schemas.js.map +1 -0
- package/dist/lib/routes/user-preferences.d.ts +4 -0
- package/dist/lib/routes/user-preferences.d.ts.map +1 -0
- package/dist/lib/routes/user-preferences.js +79 -0
- package/dist/lib/routes/user-preferences.js.map +1 -0
- package/dist/lib/routes-exports.d.ts +17 -0
- package/dist/lib/routes-exports.d.ts.map +1 -0
- package/dist/lib/routes-exports.js +23 -0
- package/dist/lib/routes-exports.js.map +1 -0
- package/dist/lib/schema/index.d.ts +6 -0
- package/dist/lib/schema/index.d.ts.map +1 -0
- package/dist/lib/schema/index.js +12 -0
- package/dist/lib/schema/index.js.map +1 -0
- package/dist/lib/schema-context.svelte.d.ts +10 -0
- package/dist/lib/schema-context.svelte.d.ts.map +1 -0
- package/dist/lib/schema-context.svelte.js +19 -0
- package/dist/lib/schema-context.svelte.js.map +1 -0
- package/dist/lib/schema-utils/cleanup.d.ts +21 -0
- package/dist/lib/schema-utils/cleanup.d.ts.map +1 -0
- package/dist/lib/schema-utils/cleanup.js +81 -0
- package/dist/lib/schema-utils/cleanup.js.map +1 -0
- package/dist/lib/schema-utils/index.d.ts +4 -0
- package/dist/lib/schema-utils/index.d.ts.map +1 -0
- package/dist/lib/schema-utils/index.js +5 -0
- package/dist/lib/schema-utils/index.js.map +1 -0
- package/dist/lib/schema-utils/utils.d.ts +34 -0
- package/dist/lib/schema-utils/utils.d.ts.map +1 -0
- package/dist/lib/schema-utils/utils.js +59 -0
- package/dist/lib/schema-utils/utils.js.map +1 -0
- package/dist/lib/schema-utils/validator.d.ts +10 -0
- package/dist/lib/schema-utils/validator.d.ts.map +1 -0
- package/dist/lib/schema-utils/validator.js +167 -0
- package/dist/lib/schema-utils/validator.js.map +1 -0
- package/dist/lib/server/index.d.ts +19 -0
- package/dist/lib/server/index.d.ts.map +1 -0
- package/dist/lib/server/index.js +35 -0
- package/dist/lib/server/index.js.map +1 -0
- package/dist/lib/services/asset-service.d.ts +86 -0
- package/dist/lib/services/asset-service.d.ts.map +1 -0
- package/dist/lib/services/asset-service.js +189 -0
- package/dist/lib/services/asset-service.js.map +1 -0
- package/dist/lib/services/index.d.ts +3 -0
- package/dist/lib/services/index.d.ts.map +1 -0
- package/dist/lib/services/index.js +5 -0
- package/dist/lib/services/index.js.map +1 -0
- package/dist/lib/storage/adapters/index.d.ts +2 -0
- package/dist/lib/storage/adapters/index.d.ts.map +1 -0
- package/dist/lib/storage/adapters/index.js +3 -0
- package/dist/lib/storage/adapters/index.js.map +1 -0
- package/dist/lib/storage/adapters/local-storage-adapter.d.ts +54 -0
- package/dist/lib/storage/adapters/local-storage-adapter.d.ts.map +1 -0
- package/dist/lib/storage/adapters/local-storage-adapter.js +189 -0
- package/dist/lib/storage/adapters/local-storage-adapter.js.map +1 -0
- package/dist/lib/storage/index.d.ts +3 -0
- package/dist/lib/storage/index.d.ts.map +1 -0
- package/dist/lib/storage/index.js +7 -0
- package/dist/lib/storage/index.js.map +1 -0
- package/dist/lib/storage/interfaces/index.d.ts +2 -0
- package/dist/lib/storage/interfaces/index.d.ts.map +1 -0
- package/dist/lib/storage/interfaces/index.js +1 -0
- package/dist/lib/storage/interfaces/index.js.map +1 -0
- package/dist/lib/storage/interfaces/storage.d.ts +91 -0
- package/dist/lib/storage/interfaces/storage.d.ts.map +1 -0
- package/dist/lib/storage/interfaces/storage.js +1 -0
- package/dist/lib/storage/interfaces/storage.js.map +1 -0
- package/dist/lib/storage/providers/storage.d.ts +43 -0
- package/dist/lib/storage/providers/storage.d.ts.map +1 -0
- package/dist/lib/storage/providers/storage.js +65 -0
- package/dist/lib/storage/providers/storage.js.map +1 -0
- package/dist/lib/types/asset.d.ts +73 -0
- package/dist/lib/types/asset.d.ts.map +1 -0
- package/dist/lib/types/asset.js +1 -0
- package/dist/lib/types/asset.js.map +1 -0
- package/dist/lib/types/auth.d.ts +62 -0
- package/dist/lib/types/auth.d.ts.map +1 -0
- package/dist/lib/types/auth.js +7 -5
- package/dist/lib/types/auth.js.map +1 -0
- package/dist/lib/types/config.d.ts +77 -0
- package/dist/lib/types/config.d.ts.map +1 -0
- package/dist/lib/types/config.js +1 -0
- package/dist/lib/types/config.js.map +1 -0
- package/dist/lib/types/document.d.ts +35 -0
- package/dist/lib/types/document.d.ts.map +1 -0
- package/dist/lib/types/document.js +1 -0
- package/dist/lib/types/document.js.map +1 -0
- package/dist/lib/types/filters.d.ts +186 -0
- package/dist/lib/types/filters.d.ts.map +1 -0
- package/dist/lib/types/filters.js +1 -0
- package/dist/lib/types/filters.js.map +1 -0
- package/dist/lib/types/index.d.ts +11 -0
- package/dist/lib/types/index.d.ts.map +1 -0
- package/dist/lib/types/index.js +2 -0
- package/dist/lib/types/index.js.map +1 -0
- package/dist/lib/types/instance.d.ts +5 -0
- package/dist/lib/types/instance.d.ts.map +1 -0
- package/dist/lib/types/instance.js +3 -0
- package/dist/lib/types/instance.js.map +1 -0
- package/dist/lib/types/organization.d.ts +108 -0
- package/dist/lib/types/organization.d.ts.map +1 -0
- package/dist/lib/types/organization.js +1 -0
- package/dist/lib/types/organization.js.map +1 -0
- package/dist/lib/types/schemas.d.ts +179 -0
- package/dist/lib/types/schemas.d.ts.map +1 -0
- package/dist/lib/types/schemas.js +1 -0
- package/dist/lib/types/schemas.js.map +1 -0
- package/dist/lib/types/sidebar.d.ts +34 -0
- package/dist/lib/types/sidebar.d.ts.map +1 -0
- package/dist/lib/types/sidebar.js +1 -0
- package/dist/lib/types/sidebar.js.map +1 -0
- package/dist/lib/types/user.d.ts +14 -0
- package/dist/lib/types/user.d.ts.map +1 -0
- package/dist/lib/types/user.js +1 -0
- package/dist/lib/types/user.js.map +1 -0
- package/dist/lib/utils/asset-actions.d.ts +9 -0
- package/dist/lib/utils/asset-actions.d.ts.map +1 -0
- package/dist/lib/utils/asset-actions.js +28 -0
- package/dist/lib/utils/asset-actions.js.map +1 -0
- package/dist/lib/utils/content-hash.d.ts +22 -0
- package/dist/lib/utils/content-hash.d.ts.map +1 -0
- package/dist/lib/utils/content-hash.js +68 -0
- package/dist/lib/utils/content-hash.js.map +1 -0
- package/dist/lib/utils/default-orderings.d.ts +10 -0
- package/dist/lib/utils/default-orderings.d.ts.map +1 -0
- package/dist/lib/utils/default-orderings.js +64 -0
- package/dist/lib/utils/default-orderings.js.map +1 -0
- package/dist/lib/utils/element-events.d.ts +15 -0
- package/dist/lib/utils/element-events.d.ts.map +1 -0
- package/dist/lib/utils/element-events.js +17 -0
- package/dist/lib/utils/element-events.js.map +1 -0
- package/dist/lib/utils/field-defaults.d.ts +8 -0
- package/dist/lib/utils/field-defaults.d.ts.map +1 -0
- package/dist/lib/utils/field-defaults.js +21 -0
- package/dist/lib/utils/field-defaults.js.map +1 -0
- package/dist/lib/utils/image-url.d.ts +88 -0
- package/dist/lib/utils/image-url.d.ts.map +1 -0
- package/dist/lib/utils/image-url.js +167 -0
- package/dist/lib/utils/image-url.js.map +1 -0
- package/dist/lib/utils/index.d.ts +8 -0
- package/dist/lib/utils/index.d.ts.map +1 -0
- package/dist/lib/utils/index.js +13 -0
- package/dist/lib/utils/index.js.map +1 -0
- package/dist/lib/utils/initial-value-helpers.d.ts +50 -0
- package/dist/lib/utils/initial-value-helpers.d.ts.map +1 -0
- package/dist/lib/utils/initial-value-helpers.js +71 -0
- package/dist/lib/utils/initial-value-helpers.js.map +1 -0
- package/dist/lib/utils/logger.d.ts +9 -0
- package/dist/lib/utils/logger.d.ts.map +1 -0
- package/dist/lib/utils/logger.js +30 -0
- package/dist/lib/utils/logger.js.map +1 -0
- package/dist/lib/utils/slug.d.ts +13 -0
- package/dist/lib/utils/slug.d.ts.map +1 -0
- package/dist/lib/utils/slug.js +31 -0
- package/dist/lib/utils/slug.js.map +1 -0
- package/dist/lib/utils.d.ts +13 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +6 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/local-api/index.d.ts.map +1 -1
- package/dist/local-api/permissions.d.ts.map +1 -1
- package/dist/local-api/permissions.js +3 -4
- package/dist/routes/assets-bulk.d.ts +3 -0
- package/dist/routes/assets-bulk.d.ts.map +1 -0
- package/dist/routes/assets-bulk.js +48 -0
- package/dist/routes/assets-by-id.d.ts.map +1 -1
- package/dist/routes/assets-by-id.js +22 -55
- package/dist/routes/assets-cdn.d.ts.map +1 -1
- package/dist/routes/assets-cdn.js +12 -50
- package/dist/routes/assets-references-counts.d.ts +7 -0
- package/dist/routes/assets-references-counts.d.ts.map +1 -0
- package/dist/routes/assets-references-counts.js +31 -0
- package/dist/routes/assets-references.d.ts +7 -0
- package/dist/routes/assets-references.d.ts.map +1 -0
- package/dist/routes/assets-references.js +34 -0
- package/dist/routes/assets.d.ts.map +1 -1
- package/dist/routes/assets.js +27 -6
- package/dist/routes/documents-by-id.d.ts.map +1 -1
- package/dist/routes/documents-by-id.js +4 -3
- package/dist/routes/documents-publish.d.ts.map +1 -1
- package/dist/routes/documents-publish.js +3 -2
- package/dist/routes/documents-query.d.ts.map +1 -1
- package/dist/routes/documents-query.js +2 -1
- package/dist/routes/documents.d.ts.map +1 -1
- package/dist/routes/documents.js +3 -2
- package/dist/routes/organizations-by-id.d.ts.map +1 -1
- package/dist/routes/organizations-by-id.js +4 -3
- package/dist/routes/organizations-invitations.d.ts.map +1 -1
- package/dist/routes/organizations-invitations.js +5 -4
- package/dist/routes/organizations-members.d.ts.map +1 -1
- package/dist/routes/organizations-members.js +7 -6
- package/dist/routes/organizations-switch.d.ts.map +1 -1
- package/dist/routes/organizations-switch.js +2 -1
- package/dist/routes/organizations.d.ts.map +1 -1
- package/dist/routes/organizations.js +3 -2
- package/dist/routes/schemas-by-type.d.ts.map +1 -1
- package/dist/routes/schemas-by-type.js +3 -2
- package/dist/routes/user-preferences.d.ts.map +1 -1
- package/dist/routes/user-preferences.js +3 -2
- package/dist/routes-exports.d.ts +3 -0
- package/dist/routes-exports.d.ts.map +1 -1
- package/dist/routes-exports.js +3 -0
- package/dist/schema/index.d.ts +6 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +11 -0
- package/dist/schema-utils/validator.d.ts.map +1 -1
- package/dist/schema-utils/validator.js +4 -3
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +4 -0
- package/dist/services/asset-service.d.ts.map +1 -1
- package/dist/services/asset-service.js +8 -7
- package/dist/storage/adapters/local-storage-adapter.d.ts.map +1 -1
- package/dist/storage/adapters/local-storage-adapter.js +5 -4
- package/dist/types/auth.d.ts +13 -1
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/auth.js +6 -5
- package/dist/types/config.d.ts +14 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/document.d.ts +1 -1
- package/dist/types/document.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/instance.d.ts +5 -0
- package/dist/types/instance.d.ts.map +1 -0
- package/dist/types/instance.js +2 -0
- package/dist/types/schemas.d.ts +1 -1
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/sidebar.d.ts +1 -0
- package/dist/types/sidebar.d.ts.map +1 -1
- package/dist/utils/asset-actions.d.ts +9 -0
- package/dist/utils/asset-actions.d.ts.map +1 -0
- package/dist/utils/asset-actions.js +27 -0
- package/dist/utils/element-events.d.ts +15 -0
- package/dist/utils/element-events.d.ts.map +1 -0
- package/dist/utils/element-events.js +16 -0
- package/dist/utils/image-url.d.ts.map +1 -1
- package/dist/utils/image-url.js +10 -9
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +29 -0
- package/package.json +69 -36
|
@@ -11,6 +11,23 @@
|
|
|
11
11
|
import ObjectModal from '../ObjectModal.svelte';
|
|
12
12
|
import ImageField from './ImageField.svelte';
|
|
13
13
|
import { getDefaultValueForFieldType } from '../../../utils/field-defaults';
|
|
14
|
+
import { DragDropProvider } from '@dnd-kit/svelte';
|
|
15
|
+
import { createSortable, isSortable } from '@dnd-kit/svelte/sortable';
|
|
16
|
+
import { arrayMove } from '@dnd-kit/helpers';
|
|
17
|
+
import {
|
|
18
|
+
GripVertical,
|
|
19
|
+
Ellipsis,
|
|
20
|
+
Pencil,
|
|
21
|
+
Trash2,
|
|
22
|
+
FileText,
|
|
23
|
+
Plus,
|
|
24
|
+
Upload,
|
|
25
|
+
Image as ImageIcon
|
|
26
|
+
} from '@lucide/svelte';
|
|
27
|
+
import { assets } from '../../../api/assets';
|
|
28
|
+
import type { ImageValue } from '../../../types/asset';
|
|
29
|
+
import { toast } from 'svelte-sonner';
|
|
30
|
+
import AssetBrowserModal from '../AssetBrowserModal.svelte';
|
|
14
31
|
|
|
15
32
|
interface Props {
|
|
16
33
|
field: ArrayFieldType;
|
|
@@ -18,7 +35,7 @@
|
|
|
18
35
|
onUpdate: (value: any) => void;
|
|
19
36
|
onOpenReference?: (documentId: string, documentType: string) => void;
|
|
20
37
|
readonly?: boolean;
|
|
21
|
-
organizationId?: string;
|
|
38
|
+
organizationId?: string;
|
|
22
39
|
}
|
|
23
40
|
|
|
24
41
|
let {
|
|
@@ -30,19 +47,14 @@
|
|
|
30
47
|
organizationId
|
|
31
48
|
}: Props = $props();
|
|
32
49
|
|
|
33
|
-
// Get schemas from context
|
|
34
50
|
const schemas = getSchemaContext();
|
|
35
51
|
|
|
36
|
-
// Get schema for a type - either from inline definition or registry
|
|
37
52
|
function getSchemaForType(typeName: string): SchemaType | null {
|
|
38
|
-
// First check if this type has an inline definition in field.of
|
|
39
|
-
// Match by name OR type (since inline objects might use either)
|
|
40
53
|
const inlineDef = field.of?.find(
|
|
41
54
|
(ref) => (ref.name && ref.name === typeName) || ref.type === typeName
|
|
42
55
|
);
|
|
43
56
|
|
|
44
57
|
if (inlineDef && inlineDef.fields) {
|
|
45
|
-
// Create a temporary SchemaType from inline definition
|
|
46
58
|
return {
|
|
47
59
|
type: 'object',
|
|
48
60
|
name: inlineDef.name || typeName,
|
|
@@ -51,25 +63,20 @@
|
|
|
51
63
|
};
|
|
52
64
|
}
|
|
53
65
|
|
|
54
|
-
// Otherwise look it up in the schema registry
|
|
55
66
|
return getSchemaByName(schemas, typeName);
|
|
56
67
|
}
|
|
57
68
|
|
|
58
|
-
// Determine if this is a primitive array or object array
|
|
59
|
-
// If the type is not found in schemas AND has no inline fields, it's a primitive type
|
|
60
69
|
const isPrimitiveArray = $derived(
|
|
61
70
|
field.of &&
|
|
62
71
|
field.of.length > 0 &&
|
|
63
72
|
field.of[0]?.type &&
|
|
64
|
-
!field.of[0].fields &&
|
|
65
|
-
!getSchemaByName(schemas, field.of[0].type)
|
|
73
|
+
!field.of[0].fields &&
|
|
74
|
+
!getSchemaByName(schemas, field.of[0].type)
|
|
66
75
|
);
|
|
67
76
|
const primitiveType = $derived(isPrimitiveArray ? field.of?.[0]?.type : null);
|
|
68
|
-
|
|
69
|
-
// Get available types for this array field (for object arrays)
|
|
70
77
|
const availableTypes = $derived(getArrayTypes(schemas, field));
|
|
71
78
|
|
|
72
|
-
// Modal state
|
|
79
|
+
// Modal state
|
|
73
80
|
let modalOpen = $state(false);
|
|
74
81
|
let editingIndex = $state<number | null>(null);
|
|
75
82
|
let editingType = $state<string | null>(null);
|
|
@@ -79,22 +86,117 @@
|
|
|
79
86
|
// Image modal state
|
|
80
87
|
let imageModalOpen = $state(false);
|
|
81
88
|
let imageModalValue = $state<any>(null);
|
|
89
|
+
let imageModalIndex = $state<number | null>(null);
|
|
90
|
+
function handleOpenImageModal(index: number) {
|
|
91
|
+
imageModalIndex = index;
|
|
92
|
+
imageModalValue = arrayValue[index];
|
|
93
|
+
imageModalOpen = true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Text editing modal state
|
|
97
|
+
let textModalOpen = $state(false);
|
|
98
|
+
let textModalIndex = $state<number | null>(null);
|
|
99
|
+
let textModalValue = $state('');
|
|
100
|
+
|
|
101
|
+
function handleOpenTextModal(index: number) {
|
|
102
|
+
textModalIndex = index;
|
|
103
|
+
textModalValue = arrayValue[index] ?? '';
|
|
104
|
+
textModalOpen = true;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function handleTextModalSave() {
|
|
108
|
+
if (textModalIndex !== null) {
|
|
109
|
+
handleUpdatePrimitive(textModalIndex, textModalValue);
|
|
110
|
+
}
|
|
111
|
+
textModalOpen = false;
|
|
112
|
+
textModalIndex = null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function handleTextModalClose() {
|
|
116
|
+
textModalOpen = false;
|
|
117
|
+
textModalIndex = null;
|
|
118
|
+
}
|
|
82
119
|
|
|
83
|
-
// Ensure value is always an array
|
|
84
120
|
const arrayValue = $derived(Array.isArray(value) ? value : []);
|
|
85
121
|
|
|
122
|
+
function generateKey(): string {
|
|
123
|
+
return Math.random().toString(36).substring(2, 9);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Stable key cache for object items that arrive without _key
|
|
127
|
+
const keyCache = new WeakMap<object, string>();
|
|
128
|
+
|
|
129
|
+
// Keyed items — ensures every object item has a _key before rendering
|
|
130
|
+
const keyedItems = $derived.by(() => {
|
|
131
|
+
if (isPrimitiveArray) return arrayValue;
|
|
132
|
+
return arrayValue.map((item: any) => {
|
|
133
|
+
if (item && typeof item === 'object' && !item._key) {
|
|
134
|
+
let cachedKey = keyCache.get(item);
|
|
135
|
+
if (!cachedKey) {
|
|
136
|
+
cachedKey = generateKey();
|
|
137
|
+
keyCache.set(item, cachedKey);
|
|
138
|
+
}
|
|
139
|
+
return { ...item, _key: cachedKey };
|
|
140
|
+
}
|
|
141
|
+
return item;
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Persist generated keys back to parent state
|
|
146
|
+
$effect(() => {
|
|
147
|
+
if (isPrimitiveArray) return;
|
|
148
|
+
const hasUnkeyed = arrayValue.some(
|
|
149
|
+
(item: any) => item && typeof item === 'object' && !item._key
|
|
150
|
+
);
|
|
151
|
+
if (hasUnkeyed) {
|
|
152
|
+
onUpdate(keyedItems);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Key to force DragDropProvider remount after reorder, clearing stale transforms
|
|
157
|
+
let dndKey = $state(0);
|
|
158
|
+
|
|
159
|
+
// Drag-and-drop handler for object arrays
|
|
160
|
+
function handleDragEnd(event: any) {
|
|
161
|
+
const { source } = event.operation;
|
|
162
|
+
if (!source || !isSortable(source)) return;
|
|
163
|
+
|
|
164
|
+
const fromIndex = (source as any).initialIndex as number;
|
|
165
|
+
const toIndex = source.index;
|
|
166
|
+
|
|
167
|
+
if (fromIndex === toIndex) return;
|
|
168
|
+
|
|
169
|
+
const reordered = arrayMove([...keyedItems], fromIndex, toIndex);
|
|
170
|
+
onUpdate(reordered);
|
|
171
|
+
dndKey++;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Drag-and-drop handler for primitive arrays
|
|
175
|
+
function handlePrimitiveDragEnd(event: any) {
|
|
176
|
+
const { source } = event.operation;
|
|
177
|
+
if (!source || !isSortable(source)) return;
|
|
178
|
+
|
|
179
|
+
const fromIndex = (source as any).initialIndex as number;
|
|
180
|
+
const toIndex = source.index;
|
|
181
|
+
|
|
182
|
+
if (fromIndex === toIndex) return;
|
|
183
|
+
|
|
184
|
+
const reordered = arrayMove([...arrayValue], fromIndex, toIndex);
|
|
185
|
+
onUpdate(reordered);
|
|
186
|
+
dndKey++;
|
|
187
|
+
}
|
|
188
|
+
|
|
86
189
|
// Primitive array functions
|
|
87
190
|
function handleAddPrimitive() {
|
|
88
191
|
if (readonly) return;
|
|
89
192
|
|
|
90
|
-
// For images, open the modal
|
|
91
193
|
if (primitiveType === 'image') {
|
|
194
|
+
imageModalIndex = null;
|
|
92
195
|
imageModalValue = null;
|
|
93
196
|
imageModalOpen = true;
|
|
94
197
|
return;
|
|
95
198
|
}
|
|
96
199
|
|
|
97
|
-
// For other primitives, add a new empty item
|
|
98
200
|
const newArray = [...arrayValue];
|
|
99
201
|
const defaultValue = primitiveType === 'boolean' ? false : primitiveType === 'number' ? 0 : '';
|
|
100
202
|
newArray.push(defaultValue);
|
|
@@ -111,39 +213,126 @@
|
|
|
111
213
|
function handleImageModalClose() {
|
|
112
214
|
imageModalOpen = false;
|
|
113
215
|
imageModalValue = null;
|
|
216
|
+
imageModalIndex = null;
|
|
114
217
|
}
|
|
115
218
|
|
|
116
219
|
function handleImageUpload(newValue: any) {
|
|
117
|
-
if (
|
|
118
|
-
//
|
|
220
|
+
if (imageModalIndex !== null) {
|
|
221
|
+
// Editing existing image — update in place (even if null/cleared)
|
|
222
|
+
const newArray = [...arrayValue];
|
|
223
|
+
newArray[imageModalIndex] = newValue;
|
|
224
|
+
imageModalValue = newValue;
|
|
225
|
+
onUpdate(newArray);
|
|
226
|
+
} else if (newValue) {
|
|
227
|
+
// Adding new image
|
|
119
228
|
const newArray = [...arrayValue, newValue];
|
|
120
229
|
onUpdate(newArray);
|
|
121
|
-
// Close
|
|
230
|
+
// Close modal after adding new image
|
|
122
231
|
imageModalOpen = false;
|
|
123
232
|
imageModalValue = null;
|
|
233
|
+
imageModalIndex = null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Multi-image upload for image arrays
|
|
238
|
+
let multiFileInputRef = $state<HTMLInputElement>(null!);
|
|
239
|
+
let isMultiUploading = $state(false);
|
|
240
|
+
let uploadProgress = $state({ current: 0, total: 0 });
|
|
241
|
+
let showArrayAssetBrowser = $state(false);
|
|
242
|
+
|
|
243
|
+
// IDs of assets already in the array (for showing ticks in the browser)
|
|
244
|
+
const existingAssetIds = $derived(
|
|
245
|
+
primitiveType === 'image'
|
|
246
|
+
? new Set(arrayValue.filter((v: any) => v?.asset?._ref).map((v: any) => v.asset._ref))
|
|
247
|
+
: new Set<string>()
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
function openMultiFileDialog() {
|
|
251
|
+
if (readonly) return;
|
|
252
|
+
multiFileInputRef?.click();
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
async function uploadImageFile(file: File): Promise<ImageValue | null> {
|
|
256
|
+
try {
|
|
257
|
+
const formData = new FormData();
|
|
258
|
+
formData.append('file', file);
|
|
259
|
+
if (organizationId) formData.append('organizationId', organizationId);
|
|
260
|
+
|
|
261
|
+
const result = await assets.upload(formData);
|
|
262
|
+
if (!result.success) throw new Error(result.error || 'Upload failed');
|
|
263
|
+
|
|
264
|
+
return {
|
|
265
|
+
_type: 'image',
|
|
266
|
+
_key: generateKey(),
|
|
267
|
+
asset: { _type: 'reference', _ref: result.data!.id }
|
|
268
|
+
};
|
|
269
|
+
} catch (error) {
|
|
270
|
+
toast.error(`Failed to upload ${file.name}`);
|
|
271
|
+
return null;
|
|
124
272
|
}
|
|
125
273
|
}
|
|
126
274
|
|
|
275
|
+
async function handleMultiFileSelect(files: FileList | null) {
|
|
276
|
+
if (readonly || !files || files.length === 0) return;
|
|
277
|
+
|
|
278
|
+
isMultiUploading = true;
|
|
279
|
+
uploadProgress = { current: 0, total: files.length };
|
|
280
|
+
|
|
281
|
+
const newImages: ImageValue[] = [];
|
|
282
|
+
for (const file of Array.from(files)) {
|
|
283
|
+
uploadProgress.current++;
|
|
284
|
+
const imageValue = await uploadImageFile(file);
|
|
285
|
+
if (imageValue) newImages.push(imageValue);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (newImages.length > 0) {
|
|
289
|
+
onUpdate([...arrayValue, ...newImages]);
|
|
290
|
+
toast.success(`Uploaded ${newImages.length} image${newImages.length > 1 ? 's' : ''}`);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
isMultiUploading = false;
|
|
294
|
+
uploadProgress = { current: 0, total: 0 };
|
|
295
|
+
// Reset file input so same files can be re-selected
|
|
296
|
+
if (multiFileInputRef) multiFileInputRef.value = '';
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function handleArrayAssetSelectMultiple(selectedAssets: any[]) {
|
|
300
|
+
const selectedRefIds = new Set(selectedAssets.map((a: any) => a.id));
|
|
301
|
+
|
|
302
|
+
// Keep existing items that are still selected (preserves order & extra data like alt)
|
|
303
|
+
const kept = arrayValue.filter((item: any) => {
|
|
304
|
+
const ref = item?.asset?._ref;
|
|
305
|
+
return ref && selectedRefIds.has(ref);
|
|
306
|
+
});
|
|
307
|
+
const keptIds = new Set(kept.map((item: any) => item.asset._ref));
|
|
308
|
+
|
|
309
|
+
// Add newly selected items
|
|
310
|
+
const added = selectedAssets
|
|
311
|
+
.filter((asset: any) => !keptIds.has(asset.id))
|
|
312
|
+
.map((asset: any) => ({
|
|
313
|
+
_type: 'image' as const,
|
|
314
|
+
_key: generateKey(),
|
|
315
|
+
asset: { _type: 'reference' as const, _ref: asset.id }
|
|
316
|
+
}));
|
|
317
|
+
|
|
318
|
+
onUpdate([...kept, ...added]);
|
|
319
|
+
}
|
|
320
|
+
|
|
127
321
|
// Object array functions
|
|
128
322
|
function handleTypeSelected(selectedType: string) {
|
|
129
323
|
if (readonly || !selectedType) return;
|
|
130
324
|
|
|
131
|
-
// Get the schema for the selected type (inline or from registry)
|
|
132
325
|
const schema = getSchemaForType(selectedType);
|
|
133
326
|
if (!schema) return;
|
|
134
327
|
|
|
135
|
-
|
|
136
|
-
const newItem: Record<string, any> = { _type: selectedType };
|
|
328
|
+
const newItem: Record<string, any> = { _type: selectedType, _key: generateKey() };
|
|
137
329
|
|
|
138
330
|
if (schema.fields) {
|
|
139
331
|
schema.fields.forEach((field) => {
|
|
140
332
|
if ('initialValue' in field && field.initialValue !== undefined) {
|
|
141
|
-
// Only use literal initialValue (skip functions to keep this synchronous)
|
|
142
333
|
if (typeof field.initialValue !== 'function') {
|
|
143
334
|
newItem[field.name] = field.initialValue;
|
|
144
335
|
} else {
|
|
145
|
-
// Function-based initialValues are skipped for nested items
|
|
146
|
-
// They will use field type defaults instead
|
|
147
336
|
newItem[field.name] = getDefaultValueForFieldType(field.type);
|
|
148
337
|
}
|
|
149
338
|
} else {
|
|
@@ -152,8 +341,7 @@
|
|
|
152
341
|
});
|
|
153
342
|
}
|
|
154
343
|
|
|
155
|
-
|
|
156
|
-
editingIndex = arrayValue.length; // New item index
|
|
344
|
+
editingIndex = arrayValue.length;
|
|
157
345
|
editingType = selectedType;
|
|
158
346
|
editingSchema = schema;
|
|
159
347
|
editingValue = newItem;
|
|
@@ -161,7 +349,7 @@
|
|
|
161
349
|
}
|
|
162
350
|
|
|
163
351
|
function handleEditItem(index: number) {
|
|
164
|
-
const item =
|
|
352
|
+
const item = keyedItems[index];
|
|
165
353
|
if (!item._type) return;
|
|
166
354
|
|
|
167
355
|
const schema = getSchemaForType(item._type);
|
|
@@ -172,34 +360,35 @@
|
|
|
172
360
|
editingSchema = schema;
|
|
173
361
|
editingValue = item;
|
|
174
362
|
modalOpen = true;
|
|
175
|
-
console.log('MODAL IS OPEN: ', modalOpen);
|
|
176
363
|
}
|
|
177
364
|
|
|
178
365
|
function handleRemoveItem(index: number) {
|
|
179
366
|
if (readonly) return;
|
|
180
|
-
const newArray =
|
|
367
|
+
const newArray = keyedItems.filter((_: any, i: number) => i !== index);
|
|
181
368
|
onUpdate(newArray);
|
|
182
369
|
}
|
|
183
370
|
|
|
184
371
|
function handleModalSave(editedData: Record<string, any>) {
|
|
185
372
|
if (editingIndex === null || !editingType) return;
|
|
186
373
|
|
|
187
|
-
|
|
188
|
-
|
|
374
|
+
const itemData: Record<string, any> = { ...editedData, _type: editingType };
|
|
375
|
+
// Preserve _key if editing existing item
|
|
376
|
+
if ((editingValue as any)._key) {
|
|
377
|
+
itemData._key = (editingValue as any)._key;
|
|
378
|
+
} else {
|
|
379
|
+
itemData._key = generateKey();
|
|
380
|
+
}
|
|
189
381
|
|
|
190
|
-
const newArray = [...
|
|
382
|
+
const newArray = [...keyedItems];
|
|
191
383
|
|
|
192
384
|
if (editingIndex >= newArray.length) {
|
|
193
|
-
// Adding new item
|
|
194
385
|
newArray.push(itemData);
|
|
195
386
|
} else {
|
|
196
|
-
// Editing existing item
|
|
197
387
|
newArray[editingIndex] = itemData;
|
|
198
388
|
}
|
|
199
389
|
|
|
200
390
|
onUpdate(newArray);
|
|
201
391
|
|
|
202
|
-
// Reset modal state
|
|
203
392
|
modalOpen = false;
|
|
204
393
|
editingIndex = null;
|
|
205
394
|
editingType = null;
|
|
@@ -215,14 +404,12 @@
|
|
|
215
404
|
editingValue = {};
|
|
216
405
|
}
|
|
217
406
|
|
|
218
|
-
// Get the title to display for an item
|
|
219
407
|
function getItemTitle(item: any): string {
|
|
220
408
|
if (!item._type) return 'Unknown Item';
|
|
221
409
|
|
|
222
|
-
const schema =
|
|
410
|
+
const schema = getSchemaForType(item._type);
|
|
223
411
|
if (!schema) return item._type;
|
|
224
412
|
|
|
225
|
-
// Try to find a meaningful field to use as title
|
|
226
413
|
const titleField = item.title || item.heading || item.name || item.label;
|
|
227
414
|
if (titleField && typeof titleField === 'string' && titleField.trim()) {
|
|
228
415
|
return titleField;
|
|
@@ -230,267 +417,350 @@
|
|
|
230
417
|
|
|
231
418
|
return schema.title || item._type;
|
|
232
419
|
}
|
|
420
|
+
|
|
421
|
+
function getItemIcon(item: any): any {
|
|
422
|
+
if (!item._type) return null;
|
|
423
|
+
const schema = getSchemaByName(schemas, item._type);
|
|
424
|
+
return schema?.icon || null;
|
|
425
|
+
}
|
|
233
426
|
</script>
|
|
234
427
|
|
|
235
|
-
|
|
236
|
-
|
|
428
|
+
{#if isPrimitiveArray}
|
|
429
|
+
<!-- Primitive array UI with DnD -->
|
|
430
|
+
{#if arrayValue.length === 0}
|
|
431
|
+
<div
|
|
432
|
+
class="border-border/50 bg-muted/30 flex items-center justify-center rounded border border-dashed p-6"
|
|
433
|
+
>
|
|
434
|
+
<p class="text-muted-foreground text-sm">No items added yet</p>
|
|
435
|
+
</div>
|
|
436
|
+
{:else if primitiveType === 'image'}
|
|
437
|
+
{#key dndKey}
|
|
438
|
+
<DragDropProvider onDragEnd={handlePrimitiveDragEnd}>
|
|
439
|
+
<div class="space-y-1">
|
|
440
|
+
{#each arrayValue as item, index (`prim-${index}`)}
|
|
441
|
+
{@const sortable = createSortable({ id: `prim-${index}`, index, disabled: readonly })}
|
|
442
|
+
<div
|
|
443
|
+
{@attach sortable.attach}
|
|
444
|
+
class="border-border/50 bg-background hover:bg-muted/50 flex h-16 items-center gap-1 rounded border px-1 transition-colors"
|
|
445
|
+
class:opacity-50={sortable.isDragging}
|
|
446
|
+
>
|
|
447
|
+
{#if !readonly}
|
|
448
|
+
<button
|
|
449
|
+
{@attach sortable.attachHandle}
|
|
450
|
+
class="text-muted-foreground hover:text-foreground flex h-8 w-6 cursor-grab items-center justify-center active:cursor-grabbing"
|
|
451
|
+
>
|
|
452
|
+
<GripVertical class="h-4 w-4" />
|
|
453
|
+
</button>
|
|
454
|
+
{/if}
|
|
237
455
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
<!-- Image item in compact mode -->
|
|
252
|
-
<ImageField
|
|
253
|
-
field={{
|
|
254
|
-
...field.of?.[0],
|
|
255
|
-
name: `image-${index}`,
|
|
256
|
-
type: 'image',
|
|
257
|
-
title: `Image ${index + 1}`
|
|
258
|
-
}}
|
|
259
|
-
value={item}
|
|
260
|
-
onUpdate={(newValue) => {
|
|
261
|
-
const newArray = [...arrayValue];
|
|
262
|
-
if (newValue === null) {
|
|
263
|
-
// Remove the image if null
|
|
264
|
-
newArray.splice(index, 1);
|
|
265
|
-
} else {
|
|
266
|
-
newArray[index] = newValue;
|
|
267
|
-
}
|
|
268
|
-
onUpdate(newArray);
|
|
269
|
-
}}
|
|
270
|
-
{readonly}
|
|
271
|
-
compact={true}
|
|
272
|
-
{organizationId}
|
|
273
|
-
/>
|
|
274
|
-
{:else}
|
|
275
|
-
<!-- Always-editable primitive with options menu -->
|
|
276
|
-
<div class="border-border/50 flex items-center gap-2 rounded border p-2">
|
|
277
|
-
<span class="text-muted-foreground text-xs">#{index + 1}</span>
|
|
278
|
-
{#if primitiveType === 'boolean'}
|
|
279
|
-
<div class="flex flex-1 items-center gap-2">
|
|
280
|
-
<Checkbox
|
|
281
|
-
checked={item}
|
|
282
|
-
onCheckedChange={(checked) => handleUpdatePrimitive(index, checked)}
|
|
283
|
-
disabled={readonly}
|
|
284
|
-
/>
|
|
285
|
-
<span class="text-sm">{item ? 'True' : 'False'}</span>
|
|
286
|
-
</div>
|
|
287
|
-
{:else if primitiveType === 'text'}
|
|
288
|
-
<Textarea
|
|
289
|
-
value={item}
|
|
290
|
-
oninput={(e) => handleUpdatePrimitive(index, e.currentTarget.value)}
|
|
291
|
-
{readonly}
|
|
292
|
-
class="flex-1"
|
|
293
|
-
rows={3}
|
|
294
|
-
placeholder="Enter text..."
|
|
295
|
-
/>
|
|
296
|
-
{:else if primitiveType === 'number'}
|
|
297
|
-
<Input
|
|
298
|
-
type="number"
|
|
299
|
-
value={item}
|
|
300
|
-
oninput={(e) =>
|
|
301
|
-
handleUpdatePrimitive(index, parseFloat(e.currentTarget.value) || 0)}
|
|
302
|
-
{readonly}
|
|
303
|
-
class="flex-1"
|
|
304
|
-
placeholder="Enter number..."
|
|
305
|
-
/>
|
|
306
|
-
{:else}
|
|
307
|
-
<Input
|
|
456
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
457
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
458
|
+
<div
|
|
459
|
+
class="min-w-0 flex-1 cursor-pointer text-left"
|
|
460
|
+
onclick={() => handleOpenImageModal(index)}
|
|
461
|
+
>
|
|
462
|
+
<ImageField
|
|
463
|
+
field={{
|
|
464
|
+
...field.of?.[0],
|
|
465
|
+
name: `image-${index}`,
|
|
466
|
+
type: 'image',
|
|
467
|
+
title: `Image ${index + 1}`
|
|
468
|
+
}}
|
|
308
469
|
value={item}
|
|
309
|
-
|
|
470
|
+
onUpdate={() => {}}
|
|
310
471
|
{readonly}
|
|
311
|
-
|
|
312
|
-
|
|
472
|
+
arrayItem={true}
|
|
473
|
+
{organizationId}
|
|
313
474
|
/>
|
|
314
|
-
|
|
475
|
+
</div>
|
|
476
|
+
|
|
315
477
|
{#if !readonly}
|
|
316
478
|
<DropdownMenu.Root>
|
|
317
479
|
<DropdownMenu.Trigger>
|
|
318
|
-
|
|
319
|
-
<
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
</svg>
|
|
327
|
-
</Button>
|
|
480
|
+
{#snippet child({ props })}
|
|
481
|
+
<button
|
|
482
|
+
{...props}
|
|
483
|
+
class="text-muted-foreground hover:text-foreground flex h-8 w-8 shrink-0 items-center justify-center rounded transition-colors hover:bg-transparent"
|
|
484
|
+
>
|
|
485
|
+
<Ellipsis class="h-4 w-4" />
|
|
486
|
+
</button>
|
|
487
|
+
{/snippet}
|
|
328
488
|
</DropdownMenu.Trigger>
|
|
329
489
|
<DropdownMenu.Content align="end">
|
|
330
|
-
<DropdownMenu.Item onclick={() =>
|
|
331
|
-
<
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
490
|
+
<DropdownMenu.Item onclick={() => handleOpenImageModal(index)}>
|
|
491
|
+
<Pencil class="mr-2 h-4 w-4" />
|
|
492
|
+
Edit
|
|
493
|
+
</DropdownMenu.Item>
|
|
494
|
+
<DropdownMenu.Separator />
|
|
495
|
+
<DropdownMenu.Item
|
|
496
|
+
class="text-destructive focus:text-destructive"
|
|
497
|
+
onclick={() => handleRemoveItem(index)}
|
|
498
|
+
>
|
|
499
|
+
<Trash2 class="mr-2 h-4 w-4" />
|
|
500
|
+
Remove
|
|
501
|
+
</DropdownMenu.Item>
|
|
502
|
+
</DropdownMenu.Content>
|
|
503
|
+
</DropdownMenu.Root>
|
|
504
|
+
{/if}
|
|
505
|
+
</div>
|
|
506
|
+
{/each}
|
|
507
|
+
</div>
|
|
508
|
+
</DragDropProvider>
|
|
509
|
+
{/key}
|
|
510
|
+
{:else}
|
|
511
|
+
{#key dndKey}
|
|
512
|
+
<DragDropProvider onDragEnd={handlePrimitiveDragEnd}>
|
|
513
|
+
<div class="space-y-1">
|
|
514
|
+
{#each arrayValue as item, index (`prim-${index}`)}
|
|
515
|
+
{@const sortable = createSortable({ id: `prim-${index}`, index, disabled: readonly })}
|
|
516
|
+
<div
|
|
517
|
+
{@attach sortable.attach}
|
|
518
|
+
class="border-border/50 bg-background hover:bg-muted/50 flex h-10 items-center gap-1 rounded border px-1 transition-colors"
|
|
519
|
+
class:opacity-50={sortable.isDragging}
|
|
520
|
+
>
|
|
521
|
+
{#if !readonly}
|
|
522
|
+
<button
|
|
523
|
+
{@attach sortable.attachHandle}
|
|
524
|
+
class="text-muted-foreground hover:text-foreground flex h-8 w-6 cursor-grab items-center justify-center active:cursor-grabbing"
|
|
525
|
+
>
|
|
526
|
+
<GripVertical class="h-4 w-4" />
|
|
527
|
+
</button>
|
|
528
|
+
{/if}
|
|
529
|
+
|
|
530
|
+
<div class="min-w-0 flex-1">
|
|
531
|
+
{#if primitiveType === 'boolean'}
|
|
532
|
+
<div class="flex items-center gap-2 px-1">
|
|
533
|
+
<Checkbox
|
|
534
|
+
checked={item}
|
|
535
|
+
onCheckedChange={(checked) => handleUpdatePrimitive(index, checked)}
|
|
536
|
+
disabled={readonly}
|
|
537
|
+
/>
|
|
538
|
+
<span class="text-sm">{item ? 'True' : 'False'}</span>
|
|
539
|
+
</div>
|
|
540
|
+
{:else if primitiveType === 'number'}
|
|
541
|
+
<Input
|
|
542
|
+
type="number"
|
|
543
|
+
value={item}
|
|
544
|
+
oninput={(e) =>
|
|
545
|
+
handleUpdatePrimitive(index, parseFloat(e.currentTarget.value) || 0)}
|
|
546
|
+
{readonly}
|
|
547
|
+
class="h-8 w-full border-none bg-transparent shadow-none focus-visible:ring-0"
|
|
548
|
+
placeholder="Enter number..."
|
|
549
|
+
/>
|
|
550
|
+
{:else}
|
|
551
|
+
<Input
|
|
552
|
+
value={item}
|
|
553
|
+
oninput={(e) => handleUpdatePrimitive(index, e.currentTarget.value)}
|
|
554
|
+
{readonly}
|
|
555
|
+
class="h-8 w-full border-none bg-transparent shadow-none focus-visible:ring-0"
|
|
556
|
+
placeholder="Enter value..."
|
|
557
|
+
/>
|
|
558
|
+
{/if}
|
|
559
|
+
</div>
|
|
560
|
+
|
|
561
|
+
{#if !readonly}
|
|
562
|
+
<DropdownMenu.Root>
|
|
563
|
+
<DropdownMenu.Trigger>
|
|
564
|
+
{#snippet child({ props })}
|
|
565
|
+
<button
|
|
566
|
+
{...props}
|
|
567
|
+
class="text-muted-foreground hover:text-foreground flex h-8 w-8 shrink-0 items-center justify-center rounded transition-colors hover:bg-transparent"
|
|
336
568
|
>
|
|
337
|
-
<
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
569
|
+
<Ellipsis class="h-4 w-4" />
|
|
570
|
+
</button>
|
|
571
|
+
{/snippet}
|
|
572
|
+
</DropdownMenu.Trigger>
|
|
573
|
+
<DropdownMenu.Content align="end">
|
|
574
|
+
{#if primitiveType === 'text'}
|
|
575
|
+
<DropdownMenu.Item onclick={() => handleOpenTextModal(index)}>
|
|
576
|
+
<Pencil class="mr-2 h-4 w-4" />
|
|
577
|
+
Edit
|
|
578
|
+
</DropdownMenu.Item>
|
|
579
|
+
<DropdownMenu.Separator />
|
|
580
|
+
{/if}
|
|
581
|
+
<DropdownMenu.Item
|
|
582
|
+
class="text-destructive focus:text-destructive"
|
|
583
|
+
onclick={() => handleRemoveItem(index)}
|
|
584
|
+
>
|
|
585
|
+
<Trash2 class="mr-2 h-4 w-4" />
|
|
344
586
|
Remove
|
|
345
587
|
</DropdownMenu.Item>
|
|
346
588
|
</DropdownMenu.Content>
|
|
347
589
|
</DropdownMenu.Root>
|
|
348
590
|
{/if}
|
|
349
591
|
</div>
|
|
350
|
-
{/
|
|
351
|
-
|
|
352
|
-
</
|
|
353
|
-
{/
|
|
592
|
+
{/each}
|
|
593
|
+
</div>
|
|
594
|
+
</DragDropProvider>
|
|
595
|
+
{/key}
|
|
596
|
+
{/if}
|
|
354
597
|
|
|
355
|
-
|
|
356
|
-
{#if
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
598
|
+
{#if !readonly}
|
|
599
|
+
{#if primitiveType === 'image'}
|
|
600
|
+
<!-- Multi-upload actions for image arrays -->
|
|
601
|
+
<input
|
|
602
|
+
bind:this={multiFileInputRef}
|
|
603
|
+
type="file"
|
|
604
|
+
accept="image/*"
|
|
605
|
+
multiple
|
|
606
|
+
style="display: none"
|
|
607
|
+
onchange={(e) => handleMultiFileSelect(e.currentTarget.files)}
|
|
608
|
+
/>
|
|
609
|
+
{#if isMultiUploading}
|
|
610
|
+
<div
|
|
611
|
+
class="border-border/50 bg-muted/30 flex h-10 w-full items-center justify-center gap-2 rounded border border-dashed text-sm"
|
|
612
|
+
>
|
|
613
|
+
<div
|
|
614
|
+
class="border-primary h-4 w-4 animate-spin rounded-full border-2 border-t-transparent"
|
|
615
|
+
></div>
|
|
616
|
+
<span class="text-muted-foreground"
|
|
617
|
+
>Uploading {uploadProgress.current} of {uploadProgress.total}...</span
|
|
618
|
+
>
|
|
619
|
+
</div>
|
|
620
|
+
{:else}
|
|
621
|
+
<div class="flex gap-2">
|
|
622
|
+
<button
|
|
623
|
+
class="border-border/50 text-muted-foreground hover:text-foreground hover:bg-muted/50 flex h-10 flex-1 items-center justify-center gap-2 rounded border border-dashed text-sm transition-colors"
|
|
624
|
+
onclick={openMultiFileDialog}
|
|
625
|
+
>
|
|
626
|
+
<Upload class="h-4 w-4" />
|
|
627
|
+
Upload images...
|
|
628
|
+
</button>
|
|
629
|
+
<button
|
|
630
|
+
class="border-border/50 text-muted-foreground hover:text-foreground hover:bg-muted/50 flex h-10 flex-1 items-center justify-center gap-2 rounded border border-dashed text-sm transition-colors"
|
|
631
|
+
onclick={() => {
|
|
632
|
+
showArrayAssetBrowser = true;
|
|
633
|
+
}}
|
|
634
|
+
>
|
|
635
|
+
<ImageIcon class="h-4 w-4" />
|
|
636
|
+
Browse media...
|
|
637
|
+
</button>
|
|
638
|
+
</div>
|
|
639
|
+
{/if}
|
|
640
|
+
{:else}
|
|
641
|
+
<button
|
|
642
|
+
class="border-border/50 text-muted-foreground hover:text-foreground hover:bg-muted/50 flex h-10 w-full items-center justify-center gap-2 rounded border border-dashed text-sm transition-colors"
|
|
643
|
+
onclick={handleAddPrimitive}
|
|
644
|
+
>
|
|
645
|
+
<Plus class="h-4 w-4" />
|
|
646
|
+
Add item...
|
|
647
|
+
</button>
|
|
368
648
|
{/if}
|
|
649
|
+
{/if}
|
|
650
|
+
{:else}
|
|
651
|
+
<!-- Object array UI — Sanity-style compact rows with DnD -->
|
|
652
|
+
{#if keyedItems.length === 0}
|
|
653
|
+
<div
|
|
654
|
+
class="border-border/50 bg-muted/30 flex items-center justify-center rounded border border-dashed p-6"
|
|
655
|
+
>
|
|
656
|
+
<p class="text-muted-foreground text-sm">No items added yet</p>
|
|
657
|
+
</div>
|
|
369
658
|
{:else}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
<h5 class="text-sm font-medium">{getItemTitle(item)}</h5>
|
|
386
|
-
{#if item._type}
|
|
387
|
-
<span class="bg-muted rounded px-2 py-1 text-xs">{item._type}</span>
|
|
388
|
-
{/if}
|
|
389
|
-
</div>
|
|
390
|
-
<div class="flex items-center gap-2">
|
|
391
|
-
<Button
|
|
392
|
-
variant="ghost"
|
|
393
|
-
size="sm"
|
|
394
|
-
onclick={() => {
|
|
395
|
-
handleEditItem(index);
|
|
396
|
-
}}
|
|
397
|
-
class="h-8 w-8 p-0"
|
|
398
|
-
title={readonly ? 'View item' : 'Edit item'}
|
|
659
|
+
{#key dndKey}
|
|
660
|
+
<DragDropProvider onDragEnd={handleDragEnd}>
|
|
661
|
+
<div class="space-y-1">
|
|
662
|
+
{#each keyedItems as item, index (item._key)}
|
|
663
|
+
{@const sortable = createSortable({ id: item._key, index, disabled: readonly })}
|
|
664
|
+
<div
|
|
665
|
+
{@attach sortable.attach}
|
|
666
|
+
class="border-border/50 bg-background hover:bg-muted/50 flex h-10 items-center gap-1 rounded border px-1 transition-colors"
|
|
667
|
+
class:opacity-50={sortable.isDragging}
|
|
668
|
+
>
|
|
669
|
+
<!-- Drag handle -->
|
|
670
|
+
{#if !readonly}
|
|
671
|
+
<button
|
|
672
|
+
{@attach sortable.attachHandle}
|
|
673
|
+
class="text-muted-foreground hover:text-foreground flex h-8 w-6 cursor-grab items-center justify-center active:cursor-grabbing"
|
|
399
674
|
>
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
stroke-width="2"
|
|
412
|
-
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
|
|
413
|
-
/>
|
|
414
|
-
</svg>
|
|
415
|
-
{:else}
|
|
416
|
-
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
417
|
-
<path
|
|
418
|
-
stroke-linecap="round"
|
|
419
|
-
stroke-linejoin="round"
|
|
420
|
-
stroke-width="2"
|
|
421
|
-
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
|
|
422
|
-
/>
|
|
423
|
-
</svg>
|
|
424
|
-
{/if}
|
|
425
|
-
</Button>
|
|
426
|
-
|
|
427
|
-
{#if !readonly}
|
|
428
|
-
<Button
|
|
429
|
-
variant="ghost"
|
|
430
|
-
size="sm"
|
|
431
|
-
onclick={() => handleRemoveItem(index)}
|
|
432
|
-
class="text-destructive hover:text-destructive h-8 w-8 p-0"
|
|
433
|
-
title="Remove item"
|
|
434
|
-
>
|
|
435
|
-
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
436
|
-
<path
|
|
437
|
-
stroke-linecap="round"
|
|
438
|
-
stroke-linejoin="round"
|
|
439
|
-
stroke-width="2"
|
|
440
|
-
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
|
|
441
|
-
/>
|
|
442
|
-
</svg>
|
|
443
|
-
</Button>
|
|
675
|
+
<GripVertical class="h-4 w-4" />
|
|
676
|
+
</button>
|
|
677
|
+
{/if}
|
|
678
|
+
|
|
679
|
+
<!-- Type icon -->
|
|
680
|
+
<div class="text-muted-foreground flex h-8 w-8 shrink-0 items-center justify-center">
|
|
681
|
+
{#if getItemIcon(item)}
|
|
682
|
+
{@const Icon = getItemIcon(item)}
|
|
683
|
+
<Icon class="h-4 w-4" />
|
|
684
|
+
{:else}
|
|
685
|
+
<FileText class="h-4 w-4" />
|
|
444
686
|
{/if}
|
|
445
687
|
</div>
|
|
446
|
-
</div>
|
|
447
688
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
689
|
+
<!-- Title (clickable to edit) -->
|
|
690
|
+
<button class="flex-1 truncate text-left text-sm" onclick={() => handleEditItem(index)}>
|
|
691
|
+
{getItemTitle(item)}
|
|
692
|
+
</button>
|
|
693
|
+
|
|
694
|
+
<!-- Context menu -->
|
|
695
|
+
<DropdownMenu.Root>
|
|
696
|
+
<DropdownMenu.Trigger>
|
|
697
|
+
{#snippet child({ props })}
|
|
698
|
+
<button
|
|
699
|
+
{...props}
|
|
700
|
+
class="text-muted-foreground hover:text-foreground flex h-8 w-8 shrink-0 items-center justify-center rounded transition-colors hover:bg-transparent"
|
|
701
|
+
>
|
|
702
|
+
<Ellipsis class="h-4 w-4" />
|
|
703
|
+
</button>
|
|
704
|
+
{/snippet}
|
|
705
|
+
</DropdownMenu.Trigger>
|
|
706
|
+
<DropdownMenu.Content align="end">
|
|
707
|
+
<DropdownMenu.Item onclick={() => handleEditItem(index)}>
|
|
708
|
+
<Pencil class="mr-2 h-4 w-4" />
|
|
709
|
+
{readonly ? 'View' : 'Edit'}
|
|
710
|
+
</DropdownMenu.Item>
|
|
711
|
+
{#if !readonly}
|
|
712
|
+
<DropdownMenu.Separator />
|
|
713
|
+
<DropdownMenu.Item
|
|
714
|
+
class="text-destructive focus:text-destructive"
|
|
715
|
+
onclick={() => handleRemoveItem(index)}
|
|
716
|
+
>
|
|
717
|
+
<Trash2 class="mr-2 h-4 w-4" />
|
|
718
|
+
Remove
|
|
719
|
+
</DropdownMenu.Item>
|
|
720
|
+
{/if}
|
|
721
|
+
</DropdownMenu.Content>
|
|
722
|
+
</DropdownMenu.Root>
|
|
457
723
|
</div>
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
</
|
|
461
|
-
{/
|
|
724
|
+
{/each}
|
|
725
|
+
</div>
|
|
726
|
+
</DragDropProvider>
|
|
727
|
+
{/key}
|
|
728
|
+
{/if}
|
|
462
729
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
730
|
+
<!-- Add item button -->
|
|
731
|
+
{#if !readonly}
|
|
732
|
+
{#if availableTypes.length === 1}
|
|
733
|
+
<button
|
|
734
|
+
class="border-border/50 text-muted-foreground hover:text-foreground hover:bg-muted/50 flex h-10 w-full items-center justify-center gap-2 rounded border border-dashed text-sm transition-colors"
|
|
735
|
+
onclick={() => handleTypeSelected(availableTypes[0]!.name)}
|
|
736
|
+
>
|
|
737
|
+
<Plus class="h-4 w-4" />
|
|
738
|
+
Add item...
|
|
739
|
+
</button>
|
|
740
|
+
{:else}
|
|
741
|
+
<DropdownMenu.Root>
|
|
742
|
+
<DropdownMenu.Trigger>
|
|
743
|
+
{#snippet child({ props })}
|
|
744
|
+
<button
|
|
745
|
+
{...props}
|
|
746
|
+
class="border-border/50 text-muted-foreground hover:text-foreground hover:bg-muted/50 flex h-10 w-full cursor-pointer items-center justify-center gap-2 rounded border border-dashed text-sm transition-colors"
|
|
747
|
+
>
|
|
748
|
+
<Plus class="h-4 w-4" />
|
|
749
|
+
Add item...
|
|
750
|
+
</button>
|
|
751
|
+
{/snippet}
|
|
752
|
+
</DropdownMenu.Trigger>
|
|
753
|
+
<DropdownMenu.Content class="w-56">
|
|
754
|
+
{#each availableTypes as type, index (index)}
|
|
755
|
+
<DropdownMenu.Item onclick={() => handleTypeSelected(type.name)}>
|
|
756
|
+
{type.title}
|
|
757
|
+
</DropdownMenu.Item>
|
|
758
|
+
{/each}
|
|
759
|
+
</DropdownMenu.Content>
|
|
760
|
+
</DropdownMenu.Root>
|
|
491
761
|
{/if}
|
|
492
762
|
{/if}
|
|
493
|
-
|
|
763
|
+
{/if}
|
|
494
764
|
|
|
495
765
|
<!-- Object editing modal -->
|
|
496
766
|
{#if editingSchema}
|
|
@@ -509,7 +779,7 @@
|
|
|
509
779
|
<!-- Image upload modal -->
|
|
510
780
|
{#if imageModalOpen}
|
|
511
781
|
<div
|
|
512
|
-
class="bg-background/80
|
|
782
|
+
class="bg-background/80 fixed top-12 right-0 bottom-0 left-0 z-40 flex items-center justify-center p-6 backdrop-blur-xs sm:absolute sm:top-0 sm:p-4"
|
|
513
783
|
onclick={(e) => {
|
|
514
784
|
if (e.target === e.currentTarget) handleImageModalClose();
|
|
515
785
|
}}
|
|
@@ -519,12 +789,18 @@
|
|
|
519
789
|
role="button"
|
|
520
790
|
tabindex="-1"
|
|
521
791
|
>
|
|
522
|
-
<Card.Root class="flex max-h-[85vh] w-full max-w-2xl flex-col
|
|
792
|
+
<Card.Root class="flex max-h-[85vh] w-full max-w-2xl flex-col shadow-lg">
|
|
523
793
|
<Card.Header class="border-b">
|
|
524
794
|
<div class="flex items-center justify-between">
|
|
525
795
|
<div>
|
|
526
|
-
<Card.Title
|
|
527
|
-
|
|
796
|
+
<Card.Title
|
|
797
|
+
>{imageModalIndex !== null ? 'Edit Image' : `${field.title} - Add Image`}</Card.Title
|
|
798
|
+
>
|
|
799
|
+
<Card.Description
|
|
800
|
+
>{imageModalIndex !== null
|
|
801
|
+
? 'Replace or remove this image'
|
|
802
|
+
: 'Upload a new image to add to the array'}</Card.Description
|
|
803
|
+
>
|
|
528
804
|
</div>
|
|
529
805
|
<Button variant="ghost" size="icon" onclick={handleImageModalClose}>
|
|
530
806
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
@@ -539,7 +815,7 @@
|
|
|
539
815
|
</div>
|
|
540
816
|
</Card.Header>
|
|
541
817
|
|
|
542
|
-
<Card.Content class="flex-1 overflow-
|
|
818
|
+
<Card.Content class="flex-1 overflow-visible">
|
|
543
819
|
<ImageField
|
|
544
820
|
field={{
|
|
545
821
|
...field.of?.[0],
|
|
@@ -555,3 +831,61 @@
|
|
|
555
831
|
</Card.Root>
|
|
556
832
|
</div>
|
|
557
833
|
{/if}
|
|
834
|
+
|
|
835
|
+
<!-- Text editing modal -->
|
|
836
|
+
{#if textModalOpen}
|
|
837
|
+
<div
|
|
838
|
+
class="bg-background/80 fixed top-12 right-0 bottom-0 left-0 z-[100] flex items-center justify-center p-6 backdrop-blur-xs sm:absolute sm:top-0 sm:p-4"
|
|
839
|
+
onclick={(e) => {
|
|
840
|
+
if (e.target === e.currentTarget) handleTextModalClose();
|
|
841
|
+
}}
|
|
842
|
+
onkeydown={(e) => {
|
|
843
|
+
if (e.key === 'Escape') handleTextModalClose();
|
|
844
|
+
}}
|
|
845
|
+
role="button"
|
|
846
|
+
tabindex="-1"
|
|
847
|
+
>
|
|
848
|
+
<Card.Root class="flex max-h-[85vh] w-full max-w-lg flex-col overflow-hidden shadow-lg">
|
|
849
|
+
<Card.Header class="border-b">
|
|
850
|
+
<div class="flex items-center justify-between">
|
|
851
|
+
<Card.Title>Edit Text</Card.Title>
|
|
852
|
+
<Button variant="ghost" size="icon" onclick={handleTextModalClose}>
|
|
853
|
+
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
854
|
+
<path
|
|
855
|
+
stroke-linecap="round"
|
|
856
|
+
stroke-linejoin="round"
|
|
857
|
+
stroke-width="2"
|
|
858
|
+
d="M6 18L18 6M6 6l12 12"
|
|
859
|
+
/>
|
|
860
|
+
</svg>
|
|
861
|
+
</Button>
|
|
862
|
+
</div>
|
|
863
|
+
</Card.Header>
|
|
864
|
+
|
|
865
|
+
<Card.Content class="pt-4">
|
|
866
|
+
<Textarea
|
|
867
|
+
value={textModalValue}
|
|
868
|
+
oninput={(e) => (textModalValue = e.currentTarget.value)}
|
|
869
|
+
class="w-full"
|
|
870
|
+
rows={6}
|
|
871
|
+
placeholder="Enter text..."
|
|
872
|
+
/>
|
|
873
|
+
</Card.Content>
|
|
874
|
+
|
|
875
|
+
<Card.Footer class="flex justify-end gap-2 border-t">
|
|
876
|
+
<Button variant="outline" onclick={handleTextModalClose}>Cancel</Button>
|
|
877
|
+
<Button onclick={handleTextModalSave}>Save</Button>
|
|
878
|
+
</Card.Footer>
|
|
879
|
+
</Card.Root>
|
|
880
|
+
</div>
|
|
881
|
+
{/if}
|
|
882
|
+
|
|
883
|
+
<!-- Asset Browser Modal for image arrays (multi-select) -->
|
|
884
|
+
<AssetBrowserModal
|
|
885
|
+
bind:open={showArrayAssetBrowser}
|
|
886
|
+
onOpenChange={(v) => (showArrayAssetBrowser = v)}
|
|
887
|
+
assetTypeFilter="image"
|
|
888
|
+
multiSelect
|
|
889
|
+
onSelectMultiple={handleArrayAssetSelectMultiple}
|
|
890
|
+
{existingAssetIds}
|
|
891
|
+
/>
|