{JSON.stringify(props, null, 2)}; 6 | } 7 | 8 | export default withDocument(SlotPreview); 9 | -------------------------------------------------------------------------------- /studio/src/resolveProductionUrl.ts: -------------------------------------------------------------------------------- 1 | import { getEnvironment, rootURLs } from "./urlResolver"; 2 | 3 | export default function resolveProductionUrl(doc) { 4 | if (!["route", "page"].includes(doc._type)) { 5 | return null; 6 | } 7 | 8 | const previewUrl = new URL(rootURLs[getEnvironment()].web); 9 | previewUrl.pathname = `/api/preview`; 10 | previewUrl.searchParams.append( 11 | `secret`, 12 | process.env.SANITY_STUDIO_PREVIEW_SECRET 13 | ); 14 | previewUrl.searchParams.append(`slug`, doc?.slug?.current ?? `/`); 15 | 16 | return previewUrl.toString(); 17 | } 18 | -------------------------------------------------------------------------------- /studio/src/setMissingField.ts: -------------------------------------------------------------------------------- 1 | import sanityClient from "part:@sanity/base/client"; 2 | 3 | const versionedClient = sanityClient.withConfig({ 4 | apiVersion: "2021-03-15", 5 | }); 6 | 7 | /** 8 | * 9 | * Sets the field to the provided value, only if it is missing for the provided type. 10 | * 11 | * ## Usage 12 | * Simply put this in a schema-file: then it will run during studio start. 13 | * It is idempotent, so rerunning it should be safe (when the path has value, nothing is done). 14 | * 15 | * `setMissingField('my-type', 'path.to.field', 'value-to-set').catch(console.error);` 16 | * 17 | * ## Caveates 18 | * For this to work, parent object must already exist for nested objects. 19 | * 20 | * @param type document type name 21 | * @param path jsonpath, eg: some.nested.field 22 | * @param value the value to setIfMissing for the field 23 | */ 24 | export async function setMissingField( 25 | type: string, 26 | path: string, 27 | value: unknown 28 | ) { 29 | const transaction = versionedClient.transaction(); 30 | const ids: string[] = await versionedClient.fetch( 31 | `* [_type=="${type}" && !defined(${path})]._id` 32 | ); 33 | 34 | console.log(`patching path ${path} for ids`, ids); 35 | 36 | ids.forEach((id) => { 37 | const patch = versionedClient.patch(id).setIfMissing({ 38 | [path]: value, 39 | }); 40 | transaction.patch(patch); 41 | }); 42 | return transaction.commit(); 43 | } 44 | -------------------------------------------------------------------------------- /studio/src/spec.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import S from "@sanity/desk-tool/structure-builder"; 3 | import { IntentLink } from "part:@sanity/base/router"; 4 | import client from "part:@sanity/base/client"; 5 | import { Card, Container, Flex, Stack, Text } from "@sanity/ui"; 6 | 7 | export const SpecPreview = (props) => { 8 | const { document } = props; 9 | const { published } = document; 10 | if (!published) { 11 | return ( 12 |
No content found.
14 |{JSON.stringify(doc, null, 2)}75 |
US: May 24–25, 2022
28 |UK & Europe: May 25–26, 2022
29 |Hosted by Sanity
30 |{description}
32 |38 | {summary} 39 |
40 | )} 41 | {callToAction && ( 42 |{children}
,
43 | link: ({ children, value }) => {
44 | const url = getEntityPath(value?.internal) || value?.external;
45 | return url ? (
46 |
50 | {children}
51 |
52 | ) : (
53 | <>{children}>
54 | );
55 | },
56 | },
57 | };
58 |
59 | interface TextBlockProps {
60 | value?:
61 | | PortableTextBlock[]
62 | | PortableTextBlock
63 | | RichTextSection
64 | | RichTextSection[];
65 | }
66 |
67 | export const TextBlock = ({ value }: TextBlockProps) =>
68 | value ?