From 2babdf1deb2ae0cbe48907bd3bb6b7513dfc014d Mon Sep 17 00:00:00 2001 From: "Kilu.He" <108015703+qinluhe@users.noreply.github.com> Date: Tue, 23 Sep 2025 16:23:31 +0800 Subject: [PATCH] chore: fix web repo issues (#82) * chore: fix the row height incorrect on firefox * chore: add back button to row modal * chore: remove sticky header on open view --- src/application/database-yjs/context.ts | 1 + .../_shared/view-icon/SpaceIcon.tsx | 92 ++++++++++++------- src/components/app/DatabaseView.tsx | 6 +- src/components/app/MainLayout.tsx | 27 +++--- src/components/app/ViewModal.tsx | 7 +- src/components/app/app.hooks.tsx | 1 + .../app/view-actions/SpaceIconButton.tsx | 27 +++--- .../view-actions/SpacePermissionButton.tsx | 7 +- src/components/database/Database.tsx | 6 +- src/components/database/DatabaseRowModal.tsx | 26 +++++- .../grid/grid-column/GridVirtualColumn.tsx | 2 - 11 files changed, 130 insertions(+), 72 deletions(-) diff --git a/src/application/database-yjs/context.ts b/src/application/database-yjs/context.ts index 51710afd..e9acf711 100644 --- a/src/application/database-yjs/context.ts +++ b/src/application/database-yjs/context.ts @@ -70,6 +70,7 @@ export interface DatabaseContextState { // Calendar view type map: viewId -> CalendarViewType calendarViewTypeMap?: Map; setCalendarViewType?: (viewId: string, viewType: CalendarViewType) => void; + openPageModalViewId?: string; } export const DatabaseContext = createContext(null); diff --git a/src/components/_shared/view-icon/SpaceIcon.tsx b/src/components/_shared/view-icon/SpaceIcon.tsx index 2c679193..d19e3042 100644 --- a/src/components/_shared/view-icon/SpaceIcon.tsx +++ b/src/components/_shared/view-icon/SpaceIcon.tsx @@ -1,8 +1,13 @@ -import { ThemeModeContext } from '@/components/main/useAppThemeMode'; -import { renderColor } from '@/utils/color'; -import { getIcon } from '@/utils/emoji'; +import DOMPurify from 'dompurify'; import { useContext, useEffect, useMemo, useState } from 'react'; + import { ReactComponent as SpaceIcon1 } from '@/assets/space_icon/space_icon_1.svg'; +import { ReactComponent as SpaceIcon10 } from '@/assets/space_icon/space_icon_10.svg'; +import { ReactComponent as SpaceIcon11 } from '@/assets/space_icon/space_icon_11.svg'; +import { ReactComponent as SpaceIcon12 } from '@/assets/space_icon/space_icon_12.svg'; +import { ReactComponent as SpaceIcon13 } from '@/assets/space_icon/space_icon_13.svg'; +import { ReactComponent as SpaceIcon14 } from '@/assets/space_icon/space_icon_14.svg'; +import { ReactComponent as SpaceIcon15 } from '@/assets/space_icon/space_icon_15.svg'; import { ReactComponent as SpaceIcon2 } from '@/assets/space_icon/space_icon_2.svg'; import { ReactComponent as SpaceIcon3 } from '@/assets/space_icon/space_icon_3.svg'; import { ReactComponent as SpaceIcon4 } from '@/assets/space_icon/space_icon_4.svg'; @@ -11,13 +16,9 @@ import { ReactComponent as SpaceIcon6 } from '@/assets/space_icon/space_icon_6.s import { ReactComponent as SpaceIcon7 } from '@/assets/space_icon/space_icon_7.svg'; import { ReactComponent as SpaceIcon8 } from '@/assets/space_icon/space_icon_8.svg'; import { ReactComponent as SpaceIcon9 } from '@/assets/space_icon/space_icon_9.svg'; -import { ReactComponent as SpaceIcon10 } from '@/assets/space_icon/space_icon_10.svg'; -import { ReactComponent as SpaceIcon11 } from '@/assets/space_icon/space_icon_11.svg'; -import { ReactComponent as SpaceIcon12 } from '@/assets/space_icon/space_icon_12.svg'; -import { ReactComponent as SpaceIcon13 } from '@/assets/space_icon/space_icon_13.svg'; -import { ReactComponent as SpaceIcon14 } from '@/assets/space_icon/space_icon_14.svg'; -import { ReactComponent as SpaceIcon15 } from '@/assets/space_icon/space_icon_15.svg'; -import DOMPurify from 'dompurify'; +import { ThemeModeContext } from '@/components/main/useAppThemeMode'; +import { renderColor } from '@/utils/color'; +import { getIcon } from '@/utils/emoji'; export const getIconComponent = (icon: string) => { switch (icon) { @@ -58,11 +59,16 @@ export const getIconComponent = (icon: string) => { } }; -function SpaceIcon({ value, char, bgColor, className: classNameProp }: { - value: string, - char?: string, - bgColor?: string, - className?: string +function SpaceIcon({ + value, + char, + bgColor, + className: classNameProp, +}: { + value: string; + char?: string; + bgColor?: string; + className?: string; }) { const IconComponent = getIconComponent(value); const isDark = useContext(ThemeModeContext)?.isDark || false; @@ -70,7 +76,7 @@ function SpaceIcon({ value, char, bgColor, className: classNameProp }: { useEffect(() => { if (value) { - void getIcon(value).then(icon => { + void getIcon(value).then((icon) => { setCustomIconContent(icon?.content || ''); }); } @@ -78,22 +84,31 @@ function SpaceIcon({ value, char, bgColor, className: classNameProp }: { const customIcon = useMemo(() => { if (customIconContent) { - const cleanSvg = DOMPurify.sanitize(customIconContent.replaceAll('black', isDark ? 'black' : 'white').replace('; + return ( + + + + ); } }, [customIconContent, isDark]); const content = useMemo(() => { if (char) { return ( - - {char} - + {char} ); } @@ -101,11 +116,18 @@ function SpaceIcon({ value, char, bgColor, className: classNameProp }: { return customIcon; } - return ; + return ; }, [IconComponent, char, customIcon]); const className = useMemo(() => { - const classList = ['icon', 'h-[1.2em]', 'w-[1.2em]', 'shrink-0', 'rounded-[4px]', 'p-[0.1em]']; + const classList = [ + 'icon', + 'h-[1.2em] min-h-[1.2em]', + 'w-[1.2em] min-w-[1.2em]', + 'shrink-0', + 'rounded-[4px]', + 'p-[0.1em]', + ]; if (classNameProp) { classList.push(classNameProp); @@ -114,12 +136,16 @@ function SpaceIcon({ value, char, bgColor, className: classNameProp }: { return classList.join(' '); }, [classNameProp]); - return {content}; + return ( + + {content} + + ); } export default SpaceIcon; diff --git a/src/components/app/DatabaseView.tsx b/src/components/app/DatabaseView.tsx index a62007aa..0224723a 100644 --- a/src/components/app/DatabaseView.tsx +++ b/src/components/app/DatabaseView.tsx @@ -2,14 +2,14 @@ import { Suspense, useCallback, useMemo } from 'react'; import { useSearchParams } from 'react-router-dom'; import { ViewComponentProps, ViewLayout, YDatabase, YjsEditorKey } from '@/application/types'; -import { useAppOutline } from '@/components/app/app.hooks'; -import { Database } from '@/components/database'; import { findView } from '@/components/_shared/outline/utils'; import ComponentLoading from '@/components/_shared/progress/ComponentLoading'; import CalendarSkeleton from '@/components/_shared/skeleton/CalendarSkeleton'; import DocumentSkeleton from '@/components/_shared/skeleton/DocumentSkeleton'; import GridSkeleton from '@/components/_shared/skeleton/GridSkeleton'; import KanbanSkeleton from '@/components/_shared/skeleton/KanbanSkeleton'; +import { useAppOutline } from '@/components/app/app.hooks'; +import { Database } from '@/components/database'; import ViewMetaPreview from 'src/components/view-meta/ViewMetaPreview'; @@ -53,6 +53,7 @@ function DatabaseView(props: ViewComponentProps) { ); const rowId = search.get('r') || undefined; + const modalRowId = search.get('r-modal') || undefined; const doc = props.doc; const database = doc?.getMap(YjsEditorKey.data_section)?.get(YjsEditorKey.database) as YDatabase; const skeleton = useMemo(() => { @@ -103,6 +104,7 @@ function DatabaseView(props: ViewComponentProps) { visibleViewIds={visibleViewIds} onChangeView={handleChangeView} onOpenRowPage={handleNavigateToRow} + modalRowId={modalRowId} /> diff --git a/src/components/app/MainLayout.tsx b/src/components/app/MainLayout.tsx index 0b62ecc4..c75f6884 100644 --- a/src/components/app/MainLayout.tsx +++ b/src/components/app/MainLayout.tsx @@ -4,7 +4,7 @@ import { ErrorBoundary } from 'react-error-boundary'; import { useOutlineDrawer } from '@/components/_shared/outline/outline.hooks'; import { AFScroller } from '@/components/_shared/scroller'; import { useAIChatContext } from '@/components/ai-chat/AIChatProvider'; -import { useViewErrorStatus } from '@/components/app/app.hooks'; +import { useAppHandlers, useViewErrorStatus } from '@/components/app/app.hooks'; import { ConnectBanner } from '@/components/app/ConnectBanner'; import { AppHeader } from '@/components/app/header'; import Main from '@/components/app/Main'; @@ -17,6 +17,7 @@ function MainLayout() { const { drawerOpened, drawerWidth, setDrawerWidth, toggleOpenDrawer } = useOutlineDrawer(); const { drawerOpen: chatViewDrawerOpen, drawerWidth: openViewDrawerWidth } = useAIChatContext(); + const { openPageModalViewId } = useAppHandlers(); const { notFound, deleted } = useViewErrorStatus(); const main = useMemo(() => { @@ -65,17 +66,19 @@ function MainLayout() { /> -
+ {!openPageModalViewId && ( +
+ )} {main} diff --git a/src/components/app/ViewModal.tsx b/src/components/app/ViewModal.tsx index 729804f3..cf4c075d 100644 --- a/src/components/app/ViewModal.tsx +++ b/src/components/app/ViewModal.tsx @@ -7,6 +7,8 @@ import { UIVariant, ViewComponentProps, ViewLayout, ViewMetaProps, YDoc } from ' import { ReactComponent as ArrowDownIcon } from '@/assets/icons/alt_arrow_down.svg'; import { ReactComponent as CloseIcon } from '@/assets/icons/close.svg'; import { ReactComponent as ExpandIcon } from '@/assets/icons/expand.svg'; +import { findAncestors, findView } from '@/components/_shared/outline/utils'; +import SpaceIcon from '@/components/_shared/view-icon/SpaceIcon'; import { useAppHandlers, useAppOutline, useCurrentWorkspaceId } from '@/components/app/app.hooks'; import DatabaseView from '@/components/app/DatabaseView'; import MoreActions from '@/components/app/header/MoreActions'; @@ -14,8 +16,6 @@ import MovePagePopover from '@/components/app/view-actions/MovePagePopover'; import { Document } from '@/components/document'; import RecordNotFound from '@/components/error/RecordNotFound'; import { useService } from '@/components/main/app.hooks'; -import { findAncestors, findView } from '@/components/_shared/outline/utils'; -import SpaceIcon from '@/components/_shared/view-icon/SpaceIcon'; import ShareButton from 'src/components/app/share/ShareButton'; @@ -144,9 +144,6 @@ function ViewModal({ viewId, open, onClose }: { viewId?: string; open: boolean; {space && ref.current && ( { diff --git a/src/components/app/app.hooks.tsx b/src/components/app/app.hooks.tsx index de5c1846..161fe28b 100644 --- a/src/components/app/app.hooks.tsx +++ b/src/components/app/app.hooks.tsx @@ -247,6 +247,7 @@ export function useAppHandlers() { onRendered: context.onRendered, addPage: context.addPage, openPageModal: context.openPageModal, + openPageModalViewId: context.openPageModalViewId, deletePage: context.deletePage, deleteTrash: context.deleteTrash, restorePage: context.restorePage, diff --git a/src/components/app/view-actions/SpaceIconButton.tsx b/src/components/app/view-actions/SpaceIconButton.tsx index 0396e43f..555f0b8a 100644 --- a/src/components/app/view-actions/SpaceIconButton.tsx +++ b/src/components/app/view-actions/SpaceIconButton.tsx @@ -1,10 +1,11 @@ -import { CustomIconPopover } from '@/components/_shared/cutsom-icon'; -import SpaceIcon from '@/components/_shared/view-icon/SpaceIcon'; import { Avatar } from '@mui/material'; import React from 'react'; -import { ReactComponent as EditIcon } from '@/assets/icons/edit.svg'; -function SpaceIconButton ({ +import { ReactComponent as EditIcon } from '@/assets/icons/edit.svg'; +import { CustomIconPopover } from '@/components/_shared/cutsom-icon'; +import SpaceIcon from '@/components/_shared/view-icon/SpaceIcon'; + +function SpaceIconButton({ spaceIcon, spaceIconColor, spaceName, @@ -39,29 +40,33 @@ function SpaceIconButton ({ > setSpaceIconEditing(true)} onMouseLeave={() => setSpaceIconEditing(false)} onClick={() => { setSpaceIconEditing(false); }} + style={{ + minWidth: size ? `${size}px` : undefined, + minHeight: size ? `${size}px` : '100%', + }} > - {spaceIconEditing && -
-
+ {spaceIconEditing && ( +
+
- } + )} ); } -export default SpaceIconButton; \ No newline at end of file +export default SpaceIconButton; diff --git a/src/components/app/view-actions/SpacePermissionButton.tsx b/src/components/app/view-actions/SpacePermissionButton.tsx index dd7da1f8..e5f70fbd 100644 --- a/src/components/app/view-actions/SpacePermissionButton.tsx +++ b/src/components/app/view-actions/SpacePermissionButton.tsx @@ -1,12 +1,13 @@ +import { Button, Divider } from '@mui/material'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; + import { SpacePermission } from '@/application/types'; import { ReactComponent as ArrowDownIcon } from '@/assets/icons/alt_arrow_down.svg'; import { ReactComponent as LockIcon } from '@/assets/icons/lock.svg'; import { ReactComponent as PublicIcon } from '@/assets/icons/public.svg'; import { ReactComponent as TickIcon } from '@/assets/icons/tick.svg'; import { Popover } from '@/components/_shared/popover'; -import { Button, Divider } from '@mui/material'; -import React from 'react'; -import { useTranslation } from 'react-i18next'; function SpacePermissionButton({ onSelected, diff --git a/src/components/database/Database.tsx b/src/components/database/Database.tsx index 178dcf01..725d1cfd 100644 --- a/src/components/database/Database.tsx +++ b/src/components/database/Database.tsx @@ -33,6 +33,7 @@ export interface Database2Props { viewId: string; iidName: string; rowId?: string; + modalRowId?: string; appendBreadcrumb?: AppendBreadcrumb; onChangeView: (viewId: string) => void; onOpenRowPage?: (rowId: string) => void; @@ -62,6 +63,7 @@ function Database(props: Database2Props) { readOnly = true, loadView, navigateToView, + modalRowId, } = props; const database = doc.getMap(YjsEditorKey.data_section)?.get(YjsEditorKey.database) as YDatabase | null; const view = database?.get(YjsDatabaseKey.views)?.get(iidIndex); @@ -136,8 +138,8 @@ function Database(props: Database2Props) { }; }, [handleUpdateRowDocMap, rowOrders]); - const [openModalRowId, setOpenModalRowId] = useState(null); - const [openModalViewId, setOpenModalViewId] = useState(null); + const [openModalRowId, setOpenModalRowId] = useState(() => modalRowId || null); + const [openModalViewId, setOpenModalViewId] = useState(() => (modalRowId ? viewId : null)); const [openModalRowDatabaseDoc, setOpenModalRowDatabaseDoc] = useState(null); const [openModalRowDocMap, setOpenModalRowDocMap] = useState | null>(null); diff --git a/src/components/database/DatabaseRowModal.tsx b/src/components/database/DatabaseRowModal.tsx index d4daf739..ca75ace2 100644 --- a/src/components/database/DatabaseRowModal.tsx +++ b/src/components/database/DatabaseRowModal.tsx @@ -3,11 +3,14 @@ import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { toast } from 'sonner'; +import { useDatabaseContext } from '@/application/database-yjs'; import { useDeleteRowDispatch, useDuplicateRowDispatch } from '@/application/database-yjs/dispatch'; +import { ReactComponent as ArrowLeftIcon } from '@/assets/icons/arrow_left.svg'; import { ReactComponent as DeleteIcon } from '@/assets/icons/delete.svg'; import { ReactComponent as DuplicateIcon } from '@/assets/icons/duplicate.svg'; import { ReactComponent as ExpandIcon } from '@/assets/icons/expand.svg'; import { ReactComponent as MoreIcon } from '@/assets/icons/more.svg'; +import { AFScroller } from '@/components/_shared/scroller'; import { DatabaseRow } from '@/components/database/DatabaseRow'; import { Button } from '@/components/ui/button'; import { @@ -19,7 +22,6 @@ import { } from '@/components/ui/dropdown-menu'; import { Progress } from '@/components/ui/progress'; import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; -import { AFScroller } from '@/components/_shared/scroller'; function DatabaseRowModal({ open, @@ -32,7 +34,7 @@ function DatabaseRowModal({ onOpenChange: (open: boolean) => void; openPage?: (rowId: string) => void; }) { - // const {} = useDatabaseContext(); + const { openPageModalViewId } = useDatabaseContext(); const { t } = useTranslation(); const duplicateRow = useDuplicateRowDispatch(); const deleteRow = useDeleteRowDispatch(); @@ -49,12 +51,32 @@ function DatabaseRowModal({ disableAutoFocus={false} disableEnforceFocus={false} disableRestoreFocus={true} + hideBackdrop={!!openPageModalViewId} PaperProps={{ className: `max-w-[70vw] relative w-[1188px] h-[80vh] overflow-hidden flex flex-col`, }} > +
+ {openPageModalViewId && ( + + + + + Go back + + )} +
+