Q42 / sanity-plugin-page-tree

MIT License
23 stars 3 forks source link

Assigning slug & parent to tab/groups #32

Open praveensewak opened 2 months ago

praveensewak commented 2 months ago

How do you assign the slug & parent fields to tab groups?

edustef commented 2 months ago

It's unfortunate that there's no option for this but what I did was re-export the definePageType and map the fields in the pageTreeType and assign the group to the slug and parent component.

On top of that I've also added a validation for the parent field so that if the current document language is english and you're trying to add a parent a page with french language it will give a validation error. This is optional and you can remove it if you wish.

import {definePageType as _definePageType} from '@q42/sanity-plugin-page-tree'

import {apiVersion} from '../env'
import {Reference, Rule, ValidationContext} from 'sanity'

type Props = Parameters<typeof _definePageType>
type Return = ReturnType<typeof _definePageType>

const DEFAULT_GROUP = 'main'

/**
 * Validates that the parent document has the same language as the current document.
 */
const validateParent = async (parent: Reference | undefined, context: ValidationContext) => {
  if (!parent || !context.document) return 'Parent is required'

  const client = context.getClient({
    apiVersion: apiVersion,
  })

  const document = await client.fetch(`*[_id == $parentRef][0] {language}`, {
    parentRef: parent._ref,
  })

  if (document.language !== context.document.language)
    return 'Parent language does not match the language of this document'

  return true
}

/**
 * Extends the page tree type definition. Adds slug and parent fields to the main group
 * and adds validation to the parent field to ensure that the parent document
 * has the same language as the current document.
 */
export function definePageType(...props: Props): Return {
  const pageTreeType = _definePageType(...props)

  const fields = pageTreeType.fields.map((field) => {
    if (field.name === 'slug') {
      return {
        ...field,
        group: DEFAULT_GROUP,
      }
    }

    if (field.name === 'parent') {
      return {
        ...field,
        group: DEFAULT_GROUP,
        // you can remove this if you wish
        validation: (Rule: Rule) => Rule.custom(validateParent),
      }
    }

    return field
  })

  return {
    ...pageTreeType,
    fields,
  }
}

So for usage it's just like before but you're using your own definePageType instead of the one from the library.


- import {definePageType} from "@q42/sanity-plugin-page-tree"
+ import {definePageType} from "src/utils/definePageType.ts"
import {pageTreeConfig} from 'src/utils/pageTreeConfig'

...
...
export const page = definePageType(_page, pageTreeConfig)

Hope this helps.

djohalo2 commented 1 month ago

@edustef Thanks for providing your workaround, but this should be possible already with the fieldsGroupName option for definePageType.

@praveensewak I would expect the following to achieve the same:

definePageType('homePage', config, {
  fieldsGroupName: 'main'
})

Let me know if this is what you are both looking for, so I can close the issue 👍

djohalo2 commented 1 month ago

Also @edustef I see you have made a custom parent validator to help content editors to not configure mismatching parent-child relations with different languages. Great idea! I'll create an issue for this if you don't mind. If you want you can also make a PR for it, otherwise I might add this when I have the time 😄

edustef commented 1 month ago

Hey @djohalo2 thanks for letting us know about the option I had no idea! I think it should be mentioned in the readme somewhere because it's really useful.

As for the parent validator not sure how great the core is as I didn't spend a lot of time on it 😄 but I think it would be awesome to have this into the plugin itself