๐Ÿ”ฎ Sanity Create is here. Writing is reinvented. Try now, no developer setup

Difference between S.editor() and S.document() and how to disable deletion and unpublishing of certain document types in Sanity.io

8 replies
Last updated: Feb 8, 2022
Maybe a noobie question, but what is the difference between
S.editor()
and
S.document()
I have created a settings document parent type with nested settings menu. But I want to disable the possibility to make it visible as a singular type instead of a document which can be repeated like posts, articles blogs etc. How can I prevent these pages from being deleted, unpublished?
I have a custom "*documentActions*" but it's kinda ugly, wondering if you build the menu with ListItems if there is a property out of the box to disable deletion, unpublish, for these settings pages.

My code.. but wondering if there is a cleaner way
๐Ÿ˜„?
import userStore from "part:@sanity/base/user";

import defaultResolve, {
  UnpublishAction,
  DuplicateAction,
  DeleteAction,
} from "part:@sanity/base/document-actions";

const documentActions = (props) => {
  return props.type === "navigation" ||
    props.type === "general" ||
    props.type === "featured" ||
    props.type === "promo" ||
    props.type === "cookie" ||
    props.type === "friends"
    ? [
        ...defaultResolve(props).filter(
          (action) =>
            action !== UnpublishAction &&
            action !== DuplicateAction &&
            action !== DeleteAction
        ),
      ]
    : [...defaultResolve(props)];
};

export default documentActions;

Feb 8, 2022, 1:38 PM
Hey
user M
๐Ÿ˜„ !
I have this now, Will refactor later on. Where should the second code part go?


import defaultResolve, {
  PublishAction,
} from "part:@sanity/base/document-actions";

const singleEdits = [
  "navigation",
  "general",
  "featured",
  "promo",
  "cookie",
  "friends",
];

export default function resolveDocumentActions(props) {
  if (singleEdits.includes(props.type)) {
    return defaultResolve(props).filter((action) => action == PublishAction);
  }

  return [...defaultResolve(props)];
}

Feb 8, 2022, 7:08 PM
Ah sorry, that your new document menu. You can see how to set that up here .
Feb 8, 2022, 7:15 PM
user M
The first part seems to be enough. Itโ€™s only possible to Publish action and not create any new document inside the settings and sub settings menu items.
Not sure, but when you apply
$.editor()
instead of
$.document()
it behaves like a single item.
Take a look:


import React from "react";

import S from "@sanity/base/structure-builder";

import { Gear, Cookie, List, Star, Sliders, FlagBanner } from "phosphor-react";

import { icon } from "../lib/helpers";

const { color, weight, size } = icon;

const generalMenu = S.listItem()
  .title("General")
  .icon(() => <Gear color={color} weight={weight} size={size} />)
  .child(
    S.editor()
      .schemaType("general")
      .documentId("generalSettings")
      .title("General Settings")
  );

const navMenu = S.listItem()
  .title("Navigation")
  .icon(() => <List color={color} weight={weight} size={size} />)
  .child(
    S.editor()
      .schemaType("navigation")
      .documentId("navigationSettings")
      .title("Navigation Settings")
  );

const featuredMenu = S.listItem()
  .title("Featured Articles")
  .icon(() => <Star color={color} weight={weight} size={size} />)
  .child(
    S.editor()
      .schemaType("featured")
      .documentId("featuredSettings")
      .title("Featured Articles")
  );

const cookieMenu = S.listItem()
  .title("Cookie Consent")
  .icon(() => <Cookie color={color} weight={weight} size={size} />)
  .child(
    S.editor()
      .schemaType("cookie")
      .documentId("cookieSettings")
      .title("Cookie Consent Settings")
  );

const promoBarMenu = S.listItem()
  .title("Promo Bar")
  .icon(() => <FlagBanner color={color} weight={weight} size={size} />)
  .child(
    S.editor()
      .schemaType("promo")
      .documentId("promoBarSettings")
      .title("Promo Bar Settings")
  );

export const settingsMenu = S.listItem()
  .title("Settings")
  .child(
    S.list()
      .title("Settings")
      .items([
        generalMenu,
        S.divider(),
        navMenu,
        S.divider(),
        featuredMenu,
        S.divider(),
        cookieMenu,
        S.divider(),
        promoBarMenu,
      ])
  )
  .icon(() => <Sliders color={color} weight={weight} size={size} />);
documentActions.js

Iโ€™v included the DiscardChanges
๐Ÿ˜„ is it good like so?
import defaultResolve, {
  DiscardChangesAction,
  PublishAction,
} from "part:@sanity/base/document-actions";

console.table(defaultResolve);

const singleEdits = [
  "navigation",
  "general",
  "featured",
  "promo",
  "cookie",
  "friends",
];

export default function resolveDocumentActions(props) {
  if (singleEdits.includes(props.type)) {
    return defaultResolve(props).filter(
      (action) => action === PublishAction || action === DiscardChangesAction
    );
  }

  return [...defaultResolve(props)];
}

Feb 8, 2022, 7:30 PM
Yep, that should work! Not sure on the
.editor
and
.document
methods though. I always just use
.document
since it has more documentation in the reference.
Feb 8, 2022, 7:39 PM
user M
Oke ๐Ÿ˜Š, finally works like a charm the only problem now, I need the โ€œ*`DiscardChangesAction`*โ€ itโ€™s working for general, promo, cookie. But not for navigation and featured which are both array fields?

import defaultResolve, {
  DiscardChangesAction,
  PublishAction,
} from "part:@sanity/base/document-actions";

const singleSettings = [
  "general",
  "navigation",
  "featured",
  "promo",
  "cookie",
  "friends",
];

const resolveDocumentActions = (props) => {
  if (singleSettings.includes(props.type)) {
    console.log(props);
    return defaultResolve(props).filter(
      (action) => action === PublishAction || action === DiscardChangesAction
    );
  }

  return [...defaultResolve(props)];
};

export default resolveDocumentActions;
Feb 8, 2022, 7:45 PM
I would think that
navigation
and
featured
aren't the actual types that get passed in, so
props.type
is something else. Can you check by `console.log`ging
props.type
?
Feb 8, 2022, 8:15 PM
user M
Figured it out never published anything to make the discard button visible thanks๐Ÿ™Œ
Feb 8, 2022, 8:20 PM
user M
Figured it out never published anything to make the discard button visible thanks๐Ÿ™Œ
Feb 8, 2022, 8:20 PM

Sanityโ€“ build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?