@ossy/resources 1.11.6 → 1.12.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/package.json +3 -3
- package/src/AudioResource.jsx +5 -5
- package/src/CreateDirectory.jsx +10 -10
- package/src/CreateDocument.jsx +14 -50
- package/src/Definition.js +2 -8
- package/src/GenericResourceCard.jsx +38 -0
- package/src/GenericResourceDetail.jsx +61 -0
- package/src/GenericResourceForm.jsx +110 -0
- package/src/ImageResource.jsx +0 -1
- package/src/PDFResource.jsx +9 -9
- package/src/ResourceContentPage.jsx +1 -1
- package/src/ResourceFactory.jsx +7 -3
- package/src/ResourceGenericView.jsx +10 -11
- package/src/ResourceList.jsx +4 -4
- package/src/ResourcePanel.jsx +14 -15
- package/src/ResourcesPage.jsx +4 -4
- package/src/Upload.jsx +4 -4
- package/src/UploadResources.jsx +5 -8
- package/src/VideoResource.jsx +5 -5
- package/src/en.translations.json +48 -0
- package/src/index.js +3 -0
- package/src/resource-create.page.jsx +48 -0
- package/src/resource-detail.page.jsx +25 -0
- package/src/sv.translations.json +48 -0
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.
|
|
4
|
+
"version": "1.12.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./src/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@jest/globals": "^30.2.0",
|
|
22
|
-
"@ossy/platform": "^1.
|
|
22
|
+
"@ossy/platform": "^1.39.0",
|
|
23
23
|
"casual": "^1.6.2",
|
|
24
24
|
"jest": "^30.2.0"
|
|
25
25
|
},
|
|
@@ -31,5 +31,5 @@
|
|
|
31
31
|
"/src",
|
|
32
32
|
"README.md"
|
|
33
33
|
],
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "d9d31182be64a448d575da432af2830d909ad4b9"
|
|
35
35
|
}
|
package/src/AudioResource.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { useResource } from '@ossy/sdk-react'
|
|
3
|
-
import {
|
|
3
|
+
import { View } from '@ossy/design-system'
|
|
4
4
|
|
|
5
5
|
export const AudioResource = ({
|
|
6
6
|
resourceId,
|
|
@@ -9,8 +9,8 @@ export const AudioResource = ({
|
|
|
9
9
|
const { resource } = useResource(resourceId)
|
|
10
10
|
|
|
11
11
|
return (
|
|
12
|
-
<
|
|
13
|
-
<
|
|
12
|
+
<View stack bordered>
|
|
13
|
+
<View.Item fill style={{ padding: '16px 8px', height: '100%' }}>
|
|
14
14
|
|
|
15
15
|
<View layout="off-center-s" inset="m" style={{ height: '100%'}}>
|
|
16
16
|
<View
|
|
@@ -21,7 +21,7 @@ export const AudioResource = ({
|
|
|
21
21
|
/>
|
|
22
22
|
</View>
|
|
23
23
|
|
|
24
|
-
</
|
|
25
|
-
</
|
|
24
|
+
</View.Item>
|
|
25
|
+
</View>
|
|
26
26
|
)
|
|
27
27
|
}
|
package/src/CreateDirectory.jsx
CHANGED
|
@@ -6,11 +6,13 @@ import {
|
|
|
6
6
|
Button,
|
|
7
7
|
View,
|
|
8
8
|
useInputValue,
|
|
9
|
-
Text
|
|
9
|
+
Text,
|
|
10
|
+
useLocale,
|
|
10
11
|
} from '@ossy/design-system'
|
|
11
12
|
import { useRouter } from '@ossy/router-react'
|
|
12
13
|
|
|
13
14
|
export const CreateDirectory = () => {
|
|
15
|
+
const { t } = useLocale()
|
|
14
16
|
const router = useRouter()
|
|
15
17
|
const { createDirectory } = useResources()
|
|
16
18
|
const [directoryName, setDirectoryName] = useInputValue('')
|
|
@@ -24,11 +26,11 @@ export const CreateDirectory = () => {
|
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
if (!directoryName || directoryName.trim() === '') {
|
|
27
|
-
return setError('
|
|
29
|
+
return setError(t('resources.createDirectory.errorEmpty'))
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
if (directoryName?.startsWith?.('@ossy') || directoryName?.startsWith?.('/@ossy')) {
|
|
31
|
-
setError('
|
|
33
|
+
setError(t('resources.createDirectory.errorOssyPrefix'))
|
|
32
34
|
return
|
|
33
35
|
}
|
|
34
36
|
|
|
@@ -48,11 +50,10 @@ export const CreateDirectory = () => {
|
|
|
48
50
|
return (
|
|
49
51
|
<View gap="s" style={{ height: '100%' }}>
|
|
50
52
|
|
|
51
|
-
<Title variant="primary" style={{ marginBottom: 'var(--space-m)' }}>
|
|
53
|
+
<Title variant="primary" style={{ marginBottom: 'var(--space-m)' }}>{t('resources.createDirectory.title')}</Title>
|
|
52
54
|
|
|
53
55
|
<Text style={{ marginBottom: 'var(--space-m)' }}>
|
|
54
|
-
|
|
55
|
-
The new directory will be created in the location: {directoryLocation}
|
|
56
|
+
{t('resources.createDirectory.description', { location: directoryLocation })}
|
|
56
57
|
</Text>
|
|
57
58
|
|
|
58
59
|
<form
|
|
@@ -64,7 +65,7 @@ export const CreateDirectory = () => {
|
|
|
64
65
|
<Input
|
|
65
66
|
id="path"
|
|
66
67
|
type="text"
|
|
67
|
-
placeholder=
|
|
68
|
+
placeholder={t('resources.createDirectory.namePlaceholder')}
|
|
68
69
|
value={directoryName}
|
|
69
70
|
onChange={setDirectoryName}
|
|
70
71
|
style={{ width: '100%', marginBottom: 'var(--space-l)' }}
|
|
@@ -78,14 +79,14 @@ export const CreateDirectory = () => {
|
|
|
78
79
|
<Button
|
|
79
80
|
id="cancel"
|
|
80
81
|
onClick={() => router.navigate('@back')}
|
|
81
|
-
>
|
|
82
|
+
>{t('design-system.cancel')}
|
|
82
83
|
</Button>
|
|
83
84
|
|
|
84
85
|
<Button
|
|
85
86
|
id="createDirectory"
|
|
86
87
|
variant="cta"
|
|
87
88
|
onClick={onCreateDirectory}
|
|
88
|
-
>
|
|
89
|
+
>{t('resources.createDirectory.submit')}
|
|
89
90
|
</Button>
|
|
90
91
|
|
|
91
92
|
</View>
|
|
@@ -95,4 +96,3 @@ export const CreateDirectory = () => {
|
|
|
95
96
|
)
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
|
package/src/CreateDocument.jsx
CHANGED
|
@@ -1,73 +1,37 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
|
-
import { useResources
|
|
3
|
-
import {
|
|
4
|
-
Alert,
|
|
5
|
-
InputTitle,
|
|
6
|
-
Button,
|
|
7
|
-
useInputValue,
|
|
8
|
-
Fields,
|
|
9
|
-
applyFieldChange,
|
|
10
|
-
} from '@ossy/design-system'
|
|
2
|
+
import { useResources } from '@ossy/sdk-react'
|
|
3
|
+
import { Alert, useLocale } from '@ossy/design-system'
|
|
11
4
|
import { useRouter } from '@ossy/router-react'
|
|
5
|
+
import { GenericResourceForm } from './GenericResourceForm.jsx'
|
|
12
6
|
|
|
13
7
|
export const CreateDocument = () => {
|
|
8
|
+
const { t } = useLocale()
|
|
14
9
|
const router = useRouter()
|
|
15
10
|
const templateId = router.searchParams.templateId
|
|
16
11
|
const location = router.searchParams.location
|
|
17
|
-
const template = useResourceTemplate(templateId)
|
|
18
|
-
const [documentData, setDocumentData] = useState({})
|
|
19
12
|
const { createDocument } = useResources()
|
|
20
|
-
const [documentName, setDocumentName] = useInputValue()
|
|
21
13
|
const [error, setError] = useState()
|
|
22
14
|
|
|
23
15
|
const onCancel = () => {
|
|
24
|
-
setDocumentData({})
|
|
25
16
|
const search = new URLSearchParams({ location }).toString()
|
|
26
17
|
router.navigate(`@storage/home?${search}`)
|
|
27
18
|
}
|
|
28
19
|
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const onCreateDocument = () => {
|
|
36
|
-
if (documentName === '' || documentName === undefined) {
|
|
37
|
-
setError('Document name needs to be set')
|
|
38
|
-
return ''
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
createDocument({
|
|
42
|
-
type: templateId,
|
|
43
|
-
location: location,
|
|
44
|
-
name: documentName,
|
|
45
|
-
content: documentData
|
|
46
|
-
})
|
|
47
|
-
.then(() => onFinish())
|
|
48
|
-
.catch(error => { setError(error.message) })
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const updateFieldData = event => {
|
|
52
|
-
setDocumentData(prev => applyFieldChange(prev, event))
|
|
20
|
+
const onSubmit = ({ name, content, type }) => {
|
|
21
|
+
createDocument({ type, location, name, content })
|
|
22
|
+
.then(() => onCancel())
|
|
23
|
+
.catch((err) => setError(err?.message || t('resources.form.createFailed')))
|
|
53
24
|
}
|
|
54
25
|
|
|
55
26
|
return (
|
|
56
27
|
<>
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
value={documentName}
|
|
63
|
-
onChange={setDocumentName}
|
|
28
|
+
<GenericResourceForm
|
|
29
|
+
templateId={templateId}
|
|
30
|
+
mode="create"
|
|
31
|
+
onSubmit={onSubmit}
|
|
32
|
+
onCancel={onCancel}
|
|
64
33
|
/>
|
|
65
|
-
|
|
66
|
-
{ error && <Alert>{error}</Alert>}
|
|
67
|
-
<div style={{ display: 'flex', justifyContent: 'flex-end', paddingTop: 'var(--space-l)'}}>
|
|
68
|
-
<Button variant="link" onClick={onCancel}>Cancel</Button>
|
|
69
|
-
<Button variant="cta" onClick={onCreateDocument}>Create {template?.name}</Button>
|
|
70
|
-
</div>
|
|
34
|
+
{error && <Alert>{error}</Alert>}
|
|
71
35
|
</>
|
|
72
36
|
)
|
|
73
37
|
}
|
package/src/Definition.js
CHANGED
|
@@ -8,12 +8,6 @@ export const Definition = {
|
|
|
8
8
|
explore the gallery below to discover valuable assets that align with your vision.
|
|
9
9
|
We hope you find them useful, and we're here if you have any questions!
|
|
10
10
|
`,
|
|
11
|
-
|
|
12
|
-
id: 'resources',
|
|
13
|
-
enabled: true
|
|
14
|
-
},
|
|
11
|
+
icon: 'image',
|
|
15
12
|
statuses: ['beta'],
|
|
16
|
-
|
|
17
|
-
views: ['home.page', 'resources.list', 'resources.get'],
|
|
18
|
-
tasks: []
|
|
19
|
-
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useResource } from '@ossy/sdk-react'
|
|
3
|
+
import { Slot, resourceSlot, View, Title, Text, DelayedRender } from '@ossy/design-system'
|
|
4
|
+
|
|
5
|
+
function GenericResourceCardFallback ({ resource }) {
|
|
6
|
+
if (!resource) return null
|
|
7
|
+
return (
|
|
8
|
+
<View surface="secondary" roundness="m" inset="m" gap="xs">
|
|
9
|
+
<Title variant="secondary">{resource.name}</Title>
|
|
10
|
+
{resource.content?.description && (
|
|
11
|
+
<Text size="s" color="secondary">{resource.content.description}</Text>
|
|
12
|
+
)}
|
|
13
|
+
</View>
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Card-sized resource preview — `resource:{type}/card`. */
|
|
18
|
+
export function GenericResourceCard ({ resourceId, resource: resourceProp }) {
|
|
19
|
+
const { resource: loaded } = useResource(resourceId)
|
|
20
|
+
const resource = resourceProp ?? loaded
|
|
21
|
+
|
|
22
|
+
if (!resource) {
|
|
23
|
+
return (
|
|
24
|
+
<DelayedRender>
|
|
25
|
+
<Text>Loading…</Text>
|
|
26
|
+
</DelayedRender>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Slot
|
|
32
|
+
name={resourceSlot(resource.type, 'card')}
|
|
33
|
+
resourceId={resourceId}
|
|
34
|
+
resource={resource}
|
|
35
|
+
fallback={<GenericResourceCardFallback resource={resource} />}
|
|
36
|
+
/>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useResource, useResourceTemplate } from '@ossy/sdk-react'
|
|
3
|
+
import {
|
|
4
|
+
Slot,
|
|
5
|
+
resourceSlot,
|
|
6
|
+
View,
|
|
7
|
+
Title,
|
|
8
|
+
Text,
|
|
9
|
+
DelayedRender,
|
|
10
|
+
Fields,
|
|
11
|
+
} from '@ossy/design-system'
|
|
12
|
+
import { ResourceGenericView } from './ResourceGenericView.jsx'
|
|
13
|
+
|
|
14
|
+
function GenericResourceDetailFallback ({ resourceId }) {
|
|
15
|
+
const { resource } = useResource(resourceId)
|
|
16
|
+
const template = useResourceTemplate(resource?.type)
|
|
17
|
+
|
|
18
|
+
if (!resource) {
|
|
19
|
+
return (
|
|
20
|
+
<DelayedRender>
|
|
21
|
+
<Text>Loading…</Text>
|
|
22
|
+
</DelayedRender>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (template?.fields?.length) {
|
|
27
|
+
return (
|
|
28
|
+
<View stack gap="m" inset="m">
|
|
29
|
+
<Title>{resource.name}</Title>
|
|
30
|
+
<Fields data={resource.content || {}} fields={template.fields} />
|
|
31
|
+
</View>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return <ResourceGenericView resourceId={resourceId} />
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Generic resource detail host — resolves `resource:{type}/detail` from the slot
|
|
40
|
+
* registry; falls back to template fields or a minimal placeholder.
|
|
41
|
+
*/
|
|
42
|
+
export function GenericResourceDetail ({ resourceId }) {
|
|
43
|
+
const { resource } = useResource(resourceId)
|
|
44
|
+
|
|
45
|
+
if (!resource) {
|
|
46
|
+
return (
|
|
47
|
+
<DelayedRender>
|
|
48
|
+
<Text>Loading…</Text>
|
|
49
|
+
</DelayedRender>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<Slot
|
|
55
|
+
name={resourceSlot(resource.type, 'detail')}
|
|
56
|
+
resourceId={resourceId}
|
|
57
|
+
resource={resource}
|
|
58
|
+
fallback={<GenericResourceDetailFallback resourceId={resourceId} />}
|
|
59
|
+
/>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { useResourceTemplate } from '@ossy/sdk-react'
|
|
3
|
+
import {
|
|
4
|
+
Slot,
|
|
5
|
+
resourceSlot,
|
|
6
|
+
View,
|
|
7
|
+
Title,
|
|
8
|
+
Text,
|
|
9
|
+
InputTitle,
|
|
10
|
+
Button,
|
|
11
|
+
Alert,
|
|
12
|
+
Fields,
|
|
13
|
+
applyFieldChange,
|
|
14
|
+
useInputValue,
|
|
15
|
+
useLocale,
|
|
16
|
+
} from '@ossy/design-system'
|
|
17
|
+
|
|
18
|
+
function GenericResourceFormFallback ({
|
|
19
|
+
templateId,
|
|
20
|
+
mode = 'create',
|
|
21
|
+
initialName = '',
|
|
22
|
+
initialContent = {},
|
|
23
|
+
onSubmit,
|
|
24
|
+
onCancel,
|
|
25
|
+
submitLabel,
|
|
26
|
+
}) {
|
|
27
|
+
const { t } = useLocale()
|
|
28
|
+
const template = useResourceTemplate(templateId)
|
|
29
|
+
const [name, setName] = useInputValue(initialName)
|
|
30
|
+
const [content, setContent] = useState(initialContent)
|
|
31
|
+
const [error, setError] = useState()
|
|
32
|
+
|
|
33
|
+
const handleSubmit = () => {
|
|
34
|
+
if (!name?.trim()) {
|
|
35
|
+
setError(t('resources.form.nameRequired'))
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
setError(undefined)
|
|
39
|
+
onSubmit?.({ name: name.trim(), content, type: templateId })
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<View stack gap="m">
|
|
44
|
+
<InputTitle
|
|
45
|
+
id="resource-name"
|
|
46
|
+
type="text"
|
|
47
|
+
placeholder={t('resources.form.untitled')}
|
|
48
|
+
value={name}
|
|
49
|
+
onChange={setName}
|
|
50
|
+
/>
|
|
51
|
+
<Fields
|
|
52
|
+
data={content}
|
|
53
|
+
onChange={(event) => setContent((prev) => applyFieldChange(prev, event))}
|
|
54
|
+
fields={template?.fields || []}
|
|
55
|
+
/>
|
|
56
|
+
{error && <Alert>{error}</Alert>}
|
|
57
|
+
<View layout="row" gap="s" justifyContent="flex-end">
|
|
58
|
+
{onCancel && <Button variant="link" onClick={onCancel}>{t('design-system.cancel')}</Button>}
|
|
59
|
+
<Button variant="cta" onClick={handleSubmit}>
|
|
60
|
+
{submitLabel || (mode === 'edit' ? t('design-system.save') : (template?.name ? `${t('design-system.add')} ${template.name}` : t('resources.form.createResource')))}
|
|
61
|
+
</Button>
|
|
62
|
+
</View>
|
|
63
|
+
</View>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Generic resource create/edit host — resolves `resource:{type}/form` from the
|
|
69
|
+
* slot registry; falls back to template-driven Fields.
|
|
70
|
+
*/
|
|
71
|
+
export function GenericResourceForm ({
|
|
72
|
+
templateId,
|
|
73
|
+
mode = 'create',
|
|
74
|
+
resourceId,
|
|
75
|
+
resource,
|
|
76
|
+
initialName,
|
|
77
|
+
initialContent,
|
|
78
|
+
onSubmit,
|
|
79
|
+
onCancel,
|
|
80
|
+
submitLabel,
|
|
81
|
+
}) {
|
|
82
|
+
const { t } = useLocale()
|
|
83
|
+
|
|
84
|
+
if (!templateId) {
|
|
85
|
+
return <Text>{t('resources.form.selectType')}</Text>
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<Slot
|
|
90
|
+
name={resourceSlot(templateId, 'form')}
|
|
91
|
+
templateId={templateId}
|
|
92
|
+
mode={mode}
|
|
93
|
+
resourceId={resourceId}
|
|
94
|
+
resource={resource}
|
|
95
|
+
onSubmit={onSubmit}
|
|
96
|
+
onCancel={onCancel}
|
|
97
|
+
fallback={
|
|
98
|
+
<GenericResourceFormFallback
|
|
99
|
+
templateId={templateId}
|
|
100
|
+
mode={mode}
|
|
101
|
+
initialName={initialName ?? resource?.name}
|
|
102
|
+
initialContent={initialContent ?? resource?.content ?? {}}
|
|
103
|
+
onSubmit={onSubmit}
|
|
104
|
+
onCancel={onCancel}
|
|
105
|
+
submitLabel={submitLabel}
|
|
106
|
+
/>
|
|
107
|
+
}
|
|
108
|
+
/>
|
|
109
|
+
)
|
|
110
|
+
}
|
package/src/ImageResource.jsx
CHANGED
package/src/PDFResource.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { useResource } from '@ossy/sdk-react'
|
|
3
|
-
import {
|
|
3
|
+
import { View } from '@ossy/design-system'
|
|
4
4
|
|
|
5
5
|
export const PDFResource = ({
|
|
6
6
|
resourceId
|
|
@@ -8,13 +8,13 @@ export const PDFResource = ({
|
|
|
8
8
|
const { resource } = useResource(resourceId)
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
<
|
|
11
|
+
<View stack bordered>
|
|
12
|
+
<View.Item fill>
|
|
13
|
+
<View stack bordered>
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
<
|
|
17
|
+
<View.Item fill style={{ padding: '16px 8px' }}>
|
|
18
18
|
|
|
19
19
|
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
|
20
20
|
<embed
|
|
@@ -24,10 +24,10 @@ export const PDFResource = ({
|
|
|
24
24
|
height="800px"
|
|
25
25
|
/>
|
|
26
26
|
</div>
|
|
27
|
-
</
|
|
27
|
+
</View.Item>
|
|
28
28
|
|
|
29
|
-
</
|
|
30
|
-
</
|
|
31
|
-
</
|
|
29
|
+
</View>
|
|
30
|
+
</View.Item>
|
|
31
|
+
</View>
|
|
32
32
|
)
|
|
33
33
|
}
|
|
@@ -55,7 +55,7 @@ export const ResourceContentPage = (props) => {
|
|
|
55
55
|
|
|
56
56
|
<View layout="row" style={{ justifyContent: 'space-between', borderRadius: 'var(--space-l)', padding: 'var(--space-xxs)', background: 'transparent' }}>
|
|
57
57
|
<Button variant="neutral" onClick={() => router.back()} style={{ padding: 'var(--space-xs)', borderRadius: '50%' }}>
|
|
58
|
-
<Icon name="
|
|
58
|
+
<Icon name="chevron-left" />
|
|
59
59
|
</Button>
|
|
60
60
|
</View>
|
|
61
61
|
|
package/src/ResourceFactory.jsx
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { useResource, AsyncStatus, useWorkspace } from '@ossy/sdk-react'
|
|
3
3
|
import { Guide, Text, DelayedRender } from '@ossy/design-system'
|
|
4
|
-
import { DocumentView } from './DocumentView.jsx'
|
|
5
4
|
import { DocumentEdit } from './DocumentEdit.jsx'
|
|
6
5
|
import { ImageResource } from './ImageResource.jsx'
|
|
7
6
|
import { AudioResource } from './AudioResource.jsx'
|
|
8
7
|
import { VideoResource } from './VideoResource.jsx'
|
|
9
8
|
import { PDFResource } from './PDFResource.jsx'
|
|
10
9
|
import { ResourceGenericView } from './ResourceGenericView.jsx'
|
|
10
|
+
import { GenericResourceDetail } from './GenericResourceDetail.jsx'
|
|
11
11
|
|
|
12
12
|
export const ResourceFactory = ({
|
|
13
13
|
resourceId,
|
|
@@ -39,8 +39,12 @@ export const ResourceFactory = ({
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
if (workspace?.resourceTemplates?.find(({ id }) => id === resource.type)) {
|
|
42
|
-
if (mode === 'View')
|
|
43
|
-
|
|
42
|
+
if (mode === 'View') {
|
|
43
|
+
return <GenericResourceDetail resourceId={resourceId} />
|
|
44
|
+
}
|
|
45
|
+
if (mode === 'Edit') {
|
|
46
|
+
return <DocumentEdit resourceId={resourceId} form={form} />
|
|
47
|
+
}
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
if (['image/jpeg', 'image/png'].includes(resource.type)) {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { useResource } from '@ossy/sdk-react'
|
|
3
3
|
import {
|
|
4
|
-
Stack,
|
|
5
4
|
View,
|
|
6
|
-
|
|
5
|
+
Icon,
|
|
7
6
|
} from '@ossy/design-system'
|
|
8
7
|
|
|
9
8
|
export const ResourceGenericView = ({
|
|
@@ -12,21 +11,21 @@ export const ResourceGenericView = ({
|
|
|
12
11
|
const { resource } = useResource(resourceId)
|
|
13
12
|
|
|
14
13
|
return (
|
|
15
|
-
<
|
|
16
|
-
<
|
|
17
|
-
<
|
|
14
|
+
<View stack bordered>
|
|
15
|
+
<View.Item fill>
|
|
16
|
+
<View stack bordered>
|
|
18
17
|
|
|
19
|
-
<
|
|
18
|
+
<View.Item fill style={{ padding: '16px 8px' }}>
|
|
20
19
|
|
|
21
20
|
<View alignItems="center" justifyContent="center" style={{ height: '100%', maxHeight: '400px' }}>
|
|
22
21
|
<View roundness="m" style={{ border: '1px solid var(--separator)', padding: 'var(--space-xl) var(--space-xl)'}}>
|
|
23
|
-
<
|
|
22
|
+
<Icon size="xl" name="file" />
|
|
24
23
|
</View>
|
|
25
24
|
</View>
|
|
26
|
-
</
|
|
25
|
+
</View.Item>
|
|
27
26
|
|
|
28
|
-
</
|
|
29
|
-
</
|
|
30
|
-
</
|
|
27
|
+
</View>
|
|
28
|
+
</View.Item>
|
|
29
|
+
</View>
|
|
31
30
|
)
|
|
32
31
|
}
|
package/src/ResourceList.jsx
CHANGED
|
@@ -4,7 +4,7 @@ import { useWorkspace } from '@ossy/sdk-react'
|
|
|
4
4
|
import {
|
|
5
5
|
Dropdown,
|
|
6
6
|
DropZone,
|
|
7
|
-
|
|
7
|
+
Icon,
|
|
8
8
|
Image,
|
|
9
9
|
View,
|
|
10
10
|
Text,
|
|
@@ -73,7 +73,7 @@ function InlineFolderRow({ name, onChange, onSave, onCancel }) {
|
|
|
73
73
|
}}
|
|
74
74
|
>
|
|
75
75
|
<View gap="m" layout="row" alignItems="center" style={{ flexGrow: 1, padding: '12px 0 12px 20px' }}>
|
|
76
|
-
<
|
|
76
|
+
<Icon size="s" name="folder" style={{ fill: 'hsl(0, 0%, 60%)' }} />
|
|
77
77
|
<input
|
|
78
78
|
ref={inputRef}
|
|
79
79
|
value={name}
|
|
@@ -163,7 +163,7 @@ function ResourceListItem({
|
|
|
163
163
|
|
|
164
164
|
if (resource?.type === 'directory') {
|
|
165
165
|
return (
|
|
166
|
-
<
|
|
166
|
+
<Icon size="s" name="folder" style={{ fill: 'hsl(0, 0%, 60%)'}} />
|
|
167
167
|
)
|
|
168
168
|
}
|
|
169
169
|
|
|
@@ -178,7 +178,7 @@ function ResourceListItem({
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
return (
|
|
181
|
-
<
|
|
181
|
+
<Icon size="s" name={resourceTemplates[resource.type]?.icon || 'file'} style={{ fill: 'hsl(0, 0%, 80%)'}} />
|
|
182
182
|
)
|
|
183
183
|
}
|
|
184
184
|
|
package/src/ResourcePanel.jsx
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
Title,
|
|
5
5
|
Overlay,
|
|
6
6
|
Switch,
|
|
7
|
-
Stack,
|
|
8
7
|
Guide,
|
|
9
8
|
View,
|
|
10
9
|
Text,
|
|
@@ -133,7 +132,7 @@ export const ResourcePanel = ({
|
|
|
133
132
|
}
|
|
134
133
|
|
|
135
134
|
return (
|
|
136
|
-
<
|
|
135
|
+
<View stack surface="primary" bordered style={{ height: '100%', width: '50%' }}>
|
|
137
136
|
|
|
138
137
|
<style href="@design-system/scroll" precedence='low'>{`
|
|
139
138
|
[data-scroll-hide] {
|
|
@@ -148,23 +147,23 @@ export const ResourcePanel = ({
|
|
|
148
147
|
|
|
149
148
|
{
|
|
150
149
|
!!error && (
|
|
151
|
-
<
|
|
150
|
+
<View.Item>
|
|
152
151
|
{error}
|
|
153
|
-
</
|
|
152
|
+
</View.Item>
|
|
154
153
|
)
|
|
155
154
|
}
|
|
156
155
|
|
|
157
|
-
<
|
|
156
|
+
<View.Item>
|
|
158
157
|
|
|
159
|
-
<
|
|
158
|
+
<View stack horizontal style={{ height: '48px', alignItems: 'center', gap: '4px' }}>
|
|
160
159
|
|
|
161
160
|
<Switch on={panelViewModes['panel-header']}>
|
|
162
161
|
|
|
163
162
|
<Switch.Case match={[ViewMode.View]}>
|
|
164
163
|
|
|
165
|
-
<
|
|
164
|
+
<View.Item fill surface="primary" style={{ padding: '4px 8px' }}>
|
|
166
165
|
<Title as="h3" variant="tertiary">{resourceName}</Title>
|
|
167
|
-
</
|
|
166
|
+
</View.Item>
|
|
168
167
|
|
|
169
168
|
<Button prefix="trash-empty" variant="command-danger" onClick={onRemoveResource}/>
|
|
170
169
|
<Button prefix="pen" variant="command" onClick={() => setPanelViewModes(x => ({ ...x, 'panel-header': ViewMode.Edit }))} />
|
|
@@ -174,7 +173,7 @@ export const ResourcePanel = ({
|
|
|
174
173
|
|
|
175
174
|
<Switch.Case match={[ViewMode.Edit]}>
|
|
176
175
|
|
|
177
|
-
<
|
|
176
|
+
<View.Item fill surface="primary" style={{ padding: '4px 8px' }}>
|
|
178
177
|
<InputTitle
|
|
179
178
|
id="document-name"
|
|
180
179
|
type="text"
|
|
@@ -183,7 +182,7 @@ export const ResourcePanel = ({
|
|
|
183
182
|
onChange={setResourceName}
|
|
184
183
|
onBlur={onRenameResource}
|
|
185
184
|
/>
|
|
186
|
-
</
|
|
185
|
+
</View.Item>
|
|
187
186
|
|
|
188
187
|
<Button prefix="close" variant="command" onClick={() => setPanelViewModes(x => ({ ...x, 'panel-header': ViewMode.View }))} />
|
|
189
188
|
<Button prefix="check" variant="command" onClick={onRenameResource}/>
|
|
@@ -192,11 +191,11 @@ export const ResourcePanel = ({
|
|
|
192
191
|
|
|
193
192
|
</Switch>
|
|
194
193
|
|
|
195
|
-
</
|
|
194
|
+
</View>
|
|
196
195
|
|
|
197
|
-
</
|
|
196
|
+
</View.Item>
|
|
198
197
|
|
|
199
|
-
<
|
|
198
|
+
<View.Item fill={true} data-scroll-hide style={{ display: 'flex', flexDirection: 'column', height: '100%', overflowY: 'auto' }}>
|
|
200
199
|
|
|
201
200
|
{panels.map(({ content: Content, ...panel }) => {
|
|
202
201
|
const isExpanded = [ViewMode.View, ViewMode.Edit].includes(panelViewModes[panel.id])
|
|
@@ -239,7 +238,7 @@ export const ResourcePanel = ({
|
|
|
239
238
|
)
|
|
240
239
|
})}
|
|
241
240
|
|
|
242
|
-
</
|
|
241
|
+
</View.Item>
|
|
243
242
|
|
|
244
243
|
{
|
|
245
244
|
overlay === Overlays.RemoveDirectory && (
|
|
@@ -267,6 +266,6 @@ export const ResourcePanel = ({
|
|
|
267
266
|
)
|
|
268
267
|
}
|
|
269
268
|
|
|
270
|
-
</
|
|
269
|
+
</View>
|
|
271
270
|
)
|
|
272
271
|
}
|
package/src/ResourcesPage.jsx
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { SDK } from '@ossy/sdk'
|
|
3
3
|
import { useResources, AsyncStatus, WorkspaceProvider } from '@ossy/sdk-react'
|
|
4
|
-
import { Title, Text, Switch, View, ImageCard, Tags } from '@ossy/design-system'
|
|
4
|
+
import { Title, Text, Switch, View, ImageCard, Tags, useLocale } from '@ossy/design-system'
|
|
5
5
|
import { useRouter } from '@ossy/router-react'
|
|
6
|
-
import { Definition } from './Definition.js'
|
|
7
6
|
|
|
8
7
|
const sdk = SDK.of({
|
|
9
8
|
/** Ossy.se workspaceID - used to fetch free resources */
|
|
@@ -18,6 +17,7 @@ const freeResourcesGridStyles = {
|
|
|
18
17
|
|
|
19
18
|
export const ResourcesPage= () => {
|
|
20
19
|
const router = useRouter()
|
|
20
|
+
const { t } = useLocale()
|
|
21
21
|
const { status, resources } = useResources('/publications/images/')
|
|
22
22
|
const tags = resources.flatMap(resource => resource?.content?.tags || [])
|
|
23
23
|
const tagsCount = tags.reduce((acc, t) => ({ ...acc, [t]: (acc?.[t] ?? 0) + 1 }), {})
|
|
@@ -34,8 +34,8 @@ export const ResourcesPage= () => {
|
|
|
34
34
|
<View gap="l" style={{ margin: '0 auto' }}>
|
|
35
35
|
|
|
36
36
|
<View gap="m">
|
|
37
|
-
<Title>{
|
|
38
|
-
<Text style={{ maxWidth: '900px'}}>{
|
|
37
|
+
<Title>{t('resources.home.title')}</Title>
|
|
38
|
+
<Text style={{ maxWidth: '900px'}}>{t('resources.home.description')}</Text>
|
|
39
39
|
</View>
|
|
40
40
|
|
|
41
41
|
<WorkspaceProvider sdk={sdk}>
|
package/src/Upload.jsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react'
|
|
2
|
-
import { Button, View, Text, Upload as _Upload,
|
|
2
|
+
import { Button, View, Text, Upload as _Upload, Icon } from '@ossy/design-system'
|
|
3
3
|
import { useRouter } from '@ossy/router-react'
|
|
4
4
|
|
|
5
5
|
const FlowStage = {
|
|
@@ -155,9 +155,9 @@ function UploadImgPreview({ file, size = "32px" }) {
|
|
|
155
155
|
|
|
156
156
|
function UploadStatus({ status }) {
|
|
157
157
|
if (status === 'preview') return <></>
|
|
158
|
-
if (status === 'uploading') return <
|
|
159
|
-
if (status === 'uploaded') return <
|
|
160
|
-
if (status === 'error') return <
|
|
158
|
+
if (status === 'uploading') return <Icon name="spinner" size="s" animation="rotate" />
|
|
159
|
+
if (status === 'uploaded') return <Icon name="check" size="s" />
|
|
160
|
+
if (status === 'error') return <Icon name="close" size="s" />
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
function getFlowStage(files = []) {
|
package/src/UploadResources.jsx
CHANGED
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { useResources } from '@ossy/sdk-react'
|
|
3
|
-
import { Title, View, Text,
|
|
3
|
+
import { Title, View, Text, useLocale } from '@ossy/design-system'
|
|
4
4
|
import { useRouter } from '@ossy/router-react'
|
|
5
5
|
import { Upload } from './Upload.jsx'
|
|
6
6
|
|
|
7
7
|
export const UploadResources = () => {
|
|
8
|
+
const { t } = useLocale()
|
|
8
9
|
const router = useRouter()
|
|
9
10
|
const location = router.searchParams.location
|
|
10
11
|
const { uploadFile } = useResources()
|
|
11
12
|
|
|
12
13
|
return (
|
|
13
14
|
<View gap="s" style={{ height: '100%' }}>
|
|
14
|
-
|
|
15
15
|
<View gap="s">
|
|
16
|
-
<Title variant="tertiary" style={{ marginBottom: '0' }}>
|
|
17
|
-
Upload
|
|
18
|
-
</Title>
|
|
16
|
+
<Title variant="tertiary" style={{ marginBottom: '0' }}>{t('resources.upload.title')}</Title>
|
|
19
17
|
<View layout="row" gap="s">
|
|
20
|
-
<Text variant="small"
|
|
18
|
+
<Text variant="small">{t('resources.upload.location', { location })}</Text>
|
|
21
19
|
</View>
|
|
22
20
|
</View>
|
|
23
|
-
|
|
24
21
|
<Upload
|
|
25
22
|
onUpload={(file) => uploadFile(location, file)}
|
|
26
23
|
onCancel={() => router.navigate(`@storage/home?location=${location}`)}
|
|
@@ -28,4 +25,4 @@ export const UploadResources = () => {
|
|
|
28
25
|
/>
|
|
29
26
|
</View>
|
|
30
27
|
)
|
|
31
|
-
}
|
|
28
|
+
}
|
package/src/VideoResource.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { useResource } from '@ossy/sdk-react'
|
|
3
|
-
import {
|
|
3
|
+
import { View } from '@ossy/design-system'
|
|
4
4
|
|
|
5
5
|
export const VideoResource = ({
|
|
6
6
|
resourceId
|
|
@@ -8,8 +8,8 @@ export const VideoResource = ({
|
|
|
8
8
|
const { resource } = useResource(resourceId)
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
|
-
<
|
|
12
|
-
<
|
|
11
|
+
<View stack bordered>
|
|
12
|
+
<View.Item fill style={{ padding: '16px 8px' }}>
|
|
13
13
|
|
|
14
14
|
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
|
15
15
|
<video
|
|
@@ -18,7 +18,7 @@ export const VideoResource = ({
|
|
|
18
18
|
style={{ width: 'auto', height: '400px', margin: 'var(--space-l) auto' }}
|
|
19
19
|
/>
|
|
20
20
|
</div>
|
|
21
|
-
</
|
|
22
|
-
</
|
|
21
|
+
</View.Item>
|
|
22
|
+
</View>
|
|
23
23
|
)
|
|
24
24
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"resources.home.documentTitle": "Free Resources",
|
|
3
|
+
"resources.home.title": "Free Resources",
|
|
4
|
+
"resources.home.description": "We believe in providing value at every step of your journey with us. That's why we've curated a collection of free resources. Whether you're looking to enhance your creative projects or simply seeking inspiration, explore the gallery below to discover valuable assets that align with your vision. We hope you find them useful, and we're here if you have any questions!",
|
|
5
|
+
"resources.form.nameRequired": "Name is required",
|
|
6
|
+
"resources.form.untitled": "Untitled",
|
|
7
|
+
"resources.form.selectType": "Select a resource type to continue.",
|
|
8
|
+
"resources.form.createFailed": "Create failed",
|
|
9
|
+
"resources.form.createResource": "Create resource",
|
|
10
|
+
"resources/create.label": "Create resource",
|
|
11
|
+
"resources/create.description": "Create a new resource in the workspace",
|
|
12
|
+
"resources/list.label": "List resources",
|
|
13
|
+
"resources/list.description": "List resources in a workspace location",
|
|
14
|
+
"resources/get.label": "Get resource",
|
|
15
|
+
"resources/get.description": "Fetch a single resource by id",
|
|
16
|
+
"resources/search.label": "Search resources",
|
|
17
|
+
"resources/search.description": "Search resources in a workspace",
|
|
18
|
+
"resources/delete.label": "Delete resource",
|
|
19
|
+
"resources/delete.description": "Delete a resource from the workspace",
|
|
20
|
+
"resources/update-name.label": "Update resource name",
|
|
21
|
+
"resources/update-name.description": "Rename a workspace resource",
|
|
22
|
+
"resources/update-content.label": "Update resource content",
|
|
23
|
+
"resources/update-content.description": "Update the content of a workspace resource",
|
|
24
|
+
"resources/update-location.label": "Update resource location",
|
|
25
|
+
"resources/update-location.description": "Move a resource to a new location",
|
|
26
|
+
"resources/update-access.label": "Update resource access",
|
|
27
|
+
"resources/update-access.description": "Change access settings for a resource",
|
|
28
|
+
"resources/upload-named-version.label": "Upload named version",
|
|
29
|
+
"resources/upload-named-version.description": "Upload a named version of a resource file",
|
|
30
|
+
"resources/create-page-view.label": "Create page view",
|
|
31
|
+
"resources/create-page-view.description": "Record a page view analytics event",
|
|
32
|
+
"resources/get-page-view-stats.label": "Get page view stats",
|
|
33
|
+
"resources/get-page-view-stats.description": "Fetch aggregated page view statistics",
|
|
34
|
+
"resources.create.generic.documentTitle": "Create resource",
|
|
35
|
+
"createDirectory.documentTitle": "Create directory",
|
|
36
|
+
"createDocument.documentTitle": "Create document",
|
|
37
|
+
"uploadMedia.documentTitle": "Upload",
|
|
38
|
+
"@resource.documentTitle": "Resource",
|
|
39
|
+
"resources.upload.title": "Upload",
|
|
40
|
+
"resources.upload.location": "Location: {location}",
|
|
41
|
+
"resources.createDirectory.title": "Create directory",
|
|
42
|
+
"resources.createDocument.title": "Create document",
|
|
43
|
+
"resources.createDirectory.description": "Create a new directory to organize your resources. The new directory will be created in the location: {location}",
|
|
44
|
+
"resources.createDirectory.namePlaceholder": "Directory name",
|
|
45
|
+
"resources.createDirectory.submit": "Create directory",
|
|
46
|
+
"resources.createDirectory.errorEmpty": "Directory name cannot be empty",
|
|
47
|
+
"resources.createDirectory.errorOssyPrefix": "Directory name cannot start with @ossy"
|
|
48
|
+
}
|
package/src/index.js
CHANGED
|
@@ -15,6 +15,9 @@ export * from './ResourceDescription.jsx'
|
|
|
15
15
|
export * from './ResourceDetails.jsx'
|
|
16
16
|
export * from './ResourceDialogMove.jsx'
|
|
17
17
|
export * from './ResourceFactory.jsx'
|
|
18
|
+
export * from './GenericResourceDetail.jsx'
|
|
19
|
+
export * from './GenericResourceForm.jsx'
|
|
20
|
+
export * from './GenericResourceCard.jsx'
|
|
18
21
|
export * from './ResourceGenericView.jsx'
|
|
19
22
|
export * from './ResourceList.jsx'
|
|
20
23
|
export * from './ResourcePage.jsx'
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { useResources } from '@ossy/sdk-react'
|
|
3
|
+
import { View, useLocale } from '@ossy/design-system'
|
|
4
|
+
import { useRouter } from '@ossy/router-react'
|
|
5
|
+
import { GenericResourceForm } from './GenericResourceForm.jsx'
|
|
6
|
+
|
|
7
|
+
export const metadata = {
|
|
8
|
+
id: 'resources/create/generic',
|
|
9
|
+
path: {
|
|
10
|
+
en: '/resources/create/:templateId',
|
|
11
|
+
sv: '/resources/skapa/:templateId',
|
|
12
|
+
},
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Generic resource create page — slot lookup with template Fields fallback. */
|
|
16
|
+
export default function GenericResourceCreatePage () {
|
|
17
|
+
const router = useRouter()
|
|
18
|
+
const { t } = useLocale()
|
|
19
|
+
const templateId = decodeURIComponent(router.params.templateId || '')
|
|
20
|
+
const location = router.searchParams.location
|
|
21
|
+
const { createDocument } = useResources()
|
|
22
|
+
const [error, setError] = useState()
|
|
23
|
+
|
|
24
|
+
const onCancel = () => {
|
|
25
|
+
const search = location ? new URLSearchParams({ location }).toString() : ''
|
|
26
|
+
router.navigate(`@storage/home${search ? `?${search}` : ''}`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const onSubmit = ({ name, content, type }) => {
|
|
30
|
+
createDocument({ type, location, name, content })
|
|
31
|
+
.then(() => onCancel())
|
|
32
|
+
.catch((err) => setError(err?.message || t('resources.form.createFailed')))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<View layout="off-center-m" style={{ height: '100%' }}>
|
|
37
|
+
<View slot="content" surface="primary" roundness="m" inset="m">
|
|
38
|
+
<GenericResourceForm
|
|
39
|
+
templateId={templateId}
|
|
40
|
+
mode="create"
|
|
41
|
+
onSubmit={onSubmit}
|
|
42
|
+
onCancel={onCancel}
|
|
43
|
+
/>
|
|
44
|
+
{error && <View inset="s"><span style={{ color: 'var(--danger)' }}>{error}</span></View>}
|
|
45
|
+
</View>
|
|
46
|
+
</View>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { View } from '@ossy/design-system'
|
|
3
|
+
import { useRouter } from '@ossy/router-react'
|
|
4
|
+
import { GenericResourceDetail } from './GenericResourceDetail.jsx'
|
|
5
|
+
|
|
6
|
+
export const metadata = {
|
|
7
|
+
id: '@resource',
|
|
8
|
+
path: {
|
|
9
|
+
en: '/resources/item/:resourceId',
|
|
10
|
+
sv: '/resources/objekt/:resourceId',
|
|
11
|
+
},
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default function ResourceDetailPage () {
|
|
15
|
+
const router = useRouter()
|
|
16
|
+
const resourceId = router.params.resourceId
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<View layout="off-center-m" style={{ height: '100%' }}>
|
|
20
|
+
<View slot="content" surface="primary" roundness="m" inset="m">
|
|
21
|
+
<GenericResourceDetail resourceId={resourceId} />
|
|
22
|
+
</View>
|
|
23
|
+
</View>
|
|
24
|
+
)
|
|
25
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"resources.home.documentTitle": "Gratis resurser",
|
|
3
|
+
"resources.home.title": "Gratis resurser",
|
|
4
|
+
"resources.home.description": "Vi tror på att leverera värde i varje steg av din resa med oss. Därför har vi samlat gratis resurser. Oavsett om du vill förbättra dina kreativa projekt eller bara söker inspiration kan du utforska galleriet nedan. Vi hoppas att du hittar något användbart — hör av dig om du har frågor!",
|
|
5
|
+
"resources.form.nameRequired": "Namn krävs",
|
|
6
|
+
"resources.form.untitled": "Namnlös",
|
|
7
|
+
"resources.form.selectType": "Välj en resurstyp för att fortsätta.",
|
|
8
|
+
"resources.form.createFailed": "Skapandet misslyckades",
|
|
9
|
+
"resources.form.createResource": "Skapa resurs",
|
|
10
|
+
"resources/create.label": "Skapa resurs",
|
|
11
|
+
"resources/create.description": "Skapa en ny resurs i workspace",
|
|
12
|
+
"resources/list.label": "Lista resurser",
|
|
13
|
+
"resources/list.description": "Lista resurser på en plats i workspace",
|
|
14
|
+
"resources/get.label": "Hämta resurs",
|
|
15
|
+
"resources/get.description": "Hämta en enskild resurs via id",
|
|
16
|
+
"resources/search.label": "Sök resurser",
|
|
17
|
+
"resources/search.description": "Sök resurser i en workspace",
|
|
18
|
+
"resources/delete.label": "Ta bort resurs",
|
|
19
|
+
"resources/delete.description": "Ta bort en resurs från workspace",
|
|
20
|
+
"resources/update-name.label": "Uppdatera resursnamn",
|
|
21
|
+
"resources/update-name.description": "Byt namn på en resurs i workspace",
|
|
22
|
+
"resources/update-content.label": "Uppdatera resursinnehåll",
|
|
23
|
+
"resources/update-content.description": "Uppdatera innehållet i en resurs",
|
|
24
|
+
"resources/update-location.label": "Uppdatera resursplats",
|
|
25
|
+
"resources/update-location.description": "Flytta en resurs till en ny plats",
|
|
26
|
+
"resources/update-access.label": "Uppdatera resursåtkomst",
|
|
27
|
+
"resources/update-access.description": "Ändra åtkomstinställningar för en resurs",
|
|
28
|
+
"resources/upload-named-version.label": "Ladda upp namngiven version",
|
|
29
|
+
"resources/upload-named-version.description": "Ladda upp en namngiven version av en resursfil",
|
|
30
|
+
"resources/create-page-view.label": "Skapa sidvisning",
|
|
31
|
+
"resources/create-page-view.description": "Registrera en sidvisningshändelse för analys",
|
|
32
|
+
"resources/get-page-view-stats.label": "Hämta sidvisningsstatistik",
|
|
33
|
+
"resources/get-page-view-stats.description": "Hämta aggregerad statistik för sidvisningar",
|
|
34
|
+
"resources.create.generic.documentTitle": "Skapa resurs",
|
|
35
|
+
"createDirectory.documentTitle": "Skapa mapp",
|
|
36
|
+
"createDocument.documentTitle": "Skapa dokument",
|
|
37
|
+
"uploadMedia.documentTitle": "Ladda upp",
|
|
38
|
+
"@resource.documentTitle": "Resurs",
|
|
39
|
+
"resources.upload.title": "Ladda upp",
|
|
40
|
+
"resources.upload.location": "Plats: {location}",
|
|
41
|
+
"resources.createDirectory.title": "Skapa mapp",
|
|
42
|
+
"resources.createDocument.title": "Skapa dokument",
|
|
43
|
+
"resources.createDirectory.description": "Skapa en ny mapp för att organisera dina resurser. Den nya mappen skapas på platsen: {location}",
|
|
44
|
+
"resources.createDirectory.namePlaceholder": "Mappnamn",
|
|
45
|
+
"resources.createDirectory.submit": "Skapa mapp",
|
|
46
|
+
"resources.createDirectory.errorEmpty": "Mappnamn får inte vara tomt",
|
|
47
|
+
"resources.createDirectory.errorOssyPrefix": "Mappnamn får inte börja med @ossy"
|
|
48
|
+
}
|