diff --git a/plasmicpkgs/plasmic-content-stack/src/contentstack.tsx b/plasmicpkgs/plasmic-content-stack/src/contentstack.tsx index 79965b94571..65c89cbcc7a 100644 --- a/plasmicpkgs/plasmic-content-stack/src/contentstack.tsx +++ b/plasmicpkgs/plasmic-content-stack/src/contentstack.tsx @@ -77,18 +77,24 @@ export function ContentStackCredentialsProvider({ } interface ContentStackFetcherProps { - entryUID?: string; contentType?: string; - limit?: number; + fetchType?: string; + entryUID?: string; + filter?: boolean; + filterField?: string; + filterType?: 'where' | 'greaterThanOrEqualTo' | 'lessThanOrEqualTo'; + filterValue?: string; + order: boolean; orderBy?: string; ascending?: boolean; + limit?: number; children?: ReactNode; className?: string; noLayout?: boolean; setControlContextData?: (data: { types?: { title: string; uid: string }[]; entries?: { title: string; uid: string }[]; - fields?: { display_name: string; uid: string}[]; + fields?: { display_name: string; uid: string }[]; }) => void; } @@ -132,6 +138,15 @@ export const ContentStackFetcherMeta: ComponentMeta = displayName: "Content type", description: "Content type to be queried.", }, + fetchType: { + type: "choice", + options: [ + { label: 'Single Entry', value: 'single' }, + { label: 'All Entries', value: 'all' }, + ], + displayName: "Fetch type", + description: "What type of query to use.", + }, entryUID: { type: "choice", options: (props, ctx) => @@ -140,11 +155,44 @@ export const ContentStackFetcherMeta: ComponentMeta = value: entry.uid, })) ?? [], displayName: "Entry UID", - description: "Query in Content Type.", + description: "Select a single entry.", + hidden: props => props.fetchType !== 'single', }, - limit: { - type: "number", - displayName: "Limit Results", + filter: { + type: "boolean", + displayName: "Filter Entries", + hidden: props => props.fetchType !== 'all', + }, + filterField: { + type: "choice", + options: (props, ctx) => + ctx?.fields?.map((field) => ({ + label: field.display_name, + value: field.uid, + })) ?? [], + displayName: "Filter On", + hidden: props => !props.filter || props.fetchType !== 'all', + }, + filterType: { + type: "choice", + options: [ + { label: 'Equals', value: 'where' }, + { label: 'Greater Than', value: 'greaterThanOrEqualTo' }, + { label: 'Less Than', value: 'lessThanOrEqualTo' } + ], + displayName: "Filter Type", + hidden: props => !props.filter || props.fetchType !== 'all', + }, + filterValue: { + type: "string", + displayName: "Filter Value", + description: "May not work on non-string fields.", + hidden: props => !props.filter || props.fetchType !== 'all', + }, + order: { + type: "boolean", + displayName: "Order Entries", + hidden: props => props.fetchType !== 'all', }, orderBy: { type: "choice", @@ -154,11 +202,18 @@ export const ContentStackFetcherMeta: ComponentMeta = value: field.uid, })) ?? [], displayName: "Order By", + hidden: props => !props.order || props.fetchType !== 'all', }, ascending: { type: "choice", - options: [{label: 'Ascending', value: true}, {label: 'Descending', value: false}], + options: [{ label: 'Ascending', value: true}, {label: 'Descending', value: false }], displayName: "Order Direction", + hidden: props => !props.order || props.fetchType !== 'all', + }, + limit: { + type: "number", + displayName: "Limit Results", + hidden: props => props.fetchType === 'single', }, noLayout: { type: "boolean", @@ -171,11 +226,17 @@ export const ContentStackFetcherMeta: ComponentMeta = }; export function ContentStackFetcher({ - entryUID, contentType, - limit, + fetchType, + entryUID, + filter, + filterField, + filterType, + filterValue, + order, orderBy, ascending, + limit, children, className, noLayout, @@ -192,7 +253,7 @@ export function ContentStackFetcher({ }); const { data: entryData } = usePlasmicQueryData( - contentType && entryUID + contentType && entryUID && fetchType === 'single' ? `${cacheKey}/${contentType}/entry/${entryUID}` : null, async () => { @@ -213,24 +274,29 @@ export function ContentStackFetcher({ ); const { data: entriesData } = usePlasmicQueryData( - contentType ? `${cacheKey}/${contentType}/entries${limit ? "/limit/" + limit : ''}${orderBy ? "/order/" + orderBy + (ascending ? '/ascending' : '') : ''}` : null, + contentType && fetchType === 'all' ? `${cacheKey}/${contentType}/entries${ + limit ? "/limit/" + limit : '' + }${ + order && orderBy ? "/order/" + orderBy + (ascending ? '/ascending' : '') : '' + }${ + filter && filterField && filterType && filterValue ? `/filter/${filterField}/${filterType}/${filterValue}` : '' + }` : null, async () => { let Query = Stack.ContentType(`${contentType!}`).Query(); - if(orderBy){ + if (filter && filterField && filterType && filterValue) { + Query = Query[filterType](filterField, filterValue); + } + if (order && orderBy){ Query = Query[ascending ? 'ascending' : 'descending'](orderBy); } - if(limit){ + if (limit){ Query = Query.limit(limit); } return await Query.toJSON().find(); } ); - const schema = [{display_name: 'Created At', uid: 'created_at'}, {display_name: 'Updated At', uid: 'updated_at'}]; - if(contentTypes){ - schema.push(...contentTypes?.filter((x: any) => x.uid === contentType)?.[0]?.schema); - } - + const schema = [{display_name: 'Created At', uid: 'created_at'}, {display_name: 'Updated At', uid: 'updated_at'}, ...(contentTypes?.filter((x: any) => x.uid === contentType)?.[0]?.schema ?? [])]; setControlContextData?.({ types: contentTypes, entries: entriesData?.[0],