### What problem does this PR solve? feat: Add sidebar to SearchPage #2247 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.11.0
| .searchSide { | .searchSide { | ||||
| overflow: auto; | |||||
| height: 100vh; | |||||
| height: calc(100vh - 72px); | |||||
| position: fixed !important; | position: fixed !important; | ||||
| inset-inline-start: 0; | inset-inline-start: 0; | ||||
| top: 0; | |||||
| top: 72px; | |||||
| bottom: 0; | bottom: 0; | ||||
| .modelForm { | |||||
| display: flex; | |||||
| padding: 24px; | |||||
| } | |||||
| .checkGroup { | .checkGroup { | ||||
| width: 100%; | width: 100%; | ||||
| height: 100%; | height: 100%; | ||||
| } | } | ||||
| .list { | .list { | ||||
| width: 100%; | width: 100%; | ||||
| height: 100%; | |||||
| overflow: auto; | |||||
| } | } | ||||
| .checkbox { | .checkbox { | ||||
| width: 100%; | width: 100%; |
| import { useNextFetchKnowledgeList } from '@/hooks/knowledge-hooks'; | |||||
| import { Checkbox, Layout, List, Typography } from 'antd'; | |||||
| import React, { useCallback } from 'react'; | |||||
| import { Layout } from 'antd'; | |||||
| import React from 'react'; | |||||
| import SearchSidebar from './sidebar'; | |||||
| import { CheckboxValueType } from 'antd/es/checkbox/Group'; | |||||
| import styles from './index.less'; | |||||
| const { Header, Content, Footer, Sider } = Layout; | |||||
| const { Header, Content, Footer } = Layout; | |||||
| const SearchPage = () => { | const SearchPage = () => { | ||||
| const { list } = useNextFetchKnowledgeList(); | |||||
| const handleChange = useCallback((checkedValue: CheckboxValueType[]) => { | |||||
| console.log('🚀 ~ handleChange ~ args:', checkedValue); | |||||
| }, []); | |||||
| return ( | return ( | ||||
| <Layout hasSider> | <Layout hasSider> | ||||
| <Sider className={styles.searchSide} theme={'light'}> | |||||
| <Checkbox.Group className={styles.checkGroup} onChange={handleChange}> | |||||
| <List | |||||
| bordered | |||||
| dataSource={list} | |||||
| className={styles.list} | |||||
| renderItem={(item) => ( | |||||
| <List.Item> | |||||
| <Checkbox value={item.id} className={styles.checkbox}> | |||||
| <Typography.Text | |||||
| ellipsis={{ tooltip: item.name }} | |||||
| className={styles.knowledgeName} | |||||
| > | |||||
| {item.name} | |||||
| </Typography.Text> | |||||
| </Checkbox> | |||||
| </List.Item> | |||||
| )} | |||||
| /> | |||||
| </Checkbox.Group> | |||||
| </Sider> | |||||
| <SearchSidebar></SearchSidebar> | |||||
| <Layout style={{ marginInlineStart: 200 }}> | <Layout style={{ marginInlineStart: 200 }}> | ||||
| <Header style={{ padding: 0 }} /> | <Header style={{ padding: 0 }} /> | ||||
| <Content style={{ margin: '24px 16px 0', overflow: 'initial' }}> | <Content style={{ margin: '24px 16px 0', overflow: 'initial' }}> |
| import { useNextFetchKnowledgeList } from '@/hooks/knowledge-hooks'; | |||||
| import type { CheckboxProps } from 'antd'; | |||||
| import { Checkbox, Layout, List, Typography } from 'antd'; | |||||
| import { CheckboxValueType } from 'antd/es/checkbox/Group'; | |||||
| import { useCallback, useMemo, useState } from 'react'; | |||||
| import { CheckboxChangeEvent } from 'antd/es/checkbox'; | |||||
| import styles from './index.less'; | |||||
| const { Sider } = Layout; | |||||
| const SearchSidebar = () => { | |||||
| const { list } = useNextFetchKnowledgeList(); | |||||
| const ids = useMemo(() => list.map((x) => x.id), [list]); | |||||
| const [checkedList, setCheckedList] = useState<string[]>(ids); | |||||
| const checkAll = list.length === checkedList.length; | |||||
| const indeterminate = | |||||
| checkedList.length > 0 && checkedList.length < list.length; | |||||
| const onChange = useCallback((list: CheckboxValueType[]) => { | |||||
| setCheckedList(list as string[]); | |||||
| }, []); | |||||
| const onCheckAllChange: CheckboxProps['onChange'] = useCallback( | |||||
| (e: CheckboxChangeEvent) => { | |||||
| setCheckedList(e.target.checked ? ids : []); | |||||
| }, | |||||
| [ids], | |||||
| ); | |||||
| return ( | |||||
| <Sider className={styles.searchSide} theme={'light'} width={260}> | |||||
| <Checkbox | |||||
| className={styles.modelForm} | |||||
| indeterminate={indeterminate} | |||||
| onChange={onCheckAllChange} | |||||
| checked={checkAll} | |||||
| > | |||||
| Check all | |||||
| </Checkbox> | |||||
| <Checkbox.Group | |||||
| className={styles.checkGroup} | |||||
| onChange={onChange} | |||||
| value={checkedList} | |||||
| > | |||||
| <List | |||||
| bordered | |||||
| dataSource={list} | |||||
| className={styles.list} | |||||
| renderItem={(item) => ( | |||||
| <List.Item> | |||||
| <Checkbox value={item.id} className={styles.checkbox}> | |||||
| <Typography.Text | |||||
| ellipsis={{ tooltip: item.name }} | |||||
| className={styles.knowledgeName} | |||||
| > | |||||
| {item.name} | |||||
| </Typography.Text> | |||||
| </Checkbox> | |||||
| </List.Item> | |||||
| )} | |||||
| /> | |||||
| </Checkbox.Group> | |||||
| </Sider> | |||||
| ); | |||||
| }; | |||||
| export default SearchSidebar; |