sanity-io/sanity-studio-secrets

How do you use this?

Opened this issue · 2 comments

pm0u commented

What do I do with MyComponent to use this package? it's not exported in the example...

pm0u commented

I'll just include here the way I used this was to add a secrets button to the navbar that opens this dialog. in my case the button is only shown for certain roles.

// src/components/secrets-toolbar.tsx

import { useState, useEffect, useCallback } from "react"
import { ToolMenuProps, ToolLink, useCurrentUser } from "sanity"
import { Button, Flex, Box } from "@sanity/ui"
import { PlugIcon, CogIcon } from "@sanity/icons"
import { fullEditorRoles } from "../../deskStructure"
import { SecretInput } from "./secrets"

export const SecretsToolbar = (props: ToolMenuProps) => {
  const { activeToolName, context, tools } = props
  const user = useCurrentUser()
  const [authorized, setAuthorized] = useState(false)
  const [secretsOpen, setSecretsOpen] = useState(false)
  const isSidebar = context === "sidebar"

  const closeSecrets = useCallback(() => {
    setSecretsOpen(false)
  }, [])

  const openSecrets = useCallback(() => {
    setSecretsOpen(true)
  }, [])

  // Change flex direction depending on context
  const direction = isSidebar ? "column" : "row"

  useEffect(() => {
    if (user) {
      setAuthorized(user.roles.some((role) => fullEditorRoles.has(role.name)))
    }
  }, [user])

  return (
    <Flex gap={1} direction={direction}>
      {tools.map((tool) => (
        <Button
          as={ToolLink}
          icon={tool.icon || PlugIcon}
          key={tool.name}
          name={tool.name}
          padding={3}
          selected={tool.name === activeToolName}
          text={tool.title || tool.name}
          tone="primary"
        />
      ))}
      {authorized ? (
        <>
          <Box padding={2}>
            <p
              style={{
                border: "1px solid white",
                opacity: 0.4,
                height: "100%",
                margin: "0",
              }}
            />
          </Box>
          <Button
            as={"button"}
            name="Secrets"
            padding={3}
            selected={secretsOpen}
            text="Secrets"
            tone="caution"
            icon={CogIcon}
            onClick={openSecrets}
            type="button"
            style={{ cursor: "pointer" }}
          />
        </>
      ) : null}
      {secretsOpen ? (
        <SecretInput open={secretsOpen} onClose={closeSecrets} />
      ) : null}
    </Flex>
  )
}

above mostly copied from https://www.sanity.io/docs/studio-components-reference#6cb8d4c1f81b

// src/components/secrets-toolbar.ts
import { SettingsView } from "@sanity/studio-secrets"

export const secretsNamespace = "secrets"

const secretConfigs = [
...
]

export const SecretInput = ({
  open,
  onClose,
}: {
  open: boolean
  onClose: () => void
}) => {
  if (!open) {
    return null
  }

  return (
    <SettingsView
      title={"Secret Settings"}
      namespace={secretsNamespace}
      keys={secretConfigs}
      onClose={onClose}
    />
  )
}
// plugins/secrets-toolbar.ts
import { definePlugin } from "sanity"
import { SecretsToolbar } from "../src/components/secrets-toolbar"

export const secretsToolbar = definePlugin({
  name: "secrets-toolbar",
  studio: {
    components: {
      toolMenu: SecretsToolbar,
    },
  },
})

Relevant config

// sanity.config.ts
import { secretsToolbar } from "./plugins/secrets-toolbar"

export default defineConfig({
  ...
  plugins: [
    ...
    secretsToolbar(),
  ],
  ...
})

image

image

Thanks for figuring this out @pm0u I was struggling with it too, not many examples out there 🤔