chore: (unstable) using controllers

This commit is contained in:
ascarbek 2023-03-03 17:14:58 +06:00
parent 08bb4e4116
commit 11649ef16d
14 changed files with 401 additions and 275 deletions

View File

@ -5,7 +5,7 @@ import {
SingleSelectTypeOptionPB,
ViewLayoutTypePB,
} from '../../../services/backend';
import { Log } from '../../utils/log';
import {Log} from '../../utils/log';
import {
assertFieldName,
assertNumberOfFields,
@ -20,10 +20,10 @@ import {
SelectOptionBackendService,
SelectOptionCellBackendService,
} from '../../stores/effects/database/cell/select_option_bd_svc';
import { TypeOptionController } from '../../stores/effects/database/field/type_option/type_option_controller';
import { None, Some } from 'ts-results';
import { RowBackendService } from '../../stores/effects/database/row/row_bd_svc';
import { makeSingleSelectTypeOptionContext } from '../../stores/effects/database/field/type_option/type_option_context';
import {TypeOptionController} from '../../stores/effects/database/field/type_option/type_option_controller';
import {None, Some} from 'ts-results';
import {RowBackendService} from '../../stores/effects/database/row/row_bd_svc';
import {makeSingleSelectTypeOptionContext} from '../../stores/effects/database/field/type_option/type_option_context';
export const TestCreateGrid = () => {
async function createBuildInGrid() {
@ -180,6 +180,7 @@ export const TestEditField = () => {
await controller.initialize();
const newName = 'hello world';
await controller.setFieldName(newName);
await controller.switchToField(FieldType.MultiSelect);
await assertFieldName(view.id, firstFieldInfo.field.id, firstFieldInfo.field.field_type, newName);
await databaseController.dispose();
@ -199,6 +200,9 @@ export const TestCreateNewField = () => {
const controller = new TypeOptionController(view.id, None);
await controller.initialize();
await assertNumberOfFields(view.id, 4);
await databaseController.dispose();
}

View File

@ -0,0 +1,99 @@
import { TypeOptionController } from '../../../stores/effects/database/field/type_option/type_option_controller';
import { Some } from 'ts-results';
import { IDatabaseField, ISelectOption } from '../../../stores/reducers/database/slice';
import {
ChecklistTypeOptionPB,
DateFormat,
FieldType,
MultiSelectTypeOptionPB,
NumberFormat,
SingleSelectTypeOptionPB,
TimeFormat,
} from '../../../../services/backend';
import {
makeChecklistTypeOptionContext,
makeDateTypeOptionContext,
makeMultiSelectTypeOptionContext,
makeNumberTypeOptionContext,
makeSingleSelectTypeOptionContext,
} from '../../../stores/effects/database/field/type_option/type_option_context';
import { boardActions } from '../../../stores/reducers/board/slice';
import { FieldInfo } from '../../../stores/effects/database/field/field_controller';
import { AppDispatch } from '../../../stores/store';
export default async function (viewId: string, fieldInfo: FieldInfo, dispatch?: AppDispatch): Promise<IDatabaseField> {
const field = fieldInfo.field;
const typeOptionController = new TypeOptionController(viewId, Some(fieldInfo));
let selectOptions: ISelectOption[] | undefined;
let numberFormat: NumberFormat | undefined;
let dateFormat: DateFormat | undefined;
let timeFormat: TimeFormat | undefined;
let includeTime: boolean | undefined;
// temporary hack to set grouping field
let groupingFieldSelected = false;
switch (field.field_type) {
case FieldType.SingleSelect:
case FieldType.MultiSelect:
case FieldType.Checklist:
{
let typeOption: SingleSelectTypeOptionPB | MultiSelectTypeOptionPB | ChecklistTypeOptionPB | undefined;
if (field.field_type === FieldType.SingleSelect) {
typeOption = (await makeSingleSelectTypeOptionContext(typeOptionController).getTypeOption()).unwrap();
if (!groupingFieldSelected) {
if (dispatch) {
dispatch(boardActions.setGroupingFieldId({ fieldId: field.id }));
}
groupingFieldSelected = true;
}
}
if (field.field_type === FieldType.MultiSelect) {
typeOption = (await makeMultiSelectTypeOptionContext(typeOptionController).getTypeOption()).unwrap();
}
if (field.field_type === FieldType.Checklist) {
typeOption = (await makeChecklistTypeOptionContext(typeOptionController).getTypeOption()).unwrap();
}
if (typeOption) {
selectOptions = typeOption.options.map<ISelectOption>((option) => {
return {
selectOptionId: option.id,
title: option.name,
color: option.color,
};
});
}
}
break;
case FieldType.Number:
{
const typeOption = (await makeNumberTypeOptionContext(typeOptionController).getTypeOption()).unwrap();
numberFormat = typeOption.format;
}
break;
case FieldType.DateTime:
{
const typeOption = (await makeDateTypeOptionContext(typeOptionController).getTypeOption()).unwrap();
dateFormat = typeOption.date_format;
timeFormat = typeOption.time_format;
includeTime = typeOption.include_time;
}
break;
}
return {
fieldId: field.id,
title: field.name,
fieldType: field.field_type,
fieldOptions: {
selectOptions,
numberFormat,
dateFormat,
timeFormat,
includeTime,
},
};
}

View File

@ -0,0 +1,40 @@
import { CellIdentifier } from '../../../stores/effects/database/cell/cell_bd_svc';
import { CellCache } from '../../../stores/effects/database/cell/cell_cache';
import { FieldController } from '../../../stores/effects/database/field/field_controller';
import { CellControllerBuilder } from '../../../stores/effects/database/cell/controller_builder';
import { DateCellDataPB, FieldType, SelectOptionCellDataPB } from '../../../../services/backend';
import { useState } from 'react';
export const useCell = (cellIdentifier: CellIdentifier, cellCache: CellCache, fieldController: FieldController) => {
const [data, setData] = useState<string[]>([]);
const loadCell = async () => {
const builder = new CellControllerBuilder(cellIdentifier, cellCache, fieldController);
const cellController = builder.build();
cellController.subscribeChanged({
onCellChanged: (value) => {
if (
cellIdentifier.fieldType === FieldType.Checklist ||
cellIdentifier.fieldType === FieldType.MultiSelect ||
cellIdentifier.fieldType === FieldType.SingleSelect
) {
const v = value.unwrap() as SelectOptionCellDataPB;
setData(v.select_options.map((option) => option.id));
} else if (cellIdentifier.fieldType === FieldType.DateTime) {
const v = value.unwrap() as DateCellDataPB;
setData([v.date]);
} else {
const v = value.unwrap() as string;
setData([v]);
}
},
});
cellController.getCellData();
};
return {
loadCell,
data,
};
};

View File

@ -0,0 +1,50 @@
import { useEffect, useState } from 'react';
import { DatabaseController } from '../../../stores/effects/database/database_controller';
import {
databaseActions,
DatabaseFieldMap,
IDatabaseColumn,
IDatabaseRow,
} from '../../../stores/reducers/database/slice';
import { useAppDispatch, useAppSelector } from '../../../stores/store';
import loadField from './loadField';
import { FieldInfo } from '../../../stores/effects/database/field/field_controller';
export const useDatabase = (viewId: string) => {
const dispatch = useAppDispatch();
const databaseStore = useAppSelector((state) => state.database);
const boardStore = useAppSelector((state) => state.board);
const [controller, setController] = useState<DatabaseController>();
useEffect(() => {
if (!viewId.length) return;
const c = new DatabaseController(viewId);
setController(c);
// on unmount dispose the controller
return () => void c.dispose();
}, [viewId]);
const loadFields = async (fieldInfos: readonly FieldInfo[]) => {
const fields: DatabaseFieldMap = {};
const columns: IDatabaseColumn[] = [];
for (const fieldInfo of fieldInfos) {
const fieldPB = fieldInfo.field;
columns.push({
fieldId: fieldPB.id,
sort: 'none',
visible: fieldPB.visibility,
});
const field = await loadField(viewId, fieldInfo, dispatch);
fields[field.fieldId] = field;
}
dispatch(databaseActions.updateFields({ fields }));
dispatch(databaseActions.updateColumns({ columns }));
console.log(fields, columns);
};
return { loadFields, controller };
};

View File

@ -0,0 +1,32 @@
import { DatabaseController } from '../../../stores/effects/database/database_controller';
import { RowController } from '../../../stores/effects/database/row/row_controller';
import { RowInfo } from '../../../stores/effects/database/row/row_cache';
import { CellIdentifier } from '../../../stores/effects/database/cell/cell_bd_svc';
import { useState } from 'react';
export const useRow = (viewId: string, databaseController: DatabaseController, rowInfo: RowInfo) => {
const [cells, setCells] = useState<{ fieldId: string; cellIdentifier: CellIdentifier }[]>([]);
const rowCache = databaseController.databaseViewCache.getRowCache();
const fieldController = databaseController.fieldController;
const rowController = new RowController(rowInfo, fieldController, rowCache);
const loadRow = async () => {
const cellsPB = await rowController.loadCells();
const loadingCells: { fieldId: string; cellIdentifier: CellIdentifier }[] = [];
for (const [fieldId, cellIdentifier] of cellsPB.entries()) {
loadingCells.push({
fieldId,
cellIdentifier,
});
}
setCells(loadingCells);
};
return {
loadRow: loadRow,
cells: cells,
};
};

View File

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import { useAppDispatch, useAppSelector } from '../../stores/store';
import { boardActions } from '../../stores/reducers/board/slice';
import { ICellData, IDatabase, IDatabaseRow, ISelectOption } from '../../stores/reducers/database/slice';
import { IDatabase, IDatabaseRow, ISelectOption } from '../../stores/reducers/database/slice';
export const useBoard = () => {
const dispatch = useAppDispatch();
@ -15,20 +15,22 @@ export const useBoard = () => {
useEffect(() => {
setTitle(database.title);
setBoardColumns(
database.fields[groupingFieldId].fieldOptions.selectOptions?.map((groupFieldItem) => {
const rows = database.rows
.filter((row) => row.cells[groupingFieldId].optionIds?.some((so) => so === groupFieldItem.selectOptionId))
.map((row) => ({
...row,
isGhost: false,
}));
return {
...groupFieldItem,
rows: rows,
};
}) || []
);
if (database.fields[groupingFieldId]) {
setBoardColumns(
database.fields[groupingFieldId].fieldOptions.selectOptions?.map((groupFieldItem) => {
/* const rows = database.rows
.filter((row) => row.cells[groupingFieldId].data?.some((so) => so === groupFieldItem.selectOptionId))
.map((row) => ({
...row,
isGhost: false,
}));*/
return {
...groupFieldItem,
rows: [],
};
}) || []
);
}
}, [database, groupingFieldId]);
const changeGroupingField = (fieldId: string) => {

View File

@ -1,13 +1,15 @@
import { SettingsSvg } from '../_shared/svg/SettingsSvg';
import { SearchInput } from '../_shared/SearchInput';
import { useDatabase } from '../_shared/Database.hooks';
import { BoardBlock } from './BoardBlock';
import { NewBoardBlock } from './NewBoardBlock';
import { IDatabaseRow } from '../../stores/reducers/database/slice';
import { useBoard } from './Board.hooks';
import { useDatabase } from '../_shared/database-hooks/useDatabase';
import { useEffect, useState } from 'react';
import { RowInfo } from '../../stores/effects/database/row/row_cache';
export const Board = ({ viewId }: { viewId: string }) => {
const { controller, loadFields } = useDatabase(viewId);
export const Board = () => {
const { database, newField, renameField, newRow } = useDatabase();
const {
title,
boardColumns,
@ -20,6 +22,24 @@ export const Board = () => {
ghostLocation,
} = useBoard();
const [rows, setRows] = useState<readonly RowInfo[]>([]);
useEffect(() => {
if (!controller) return;
void (async () => {
controller.subscribe({
onRowsChanged: (rowInfos) => {
setRows(rowInfos);
},
onFieldsChanged: (fieldInfos) => {
void loadFields(fieldInfos);
},
});
await controller.open();
})();
}, [controller]);
return (
<>
<div className='flex w-full items-center justify-between'>
@ -36,16 +56,15 @@ export const Board = () => {
</div>
<div className={'relative w-full flex-1 overflow-auto'}>
<div className={'absolute flex h-full flex-shrink-0 items-start justify-start gap-4'}>
{database &&
{controller &&
boardColumns?.map((column, index) => (
<BoardBlock
viewId={viewId}
controller={controller}
key={index}
title={column.title}
rows={rows}
groupingFieldId={groupingFieldId}
count={column.rows.length}
fields={database.fields}
columns={database.columns}
rows={column.rows}
startMove={startMove}
endMove={endMove}
/>

View File

@ -1,24 +1,26 @@
import { Details2Svg } from '../_shared/svg/Details2Svg';
import AddSvg from '../_shared/svg/AddSvg';
import { DatabaseFieldMap, ICellData, IDatabaseColumn, IDatabaseRow } from '../../stores/reducers/database/slice';
import { BoardBlockItem } from './BoardBlockItem';
import { DatabaseFieldMap, IDatabaseColumn, IDatabaseRow } from '../../stores/reducers/database/slice';
import { BoardCard } from './BoardCard';
import { RowInfo } from '../../stores/effects/database/row/row_cache';
import { useEffect } from 'react';
import { useRow } from '../_shared/database-hooks/useRow';
import { DatabaseController } from '../../stores/effects/database/database_controller';
export const BoardBlock = ({
viewId,
controller,
title,
groupingFieldId,
count,
fields,
columns,
rows,
startMove,
endMove,
}: {
viewId: string;
controller: DatabaseController;
title: string;
groupingFieldId: string;
count: number;
fields: DatabaseFieldMap;
columns: IDatabaseColumn[];
rows: IDatabaseRow[];
rows: readonly RowInfo[];
startMove: (id: string) => void;
endMove: () => void;
}) => {
@ -27,7 +29,7 @@ export const BoardBlock = ({
<div className={'flex items-center justify-between p-4'}>
<div className={'flex items-center gap-2'}>
<span>{title}</span>
<span className={'text-shade-4'}>({count})</span>
<span className={'text-shade-4'}>()</span>
</div>
<div className={'flex items-center gap-2'}>
<button className={'h-5 w-5 rounded hover:bg-surface-2'}>
@ -40,15 +42,15 @@ export const BoardBlock = ({
</div>
<div className={'flex flex-1 flex-col gap-1 overflow-auto px-2'}>
{rows.map((row, index) => (
<BoardBlockItem
<BoardCard
viewId={viewId}
controller={controller}
key={index}
groupingFieldId={groupingFieldId}
fields={fields}
columns={columns}
row={row}
startMove={() => startMove(row.rowId)}
startMove={() => startMove(row.row.id)}
endMove={() => endMove()}
></BoardBlockItem>
></BoardCard>
))}
</div>
<div className={'p-2'}>

View File

@ -3,22 +3,32 @@ import { Details2Svg } from '../_shared/svg/Details2Svg';
import { FieldType } from '../../../services/backend';
import { getBgColor } from '../_shared/getColor';
import { MouseEventHandler, useEffect, useRef, useState } from 'react';
import { RowInfo } from '../../stores/effects/database/row/row_cache';
import { useRow } from '../_shared/database-hooks/useRow';
import { DatabaseController } from '../../stores/effects/database/database_controller';
import { useAppSelector } from '../../stores/store';
import { BoardCell } from './BoardCell';
export const BoardBlockItem = ({
export const BoardCard = ({
viewId,
controller,
groupingFieldId,
fields,
columns,
// fields,
// columns,
row,
startMove,
endMove,
}: {
viewId: string;
controller: DatabaseController;
groupingFieldId: string;
fields: DatabaseFieldMap;
columns: IDatabaseColumn[];
row: IDatabaseRow;
// fields: DatabaseFieldMap;
// columns: IDatabaseColumn[];
row: RowInfo;
startMove: () => void;
endMove: () => void;
}) => {
const databaseStore = useAppSelector((state) => state.database);
const [isMoving, setIsMoving] = useState(false);
const [isDown, setIsDown] = useState(false);
const [ghostWidth, setGhostWidth] = useState(0);
@ -43,6 +53,13 @@ export const BoardBlockItem = ({
}
}, [el, isMoving]);
const { loadRow, cells } = useRow(viewId, controller, row);
useEffect(() => {
void (async () => {
await loadRow();
})();
}, []);
const onMouseMove: MouseEventHandler<HTMLDivElement> = (e) => {
setGhostLeft(ghostLeft + e.movementX);
setGhostTop(ghostTop + e.movementY);
@ -74,31 +91,14 @@ export const BoardBlockItem = ({
<Details2Svg></Details2Svg>
</button>
<div className={'flex flex-col gap-3'}>
{columns
.filter((column) => column.fieldId !== groupingFieldId)
.map((column, index) => {
switch (fields[column.fieldId].fieldType) {
case FieldType.MultiSelect:
return (
<div key={index} className={'flex flex-wrap items-center gap-2'}>
{row.cells[column.fieldId].optionIds?.map((option, indexOption) => {
const selectOptions = fields[column.fieldId].fieldOptions.selectOptions;
const selectedOption = selectOptions?.find((so) => so.selectOptionId === option);
return (
<div
key={indexOption}
className={`rounded px-1 py-0.5 text-sm ${getBgColor(selectedOption?.color)}`}
>
{selectedOption?.title}
</div>
);
})}
</div>
);
default:
return <div key={index}>{row.cells[column.fieldId].data}</div>;
}
})}
{cells.map((cell, index) => (
<BoardCell
key={index}
cellIdentifier={cell.cellIdentifier}
cellCache={controller.databaseViewCache.getRowCache().getCellCache()}
fieldController={controller.fieldController}
></BoardCell>
))}
</div>
</div>
{isMoving && (

View File

@ -0,0 +1,23 @@
import { useCell } from '../_shared/database-hooks/useCell';
import { CellIdentifier } from '../../stores/effects/database/cell/cell_bd_svc';
import { CellCache } from '../../stores/effects/database/cell/cell_cache';
import { FieldController } from '../../stores/effects/database/field/field_controller';
import {useEffect} from "react";
export const BoardCell = ({
cellIdentifier,
cellCache,
fieldController,
}: {
cellIdentifier: CellIdentifier;
cellCache: CellCache;
fieldController: FieldController;
}) => {
const { loadCell, data } = useCell(cellIdentifier, cellCache, fieldController);
useEffect(() => {
void (async () => {
await loadCell()
})();
}, [])
return <div>{data}</div>;
};

View File

@ -3,7 +3,8 @@ import { FieldController, FieldInfo } from './field/field_controller';
import { DatabaseViewCache } from './view/database_view_cache';
import { DatabasePB } from '../../../../services/backend/models/flowy-database/grid_entities';
import { RowChangedReason, RowInfo } from './row/row_cache';
import { Err, Ok } from 'ts-results';
import { Err, Ok, Result } from 'ts-results';
import { FlowyError, RowPB } from '../../../../services/backend';
export type SubscribeCallback = {
onViewChanged?: (data: DatabasePB) => void;

View File

@ -1,6 +1,6 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
const initialState = 'field1';
const initialState = '';
export const boardSlice = createSlice({
name: 'board',

View File

@ -1,5 +1,4 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { nanoid } from 'nanoid';
import { FieldType } from '../../../../services/backend/models/flowy-database/field_entities';
import { DateFormat, NumberFormat, SelectOptionColorPB, TimeFormat } from '../../../../services/backend';
@ -27,24 +26,22 @@ export interface IDatabaseField {
export interface IDatabaseColumn {
fieldId: string;
sort: 'none' | 'asc' | 'desc';
filter?: any;
visible: boolean;
}
export interface ICellData {
/*export interface ICellData {
rowId: string;
fieldId: string;
cellId: string;
data: string | number;
optionIds?: string[];
}
data: string[];
}*/
export type DatabaseCellMap = { [keys: string]: ICellData };
// export type DatabaseCellMap = { [keys: string]: ICellData };
export interface IDatabaseRow {
rowId: string;
// key(fieldId) -> value(Cell)
cells: DatabaseCellMap;
// cells: DatabaseCellMap;
}
export type DatabaseFieldMap = { [keys: string]: IDatabaseField };
@ -56,190 +53,47 @@ export interface IDatabase {
columns: IDatabaseColumn[];
}
// key(databaseId) -> value(IDatabase)
const initialState: IDatabase = {
title: 'Database One',
columns: [
{
visible: true,
fieldId: 'field1',
sort: 'none',
},
{
visible: true,
fieldId: 'field2',
sort: 'none',
},
{
visible: true,
fieldId: 'field3',
sort: 'none',
},
{
visible: true,
fieldId: 'field4',
sort: 'none',
},
],
fields: {
field1: {
title: 'status',
fieldId: 'field1',
fieldType: FieldType.SingleSelect,
fieldOptions: {
selectOptions: [
{
selectOptionId: 'so1',
title: 'To Do',
color: SelectOptionColorPB.Orange,
},
{
selectOptionId: 'so2',
title: 'In Progress',
color: SelectOptionColorPB.Green,
},
{
selectOptionId: 'so3',
title: 'Done',
color: SelectOptionColorPB.Blue,
},
],
},
},
field2: {
title: 'name',
fieldId: 'field2',
fieldType: FieldType.RichText,
fieldOptions: {},
},
field3: {
title: 'percent',
fieldId: 'field3',
fieldType: FieldType.Number,
fieldOptions: {
numberFormat: NumberFormat.Num,
},
},
field4: {
title: 'tags',
fieldId: 'field4',
fieldType: FieldType.MultiSelect,
fieldOptions: {
selectOptions: [
{
selectOptionId: 'f4so1',
title: 'type1',
color: SelectOptionColorPB.Blue,
},
{
selectOptionId: 'f4so2',
title: 'type2',
color: SelectOptionColorPB.Aqua,
},
{
selectOptionId: 'f4so3',
title: 'type3',
color: SelectOptionColorPB.Purple,
},
{
selectOptionId: 'f4so4',
title: 'type4',
color: SelectOptionColorPB.Purple,
},
{
selectOptionId: 'f4so5',
title: 'type5',
color: SelectOptionColorPB.Purple,
},
{
selectOptionId: 'f4so6',
title: 'type6',
color: SelectOptionColorPB.Purple,
},
{
selectOptionId: 'f4so7',
title: 'type7',
color: SelectOptionColorPB.Purple,
},
],
},
},
},
rows: [
{
rowId: 'row1',
cells: {
field1: {
rowId: 'row1',
fieldId: 'field1',
cellId: 'cell11',
data: '',
optionIds: ['so1'],
},
field2: {
rowId: 'row1',
fieldId: 'field2',
cellId: 'cell12',
data: 'Card 1',
},
field3: {
rowId: 'row1',
fieldId: 'field3',
cellId: 'cell13',
data: 10,
},
field4: {
rowId: 'row1',
fieldId: 'field4',
cellId: 'cell14',
data: '',
optionIds: ['f4so2', 'f4so3', 'f4so4', 'f4so5', 'f4so6', 'f4so7'],
},
},
},
{
rowId: 'row2',
cells: {
field1: {
rowId: 'row2',
fieldId: 'field1',
cellId: 'cell21',
data: '',
optionIds: ['so1'],
},
field2: {
rowId: 'row2',
fieldId: 'field2',
cellId: 'cell22',
data: 'Card 2',
},
field3: {
rowId: 'row2',
fieldId: 'field3',
cellId: 'cell23',
data: 20,
},
field4: {
rowId: 'row2',
fieldId: 'field4',
cellId: 'cell24',
data: '',
optionIds: ['f4so1'],
},
},
},
],
columns: [],
fields: {},
rows: [],
};
export const databaseSlice = createSlice({
name: 'database',
initialState: initialState,
reducers: {
clear: () => {
return initialState;
},
updateRows: (state, action: PayloadAction<{ rows: IDatabaseRow[] }>) => {
return {
...state,
rows: action.payload.rows,
};
},
updateFields: (state, action: PayloadAction<{ fields: DatabaseFieldMap }>) => {
return {
...state,
fields: action.payload.fields,
};
},
updateColumns: (state, action: PayloadAction<{ columns: IDatabaseColumn[] }>) => {
return {
...state,
columns: action.payload.columns,
};
},
updateTitle: (state, action: PayloadAction<{ title: string }>) => {
state.title = action.payload.title;
},
addField: (state, action: PayloadAction<{ field: IDatabaseField }>) => {
/*addField: (state, action: PayloadAction<{ field: IDatabaseField }>) => {
const { field } = action.payload;
state.fields[field.fieldId] = field;
@ -253,7 +107,7 @@ export const databaseSlice = createSlice({
cells[field.fieldId] = {
rowId: r.rowId,
fieldId: field.fieldId,
data: '',
data: [''],
cellId: nanoid(6),
};
return {
@ -261,15 +115,15 @@ export const databaseSlice = createSlice({
cells: cells,
};
});
},
},*/
updateField: (state, action: PayloadAction<{ field: IDatabaseField }>) => {
/*updateField: (state, action: PayloadAction<{ field: IDatabaseField }>) => {
const { field } = action.payload;
state.fields[field.fieldId] = field;
},
},*/
addFieldSelectOption: (state, action: PayloadAction<{ fieldId: string; option: ISelectOption }>) => {
/*addFieldSelectOption: (state, action: PayloadAction<{ fieldId: string; option: ISelectOption }>) => {
const { fieldId, option } = action.payload;
const field = state.fields[fieldId];
@ -283,9 +137,9 @@ export const databaseSlice = createSlice({
selectOptions: [option],
};
}
},
},*/
updateFieldSelectOption: (state, action: PayloadAction<{ fieldId: string; option: ISelectOption }>) => {
/*updateFieldSelectOption: (state, action: PayloadAction<{ fieldId: string; option: ISelectOption }>) => {
const { fieldId, option } = action.payload;
const field = state.fields[fieldId];
@ -293,16 +147,16 @@ export const databaseSlice = createSlice({
if (selectOptions) {
selectOptions[selectOptions.findIndex((o) => o.selectOptionId === option.selectOptionId)] = option;
}
},
},*/
addRow: (state) => {
/*addRow: (state) => {
const rowId = nanoid(6);
const cells: { [keys: string]: ICellData } = {};
Object.keys(state.fields).forEach((id) => {
cells[id] = {
rowId: rowId,
fieldId: id,
data: '',
data: [''],
cellId: nanoid(6),
};
});
@ -312,15 +166,15 @@ export const databaseSlice = createSlice({
};
state.rows.push(newRow);
},
},*/
updateCellValue: (source, action: PayloadAction<{ cell: ICellData }>) => {
/*updateCellValue: (source, action: PayloadAction<{ cell: ICellData }>) => {
const { cell } = action.payload;
const row = source.rows.find((r) => r.rowId === cell.rowId);
if (row) {
row.cells[cell.fieldId] = cell;
}
},
},*/
},
});

View File

@ -4,19 +4,19 @@ import { Board } from '../components/board/Board';
export const BoardPage = () => {
const params = useParams();
const [databaseId, setDatabaseId] = useState('');
const [viewId, setViewId] = useState('');
useEffect(() => {
if (params?.id?.length) {
// setDatabaseId(params.id);
setDatabaseId('testDb');
setViewId(params.id);
// setDatabaseId('testDb');
}
}, [params]);
return (
<div className='flex h-full flex-col gap-8 px-8 pt-8'>
<h1 className='text-4xl font-bold'>Board</h1>
{databaseId?.length && <Board />}
<h1 className='text-4xl font-bold'>Board: {viewId}</h1>
{viewId?.length && <Board viewId={viewId} />}
</div>
);
};