-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'padms/i18n-even-more-custom' into staging
- Loading branch information
Showing
59 changed files
with
4,102 additions
and
1,261 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { useToast } from '@sanity/ui' | ||
import { DocumentActionComponent, DocumentActionDescription, DocumentActionProps, DocumentActionsContext } from 'sanity' | ||
import { defaultLanguage } from '../languages' | ||
import { apiVersion } from '../sanity.client' | ||
|
||
export function createCustomDuplicateAction(originalAction: DocumentActionComponent, context: DocumentActionsContext) { | ||
const CustumDuplicateAction = (props: DocumentActionProps) => { | ||
const originalResult = originalAction(props) as DocumentActionDescription | ||
const toast = useToast() | ||
return { | ||
...originalResult, | ||
onHandle: () => { | ||
context | ||
.getClient({ apiVersion: apiVersion }) | ||
.fetch(/* groq */ `*[_id match '*'+$id][0]{lang}`, { id: context.documentId }) | ||
.then((result) => { | ||
if (result?.lang == defaultLanguage.name) { | ||
// allow duplicate action only on bas language | ||
originalResult.onHandle && originalResult.onHandle() | ||
} else { | ||
toast.push({ | ||
duration: 7000, | ||
status: 'error', | ||
title: 'Cannot duplicate the translation.', | ||
}) | ||
} | ||
}) | ||
.catch((error) => { | ||
console.log(error) | ||
toast.push({ | ||
duration: 7000, | ||
status: 'error', | ||
title: 'Failed to duplicate', | ||
}) | ||
}) | ||
}, | ||
} | ||
} | ||
return CustumDuplicateAction | ||
} |
122 changes: 122 additions & 0 deletions
122
sanityv3/actions/customDelete/DeleteTranslationAction.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { TrashIcon } from '@sanity/icons' | ||
import { type ButtonTone, useToast } from '@sanity/ui' | ||
import { useCallback, useState } from 'react' | ||
import { type DocumentActionComponent, type SanityDocument, useClient } from 'sanity' | ||
import DeleteTranslationDialog from './components/DeleteTranslationDialog' | ||
import DeleteTranslationFooter from './components/DeleteTranslationFooter' | ||
import { useDocumentInternationalizationContext } from '@equinor/document-internationalization' | ||
import { apiVersion } from '../../sanity.client' | ||
import { defaultLanguage } from '../../languages' | ||
import { Patch, Transaction } from '@sanity/client' | ||
|
||
const TRANSLATIONS_ARRAY_NAME = 'translations' | ||
export const DeleteTranslationAction: DocumentActionComponent = (props) => { | ||
const { languageField } = useDocumentInternationalizationContext() | ||
|
||
const doc = props.draft || props.published | ||
const documentLanguage = doc ? doc[languageField] : null | ||
const isDefaultLanguageDocument = defaultLanguage.name === documentLanguage | ||
|
||
const { id: documentId } = props | ||
const [isDialogOpen, setDialogOpen] = useState(false) | ||
const [translations, setTranslations] = useState<SanityDocument[]>([]) | ||
const [hasOtherReferences, setHasOtherReferences] = useState<boolean>(false) | ||
const onClose = useCallback(() => setDialogOpen(false), []) | ||
|
||
const toast = useToast() | ||
const client = useClient({ apiVersion: apiVersion }) | ||
|
||
const unsetAndDeleteCurrentTranslation = (tx: Transaction) => { | ||
//unset current translation reference from metadata | ||
translations.forEach((translation) => { | ||
tx.patch(translation._id, (patch: Patch) => | ||
patch.unset([`${TRANSLATIONS_ARRAY_NAME}[_key == "${documentLanguage}"]`]), | ||
) | ||
}) | ||
|
||
// delete the current document | ||
tx.delete(documentId) | ||
tx.delete(`drafts.${documentId}`) | ||
} | ||
|
||
const unsetAndDeleteDefaultWithMetaData = (tx: Transaction) => { | ||
//unset translation references array in metadata | ||
translations.forEach((translation) => { | ||
tx.patch(translation._id, (patch) => patch.unset([TRANSLATIONS_ARRAY_NAME])) | ||
}) | ||
|
||
// delete each of the translations and delete metadata | ||
if (translations.length > 0) { | ||
translations.forEach((translation: any) => { | ||
translation.translations.forEach((it: any) => { | ||
tx.delete(it.id) | ||
tx.delete(`drafts.${it.id}`) | ||
}) | ||
tx.delete(translation._id) | ||
// Shouldn't exist as this document type is in liveEdit | ||
tx.delete(`drafts.${translation._id}`) | ||
}) | ||
} else { | ||
//simply a doc without metadata.. so delete it. | ||
|
||
tx.delete(documentId) | ||
tx.delete(`drafts.${documentId}`) | ||
} | ||
} | ||
// Remove translation reference and delete document in one transaction | ||
const onProceed = useCallback(() => { | ||
const tx = client.transaction() | ||
if (isDefaultLanguageDocument) { | ||
unsetAndDeleteDefaultWithMetaData(tx) | ||
} else { | ||
unsetAndDeleteCurrentTranslation(tx) | ||
} | ||
|
||
tx.commit() | ||
.then(() => { | ||
onClose() | ||
toast.push({ | ||
status: 'success', | ||
title: 'Deleted document and translations', | ||
}) | ||
}) | ||
.catch((err) => { | ||
toast.push({ | ||
status: 'error', | ||
title: 'Failed to delete document and translations', | ||
description: err.message, | ||
}) | ||
}) | ||
}, [client, translations, documentId, onClose, toast]) | ||
Check warning on line 90 in sanityv3/actions/customDelete/DeleteTranslationAction.tsx GitHub Actions / check-code
|
||
|
||
return { | ||
label: `Delete translation...`, | ||
disabled: !doc || !documentLanguage, | ||
icon: TrashIcon, | ||
tone: 'critical' as ButtonTone, | ||
onHandle: () => { | ||
setDialogOpen(true) | ||
}, | ||
dialog: isDialogOpen && { | ||
type: 'dialog', | ||
onClose, | ||
header: 'Delete translation', | ||
content: doc ? ( | ||
<DeleteTranslationDialog | ||
doc={doc} | ||
documentId={documentId} | ||
setTranslations={setTranslations} | ||
setHasOtherReferences={setHasOtherReferences} | ||
/> | ||
) : null, | ||
footer: ( | ||
<DeleteTranslationFooter | ||
onClose={onClose} | ||
onProceed={onProceed} | ||
translations={translations} | ||
disable={hasOtherReferences} | ||
/> | ||
), | ||
}, | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
sanityv3/actions/customDelete/components/DeleteTranslationDialog/DocumentPreview.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Preview, useSchema } from 'sanity' | ||
import { Feedback } from 'sanity-plugin-utils' | ||
|
||
type DocumentPreviewProps = { | ||
value: unknown | ||
type: string | ||
} | ||
|
||
// Wrapper of Preview just so that the schema type is satisfied by schema.get() | ||
export default function DocumentPreview(props: DocumentPreviewProps) { | ||
const schema = useSchema() | ||
|
||
const schemaType = schema.get(props.type) | ||
if (!schemaType) { | ||
return <Feedback tone="critical" title="Schema type not found" /> | ||
} | ||
|
||
return <Preview value={props.value} schemaType={schemaType} /> | ||
} |
90 changes: 90 additions & 0 deletions
90
sanityv3/actions/customDelete/components/DeleteTranslationDialog/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import { Card, Flex, Spinner, Stack, Text } from '@sanity/ui' | ||
import { useEffect, useMemo, useState } from 'react' | ||
import { SanityDocument } from 'sanity' | ||
import { useClient } from 'sanity' | ||
import { separateReferences } from './seperateReferences' | ||
import { apiVersion } from '../../../../sanity.client' | ||
import { defaultLanguage } from '../../../../languages' | ||
import DocumentPreview from './DocumentPreview' | ||
|
||
type DeleteTranslationDialogProps = { | ||
doc: SanityDocument | ||
documentId: string | ||
setTranslations: (translations: SanityDocument[]) => void | ||
setHasOtherReferences: (hasOtherReferences: boolean) => void | ||
} | ||
|
||
export default function DeleteTranslationDialog(props: DeleteTranslationDialogProps) { | ||
const { doc, documentId, setTranslations, setHasOtherReferences } = props | ||
|
||
const client = useClient({ apiVersion: apiVersion }) | ||
const [data, setData] = useState<SanityDocument[]>() | ||
|
||
const getData = async () => { | ||
const data = await client.fetch<SanityDocument[]>( | ||
/* groq */ `*[_type == "translation.metadata" && references($id)]{ | ||
..., | ||
_id, | ||
translations[]{ | ||
"id":@.value._ref, | ||
"doc": @.value-> | ||
} | ||
}{ | ||
..., | ||
translations[]{ | ||
..., | ||
"dependants": *[references(^.id) && _type!= "translation.metadata"] | ||
} | ||
}`, | ||
{ id: documentId }, | ||
) | ||
setLoading(false) | ||
setData(data) | ||
} | ||
const [loading, setLoading] = useState<Boolean>(true) | ||
// Get all references and check if any of them are translations metadata | ||
|
||
if (loading) getData() | ||
const { translations, otherReferences, translatedDocs } = useMemo(() => separateReferences(data), [data]) | ||
|
||
useEffect(() => { | ||
setTranslations(translations) | ||
}, [setTranslations, translations]) | ||
useEffect(() => { | ||
setHasOtherReferences(otherReferences.length > 0) | ||
}, [setHasOtherReferences, otherReferences]) | ||
|
||
if (loading) { | ||
return ( | ||
<Flex padding={4} align="center" justify="center"> | ||
<Spinner /> | ||
</Flex> | ||
) | ||
} | ||
|
||
return ( | ||
<Stack space={4}> | ||
{translations && translations.length > 0 && doc.lang === defaultLanguage.name ? ( | ||
<> | ||
<Text>Delete this document and its translations?</Text> | ||
{translatedDocs.length > 0 && | ||
translatedDocs.map((it) => <DocumentPreview key={it._id} value={it} type={it._type} />)} | ||
</> | ||
) : ( | ||
<Text>Delete this document?</Text> | ||
)} | ||
{otherReferences.length > 0 && ( | ||
<> | ||
<Card borderTop /> | ||
<> | ||
You may not be able to delete this document as there are other published references to this document (or its | ||
translations). | ||
</> | ||
{otherReferences.map((it) => ( | ||
<DocumentPreview key={it._id} value={it} type={it._type} /> | ||
))} | ||
</> | ||
)} | ||
</Stack> | ||
) | ||
} |
23 changes: 23 additions & 0 deletions
23
sanityv3/actions/customDelete/components/DeleteTranslationDialog/seperateReferences.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { SanityDocument } from 'sanity' | ||
|
||
export function separateReferences(data: SanityDocument[] | null = []): { | ||
translations: SanityDocument[] | ||
translatedDocs: SanityDocument[] | ||
otherReferences: SanityDocument[] | ||
} { | ||
const translations: SanityDocument[] = [] | ||
const otherReferences: SanityDocument[] = [] | ||
const translatedDocs: SanityDocument[] = [] | ||
|
||
if (data && data.length > 0) { | ||
data.forEach((translationMetadata: SanityDocument) => { | ||
translations.push(translationMetadata) | ||
;(translationMetadata.translations as SanityDocument[]).forEach((translation: SanityDocument) => { | ||
if (translation.doc) translatedDocs.push(translation.doc as SanityDocument) | ||
otherReferences.push(...(translation.dependants as SanityDocument[])) | ||
}) | ||
}) | ||
} | ||
|
||
return { translations, otherReferences, translatedDocs } | ||
} |
23 changes: 23 additions & 0 deletions
23
sanityv3/actions/customDelete/components/DeleteTranslationFooter.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { Button, Grid } from '@sanity/ui' | ||
|
||
type DeleteTranslationFooterProps = { | ||
translations: unknown[] | ||
disable: boolean | ||
onClose: () => void | ||
onProceed: () => void | ||
} | ||
|
||
export default function DeleteTranslationFooter(props: DeleteTranslationFooterProps) { | ||
const { translations, onClose, onProceed, disable } = props | ||
return ( | ||
<Grid columns={2} gap={2}> | ||
<Button text="Cancel" onClick={onClose} mode="ghost" /> | ||
<Button | ||
text={translations && translations.length > 0 ? `Delete document and translations` : `Delete document`} | ||
onClick={onProceed} | ||
tone="critical" | ||
disabled={disable} | ||
/> | ||
</Grid> | ||
) | ||
} |
Oops, something went wrong.