Skip to content

Commit cb8dc7d

Browse files
committed
fix: add values in filters
1 parent 0569d36 commit cb8dc7d

1 file changed

Lines changed: 77 additions & 2 deletions

File tree

src/components/Filter.tsx

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
1-
import React, { useRef } from "react";
1+
import React, { useCallback, useMemo, useRef } from "react";
22
import { ConnectOprtator, FilterItem, FilterKey, FilterOperator } from "../types/FilterItem";
33
import { Chip } from './Chip';
44
import { Menu } from 'primereact/menu';
5+
import { gql, useQuery } from "@apollo/client";
6+
import { Tag } from "../types/Tag";
7+
8+
const GET_TAGS = gql`
9+
query GetTags {
10+
tag {
11+
nodes {
12+
id,
13+
name,
14+
description,
15+
note,
16+
tagType
17+
}
18+
}
19+
}
20+
`;
521

622
export interface FilterProps {
723
item: FilterItem;
@@ -10,6 +26,23 @@ export interface FilterProps {
1026
}
1127

1228
export const Filter: React.FC<FilterProps> = (props) => {
29+
const { data: raw, loading, error } = useQuery(GET_TAGS);
30+
31+
const data = useMemo(() => {
32+
if (raw?.tag?.nodes) {
33+
return raw.tag.nodes.filter((item: Tag) => item.description !== '測試');
34+
}
35+
return [];
36+
}, [raw]);
37+
38+
const photographers = useMemo(() => {
39+
return data.filter((item: Tag) => item.tagType === 'photographer')
40+
}, [data]);
41+
42+
const categories = useMemo(() => {
43+
return data.filter((item: Tag) => item.tagType === 'category')
44+
}, [data]);
45+
1346
const onConnectChange = (value: ConnectOprtator) => {
1447
props.setPayloads((prev) => {
1548
const updated = prev.map((item) => {
@@ -59,6 +92,44 @@ export const Filter: React.FC<FilterProps> = (props) => {
5992
{ label: '包含', value: FilterOperator.IN, command: () => onOperatorChange(FilterOperator.IN) },
6093
{ label: '不包含', value: FilterOperator.NOT_IN, command: () => onOperatorChange(FilterOperator.NOT_IN) },
6194
]
95+
const onValueChange = (value: string) => {
96+
props.setPayloads((prev) => {
97+
const updated = prev.map((item) => {
98+
if (item.id === props.item.id) {
99+
if (item.values.includes(value)) {
100+
const values = item.values.filter((v) => v !== value);
101+
return { ...item, values };
102+
} else {
103+
const values =item.values.concat(value);
104+
return { ...item, values };
105+
}
106+
}
107+
return item;
108+
});
109+
return updated;
110+
});
111+
}
112+
const makeValueeOption = useCallback((value: string, selecteds: string[]) => {
113+
return { label: value, icon: selecteds.includes(value) ? 'pi pi-check' : '', value, command: () => onValueChange(value) };
114+
// eslint-disable-next-line react-hooks/exhaustive-deps
115+
}, []);
116+
const valueMenu = useRef<Menu | null>(null);
117+
const valueOptions = useMemo(() => {
118+
switch (props.item.label) {
119+
case FilterKey.REACTIONS:
120+
return ['正向', '負向'].map((item) => makeValueeOption(item, props.item.values));
121+
case FilterKey.AUTHORS:
122+
return photographers.map((item: Tag) => makeValueeOption(item.name, props.item.values));
123+
case FilterKey.CATEGORIES:
124+
return categories.map((item: Tag) => makeValueeOption(item.name, props.item.values));
125+
default:
126+
return [];
127+
}
128+
}, [props.item, photographers, categories, makeValueeOption]);
129+
130+
if (loading) return <div>Loading...</div>;
131+
if (error) return <div>Error: {error.message}</div>;
132+
62133
return (
63134
<>
64135
{props.showConnect && (
@@ -80,7 +151,11 @@ export const Filter: React.FC<FilterProps> = (props) => {
80151
onClick={(event) => operatorMenu?.current?.toggle(event)}
81152
/>
82153
<Menu popup ref={operatorMenu} model={operatorOptions} />
83-
<Chip label={props.item.values.join(', ')} />
154+
<Chip
155+
label={props.item.values.join(', ')}
156+
onClick={(event) => valueMenu?.current?.toggle(event)}
157+
/>
158+
<Menu popup ref={valueMenu} model={valueOptions} />
84159
<Chip label='x' onClick={() => {
85160
props.setPayloads((prev) => {
86161
const removed = prev.filter((item) => item.id !== props.item.id);

0 commit comments

Comments
 (0)