feat: new workspace switch dropdown design (#3700)

Co-authored-by: Alex Yang <himself65@outlook.com>
This commit is contained in:
danielchim
2023-08-17 06:18:43 +08:00
committed by GitHub
parent f369ca39f7
commit 9ab9c0c70d
11 changed files with 368 additions and 192 deletions
@@ -1,11 +1,4 @@
import {
Menu,
MenuItem,
Modal,
ModalCloseButton,
ModalWrapper,
Tooltip,
} from '@affine/component';
import { Menu, MenuItem, Tooltip } from '@affine/component';
import { ScrollableContainer } from '@affine/component';
import { WorkspaceList } from '@affine/component/workspace-list';
import type {
@@ -15,28 +8,38 @@ import type {
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { RootWorkspaceMetadata } from '@affine/workspace/atom';
import { HelpIcon, ImportIcon, PlusIcon } from '@blocksuite/icons';
import type { DragEndEvent } from '@dnd-kit/core';
import { useCallback, useRef } from 'react';
import type { AllWorkspace } from '../../../shared';
import { Footer } from '../footer';
import {
StyledCreateWorkspaceCard,
CloudWorkspaceIcon,
HelpIcon,
ImportIcon,
MoreHorizontalIcon,
PlusIcon,
} from '@blocksuite/icons';
import type { DragEndEvent } from '@dnd-kit/core';
import { Popover } from '@mui/material';
import { IconButton } from '@toeverything/components/button';
import { Divider } from '@toeverything/components/divider';
import { useSetAtom } from 'jotai';
import { useCallback } from 'react';
import { openDisableCloudAlertModalAtom } from '../../../atoms';
import type { AllWorkspace } from '../../../shared';
import {
StyledCreateWorkspaceCardPill,
StyledCreateWorkspaceCardPillContainer,
StyledCreateWorkspaceCardPillContent,
StyledCreateWorkspaceCardPillIcon,
StyledCreateWorkspaceCardPillTextSecondary,
StyledHelperContainer,
StyledImportWorkspaceCardPill,
StyledModalBody,
StyledModalContent,
StyledModalHeader,
StyledModalHeaderLeft,
StyledModalTitle,
StyledOperationWrapper,
StyleWorkspaceAdd,
StyleWorkspaceInfo,
StyleWorkspaceTitle,
StyledSignInCardPill,
StyledSignInCardPillTextCotainer,
StyledSignInCardPillTextPrimary,
StyledSignInCardPillTextSecondary,
} from './styles';
interface WorkspaceModalProps {
@@ -52,105 +55,94 @@ interface WorkspaceModalProps {
onMoveWorkspace: (activeId: string, overId: string) => void;
}
const CreateWorkspaceCard = ({
onNewWorkspace,
onAddWorkspace,
}: {
onNewWorkspace: () => void;
onAddWorkspace: () => void;
}) => {
const AccountMenu = () => {
const t = useAFFiNEI18N();
const anchorEL = useRef<HTMLDivElement>(null);
return (
<div>
<div>Unlimted</div>
<Divider></Divider>
<MenuItem icon={<ImportIcon />} data-testid="editor-option-menu-import">
{t['com.affine.workspace.cloud.join']()}
</MenuItem>
<MenuItem icon={<ImportIcon />} data-testid="editor-option-menu-import">
{t['com.affine.workspace.cloud.account.settings']()}
</MenuItem>
<Divider></Divider>
<MenuItem icon={<ImportIcon />} data-testid="editor-option-menu-import">
{t['com.affine.workspace.cloud.account.logout']()}
</MenuItem>
</div>
);
};
if (runtimeConfig.enableSQLiteProvider && environment.isDesktop) {
return (
<Menu
placement="auto"
trigger={['click']}
zIndex={1000}
content={
<StyledCreateWorkspaceCardPillContainer>
<StyledCreateWorkspaceCardPill>
<MenuItem
style={{
height: 'auto',
padding: '8px 12px',
}}
onClick={onNewWorkspace}
data-testid="new-workspace"
>
<StyledCreateWorkspaceCardPillContent>
<div>
<p>{t['New Workspace']()}</p>
<StyledCreateWorkspaceCardPillTextSecondary>
<p>{t['Create your own workspace']()}</p>
</StyledCreateWorkspaceCardPillTextSecondary>
</div>
<StyledCreateWorkspaceCardPillIcon>
<PlusIcon />
</StyledCreateWorkspaceCardPillIcon>
</StyledCreateWorkspaceCardPillContent>
</MenuItem>
</StyledCreateWorkspaceCardPill>
<StyledCreateWorkspaceCardPill>
<MenuItem
onClick={onAddWorkspace}
data-testid="add-workspace"
style={{
height: 'auto',
padding: '8px 12px',
}}
>
<StyledCreateWorkspaceCardPillContent>
<div>
<p>{t['Add Workspace']()}</p>
<StyledCreateWorkspaceCardPillTextSecondary>
<p>{t['Add Workspace Hint']()}</p>
</StyledCreateWorkspaceCardPillTextSecondary>
</div>
<StyledCreateWorkspaceCardPillIcon>
<ImportIcon />
</StyledCreateWorkspaceCardPillIcon>
</StyledCreateWorkspaceCardPillContent>
</MenuItem>
</StyledCreateWorkspaceCardPill>
</StyledCreateWorkspaceCardPillContainer>
}
>
<StyledCreateWorkspaceCard
ref={anchorEL}
data-testid="add-or-new-workspace"
>
<StyleWorkspaceAdd className="add-icon">
<PlusIcon />
</StyleWorkspaceAdd>
const CloudWorkSpaceList = ({
disabled,
workspaces,
onClickWorkspace,
onClickWorkspaceSetting,
currentWorkspaceId,
onMoveWorkspace,
}: WorkspaceModalProps) => {
const t = useAFFiNEI18N();
<StyleWorkspaceInfo>
<StyleWorkspaceTitle>{t['New Workspace']()}</StyleWorkspaceTitle>
<p>{t['Create Or Import']()}</p>
</StyleWorkspaceInfo>
</StyledCreateWorkspaceCard>
</Menu>
);
} else {
return (
<div>
<StyledCreateWorkspaceCard
onClick={onNewWorkspace}
data-testid="new-workspace"
>
<StyleWorkspaceAdd className="add-icon">
<PlusIcon />
</StyleWorkspaceAdd>
return (
<>
<StyledModalHeader>
<StyledModalHeaderLeft>
<StyledModalTitle>
{t['com.affine.workspace.cloud.sync']()}
</StyledModalTitle>
<Tooltip
content={t['Workspace description']()}
placement="top-start"
disablePortal={true}
>
<StyledHelperContainer>
<HelpIcon />
</StyledHelperContainer>
</Tooltip>
</StyledModalHeaderLeft>
<StyleWorkspaceInfo>
<StyleWorkspaceTitle>{t['New Workspace']()}</StyleWorkspaceTitle>
<p>{t['Create Or Import']()}</p>
</StyleWorkspaceInfo>
</StyledCreateWorkspaceCard>
</div>
);
}
<StyledOperationWrapper>
<Menu
placement="bottom-end"
trigger={['click']}
content={<AccountMenu />}
zIndex={1000}
>
<IconButton
data-testid="previous-image-button"
icon={<MoreHorizontalIcon />}
type="plain"
/>
</Menu>
</StyledOperationWrapper>
</StyledModalHeader>
<StyledModalContent>
<WorkspaceList
disabled={disabled}
items={
workspaces.filter(
({ flavour }) => flavour !== WorkspaceFlavour.PUBLIC
) as (AffineCloudWorkspace | LocalWorkspace)[]
}
currentWorkspaceId={currentWorkspaceId}
onClick={onClickWorkspace}
onSettingClick={onClickWorkspaceSetting}
onDragEnd={useCallback(
(event: DragEndEvent) => {
const { active, over } = event;
if (active.id !== over?.id) {
onMoveWorkspace(active.id as string, over?.id as string);
}
},
[onMoveWorkspace]
)}
/>
<Divider />
</StyledModalContent>
</>
);
};
export const WorkspaceListModal = ({
@@ -166,19 +158,77 @@ export const WorkspaceListModal = ({
onMoveWorkspace,
}: WorkspaceModalProps) => {
const t = useAFFiNEI18N();
const setOpen = useSetAtom(openDisableCloudAlertModalAtom);
// TODO: AFFiNE Cloud support
const isLoggedIn = false;
const anchorEl = document.getElementById('current-workspace');
return (
<Modal open={open} onClose={onClose}>
<ModalWrapper
width={720}
height={690}
style={{
display: 'flex',
flexDirection: 'column',
}}
>
<StyledModalHeader>
<StyledModalHeaderLeft>
<StyledModalTitle>{t['My Workspaces']()}</StyledModalTitle>
<Popover
sx={{
color: 'success.main',
zIndex: 999,
'& .MuiPopover-paper': {
borderRadius: '8px',
boxShadow: 'var(--affine-shadow-1)',
},
}}
open={open}
anchorEl={anchorEl}
onClose={onClose}
>
<StyledModalBody>
<ScrollableContainer>
{isLoggedIn ? (
<CloudWorkSpaceList
disabled={disabled}
open={open}
onClose={onClose}
workspaces={workspaces}
onClickWorkspace={onClickWorkspace}
onClickWorkspaceSetting={onClickWorkspaceSetting}
onNewWorkspace={onNewWorkspace}
onAddWorkspace={onAddWorkspace}
currentWorkspaceId={currentWorkspaceId}
onMoveWorkspace={onMoveWorkspace}
/>
) : (
<>
<StyledModalContent>
<StyledSignInCardPill>
<MenuItem
style={{
height: 'auto',
padding: '8px 12px',
}}
onClick={async () => {
if (!runtimeConfig.enableCloud) {
setOpen(true);
}
}}
data-testid="cloud-signin-button"
>
<StyledCreateWorkspaceCardPillContent>
<StyledCreateWorkspaceCardPillIcon>
<CloudWorkspaceIcon />
</StyledCreateWorkspaceCardPillIcon>
<StyledSignInCardPillTextCotainer>
<StyledSignInCardPillTextPrimary>
{t['com.affine.workspace.cloud.auth']()}
</StyledSignInCardPillTextPrimary>
<StyledSignInCardPillTextSecondary>
Sync with AFFiNE Cloud
</StyledSignInCardPillTextSecondary>
</StyledSignInCardPillTextCotainer>
</StyledCreateWorkspaceCardPillContent>
</MenuItem>
</StyledSignInCardPill>
<Divider />
</StyledModalContent>
</>
)}
<StyledModalHeader>
<StyledModalTitle>{t['Local Workspace']()}</StyledModalTitle>
<Tooltip
content={t['Workspace description']()}
placement="top-start"
@@ -188,19 +238,7 @@ export const WorkspaceListModal = ({
<HelpIcon />
</StyledHelperContainer>
</Tooltip>
</StyledModalHeaderLeft>
<StyledOperationWrapper>
<ModalCloseButton
data-testid="close-workspace-modal"
onClick={() => {
onClose();
}}
absolute={false}
/>
</StyledOperationWrapper>
</StyledModalHeader>
<ScrollableContainer>
</StyledModalHeader>
<StyledModalContent>
<WorkspaceList
disabled={disabled}
@@ -222,14 +260,51 @@ export const WorkspaceListModal = ({
[onMoveWorkspace]
)}
/>
<CreateWorkspaceCard
onNewWorkspace={onNewWorkspace}
onAddWorkspace={onAddWorkspace}
/>
</StyledModalContent>
<StyledModalContent>
{runtimeConfig.enableSQLiteProvider && environment.isDesktop ? (
<StyledImportWorkspaceCardPill>
<MenuItem
onClick={onAddWorkspace}
data-testid="add-workspace"
style={{
height: 'auto',
padding: '8px 12px',
}}
>
<StyledCreateWorkspaceCardPillContent>
<StyledCreateWorkspaceCardPillIcon>
<ImportIcon />
</StyledCreateWorkspaceCardPillIcon>
<div>
<p>{t['com.affine.workspace.local.import']()}</p>
</div>
</StyledCreateWorkspaceCardPillContent>
</MenuItem>
</StyledImportWorkspaceCardPill>
) : null}
<StyledCreateWorkspaceCardPill>
<MenuItem
style={{
height: 'auto',
padding: '8px 12px',
}}
onClick={onNewWorkspace}
data-testid="new-workspace"
>
<StyledCreateWorkspaceCardPillContent>
<StyledCreateWorkspaceCardPillIcon>
<PlusIcon />
</StyledCreateWorkspaceCardPillIcon>
<div>
<p>{t['New Workspace']()}</p>
</div>
</StyledCreateWorkspaceCardPillContent>
</MenuItem>
</StyledCreateWorkspaceCardPill>
</StyledModalContent>
</ScrollableContainer>
<Footer />
</ModalWrapper>
</Modal>
</StyledModalBody>
</Popover>
);
};
@@ -81,11 +81,33 @@ export const StyledCreateWorkspaceCardPillContainer = styled('div')(() => {
});
export const StyledCreateWorkspaceCardPill = styled('div')(() => {
return {
borderRadius: '8px',
display: 'flex',
width: '100%',
height: '58px',
background: 'var(--affine-background-primary-color)',
border: `1px solid var(--affine-border-color)`,
};
});
export const StyledSignInCardPill = styled('div')(() => {
return {
borderRadius: '8px',
display: 'flex',
width: '100%',
height: '58px',
marginBottom: '6px',
background: 'var(--affine-background-primary-color)',
};
});
export const StyledImportWorkspaceCardPill = styled('div')(() => {
return {
borderRadius: '5px',
display: 'flex',
boxShadow: '0px 0px 6px 0px rgba(0, 0, 0, 0.1)',
background: 'var(--affine-background-primary-color)',
width: '100%',
marginBottom: '12px',
};
});
@@ -94,7 +116,6 @@ export const StyledCreateWorkspaceCardPillContent = styled('div')(() => {
display: 'flex',
gap: '12px',
alignItems: 'center',
justifyContent: 'space-between',
};
});
@@ -106,13 +127,30 @@ export const StyledCreateWorkspaceCardPillIcon = styled('div')(() => {
};
});
export const StyledCreateWorkspaceCardPillTextSecondary = styled('div')(() => {
export const StyledSignInCardPillTextCotainer = styled('div')(() => {
return {
display: 'flex',
flexDirection: 'column',
};
});
export const StyledSignInCardPillTextSecondary = styled('div')(() => {
return {
fontSize: '12px',
color: 'var(--affine-text-secondary-color)',
};
});
export const StyledSignInCardPillTextPrimary = styled('div')(() => {
return {
fontSize: 'var(--affine-font-base)',
fontWeight: 600,
lineHeight: '24px',
maxWidth: '200px',
...textEllipsis(1),
};
});
export const StyledModalHeaderLeft = styled('div')(() => {
return { ...displayFlex('flex-start', 'center') };
});
@@ -120,6 +158,7 @@ export const StyledModalTitle = styled('div')(() => {
return {
fontWeight: 600,
fontSize: 'var(--affine-font-h6)',
color: 'var(--affine-text-primary-color)',
};
});
@@ -134,10 +173,9 @@ export const StyledHelperContainer = styled('div')(() => {
});
export const StyledModalContent = styled('div')({
height: '540px',
padding: '8px 40px',
...displayFlex('space-between', 'flex-start', 'flex-start'),
flexWrap: 'wrap',
flexDirection: 'column',
});
export const StyledOperationWrapper = styled('div')(() => {
return {
@@ -162,11 +200,22 @@ export const StyleWorkspaceAdd = styled('div')(() => {
export const StyledModalHeader = styled('div')(() => {
return {
width: '100%',
marginTop: '10px',
left: 0,
top: 0,
borderRadius: '24px 24px 0 0',
padding: '10px 40px',
padding: '12px 14px',
...displayFlex('space-between', 'center'),
};
});
export const StyledModalBody = styled('div')(() => {
return {
borderRadius: '8px',
padding: '12px',
display: 'inline-flex',
flexDirection: 'column',
alignItems: 'flex-start',
gap: '12px',
background: 'var(--affine-white)',
};
});
@@ -32,6 +32,7 @@ export const WorkspaceSelector = ({
// Open dialog when `Enter` or `Space` pressed
// TODO-Doma Refactor with `@radix-ui/react-dialog` or other libraries that handle these out of the box and be accessible by default
// TODO: Delete this?
const handleKeyDown = useCallback(
(e: React.KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') {
@@ -50,6 +51,7 @@ export const WorkspaceSelector = ({
onClick={onClick}
onKeyDown={handleKeyDown}
data-testid="current-workspace"
id="current-workspace"
>
<WorkspaceAvatar
data-testid="workspace-avatar"
+10 -5
View File
@@ -126,6 +126,7 @@ export const AllWorkspaceModals = (): ReactElement => {
);
const setCurrentPageId = useSetAtom(currentPageIdAtom);
const [isPending, startTransition] = useTransition();
const [, startCloseTransition] = useTransition();
const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom);
const handleOpenSettingModal = useCallback(
@@ -153,7 +154,9 @@ export const AllWorkspaceModals = (): ReactElement => {
isOpenCreateWorkspaceModal === false
}
onClose={useCallback(() => {
setOpenWorkspacesModal(false);
startCloseTransition(() => {
setOpenWorkspacesModal(false);
});
}, [setOpenWorkspacesModal])}
onMoveWorkspace={useCallback(
(activeId, overId) => {
@@ -169,10 +172,12 @@ export const AllWorkspaceModals = (): ReactElement => {
)}
onClickWorkspace={useCallback(
workspaceId => {
setOpenWorkspacesModal(false);
setCurrentWorkspaceId(workspaceId);
setCurrentPageId(null);
jumpToSubPath(workspaceId, WorkspaceSubPath.ALL);
startCloseTransition(() => {
setOpenWorkspacesModal(false);
setCurrentWorkspaceId(workspaceId);
setCurrentPageId(null);
jumpToSubPath(workspaceId, WorkspaceSubPath.ALL);
});
},
[
jumpToSubPath,
+33 -3
View File
@@ -1,7 +1,7 @@
import { pluginRegisterPromise } from '@affine/core/bootstrap/register-plugins';
import { routes } from '@affine/core/router';
import { assertExists } from '@blocksuite/global/utils';
import type { StoryContext, StoryFn } from '@storybook/react';
import type { Decorator, StoryFn } from '@storybook/react';
import { userEvent, waitFor } from '@storybook/testing-library';
import { use } from 'foxact/use';
import { Outlet, useLocation } from 'react-router-dom';
@@ -11,9 +11,9 @@ import {
withRouter,
} from 'storybook-addon-react-router-v6';
const withCleanLocalStorage = (Story: StoryFn, context: StoryContext) => {
const withCleanLocalStorage: Decorator = (Story, context) => {
localStorage.clear();
return <Story {...context.args} />;
return <Story {...context} />;
};
const FakeApp = () => {
@@ -78,3 +78,33 @@ NotFoundPage.parameters = {
},
}),
};
export const WorkspaceList: StoryFn = () => {
return <FakeApp />;
};
WorkspaceList.play = async ({ canvasElement }) => {
// click current-workspace
await waitFor(
() => {
assertExists(
canvasElement.querySelector('[data-testid="current-workspace"]')
);
},
{
timeout: 5000,
}
);
const currentWorkspace = canvasElement.querySelector(
'[data-testid="current-workspace"]'
) as Element;
await userEvent.click(currentWorkspace);
};
WorkspaceList.decorators = [withRouter, withCleanLocalStorage];
WorkspaceList.parameters = {
reactRouter: reactRouterParameters({
routing: reactRouterOutlets(routes),
location: {
path: '/',
},
}),
};
@@ -5,7 +5,6 @@ import { SettingsIcon } from '@blocksuite/icons';
import {
CloudWorkspaceIcon as DefaultCloudWorkspaceIcon,
CollaborationIcon as DefaultJoinedWorkspaceIcon,
LocalDataIcon as DefaultLocalDataIcon,
LocalWorkspaceIcon as DefaultLocalWorkspaceIcon,
} from '@blocksuite/icons';
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
@@ -16,8 +15,8 @@ import { WorkspaceAvatar } from '../../workspace-avatar';
import {
StyledCard,
StyledSettingLink,
StyleWorkspaceInfo,
StyleWorkspaceTitle,
StyledWorkspaceInfo,
StyledWorkspaceTitle,
} from './styles';
const JoinedWorkspaceIcon = () => {
@@ -31,9 +30,9 @@ const CloudWorkspaceIcon = () => {
return <DefaultCloudWorkspaceIcon style={{ color: '#60A5FA' }} />;
};
const LocalDataIcon = () => {
return <DefaultLocalDataIcon style={{ color: '#62CD80' }} />;
};
// const LocalDataIcon = () => {
// return <DefaultLocalDataIcon style={{ color: '#62CD80' }} />;
// };
export interface WorkspaceTypeProps {
flavour: WorkspaceFlavour;
@@ -46,7 +45,7 @@ const WorkspaceType = ({ flavour }: WorkspaceTypeProps) => {
if (flavour === WorkspaceFlavour.LOCAL) {
return (
<p title={t['Local Workspace']()}>
<p style={{ fontSize: '10px' }} title={t['Local Workspace']()}>
<LocalWorkspaceIcon />
<span>{t['Local Workspace']()}</span>
</p>
@@ -54,12 +53,12 @@ const WorkspaceType = ({ flavour }: WorkspaceTypeProps) => {
}
return isOwner ? (
<p title={t['Cloud Workspace']()}>
<p style={{ fontSize: '10px' }} title={t['Cloud Workspace']()}>
<CloudWorkspaceIcon />
<span>{t['Cloud Workspace']()}</span>
</p>
) : (
<p title={t['Joined Workspace']()}>
<p style={{ fontSize: '10px' }} title={t['Joined Workspace']()}>
<JoinedWorkspaceIcon />
<span>{t['Joined Workspace']()}</span>
</p>
@@ -79,7 +78,7 @@ export const WorkspaceCard = ({
currentWorkspaceId,
meta,
}: WorkspaceCardProps) => {
const t = useAFFiNEI18N();
// const t = useAFFiNEI18N();
const workspace = useStaticBlockSuiteWorkspace(meta.id);
const [name] = useBlockSuiteWorkspaceName(workspace);
@@ -91,18 +90,18 @@ export const WorkspaceCard = ({
}, [onClick, meta.id])}
active={workspace.id === currentWorkspaceId}
>
<WorkspaceAvatar size={58} workspace={workspace} />
<WorkspaceAvatar size={28} workspace={workspace} />
<StyleWorkspaceInfo>
<StyleWorkspaceTitle>{name}</StyleWorkspaceTitle>
<StyledWorkspaceInfo>
<StyledWorkspaceTitle>{name}</StyledWorkspaceTitle>
<WorkspaceType flavour={meta.flavour} />
{meta.flavour === WorkspaceFlavour.LOCAL && (
{/* {meta.flavour === WorkspaceFlavour.LOCAL && (
<p title={t['Available Offline']()}>
<LocalDataIcon />
<span>{t['Available Offline']()}</span>
</p>
)}
</StyleWorkspaceInfo>
)} */}
</StyledWorkspaceInfo>
<StyledSettingLink
className="setting-entry"
onClick={e => {
@@ -2,7 +2,7 @@ import { IconButton } from '@toeverything/components/button';
import { displayFlex, styled, textEllipsis } from '../../../styles';
export const StyleWorkspaceInfo = styled('div')(() => {
export const StyledWorkspaceInfo = styled('div')(() => {
return {
marginLeft: '15px',
width: '202px',
@@ -23,13 +23,13 @@ export const StyleWorkspaceInfo = styled('div')(() => {
};
});
export const StyleWorkspaceTitle = styled('div')(() => {
export const StyledWorkspaceTitle = styled('div')(() => {
return {
fontSize: 'var(--affine-font-base)',
fontWeight: 600,
lineHeight: '24px',
marginBottom: '10px',
maxWidth: '200px',
color: 'var(--affine-text-primary-color)',
...textEllipsis(1),
};
});
@@ -38,19 +38,21 @@ export const StyledCard = styled('div')<{
active?: boolean;
}>(({ active }) => {
const borderColor = active ? 'var(--affine-primary-color)' : 'transparent';
const backgroundColor = active ? 'var(--affine-white)' : 'transparent';
return {
width: '310px',
height: '124px',
width: '280px',
height: '58px',
cursor: 'pointer',
padding: '16px',
boxShadow: 'var(--affine-shadow-1)',
borderRadius: '12px',
border: `1px solid ${borderColor}`,
...displayFlex('flex-start', 'flex-start'),
marginBottom: '24px',
marginBottom: '12px',
transition: 'background .2s',
background: 'var(--affine-white-80)',
alignItems: 'center',
position: 'relative',
color: 'var(--affine-text-secondary-color)',
background: backgroundColor,
':hover': {
background: 'var(--affine-hover-color)',
'.add-icon': {
@@ -96,3 +98,9 @@ export const StyledSettingLink = styled(IconButton)(() => {
},
};
});
export const StyledWorkspaceType = styled('p')(() => {
return {
fontSize: 10,
};
});
+6
View File
@@ -470,6 +470,12 @@
"com.affine.auth.create.count": "Create Account",
"com.affine.expired.page.title": "This link has expired...",
"com.affine.expired.page.subtitle": "Please request a new reset password link.",
"com.affine.workspace.cloud.join": "Join Workspace",
"com.affine.workspace.cloud.account.settings": "Account Settings",
"com.affine.workspace.cloud.account.logout": "Log Out",
"com.affine.workspace.cloud.sync": "Cloud sync",
"com.affine.workspace.cloud.auth": "Sign up/ Sign in",
"com.affine.workspace.local.import": "Import Workspace",
"core": "core",
"dark": "Dark",
"emptyAllPages": "Click on the <1>$t(New Page)</1> button to create your first page.",
+1 -1
View File
@@ -625,7 +625,7 @@ test('tooltips for all buttons should be visible when hovering', async ({
}
await locator.getByTestId('download-button').hover();
await page.waitForTimeout(2000);
await page.waitForTimeout(1000);
{
const element = await page.getByRole('tooltip');
const downloadTooltip = await element.getByText('Download').count();
@@ -45,8 +45,7 @@ test('create one workspace in the workspace list', async ({
expect(workspaceCards.length).toBe(2);
//check page list length
const closeWorkspaceModal = page.getByTestId('close-workspace-modal');
await closeWorkspaceModal.click();
await page.keyboard.press('Escape');
await clickSideBarAllPageButton(page);
await page.waitForTimeout(1000);
const pageList = page.locator('[data-testid=page-list-item]');
@@ -91,6 +90,7 @@ test('create multi workspace in the workspace list', async ({
expect(currentWorkspace.flavour).toContain('local');
await openWorkspaceListModal(page);
await page.waitForTimeout(1000);
const sourceElement = page.getByTestId('draggable-item').nth(2);
const targetElement = page.getByTestId('draggable-item').nth(1);
+4 -2
View File
@@ -16,12 +16,14 @@ export async function createWorkspace(
await openWorkspaceListModal(page);
// open create workspace modal
await page.locator('.add-icon').click();
await page.getByTestId('new-workspace').click();
// input workspace name
await page.getByPlaceholder('Set a Workspace name').click();
await page.getByPlaceholder('Set a Workspace name').fill(params.name);
// click create button
return page.getByRole('button', { name: 'Create' }).click();
return page.getByRole('button', { name: 'Create' }).click({
delay: 500,
});
}