Returning a specific number of items with `S.documentTypeList()` in Sanity.io
10 replies
Last updated: Dec 9, 2021
Hello! Is it possible to return a specific number of items, rather than all of them, for
S.documentTypeList()using the desk structure builder? Its
.filterexpects a GROQ query string, but it isn’t itself a GROQ query so adding
[0…19]doesn’t work 😢 Any other ways around this? Is there a way to access the index and pass that to
.paramsfor use in
.filter?
Dec 7, 2021, 12:38 AM
I found a previous example using
Hope that helps!
rxjsthat may work for you:
// deskStructure.js import React from 'react' import S from '@sanity/base/structure-builder' import documentStore from 'part:@sanity/base/datastore/document' import {map} from 'rxjs/operators' ... const query = `*[_type == 'room'][0...19]` export default S.listItem() .title('Recently Published Rooms') .child(() => documentStore.listenQuery(query).pipe( map(rooms => S.list() .title('Rooms') .items([ ...rooms.map(room => S.listItem() .title(room.title) ) ]) ) ) )
Dec 7, 2021, 1:35 AM
Alternatively, I've worked out the following that does not require `rxjs`:
import client from 'part:@sanity/base/client' import S from '@sanity/desk-tool/structure-builder' const sanityClient = client.withConfig({apiVersion: '2021-03-25'}) const query = `*[_type == 'room']| order(_updatedAt desc)[0...19]` export default S.listItem() .title('Recently Published Rooms') .child(async () => { const rooms = await sanityClient.fetch(query) return S.list() .title('Recently Published Rooms') .items([ ...rooms.map(room => S.listItem() .id(room._id) .title(room.title) .child( S.document() .id(room._id) ) ) ]) })
Dec 7, 2021, 3:46 AM
Alternatively, I've worked out the following that does not require `rxjs`:
import client from 'part:@sanity/base/client' import S from '@sanity/desk-tool/structure-builder' const sanityClient = client.withConfig({apiVersion: '2021-03-25'}) const query = `*[_type == 'room']| order(_updatedAt desc)[0...19]` export default S.listItem() .title('Recently Published Rooms') .child(async () => { const rooms = await sanityClient.fetch(query) return S.list() .title('Recently Published Rooms') .items([ ...rooms.map(room => S.listItem() .id(room._id) .title(room.title) .child( S.document() .id(room._id) ) ) ]) })
Dec 7, 2021, 3:46 AM
A
While the snippet without rxjs works well for static lists it won’t receive updated content. So changing the title of a document won’t be visible in the list. I think both of the snippets will show both drafts and published items in the same lists.
Dec 8, 2021, 6:50 AM
&& !(_id in path("drafts.**"))to the query,
user B
, I’m not able to update the title shown in the list when I update the document. Is there a way to do it without rxjs? I’d prefer not to add a new library just for this.Dec 8, 2021, 6:23 PM
I believe you need to use the bit if you want updates without rerendering the pane.
documentStore.listenQuery(query).pipe(...)
Dec 8, 2021, 6:25 PM
Updating what ended up working for me, in case anyone is looking for a similar solution:
const newRoomsQuery = `*[_type == 'room' && !(_id in path("drafts.**"))]| order(date desc)[0..19]` const newRooms = await sanityClient.fetch(newRoomsQuery) .items([ S.listItem({ id: 'newest-rooms', title: 'New', icon: MdNewReleases, child: () => S.list() .title('New Rooms') .items([ ...newRooms?.map(room => S.documentListItem().id(room._id).schemaType('room') ) ]) }), // ... ])
Dec 9, 2021, 12:59 AM
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.