enables searching on List view
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
|
||||
.template-default {
|
||||
padding-top: $baseline;
|
||||
margin-left: base(10);
|
||||
width: calc(100% - #{base(10)});
|
||||
margin-left: base(8);
|
||||
width: calc(100% - #{base(8)});
|
||||
|
||||
&__eyebrow,
|
||||
&__wrap {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
import queryString from 'qs';
|
||||
import PropTypes from 'prop-types';
|
||||
@@ -6,23 +6,62 @@ import customComponents from '../../../customComponents';
|
||||
import { useStepNav } from '../../../elements/StepNav';
|
||||
import usePayloadAPI from '../../../../hooks/usePayloadAPI';
|
||||
import Paginator from '../../../elements/Paginator';
|
||||
import Text from '../../../forms/field-types/Text';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const { serverURL, routes: { api, admin } } = PAYLOAD_CONFIG;
|
||||
|
||||
const baseClass = 'collection-list';
|
||||
|
||||
const DefaultList = (props) => {
|
||||
const { collection, data } = props;
|
||||
const [search, setSearch] = useState('');
|
||||
const [columns, setColumns] = useState(null);
|
||||
const [filters, setFilters] = useState(null);
|
||||
|
||||
const location = useLocation();
|
||||
const { collection } = props;
|
||||
|
||||
const { page } = queryString.parse(location.search, { ignoreQueryPrefix: true });
|
||||
|
||||
const apiURL = `${serverURL}${api}/${collection.slug}`;
|
||||
|
||||
const [{ data }, { setParams }] = usePayloadAPI(apiURL, {});
|
||||
|
||||
useEffect(() => {
|
||||
const params = {
|
||||
where: {
|
||||
},
|
||||
};
|
||||
|
||||
if (page) params.page = page;
|
||||
|
||||
if (search) {
|
||||
params.where[collection.useAsTitle || 'id'] = {
|
||||
like: search,
|
||||
};
|
||||
}
|
||||
|
||||
setParams(params);
|
||||
}, [search, setParams, page, collection.useAsTitle]);
|
||||
|
||||
return (
|
||||
<div className="collection-list">
|
||||
<div className={baseClass}>
|
||||
<h1>{collection.labels.plural}</h1>
|
||||
<div className={`${baseClass}__controls`}>
|
||||
<input
|
||||
type="text"
|
||||
value={search}
|
||||
onChange={e => setSearch(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
{data.docs && (
|
||||
<ul>
|
||||
{data.docs.map((doc) => {
|
||||
return (
|
||||
<li key={doc.id}>
|
||||
<Link to={`${admin}/collections/${collection.slug}/${doc.id}`}>
|
||||
{doc.id}
|
||||
{doc[collection.useAsTitle || 'id']}
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
@@ -44,44 +83,19 @@ const DefaultList = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
DefaultList.defaultProps = {
|
||||
data: undefined,
|
||||
};
|
||||
|
||||
DefaultList.propTypes = {
|
||||
collection: PropTypes.shape({
|
||||
labels: PropTypes.shape({
|
||||
plural: PropTypes.string,
|
||||
}),
|
||||
slug: PropTypes.string,
|
||||
useAsTitle: PropTypes.string,
|
||||
}).isRequired,
|
||||
data: PropTypes.shape({
|
||||
docs: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
totalDocs: PropTypes.number,
|
||||
prevPage: PropTypes.number,
|
||||
nextPage: PropTypes.number,
|
||||
hasNextPage: PropTypes.bool,
|
||||
hasPrevPage: PropTypes.bool,
|
||||
limit: PropTypes.number,
|
||||
page: PropTypes.number,
|
||||
totalPages: PropTypes.number,
|
||||
}),
|
||||
};
|
||||
|
||||
const ListView = (props) => {
|
||||
const { collection } = props;
|
||||
const location = useLocation();
|
||||
const { setStepNav } = useStepNav();
|
||||
const { page } = queryString.parse(location.search, { ignoreQueryPrefix: true });
|
||||
|
||||
const apiURL = [
|
||||
`${serverURL}${api}/${collection.slug}`,
|
||||
page && `?page=${page}&`,
|
||||
].filter(Boolean).join('');
|
||||
|
||||
const [{ data }] = usePayloadAPI(apiURL);
|
||||
|
||||
useEffect(() => {
|
||||
setStepNav([
|
||||
@@ -94,10 +108,9 @@ const ListView = (props) => {
|
||||
const List = customComponents?.[collection.slug]?.views?.List || DefaultList;
|
||||
|
||||
return (
|
||||
<List
|
||||
data={data}
|
||||
collection={collection}
|
||||
/>
|
||||
<>
|
||||
<List collection={collection} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
@import '../../../../scss/styles';
|
||||
|
||||
.collection-list {
|
||||
padding: base(3);
|
||||
background: white;
|
||||
height: 300px;
|
||||
|
||||
@include mid-break {
|
||||
padding: base(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
|
||||
%h1 {
|
||||
margin: 0 0 base(1);
|
||||
font-size: base(1);
|
||||
line-height: base(1);
|
||||
font-size: base(2);
|
||||
line-height: 1;
|
||||
letter-spacing: -1px;
|
||||
|
||||
@include small-break {
|
||||
letter-spacing: base(0);
|
||||
|
||||
@@ -44,10 +44,10 @@ class ParamParser {
|
||||
if (key === 'where') {
|
||||
// We need to determine if the whereKey is an AND, OR, or a schema path
|
||||
for (const relationOrPath of Object.keys(this.rawParams.where)) {
|
||||
if (relationOrPath === 'and') {
|
||||
if (relationOrPath.toLowerCase() === 'and') {
|
||||
const andConditions = this.rawParams.where[relationOrPath];
|
||||
this.query.searchParams.$and = await this.buildAndOrConditions(andConditions);
|
||||
} else if (relationOrPath === 'or' && Array.isArray(this.rawParams.where[relationOrPath])) {
|
||||
} else if (relationOrPath.toLowerCase() === 'or' && Array.isArray(this.rawParams.where[relationOrPath])) {
|
||||
const orConditions = this.rawParams.where[relationOrPath];
|
||||
this.query.searchParams.$or = await this.buildAndOrConditions(orConditions);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user