mirror of
				https://github.com/AppFlowy-IO/AppFlowy.git
				synced 2025-10-31 10:03:18 +00:00 
			
		
		
		
	fix/move grid view options to dropdown
This commit is contained in:
		
							parent
							
								
									07b183aef2
								
							
						
					
					
						commit
						5da5d92b8a
					
				| @ -0,0 +1,11 @@ | |||||||
|  | export const GroupBySvg = () => { | ||||||
|  |   return ( | ||||||
|  |     <svg width='100%' height='100%' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'> | ||||||
|  |       <path d='M10 2H13C13.5523 2 14 2.44772 14 3V6' stroke='#333333' strokeLinecap='round' strokeLinejoin='round' /> | ||||||
|  |       <path d='M6 2H3C2.44772 2 2 2.44772 2 3V6' stroke='#333333' strokeLinecap='round' strokeLinejoin='round' /> | ||||||
|  |       <path d='M6 14H3C2.44772 14 2 13.5523 2 13V10' stroke='#333333' strokeLinecap='round' strokeLinejoin='round' /> | ||||||
|  |       <path d='M10 14H13C13.5523 14 14 13.5523 14 13V10' stroke='#333333' strokeLinecap='round' strokeLinejoin='round' /> | ||||||
|  |       <rect x='6' y='6' width='4' height='4' rx='1' stroke='#333333' /> | ||||||
|  |     </svg> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
| @ -0,0 +1,29 @@ | |||||||
|  | import { GridTableCount } from '../GridTableCount/GridTableCount'; | ||||||
|  | import { GridTableHeader } from '../GridTableHeader/GridTableHeader'; | ||||||
|  | import { GridAddRow } from '../GridTableRows/GridAddRow'; | ||||||
|  | import { GridTableRows } from '../GridTableRows/GridTableRows'; | ||||||
|  | import { GridTitle } from '../GridTitle/GridTitle'; | ||||||
|  | import { GridToolbar } from '../GridToolbar/GridToolbar'; | ||||||
|  | 
 | ||||||
|  | export const Grid = ({ viewId }: { viewId: string }) => { | ||||||
|  |   return ( | ||||||
|  |     <div className='mx-auto mt-8 flex flex-col gap-8 px-8'> | ||||||
|  |       <div className='flex w-full  items-center justify-between'> | ||||||
|  |         <GridTitle /> | ||||||
|  |         <GridToolbar /> | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|  |       {/* table component view with text area for td */} | ||||||
|  |       <div className='flex flex-col gap-4'> | ||||||
|  |         <table className='w-full table-fixed text-sm'> | ||||||
|  |           <GridTableHeader /> | ||||||
|  |           <GridTableRows /> | ||||||
|  |         </table> | ||||||
|  | 
 | ||||||
|  |         <GridAddRow /> | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|  |       <GridTableCount /> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
| @ -15,7 +15,7 @@ export const GridTableItem = ({ | |||||||
|   return ( |   return ( | ||||||
|     <div> |     <div> | ||||||
|       <input |       <input | ||||||
|         className='h-full w-full rounded-lg border border-transparent p-2 hover:border-main-accent' |         className='h-full w-full rounded-lg border border-transparent p-2 focus:border-main-accent' | ||||||
|         type='text' |         type='text' | ||||||
|         value={value} |         value={value} | ||||||
|         onChange={onValueChange} |         onChange={onValueChange} | ||||||
|  | |||||||
| @ -1,7 +1,5 @@ | |||||||
|  | import { useAppDispatch, useAppSelector } from '@/appflowy_app/stores/store'; | ||||||
| import { useState } from 'react'; | import { useState } from 'react'; | ||||||
| import { gridActions } from '../../../stores/reducers/grid/slice'; |  | ||||||
| 
 |  | ||||||
| import { useAppDispatch, useAppSelector } from '../../../stores/store'; |  | ||||||
| 
 | 
 | ||||||
| export const useGridTitleHooks = function () { | export const useGridTitleHooks = function () { | ||||||
|   const dispatch = useAppDispatch(); |   const dispatch = useAppDispatch(); | ||||||
| @ -9,16 +7,12 @@ export const useGridTitleHooks = function () { | |||||||
| 
 | 
 | ||||||
|   const [title, setTitle] = useState(grid.title); |   const [title, setTitle] = useState(grid.title); | ||||||
|   const [changingTitle, setChangingTitle] = useState(false); |   const [changingTitle, setChangingTitle] = useState(false); | ||||||
|  |   const [showOptions, setShowOptions] = useState(false); | ||||||
| 
 | 
 | ||||||
|   const onTitleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => { |   const onTitleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => { | ||||||
|     setTitle(event.target.value); |     setTitle(event.target.value); | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const onTitleBlur = () => { |  | ||||||
|     dispatch(gridActions.updateGridTitle({ title })); |  | ||||||
|     setChangingTitle(false); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   const onTitleClick = () => { |   const onTitleClick = () => { | ||||||
|     setChangingTitle(true); |     setChangingTitle(true); | ||||||
|   }; |   }; | ||||||
| @ -26,8 +20,9 @@ export const useGridTitleHooks = function () { | |||||||
|   return { |   return { | ||||||
|     title, |     title, | ||||||
|     onTitleChange, |     onTitleChange, | ||||||
|     onTitleBlur, |  | ||||||
|     onTitleClick, |     onTitleClick, | ||||||
|     changingTitle, |     changingTitle, | ||||||
|  |     showOptions, | ||||||
|  |     setShowOptions, | ||||||
|   }; |   }; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,15 +1,21 @@ | |||||||
| import { useGridTitleHooks } from './GridTitle.hooks'; | import { useGridTitleHooks } from './GridTitle.hooks'; | ||||||
| import { SettingsSvg } from '../../_shared/svg/SettingsSvg'; | import { SettingsSvg } from '../../_shared/svg/SettingsSvg'; | ||||||
|  | import { GridTitleOptionsPopup } from './GridTitleOptionsPopup'; | ||||||
| 
 | 
 | ||||||
| export const GridTitle = () => { | export const GridTitle = () => { | ||||||
|   const { title } = useGridTitleHooks(); |   const { title, showOptions, setShowOptions } = useGridTitleHooks(); | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div className={'flex items-center text-xl font-semibold'}> |     <div className={'relative flex items-center '}> | ||||||
|       <div>{title}</div> |       <div>{title}</div> | ||||||
|       <button className={'ml-2 h-5 w-5'}> | 
 | ||||||
|         <SettingsSvg></SettingsSvg> |       <div className='flex '> | ||||||
|       </button> |         <button className={'ml-2 h-5 w-5 '} onClick={() => setShowOptions(!showOptions)}> | ||||||
|  |           <SettingsSvg></SettingsSvg> | ||||||
|  |         </button> | ||||||
|  | 
 | ||||||
|  |         {showOptions && <GridTitleOptionsPopup onClose={() => setShowOptions(!showOptions)} />} | ||||||
|  |       </div> | ||||||
|     </div> |     </div> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -0,0 +1,55 @@ | |||||||
|  | import { IPopupItem, Popup } from '../../_shared/Popup'; | ||||||
|  | import { FilterSvg } from '../../_shared/svg/FilterSvg'; | ||||||
|  | import { GroupBySvg } from '../../_shared/svg/GroupBySvg'; | ||||||
|  | import { PropertiesSvg } from '../../_shared/svg/PropertiesSvg'; | ||||||
|  | import { SortSvg } from '../../_shared/svg/SortSvg'; | ||||||
|  | 
 | ||||||
|  | export const GridTitleOptionsPopup = ({ onClose }: { onClose?: () => void }) => { | ||||||
|  |   const items: IPopupItem[] = [ | ||||||
|  |     { | ||||||
|  |       icon: ( | ||||||
|  |         <i className={'h-[16px] w-[16px] text-black'}> | ||||||
|  |           <FilterSvg /> | ||||||
|  |         </i> | ||||||
|  |       ), | ||||||
|  |       onClick: () => { | ||||||
|  |         console.log('filter'); | ||||||
|  |       }, | ||||||
|  |       title: 'Filter', | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       icon: ( | ||||||
|  |         <i className={'h-[16px] w-[16px] text-black'}> | ||||||
|  |           <SortSvg /> | ||||||
|  |         </i> | ||||||
|  |       ), | ||||||
|  |       onClick: () => { | ||||||
|  |         console.log('sort'); | ||||||
|  |       }, | ||||||
|  |       title: 'Sort', | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       icon: ( | ||||||
|  |         <i className={'h-[16px] w-[16px] text-black'}> | ||||||
|  |           <PropertiesSvg /> | ||||||
|  |         </i> | ||||||
|  |       ), | ||||||
|  |       onClick: () => { | ||||||
|  |         console.log('fields'); | ||||||
|  |       }, | ||||||
|  |       title: 'Fields', | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       icon: ( | ||||||
|  |         <i className={'h-[16px] w-[16px] text-black'}> | ||||||
|  |           <GroupBySvg /> | ||||||
|  |         </i> | ||||||
|  |       ), | ||||||
|  |       onClick: () => { | ||||||
|  |         console.log('group by'); | ||||||
|  |       }, | ||||||
|  |       title: 'Group by', | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  |   return <Popup items={items} className={'absolute top-full z-10 w-fit'} onOutsideClick={onClose} />; | ||||||
|  | }; | ||||||
| @ -1,17 +1,11 @@ | |||||||
| import { GridAddView } from '../GridAddView/GridAddView'; | import { GridAddView } from '../GridAddView/GridAddView'; | ||||||
| import { SearchInput } from '../../_shared/SearchInput'; | import { SearchInput } from '../../_shared/SearchInput'; | ||||||
| import { GridSortButton } from './GridSortButton'; |  | ||||||
| import { GridFieldsButton } from './GridFieldsButton'; |  | ||||||
| import { GridFilterButton } from './GridFilterButton'; |  | ||||||
| 
 | 
 | ||||||
| export const GridToolbar = () => { | export const GridToolbar = () => { | ||||||
|   return ( |   return ( | ||||||
|     <div className='flex shrink-0 items-center gap-4'> |     <div className='flex shrink-0 items-center gap-4'> | ||||||
|       <SearchInput /> |       <SearchInput /> | ||||||
|       <GridAddView /> |       <GridAddView /> | ||||||
|       <GridFilterButton></GridFilterButton> |  | ||||||
|       <GridSortButton></GridSortButton> |  | ||||||
|       <GridFieldsButton></GridFieldsButton> |  | ||||||
|     </div> |     </div> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,9 +0,0 @@ | |||||||
| export const useGrid = () => { |  | ||||||
|   const loadGrid = async (id: string) => { |  | ||||||
|     console.log('loading grid'); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   return { |  | ||||||
|     loadGrid, |  | ||||||
|   }; |  | ||||||
| }; |  | ||||||
| @ -1,45 +1,22 @@ | |||||||
| import { GridAddView } from '../components/grid/GridAddView/GridAddView'; |  | ||||||
| import { GridTableCount } from '../components/grid/GridTableCount/GridTableCount'; |  | ||||||
| import { GridTableHeader } from '../components/grid/GridTableHeader/GridTableHeader'; |  | ||||||
| import { GridAddRow } from '../components/grid/GridTableRows/GridAddRow'; |  | ||||||
| import { GridTableRows } from '../components/grid/GridTableRows/GridTableRows'; |  | ||||||
| import { GridTitle } from '../components/grid/GridTitle/GridTitle'; |  | ||||||
| import { SearchInput } from '../components/_shared/SearchInput'; |  | ||||||
| import { GridToolbar } from '../components/grid/GridToolbar/GridToolbar'; |  | ||||||
| import { useParams } from 'react-router-dom'; | import { useParams } from 'react-router-dom'; | ||||||
| import { useGrid } from './GridPage.hooks'; | 
 | ||||||
| import { useEffect } from 'react'; | import { useEffect, useState } from 'react'; | ||||||
|  | import { Grid } from '../components/grid/Grid/Grid'; | ||||||
| 
 | 
 | ||||||
| export const GridPage = () => { | export const GridPage = () => { | ||||||
|   const params = useParams(); |   const params = useParams(); | ||||||
|   const { loadGrid } = useGrid(); |   const [viewId, setViewId] = useState(''); | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     void (async () => { |     if (params?.id?.length) { | ||||||
|       if (!params?.id) return; |       setViewId(params.id); | ||||||
|       await loadGrid(params.id); |       // setDatabaseId('testDb');
 | ||||||
|     })(); |     } | ||||||
|   }, [params]); |   }, [params]); | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div className='mx-auto mt-8 flex flex-col gap-8 px-8'> |     <div className='flex h-full flex-col gap-8 px-8 pt-8'> | ||||||
|       <h1 className='text-4xl font-bold'>Grid</h1> |       <h1 className='text-4xl font-bold'>Grid: {viewId}</h1> | ||||||
| 
 |       {viewId?.length && <Grid viewId={viewId} />} | ||||||
|       <div className='flex w-full  items-center justify-between'> |  | ||||||
|         <GridTitle /> |  | ||||||
|         <GridToolbar /> |  | ||||||
|       </div> |  | ||||||
| 
 |  | ||||||
|       {/* table component view with text area for td */} |  | ||||||
|       <div className='flex flex-col gap-4'> |  | ||||||
|         <table className='w-full table-fixed text-sm'> |  | ||||||
|           <GridTableHeader /> |  | ||||||
|           <GridTableRows /> |  | ||||||
|         </table> |  | ||||||
| 
 |  | ||||||
|         <GridAddRow /> |  | ||||||
|       </div> |  | ||||||
| 
 |  | ||||||
|       <GridTableCount /> |  | ||||||
|     </div> |     </div> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Mike Abebe
						Mike Abebe