Created
January 31, 2023 01:11
-
-
Save runeb/f9d59702c2580249b3df638decdb0e19 to your computer and use it in GitHub Desktop.
Example of a custom tool to discover possibly orphaned documents, create a mutation to delete them and optionally perform the mutation
This file contains hidden or 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
import * as React from 'react' | |
import {definePlugin, SanityClient, useClient, useSchema} from 'sanity' | |
import type {Tool} from 'sanity' | |
import {Card, Stack, Grid, Checkbox, Flex, Box, Text, Heading, Button} from '@sanity/ui' | |
import {useEffect} from 'react' | |
type ToolProps = { | |
tool: Tool | |
} | |
const Mutation = ({typeNames, client}: {typeNames: string[]; client: SanityClient}) => { | |
const mutation = { | |
delete: { | |
query: '*[_type in $types]', | |
params: { | |
types: typeNames, | |
}, | |
}, | |
} | |
const onClick = () => { | |
client | |
.mutate([mutation]) | |
.then(console.log) | |
.catch(console.error) | |
.finally(() => alert('See console for results, reload to update schema types')) | |
} | |
return ( | |
<Card> | |
<pre>{JSON.stringify(mutation, null, 2)}</pre> | |
<Button onClick={onClick} disabled={!typeNames || typeNames.length === 0} tone="critical"> | |
Delete | |
</Button> | |
</Card> | |
) | |
} | |
const ToolComponent = ({tool}: ToolProps) => { | |
const schema = useSchema() | |
const client = useClient({apiVersion: '2021-03-25'}) | |
const [undefinedNames, setUndefinedNames] = React.useState<string[]>() | |
const [schemaNames, setSchemaNames] = React.useState<string[]>() | |
const [selected, setSelected] = React.useState<Record<string, any>>({}) | |
const [count, setCount] = React.useState<number>() | |
useEffect(() => { | |
const documentNames = schema._original?.types | |
.filter((type) => type.type === 'document') | |
.map((type) => type.name) | |
setSchemaNames(documentNames) | |
}, [schema]) | |
useEffect(() => { | |
console.log('Fetching undefined names') | |
client.fetch<string[]>('array::unique(*[]._type)').then((names) => { | |
// Pick out the names that do not appear in documentNames | |
const types = names.filter((name) => !schemaNames?.includes(name)) | |
setUndefinedNames(types) | |
setSelected({}) | |
}) | |
}, [client, schemaNames]) | |
useEffect(() => { | |
if (selected) { | |
const types = Object.keys(selected).filter((key) => selected[key]) | |
client.fetch(`count(*[_type in $types])`, {types}).then(setCount) | |
} | |
}, [selected, client]) | |
return ( | |
<Card padding={2}> | |
<Stack space={2}> | |
<Heading>Document types in dataset not in schema definition</Heading> | |
<Text> | |
Note that in certain cases there may be a different workspace or Studio that cares about | |
those schema types! | |
</Text> | |
<Grid columns={[2, 3, 4, 6]} gap={[1, 1, 2, 3]} padding={4}> | |
{undefinedNames?.map((name) => ( | |
<React.Fragment key={name}> | |
<Flex align="center"> | |
<Checkbox | |
id="checkbox" | |
style={{display: 'block'}} | |
onChange={() => { | |
setSelected({...selected, [name]: !selected[name]}) | |
}} | |
/> | |
<Box flex={1} paddingLeft={3}> | |
<Text> | |
<label htmlFor="checkbox">{name}</label> | |
</Text> | |
</Box> | |
</Flex> | |
</React.Fragment> | |
))} | |
</Grid> | |
</Stack> | |
<Stack space={2}> | |
<Heading>Mutation for deleting documents</Heading> | |
<Text>Matches {count} documents</Text> | |
</Stack> | |
<Mutation client={client} typeNames={Object.keys(selected).filter((key) => selected[key])} /> | |
</Card> | |
) | |
} | |
const tools: Tool[] = [ | |
{ | |
name: 'delete-undefined', | |
title: 'Unknown docs', | |
component: ToolComponent, | |
}, | |
] | |
export const deleteUndefined = definePlugin({ | |
name: 'delete-undefined', | |
tools, | |
}) |
This file contains hidden or 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
import {defineConfig} from 'sanity' | |
import {deskTool} from 'sanity/desk' | |
import {visionTool} from '@sanity/vision' | |
import {schemaTypes} from './schemas' | |
// Importing the plugin defined in the other file | |
import { deleteUndefined } from './deleteUndefined' | |
export default defineConfig({ | |
name: 'default', | |
title: 'Clean Sandbox', | |
projectId: 'kbrhtt13', | |
dataset: 'v3', | |
plugins: [ | |
deskTool(), | |
visionTool(), | |
// Here we add it to the Studio | |
deleteUndefined() | |
], | |
schema: { | |
types: schemaTypes, | |
}, | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment