diff --git a/frontend/appflowy_web_app/src/application/collab.type.ts b/frontend/appflowy_web_app/src/application/collab.type.ts index 7e8491bac5..affc19e921 100644 --- a/frontend/appflowy_web_app/src/application/collab.type.ts +++ b/frontend/appflowy_web_app/src/application/collab.type.ts @@ -27,6 +27,8 @@ export enum BlockType { DividerBlock = 'divider', ImageBlock = 'image', GridBlock = 'grid', + BoardBlock = 'board', + CalendarBlock = 'calendar', OutlineBlock = 'outline', TableBlock = 'table', TableCell = 'table/cell', @@ -111,6 +113,10 @@ export interface TableCellBlockData extends BlockData { width: number; } +export interface DatabaseNodeData extends BlockData { + view_id: ViewId; +} + export enum MentionType { PageRef = 'page', Date = 'date', diff --git a/frontend/appflowy_web_app/src/application/database-yjs/index.ts b/frontend/appflowy_web_app/src/application/database-yjs/index.ts index 708ae080d2..1d5aa0ce3d 100644 --- a/frontend/appflowy_web_app/src/application/database-yjs/index.ts +++ b/frontend/appflowy_web_app/src/application/database-yjs/index.ts @@ -4,5 +4,3 @@ export * from './context'; export * from './selector'; export * from './database.type'; export * from './const'; -export * from './filter'; -export * from './sort'; diff --git a/frontend/appflowy_web_app/src/application/database-yjs/selector.ts b/frontend/appflowy_web_app/src/application/database-yjs/selector.ts index ebd91ae726..d42399d882 100644 --- a/frontend/appflowy_web_app/src/application/database-yjs/selector.ts +++ b/frontend/appflowy_web_app/src/application/database-yjs/selector.ts @@ -101,7 +101,7 @@ export function useFieldsSelector(visibilitys: FieldVisibility[] = defaultVisibl visibility: Number( setting?.get(YjsDatabaseKey.visibility) || FieldVisibility.AlwaysShown ) as FieldVisibility, - wrap: setting?.get(YjsDatabaseKey.wrap), + wrap: setting?.get(YjsDatabaseKey.wrap) ?? true, }; }) .filter((column) => { diff --git a/frontend/appflowy_web_app/src/application/services/js-services/storage/collab.ts b/frontend/appflowy_web_app/src/application/services/js-services/storage/collab.ts index 27ce771d74..bdc1392024 100644 --- a/frontend/appflowy_web_app/src/application/services/js-services/storage/collab.ts +++ b/frontend/appflowy_web_app/src/application/services/js-services/storage/collab.ts @@ -1,7 +1,7 @@ import { CollabType, YDoc, YjsEditorKey } from '@/application/collab.type'; import { getDBName, openCollabDB } from '@/application/services/js-services/db'; import { APIService } from '@/application/services/js-services/wasm'; -import { applyDocument } from '@/application/ydoc/apply'; +import { applyYDoc } from '@/application/ydoc/apply'; export function fetchCollab(workspaceId: string, id: string, type: CollabType) { return APIService.getCollab(workspaceId, id, type); @@ -47,7 +47,7 @@ export async function getCollabStorageWithAPICall(workspaceId: string, id: strin const asyncApply = async () => { const res = await fetchCollab(workspaceId, id, type); - applyDocument(doc, res.state); + applyYDoc(doc, res.state); }; // If the document exists locally, apply the state asynchronously, @@ -95,7 +95,7 @@ export async function batchCollabs( const { doc } = await getCollabStorage(id, type); - applyDocument(doc, data); + applyYDoc(doc, data); } })(); } diff --git a/frontend/appflowy_web_app/src/application/ydoc/apply/__tests__/document.test.ts b/frontend/appflowy_web_app/src/application/ydoc/apply/__tests__/document.test.ts index 512c28ae6a..8a332f4b60 100644 --- a/frontend/appflowy_web_app/src/application/ydoc/apply/__tests__/document.test.ts +++ b/frontend/appflowy_web_app/src/application/ydoc/apply/__tests__/document.test.ts @@ -1,5 +1,5 @@ import { YjsEditorKey } from '@/application/collab.type'; -import { applyDocument } from '@/application/ydoc/apply'; +import { applyYDoc } from '@/application/ydoc/apply'; import * as Y from 'yjs'; import * as docJson from '../../../../../cypress/fixtures/simple_doc.json'; @@ -11,7 +11,7 @@ describe('apply document', () => { data.set(YjsEditorKey.document, document); const state = new Uint8Array(docJson.data.doc_state); - applyDocument(collab, state); + applyYDoc(collab, state); }); }); diff --git a/frontend/appflowy_web_app/src/application/ydoc/apply/document.ts b/frontend/appflowy_web_app/src/application/ydoc/apply/document.ts deleted file mode 100644 index 60d02d0450..0000000000 --- a/frontend/appflowy_web_app/src/application/ydoc/apply/document.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { CollabOrigin } from '@/application/collab.type'; -import * as Y from 'yjs'; - -/** - * Apply doc state from server to client - * Note: origin is always remote - * @param doc local Y.Doc - * @param state state from server - */ -export function applyDocument(doc: Y.Doc, state: Uint8Array) { - Y.transact( - doc, - () => { - Y.applyUpdate(doc, state); - }, - CollabOrigin.Remote - ); -} diff --git a/frontend/appflowy_web_app/src/application/ydoc/apply/index.ts b/frontend/appflowy_web_app/src/application/ydoc/apply/index.ts index 8147823035..b19cb43328 100644 --- a/frontend/appflowy_web_app/src/application/ydoc/apply/index.ts +++ b/frontend/appflowy_web_app/src/application/ydoc/apply/index.ts @@ -1 +1,18 @@ -export * from 'src/application/ydoc/apply/document'; +import { CollabOrigin } from '@/application/collab.type'; +import * as Y from 'yjs'; + +/** + * Apply doc state from server to client + * Note: origin is always remote + * @param doc local Y.Doc + * @param state state from server + */ +export function applyYDoc(doc: Y.Doc, state: Uint8Array) { + Y.transact( + doc, + () => { + Y.applyUpdate(doc, state); + }, + CollabOrigin.Remote + ); +} diff --git a/frontend/appflowy_web_app/src/components/_shared/context-provider/IdProvider.tsx b/frontend/appflowy_web_app/src/components/_shared/context-provider/IdProvider.tsx index 789642420d..15682f1c82 100644 --- a/frontend/appflowy_web_app/src/components/_shared/context-provider/IdProvider.tsx +++ b/frontend/appflowy_web_app/src/components/_shared/context-provider/IdProvider.tsx @@ -1,4 +1,3 @@ -import { CollabType } from '@/application/collab.type'; import { useContext, createContext } from 'react'; export const IdContext = createContext(null); @@ -6,7 +5,6 @@ export const IdContext = createContext(null); interface IdProviderProps { workspaceId: string; objectId: string; - collabType: CollabType; } export const IdProvider = ({ children, ...props }: IdProviderProps & { children: React.ReactNode }) => { diff --git a/frontend/appflowy_web_app/src/components/_shared/popover/RichTooltip.tsx b/frontend/appflowy_web_app/src/components/_shared/popover/RichTooltip.tsx index 06e6f3c51b..437b08eaf5 100644 --- a/frontend/appflowy_web_app/src/components/_shared/popover/RichTooltip.tsx +++ b/frontend/appflowy_web_app/src/components/_shared/popover/RichTooltip.tsx @@ -26,7 +26,7 @@ export const RichTooltip = ({ placement = 'top', open, onClose, content, childre anchorEl={childNode} placement={placement} transition - style={{ zIndex: 2000 }} + style={{ zIndex: 1200 }} modifiers={[ { name: 'flip', diff --git a/frontend/appflowy_web_app/src/components/database/Database.tsx b/frontend/appflowy_web_app/src/components/database/Database.tsx index 9e8399d315..fe35a99cc6 100644 --- a/frontend/appflowy_web_app/src/components/database/Database.tsx +++ b/frontend/appflowy_web_app/src/components/database/Database.tsx @@ -2,7 +2,6 @@ import { YDoc, YjsEditorKey } from '@/application/collab.type'; import { useId } from '@/components/_shared/context-provider/IdProvider'; import RecordNotFound from '@/components/_shared/not-found/RecordNotFound'; import { AFConfigContext } from '@/components/app/AppConfig'; -import { DatabaseHeader } from '@/components/database/components/header'; import DatabaseViews from '@/components/database/DatabaseViews'; import { DatabaseContextProvider } from '@/components/database/DatabaseContext'; import { Log } from '@/utils/log'; @@ -71,19 +70,16 @@ export const Database = memo(() => { } return ( -
- -
- - - -
+
+ + +
); }); diff --git a/frontend/appflowy_web_app/src/components/database/calendar/Calendar.tsx b/frontend/appflowy_web_app/src/components/database/calendar/Calendar.tsx index 800687fce2..046d558254 100644 --- a/frontend/appflowy_web_app/src/components/database/calendar/Calendar.tsx +++ b/frontend/appflowy_web_app/src/components/database/calendar/Calendar.tsx @@ -8,7 +8,7 @@ export function Calendar() { const { dayPropGetter, localizer, formats, events, emptyEvents } = useCalendarSetup(); return ( -
+
, diff --git a/frontend/appflowy_web_app/src/components/database/calendar/calendar.scss b/frontend/appflowy_web_app/src/components/database/calendar/calendar.scss index 0b3f29658a..4d2877154a 100644 --- a/frontend/appflowy_web_app/src/components/database/calendar/calendar.scss +++ b/frontend/appflowy_web_app/src/components/database/calendar/calendar.scss @@ -10,8 +10,9 @@ $today-highlight-bg: transparent; @apply rounded-full w-[20px] h-[20px] my-1.5; } -.rbc-date-cell { - min-width: 100px; + +.rbc-date-cell, .rbc-header { + min-width: 120px; max-width: 180px; } @@ -31,6 +32,7 @@ $today-highlight-bg: transparent; .rbc-month-row { border: 1px solid var(--line-divider); border-top: none; + } &::-webkit-scrollbar { @@ -57,11 +59,12 @@ $today-highlight-bg: transparent; top: 0; background: var(--bg-body); z-index: 50; - @apply border-b border-line-divider; .rbc-header { border: none; - @apply flex items-end py-2 justify-center font-normal text-text-caption; + border-bottom: 1px solid var(--line-divider); + @apply flex items-end py-2 justify-center font-normal text-text-caption bg-bg-body; + } } diff --git a/frontend/appflowy_web_app/src/components/database/components/calendar/event/EventPaper.tsx b/frontend/appflowy_web_app/src/components/database/components/calendar/event/EventPaper.tsx index 993c87c6ae..3bc31dd942 100644 --- a/frontend/appflowy_web_app/src/components/database/components/calendar/event/EventPaper.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/calendar/event/EventPaper.tsx @@ -1,25 +1,30 @@ import { useFieldsSelector, useNavigateToRow } from '@/application/database-yjs'; import { Property } from '@/components/database/components/property'; -import { IconButton } from '@mui/material'; +import { Tooltip } from '@mui/material'; import React from 'react'; import { ReactComponent as ExpandMoreIcon } from '$icons/16x/full_view.svg'; +import { useTranslation } from 'react-i18next'; function EventPaper({ rowId }: { rowId: string }) { const fields = useFieldsSelector(); const navigateToRow = useNavigateToRow(); + const { t } = useTranslation(); return (
- { - navigateToRow?.(rowId); - }} - size={'small'} - > - - + + +
{fields.map((field) => { diff --git a/frontend/appflowy_web_app/src/components/database/components/cell/primary/PrimaryCell.tsx b/frontend/appflowy_web_app/src/components/database/components/cell/primary/PrimaryCell.tsx index f29773a8ea..b9014f02f7 100644 --- a/frontend/appflowy_web_app/src/components/database/components/cell/primary/PrimaryCell.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/cell/primary/PrimaryCell.tsx @@ -3,26 +3,45 @@ import { useNavigateToRow, useRowMetaSelector } from '@/application/database-yjs import { TextCell as CellType, CellProps } from '@/components/database/components/cell/cell.type'; import { TextCell } from '@/components/database/components/cell/text'; import { Tooltip } from '@mui/material'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; export function PrimaryCell(props: CellProps) { const navigateToRow = useNavigateToRow(); const { rowId } = props; - // const icon = null; const icon = useRowMetaSelector(rowId)?.icon; const [hover, setHover] = useState(false); const { t } = useTranslation(); + useEffect(() => { + const table = document.querySelector('.grid-table'); + + if (!table) { + return; + } + + const onMouseMove = (e: Event) => { + const target = e.target as HTMLElement; + + if (target.closest('.grid-row-cell')?.getAttribute('data-row-id') === rowId) { + setHover(true); + } else { + setHover(false); + } + }; + + table.addEventListener('mousemove', onMouseMove); + return () => { + table.removeEventListener('mousemove', onMouseMove); + }; + }, [rowId]); return ( -
setHover(true)} - onMouseLeave={() => setHover(false)} - className={'primary-cell relative flex w-full items-center gap-2'} - > +
{icon &&
{icon}
} - +
+ +
{hover && ( diff --git a/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationItems.tsx b/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationItems.tsx index e2008c7552..6d68eee4af 100644 --- a/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationItems.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/cell/relation/RelationItems.tsx @@ -35,12 +35,12 @@ function RelationItems({ style, cell, fieldId }: { cell: RelationCell; fieldId: }, [workspaceId, databaseId, databaseService, rowIds]); return ( -
+
{rowIds.map((rowId) => { const rowDoc = rows?.get(rowId); return ( -
+
{rowDoc && databasePrimaryFieldId && ( )} diff --git a/frontend/appflowy_web_app/src/components/database/components/cell/select-option/SelectOptionCell.tsx b/frontend/appflowy_web_app/src/components/database/components/cell/select-option/SelectOptionCell.tsx index 37a98659d1..4d3318297f 100644 --- a/frontend/appflowy_web_app/src/components/database/components/cell/select-option/SelectOptionCell.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/cell/select-option/SelectOptionCell.tsx @@ -31,7 +31,10 @@ export function SelectOptionCell({ cell, fieldId, style, placeholder }: CellProp ) : null; return ( -
+
{renderSelectedOptions(selectOptionIds)}
); diff --git a/frontend/appflowy_web_app/src/components/database/components/cell/text/TextCell.tsx b/frontend/appflowy_web_app/src/components/database/components/cell/text/TextCell.tsx index e27f1e835f..4d882b8c28 100644 --- a/frontend/appflowy_web_app/src/components/database/components/cell/text/TextCell.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/cell/text/TextCell.tsx @@ -7,7 +7,7 @@ export function TextCell({ cell, style }: CellProps) { if (!cell?.data) return null; return ( -
+
{cell?.data}
); diff --git a/frontend/appflowy_web_app/src/components/database/components/grid/grid-table/GridTable.tsx b/frontend/appflowy_web_app/src/components/database/components/grid/grid-table/GridTable.tsx index b855c8b4cb..ee39bfb957 100644 --- a/frontend/appflowy_web_app/src/components/database/components/grid/grid-table/GridTable.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/grid/grid-table/GridTable.tsx @@ -94,10 +94,10 @@ export const GridTable = ({ scrollLeft, columnWidth, columns, onScrollLeft }: Gr const row = data.rows[rowIndex]; const column = data.columns[columnIndex] as RenderColumn; - const classList = ['flex', 'items-center', 'overflow-hidden']; + const classList = ['flex', 'items-center', 'overflow-hidden', 'grid-row-cell']; if (column.wrap) { - classList.push('whitespace-pre-wrap', 'break-words'); + classList.push('wrap-cell'); } else { classList.push('whitespace-nowrap'); } @@ -113,6 +113,7 @@ export const GridTable = ({ scrollLeft, columnWidth, columns, onScrollLeft }: Gr if (row.type === RenderRowType.Row) { return (
@@ -153,6 +154,7 @@ export const GridTable = ({ scrollLeft, columnWidth, columns, onScrollLeft }: Gr columnCount={columns.length} columnWidth={(index) => columnWidth(index, width)} rowHeight={rowHeight} + className={'grid-table'} overscanRowCount={5} overscanColumnCount={5} style={{ diff --git a/frontend/appflowy_web_app/src/components/database/components/tabs/DatabaseTabs.tsx b/frontend/appflowy_web_app/src/components/database/components/tabs/DatabaseTabs.tsx index c79545da38..8e33c7eaba 100644 --- a/frontend/appflowy_web_app/src/components/database/components/tabs/DatabaseTabs.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/tabs/DatabaseTabs.tsx @@ -83,7 +83,7 @@ export const DatabaseTabs = forwardRef( icon={} iconPosition='start' color='inherit' - label={name || t('grid.title.placeholder')} + label={{name || t('grid.title.placeholder')}} value={viewId} /> ); diff --git a/frontend/appflowy_web_app/src/components/database/index.ts b/frontend/appflowy_web_app/src/components/database/index.ts index 7cef3e91fb..8ef9c34dc1 100644 --- a/frontend/appflowy_web_app/src/components/database/index.ts +++ b/frontend/appflowy_web_app/src/components/database/index.ts @@ -1,4 +1,3 @@ import { lazy } from 'react'; export const Database = lazy(() => import('./Database')); -export const DatabaseRow = lazy(() => import('./DatabaseRow')); diff --git a/frontend/appflowy_web_app/src/components/document/Document.tsx b/frontend/appflowy_web_app/src/components/document/Document.tsx index c8578fa2a6..219b76e7e5 100644 --- a/frontend/appflowy_web_app/src/components/document/Document.tsx +++ b/frontend/appflowy_web_app/src/components/document/Document.tsx @@ -51,3 +51,5 @@ export const Document = () => { ); }; + +export default Document; diff --git a/frontend/appflowy_web_app/src/components/editor/Editor.cy.tsx b/frontend/appflowy_web_app/src/components/editor/Editor.cy.tsx index 12c2feb435..766e1e6d29 100644 --- a/frontend/appflowy_web_app/src/components/editor/Editor.cy.tsx +++ b/frontend/appflowy_web_app/src/components/editor/Editor.cy.tsx @@ -1,6 +1,6 @@ import { YDoc } from '@/application/collab.type'; import { DocumentTest } from '@/../cypress/support/document'; -import { applyDocument } from '@/application/ydoc/apply'; +import { applyYDoc } from '@/application/ydoc/apply'; import React from 'react'; import * as Y from 'yjs'; import { Editor } from './Editor'; @@ -20,7 +20,7 @@ describe('', () => { const doc = new Y.Doc(); const state = new Uint8Array(docJson.data.doc_state); - applyDocument(doc, state); + applyYDoc(doc, state); renderEditor(doc); }); }); diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted_list/BulletedList.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted-list/BulletedList.tsx similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted_list/BulletedList.tsx rename to frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted-list/BulletedList.tsx diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted_list/BulletedListIcon.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted-list/BulletedListIcon.tsx similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted_list/BulletedListIcon.tsx rename to frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted-list/BulletedListIcon.tsx diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted_list/index.ts b/frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted-list/index.ts similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted_list/index.ts rename to frontend/appflowy_web_app/src/components/editor/components/blocks/bulleted-list/index.ts diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/BoardBlock.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/BoardBlock.tsx new file mode 100644 index 0000000000..88e3790551 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/BoardBlock.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +function BoardBlock() { + return
; +} + +export default BoardBlock; diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/CalendarBlock.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/CalendarBlock.tsx new file mode 100644 index 0000000000..19c2b32bf0 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/CalendarBlock.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +function CalendarBlock() { + return
; +} + +export default CalendarBlock; diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/DatabaseBlock.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/DatabaseBlock.tsx new file mode 100644 index 0000000000..b9bc174969 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/DatabaseBlock.tsx @@ -0,0 +1,60 @@ +import { IdProvider, useId } from '@/components/_shared/context-provider/IdProvider'; +import { Database } from '@/components/database'; +import { DatabaseNode, EditorElementProps } from '@/components/editor/editor.type'; +import React, { forwardRef, memo, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; +import { BlockType } from '@/application/collab.type'; + +export const DatabaseBlock = memo( + forwardRef>(({ node, children, ...attributes }, ref) => { + const { t } = useTranslation(); + const viewId = node.data.view_id; + const workspaceId = useId()?.workspaceId; + const type = node.type; + + const style = useMemo(() => { + const style = {}; + + switch (type) { + case BlockType.GridBlock: + Object.assign(style, { + height: 360, + }); + break; + case BlockType.CalendarBlock: + case BlockType.BoardBlock: + Object.assign(style, { + height: 560, + }); + } + + return style; + }, [type]); + + return ( + <> +
+
+ {children} +
+
+ {viewId ? ( + + + + ) : ( +
+
{t('document.plugins.database.noDataSource')}
+
{t('grid.relation.noDatabaseSelected')}
+
+ )} +
+
+ + ); + }) +); + +export default DatabaseBlock; diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/GridBlock.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/GridBlock.tsx new file mode 100644 index 0000000000..eaf2742ceb --- /dev/null +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/GridBlock.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +function GridBlock() { + return
; +} + +export default GridBlock; diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/database/index.ts b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/index.ts new file mode 100644 index 0000000000..8eaf478025 --- /dev/null +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/database/index.ts @@ -0,0 +1 @@ +export * from './DatabaseBlock'; diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/math_equation/MathEquation.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/MathEquation.tsx similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/math_equation/MathEquation.tsx rename to frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/MathEquation.tsx diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/math_equation/index.ts b/frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/index.ts similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/math_equation/index.ts rename to frontend/appflowy_web_app/src/components/editor/components/blocks/math-equation/index.ts diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/numbered_list/NumberListIcon.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/numbered-list/NumberListIcon.tsx similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/numbered_list/NumberListIcon.tsx rename to frontend/appflowy_web_app/src/components/editor/components/blocks/numbered-list/NumberListIcon.tsx diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/numbered_list/NumberedList.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/numbered-list/NumberedList.tsx similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/numbered_list/NumberedList.tsx rename to frontend/appflowy_web_app/src/components/editor/components/blocks/numbered-list/NumberedList.tsx diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/numbered_list/index.ts b/frontend/appflowy_web_app/src/components/editor/components/blocks/numbered-list/index.ts similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/numbered_list/index.ts rename to frontend/appflowy_web_app/src/components/editor/components/blocks/numbered-list/index.ts diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/text/StartIcon.hooks.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/text/StartIcon.hooks.tsx index 119c6fe9fe..2ab5996b09 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/text/StartIcon.hooks.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/text/StartIcon.hooks.tsx @@ -1,12 +1,12 @@ import { BlockType } from '@/application/collab.type'; -import { BulletedListIcon } from '@/components/editor/components/blocks/bulleted_list'; -import { NumberListIcon } from '@/components/editor/components/blocks/numbered_list'; -import ToggleIcon from '@/components/editor/components/blocks/toggle_list/ToggleIcon'; +import { BulletedListIcon } from '@/components/editor/components/blocks/bulleted-list'; +import { NumberListIcon } from '@/components/editor/components/blocks/numbered-list'; +import ToggleIcon from '@/components/editor/components/blocks/toggle-list/ToggleIcon'; import { TextNode } from '@/components/editor/editor.type'; import React, { FC, useCallback, useMemo } from 'react'; import { ReactEditor, useSlate } from 'slate-react'; import { Editor, Element } from 'slate'; -import CheckboxIcon from '../todo_list/CheckboxIcon'; +import CheckboxIcon from '@/components/editor/components/blocks/todo-list/CheckboxIcon'; export function useStartIcon(node: TextNode) { const editor = useSlate(); @@ -37,7 +37,7 @@ export function useStartIcon(node: TextNode) { return null; } - return ; + return ; }, [Component, block]); return { diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/todo_list/CheckboxIcon.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/todo-list/CheckboxIcon.tsx similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/todo_list/CheckboxIcon.tsx rename to frontend/appflowy_web_app/src/components/editor/components/blocks/todo-list/CheckboxIcon.tsx diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/todo_list/TodoList.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/todo-list/TodoList.tsx similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/todo_list/TodoList.tsx rename to frontend/appflowy_web_app/src/components/editor/components/blocks/todo-list/TodoList.tsx diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/todo_list/index.ts b/frontend/appflowy_web_app/src/components/editor/components/blocks/todo-list/index.ts similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/todo_list/index.ts rename to frontend/appflowy_web_app/src/components/editor/components/blocks/todo-list/index.ts diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/toggle_list/ToggleIcon.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/toggle-list/ToggleIcon.tsx similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/toggle_list/ToggleIcon.tsx rename to frontend/appflowy_web_app/src/components/editor/components/blocks/toggle-list/ToggleIcon.tsx diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/toggle_list/ToggleList.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/toggle-list/ToggleList.tsx similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/toggle_list/ToggleList.tsx rename to frontend/appflowy_web_app/src/components/editor/components/blocks/toggle-list/ToggleList.tsx diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/toggle_list/index.ts b/frontend/appflowy_web_app/src/components/editor/components/blocks/toggle-list/index.ts similarity index 100% rename from frontend/appflowy_web_app/src/components/editor/components/blocks/toggle_list/index.ts rename to frontend/appflowy_web_app/src/components/editor/components/blocks/toggle-list/index.ts diff --git a/frontend/appflowy_web_app/src/components/editor/components/element/Element.tsx b/frontend/appflowy_web_app/src/components/editor/components/element/Element.tsx index f535bde10c..46a784dd37 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/element/Element.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/element/Element.tsx @@ -1,20 +1,20 @@ import { BlockData, BlockType, InlineBlockType, YjsEditorKey } from '@/application/collab.type'; -import { BulletedList } from '@/components/editor/components/blocks/bulleted_list'; +import { BulletedList } from '@/components/editor/components/blocks/bulleted-list'; import { Callout } from '@/components/editor/components/blocks/callout'; import { CodeBlock } from '@/components/editor/components/blocks/code'; import { DividerNode } from '@/components/editor/components/blocks/divider'; import { Heading } from '@/components/editor/components/blocks/heading'; import { ImageBlock } from '@/components/editor/components/blocks/image'; -import { MathEquation } from '@/components/editor/components/blocks/math_equation'; -import { NumberedList } from '@/components/editor/components/blocks/numbered_list'; +import { MathEquation } from '@/components/editor/components/blocks/math-equation'; +import { NumberedList } from '@/components/editor/components/blocks/numbered-list'; import { Outline } from '@/components/editor/components/blocks/outline'; import { Page } from '@/components/editor/components/blocks/page'; import { Paragraph } from '@/components/editor/components/blocks/paragraph'; import { Quote } from '@/components/editor/components/blocks/quote'; import { TableBlock, TableCellBlock } from '@/components/editor/components/blocks/table'; import { Text } from '@/components/editor/components/blocks/text'; -import { TodoList } from '@/components/editor/components/blocks/todo_list'; -import { ToggleList } from '@/components/editor/components/blocks/toggle_list'; +import { TodoList } from 'src/components/editor/components/blocks/todo-list'; +import { ToggleList } from 'src/components/editor/components/blocks/toggle-list'; import { UnSupportedBlock } from '@/components/editor/components/element/UnSupportedBlock'; import { Formula } from '@/components/editor/components/leaf/formula'; import { Mention } from '@/components/editor/components/leaf/mention'; @@ -22,6 +22,7 @@ import { EditorElementProps, TextNode } from '@/components/editor/editor.type'; import { renderColor } from '@/utils/color'; import React, { FC, useMemo } from 'react'; import { RenderElementProps } from 'slate-react'; +import { DatabaseBlock } from 'src/components/editor/components/blocks/database'; export const Element = ({ element: node, @@ -64,6 +65,10 @@ export const Element = ({ return TableBlock; case BlockType.TableCell: return TableCellBlock; + case BlockType.GridBlock: + case BlockType.BoardBlock: + case BlockType.CalendarBlock: + return DatabaseBlock; default: return UnSupportedBlock; } diff --git a/frontend/appflowy_web_app/src/components/editor/components/leaf/Leaf.tsx b/frontend/appflowy_web_app/src/components/editor/components/leaf/Leaf.tsx index 714b41db97..38ba65e3f2 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/leaf/Leaf.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/leaf/Leaf.tsx @@ -10,9 +10,7 @@ export function Leaf({ attributes, children, leaf }: RenderLeafProps) { const classList = [leaf.prism_token, leaf.prism_token && 'token', leaf.class_name].filter(Boolean); if (leaf.code) { - newChildren = ( - {newChildren} - ); + newChildren = {newChildren}; } if (leaf.underline) { diff --git a/frontend/appflowy_web_app/src/components/editor/editor.type.ts b/frontend/appflowy_web_app/src/components/editor/editor.type.ts index fec9ffbcbf..d21f75cd3a 100644 --- a/frontend/appflowy_web_app/src/components/editor/editor.type.ts +++ b/frontend/appflowy_web_app/src/components/editor/editor.type.ts @@ -16,6 +16,7 @@ import { TableCellBlockData, BlockId, BlockData, + DatabaseNodeData, } from '@/application/collab.type'; import { HTMLAttributes } from 'react'; import { Element } from 'slate'; @@ -120,6 +121,12 @@ export interface TableCellNode extends BlockNode { data: TableCellBlockData; } +export interface DatabaseNode extends BlockNode { + type: BlockType.GridBlock | BlockType.BoardBlock | BlockType.CalendarBlock; + blockId: string; + data: DatabaseNodeData; +} + export interface EditorElementProps extends HTMLAttributes { node: T; } diff --git a/frontend/appflowy_web_app/src/components/layout/layout.scss b/frontend/appflowy_web_app/src/components/layout/layout.scss index 53b1c59eaa..2aa965dd15 100644 --- a/frontend/appflowy_web_app/src/components/layout/layout.scss +++ b/frontend/appflowy_web_app/src/components/layout/layout.scss @@ -91,8 +91,22 @@ display: block; width: 100%; height: 100%; - boxShadow: var(--shadow); - backgroundColor: var(--bg-body); + box-shadow: var(--shadow); + background-color: var(--bg-body); transform: rotate(45deg); } } + +.grid-row-cell.wrap-cell { + .text-cell { + @apply py-2 break-words whitespace-pre-wrap; + } + + .relation-cell { + @apply py-2 break-words whitespace-pre-wrap flex-wrap; + } + + .select-option-cell { + @apply flex-wrap py-2; + } +} diff --git a/frontend/appflowy_web_app/src/pages/DatabasePage.tsx b/frontend/appflowy_web_app/src/pages/DatabasePage.tsx index 58ddfbdd32..f5b4839924 100644 --- a/frontend/appflowy_web_app/src/pages/DatabasePage.tsx +++ b/frontend/appflowy_web_app/src/pages/DatabasePage.tsx @@ -1,8 +1,12 @@ -import { Database, DatabaseRow } from '@/components/database'; +import { useId } from '@/components/_shared/context-provider/IdProvider'; +import { DatabaseHeader } from '@/components/database/components/header'; import React from 'react'; import { useSearchParams } from 'react-router-dom'; +import DatabaseRow from '@/components/database/DatabaseRow'; +import Database from '@/components/database/Database'; function DatabasePage() { + const objectId = useId()?.objectId; const [search] = useSearchParams(); const rowId = search.get('r'); @@ -10,7 +14,12 @@ function DatabasePage() { return ; } - return ; + return ( +
+ + +
+ ); } export default DatabasePage; diff --git a/frontend/appflowy_web_app/src/pages/ProductPage.tsx b/frontend/appflowy_web_app/src/pages/ProductPage.tsx index f7b5615a77..0cd4d16cac 100644 --- a/frontend/appflowy_web_app/src/pages/ProductPage.tsx +++ b/frontend/appflowy_web_app/src/pages/ProductPage.tsx @@ -1,10 +1,10 @@ -import { CollabType } from '@/application/collab.type'; import { IdProvider } from '@/components/_shared/context-provider/IdProvider'; -import DatabasePage from '@/pages/DatabasePage'; -import React, { useMemo } from 'react'; +import React, { lazy, useMemo } from 'react'; import { useParams } from 'react-router-dom'; import DocumentPage from '@/pages/DocumentPage'; +const DatabasePage = lazy(() => import('./DatabasePage')); + enum URL_COLLAB_TYPE { DOCUMENT = 'document', GRID = 'grid', @@ -12,13 +12,6 @@ enum URL_COLLAB_TYPE { CALENDAR = 'calendar', } -const collabTypeMap: Record = { - [URL_COLLAB_TYPE.DOCUMENT]: CollabType.Document, - [URL_COLLAB_TYPE.GRID]: CollabType.WorkspaceDatabase, - [URL_COLLAB_TYPE.BOARD]: CollabType.WorkspaceDatabase, - [URL_COLLAB_TYPE.CALENDAR]: CollabType.WorkspaceDatabase, -}; - function ProductPage() { const { workspaceId, type, objectId } = useParams(); const PageComponent = useMemo(() => { @@ -38,7 +31,7 @@ function ProductPage() { if (!workspaceId || !type || !objectId) return null; return ( - + {PageComponent && } ); diff --git a/frontend/appflowy_web_app/vite.config.ts b/frontend/appflowy_web_app/vite.config.ts index e5b8d1cba6..87a5e284bf 100644 --- a/frontend/appflowy_web_app/vite.config.ts +++ b/frontend/appflowy_web_app/vite.config.ts @@ -72,7 +72,7 @@ export default defineConfig({ }, envPrefix: ['AF', 'TAURI_'], esbuild: { - drop: ['console', 'debugger'], + drop: isDev ? [] : ['console', 'debugger'], }, build: !!process.env.TAURI_PLATFORM ? {