import { StarFilled, StarOutlined } from '@ant-design/icons'; import isEqual from 'lodash/isEqual'; import React, { Dispatch, SetStateAction, useCallback, useContext, useMemo, useState } from 'react'; import useMedia from 'react-use/lib/useMedia'; import Button from '../../../button'; import ConfigProvider from '../../../config-provider'; import Form from '../../../form'; import Input from '../../../input'; import Popover from '../../../popover'; import Tag from '../../../tag'; import { ApolloColumnType, SelectedView, OrderDirection, Ordering, SelectedViewsProps, } from '../../interfaces'; import { findColumn } from '../../utils/findColumn'; import { generateLabel } from '../../utils/generateLabel'; import defaultLocale from '../../../locale/en_US'; import { localFilterToComponent } from '../../utils/localFilterToComponent'; import Modal from '../../../modal'; interface SelectedViewButtonProps { columns: ApolloColumnType[]; selectedViews: SelectedViewsProps; activeKey: string; value: SelectedView[]; queryValue: string; sortValue: string; filterValues: Record; defaultSortValue?: Ordering; allSelectedViews: SelectedView[]; searchParams: Record; setQueryValue: Dispatch>; setSortValue: Dispatch>; setFilterValues: Dispatch>>; setSearchParams: (nextQuery: Record) => void; onChange: React.Dispatch>; onActiveKeyChange: Dispatch>; } export const SelectedViewButton = ({ defaultSortValue, selectedViews, columns, activeKey, queryValue, sortValue, filterValues, value, searchParams, setQueryValue, setSortValue, setFilterValues, setSearchParams, allSelectedViews: propsAllSelectedViews, onChange, onActiveKeyChange, }: SelectedViewButtonProps) => { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const { getPrefixCls, locale: { ApolloTable: locale } = { ApolloTable: defaultLocale.ApolloTable }, } = useContext(ConfigProvider.ConfigContext); const [visible, setVisible] = useState(false); const showSelectedViewButton = useMedia('(max-width: 892px)'); const allSelectedViews = useMemo( () => propsAllSelectedViews.filter(item => item.id !== 'all'), [propsAllSelectedViews], ); const disabled = useMemo(() => { // 如果是 local 或 服务端,永远是 false if (activeKey.startsWith('savedSearch') || searchParams.saved_search_id) { return false; } // 如果是所有,不对比排序 if (activeKey === 'all') { if ( queryValue || Object.keys(filterValues).length > 0 || sortValue !== (defaultSortValue ? `${defaultSortValue.field} ${defaultSortValue.direction}` : '') ) { return false; } return true; } // 否则是配置的 const current = allSelectedViews?.find(item => item.id === activeKey); // 如果条件相等禁用 if ( queryValue === (current?.query || '') && sortValue === (current?.orderBy ? `${current.orderBy.field} ${current.orderBy.direction}` : '') && isEqual(filterValues, current?.filters || {}) ) { return true; } return false; }, [ activeKey, searchParams.saved_search_id, allSelectedViews, queryValue, sortValue, filterValues, defaultSortValue, ]); const isEdit = useMemo(() => { if (activeKey.startsWith('savedSearch')) { const current = allSelectedViews.find(item => item.id === activeKey); if ( current && queryValue === (current.query || '') && sortValue === (current.orderBy ? `${current.orderBy.field} ${current.orderBy.direction}` : '') && isEqual(filterValues, localFilterToComponent(current.filters || {}, columns)) ) { return true; } return false; } if (disabled || searchParams.saved_search_id) { return true; } return false; }, [ activeKey, disabled, searchParams.saved_search_id, allSelectedViews, queryValue, sortValue, filterValues, columns, ]); const renderTags = () => { const filtersArr = Object.keys(filterValues).map(key => { const col = findColumn(columns, key); return ( <> {col.title}: {generateLabel(col, filterValues[key], locale)} ); }); return (
{queryValue && {`"${queryValue}"`}} {filtersArr.map((item, index) => ( // eslint-disable-next-line react/no-array-index-key {item} ))}
); }; const handleSave = useCallback(async () => { await form.validateFields(); // 编辑 if (isEdit) { const newValue = [...value]; const index = value.findIndex(item => item.id === activeKey); newValue[index] = { name: form.getFieldValue('label'), id: selectedViews.store ? activeKey : `savedSearch_${form.getFieldValue('label')}`, query: queryValue, orderBy: sortValue ? { field: sortValue.split(' ')[0], direction: sortValue.split(' ')[1] as OrderDirection, } : undefined, filters: filterValues, }; const fn = () => { onChange(newValue); form.setFieldsValue({ label: '' }); setVisible(false); }; if (selectedViews.store) { setLoading(true); const { success } = await selectedViews.store.update({ id: activeKey, name: form.getFieldValue('label'), }); setLoading(false); if (success) { fn(); } } else { fn(); onActiveKeyChange(`savedSearch_${form.getFieldValue('label')}`); } // 保存 } else { const addSelectedView = { name: form.getFieldValue('label'), query: queryValue, orderBy: sortValue ? { field: sortValue.split(' ')[0], direction: sortValue.split(' ')[1] as OrderDirection, } : null, filters: filterValues, }; if (selectedViews.store) { setLoading(true); const { success, id } = await selectedViews.store.add(addSelectedView); setLoading(false); if (success && id) { const undefinedParams: any = {}; Object.keys(searchParams).forEach(key => { undefinedParams[key] = undefined; }); setSearchParams({ ...undefinedParams, saved_search_id: id, }); onChange([...value, { ...addSelectedView, id }]); onActiveKeyChange(id); form.setFieldsValue({ label: '' }); setVisible(false); } } else { setSearchParams({ selectedView: 'savedSearch', }); onChange([ ...value, { ...addSelectedView, id: `savedSearch_${form.getFieldValue('label')}` }, ]); onActiveKeyChange(`savedSearch_${form.getFieldValue('label')}`); form.setFieldsValue({ label: '' }); setVisible(false); } } }, [ form, isEdit, value, queryValue, sortValue, filterValues, selectedViews.store, activeKey, onChange, onActiveKeyChange, searchParams, setSearchParams, ]); const handleRemove = useCallback(() => { setVisible(false); Modal.confirm({ title: `${locale?.removeText} ${allSelectedViews.find(item => item.id === activeKey)?.name} ${ locale?.filterText }`, content: locale?.deleteHelpText, okButtonProps: { danger: true, }, onOk: async () => { const fn = () => { onChange(value.filter(item => item.id !== activeKey)); onActiveKeyChange('all'); setQueryValue(''); setSortValue( defaultSortValue ? `${defaultSortValue.field} ${defaultSortValue.direction}` : '', ); setFilterValues({}); }; if (selectedViews.store) { setLoading(true); const { success } = await selectedViews.store.remove(activeKey); setLoading(false); if (success) { fn(); } } else { fn(); } }, }); }, [ activeKey, allSelectedViews, defaultSortValue, locale?.deleteHelpText, locale?.filterText, locale?.removeText, onActiveKeyChange, onChange, selectedViews.store, setFilterValues, setQueryValue, setSortValue, value, ]); return ( {renderTags()} { if (!allSelectedViews.find(item => item.name === val)) { return Promise.resolve(); } return Promise.reject(new Error(locale?.viewError)); }, }, ]} style={{ marginBottom: 0 }} > prevValues.label !== currentValues.label} > {({ getFieldValue }) => (
{(activeKey.startsWith('savedSearch') || searchParams.saved_search_id) && ( )}
)}
} placement="bottomRight" visible={visible} onVisibleChange={vis => { if (vis) { form.setFieldsValue({ label: '' }); } else { setVisible(false); } }} >
); };