From 11649ef16dd20ce79f8344fe10fb78e749edf0d2 Mon Sep 17 00:00:00 2001 From: ascarbek Date: Fri, 3 Mar 2023 17:14:58 +0600 Subject: [PATCH] chore: (unstable) using controllers --- .../components/TestApiButton/TestGrid.tsx | 14 +- .../_shared/database-hooks/loadField.ts | 99 ++++++++ .../_shared/database-hooks/useCell.ts | 40 +++ .../_shared/database-hooks/useDatabase.ts | 50 ++++ .../_shared/database-hooks/useRow.ts | 32 +++ .../components/board/Board.hooks.ts | 32 +-- .../appflowy_app/components/board/Board.tsx | 37 ++- .../components/board/BoardBlock.tsx | 32 +-- .../{BoardBlockItem.tsx => BoardCard.tsx} | 62 ++--- .../components/board/BoardCell.tsx | 23 ++ .../effects/database/database_controller.ts | 3 +- .../stores/reducers/board/slice.ts | 2 +- .../stores/reducers/database/slice.ts | 240 ++++-------------- .../src/appflowy_app/views/BoardPage.tsx | 10 +- 14 files changed, 401 insertions(+), 275 deletions(-) create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/loadField.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useCell.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useDatabase.ts create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useRow.ts rename frontend/appflowy_tauri/src/appflowy_app/components/board/{BoardBlockItem.tsx => BoardCard.tsx} (67%) create mode 100644 frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCell.tsx diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/TestApiButton/TestGrid.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/TestApiButton/TestGrid.tsx index d0ccbfab47..b75e42e841 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/TestApiButton/TestGrid.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/TestApiButton/TestGrid.tsx @@ -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(); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/loadField.ts b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/loadField.ts new file mode 100644 index 0000000000..50a69d0828 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/loadField.ts @@ -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 { + 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((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, + }, + }; +} diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useCell.ts b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useCell.ts new file mode 100644 index 0000000000..0a270c86ef --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useCell.ts @@ -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([]); + + 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, + }; +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useDatabase.ts b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useDatabase.ts new file mode 100644 index 0000000000..adc75c9b22 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useDatabase.ts @@ -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(); + + 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 }; +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useRow.ts b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useRow.ts new file mode 100644 index 0000000000..3694d3fb84 --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/database-hooks/useRow.ts @@ -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, + }; +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/board/Board.hooks.ts b/frontend/appflowy_tauri/src/appflowy_app/components/board/Board.hooks.ts index 38f18c3f60..c5c2f42d5a 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/board/Board.hooks.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/board/Board.hooks.ts @@ -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) => { diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/board/Board.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/board/Board.tsx index e4cee56016..bd20cdbf64 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/board/Board.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/board/Board.tsx @@ -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([]); + + useEffect(() => { + if (!controller) return; + + void (async () => { + controller.subscribe({ + onRowsChanged: (rowInfos) => { + setRows(rowInfos); + }, + onFieldsChanged: (fieldInfos) => { + void loadFields(fieldInfos); + }, + }); + await controller.open(); + })(); + }, [controller]); + return ( <>
@@ -36,16 +56,15 @@ export const Board = () => {
- {database && + {controller && boardColumns?.map((column, index) => ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardBlock.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardBlock.tsx index 9d5e493d70..03373b58f9 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardBlock.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardBlock.tsx @@ -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 = ({
{title} - ({count}) + ()
{rows.map((row, index) => ( - startMove(row.rowId)} + startMove={() => startMove(row.row.id)} endMove={() => endMove()} - > + > ))}
diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardBlockItem.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCard.tsx similarity index 67% rename from frontend/appflowy_tauri/src/appflowy_app/components/board/BoardBlockItem.tsx rename to frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCard.tsx index 7741bbd05f..772f23f128 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardBlockItem.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCard.tsx @@ -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 = (e) => { setGhostLeft(ghostLeft + e.movementX); setGhostTop(ghostTop + e.movementY); @@ -74,31 +91,14 @@ export const BoardBlockItem = ({
- {columns - .filter((column) => column.fieldId !== groupingFieldId) - .map((column, index) => { - switch (fields[column.fieldId].fieldType) { - case FieldType.MultiSelect: - return ( -
- {row.cells[column.fieldId].optionIds?.map((option, indexOption) => { - const selectOptions = fields[column.fieldId].fieldOptions.selectOptions; - const selectedOption = selectOptions?.find((so) => so.selectOptionId === option); - return ( -
- {selectedOption?.title} -
- ); - })} -
- ); - default: - return
{row.cells[column.fieldId].data}
; - } - })} + {cells.map((cell, index) => ( + + ))}
{isMoving && ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCell.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCell.tsx new file mode 100644 index 0000000000..e0a0dc66cc --- /dev/null +++ b/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCell.tsx @@ -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
{data}
; +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_controller.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_controller.ts index 25af4535ea..0d417a0f4a 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_controller.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_controller.ts @@ -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; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/board/slice.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/board/slice.ts index 9a9fe82ab5..dff96c6a31 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/board/slice.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/board/slice.ts @@ -1,6 +1,6 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -const initialState = 'field1'; +const initialState = ''; export const boardSlice = createSlice({ name: 'board', diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/database/slice.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/database/slice.ts index 8c83a0c8f6..d959bf7190 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/database/slice.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/reducers/database/slice.ts @@ -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; } - }, + },*/ }, }); diff --git a/frontend/appflowy_tauri/src/appflowy_app/views/BoardPage.tsx b/frontend/appflowy_tauri/src/appflowy_app/views/BoardPage.tsx index 0e2cc8cc19..d533850710 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/views/BoardPage.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/views/BoardPage.tsx @@ -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 (
-

Board

- {databaseId?.length && } +

Board: {viewId}

+ {viewId?.length && }
); };