@sanity/document-internationalization 4.1.1 → 5.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/LICENSE +1 -1
- package/README.md +44 -36
- package/dist/_chunks-es/{resources.mjs → resources.js} +1 -1
- package/dist/{_chunks-cjs → _chunks-es}/resources.js.map +1 -1
- package/dist/index.d.ts +112 -88
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1075 -1337
- package/dist/index.js.map +1 -1
- package/package.json +35 -69
- package/dist/_chunks-cjs/resources.js +0 -8
- package/dist/_chunks-es/resources.mjs.map +0 -1
- package/dist/_legacy/resources.esm.js +0 -9
- package/dist/_legacy/resources.esm.js.map +0 -1
- package/dist/index.d.mts +0 -108
- package/dist/index.esm.js +0 -1625
- package/dist/index.esm.js.map +0 -1
- package/dist/index.mjs +0 -1625
- package/dist/index.mjs.map +0 -1
- package/sanity.json +0 -8
- package/src/actions/DeleteMetadataAction.tsx +0 -93
- package/src/actions/DeleteTranslationAction.tsx +0 -102
- package/src/actions/DuplicateWithTranslationsAction.tsx +0 -251
- package/src/badges/index.tsx +0 -27
- package/src/components/BulkPublish/DocumentCheck.tsx +0 -90
- package/src/components/BulkPublish/Info.tsx +0 -28
- package/src/components/BulkPublish/InfoIcon.tsx +0 -34
- package/src/components/BulkPublish/index.tsx +0 -181
- package/src/components/ConstrainedBox.tsx +0 -6
- package/src/components/DeleteTranslationDialog/DocumentPreview.tsx +0 -19
- package/src/components/DeleteTranslationDialog/index.tsx +0 -111
- package/src/components/DeleteTranslationDialog/separateReferences.ts +0 -23
- package/src/components/DeleteTranslationFooter.tsx +0 -28
- package/src/components/DocumentInternationalizationContext.tsx +0 -47
- package/src/components/DocumentInternationalizationMenu.tsx +0 -235
- package/src/components/LanguageManage.tsx +0 -108
- package/src/components/LanguageOption.tsx +0 -259
- package/src/components/LanguagePatch.tsx +0 -67
- package/src/components/OptimisticallyStrengthen/ReferencePatcher.tsx +0 -50
- package/src/components/OptimisticallyStrengthen/index.tsx +0 -34
- package/src/components/Warning.tsx +0 -18
- package/src/constants.ts +0 -16
- package/src/hooks/useLanguageMetadata.tsx +0 -26
- package/src/hooks/useOpenInNewPane.tsx +0 -33
- package/src/i18n/index.ts +0 -21
- package/src/i18n/resources.ts +0 -7
- package/src/index.ts +0 -6
- package/src/plugin.tsx +0 -239
- package/src/schema/translation/metadata.ts +0 -68
- package/src/types.ts +0 -97
- package/src/utils/createReference.ts +0 -20
- package/src/utils/excludePaths.ts +0 -123
- package/v2-incompatible.js +0 -11
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import {Card, Flex, Spinner, Stack, Text} from '@sanity/ui'
|
|
2
|
-
import {useEffect, useMemo} from 'react'
|
|
3
|
-
import type {SanityDocument} from 'sanity'
|
|
4
|
-
import {useListeningQuery} from 'sanity-plugin-utils'
|
|
5
|
-
|
|
6
|
-
import DocumentPreview from './DocumentPreview'
|
|
7
|
-
import {separateReferences} from './separateReferences'
|
|
8
|
-
|
|
9
|
-
type DeleteTranslationDialogProps = {
|
|
10
|
-
doc: SanityDocument
|
|
11
|
-
documentId: string
|
|
12
|
-
setTranslations: (translations: SanityDocument[]) => void
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export default function DeleteTranslationDialog(
|
|
16
|
-
props: DeleteTranslationDialogProps
|
|
17
|
-
) {
|
|
18
|
-
const {doc, documentId, setTranslations} = props
|
|
19
|
-
|
|
20
|
-
// Get all references and check if any of them are translations metadata
|
|
21
|
-
const {data, loading} = useListeningQuery<SanityDocument[]>(
|
|
22
|
-
`*[references($id)]{_id, _type}`,
|
|
23
|
-
{params: {id: documentId}, initialValue: []}
|
|
24
|
-
)
|
|
25
|
-
const {translations, otherReferences} = useMemo(
|
|
26
|
-
() => separateReferences(data as SanityDocument[] | null),
|
|
27
|
-
[data]
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
setTranslations(translations)
|
|
32
|
-
}, [setTranslations, translations])
|
|
33
|
-
|
|
34
|
-
if (loading) {
|
|
35
|
-
return (
|
|
36
|
-
<Flex padding={4} align="center" justify="center">
|
|
37
|
-
<Spinner />
|
|
38
|
-
</Flex>
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<Stack space={4}>
|
|
44
|
-
{translations && translations.length > 0 ? (
|
|
45
|
-
<Text>
|
|
46
|
-
This document is a language-specific version which other translations
|
|
47
|
-
depend on.
|
|
48
|
-
</Text>
|
|
49
|
-
) : (
|
|
50
|
-
<Text>This document does not have connected translations.</Text>
|
|
51
|
-
)}
|
|
52
|
-
<Card border padding={3}>
|
|
53
|
-
<Stack space={4}>
|
|
54
|
-
<Text size={1} weight="semibold">
|
|
55
|
-
{translations && translations.length > 0 ? (
|
|
56
|
-
<>Before this document can be deleted</>
|
|
57
|
-
) : (
|
|
58
|
-
<>This document can now be deleted</>
|
|
59
|
-
)}
|
|
60
|
-
</Text>
|
|
61
|
-
<DocumentPreview value={doc} type={doc._type} />
|
|
62
|
-
{translations && translations.length > 0 ? (
|
|
63
|
-
<>
|
|
64
|
-
<Card borderTop />
|
|
65
|
-
<Text size={1} weight="semibold">
|
|
66
|
-
The reference in{' '}
|
|
67
|
-
{translations.length === 1
|
|
68
|
-
? `this translations document`
|
|
69
|
-
: `these translations documents`}{' '}
|
|
70
|
-
must be removed
|
|
71
|
-
</Text>
|
|
72
|
-
{translations.map((translation) => (
|
|
73
|
-
<DocumentPreview
|
|
74
|
-
key={translation._id}
|
|
75
|
-
value={translation}
|
|
76
|
-
type={translation._type}
|
|
77
|
-
/>
|
|
78
|
-
))}
|
|
79
|
-
</>
|
|
80
|
-
) : null}
|
|
81
|
-
{otherReferences && otherReferences.length > 0 ? (
|
|
82
|
-
<>
|
|
83
|
-
<Card borderTop />
|
|
84
|
-
<Text size={1} weight="semibold">
|
|
85
|
-
{otherReferences.length === 1
|
|
86
|
-
? `There is an additional reference`
|
|
87
|
-
: `There are additional references`}{' '}
|
|
88
|
-
to this document
|
|
89
|
-
</Text>
|
|
90
|
-
{otherReferences.map((reference) => (
|
|
91
|
-
<DocumentPreview
|
|
92
|
-
key={reference._id}
|
|
93
|
-
value={reference}
|
|
94
|
-
type={reference._type}
|
|
95
|
-
/>
|
|
96
|
-
))}
|
|
97
|
-
</>
|
|
98
|
-
) : null}
|
|
99
|
-
</Stack>
|
|
100
|
-
</Card>
|
|
101
|
-
{otherReferences.length === 0 ? (
|
|
102
|
-
<Text>This document has no other references.</Text>
|
|
103
|
-
) : (
|
|
104
|
-
<Text>
|
|
105
|
-
You may not be able to delete this document because other documents
|
|
106
|
-
refer to it.
|
|
107
|
-
</Text>
|
|
108
|
-
)}
|
|
109
|
-
</Stack>
|
|
110
|
-
)
|
|
111
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type {SanityDocument} from 'sanity'
|
|
2
|
-
|
|
3
|
-
import {METADATA_SCHEMA_NAME} from '../../constants'
|
|
4
|
-
|
|
5
|
-
export function separateReferences(data: SanityDocument[] | null = []): {
|
|
6
|
-
translations: SanityDocument[]
|
|
7
|
-
otherReferences: SanityDocument[]
|
|
8
|
-
} {
|
|
9
|
-
const translations: SanityDocument[] = []
|
|
10
|
-
const otherReferences: SanityDocument[] = []
|
|
11
|
-
|
|
12
|
-
if (data && data.length > 0) {
|
|
13
|
-
data.forEach((doc) => {
|
|
14
|
-
if (doc._type === METADATA_SCHEMA_NAME) {
|
|
15
|
-
translations.push(doc)
|
|
16
|
-
} else {
|
|
17
|
-
otherReferences.push(doc)
|
|
18
|
-
}
|
|
19
|
-
})
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return {translations, otherReferences}
|
|
23
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import {Button, Grid} from '@sanity/ui'
|
|
2
|
-
|
|
3
|
-
type DeleteTranslationFooterProps = {
|
|
4
|
-
translations: unknown[]
|
|
5
|
-
onClose: () => void
|
|
6
|
-
onProceed: () => void
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export default function DeleteTranslationFooter(
|
|
10
|
-
props: DeleteTranslationFooterProps
|
|
11
|
-
) {
|
|
12
|
-
const {translations, onClose, onProceed} = props
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<Grid columns={2} gap={2}>
|
|
16
|
-
<Button text="Cancel" onClick={onClose} mode="ghost" />
|
|
17
|
-
<Button
|
|
18
|
-
text={
|
|
19
|
-
translations && translations.length > 0
|
|
20
|
-
? `Unset translation reference`
|
|
21
|
-
: `Delete document`
|
|
22
|
-
}
|
|
23
|
-
onClick={onProceed}
|
|
24
|
-
tone="critical"
|
|
25
|
-
/>
|
|
26
|
-
</Grid>
|
|
27
|
-
)
|
|
28
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import {useContext} from 'react'
|
|
2
|
-
import {createContext} from 'react'
|
|
3
|
-
import {type LayoutProps, useClient, useWorkspace} from 'sanity'
|
|
4
|
-
import {suspend} from 'suspend-react'
|
|
5
|
-
|
|
6
|
-
import {DEFAULT_CONFIG} from '../constants'
|
|
7
|
-
import type {PluginConfig, PluginConfigContext} from '../types'
|
|
8
|
-
|
|
9
|
-
const DocumentInternationalizationContext =
|
|
10
|
-
createContext<PluginConfigContext>(DEFAULT_CONFIG)
|
|
11
|
-
|
|
12
|
-
export function useDocumentInternationalizationContext() {
|
|
13
|
-
return useContext(DocumentInternationalizationContext)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
type DocumentInternationalizationProviderProps = LayoutProps & {
|
|
17
|
-
pluginConfig: Required<PluginConfig>
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* This Provider wraps the Studio and provides the DocumentInternationalization context to document actions and components.
|
|
22
|
-
*/
|
|
23
|
-
export function DocumentInternationalizationProvider(
|
|
24
|
-
props: DocumentInternationalizationProviderProps
|
|
25
|
-
) {
|
|
26
|
-
const {pluginConfig} = props
|
|
27
|
-
|
|
28
|
-
const client = useClient({apiVersion: pluginConfig.apiVersion})
|
|
29
|
-
const workspace = useWorkspace()
|
|
30
|
-
const supportedLanguages = Array.isArray(pluginConfig.supportedLanguages)
|
|
31
|
-
? pluginConfig.supportedLanguages
|
|
32
|
-
: // eslint-disable-next-line require-await
|
|
33
|
-
suspend(async () => {
|
|
34
|
-
if (typeof pluginConfig.supportedLanguages === 'function') {
|
|
35
|
-
return pluginConfig.supportedLanguages(client)
|
|
36
|
-
}
|
|
37
|
-
return pluginConfig.supportedLanguages
|
|
38
|
-
}, [workspace])
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<DocumentInternationalizationContext.Provider
|
|
42
|
-
value={{...pluginConfig, supportedLanguages}}
|
|
43
|
-
>
|
|
44
|
-
{props.renderDefault(props)}
|
|
45
|
-
</DocumentInternationalizationContext.Provider>
|
|
46
|
-
)
|
|
47
|
-
}
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import {TranslateIcon} from '@sanity/icons'
|
|
2
|
-
import {
|
|
3
|
-
Box,
|
|
4
|
-
Button,
|
|
5
|
-
Card,
|
|
6
|
-
Popover,
|
|
7
|
-
Stack,
|
|
8
|
-
Text,
|
|
9
|
-
TextInput,
|
|
10
|
-
useClickOutside,
|
|
11
|
-
} from '@sanity/ui'
|
|
12
|
-
import {uuid} from '@sanity/uuid'
|
|
13
|
-
import {type FormEvent, useCallback, useMemo, useState} from 'react'
|
|
14
|
-
import {useEditState} from 'sanity'
|
|
15
|
-
|
|
16
|
-
import {useTranslationMetadata} from '../hooks/useLanguageMetadata'
|
|
17
|
-
import type {DocumentInternationalizationMenuProps} from '../types'
|
|
18
|
-
import {useDocumentInternationalizationContext} from './DocumentInternationalizationContext'
|
|
19
|
-
import LanguageManage from './LanguageManage'
|
|
20
|
-
import LanguageOption from './LanguageOption'
|
|
21
|
-
import LanguagePatch from './LanguagePatch'
|
|
22
|
-
import Warning from './Warning'
|
|
23
|
-
|
|
24
|
-
export function DocumentInternationalizationMenu(
|
|
25
|
-
props: DocumentInternationalizationMenuProps
|
|
26
|
-
) {
|
|
27
|
-
const {documentId} = props
|
|
28
|
-
const schemaType = props.schemaType
|
|
29
|
-
const {languageField, supportedLanguages} =
|
|
30
|
-
useDocumentInternationalizationContext()
|
|
31
|
-
|
|
32
|
-
// Search filter query
|
|
33
|
-
const [query, setQuery] = useState(``)
|
|
34
|
-
const handleQuery = useCallback((event: FormEvent<HTMLInputElement>) => {
|
|
35
|
-
if (event.currentTarget.value) {
|
|
36
|
-
setQuery(event.currentTarget.value)
|
|
37
|
-
} else {
|
|
38
|
-
setQuery(``)
|
|
39
|
-
}
|
|
40
|
-
}, [])
|
|
41
|
-
|
|
42
|
-
// UI Handlers
|
|
43
|
-
const [open, setOpen] = useState(false)
|
|
44
|
-
const handleClick = useCallback(() => setOpen((o) => !o), [])
|
|
45
|
-
const [button, setButton] = useState<HTMLElement | null>(null)
|
|
46
|
-
const [popover, setPopover] = useState<HTMLElement | null>(null)
|
|
47
|
-
const handleClickOutside = useCallback(() => setOpen(false), [])
|
|
48
|
-
useClickOutside(handleClickOutside, [button, popover])
|
|
49
|
-
|
|
50
|
-
// Get metadata from content lake
|
|
51
|
-
const {data, loading, error} = useTranslationMetadata(documentId)
|
|
52
|
-
const metadata = Array.isArray(data) && data.length ? data[0] : null
|
|
53
|
-
|
|
54
|
-
// Optimistically set a metadata ID for a newly created metadata document
|
|
55
|
-
// Cannot rely on generated metadata._id from useTranslationMetadata
|
|
56
|
-
// As the document store might not have returned it before creating another translation
|
|
57
|
-
const metadataId = useMemo(() => {
|
|
58
|
-
if (loading) {
|
|
59
|
-
return null
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Once created, these two values should be the same anyway
|
|
63
|
-
return metadata?._id ?? uuid()
|
|
64
|
-
}, [loading, metadata?._id])
|
|
65
|
-
|
|
66
|
-
// Duplicate a new language version from the most recent version of this document
|
|
67
|
-
const {draft, published} = useEditState(documentId, schemaType.name)
|
|
68
|
-
const source = draft || published
|
|
69
|
-
|
|
70
|
-
// Check for data issues
|
|
71
|
-
const documentIsInOneMetadataDocument = useMemo(() => {
|
|
72
|
-
return Array.isArray(data) && data.length <= 1
|
|
73
|
-
}, [data])
|
|
74
|
-
const sourceLanguageId = source?.[languageField] as string | undefined
|
|
75
|
-
const sourceLanguageIsValid = supportedLanguages.some(
|
|
76
|
-
(l) => l.id === sourceLanguageId
|
|
77
|
-
)
|
|
78
|
-
const allLanguagesAreValid = useMemo(() => {
|
|
79
|
-
const valid = supportedLanguages.every((l) => l.id && l.title)
|
|
80
|
-
if (!valid) {
|
|
81
|
-
console.warn(
|
|
82
|
-
`Not all languages are valid. It should be an array of objects with an "id" and "title" property. Or a function that returns an array of objects with an "id" and "title" property.`,
|
|
83
|
-
supportedLanguages
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return valid
|
|
88
|
-
}, [supportedLanguages])
|
|
89
|
-
|
|
90
|
-
const content = (
|
|
91
|
-
<Box padding={1}>
|
|
92
|
-
{error ? (
|
|
93
|
-
<Card tone="critical" padding={1}>
|
|
94
|
-
<Text>There was an error returning translations metadata</Text>
|
|
95
|
-
</Card>
|
|
96
|
-
) : (
|
|
97
|
-
<Stack space={1}>
|
|
98
|
-
<LanguageManage
|
|
99
|
-
id={metadata?._id}
|
|
100
|
-
documentId={documentId}
|
|
101
|
-
metadataId={metadataId}
|
|
102
|
-
schemaType={schemaType}
|
|
103
|
-
sourceLanguageId={sourceLanguageId}
|
|
104
|
-
/>
|
|
105
|
-
{supportedLanguages.length > 4 ? (
|
|
106
|
-
<TextInput
|
|
107
|
-
onChange={handleQuery}
|
|
108
|
-
value={query}
|
|
109
|
-
placeholder="Filter languages"
|
|
110
|
-
/>
|
|
111
|
-
) : null}
|
|
112
|
-
{supportedLanguages.length > 0 ? (
|
|
113
|
-
<>
|
|
114
|
-
{/* Once metadata is loaded, there may be issues */}
|
|
115
|
-
{loading ? null : (
|
|
116
|
-
<>
|
|
117
|
-
{/* Not all languages are valid */}
|
|
118
|
-
{data && documentIsInOneMetadataDocument ? null : (
|
|
119
|
-
<Warning>
|
|
120
|
-
{/* TODO: Surface these documents to the user */}
|
|
121
|
-
This document has been found in more than one Translations
|
|
122
|
-
Metadata documents
|
|
123
|
-
</Warning>
|
|
124
|
-
)}
|
|
125
|
-
{/* Not all languages are valid */}
|
|
126
|
-
{allLanguagesAreValid ? null : (
|
|
127
|
-
<Warning>
|
|
128
|
-
Not all language objects are valid. See the console.
|
|
129
|
-
</Warning>
|
|
130
|
-
)}
|
|
131
|
-
{/* Current document has no language field */}
|
|
132
|
-
{sourceLanguageId ? null : (
|
|
133
|
-
<Warning>
|
|
134
|
-
Choose a language to apply to{' '}
|
|
135
|
-
<strong>this Document</strong>
|
|
136
|
-
</Warning>
|
|
137
|
-
)}
|
|
138
|
-
{/* Current document has an invalid language field */}
|
|
139
|
-
{sourceLanguageId && !sourceLanguageIsValid ? (
|
|
140
|
-
<Warning>
|
|
141
|
-
Select a supported language. Current language value:{' '}
|
|
142
|
-
<code>{sourceLanguageId}</code>
|
|
143
|
-
</Warning>
|
|
144
|
-
) : null}
|
|
145
|
-
</>
|
|
146
|
-
)}
|
|
147
|
-
{supportedLanguages
|
|
148
|
-
.filter((language) => {
|
|
149
|
-
if (query) {
|
|
150
|
-
return language.title
|
|
151
|
-
.toLowerCase()
|
|
152
|
-
.includes(query.toLowerCase())
|
|
153
|
-
}
|
|
154
|
-
return true
|
|
155
|
-
})
|
|
156
|
-
.map((language) =>
|
|
157
|
-
!loading && sourceLanguageId && sourceLanguageIsValid ? (
|
|
158
|
-
// Button to duplicate this document to a new translation
|
|
159
|
-
// And either create or update the metadata document
|
|
160
|
-
<LanguageOption
|
|
161
|
-
key={language.id}
|
|
162
|
-
language={language}
|
|
163
|
-
schemaType={schemaType}
|
|
164
|
-
documentId={documentId}
|
|
165
|
-
disabled={loading || !allLanguagesAreValid}
|
|
166
|
-
current={language.id === sourceLanguageId}
|
|
167
|
-
metadata={metadata}
|
|
168
|
-
metadataId={metadataId}
|
|
169
|
-
source={source}
|
|
170
|
-
sourceLanguageId={sourceLanguageId}
|
|
171
|
-
/>
|
|
172
|
-
) : (
|
|
173
|
-
// Button to set a language field on *this* document
|
|
174
|
-
<LanguagePatch
|
|
175
|
-
key={language.id}
|
|
176
|
-
source={source}
|
|
177
|
-
language={language}
|
|
178
|
-
// Only allow language patch change to:
|
|
179
|
-
// - Keys not in metadata
|
|
180
|
-
// - The key of this document in the metadata
|
|
181
|
-
disabled={
|
|
182
|
-
(loading ||
|
|
183
|
-
!allLanguagesAreValid ||
|
|
184
|
-
metadata?.translations
|
|
185
|
-
.filter((t) => t?.value?._ref !== documentId)
|
|
186
|
-
.some((t) => t._key === language.id)) ??
|
|
187
|
-
false
|
|
188
|
-
}
|
|
189
|
-
/>
|
|
190
|
-
)
|
|
191
|
-
)}
|
|
192
|
-
</>
|
|
193
|
-
) : null}
|
|
194
|
-
</Stack>
|
|
195
|
-
)}
|
|
196
|
-
</Box>
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
const issueWithTranslations =
|
|
200
|
-
!loading && sourceLanguageId && !sourceLanguageIsValid
|
|
201
|
-
|
|
202
|
-
if (!documentId) {
|
|
203
|
-
return null
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (!schemaType || !schemaType.name) {
|
|
207
|
-
return null
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return (
|
|
211
|
-
<Popover
|
|
212
|
-
animate
|
|
213
|
-
constrainSize
|
|
214
|
-
content={content}
|
|
215
|
-
open={open}
|
|
216
|
-
portal
|
|
217
|
-
ref={setPopover}
|
|
218
|
-
overflow="auto"
|
|
219
|
-
tone="default"
|
|
220
|
-
>
|
|
221
|
-
<Button
|
|
222
|
-
text="Translations"
|
|
223
|
-
mode="bleed"
|
|
224
|
-
disabled={!source}
|
|
225
|
-
tone={
|
|
226
|
-
!source || loading || !issueWithTranslations ? undefined : `caution`
|
|
227
|
-
}
|
|
228
|
-
icon={TranslateIcon}
|
|
229
|
-
onClick={handleClick}
|
|
230
|
-
ref={setButton}
|
|
231
|
-
selected={open}
|
|
232
|
-
/>
|
|
233
|
-
</Popover>
|
|
234
|
-
)
|
|
235
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import {CogIcon} from '@sanity/icons'
|
|
2
|
-
import {Box, Button, Stack, Text, Tooltip} from '@sanity/ui'
|
|
3
|
-
import {useCallback, useState} from 'react'
|
|
4
|
-
import {type ObjectSchemaType, useClient} from 'sanity'
|
|
5
|
-
|
|
6
|
-
import {METADATA_SCHEMA_NAME} from '../constants'
|
|
7
|
-
import {useOpenInNewPane} from '../hooks/useOpenInNewPane'
|
|
8
|
-
import {createReference} from '../utils/createReference'
|
|
9
|
-
import {useDocumentInternationalizationContext} from './DocumentInternationalizationContext'
|
|
10
|
-
|
|
11
|
-
type LanguageManageProps = {
|
|
12
|
-
id?: string
|
|
13
|
-
metadataId?: string | null
|
|
14
|
-
schemaType: ObjectSchemaType
|
|
15
|
-
documentId: string
|
|
16
|
-
sourceLanguageId?: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export default function LanguageManage(props: LanguageManageProps) {
|
|
20
|
-
const {id, metadataId, schemaType, documentId, sourceLanguageId} = props
|
|
21
|
-
const open = useOpenInNewPane(id, METADATA_SCHEMA_NAME)
|
|
22
|
-
const openCreated = useOpenInNewPane(metadataId, METADATA_SCHEMA_NAME)
|
|
23
|
-
const {allowCreateMetaDoc, apiVersion, weakReferences} =
|
|
24
|
-
useDocumentInternationalizationContext()
|
|
25
|
-
const client = useClient({apiVersion})
|
|
26
|
-
const [userHasClicked, setUserHasClicked] = useState(false)
|
|
27
|
-
|
|
28
|
-
const canCreate = !id && Boolean(metadataId) && allowCreateMetaDoc
|
|
29
|
-
|
|
30
|
-
const handleClick = useCallback(() => {
|
|
31
|
-
if (!id && metadataId && sourceLanguageId) {
|
|
32
|
-
/* Disable button while this request is pending */
|
|
33
|
-
setUserHasClicked(true)
|
|
34
|
-
|
|
35
|
-
// handle creation of meta document
|
|
36
|
-
const transaction = client.transaction()
|
|
37
|
-
|
|
38
|
-
const sourceReference = createReference(
|
|
39
|
-
sourceLanguageId,
|
|
40
|
-
documentId,
|
|
41
|
-
schemaType.name,
|
|
42
|
-
!weakReferences
|
|
43
|
-
)
|
|
44
|
-
const newMetadataDocument = {
|
|
45
|
-
_id: metadataId,
|
|
46
|
-
_type: METADATA_SCHEMA_NAME,
|
|
47
|
-
schemaTypes: [schemaType.name],
|
|
48
|
-
translations: [sourceReference],
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
transaction.createIfNotExists(newMetadataDocument)
|
|
52
|
-
|
|
53
|
-
transaction
|
|
54
|
-
.commit()
|
|
55
|
-
.then(() => {
|
|
56
|
-
setUserHasClicked(false)
|
|
57
|
-
openCreated()
|
|
58
|
-
})
|
|
59
|
-
.catch((err) => {
|
|
60
|
-
console.error(err)
|
|
61
|
-
setUserHasClicked(false)
|
|
62
|
-
})
|
|
63
|
-
} else {
|
|
64
|
-
open()
|
|
65
|
-
}
|
|
66
|
-
}, [
|
|
67
|
-
id,
|
|
68
|
-
metadataId,
|
|
69
|
-
sourceLanguageId,
|
|
70
|
-
client,
|
|
71
|
-
documentId,
|
|
72
|
-
schemaType.name,
|
|
73
|
-
weakReferences,
|
|
74
|
-
openCreated,
|
|
75
|
-
open,
|
|
76
|
-
])
|
|
77
|
-
|
|
78
|
-
const disabled =
|
|
79
|
-
(!id && !canCreate) || (canCreate && !sourceLanguageId) || userHasClicked
|
|
80
|
-
|
|
81
|
-
return (
|
|
82
|
-
<Tooltip
|
|
83
|
-
animate
|
|
84
|
-
content={
|
|
85
|
-
<Box padding={2}>
|
|
86
|
-
<Text muted size={1}>
|
|
87
|
-
Document has no other translations
|
|
88
|
-
</Text>
|
|
89
|
-
</Box>
|
|
90
|
-
}
|
|
91
|
-
fallbackPlacements={['right', 'left']}
|
|
92
|
-
placement="top"
|
|
93
|
-
portal
|
|
94
|
-
disabled={Boolean(id) || canCreate}
|
|
95
|
-
>
|
|
96
|
-
<Stack>
|
|
97
|
-
<Button
|
|
98
|
-
disabled={disabled}
|
|
99
|
-
mode="ghost"
|
|
100
|
-
text="Manage Translations"
|
|
101
|
-
icon={CogIcon}
|
|
102
|
-
loading={userHasClicked}
|
|
103
|
-
onClick={handleClick}
|
|
104
|
-
/>
|
|
105
|
-
</Stack>
|
|
106
|
-
</Tooltip>
|
|
107
|
-
)
|
|
108
|
-
}
|