Files
dm-companion/src/components/RelationshipList.tsx
2025-06-14 20:45:32 -07:00

82 lines
2.5 KiB
TypeScript

import { DocumentList } from "@/components/DocumentList";
import { pb } from "@/lib/pocketbase";
import { displayName } from "@/lib/relationships";
import type { AnyDocument, Document, RelationshipType } from "@/lib/types";
import { useState } from "react";
import { Loader } from "./Loader";
import { DocumentRow } from "./documents/DocumentRow";
import { NewRelatedDocumentForm } from "./documents/NewRelatedDocumentForm";
interface RelationshipListProps {
root: AnyDocument;
items: AnyDocument[];
relationshipType: RelationshipType;
}
/**
* RelationshipList manages a list of documents related to a root document via a relationship type.
* It handles fetching, creation, and relationship management, and renders a DocumentList.
*/
export function RelationshipList({
root,
items: initialItems,
relationshipType,
}: RelationshipListProps) {
const [items, setItems] = useState<Document[]>(initialItems);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
// Handles creation of a new document and adds it to the relationship
const handleCreate = async (doc: Document) => {
setLoading(true);
setError(null);
try {
// Check for existing relationship
const existing = await pb.collection("relationships").getFullList({
filter: `primary = "${root.id}" && type = "${relationshipType}"`,
});
if (existing.length > 0) {
console.debug("Adding to existing relationship");
await pb.collection("relationships").update(existing[0].id, {
"+secondary": doc.id,
});
} else {
console.debug("Creating new relationship");
await pb.collection("relationships").create({
primary: root.id,
secondary: [doc.id],
type: relationshipType,
});
}
setItems((prev) => [...prev, doc]);
} catch (e: any) {
setError(e?.message || "Failed to add document to relationship.");
} finally {
setLoading(false);
}
};
if (loading) {
<Loader />;
}
return (
<DocumentList
title={displayName(relationshipType)}
items={items}
error={error}
renderRow={(document) => <DocumentRow document={document} />}
newItemForm={(onSubmit) => (
<NewRelatedDocumentForm
campaignId={root.campaign}
relationshipType={relationshipType}
onCreate={async (doc: Document) => {
await handleCreate(doc);
onSubmit();
}}
/>
)}
/>
);
}