mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-30 00:29:46 +08:00
feat: improve the ui of workspace item
This commit is contained in:
@@ -6,6 +6,10 @@ import {
|
|||||||
getWorkspaces,
|
getWorkspaces,
|
||||||
Workspace,
|
Workspace,
|
||||||
setActiveWorkspace,
|
setActiveWorkspace,
|
||||||
|
Login,
|
||||||
|
User,
|
||||||
|
getUserInfo,
|
||||||
|
SignOut,
|
||||||
} from '@/hooks/mock-data/mock';
|
} from '@/hooks/mock-data/mock';
|
||||||
import { CreateWorkspaceModal } from '../create-workspace';
|
import { CreateWorkspaceModal } from '../create-workspace';
|
||||||
import {
|
import {
|
||||||
@@ -13,6 +17,8 @@ import {
|
|||||||
CloudInsyncIcon,
|
CloudInsyncIcon,
|
||||||
UsersIcon,
|
UsersIcon,
|
||||||
} from '@blocksuite/icons';
|
} from '@blocksuite/icons';
|
||||||
|
import { useConfirm } from '@/providers/confirm-provider';
|
||||||
|
import { toast } from '@/ui/toast';
|
||||||
|
|
||||||
interface LoginModalProps {
|
interface LoginModalProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -21,20 +27,29 @@ interface LoginModalProps {
|
|||||||
|
|
||||||
export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
|
export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
|
||||||
const [workspaceList, setWorkspaceList] = useState<Workspace[]>([]);
|
const [workspaceList, setWorkspaceList] = useState<Workspace[]>([]);
|
||||||
|
const [user, setUser] = useState<User | null>();
|
||||||
const [createWorkspaceOpen, setCreateWorkspaceOpen] = useState(false);
|
const [createWorkspaceOpen, setCreateWorkspaceOpen] = useState(false);
|
||||||
|
const { confirm } = useConfirm();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getList();
|
setList();
|
||||||
|
setUserInfo();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const getList = () => {
|
const setList = () => {
|
||||||
const data = getWorkspaces();
|
const data = getWorkspaces();
|
||||||
setWorkspaceList(data);
|
setWorkspaceList(data);
|
||||||
};
|
};
|
||||||
|
const setUserInfo = () => {
|
||||||
|
const data = getUserInfo();
|
||||||
|
setUser(data);
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Modal open={open} onClose={onClose}>
|
<Modal open={open} onClose={onClose}>
|
||||||
<ModalWrapper width={820} style={{ padding: '10px' }}>
|
<ModalWrapper
|
||||||
|
width={820}
|
||||||
|
style={{ padding: '10px', display: 'flex', flexDirection: 'column' }}
|
||||||
|
>
|
||||||
<Header>
|
<Header>
|
||||||
<ContentTitle>My Workspaces</ContentTitle>
|
<ContentTitle>My Workspaces</ContentTitle>
|
||||||
<ModalCloseButton
|
<ModalCloseButton
|
||||||
@@ -111,20 +126,47 @@ export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
|
|||||||
</Button>
|
</Button>
|
||||||
</li>
|
</li>
|
||||||
</WorkspaceList>
|
</WorkspaceList>
|
||||||
</Content>
|
|
||||||
<Footer>
|
|
||||||
<p style={{ fontSize: '14px', color: '#ccc', margin: '12px 0' }}>
|
<p style={{ fontSize: '14px', color: '#ccc', margin: '12px 0' }}>
|
||||||
Tips:Workspace is your virtual space to capture, create and plan
|
Tips:Workspace is your virtual space to capture, create and plan
|
||||||
as just one person or together as a team.
|
as just one person or together as a team.
|
||||||
</p>
|
</p>
|
||||||
<Button>Sign in AFFiNE Cloud</Button>
|
</Content>
|
||||||
|
<Footer>
|
||||||
|
{!user ? (
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
Login();
|
||||||
|
toast('login success');
|
||||||
|
setUserInfo();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Sign in AFFiNE Cloud
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
SignOut();
|
||||||
|
setUserInfo();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Sign out of AFFiNE Cloud
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</Footer>
|
</Footer>
|
||||||
<CreateWorkspaceModal
|
<CreateWorkspaceModal
|
||||||
open={createWorkspaceOpen}
|
open={createWorkspaceOpen}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setCreateWorkspaceOpen(false);
|
setCreateWorkspaceOpen(false);
|
||||||
getList();
|
setList();
|
||||||
onClose();
|
onClose();
|
||||||
|
confirm({
|
||||||
|
title: 'Enable AFFiNE Cloud?',
|
||||||
|
content: `If enabled, the data in this workspace will be backed up and synchronized via AFFiNE Cloud.`,
|
||||||
|
confirmText: user ? 'Enable' : 'Sign in and Enable',
|
||||||
|
cancelText: 'Skip',
|
||||||
|
}).then(confirm => {
|
||||||
|
confirm && Login();
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
></CreateWorkspaceModal>
|
></CreateWorkspaceModal>
|
||||||
</ModalWrapper>
|
</ModalWrapper>
|
||||||
@@ -143,6 +185,7 @@ const Content = styled('div')({
|
|||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: '16px',
|
gap: '16px',
|
||||||
|
flex: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
const ContentTitle = styled('span')({
|
const ContentTitle = styled('span')({
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { Workspace as StoreWorkspace } from '@blocksuite/store';
|
|||||||
import { debounce } from '@/utils';
|
import { debounce } from '@/utils';
|
||||||
import { WorkspaceLeave } from './leave';
|
import { WorkspaceLeave } from './leave';
|
||||||
import { Upload } from '@/components/file-upload';
|
import { Upload } from '@/components/file-upload';
|
||||||
import { Workspace } from '@/hooks/mock-data/mock';
|
import { getUserInfo, Workspace } from '@/hooks/mock-data/mock';
|
||||||
|
|
||||||
export const GeneralPage = ({
|
export const GeneralPage = ({
|
||||||
workspace,
|
workspace,
|
||||||
@@ -30,6 +30,7 @@ export const GeneralPage = ({
|
|||||||
workspaces,
|
workspaces,
|
||||||
refreshWorkspacesMeta,
|
refreshWorkspacesMeta,
|
||||||
} = useAppState();
|
} = useAppState();
|
||||||
|
// const user = getUserInfo();
|
||||||
const [showDelete, setShowDelete] = useState<boolean>(false);
|
const [showDelete, setShowDelete] = useState<boolean>(false);
|
||||||
const [showLeave, setShowLeave] = useState<boolean>(false);
|
const [showLeave, setShowLeave] = useState<boolean>(false);
|
||||||
const [uploading, setUploading] = useState<boolean>(false);
|
const [uploading, setUploading] = useState<boolean>(false);
|
||||||
@@ -38,11 +39,9 @@ export const GeneralPage = ({
|
|||||||
refreshWorkspacesMeta();
|
refreshWorkspacesMeta();
|
||||||
}, 100);
|
}, 100);
|
||||||
const isOwner = true;
|
const isOwner = true;
|
||||||
|
|
||||||
const handleChangeWorkSpaceName = (newName: string) => {
|
const handleChangeWorkSpaceName = (newName: string) => {
|
||||||
setWorkspaceName(newName);
|
setWorkspaceName(newName);
|
||||||
currentWorkspace?.meta.setName(newName);
|
|
||||||
workspaces[workspace.id]?.meta.setName(newName);
|
|
||||||
debouncedRefreshWorkspacesMeta();
|
|
||||||
};
|
};
|
||||||
const currentWorkspaceIndex = workspacesMeta.findIndex(
|
const currentWorkspaceIndex = workspacesMeta.findIndex(
|
||||||
meta => meta.id === workspace.id
|
meta => meta.id === workspace.id
|
||||||
|
|||||||
@@ -43,7 +43,11 @@ import { toast } from '@/ui/toast';
|
|||||||
import { Empty } from '@/ui/empty';
|
import { Empty } from '@/ui/empty';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
import { useAppState } from '@/providers/app-state-provider';
|
||||||
import { GeneralPage } from './general';
|
import { GeneralPage } from './general';
|
||||||
import { getActiveWorkspace, Workspace } from '@/hooks/mock-data/mock';
|
import {
|
||||||
|
getActiveWorkspace,
|
||||||
|
setWorkspacePublish,
|
||||||
|
Workspace,
|
||||||
|
} from '@/hooks/mock-data/mock';
|
||||||
|
|
||||||
enum ActiveTab {
|
enum ActiveTab {
|
||||||
'general' = 'general',
|
'general' = 'general',
|
||||||
@@ -112,6 +116,7 @@ export const WorkspaceSetting = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const workspace = getActiveWorkspace();
|
const workspace = getActiveWorkspace();
|
||||||
|
console.log('workspace: ', workspace);
|
||||||
const handleClickClose = () => {
|
const handleClickClose = () => {
|
||||||
onClose && onClose();
|
onClose && onClose();
|
||||||
};
|
};
|
||||||
@@ -123,7 +128,7 @@ export const WorkspaceSetting = ({
|
|||||||
}
|
}
|
||||||
}, [isShow]);
|
}, [isShow]);
|
||||||
return (
|
return (
|
||||||
<Modal open={false}>
|
<Modal open={isShow}>
|
||||||
<StyledSettingContainer>
|
<StyledSettingContainer>
|
||||||
<ModalCloseButton onClick={handleClickClose} />
|
<ModalCloseButton onClick={handleClickClose} />
|
||||||
{isOwner ? (
|
{isOwner ? (
|
||||||
@@ -287,23 +292,16 @@ const MembersPage = ({ workspace }: { workspace: Workspace }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const PublishPage = ({ workspace }: { workspace: Workspace }) => {
|
const PublishPage = ({ workspace }: { workspace: Workspace }) => {
|
||||||
const shareUrl = window.location.host + '/workspace/' + workspace.id;
|
const shareUrl =
|
||||||
|
window.location.host + '/workspace/' + workspace.id + '?share=true';
|
||||||
const [publicStatus, setPublicStatus] = useState<boolean | null>(
|
const [publicStatus, setPublicStatus] = useState<boolean | null>(
|
||||||
workspace.isPublish ?? false
|
workspace.isPublish ?? false
|
||||||
);
|
);
|
||||||
const togglePublic = (flag: boolean) => {
|
const togglePublic = (flag: boolean) => {
|
||||||
getDataCenter()
|
const isPublic = setWorkspacePublish(workspace.id, flag);
|
||||||
.then(dc =>
|
setPublicStatus(isPublic);
|
||||||
dc.apis.updateWorkspace({
|
|
||||||
id: workspace.id,
|
|
||||||
public: flag,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.then(data => {
|
|
||||||
setPublicStatus(data?.public);
|
|
||||||
toast('Updated Public Status Success');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const copyUrl = () => {
|
const copyUrl = () => {
|
||||||
navigator.clipboard.writeText(shareUrl);
|
navigator.clipboard.writeText(shareUrl);
|
||||||
toast('Copied url to clipboard');
|
toast('Copied url to clipboard');
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ export const WorkSpaceSliderBar = () => {
|
|||||||
const [showTip, setShowTip] = useState(false);
|
const [showTip, setShowTip] = useState(false);
|
||||||
const [show, setShow] = useLocalStorage('AFFiNE_SLIDE_BAR', false, true);
|
const [show, setShow] = useLocalStorage('AFFiNE_SLIDE_BAR', false, true);
|
||||||
|
|
||||||
|
const [showWorkspaceSetting, setShowWorkspaceSetting] = useState(false);
|
||||||
|
|
||||||
const paths = {
|
const paths = {
|
||||||
all: currentWorkspaceId ? `/workspace/${currentWorkspaceId}/all` : '',
|
all: currentWorkspaceId ? `/workspace/${currentWorkspaceId}/all` : '',
|
||||||
favorite: currentWorkspaceId
|
favorite: currentWorkspaceId
|
||||||
@@ -150,16 +152,16 @@ export const WorkSpaceSliderBar = () => {
|
|||||||
<FavoriteList showList={showSubFavorite} />
|
<FavoriteList showList={showSubFavorite} />
|
||||||
<StyledListItem
|
<StyledListItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
console.log('ttt');
|
setShowWorkspaceSetting(true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SettingsIcon /> Setting
|
<SettingsIcon /> Setting
|
||||||
</StyledListItem>
|
</StyledListItem>
|
||||||
|
|
||||||
<WorkspaceSetting
|
<WorkspaceSetting
|
||||||
isShow={true}
|
isShow={showWorkspaceSetting}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
console.log(1231231);
|
setShowWorkspaceSetting(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ export const StyledListItem = styled.div<{
|
|||||||
color: active ? theme.colors.primaryColor : theme.colors.popoverColor,
|
color: active ? theme.colors.primaryColor : theme.colors.popoverColor,
|
||||||
paddingLeft: '12px',
|
paddingLeft: '12px',
|
||||||
borderRadius: '5px',
|
borderRadius: '5px',
|
||||||
|
cursor: 'pointer',
|
||||||
...displayFlex('flex-start', 'center'),
|
...displayFlex('flex-start', 'center'),
|
||||||
...(disabled
|
...(disabled
|
||||||
? {
|
? {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export interface Workspace {
|
|||||||
workspaceOwner?: User; // 本地工作空间的拥有者
|
workspaceOwner?: User; // 本地工作空间的拥有者
|
||||||
}
|
}
|
||||||
|
|
||||||
interface User {
|
export interface User {
|
||||||
name: string;
|
name: string;
|
||||||
id: string;
|
id: string;
|
||||||
email: string;
|
email: string;
|
||||||
@@ -109,3 +109,23 @@ export function setActiveWorkspace(workspaceData: Workspace) {
|
|||||||
JSON.stringify(workspaceData)
|
JSON.stringify(workspaceData)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getUserInfo(): User {
|
||||||
|
return JSON.parse(localStorage.getItem('affine-user') ?? 'null');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Login(): void {
|
||||||
|
localStorage.setItem(
|
||||||
|
'affine-user',
|
||||||
|
JSON.stringify({
|
||||||
|
name: 'Diamond',
|
||||||
|
id: 'ttt',
|
||||||
|
email: 'diamond.shx@gmail.com',
|
||||||
|
avatar: 'string',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SignOut(): void {
|
||||||
|
localStorage.removeItem('affine-user');
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export type ConfirmProps = {
|
|||||||
title?: string;
|
title?: string;
|
||||||
content?: string;
|
content?: string;
|
||||||
confirmText?: string;
|
confirmText?: string;
|
||||||
|
cancelText?: string;
|
||||||
// TODO: Confirm button's color should depend on confirm type
|
// TODO: Confirm button's color should depend on confirm type
|
||||||
confirmType?: 'primary' | 'warning' | 'danger';
|
confirmType?: 'primary' | 'warning' | 'danger';
|
||||||
onConfirm?: () => void;
|
onConfirm?: () => void;
|
||||||
@@ -24,6 +25,7 @@ export const Confirm = ({
|
|||||||
confirmType,
|
confirmType,
|
||||||
onConfirm,
|
onConfirm,
|
||||||
onCancel,
|
onCancel,
|
||||||
|
cancelText = 'Cancel',
|
||||||
}: ConfirmProps) => {
|
}: ConfirmProps) => {
|
||||||
const [open, setOpen] = useState(true);
|
const [open, setOpen] = useState(true);
|
||||||
return (
|
return (
|
||||||
@@ -48,7 +50,7 @@ export const Confirm = ({
|
|||||||
}}
|
}}
|
||||||
style={{ marginRight: '24px' }}
|
style={{ marginRight: '24px' }}
|
||||||
>
|
>
|
||||||
Cancel
|
{cancelText}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type={confirmType}
|
type={confirmType}
|
||||||
|
|||||||
Reference in New Issue
Block a user