"use client"; import { useState } from "react"; import Link from "next/link"; import { useQuery } from "@tanstack/react-query"; import { fetchContentList, fetchCollections } from "@/lib/api"; import type { FieldDefinition } from "@/lib/api"; type Props = { name: string; def: FieldDefinition; value: string[] | string; onChange: (value: string[]) => void; required?: boolean; error?: unknown; locale?: string; label: React.ReactNode; }; /** Referenced collection(s) from schema: single collection or list for polymorphic. */ function getCollections(def: FieldDefinition): string[] { const items = def.items as FieldDefinition | undefined; if (!items) return []; if (items.collection) return [items.collection]; if (Array.isArray(items.collections) && items.collections.length > 0) return items.collections; return []; } export function ReferenceArrayField({ name, def, value, onChange, required, error, locale, label, }: Props) { const schemaCollections = getCollections(def); const singleCollection = schemaCollections.length === 1 ? schemaCollections[0] : null; const multipleCollections = schemaCollections.length > 1 ? schemaCollections : []; const valueList: string[] = Array.isArray(value) ? value : typeof value === "string" ? value .split(/[\n,]+/) .map((s) => s.trim()) .filter(Boolean) : []; const [pickedCollection, setPickedCollection] = useState( singleCollection ?? multipleCollections[0] ?? "", ); const { data: collectionsData } = useQuery({ queryKey: ["collections"], queryFn: fetchCollections, enabled: schemaCollections.length === 0, }); const availableCollections = schemaCollections.length > 0 ? schemaCollections : (collectionsData?.collections ?? []) .map((c) => c.name) .filter( (n) => n !== "content_layout" && n !== "component_layout" && n !== "seo", ); const effectiveCollection = singleCollection ?? pickedCollection; const listParams = { _per_page: 200, ...(locale ? { _locale: locale } : {}) }; const singleQuery = useQuery({ queryKey: ["content", effectiveCollection, listParams], queryFn: () => fetchContentList(effectiveCollection!, listParams), enabled: !!effectiveCollection && schemaCollections.length <= 1, }); const multiQueries = useQuery({ queryKey: ["content-multi", multipleCollections, listParams], queryFn: async () => { const results = await Promise.all( multipleCollections.map((coll) => fetchContentList(coll, listParams)), ); return multipleCollections.map((coll, i) => ({ collection: coll, items: results[i]?.items ?? [], })); }, enabled: multipleCollections.length > 1, }); type OptionItem = { slug: string; collection: string }; const options: OptionItem[] = multipleCollections.length > 1 && multiQueries.data ? multiQueries.data.flatMap(({ collection: coll, items }) => (items as { _slug?: string }[]) .map((o) => ({ slug: String(o._slug ?? ""), collection: coll, })) .filter((o) => o.slug), ) : ((singleQuery.data?.items ?? []) as { _slug?: string }[]) .map((o) => ({ slug: String(o._slug ?? ""), collection: effectiveCollection ?? "", })) .filter((o) => o.slug); const isLoading = schemaCollections.length <= 1 ? singleQuery.isLoading : multiQueries.isLoading; const add = (slug: string) => { if (!slug || valueList.includes(slug)) return; onChange([...valueList, slug]); }; const addFromOption = (optionValue: string) => { const slug = optionValue.includes(":") ? optionValue.split(":")[1]! : optionValue; add(slug); }; const remove = (index: number) => { onChange(valueList.filter((_, i) => i !== index)); }; const move = (index: number, dir: number) => { const next = index + dir; if (next < 0 || next >= valueList.length) return; const copy = [...valueList]; const tmp = copy[index]; copy[index] = copy[next]; copy[next] = tmp; onChange(copy); }; const collectionsForNew = multipleCollections.length > 1 ? multipleCollections : effectiveCollection ? [effectiveCollection] : []; return (
{label} {schemaCollections.length > 0 ? ( {schemaCollections.length === 1 ? `Typ: ${schemaCollections[0]}` : `Typen: ${schemaCollections.join(", ")}`} ) : null}
{/* Selected entries */} {/* Without schema collection: choose component type first */} {!singleCollection && schemaCollections.length === 0 && availableCollections.length > 0 ? (
) : null} {/* Add: select from existing + create new component */} {effectiveCollection || multipleCollections.length > 1 ? (
{collectionsForNew.length > 0 ? ( {collectionsForNew.length === 1 ? ( + New {collectionsForNew[0]} component ) : ( )} Open in new tab; then reload this page. ) : null}
) : null} {schemaCollections.length === 0 && availableCollections.length === 0 ? (

No reference collection in schema. Set{" "} items.collection or{" "} items.collections{" "} in the type, or start the API and reload the page.

) : null} {error ? (

{String((error as { message?: string })?.message ?? error)}

) : null}
); }