diff --git a/app/(builder)/ycode/api/collections/[id]/items/filter/route.ts b/app/(builder)/ycode/api/collections/[id]/items/filter/route.ts index 4fe1c4c6..dd0cfe53 100644 --- a/app/(builder)/ycode/api/collections/[id]/items/filter/route.ts +++ b/app/(builder)/ycode/api/collections/[id]/items/filter/route.ts @@ -497,6 +497,7 @@ export async function POST( localeCode, collectionLayerClasses, collectionLayerTag, + published: isPublished = true, } = body; if (!layerTemplate || !Array.isArray(layerTemplate)) { @@ -508,7 +509,7 @@ export async function POST( const { matchingIds, total: filteredTotal } = await getFilteredItemIds( collectionId, - true, + isPublished, filterGroups, ); @@ -525,7 +526,7 @@ export async function POST( if (!sortBy || sortBy === 'none' || sortBy === 'manual') { // Let DB do ordering and pagination for cheap paths. - const { items } = await getItemsByCollectionId(collectionId, true, { + const { items } = await getItemsByCollectionId(collectionId, isPublished, { itemIds: matchingIds, limit: pageLimit, offset: pageOffset, @@ -536,7 +537,7 @@ export async function POST( const randomizedIds = [...matchingIds].sort(() => Math.random() - 0.5); pageItemIds = randomizedIds.slice(pageOffset, pageOffset + pageLimit); if (pageItemIds.length > 0) { - const { items } = await getItemsByCollectionId(collectionId, true, { + const { items } = await getItemsByCollectionId(collectionId, isPublished, { itemIds: pageItemIds, }); pageRawItems = reorderItemsById(items, pageItemIds); @@ -544,7 +545,7 @@ export async function POST( } else { // For field-based sort, sort IDs using just the sort field values first, // then hydrate only the requested page window. - const sortValueByItem = await getFieldValuesForItems(sortBy, true, matchingIds); + const sortValueByItem = await getFieldValuesForItems(sortBy, isPublished, matchingIds); const sortedIds = [...matchingIds].sort((a, b) => { const aStr = String(sortValueByItem.get(a) || ''); const bStr = String(sortValueByItem.get(b) || ''); @@ -559,7 +560,7 @@ export async function POST( }); pageItemIds = sortedIds.slice(pageOffset, pageOffset + pageLimit); if (pageItemIds.length > 0) { - const { items } = await getItemsByCollectionId(collectionId, true, { + const { items } = await getItemsByCollectionId(collectionId, isPublished, { itemIds: pageItemIds, }); pageRawItems = reorderItemsById(items, pageItemIds); @@ -568,7 +569,7 @@ export async function POST( const valuesByItem = await getValuesByItemIds( pageRawItems.map(i => i.id), - true, + isPublished, ); const paginatedItems: CollectionItemWithValues[] = pageRawItems.map(item => ({ ...item, @@ -576,7 +577,7 @@ export async function POST( })); const hasMore = pageOffset + paginatedItems.length < filteredTotal; - const collectionFields = await getFieldsByCollectionId(collectionId, true, { excludeComputed: true }); + const collectionFields = await getFieldsByCollectionId(collectionId, isPublished, { excludeComputed: true }); const slugField = collectionFields.find(f => f.key === 'slug'); const collectionItemSlugs: Record = {}; if (slugField) { @@ -595,7 +596,7 @@ export async function POST( let locale = null; let translations: Record | undefined; if (localeCode) { - const localeData = await loadTranslationsForLocale(localeCode, true); + const localeData = await loadTranslationsForLocale(localeCode, isPublished); locale = localeData.locale; translations = localeData.translations; } @@ -605,7 +606,7 @@ export async function POST( layerTemplate as Layer[], collectionId, collectionLayerId, - true, + isPublished, pages, folders, collectionItemSlugs, diff --git a/components/FilterableCollection.tsx b/components/FilterableCollection.tsx index e7810f10..f80dd936 100644 --- a/components/FilterableCollection.tsx +++ b/components/FilterableCollection.tsx @@ -19,6 +19,7 @@ interface FilterableCollectionProps { layerTemplate: Layer[]; collectionLayerClasses?: string[]; collectionLayerTag?: string; + isPublished?: boolean; } const FC_FILTERED_ATTR = 'data-fc-filtered'; @@ -37,6 +38,7 @@ export default function FilterableCollection({ layerTemplate, collectionLayerClasses, collectionLayerTag, + isPublished = true, }: FilterableCollectionProps) { const markerRef = useRef(null); const ssrChildrenRef = useRef([]); @@ -185,9 +187,10 @@ export default function FilterableCollection({ if (inputValue && inputValue.includes(',')) { const checkedValues = inputValue.split(',').filter(Boolean); if (checkedValues.length > 0) { + const arrayOperators = ['is_one_of', 'is_not_one_of', 'contains_all_of', 'contains_exactly']; activeInGroup.push({ fieldId: condition.fieldId, - operator: 'is_one_of', + operator: arrayOperators.includes(condition.operator) ? condition.operator : 'is_one_of', value: JSON.stringify(checkedValues), fieldType: condition.fieldType, }); @@ -529,7 +532,7 @@ export default function FilterableCollection({ sortOrder: effectiveSortOrder, limit, offset, - published: true, + published: isPublished, collectionLayerClasses, collectionLayerTag, }), @@ -582,7 +585,7 @@ export default function FilterableCollection({ abortRef.current = null; } }); - }, [collectionId, collectionLayerId, layerTemplate, effectiveSortBy, effectiveSortOrder, limit, paginationMode, updateEmptyStateElements, injectFilteredHTML, collectionLayerClasses, collectionLayerTag]); + }, [collectionId, collectionLayerId, layerTemplate, effectiveSortBy, effectiveSortOrder, limit, paginationMode, updateEmptyStateElements, injectFilteredHTML, collectionLayerClasses, collectionLayerTag, isPublished]); const fetchFilteredRef = useRef(fetchFiltered); useEffect(() => { fetchFilteredRef.current = fetchFiltered; }, [fetchFiltered]); diff --git a/components/LayerRenderer.tsx b/components/LayerRenderer.tsx index eb0763d5..69ffe970 100644 --- a/components/LayerRenderer.tsx +++ b/components/LayerRenderer.tsx @@ -246,6 +246,7 @@ const LayerRenderer: React.FC = ({ layerTemplate={layer._filterConfig!.layerTemplate} collectionLayerClasses={layer._filterConfig!.collectionLayerClasses} collectionLayerTag={layer._filterConfig!.collectionLayerTag} + isPublished={layer._filterConfig!.isPublished} > {content} @@ -803,7 +804,7 @@ const LayerItem: React.FC<{ if (!inputLayerId) return; const nameAttr = inputEl.getAttribute('name'); if (nameAttr) nameMap[inputLayerId] = nameAttr; - if (inputEl.type === 'checkbox') { + if (inputEl.type === 'checkbox' || inputEl.type === 'radio') { const checked = (inputEl as HTMLInputElement).checked; const val = checked ? ((inputEl as HTMLInputElement).value || 'true') : ''; inputValues[inputLayerId] = val; diff --git a/lib/page-fetcher.ts b/lib/page-fetcher.ts index c1a0fb70..f0a059ec 100644 --- a/lib/page-fetcher.ts +++ b/lib/page-fetcher.ts @@ -1980,6 +1980,7 @@ export async function resolveCollectionLayers( layerTemplate: layer.children || [], collectionLayerClasses: Array.isArray(layer.classes) ? layer.classes : (layer.classes ? [layer.classes] : []), collectionLayerTag: layer.name || 'div', + isPublished, } : undefined, }; } catch (error) { diff --git a/types/index.ts b/types/index.ts index e4d18683..d9bb3b24 100644 --- a/types/index.ts +++ b/types/index.ts @@ -428,6 +428,7 @@ export interface Layer { layerTemplate: Layer[]; collectionLayerClasses?: string[]; collectionLayerTag?: string; + isPublished?: boolean; }; }