@ossy/resources 1.12.2 → 3.0.1
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 +16 -4
- package/src/AudioResource.jsx +2 -2
- package/src/CreateDirectory.jsx +2 -10
- package/src/CreateDirectory.page.jsx +1 -1
- package/src/CreateDocument.jsx +2 -2
- package/src/CreateDocument.page.jsx +1 -1
- package/src/Definition.js +3 -2
- package/src/DocumentEdit.jsx +10 -38
- package/src/DocumentView.jsx +11 -22
- package/src/GenericResourceCard.jsx +25 -7
- package/src/GenericResourceDetail.jsx +6 -60
- package/src/GenericResourceForm.jsx +171 -37
- package/src/ImageResource.jsx +1 -1
- package/src/PDFResource.jsx +1 -1
- package/src/PlatformFileField.jsx +239 -0
- package/src/ResourceContentPage.jsx +5 -5
- package/src/ResourceDescription.jsx +1 -1
- package/src/ResourceDetails.jsx +3 -4
- package/src/ResourceDialogMove.jsx +3 -3
- 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/SchemaDetailView.jsx +97 -0
- package/src/SchemaFormDefault.jsx +86 -0
- package/src/SchemaPresenter.jsx +207 -0
- package/src/Upload.jsx +6 -25
- package/src/Upload.page.jsx +1 -1
- 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 +27 -29
- package/src/delete.action.js +1 -1
- package/src/delete.task.js +9 -13
- package/src/en.translations.json +25 -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 +10 -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 +5 -5
- package/src/resource-detail.page.jsx +1 -1
- 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/schema-detail.component.jsx +24 -0
- package/src/schema-form-default.component.jsx +14 -0
- package/src/schemaFormSlots.js +6 -0
- package/src/schemaViewSlots.js +6 -0
- 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 +25 -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
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import { Aggregate } from '@ossy/event-store'
|
|
2
|
-
import { Resource } from './resource.aggregate.js'
|
|
3
1
|
import { ResourcesEvents } from './resources.events.js'
|
|
4
|
-
import {
|
|
2
|
+
import { mutateResource } from './resource-stream.helpers.js'
|
|
3
|
+
import { resolveResourceId } from './resource-read.helpers.js'
|
|
4
|
+
import { derivativeObjectKey } from '@ossy/platform/storage-keys'
|
|
5
5
|
import { mediaContextFromRun, withResourceMedia } from './resources.action-media.js'
|
|
6
6
|
|
|
7
|
-
export const metadata = { id: 'resources/upload-named-version' }
|
|
7
|
+
export const metadata = { id: '@ossy/resources/tasks/upload-named-version' }
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export async function run({ payload, integrations, req }) {
|
|
9
|
+
export async function run ({ payload, integrations, req }) {
|
|
12
10
|
const createdBy = payload?.userId ?? req?.userId
|
|
13
|
-
const
|
|
14
|
-
const resourceId = payload?.resourceId ?? req?.params?.resourceId
|
|
11
|
+
const resourceId = resolveResourceId({ payload, req })
|
|
15
12
|
const namedVersion = payload?.namedVersion ?? req?.params?.namedVersion
|
|
16
13
|
const type = payload?.type
|
|
17
14
|
const size = payload?.size
|
|
@@ -19,26 +16,23 @@ export async function run({ payload, integrations, req }) {
|
|
|
19
16
|
if (!resourceId) throw Object.assign(new Error('resourceId is required'), { status: 400 })
|
|
20
17
|
if (!namedVersion) throw Object.assign(new Error('namedVersion is required'), { status: 400 })
|
|
21
18
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const event = ResourcesEvents.NamedVersionUploaded({
|
|
19
|
+
const event = ResourcesEvents.Patched({
|
|
25
20
|
createdBy,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
content: {
|
|
22
|
+
sizes: { [namedVersion]: derivativeObjectKey(resourceId, namedVersion) },
|
|
23
|
+
ContentLength: size,
|
|
24
|
+
ContentType: type,
|
|
25
|
+
},
|
|
30
26
|
})
|
|
31
27
|
|
|
32
28
|
const storageClient = integrations?.get?.('storage')
|
|
33
29
|
const uploadHeaders = {
|
|
34
|
-
ContentLength:
|
|
35
|
-
ContentType:
|
|
36
|
-
Key:
|
|
30
|
+
ContentLength: size,
|
|
31
|
+
ContentType: type,
|
|
32
|
+
Key: derivativeObjectKey(resourceId, namedVersion),
|
|
37
33
|
}
|
|
38
34
|
const uploadUrl = storageClient ? await storageClient.createUploadUrl(uploadHeaders) : null
|
|
39
|
-
const resource = await
|
|
40
|
-
.then(Aggregate.Add(event))
|
|
41
|
-
.then(Aggregate.View())
|
|
35
|
+
const resource = await mutateResource(resourceId, event)
|
|
42
36
|
const withUpload = uploadUrl
|
|
43
37
|
? { ...resource, content: { ...resource.content, uploadUrl } }
|
|
44
38
|
: resource
|
package/src/useActivePath.jsx
CHANGED
|
@@ -4,20 +4,15 @@ import {
|
|
|
4
4
|
o,
|
|
5
5
|
endsWith
|
|
6
6
|
} from 'ramda'
|
|
7
|
-
import {
|
|
8
|
-
import React, { useEffect } from 'react'
|
|
7
|
+
import { useSearchParams } from '@ossy/router-react'
|
|
9
8
|
|
|
10
9
|
const prependSlash = unless(startsWith('/'), path => `/${path}`)
|
|
11
10
|
const appendSlash = unless(endsWith('/'), path => `${path}/`)
|
|
12
11
|
const addSlashes = o(prependSlash, appendSlash)
|
|
13
12
|
|
|
14
13
|
export const useActivePath = () => {
|
|
15
|
-
const
|
|
16
|
-
const activePath = addSlashes(
|
|
17
|
-
|
|
18
|
-
// useEffect(() => {
|
|
19
|
-
// console.log('useActivePath', activePath)
|
|
20
|
-
// }, [activePath])
|
|
14
|
+
const searchParams = useSearchParams()
|
|
15
|
+
const activePath = addSlashes(searchParams.location || '/')
|
|
21
16
|
|
|
22
17
|
return activePath
|
|
23
18
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
import { contentValidator } from '@ossy/schema'
|
|
3
|
+
import { useSchemaEngine } from './useSchemaEngine.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns a Form-compatible validator for a document schema (merged system + workspace).
|
|
7
|
+
*
|
|
8
|
+
* @param {string | object | undefined} schema
|
|
9
|
+
*/
|
|
10
|
+
export function useDocumentValidator (schema) {
|
|
11
|
+
const engine = useSchemaEngine()
|
|
12
|
+
return useMemo(() => {
|
|
13
|
+
if (!schema) return undefined
|
|
14
|
+
return contentValidator(engine, schema)
|
|
15
|
+
}, [engine, schema])
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
import { Schema } from '@ossy/schema'
|
|
3
|
+
import { useSchemas } from './useSchemas.js'
|
|
4
|
+
|
|
5
|
+
/** Merged system + workspace schema engine for client-side validation. */
|
|
6
|
+
export function useSchemaEngine () {
|
|
7
|
+
const schemas = useSchemas()
|
|
8
|
+
return useMemo(() => Schema.of({ schemas }), [schemas])
|
|
9
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
import { GetSchemas } from '@ossy/workspaces'
|
|
3
|
+
import { useSdk } from '@ossy/sdk-react'
|
|
4
|
+
|
|
5
|
+
/** Merged system + workspace schemas (see workspaces/actions/get-schemas). */
|
|
6
|
+
export function useSchemas () {
|
|
7
|
+
const sdk = useSdk()
|
|
8
|
+
const { data: schemas = [] } = sdk.read(GetSchemas)
|
|
9
|
+
return schemas
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function useSchemasById () {
|
|
13
|
+
const schemas = useSchemas()
|
|
14
|
+
return useMemo(
|
|
15
|
+
() => schemas.reduce((acc, schema) => {
|
|
16
|
+
acc[schema.id] = schema
|
|
17
|
+
return acc
|
|
18
|
+
}, {}),
|
|
19
|
+
[schemas],
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function useSchema (schemaId) {
|
|
24
|
+
const schemas = useSchemas()
|
|
25
|
+
return useMemo(
|
|
26
|
+
() => schemas.find(s => s.id === schemaId),
|
|
27
|
+
[schemas, schemaId],
|
|
28
|
+
)
|
|
29
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react'
|
|
2
|
+
import { useSearchParams } from '@ossy/router-react'
|
|
3
|
+
|
|
4
|
+
export const RESOURCE_QUERY_PARAM = 'r'
|
|
5
|
+
export const RESOURCE_QUERY_PARAM_ALT = 'resourceId'
|
|
6
|
+
|
|
7
|
+
export const useSelectedResourceId = () => {
|
|
8
|
+
const searchParams = useSearchParams()
|
|
9
|
+
|
|
10
|
+
const selectedResourceId =
|
|
11
|
+
searchParams[RESOURCE_QUERY_PARAM] ||
|
|
12
|
+
searchParams[RESOURCE_QUERY_PARAM_ALT] ||
|
|
13
|
+
undefined
|
|
14
|
+
|
|
15
|
+
const setSelectedResourceId = useCallback((resourceId) => {
|
|
16
|
+
if (resourceId) {
|
|
17
|
+
searchParams.set(RESOURCE_QUERY_PARAM, resourceId)
|
|
18
|
+
searchParams.delete(RESOURCE_QUERY_PARAM_ALT)
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
searchParams.delete(RESOURCE_QUERY_PARAM)
|
|
23
|
+
searchParams.delete(RESOURCE_QUERY_PARAM_ALT)
|
|
24
|
+
}, [searchParams.set, searchParams.delete])
|
|
25
|
+
|
|
26
|
+
const clearSelectedResourceId = useCallback(
|
|
27
|
+
() => setSelectedResourceId(undefined),
|
|
28
|
+
[setSelectedResourceId],
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
return useMemo(() => ({
|
|
32
|
+
selectedResourceId,
|
|
33
|
+
setSelectedResourceId,
|
|
34
|
+
clearSelectedResourceId,
|
|
35
|
+
}), [selectedResourceId, setSelectedResourceId, clearSelectedResourceId])
|
|
36
|
+
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { ResourceContentPage } from './ResourceContentPage.jsx'
|
|
3
|
-
|
|
4
|
-
export default {
|
|
5
|
-
title: 'Websites/Ossy/ResourceContentPage',
|
|
6
|
-
component: ResourceContentPage,
|
|
7
|
-
parameters: {
|
|
8
|
-
layout: 'fullscreen',
|
|
9
|
-
workspaceId: '36zDqF0TKZZ5KkJdyg7NH',
|
|
10
|
-
params: {
|
|
11
|
-
resourceId: 'yBa6GdMeHg2EQr-u5xDd3'
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const Story = props => <ResourceContentPage {...props}/>
|
|
17
|
-
|
|
18
|
-
export const Default = Story.bind({})
|
|
19
|
-
Default.args = { }
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
export class Resource {
|
|
2
|
-
|
|
3
|
-
static AggregateType = 'Resource'
|
|
4
|
-
|
|
5
|
-
static View(events, savedState = {}) {
|
|
6
|
-
return events.reduce((resource, event) => {
|
|
7
|
-
switch (event.type) {
|
|
8
|
-
|
|
9
|
-
case 'Created': {
|
|
10
|
-
const content = event?.payload?.content || {}
|
|
11
|
-
|
|
12
|
-
return {
|
|
13
|
-
...resource,
|
|
14
|
-
id: event.aggregateId,
|
|
15
|
-
name: event.payload.name,
|
|
16
|
-
location: event.payload.location,
|
|
17
|
-
belongsTo: event.payload.belongsTo,
|
|
18
|
-
type: event.payload.type,
|
|
19
|
-
createdBy: event.createdBy,
|
|
20
|
-
created: event.created,
|
|
21
|
-
lastUpdated: event.created,
|
|
22
|
-
content: content,
|
|
23
|
-
access: event.payload.access || 'restricted',
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
case 'NameUpdated':
|
|
28
|
-
return {
|
|
29
|
-
...resource,
|
|
30
|
-
lastUpdated: event.created,
|
|
31
|
-
name: event.payload.name
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
case 'LocationUpdated':
|
|
35
|
-
return {
|
|
36
|
-
...resource,
|
|
37
|
-
lastUpdated: event.created,
|
|
38
|
-
location: event.payload.location
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
case 'ContentUpdated':
|
|
42
|
-
return {
|
|
43
|
-
...resource,
|
|
44
|
-
lastUpdated: event.created,
|
|
45
|
-
content: event.payload.content
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
case 'AccessUpdated':
|
|
49
|
-
return {
|
|
50
|
-
...resource,
|
|
51
|
-
lastUpdated: event.created,
|
|
52
|
-
access: event.payload.access
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
case 'NamedVersionUploaded': {
|
|
56
|
-
const mediaKey = event.payload.Key
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
...resource,
|
|
60
|
-
lastUpdated: event.created,
|
|
61
|
-
content: {
|
|
62
|
-
...resource.content,
|
|
63
|
-
sizes: {
|
|
64
|
-
...(resource.content.sizes || {}),
|
|
65
|
-
[event.payload.namedVersion]: mediaKey
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
case 'Deleted':
|
|
72
|
-
return {
|
|
73
|
-
status: ['removed'],
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
default:
|
|
77
|
-
return resource
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
}, savedState)
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export { Resource as Aggregate }
|
|
86
|
-
export const id = 'Resource'
|