feat: dynamically populates richtext relationships
* feat: adds relationship field to test searchable input * fix: searching on relationship fields properly fetches results * chore: more dry relationship field * feat: sets default access control to requiring a user to be logged in * feat: dynamically populates richtext relationships * feat: allows depth param in graphql richText field * feat: ensures relationship input is initialized with up to 3 related collections
This commit is contained in:
@@ -246,19 +246,44 @@ const Relationship: React.FC<Props> = (props) => {
|
||||
|
||||
useEffect(() => {
|
||||
const getFirstResults = async () => {
|
||||
const relation = relations[0];
|
||||
const res = await fetch(`${serverURL}${api}/${relation}?limit=${maxResultsPerRequest}&depth=0`);
|
||||
const res = await fetch(`${serverURL}${api}/${relations[0]}?limit=${maxResultsPerRequest}&depth=0`);
|
||||
|
||||
if (res.ok) {
|
||||
const data: PaginatedDocs = await res.json();
|
||||
|
||||
addOptions(data, relation);
|
||||
addOptions(data, relations[0]);
|
||||
|
||||
|
||||
if (!data.hasNextPage) {
|
||||
setLastFullyLoadedRelation(relations.indexOf(relation));
|
||||
} else {
|
||||
setLastLoadedPage(2);
|
||||
setLastFullyLoadedRelation(0);
|
||||
|
||||
if (relations[1]) {
|
||||
const secondRes = await fetch(`${serverURL}${api}/${relations[1]}?limit=${maxResultsPerRequest}&depth=0`);
|
||||
|
||||
if (res.ok) {
|
||||
const secondData: PaginatedDocs = await secondRes.json();
|
||||
|
||||
addOptions(secondData, relations[1]);
|
||||
|
||||
if (!secondData.hasNextPage) {
|
||||
setLastFullyLoadedRelation(1);
|
||||
|
||||
if (relations[2]) {
|
||||
const thirdRes = await fetch(`${serverURL}${api}/${relations[2]}?limit=${maxResultsPerRequest}&depth=0`);
|
||||
|
||||
if (res.ok) {
|
||||
const thirdData: PaginatedDocs = await thirdRes.json();
|
||||
|
||||
addOptions(thirdData, relations[2]);
|
||||
|
||||
if (!thirdData.hasNextPage) {
|
||||
setLastFullyLoadedRelation(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setHasLoadedFirstOptions(true);
|
||||
|
||||
@@ -2,10 +2,8 @@ import React, { Fragment, useState, useEffect } from 'react';
|
||||
import { useConfig, useAuth } from '@payloadcms/config-provider';
|
||||
import { useWatchForm } from '../../../../../../Form/context';
|
||||
import Relationship from '../../../../../Relationship';
|
||||
import Number from '../../../../../Number';
|
||||
import Select from '../../../../../Select';
|
||||
|
||||
|
||||
const createOptions = (collections, permissions) => collections.reduce((options, collection) => {
|
||||
if (permissions?.collections?.[collection.slug]?.read?.permission && collection?.admin?.enableRichTextRelationship) {
|
||||
return [
|
||||
@@ -21,7 +19,7 @@ const createOptions = (collections, permissions) => collections.reduce((options,
|
||||
}, []);
|
||||
|
||||
const RelationshipFields = () => {
|
||||
const { collections, maxDepth } = useConfig();
|
||||
const { collections } = useConfig();
|
||||
const { permissions } = useAuth();
|
||||
|
||||
const [options, setOptions] = useState(() => createOptions(collections, permissions));
|
||||
@@ -49,13 +47,6 @@ const RelationshipFields = () => {
|
||||
required
|
||||
/>
|
||||
)}
|
||||
<Number
|
||||
required
|
||||
name="depth"
|
||||
label="Depth"
|
||||
min={0}
|
||||
max={maxDepth}
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -15,19 +15,16 @@ import { requests } from '../../../../../../../api';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const initialFormData = {
|
||||
depth: 0,
|
||||
};
|
||||
const initialFormData = {};
|
||||
|
||||
const baseClass = 'relationship-rich-text-button';
|
||||
|
||||
const insertRelationship = (editor, { value, relationTo, depth }) => {
|
||||
const insertRelationship = (editor, { value, relationTo }) => {
|
||||
const text = { text: ' ' };
|
||||
|
||||
const relationship = {
|
||||
type: 'relationship',
|
||||
value,
|
||||
depth,
|
||||
relationTo,
|
||||
children: [
|
||||
text,
|
||||
@@ -58,13 +55,13 @@ const RelationshipButton: React.FC<{path: string}> = ({ path }) => {
|
||||
const [hasEnabledCollections] = useState(() => collections.find(({ admin: { enableRichTextRelationship } }) => enableRichTextRelationship));
|
||||
const modalSlug = `${path}-add-relationship`;
|
||||
|
||||
const handleAddRelationship = useCallback(async (_, { relationTo, value, depth }) => {
|
||||
const handleAddRelationship = useCallback(async (_, { relationTo, value }) => {
|
||||
setLoading(true);
|
||||
|
||||
const res = await requests.get(`${serverURL}${api}/${relationTo}/${value}?depth=${depth}`);
|
||||
const res = await requests.get(`${serverURL}${api}/${relationTo}/${value}?depth=0`);
|
||||
const json = await res.json();
|
||||
|
||||
insertRelationship(editor, { value: json, depth, relationTo });
|
||||
insertRelationship(editor, { value: { id: json.id }, relationTo });
|
||||
closeAll();
|
||||
setRenderModal(false);
|
||||
setLoading(false);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
align-items: flex-start;
|
||||
background: $color-background-gray;
|
||||
max-width: base(15);
|
||||
margin-bottom: $baseline;
|
||||
margin-bottom: base(.5);
|
||||
|
||||
svg {
|
||||
width: base(1.25);
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useConfig } from '@payloadcms/config-provider';
|
||||
import RelationshipIcon from '../../../../../../icons/Relationship';
|
||||
import usePayloadAPI from '../../../../../../../hooks/usePayloadAPI';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'rich-text-relationship';
|
||||
|
||||
const initialParams = {
|
||||
depth: 0,
|
||||
};
|
||||
|
||||
const Element = ({ attributes, children, element }) => {
|
||||
const { relationTo, value } = element;
|
||||
const { collections } = useConfig();
|
||||
const { collections, serverURL, routes: { api } } = useConfig();
|
||||
const [relatedCollection] = useState(() => collections.find((coll) => coll.slug === relationTo));
|
||||
|
||||
const [{ data }] = usePayloadAPI(
|
||||
`${serverURL}${api}/${relatedCollection.slug}/${value?.id}`,
|
||||
{ initialParams },
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={baseClass}
|
||||
@@ -24,7 +34,7 @@ const Element = ({ attributes, children, element }) => {
|
||||
{' '}
|
||||
Relationship
|
||||
</div>
|
||||
<h5>{value[relatedCollection?.admin?.useAsTitle || 'id']}</h5>
|
||||
<h5>{data[relatedCollection?.admin?.useAsTitle || 'id']}</h5>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user