@ossy/resources 1.12.2 → 1.12.3
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/package.json +11 -3
- package/src/AudioResource.jsx +1 -1
- package/src/CreateDirectory.jsx +2 -10
- package/src/CreateDocument.jsx +2 -2
- package/src/Definition.js +2 -1
- package/src/DocumentEdit.jsx +10 -38
- package/src/DocumentView.jsx +3 -4
- package/src/GenericResourceCard.jsx +25 -7
- package/src/GenericResourceDetail.jsx +6 -60
- package/src/GenericResourceForm.jsx +66 -31
- package/src/ImageResource.jsx +1 -1
- package/src/PDFResource.jsx +1 -1
- package/src/PlatformFileField.jsx +239 -0
- package/src/ResourceContentPage.jsx +3 -3
- package/src/ResourceDescription.jsx +1 -1
- package/src/ResourceDetails.jsx +3 -4
- package/src/ResourceDialogMove.jsx +2 -2
- package/src/ResourceFactory.jsx +11 -64
- package/src/ResourceGenericView.jsx +1 -1
- package/src/ResourceList.jsx +89 -106
- package/src/ResourcePanel.jsx +40 -57
- package/src/ResourceTags.jsx +1 -1
- package/src/ResourcesPage.jsx +26 -35
- package/src/SchemaPresenter.jsx +215 -0
- package/src/Upload.jsx +6 -25
- package/src/UploadResources.jsx +2 -2
- package/src/VideoResource.jsx +1 -1
- package/src/access-filter.spec.js +1 -1
- package/src/create-page-view.action.js +1 -1
- package/src/create-page-view.task.js +10 -9
- package/src/create.action.js +1 -1
- package/src/create.task.js +28 -29
- package/src/delete.action.js +1 -1
- package/src/delete.task.js +10 -13
- package/src/en.translations.json +24 -24
- package/src/get-page-view-stats.action.js +1 -1
- package/src/get-page-view-stats.task.js +3 -4
- package/src/get-resource-alias.api.js +8 -0
- package/src/get-resource-info-alias.api.js +8 -0
- package/src/get-resource-info.api.js +36 -0
- package/src/get-resource-variant.api.js +8 -0
- package/src/get-resource.api.js +51 -0
- package/src/get.action.js +1 -1
- package/src/get.task.js +6 -6
- package/src/index.js +6 -0
- package/src/list.action.js +1 -1
- package/src/list.task.js +1 -1
- package/src/platform-file-field.component.jsx +5 -0
- package/src/platform-image-field.component.jsx +5 -0
- package/src/resource-create.page.jsx +4 -4
- package/src/resource-read.helpers.js +151 -0
- package/src/resource-stream.helpers.js +20 -0
- package/src/resource-stream.js +108 -0
- package/src/resource.helpers.js +9 -9
- package/src/resources.attach-media-urls.js +9 -3
- package/src/resources.events.js +42 -81
- package/src/{resources.spec.js → resources.integration.spec.js} +19 -19
- package/src/resources.queries.js +5 -2
- package/src/search.action.js +1 -1
- package/src/search.task.js +1 -1
- package/src/server.js +2 -1
- package/src/sv.translations.json +24 -24
- package/src/update-access.action.js +1 -1
- package/src/update-access.task.js +9 -8
- package/src/update-content.action.js +1 -1
- package/src/update-content.task.js +25 -27
- package/src/update-location.action.js +1 -1
- package/src/update-location.task.js +9 -8
- package/src/update-name.action.js +1 -1
- package/src/update-name.task.js +9 -8
- package/src/upload-named-version.action.js +1 -1
- package/src/upload-named-version.task.js +16 -22
- package/src/useActivePath.jsx +3 -8
- package/src/useDocumentValidator.js +16 -0
- package/src/useSchemaEngine.js +9 -0
- package/src/useSchemas.js +29 -0
- package/src/useSelectedResourceId.jsx +36 -0
- package/src/ResourceContentPage.stories.jsx +0 -19
- package/src/resource.aggregate.js +0 -86
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ossy/resources",
|
|
3
3
|
"description": "Resource domain — aggregate and events for the Ossy resource model",
|
|
4
|
-
"version": "1.12.
|
|
4
|
+
"version": "1.12.3",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./src/index.js",
|
|
@@ -11,14 +11,22 @@
|
|
|
11
11
|
"./server": "./src/server.js"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
|
-
"test": "NODE_OPTIONS=--experimental-vm-modules jest --verbose"
|
|
14
|
+
"test": "NODE_OPTIONS=--experimental-vm-modules jest --verbose",
|
|
15
|
+
"test:integration": "NODE_OPTIONS=--experimental-vm-modules jest --config jest.integration.config.js --verbose"
|
|
15
16
|
},
|
|
16
17
|
"author": "Ossy <yourfriends@ossy.se> (https://ossy.se)",
|
|
17
18
|
"license": "MIT",
|
|
18
19
|
"ossy": {
|
|
19
20
|
"src": "./src"
|
|
20
21
|
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@ossy/event-store": "^1.8.3",
|
|
24
|
+
"@ossy/fold": "^1.0.1",
|
|
25
|
+
"@ossy/platform": "^1.39.3",
|
|
26
|
+
"@ossy/schema": "^1.0.1"
|
|
27
|
+
},
|
|
21
28
|
"peerDependencies": {
|
|
29
|
+
"@ossy/schema": "*",
|
|
22
30
|
"@ossy/sdk-react": ">=1.0.0",
|
|
23
31
|
"@ossy/workspaces": ">=1.0.0",
|
|
24
32
|
"react": ">=19.0.0 <20.0.0"
|
|
@@ -37,5 +45,5 @@
|
|
|
37
45
|
"/src",
|
|
38
46
|
"README.md"
|
|
39
47
|
],
|
|
40
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "a0d89185a17f8de8ce328c3a648c108ff1d61d8f"
|
|
41
49
|
}
|
package/src/AudioResource.jsx
CHANGED
|
@@ -8,7 +8,7 @@ export const AudioResource = ({
|
|
|
8
8
|
onClose: _onClose
|
|
9
9
|
}) => {
|
|
10
10
|
const sdk = useSdk()
|
|
11
|
-
const { data: resource } = sdk.read(GetResource, {
|
|
11
|
+
const { data: resource } = sdk.read(GetResource, { resourceId }, { enabled: !!resourceId })
|
|
12
12
|
|
|
13
13
|
return (
|
|
14
14
|
<View stack bordered>
|
package/src/CreateDirectory.jsx
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
import React, { useState, useRef } from 'react'
|
|
2
2
|
import { createDirectory } from './resource.helpers.js'
|
|
3
3
|
import { useSdk } from '@ossy/sdk-react'
|
|
4
|
-
import {
|
|
5
|
-
Input,
|
|
6
|
-
Title,
|
|
7
|
-
Button,
|
|
8
|
-
View,
|
|
9
|
-
useInputValue,
|
|
10
|
-
Text,
|
|
11
|
-
useLocale,
|
|
12
|
-
} from '@ossy/design-system'
|
|
4
|
+
import { Input, Button, View, useInputValue, Text, useLocale } from '@ossy/design-system'
|
|
13
5
|
import { useRouter } from '@ossy/router-react'
|
|
14
6
|
|
|
15
7
|
export const CreateDirectory = () => {
|
|
@@ -51,7 +43,7 @@ export const CreateDirectory = () => {
|
|
|
51
43
|
return (
|
|
52
44
|
<View gap="s" style={{ height: '100%' }}>
|
|
53
45
|
|
|
54
|
-
<
|
|
46
|
+
<Text variant="heading-primary" style={{ marginBottom: 'var(--space-m)' }} as="h1" text="resources.createDirectory.title" />
|
|
55
47
|
|
|
56
48
|
<Text style={{ marginBottom: 'var(--space-m)' }}>
|
|
57
49
|
{t('resources.createDirectory.description', { location: directoryLocation })}
|
package/src/CreateDocument.jsx
CHANGED
|
@@ -8,7 +8,7 @@ import { GenericResourceForm } from './GenericResourceForm.jsx'
|
|
|
8
8
|
export const CreateDocument = () => {
|
|
9
9
|
const { t } = useLocale()
|
|
10
10
|
const router = useRouter()
|
|
11
|
-
const
|
|
11
|
+
const schemaId = router.searchParams.schemaId
|
|
12
12
|
const location = router.searchParams.location
|
|
13
13
|
const sdk = useSdk()
|
|
14
14
|
const [error, setError] = useState()
|
|
@@ -27,7 +27,7 @@ export const CreateDocument = () => {
|
|
|
27
27
|
return (
|
|
28
28
|
<>
|
|
29
29
|
<GenericResourceForm
|
|
30
|
-
|
|
30
|
+
schemaId={schemaId}
|
|
31
31
|
mode="create"
|
|
32
32
|
onSubmit={onSubmit}
|
|
33
33
|
onCancel={onCancel}
|
package/src/Definition.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const Definition = {
|
|
2
2
|
id: 'resources',
|
|
3
|
-
title: '
|
|
3
|
+
title: 'Resources',
|
|
4
4
|
description: `
|
|
5
5
|
We believe in providing value at every step of your journey with us.
|
|
6
6
|
That's why we've curated a collection of free resources.
|
|
@@ -10,4 +10,5 @@ export const Definition = {
|
|
|
10
10
|
`,
|
|
11
11
|
icon: 'image',
|
|
12
12
|
statuses: ['beta'],
|
|
13
|
+
entitlementRequired: false,
|
|
13
14
|
}
|
package/src/DocumentEdit.jsx
CHANGED
|
@@ -1,51 +1,23 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { metadata as GetResource } from './get.action.js'
|
|
3
|
-
import { GetWorkspace } from '@ossy/workspaces'
|
|
4
3
|
import { useSdk } from '@ossy/sdk-react'
|
|
5
|
-
import {
|
|
6
|
-
Text,
|
|
7
|
-
View,
|
|
8
|
-
DelayedRender,
|
|
9
|
-
Fields,
|
|
10
|
-
} from '@ossy/design-system'
|
|
4
|
+
import { GenericResourceForm } from './GenericResourceForm.jsx'
|
|
11
5
|
|
|
6
|
+
/** @deprecated Prefer SchemaPresenter flow="Edit" or GenericResourceForm directly. */
|
|
12
7
|
export const DocumentEdit = ({
|
|
13
8
|
resourceId,
|
|
14
9
|
form,
|
|
15
10
|
}) => {
|
|
16
11
|
const sdk = useSdk()
|
|
17
|
-
const { data: resource } = sdk.read(GetResource, {
|
|
18
|
-
const { data: workspace } = sdk.read(GetWorkspace)
|
|
19
|
-
const template = workspace?.resourceTemplates?.find(t => t.id === resource?.type)
|
|
20
|
-
|
|
21
|
-
if (template?.fields && form.data) {
|
|
22
|
-
return (
|
|
23
|
-
<View style={{ padding: '16px 0' }}>
|
|
24
|
-
<Fields data={form.data} onChange={form.onChange} fields={template.fields} />
|
|
25
|
-
</View>
|
|
26
|
-
)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Loading
|
|
30
|
-
if (template?.fields && !form.data) {
|
|
31
|
-
return (
|
|
32
|
-
<DelayedRender>
|
|
33
|
-
<View style={{ padding: '16px 0' }}>
|
|
34
|
-
Loading...
|
|
35
|
-
</View>
|
|
36
|
-
</DelayedRender>
|
|
37
|
-
)
|
|
38
|
-
}
|
|
12
|
+
const { data: resource } = sdk.read(GetResource, { resourceId }, { enabled: !!resourceId })
|
|
39
13
|
|
|
40
14
|
return (
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
15
|
+
<GenericResourceForm
|
|
16
|
+
schemaId={resource?.type}
|
|
17
|
+
mode="edit"
|
|
18
|
+
resourceId={resourceId}
|
|
19
|
+
resource={resource}
|
|
20
|
+
form={form}
|
|
21
|
+
/>
|
|
48
22
|
)
|
|
49
|
-
|
|
50
|
-
|
|
51
23
|
}
|
package/src/DocumentView.jsx
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { pipe, keys, map } from 'ramda'
|
|
3
3
|
import { metadata as GetResource } from './get.action.js'
|
|
4
|
-
import { GetWorkspace } from '@ossy/workspaces'
|
|
5
4
|
import { useSdk } from '@ossy/sdk-react'
|
|
5
|
+
import { useSchema } from './useSchemas.js'
|
|
6
6
|
import { Text, View } from '@ossy/design-system'
|
|
7
7
|
|
|
8
8
|
export const DocumentView = ({
|
|
9
9
|
resourceId
|
|
10
10
|
}) => {
|
|
11
11
|
const sdk = useSdk()
|
|
12
|
-
const { data: resource } = sdk.read(GetResource, {
|
|
13
|
-
const
|
|
14
|
-
const template = workspace?.resourceTemplates?.find(t => t.id === resource?.type)
|
|
12
|
+
const { data: resource } = sdk.read(GetResource, { resourceId }, { enabled: !!resourceId })
|
|
13
|
+
const template = useSchema(resource?.type)
|
|
15
14
|
|
|
16
15
|
return (
|
|
17
16
|
<View style={{ padding: '16px 0' }}>
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useMemo } from 'react'
|
|
2
2
|
import { metadata as GetResource } from './get.action.js'
|
|
3
3
|
import { useSdk } from '@ossy/sdk-react'
|
|
4
|
-
import {
|
|
4
|
+
import { resolveViewComponentChain } from '@ossy/schema/resolve'
|
|
5
|
+
import { Slot, View, Text, DelayedRender } from '@ossy/design-system'
|
|
5
6
|
|
|
6
7
|
function GenericResourceCardFallback ({ resource }) {
|
|
7
8
|
if (!resource) return null
|
|
8
9
|
return (
|
|
9
10
|
<View surface="secondary" roundness="m" inset="m" gap="xs">
|
|
10
|
-
<
|
|
11
|
+
<Text variant="heading-secondary" as="h2">{resource.name}</Text>
|
|
11
12
|
{resource.content?.description && (
|
|
12
13
|
<Text size="s" color="secondary">{resource.content.description}</Text>
|
|
13
14
|
)}
|
|
@@ -15,11 +16,15 @@ function GenericResourceCardFallback ({ resource }) {
|
|
|
15
16
|
)
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
/** Card-
|
|
19
|
+
/** Card projection for a schema-backed resource — ADR 0006. */
|
|
19
20
|
export function GenericResourceCard ({ resourceId, resource: resourceProp }) {
|
|
20
21
|
const sdk = useSdk()
|
|
21
|
-
const { data: loaded } = sdk.read(GetResource, {
|
|
22
|
+
const { data: loaded } = sdk.read(GetResource, { resourceId }, { enabled: !!resourceId && !resourceProp })
|
|
22
23
|
const resource = resourceProp ?? loaded
|
|
24
|
+
const chain = useMemo(
|
|
25
|
+
() => (resource?.type ? resolveViewComponentChain(resource.type, 'card') : []),
|
|
26
|
+
[resource?.type],
|
|
27
|
+
)
|
|
23
28
|
|
|
24
29
|
if (!resource) {
|
|
25
30
|
return (
|
|
@@ -29,12 +34,25 @@ export function GenericResourceCard ({ resourceId, resource: resourceProp }) {
|
|
|
29
34
|
)
|
|
30
35
|
}
|
|
31
36
|
|
|
37
|
+
const [primary, secondary] = chain
|
|
38
|
+
|
|
32
39
|
return (
|
|
33
40
|
<Slot
|
|
34
|
-
name={
|
|
41
|
+
name={primary}
|
|
35
42
|
resourceId={resourceId}
|
|
36
43
|
resource={resource}
|
|
37
|
-
|
|
44
|
+
schemaId={resource.type}
|
|
45
|
+
projection="card"
|
|
46
|
+
fallback={
|
|
47
|
+
<Slot
|
|
48
|
+
name={secondary}
|
|
49
|
+
resourceId={resourceId}
|
|
50
|
+
resource={resource}
|
|
51
|
+
schemaId={resource.type}
|
|
52
|
+
projection="card"
|
|
53
|
+
fallback={<GenericResourceCardFallback resource={resource} />}
|
|
54
|
+
/>
|
|
55
|
+
}
|
|
38
56
|
/>
|
|
39
57
|
)
|
|
40
58
|
}
|
|
@@ -1,66 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { metadata as GetResource } from './get.action.js'
|
|
3
|
-
import { GetWorkspace } from '@ossy/workspaces'
|
|
4
|
-
import { useSdk } from '@ossy/sdk-react'
|
|
5
|
-
import {
|
|
6
|
-
Slot,
|
|
7
|
-
resourceSlot,
|
|
8
|
-
View,
|
|
9
|
-
Title,
|
|
10
|
-
Text,
|
|
11
|
-
DelayedRender,
|
|
12
|
-
Fields,
|
|
13
|
-
} from '@ossy/design-system'
|
|
14
|
-
import { ResourceGenericView } from './ResourceGenericView.jsx'
|
|
15
|
-
|
|
16
|
-
function GenericResourceDetailFallback ({ resourceId }) {
|
|
17
|
-
const sdk = useSdk()
|
|
18
|
-
const { data: resource } = sdk.read(GetResource, { id: resourceId }, { enabled: !!resourceId })
|
|
19
|
-
const { data: workspace } = sdk.read(GetWorkspace)
|
|
20
|
-
const template = workspace?.resourceTemplates?.find(t => t.id === resource?.type)
|
|
21
|
-
|
|
22
|
-
if (!resource) {
|
|
23
|
-
return (
|
|
24
|
-
<DelayedRender>
|
|
25
|
-
<Text>Loading…</Text>
|
|
26
|
-
</DelayedRender>
|
|
27
|
-
)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (template?.fields?.length) {
|
|
31
|
-
return (
|
|
32
|
-
<View stack gap="m" inset="m">
|
|
33
|
-
<Title>{resource.name}</Title>
|
|
34
|
-
<Fields data={resource.content || {}} fields={template.fields} />
|
|
35
|
-
</View>
|
|
36
|
-
)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return <ResourceGenericView resourceId={resourceId} />
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Generic resource detail host — resolves `resource:{type}/detail` from the slot
|
|
44
|
-
* registry; falls back to template fields or a minimal placeholder.
|
|
45
|
-
*/
|
|
46
|
-
export function GenericResourceDetail ({ resourceId }) {
|
|
47
|
-
const sdk = useSdk()
|
|
48
|
-
const { data: resource } = sdk.read(GetResource, { id: resourceId }, { enabled: !!resourceId })
|
|
49
|
-
|
|
50
|
-
if (!resource) {
|
|
51
|
-
return (
|
|
52
|
-
<DelayedRender>
|
|
53
|
-
<Text>Loading…</Text>
|
|
54
|
-
</DelayedRender>
|
|
55
|
-
)
|
|
56
|
-
}
|
|
1
|
+
import { SchemaPresenter } from './SchemaPresenter.jsx'
|
|
57
2
|
|
|
3
|
+
/** Read view for a schema-backed resource — ADR 0006 component id chain. */
|
|
4
|
+
export function GenericResourceDetail ({ resourceId, projection }) {
|
|
58
5
|
return (
|
|
59
|
-
<
|
|
60
|
-
name={resourceSlot(resource.type, 'detail')}
|
|
6
|
+
<SchemaPresenter
|
|
61
7
|
resourceId={resourceId}
|
|
62
|
-
|
|
63
|
-
|
|
8
|
+
flow="View"
|
|
9
|
+
projection={projection}
|
|
64
10
|
/>
|
|
65
11
|
)
|
|
66
12
|
}
|
|
@@ -1,24 +1,14 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
View,
|
|
8
|
-
Title,
|
|
9
|
-
Text,
|
|
10
|
-
InputTitle,
|
|
11
|
-
Button,
|
|
12
|
-
Alert,
|
|
13
|
-
Fields,
|
|
14
|
-
applyFieldChange,
|
|
15
|
-
useInputValue,
|
|
16
|
-
useLocale,
|
|
17
|
-
} from '@ossy/design-system'
|
|
2
|
+
import { useSchema } from './useSchemas.js'
|
|
3
|
+
import { useSchemaEngine } from './useSchemaEngine.js'
|
|
4
|
+
import { validateContent } from '@ossy/schema'
|
|
5
|
+
import { resolveFormComponentId } from '@ossy/schema/resolve'
|
|
6
|
+
import { Slot, View, Text, InputTitle, Button, Alert, Fields, applyFieldChange, useInputValue, useLocale, DelayedRender } from '@ossy/design-system'
|
|
18
7
|
|
|
19
8
|
function GenericResourceFormFallback ({
|
|
20
|
-
|
|
9
|
+
schemaId,
|
|
21
10
|
mode = 'create',
|
|
11
|
+
form,
|
|
22
12
|
initialName = '',
|
|
23
13
|
initialContent = {},
|
|
24
14
|
onSubmit,
|
|
@@ -26,20 +16,59 @@ function GenericResourceFormFallback ({
|
|
|
26
16
|
submitLabel,
|
|
27
17
|
}) {
|
|
28
18
|
const { t } = useLocale()
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const template = workspace?.resourceTemplates?.find(t => t.id === templateId)
|
|
19
|
+
const template = useSchema(schemaId)
|
|
20
|
+
const engine = useSchemaEngine()
|
|
32
21
|
const [name, setName] = useInputValue(initialName)
|
|
33
22
|
const [content, setContent] = useState(initialContent)
|
|
34
23
|
const [error, setError] = useState()
|
|
35
24
|
|
|
25
|
+
if (form && mode === 'edit') {
|
|
26
|
+
if (template?.fields && form.data) {
|
|
27
|
+
return (
|
|
28
|
+
<View style={{ padding: '16px 0' }}>
|
|
29
|
+
<Fields data={form.data} onChange={form.onChange} fields={template.fields} />
|
|
30
|
+
</View>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (template?.fields && !form.data) {
|
|
35
|
+
return (
|
|
36
|
+
<DelayedRender>
|
|
37
|
+
<View style={{ padding: '16px 0' }}>
|
|
38
|
+
<Text>Loading...</Text>
|
|
39
|
+
</View>
|
|
40
|
+
</DelayedRender>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<View style={{ padding: '16px 0' }}>
|
|
46
|
+
<View inset="m">
|
|
47
|
+
<Text>
|
|
48
|
+
This documents template has been deleted and can therefore not be edited
|
|
49
|
+
</Text>
|
|
50
|
+
</View>
|
|
51
|
+
</View>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
36
55
|
const handleSubmit = () => {
|
|
37
56
|
if (!name?.trim()) {
|
|
38
57
|
setError(t('resources.form.nameRequired'))
|
|
39
58
|
return
|
|
40
59
|
}
|
|
60
|
+
if (template) {
|
|
61
|
+
const result = validateContent(engine, template, content)
|
|
62
|
+
if (!result.ok) {
|
|
63
|
+
setError(result.message)
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
setError(undefined)
|
|
67
|
+
onSubmit?.({ name: name.trim(), content: result.data, type: schemaId })
|
|
68
|
+
return
|
|
69
|
+
}
|
|
41
70
|
setError(undefined)
|
|
42
|
-
onSubmit?.({ name: name.trim(), content, type:
|
|
71
|
+
onSubmit?.({ name: name.trim(), content, type: schemaId })
|
|
43
72
|
}
|
|
44
73
|
|
|
45
74
|
return (
|
|
@@ -53,12 +82,15 @@ function GenericResourceFormFallback ({
|
|
|
53
82
|
/>
|
|
54
83
|
<Fields
|
|
55
84
|
data={content}
|
|
56
|
-
onChange={(event) =>
|
|
85
|
+
onChange={(event) => {
|
|
86
|
+
setError(undefined)
|
|
87
|
+
setContent((prev) => applyFieldChange(prev, event))
|
|
88
|
+
}}
|
|
57
89
|
fields={template?.fields || []}
|
|
58
90
|
/>
|
|
59
|
-
{error && <Alert>{error}</Alert>}
|
|
91
|
+
{error && <Alert variant="danger">{error}</Alert>}
|
|
60
92
|
<View layout="row" gap="s" justifyContent="flex-end">
|
|
61
|
-
{onCancel && <Button variant="link" onClick={onCancel}
|
|
93
|
+
{onCancel && <Button variant="link" onClick={onCancel} label="design-system.cancel" />}
|
|
62
94
|
<Button variant="cta" onClick={handleSubmit}>
|
|
63
95
|
{submitLabel || (mode === 'edit' ? t('design-system.save') : (template?.name ? `${t('design-system.add')} ${template.name}` : t('resources.form.createResource')))}
|
|
64
96
|
</Button>
|
|
@@ -68,14 +100,15 @@ function GenericResourceFormFallback ({
|
|
|
68
100
|
}
|
|
69
101
|
|
|
70
102
|
/**
|
|
71
|
-
* Generic resource create/edit host — resolves
|
|
103
|
+
* Generic resource create/edit host — resolves `@ossy/…/form/{concept}` via
|
|
72
104
|
* slot registry; falls back to template-driven Fields.
|
|
73
105
|
*/
|
|
74
106
|
export function GenericResourceForm ({
|
|
75
|
-
|
|
107
|
+
schemaId,
|
|
76
108
|
mode = 'create',
|
|
77
109
|
resourceId,
|
|
78
110
|
resource,
|
|
111
|
+
form,
|
|
79
112
|
initialName,
|
|
80
113
|
initialContent,
|
|
81
114
|
onSubmit,
|
|
@@ -84,23 +117,25 @@ export function GenericResourceForm ({
|
|
|
84
117
|
}) {
|
|
85
118
|
const { t } = useLocale()
|
|
86
119
|
|
|
87
|
-
if (!
|
|
88
|
-
return <Text
|
|
120
|
+
if (!schemaId) {
|
|
121
|
+
return <Text text="resources.form.selectType" />
|
|
89
122
|
}
|
|
90
123
|
|
|
91
124
|
return (
|
|
92
125
|
<Slot
|
|
93
|
-
name={
|
|
94
|
-
|
|
126
|
+
name={resolveFormComponentId(schemaId)}
|
|
127
|
+
schemaId={schemaId}
|
|
95
128
|
mode={mode}
|
|
96
129
|
resourceId={resourceId}
|
|
97
130
|
resource={resource}
|
|
131
|
+
form={form}
|
|
98
132
|
onSubmit={onSubmit}
|
|
99
133
|
onCancel={onCancel}
|
|
100
134
|
fallback={
|
|
101
135
|
<GenericResourceFormFallback
|
|
102
|
-
|
|
136
|
+
schemaId={schemaId}
|
|
103
137
|
mode={mode}
|
|
138
|
+
form={form}
|
|
104
139
|
initialName={initialName ?? resource?.name}
|
|
105
140
|
initialContent={initialContent ?? resource?.content ?? {}}
|
|
106
141
|
onSubmit={onSubmit}
|
package/src/ImageResource.jsx
CHANGED
|
@@ -9,7 +9,7 @@ export const ImageResource = ({
|
|
|
9
9
|
resourceId
|
|
10
10
|
}) => {
|
|
11
11
|
const sdk = useSdk()
|
|
12
|
-
const { data: resource } = sdk.read(GetResource, {
|
|
12
|
+
const { data: resource } = sdk.read(GetResource, { resourceId }, { enabled: !!resourceId })
|
|
13
13
|
|
|
14
14
|
return (
|
|
15
15
|
<div style={{ display: 'flex', justifyContent: 'center', padding: 'var(--space-m) var(--space-s) var(--space-xl)' }}>
|
package/src/PDFResource.jsx
CHANGED
|
@@ -7,7 +7,7 @@ export const PDFResource = ({
|
|
|
7
7
|
resourceId
|
|
8
8
|
}) => {
|
|
9
9
|
const sdk = useSdk()
|
|
10
|
-
const { data: resource } = sdk.read(GetResource, {
|
|
10
|
+
const { data: resource } = sdk.read(GetResource, { resourceId }, { enabled: !!resourceId })
|
|
11
11
|
|
|
12
12
|
return (
|
|
13
13
|
<View stack bordered>
|