feat:mock workspace-setting

This commit is contained in:
DiamondThree 2023-01-05 16:05:54 +08:00
parent 5f729464a2
commit 4dc61165b2
9 changed files with 160 additions and 122 deletions

View File

@ -2,7 +2,11 @@ import { styled } from '@/styles';
import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal';
import { Button } from '@/ui/button';
import { useEffect, useState } from 'react';
import { getWorkspaceList, Workspace } from '@/hooks/mock-data/mock';
import {
getWorkspaces,
Workspace,
setActiveWorkspace,
} from '@/hooks/mock-data/mock';
import { CreateWorkspaceModal } from '../create-workspace';
interface LoginModalProps {
@ -19,7 +23,7 @@ export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
}, []);
const getList = () => {
const data = getWorkspaceList();
const data = getWorkspaces();
setWorkspaceList(data);
};
return (
@ -40,11 +44,16 @@ export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
<WorkspaceList>
{workspaceList.map(item => {
return (
<WorkspaceItem key={item.id}>
<span></span>
<WorkspaceItem
onClick={() => {
setActiveWorkspace(item);
onClose();
}}
key={item.id}
>
<span>{item.name}</span>/
{item.type === 'local' && <b>local</b>}
{item.type === 'share' && <b>share</b>}/
{item.type === 'join' && <b>join</b>}/
{item.isPublish ? 'isPublish' : 'isPrivate'}/
{item.isLocal ? 'isLocal' : ''}/
</WorkspaceItem>
@ -70,6 +79,7 @@ export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
onClose={() => {
setCreateWorkspaceOpen(false);
getList();
onClose();
}}
></CreateWorkspaceModal>
</ModalWrapper>

View File

@ -9,25 +9,22 @@ import { StyledSettingH2 } from '../style';
import { useState } from 'react';
import { Button } from '@/ui/button';
import Input from '@/ui/input';
import { getDataCenter, Workspace, WorkspaceType } from '@affine/datacenter';
import { getDataCenter } from '@affine/datacenter';
import { useAppState } from '@/providers/app-state-provider';
import { WorkspaceDetails } from '@/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent';
import { WorkspaceDelete } from './delete';
import { Workspace as StoreWorkspace } from '@blocksuite/store';
import { debounce } from '@/utils';
import { WorkspaceLeave } from './leave';
import { Upload } from '@/components/file-upload';
import { Workspace } from '@/hooks/mock-data/mock';
export const GeneralPage = ({
workspace,
owner,
}: {
workspace: Workspace;
owner: WorkspaceDetails[string]['owner'];
workspaces: Record<string, StoreWorkspace | null>;
}) => {
const {
user,
currentWorkspace,
workspacesMeta,
workspaces,
@ -36,14 +33,11 @@ export const GeneralPage = ({
const [showDelete, setShowDelete] = useState<boolean>(false);
const [showLeave, setShowLeave] = useState<boolean>(false);
const [uploading, setUploading] = useState<boolean>(false);
const [workspaceName, setWorkspaceName] = useState<string>(
workspaces[workspace.id]?.meta.name ||
(workspace.type === WorkspaceType.Private && user ? user.name : '')
);
const [workspaceName, setWorkspaceName] = useState<string>('');
const debouncedRefreshWorkspacesMeta = debounce(() => {
refreshWorkspacesMeta();
}, 100);
const isOwner = user && owner.id === user.id;
const isOwner = true;
const handleChangeWorkSpaceName = (newName: string) => {
setWorkspaceName(newName);
currentWorkspace?.meta.setName(newName);
@ -119,7 +113,6 @@ export const GeneralPage = ({
width={327}
value={workspaceName}
placeholder="Workspace Name"
disabled={!isOwner}
maxLength={14}
minLength={1}
onChange={handleChangeWorkSpaceName}
@ -130,7 +123,7 @@ export const GeneralPage = ({
<Input
width={327}
disabled
value={owner.name}
// value={owner.name}
placeholder="Workspace Owner"
></Input>
</StyledSettingInputContainer>

View File

@ -36,14 +36,14 @@ import { useCallback, useEffect, useState } from 'react';
import { Button, IconButton } from '@/ui/button';
import Input from '@/ui/input';
import { InviteMembers } from '../invite-members/index';
import { Workspace, Member, getDataCenter } from '@affine/datacenter';
import { Member, getDataCenter } from '@affine/datacenter';
import { Avatar } from '@mui/material';
import { Menu, MenuItem } from '@/ui/menu';
import { toast } from '@/ui/toast';
import { Empty } from '@/ui/empty';
import { useAppState } from '@/providers/app-state-provider';
import { WorkspaceDetails } from '../workspace-slider-bar/WorkspaceSelector/SelectorPopperContent';
import { GeneralPage } from './general';
import { getActiveWorkspace, Workspace } from '@/hooks/mock-data/mock';
enum ActiveTab {
'general' = 'general',
@ -59,8 +59,6 @@ type SettingTabProps = {
type WorkspaceSettingProps = {
isShow: boolean;
onClose?: () => void;
workspace: Workspace;
owner: WorkspaceDetails[string]['owner'];
};
const WorkspaceSettingTab = ({ activeTab, onTabChange }: SettingTabProps) => {
@ -106,18 +104,18 @@ const WorkspaceSettingTab = ({ activeTab, onTabChange }: SettingTabProps) => {
export const WorkspaceSetting = ({
isShow,
onClose,
workspace,
owner,
}: WorkspaceSettingProps) => {
const { user, workspaces } = useAppState();
const { workspaces } = useAppState();
const [activeTab, setActiveTab] = useState<ActiveTab>(ActiveTab.general);
const handleTabChange = (tab: ActiveTab) => {
setActiveTab(tab);
};
const workspace = getActiveWorkspace();
const handleClickClose = () => {
onClose && onClose();
};
const isOwner = user && owner.id === user.id;
const isOwner = true;
useEffect(() => {
// reset tab when modal is closed
if (!isShow) {
@ -125,7 +123,7 @@ export const WorkspaceSetting = ({
}
}, [isShow]);
return (
<Modal open={isShow}>
<Modal open={false}>
<StyledSettingContainer>
<ModalCloseButton onClick={handleClickClose} />
{isOwner ? (
@ -141,11 +139,7 @@ export const WorkspaceSetting = ({
) : null}
<StyledSettingContent>
{activeTab === ActiveTab.general && (
<GeneralPage
workspace={workspace}
owner={owner}
workspaces={workspaces}
/>
<GeneralPage workspace={workspace} workspaces={workspaces} />
)}
{activeTab === ActiveTab.members && workspace && (
<MembersPage workspace={workspace} />
@ -295,7 +289,7 @@ const MembersPage = ({ workspace }: { workspace: Workspace }) => {
const PublishPage = ({ workspace }: { workspace: Workspace }) => {
const shareUrl = window.location.host + '/workspace/' + workspace.id;
const [publicStatus, setPublicStatus] = useState<boolean | null>(
workspace.public
workspace.isPublish ?? false
);
const togglePublic = (flag: boolean) => {
getDataCenter()

View File

@ -130,16 +130,16 @@ export const SelectorPopperContent = ({
<CreateWorkspaceItem />
{settingWorkspace ? (
<WorkspaceSetting
isShow={Boolean(settingWorkspaceId)}
isShow={false}
onClose={handleCloseWorkSpace}
workspace={settingWorkspace}
owner={
(settingWorkspaceId &&
workSpaceDetails[settingWorkspaceId]?.owner) || {
id: user.id,
name: user.name,
}
}
// workspace={settingWorkspace}
// owner={
// (settingWorkspaceId &&
// workSpaceDetails[settingWorkspaceId]?.owner) || {
// id: user.id,
// name: user.name,
// }
// }
/>
) : null}
<StyledDivider />

View File

@ -1,53 +1,46 @@
import { Popper } from '@/ui/popper';
import { Avatar, WorkspaceName, SelectorWrapper } from './styles';
import { SelectorPopperContent } from './SelectorPopperContent';
import { useState } from 'react';
import { useAppState } from '@/providers/app-state-provider';
import { WorkspaceType } from '@affine/datacenter';
import { useEffect, useState } from 'react';
import { AffineIcon } from '../icons/icons';
import { WorkspaceModal } from '@/components/workspace-modal';
import { getActiveWorkspace } from '@/hooks/mock-data/mock';
export const WorkspaceSelector = () => {
const [isShow, setIsShow] = useState(false);
const { currentWorkspace, workspacesMeta, currentWorkspaceId, user } =
useAppState();
const workspaceMeta = workspacesMeta.find(
meta => String(meta.id) === String(currentWorkspaceId)
);
const [workspaceListShow, setWorkspaceListShow] = useState(false);
const [workspace, setWorkSpace] = useState(getActiveWorkspace());
useEffect(() => {
getWorkspace();
}, [workspaceListShow]);
const getWorkspace = () => {
const workspace = getActiveWorkspace();
setWorkSpace(workspace);
};
return (
<Popper
content={<SelectorPopperContent isShow={isShow} />}
zIndex={1000}
placement="bottom-start"
trigger="click"
onVisibleChange={setIsShow}
<>
<SelectorWrapper
onClick={() => {
setWorkspaceListShow(true);
}}
data-testid="current-workspace"
>
<SelectorWrapper data-testid="current-workspace">
<Avatar
alt="Affine"
data-testid="workspace-avatar"
src={
workspaceMeta?.type === WorkspaceType.Private
? user
? user.avatar_url
: ''
: currentWorkspace?.meta.avatar &&
`/api/blob/${currentWorkspace?.meta.avatar}`
}
src={workspace.avatar}
>
{workspaceMeta?.type === WorkspaceType.Private && user ? (
user?.name[0]
) : (
<AffineIcon />
)}
</Avatar>
<WorkspaceName data-testid="workspace-name">
{workspaceMeta?.type === WorkspaceType.Private
? user
? user.name
: 'AFFiNE'
: currentWorkspace?.meta.name || 'AFFiNE'}
{workspace?.name ?? 'AFFiNE'}
</WorkspaceName>
</SelectorWrapper>
</Popper>
<WorkspaceModal
open={workspaceListShow}
onClose={() => {
setWorkspaceListShow(false);
getWorkspace();
}}
></WorkspaceModal>
</>
);
};

View File

@ -21,6 +21,7 @@ import {
ImportIcon,
TrashIcon,
AddIcon,
SettingsIcon,
} from '@blocksuite/icons';
import Link from 'next/link';
import { Tooltip } from '@/ui/tooltip';
@ -31,6 +32,7 @@ import { IconButton } from '@/ui/button';
import useLocalStorage from '@/hooks/use-local-storage';
import usePageMetaList from '@/hooks/use-page-meta-list';
import { usePageHelper } from '@/hooks/use-page-helper';
import { WorkspaceSetting } from '@/components/workspace-setting';
const FavoriteList = ({ showList }: { showList: boolean }) => {
const { openPage } = usePageHelper();
@ -146,6 +148,20 @@ export const WorkSpaceSliderBar = () => {
</IconButton>
</StyledListItem>
<FavoriteList showList={showSubFavorite} />
<StyledListItem
onClick={() => {
console.log('ttt');
}}
>
<SettingsIcon /> Setting
</StyledListItem>
<WorkspaceSetting
isShow={true}
onClose={() => {
console.log(1231231);
}}
/>
<StyledListItem
onClick={() => {

View File

@ -4,7 +4,7 @@ export interface Workspace {
isPublish?: boolean; // 是否公开
isLocal?: boolean; // 是否全部数据都在本地
avatar?: string; // 封面
type: 'local' | 'cloud' | 'share'; // cloud: 云端本次暂不支持local: 本地share: 分享
type: 'local' | 'cloud' | 'join'; // cloud: 云端本次暂不支持local: 本地join : 加入别人的
workspaceOwner?: User; // 本地工作空间的拥有者
}
@ -15,45 +15,15 @@ interface User {
avatar: string;
}
export function getWorkspaceList(): Workspace[] {
const workspacesMeta = JSON.parse(
localStorage.getItem('affine-workspace') ?? '[]'
);
return workspacesMeta;
}
export function getPagesByWorkspaceId(workspaceId: string) {
if (!workspaceId) return [];
const workspacesMeta = [];
for (let i = 0; i < 10; i++) {
workspacesMeta.push({
id: 'page-' + i,
name: 'page ' + i,
});
}
}
export function addWorkSpace(workspaceData: Workspace) {
const workspacesMeta = getWorkspaceList();
workspacesMeta.push(workspaceData);
localStorage.setItem('affine-workspace', JSON.stringify(workspacesMeta));
}
export function deleteWorkspaceById(workspaceId: string) {
const workspacesMeta = getWorkspaceList();
const newWorkspacesMeta = workspacesMeta.filter(() => {
return workspaceId !== workspaceId;
});
localStorage.setItem('affine-workspace', JSON.stringify(newWorkspacesMeta));
}
export function updateWorkspaceById(
export function updateWorkspaceMeta(
workspaceId: string,
workspaceData: Workspace
) {
const workspacesMeta = getWorkspaceList();
const workspacesMeta = getWorkspaces();
const newWorkspacesMeta = workspacesMeta.map((workspace: Workspace) => {
if (workspace.id === workspaceId) {
workspaceData.name && (workspace.name = workspaceData.name);
workspaceData.avatar && (workspace.avatar = workspaceData.avatar);
return workspaceData;
}
return workspace;
@ -69,7 +39,73 @@ export function createWorkspace(workspaceName: string) {
avatar: '',
type: 'local',
} as Workspace;
const workspacesMeta = getWorkspaceList();
const workspacesMeta = getWorkspaces();
workspacesMeta.push(workspaceData);
localStorage.setItem('affine-workspace', JSON.stringify(workspacesMeta));
setActiveWorkspace(workspaceData);
}
export function getWorkspaces(): Workspace[] {
const workspacesMeta = JSON.parse(
localStorage.getItem('affine-workspace') ?? '[]'
);
return workspacesMeta;
}
export function deleteWorkspace(workspaceId: string) {
const workspacesMeta = getWorkspaces();
const newWorkspacesMeta = workspacesMeta.filter(() => {
return workspaceId !== workspaceId;
});
localStorage.setItem('affine-workspace', JSON.stringify(newWorkspacesMeta));
}
export function getMembers(id: string): User[] {
const memberMap = JSON.parse(localStorage.getItem('affine-member') ?? '{}');
return memberMap[id] || [];
}
export function leaveWorkspace(id: string) {
return true;
}
export function setWorkspacePublish(id: string, isPublish: boolean): boolean {
const workspacesMeta = getWorkspaces();
const newWorkspacesMeta = workspacesMeta.map((workspace: Workspace) => {
if (workspace.id === id) {
workspace.isPublish = isPublish;
}
return workspace;
});
localStorage.setItem('affine-workspace', JSON.stringify(newWorkspacesMeta));
return isPublish;
}
export function getWorkspaceById(id: string) {
const workspacesMeta = getWorkspaces();
return workspacesMeta.find((workspace: Workspace) => {
return workspace.id === id;
});
}
export function getPagesByWorkspaceId(workspaceId: string) {
if (!workspaceId) return [];
const workspacesMeta = [];
for (let i = 0; i < 10; i++) {
workspacesMeta.push({
id: 'page-' + i,
name: 'page ' + i,
});
}
}
export function getActiveWorkspace(): Workspace {
return JSON.parse(localStorage.getItem('affine-active-workspace') ?? '{}');
}
export function setActiveWorkspace(workspaceData: Workspace) {
localStorage.setItem(
'affine-active-workspace',
JSON.stringify(workspaceData)
);
}

View File

@ -1,14 +1,14 @@
import { WorkspaceModal } from '@/components/workspace-modal';
import { getWorkspaceList } from '@/hooks/mock-data/mock';
import { getWorkspaces } from '@/hooks/mock-data/mock';
import { useEffect, useState } from 'react';
import { styled } from '@/styles';
import Button from '@/ui/button/Button';
const Page = () => {
const [open, setOpen] = useState<boolean>(true);
const [open, setOpen] = useState<boolean>(false);
useEffect(() => {
const data = getWorkspaceList();
const data = getWorkspaces();
if (!data.length) {
setOpen(true);
}

View File

@ -40,14 +40,10 @@ export interface AppStateContext extends AppStateValue {
export const AppState = createContext<AppStateContext>({
user: null,
workspacesMeta: [],
currentWorkspaceId: '',
currentWorkspace: null,
currentPage: null,
editor: null,
// eslint-disable-next-line @typescript-eslint/no-empty-function
setState: () => {},
createEditor: undefined,