mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-09-09 08:40:06 +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