Skip to content

Commit

Permalink
feat: add filter fields to ExternalFields
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvxd committed Jan 16, 2024
1 parent 1cfca2b commit 7a55053
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 79 deletions.
28 changes: 24 additions & 4 deletions apps/demo/config/blocks/Hero/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,23 @@ export const Hero: ComponentConfig<HeroProps> = {
type: "external",
placeholder: "Select a quote",
showSearch: true,
fetchList: async ({ query }) => {
filterFields: {
author: {
type: "select",
options: [
{ value: "", label: "Select an author" },
{ value: "Mark Twain", label: "Mark Twain" },
{ value: "Henry Ford", label: "Henry Ford" },
{ value: "Kurt Vonnegut", label: "Kurt Vonnegut" },
{ value: "Andrew Carnegie", label: "Andrew Carnegie" },
{ value: "C. S. Lewis", label: "C. S. Lewis" },
{ value: "Confucius", label: "Confucius" },
{ value: "Eleanor Roosevelt", label: "Eleanor Roosevelt" },
{ value: "Samuel Ullman", label: "Samuel Ullman" },
],
},
},
fetchList: async ({ query, filters }) => {
// Simulate delay
await new Promise((res) => setTimeout(res, 500));

Expand All @@ -44,16 +60,20 @@ export const Hero: ComponentConfig<HeroProps> = {
description: quote.content,
}))
.filter((item) => {
if (!query) return item;
if (filters?.author && item.title !== filters?.author) {
return false;
}

if (!query) return true;

const queryLowercase = query.toLowerCase();

if (item.title.toLowerCase().indexOf(queryLowercase) > -1) {
return item;
return true;
}

if (item.description.toLowerCase().indexOf(queryLowercase) > -1) {
return item;
return true;
}
});
},
Expand Down
152 changes: 144 additions & 8 deletions apps/docs/pages/docs/api-reference/configuration/fields/external.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const config = {
| [`placeholder`](#placeholder) | `placeholder: "Select content"` | String | - |
| [`showSearch`](#showsearch) | `showSearch: true` | Boolean | - |
| [`initialQuery`](#initialquery) | `initialQuery: "Hello, world"` | String | - |
| [`filterFields`](#filterfields) | `{ "rating": { type: "number" } }` | Object | - |
| [`initialFilters`](#initialfilters) | `"{ "rating": 1 }"` | Object | - |

## Required params

Expand Down Expand Up @@ -88,7 +90,7 @@ const config = {
};
```

### `fetchList()`
### `fetchList(queryParams)`

Return a promise with a list of objects to be rendered in a tabular format via the external input modal.

Expand Down Expand Up @@ -117,6 +119,23 @@ const config = {
};
```

#### `queryParams`

The parameters passed to the `fetchList` method based on your field configuration.

| Param | Example | Type |
| --------------------- | ------------------- | ------ |
| [`query`](#query) | `"My Query"` | String |
| [`filters`](#filters) | `"{ "rating": 1 }"` | Object |

##### `query`

The search query when using [`showSearch`](#showsearch).

##### `filters`

An object describing the filters configured by [`filterFields`](#filterfields).

## Optional params

### `getItemSummary(item)`
Expand Down Expand Up @@ -169,7 +188,6 @@ const config = {
render: ({ data }) => {
return <p>{data?.title || "No data selected"}</p>;
},
// ...
}}
/>

Expand Down Expand Up @@ -220,7 +238,6 @@ const config = {
render: ({ data }) => {
return <p>{data || "No data selected"}</p>;
},
// ...
}}
/>

Expand Down Expand Up @@ -276,7 +293,6 @@ const config = {
render: ({ data }) => {
return <p>{data?.title || "No data selected"}</p>;
},
// ...
}}
/>

Expand All @@ -291,7 +307,7 @@ const config = {
fields: {
data: {
type: "external",
fetchList: async ({ params }) => {
fetchList: async ({ query }) => {
return [
{ title: "Apple", description: "Lorem ipsum 1" },
{ title: "Orange", description: "Lorem ipsum 2" },
Expand Down Expand Up @@ -346,7 +362,6 @@ const config = {
render: ({ data }) => {
return <p>{data?.title || "No data selected"}</p>;
},
// ...

}}
/>
Expand All @@ -362,7 +377,7 @@ const config = {
fields: {
data: {
type: "external",
fetchList: async ({ params }) => {
fetchList: async ({ query }) => {
return [
{ title: "Apple", description: "Lorem ipsum 1" },
{ title: "Orange", description: "Lorem ipsum 2" },
Expand Down Expand Up @@ -419,7 +434,128 @@ const config = {
render: ({ data }) => {
return <p>{data?.title || "No data selected"}</p>;
},
// ...

}}
/>

### `filterFields`

An object describing filters for your query using the [Fields API](/docs/api-reference/configuration/fields)

```tsx {13-17} copy
const config = {
components: {
Example: {
fields: {
data: {
type: "external",
fetchList: async ({ filters }) => {
return [
{ title: "Apple", description: "Lorem ipsum 1", rating: 5 },
{ title: "Orange", description: "Lorem ipsum 2", rating: 3 },
].filter((item) => item.rating >= (filters.rating || 0));
},
filterFields: {
rating: {
type: "number",
},
},
},
},
// ...
},
},
};
```

<ConfigPreview
label="Example"
componentConfig={{
fields: {
data: {
type: "external",
fetchList: async ({ filters }) => {
return [
{ title: "Apple", description: "Lorem ipsum 1", rating: 5 },
{ title: "Orange", description: "Lorem ipsum 2", rating: 3 },
].filter((item) =>
item.rating >= (filters.rating || 0)
)
},
filterFields: {
rating: {
type: "number",
},
},
},
},
render: ({ data }) => {
return <p>{data?.title || "No data selected"}</p>;
},

}}
/>

### `initialFilters`

The initial filter values when using [`filterFields`](#filterfields).

```tsx {18-20} copy
const config = {
components: {
Example: {
fields: {
data: {
type: "external",
fetchList: async ({ filters }) => {
return [
{ title: "Apple", description: "Lorem ipsum 1", rating: 5 },
{ title: "Orange", description: "Lorem ipsum 2", rating: 3 },
].filter((item) => item.rating >= (filters.rating || 0));
},
filterFields: {
rating: {
type: "number",
},
},
initialFilters: {
rating: 1,
},
},
},
// ...
},
},
};
```

<ConfigPreview
label="Example"
componentConfig={{
fields: {
data: {
type: "external",
fetchList: async ({ filters }) => {
return [
{ title: "Apple", description: "Lorem ipsum 1", rating: 5 },
{ title: "Orange", description: "Lorem ipsum 2", rating: 3 },
].filter((item) =>
item.rating >= (filters.rating || 0)
)
},
filterFields: {
rating: {
type: "number",
},
},
initialFilters: {
rating: 1,
},
},
},
render: ({ data }) => {
return <p>{data?.title || "No data selected"}</p>;
},

}}
/>
Expand Down
Loading

0 comments on commit 7a55053

Please sign in to comment.