mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-20 19:46:32 +08:00
feat(core): linked doc visiblity setting and new sidebar layout (#12836)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added a setting to control the visibility of linked document structures in the sidebar, enabled by default. - Introduced a "dense" mode for workspace selectors and cards, providing a more compact display. - **Improvements** - Refined sidebar and navigation panel layouts with updated padding, spacing, and avatar/button sizing for a cleaner and more consistent appearance. - Enhanced sidebar appearance settings UI, including new localization for the linked doc visibility option. - Updated color theming and spacing in sidebar menu items and quick search input for better usability. - Enabled collapsible behavior control for navigation panel tree nodes, improving user interaction flexibility. - **Style** - Adjusted various component styles for improved compactness and alignment across the sidebar and navigation panels. - Reduced sizes and padding of buttons and icons for a tidier interface. - Updated CSS variables and dynamic sizing for workspace cards to support dense mode. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -5,6 +5,9 @@ export const workspaceAndUserWrapper = style({
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
gap: 8,
|
||||
width: 'calc(100% + 12px)',
|
||||
paddingRight: 6,
|
||||
alignSelf: 'center',
|
||||
});
|
||||
export const quickSearchAndNewPage = style({
|
||||
display: 'flex',
|
||||
|
||||
@@ -167,6 +167,7 @@ export const RootAppSidebar = memo((): ReactElement => {
|
||||
showSyncStatus
|
||||
open={workspaceSelectorOpen}
|
||||
onOpenChange={onWorkspaceSelectorOpenChange}
|
||||
dense
|
||||
/>
|
||||
</div>
|
||||
<UserInfo />
|
||||
|
||||
@@ -38,8 +38,14 @@ const menuContentOptions: MenuProps['contentOptions'] = {
|
||||
const AuthorizedUserInfo = ({ account }: { account: AuthAccountInfo }) => {
|
||||
return (
|
||||
<Menu items={<OperationMenu />} contentOptions={menuContentOptions}>
|
||||
<IconButton data-testid="sidebar-user-avatar" variant="plain" size="24">
|
||||
<Avatar size={24} name={account.label} url={account.avatar} />
|
||||
<IconButton
|
||||
data-testid="sidebar-user-avatar"
|
||||
variant="plain"
|
||||
size="20"
|
||||
style={{ padding: 0 }}
|
||||
withoutHover
|
||||
>
|
||||
<Avatar size={20} name={account.label} url={account.avatar} />
|
||||
</IconButton>
|
||||
</Menu>
|
||||
);
|
||||
@@ -57,7 +63,7 @@ const UnauthorizedUserInfo = () => {
|
||||
onClick={openSignInModal}
|
||||
data-testid="sidebar-user-avatar"
|
||||
variant="plain"
|
||||
size="24"
|
||||
size="20"
|
||||
>
|
||||
<UnknownUserIcon />
|
||||
</IconButton>
|
||||
|
||||
@@ -32,6 +32,8 @@ interface WorkspaceSelectorProps {
|
||||
disable?: boolean;
|
||||
menuContentOptions?: MenuProps['contentOptions'];
|
||||
className?: string;
|
||||
/** if true, will hide cloud/local, and scale the avatar */
|
||||
dense?: boolean;
|
||||
}
|
||||
|
||||
export const WorkspaceSelector = ({
|
||||
@@ -46,6 +48,7 @@ export const WorkspaceSelector = ({
|
||||
showSyncStatus,
|
||||
className,
|
||||
menuContentOptions,
|
||||
dense,
|
||||
}: WorkspaceSelectorProps) => {
|
||||
const { workspacesService, globalContextService } = useServices({
|
||||
GlobalContextService,
|
||||
@@ -133,6 +136,7 @@ export const WorkspaceSelector = ({
|
||||
hideCollaborationIcon={true}
|
||||
hideTeamWorkspaceIcon={true}
|
||||
data-testid="current-workspace-card"
|
||||
dense={dense}
|
||||
/>
|
||||
) : (
|
||||
<span></span>
|
||||
|
||||
@@ -174,9 +174,11 @@ const usePauseAnimation = (timeToResume = 5000) => {
|
||||
const WorkspaceSyncInfo = ({
|
||||
workspaceMetadata,
|
||||
workspaceProfile,
|
||||
dense,
|
||||
}: {
|
||||
workspaceMetadata: WorkspaceMetadata;
|
||||
workspaceProfile: WorkspaceProfileInfo;
|
||||
dense?: boolean;
|
||||
}) => {
|
||||
const syncStatus = useSyncEngineSyncProgress(workspaceMetadata);
|
||||
const isCloud = workspaceMetadata.flavour !== 'local';
|
||||
@@ -209,15 +211,21 @@ const WorkspaceSyncInfo = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.workspaceInfoSlider} data-active={delayActive}>
|
||||
<div
|
||||
className={styles.workspaceInfoSlider}
|
||||
data-active={delayActive}
|
||||
data-dense={dense}
|
||||
>
|
||||
<div className={styles.workspaceInfoSlide}>
|
||||
<div className={styles.workspaceInfo} data-type="normal">
|
||||
<div className={styles.workspaceName} data-testid="workspace-name">
|
||||
{workspaceProfile.name}
|
||||
</div>
|
||||
<div className={styles.workspaceStatus}>
|
||||
{isCloud ? <CloudWorkspaceStatus /> : <LocalWorkspaceStatus />}
|
||||
</div>
|
||||
{!dense ? (
|
||||
<div className={styles.workspaceStatus}>
|
||||
{isCloud ? <CloudWorkspaceStatus /> : <LocalWorkspaceStatus />}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{/* when syncing/offline/... */}
|
||||
@@ -250,6 +258,7 @@ export const WorkspaceCard = forwardRef<
|
||||
hideTeamWorkspaceIcon?: boolean;
|
||||
active?: boolean;
|
||||
infoClassName?: string;
|
||||
dense?: boolean;
|
||||
onClickOpenSettings?: (workspaceMetadata: WorkspaceMetadata) => void;
|
||||
onClickEnableCloud?: (workspaceMetadata: WorkspaceMetadata) => void;
|
||||
}
|
||||
@@ -259,7 +268,6 @@ export const WorkspaceCard = forwardRef<
|
||||
workspaceMetadata,
|
||||
showSyncStatus,
|
||||
showArrowDownIcon,
|
||||
avatarSize = 32,
|
||||
onClickOpenSettings,
|
||||
onClickEnableCloud,
|
||||
className,
|
||||
@@ -268,6 +276,8 @@ export const WorkspaceCard = forwardRef<
|
||||
hideCollaborationIcon,
|
||||
hideTeamWorkspaceIcon,
|
||||
active,
|
||||
dense,
|
||||
avatarSize = dense ? 20 : 32,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
@@ -301,6 +311,7 @@ export const WorkspaceCard = forwardRef<
|
||||
<div className={clsx(styles.infoContainer, infoClassName)}>
|
||||
{information ? (
|
||||
<WorkspaceAvatar
|
||||
className={styles.avatar}
|
||||
meta={workspaceMetadata}
|
||||
rounded={3}
|
||||
data-testid="workspace-avatar"
|
||||
@@ -317,6 +328,7 @@ export const WorkspaceCard = forwardRef<
|
||||
<WorkspaceSyncInfo
|
||||
workspaceProfile={information}
|
||||
workspaceMetadata={workspaceMetadata}
|
||||
dense={dense}
|
||||
/>
|
||||
) : (
|
||||
<span className={styles.workspaceName}>{information.name}</span>
|
||||
|
||||
+15
-5
@@ -9,11 +9,10 @@ const wsSlideAnim = {
|
||||
};
|
||||
|
||||
export const container = style({
|
||||
height: '50px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
padding: '0 6px',
|
||||
padding: '4px 6px',
|
||||
borderRadius: 4,
|
||||
outline: 'none',
|
||||
width: '100%',
|
||||
@@ -48,8 +47,16 @@ export const disable = style({
|
||||
});
|
||||
|
||||
export const workspaceInfoSlider = style({
|
||||
height: 42,
|
||||
vars: {
|
||||
'--h': '42px',
|
||||
},
|
||||
height: 'var(--h)',
|
||||
overflow: 'hidden',
|
||||
selectors: {
|
||||
'&[data-dense="true"]': {
|
||||
vars: { '--h': '22px' },
|
||||
},
|
||||
},
|
||||
});
|
||||
export const workspaceInfoSlide = style({
|
||||
display: 'flex',
|
||||
@@ -59,15 +66,18 @@ export const workspaceInfoSlide = style({
|
||||
transition: `transform ${wsSlideAnim.duration} ${wsSlideAnim.ease} ${wsSlideAnim.delay}`,
|
||||
selectors: {
|
||||
[`.${workspaceInfoSlider}[data-active="true"] &`]: {
|
||||
transform: 'translateY(-42px)',
|
||||
transform: 'translateY(calc(var(--h) * -1))',
|
||||
},
|
||||
},
|
||||
});
|
||||
export const avatar = style({
|
||||
border: `0.5px solid ${cssVarV2.layer.insideBorder.border}`,
|
||||
});
|
||||
export const workspaceInfo = style({
|
||||
width: '100%',
|
||||
flexGrow: 1,
|
||||
overflow: 'hidden',
|
||||
height: 42,
|
||||
height: 'var(--h)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
|
||||
Reference in New Issue
Block a user