mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat/integrate table with backend
This commit is contained in:
parent
5da5d92b8a
commit
073adf6268
@ -1,3 +1,6 @@
|
|||||||
|
import { ViewLayoutTypePB } from '@/services/backend';
|
||||||
|
|
||||||
|
import { useDatabase } from '../../_shared/database-hooks/useDatabase';
|
||||||
import { GridTableCount } from '../GridTableCount/GridTableCount';
|
import { GridTableCount } from '../GridTableCount/GridTableCount';
|
||||||
import { GridTableHeader } from '../GridTableHeader/GridTableHeader';
|
import { GridTableHeader } from '../GridTableHeader/GridTableHeader';
|
||||||
import { GridAddRow } from '../GridTableRows/GridAddRow';
|
import { GridAddRow } from '../GridTableRows/GridAddRow';
|
||||||
@ -6,24 +9,29 @@ import { GridTitle } from '../GridTitle/GridTitle';
|
|||||||
import { GridToolbar } from '../GridToolbar/GridToolbar';
|
import { GridToolbar } from '../GridToolbar/GridToolbar';
|
||||||
|
|
||||||
export const Grid = ({ viewId }: { viewId: string }) => {
|
export const Grid = ({ viewId }: { viewId: string }) => {
|
||||||
|
const { controller, rows, groups } = useDatabase(viewId, ViewLayoutTypePB.Grid);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='mx-auto mt-8 flex flex-col gap-8 px-8'>
|
controller &&
|
||||||
<div className='flex w-full items-center justify-between'>
|
groups && (
|
||||||
<GridTitle />
|
<div className='mx-auto mt-8 flex flex-col gap-8 px-8'>
|
||||||
<GridToolbar />
|
<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 allRows={rows} viewId={viewId} controller={controller} />
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<GridAddRow />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<GridTableCount />
|
||||||
</div>
|
</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>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,7 @@ import { useAppDispatch, useAppSelector } from '../../../stores/store';
|
|||||||
|
|
||||||
export const useGridTableHeaderHooks = function () {
|
export const useGridTableHeaderHooks = function () {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const grid = useAppSelector((state) => state.grid);
|
const database = useAppSelector((state) => state.database);
|
||||||
|
|
||||||
const onAddField = () => {
|
const onAddField = () => {
|
||||||
dispatch(
|
dispatch(
|
||||||
@ -21,7 +21,13 @@ export const useGridTableHeaderHooks = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fields: grid.fields,
|
fields: Object.values(database.fields).map((field) => {
|
||||||
|
return {
|
||||||
|
fieldId: field.fieldId,
|
||||||
|
name: field.title,
|
||||||
|
fieldType: field.fieldType,
|
||||||
|
};
|
||||||
|
}),
|
||||||
onAddField,
|
onAddField,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,7 @@ export const GridTableHeader = () => {
|
|||||||
{field.fieldType === FieldType.SingleSelect && <SingleSelectTypeSvg></SingleSelectTypeSvg>}
|
{field.fieldType === FieldType.SingleSelect && <SingleSelectTypeSvg></SingleSelectTypeSvg>}
|
||||||
{field.fieldType === FieldType.MultiSelect && <MultiSelectTypeSvg></MultiSelectTypeSvg>}
|
{field.fieldType === FieldType.MultiSelect && <MultiSelectTypeSvg></MultiSelectTypeSvg>}
|
||||||
{field.fieldType === FieldType.Checklist && <ChecklistTypeSvg></ChecklistTypeSvg>}
|
{field.fieldType === FieldType.Checklist && <ChecklistTypeSvg></ChecklistTypeSvg>}
|
||||||
|
{field.fieldType === FieldType.Checkbox && <ChecklistTypeSvg></ChecklistTypeSvg>}
|
||||||
{field.fieldType === FieldType.URL && <UrlTypeSvg></UrlTypeSvg>}
|
{field.fieldType === FieldType.URL && <UrlTypeSvg></UrlTypeSvg>}
|
||||||
</i>
|
</i>
|
||||||
<span>{field.name}</span>
|
<span>{field.name}</span>
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
import { gridActions } from '../../../stores/reducers/grid/slice';
|
|
||||||
import { useAppDispatch } from '../../../stores/store';
|
|
||||||
|
|
||||||
export const useGridAddRow = () => {
|
export const useGridAddRow = () => {
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
|
|
||||||
function addRow() {
|
function addRow() {
|
||||||
dispatch(gridActions.addRow());
|
// create a new row
|
||||||
|
console.log('create a new row');
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
import { CellIdentifier } from '@/appflowy_app/stores/effects/database/cell/cell_bd_svc';
|
||||||
|
import { CellCache } from '@/appflowy_app/stores/effects/database/cell/cell_cache';
|
||||||
|
import { FieldController } from '@/appflowy_app/stores/effects/database/field/field_controller';
|
||||||
|
import { BoardCell } from '../../board/BoardCell';
|
||||||
|
import { useCell } from '../../_shared/database-hooks/useCell';
|
||||||
|
|
||||||
|
export const GridTableCell = ({
|
||||||
|
cellIdentifier,
|
||||||
|
cellCache,
|
||||||
|
fieldController,
|
||||||
|
}: {
|
||||||
|
cellIdentifier: CellIdentifier;
|
||||||
|
cellCache: CellCache;
|
||||||
|
fieldController: FieldController;
|
||||||
|
}) => {
|
||||||
|
const { data } = useCell(cellIdentifier, cellCache, fieldController);
|
||||||
|
|
||||||
|
console.log({ data });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='min-h-[32px] w-full rounded-lg border border-transparent p-2 focus:border-main-accent'>
|
||||||
|
<BoardCell cellIdentifier={cellIdentifier} cellCache={cellCache} fieldController={fieldController} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -1,28 +0,0 @@
|
|||||||
import { useState } from 'react';
|
|
||||||
import { gridActions } from '../../../stores/reducers/grid/slice';
|
|
||||||
import { useAppDispatch, useAppSelector } from '../../../stores/store';
|
|
||||||
|
|
||||||
export const useGridTableItemHooks = (
|
|
||||||
rowItem: { value: string | number; fieldId: string; cellId: string },
|
|
||||||
rowId: string
|
|
||||||
) => {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const [value, setValue] = useState(rowItem.value);
|
|
||||||
|
|
||||||
function onValueChange(event: React.ChangeEvent<HTMLInputElement>) {
|
|
||||||
setValue(event.target.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onValueBlur() {
|
|
||||||
dispatch(gridActions.updateRowValue({ rowId: rowId, cellId: rowItem.cellId, value }));
|
|
||||||
}
|
|
||||||
|
|
||||||
const grid = useAppSelector((state) => state.grid);
|
|
||||||
|
|
||||||
return {
|
|
||||||
rows: grid.rows,
|
|
||||||
onValueChange,
|
|
||||||
value,
|
|
||||||
onValueBlur,
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,26 +0,0 @@
|
|||||||
import { useGridTableItemHooks } from './GridTableItem.hooks';
|
|
||||||
|
|
||||||
export const GridTableItem = ({
|
|
||||||
rowItem,
|
|
||||||
rowId,
|
|
||||||
}: {
|
|
||||||
rowItem: {
|
|
||||||
fieldId: string;
|
|
||||||
value: string | number;
|
|
||||||
cellId: string;
|
|
||||||
};
|
|
||||||
rowId: string;
|
|
||||||
}) => {
|
|
||||||
const { value, onValueChange, onValueBlur } = useGridTableItemHooks(rowItem, rowId);
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<input
|
|
||||||
className='h-full w-full rounded-lg border border-transparent p-2 focus:border-main-accent'
|
|
||||||
type='text'
|
|
||||||
value={value}
|
|
||||||
onChange={onValueChange}
|
|
||||||
onBlur={onValueBlur}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
@ -0,0 +1,33 @@
|
|||||||
|
import { DatabaseController } from '@/appflowy_app/stores/effects/database/database_controller';
|
||||||
|
import { RowInfo } from '@/appflowy_app/stores/effects/database/row/row_cache';
|
||||||
|
import { useRow } from '../../_shared/database-hooks/useRow';
|
||||||
|
import { GridTableCell } from './GridTableCell';
|
||||||
|
|
||||||
|
export const GridTableRow = ({
|
||||||
|
viewId,
|
||||||
|
controller,
|
||||||
|
row,
|
||||||
|
}: {
|
||||||
|
viewId: string;
|
||||||
|
controller: DatabaseController;
|
||||||
|
row: RowInfo;
|
||||||
|
}) => {
|
||||||
|
const { cells } = useRow(viewId, controller, row);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr>
|
||||||
|
{cells.map((cell, cellIndex) => {
|
||||||
|
return (
|
||||||
|
<td className='m-0 border border-l-0 border-shade-6 p-0 '>
|
||||||
|
<GridTableCell
|
||||||
|
key={cellIndex}
|
||||||
|
cellIdentifier={cell.cellIdentifier}
|
||||||
|
cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
|
||||||
|
fieldController={controller.fieldController}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
};
|
@ -1,9 +0,0 @@
|
|||||||
import { useAppSelector } from '../../../stores/store';
|
|
||||||
|
|
||||||
export const useGridTableRowsHooks = () => {
|
|
||||||
const grid = useAppSelector((state) => state.grid);
|
|
||||||
|
|
||||||
return {
|
|
||||||
rows: grid.rows,
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,24 +1,19 @@
|
|||||||
import { GridTableItem } from './GridTableItem';
|
import { DatabaseController } from '@/appflowy_app/stores/effects/database/database_controller';
|
||||||
import { useGridTableRowsHooks } from './GridTableRows.hooks';
|
import { RowInfo } from '@/appflowy_app/stores/effects/database/row/row_cache';
|
||||||
|
import { GridTableRow } from './GridTableRow';
|
||||||
export const GridTableRows = () => {
|
export const GridTableRows = ({
|
||||||
const { rows } = useGridTableRowsHooks();
|
viewId,
|
||||||
|
controller,
|
||||||
|
allRows,
|
||||||
|
}: {
|
||||||
|
viewId: string;
|
||||||
|
controller: DatabaseController;
|
||||||
|
allRows: readonly RowInfo[];
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<tbody>
|
<tbody>
|
||||||
{rows.map((row, i) => {
|
{allRows.map((row, i) => {
|
||||||
return (
|
return <GridTableRow row={row} key={i} viewId={viewId} controller={controller} />;
|
||||||
<tr key={row.rowId}>
|
|
||||||
{row.values.map((value) => {
|
|
||||||
return (
|
|
||||||
<td key={value.fieldId} className='m-0 border border-l-0 border-shade-6 p-0'>
|
|
||||||
<GridTableItem rowItem={value} rowId={row.rowId} />
|
|
||||||
</td>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
|
|
||||||
<td className='m-0 border border-r-0 border-shade-6 p-0'></td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
})}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user