mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-16 17:46:18 +08:00
feat: set workspace names
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import Modal, { ModalCloseButton } from '@/ui/modal';
|
||||
import {
|
||||
StyledDeleteButtonContainer,
|
||||
StyledSettingAvatar,
|
||||
StyledSettingAvatarContent,
|
||||
StyledSettingInputContainer,
|
||||
} from './style';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { Button } from '@/ui/button';
|
||||
import Input from '@/ui/input';
|
||||
import { Workspace, WorkspaceType } from '@pathfinder/data-services';
|
||||
import { useAppState } from '@/providers/app-state-provider';
|
||||
import { WorkspaceDetails } from '@/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent';
|
||||
import { StyledSettingH2 } from '../style';
|
||||
export const GeneralPage = ({
|
||||
workspace,
|
||||
owner,
|
||||
}: {
|
||||
workspace: Workspace;
|
||||
owner: WorkspaceDetails[string]['owner'];
|
||||
}) => {
|
||||
const { workspaces, user, currentWorkspace } = useAppState();
|
||||
const [workspaceName, setWorkspaceName] = useState<string>(
|
||||
workspaces[workspace.id]?.meta.name ||
|
||||
(workspace.type === WorkspaceType.Private && user
|
||||
? user.name
|
||||
: `workspace-${workspace?.id}`)
|
||||
);
|
||||
const isOwner = user && owner.id === user.id;
|
||||
const handleChangeWorkSpaceName = (newName: string) => {
|
||||
setWorkspaceName(newName);
|
||||
currentWorkspace?.meta.setName(newName);
|
||||
workspaces[workspace.id]?.meta.setName(newName);
|
||||
};
|
||||
return workspace ? (
|
||||
<div>
|
||||
<StyledSettingH2 marginTop={56}>Workspace Avatar</StyledSettingH2>
|
||||
<StyledSettingAvatarContent>
|
||||
<StyledSettingAvatar
|
||||
alt="workspace avatar"
|
||||
src={workspaces[workspace.id]?.meta.avatar || ''}
|
||||
>
|
||||
W
|
||||
</StyledSettingAvatar>
|
||||
{/* {isOwner ? (
|
||||
<StyledAvatarUploadBtn shape="round">upload</StyledAvatarUploadBtn>
|
||||
) : null} */}
|
||||
{/* <Button shape="round">remove</Button> */}
|
||||
</StyledSettingAvatarContent>
|
||||
<StyledSettingH2 marginTop={36}>Workspace Name</StyledSettingH2>
|
||||
<StyledSettingInputContainer>
|
||||
<Input
|
||||
width={327}
|
||||
value={workspaceName}
|
||||
placeholder="Workspace Name"
|
||||
disabled={!isOwner}
|
||||
maxLength={14}
|
||||
minLength={1}
|
||||
onChange={handleChangeWorkSpaceName}
|
||||
></Input>
|
||||
</StyledSettingInputContainer>
|
||||
<StyledSettingH2 marginTop={36}>Workspace Owner</StyledSettingH2>
|
||||
<StyledSettingInputContainer>
|
||||
<Input
|
||||
width={327}
|
||||
disabled
|
||||
value={owner.name}
|
||||
placeholder="Workspace Owner"
|
||||
></Input>
|
||||
</StyledSettingInputContainer>
|
||||
<StyledDeleteButtonContainer>
|
||||
<Button type="danger" shape="circle">
|
||||
Delete Workspace
|
||||
</Button>
|
||||
</StyledDeleteButtonContainer>
|
||||
</div>
|
||||
) : null;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export * from './general';
|
||||
@@ -0,0 +1,28 @@
|
||||
import { styled } from '@/styles';
|
||||
import MuiAvatar from '@mui/material/Avatar';
|
||||
|
||||
export const StyledSettingInputContainer = styled('div')(({ theme }) => {
|
||||
return {
|
||||
marginTop: '12px',
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledDeleteButtonContainer = styled('div')(({ theme }) => {
|
||||
return {
|
||||
marginTop: '154px',
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledSettingAvatarContent = styled('div')(({ theme }) => {
|
||||
return {
|
||||
marginTop: '12px',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
height: '72px',
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledSettingAvatar = styled(MuiAvatar)(({ theme }) => {
|
||||
return { height: '72px', width: '72px' };
|
||||
});
|
||||
@@ -29,6 +29,7 @@ export const StyledSettingSidebar = styled('div')(({ theme }) => {
|
||||
export const StyledSettingContent = styled('div')(({ theme }) => {
|
||||
return {
|
||||
paddingLeft: '48px',
|
||||
height: '620px',
|
||||
};
|
||||
});
|
||||
|
||||
@@ -103,20 +104,6 @@ export const StyledSettingH2 = styled('h2')<{ marginTop?: number }>(
|
||||
}
|
||||
);
|
||||
|
||||
export const StyledSettingAvatarContent = styled('div')(({ theme }) => {
|
||||
return {
|
||||
marginTop: '12px',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
height: '72px',
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledSettingAvatar = styled(MuiAvatar)(({ theme }) => {
|
||||
return { height: '72px', width: '72px' };
|
||||
});
|
||||
|
||||
export const StyledAvatarUploadBtn = styled(Button)(({ theme }) => {
|
||||
return {
|
||||
backgroundColor: theme.colors.hoverBackground,
|
||||
@@ -125,18 +112,6 @@ export const StyledAvatarUploadBtn = styled(Button)(({ theme }) => {
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledSettingInputContainer = styled('div')(({ theme }) => {
|
||||
return {
|
||||
marginTop: '12px',
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledDeleteButtonContainer = styled('div')(({ theme }) => {
|
||||
return {
|
||||
marginTop: '154px',
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledMemberTitleContainer = styled('div')(({ theme }) => {
|
||||
return {
|
||||
display: 'flex',
|
||||
|
||||
@@ -2,7 +2,6 @@ import Modal, { ModalCloseButton } from '@/ui/modal';
|
||||
import {
|
||||
StyledAvatarUploadBtn,
|
||||
StyledCopyButtonContainer,
|
||||
StyledDeleteButtonContainer,
|
||||
StyledMemberAvatar,
|
||||
StyledMemberButtonContainer,
|
||||
StyledMemberEmail,
|
||||
@@ -17,12 +16,9 @@ import {
|
||||
StyledPublishContent,
|
||||
StyledPublishCopyContainer,
|
||||
StyledPublishExplanation,
|
||||
StyledSettingAvatar,
|
||||
StyledSettingAvatarContent,
|
||||
StyledSettingContainer,
|
||||
StyledSettingContent,
|
||||
StyledSettingH2,
|
||||
StyledSettingInputContainer,
|
||||
StyledSettingSidebar,
|
||||
StyledSettingSidebarHeader,
|
||||
StyledSettingTabContainer,
|
||||
@@ -52,6 +48,10 @@ import { Avatar } from '@mui/material';
|
||||
import { Menu, MenuItem } from '@/ui/menu';
|
||||
import { toast } from '@/ui/toast';
|
||||
import { useConfirm } from '@/providers/confirm-provider';
|
||||
import { useAppState } from '@/providers/app-state-provider';
|
||||
import { WorkspaceDetails } from '../workspace-slider-bar/WorkspaceSelector/SelectorPopperContent';
|
||||
import { GeneralPage } from './general';
|
||||
|
||||
enum ActiveTab {
|
||||
'general' = 'general',
|
||||
'members' = 'members',
|
||||
@@ -66,7 +66,8 @@ type SettingTabProps = {
|
||||
type WorkspaceSettingProps = {
|
||||
isShow: boolean;
|
||||
onClose?: () => void;
|
||||
workspace?: Workspace;
|
||||
workspace: Workspace;
|
||||
owner: WorkspaceDetails[string]['owner'];
|
||||
};
|
||||
|
||||
const WorkspaceSettingTab = ({ activeTab, onTabChange }: SettingTabProps) => {
|
||||
@@ -113,7 +114,9 @@ export const WorkspaceSetting = ({
|
||||
isShow,
|
||||
onClose,
|
||||
workspace,
|
||||
owner,
|
||||
}: WorkspaceSettingProps) => {
|
||||
const { workspaces, user } = useAppState();
|
||||
const [activeTab, setActiveTab] = useState<ActiveTab>(ActiveTab.general);
|
||||
const handleTabChange = (tab: ActiveTab) => {
|
||||
setActiveTab(tab);
|
||||
@@ -121,7 +124,7 @@ export const WorkspaceSetting = ({
|
||||
const handleClickClose = () => {
|
||||
onClose && onClose();
|
||||
};
|
||||
const isPrivate = workspace?.type === WorkspaceType.Private;
|
||||
const isOwner = user && owner.id === user.id;
|
||||
useEffect(() => {
|
||||
// reset tab when modal is closed
|
||||
if (!isShow) {
|
||||
@@ -132,18 +135,20 @@ export const WorkspaceSetting = ({
|
||||
<Modal onClose={onClose} open={isShow}>
|
||||
<StyledSettingContainer>
|
||||
<ModalCloseButton onClick={handleClickClose} />
|
||||
<StyledSettingSidebar>
|
||||
<StyledSettingSidebarHeader>
|
||||
Workspace Settings
|
||||
</StyledSettingSidebarHeader>
|
||||
<WorkspaceSettingTab
|
||||
activeTab={activeTab}
|
||||
onTabChange={handleTabChange}
|
||||
/>
|
||||
</StyledSettingSidebar>
|
||||
{isOwner ? (
|
||||
<StyledSettingSidebar>
|
||||
<StyledSettingSidebarHeader>
|
||||
Workspace Settings
|
||||
</StyledSettingSidebarHeader>
|
||||
<WorkspaceSettingTab
|
||||
activeTab={activeTab}
|
||||
onTabChange={handleTabChange}
|
||||
/>
|
||||
</StyledSettingSidebar>
|
||||
) : null}
|
||||
<StyledSettingContent>
|
||||
{activeTab === ActiveTab.general && (
|
||||
<GeneralPage workspace={workspace} />
|
||||
<GeneralPage workspace={workspace} owner={owner} />
|
||||
)}
|
||||
{activeTab === ActiveTab.members && workspace && (
|
||||
<MembersPage workspace={workspace} />
|
||||
@@ -155,32 +160,6 @@ export const WorkspaceSetting = ({
|
||||
);
|
||||
};
|
||||
|
||||
const GeneralPage = ({ workspace }: { workspace?: Workspace }) => {
|
||||
return (
|
||||
<div>
|
||||
<StyledSettingH2 marginTop={56}>Workspace Avatar</StyledSettingH2>
|
||||
<StyledSettingAvatarContent>
|
||||
<StyledSettingAvatar alt="workspace avatar">W</StyledSettingAvatar>
|
||||
{/* <StyledAvatarUploadBtn shape="round">upload</StyledAvatarUploadBtn>
|
||||
<Button shape="round">remove</Button> */}
|
||||
</StyledSettingAvatarContent>
|
||||
<StyledSettingH2 marginTop={36}>Workspace Name</StyledSettingH2>
|
||||
<StyledSettingInputContainer>
|
||||
<Input width={327} placeholder="Workspace Name"></Input>
|
||||
</StyledSettingInputContainer>
|
||||
<StyledSettingH2 marginTop={36}>Workspace Owner</StyledSettingH2>
|
||||
<StyledSettingInputContainer>
|
||||
<Input width={327} placeholder="Workspace Owner"></Input>
|
||||
</StyledSettingInputContainer>
|
||||
<StyledDeleteButtonContainer>
|
||||
<Button type="danger" shape="circle">
|
||||
Delete Workspace
|
||||
</Button>
|
||||
</StyledDeleteButtonContainer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const MembersPage = ({ workspace }: { workspace: Workspace }) => {
|
||||
const [isInviteModalShow, setIsInviteModalShow] = useState(false);
|
||||
const [members, setMembers] = useState<Member[]>([]);
|
||||
|
||||
+21
-13
@@ -14,7 +14,7 @@ import { WorkspaceSetting } from '@/components/workspace-setting';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { getWorkspaceDetail, WorkspaceType } from '@pathfinder/data-services';
|
||||
|
||||
type WorkspaceDetails = Record<
|
||||
export type WorkspaceDetails = Record<
|
||||
string,
|
||||
{ memberCount: number; owner: { id: string; name: string } }
|
||||
>;
|
||||
@@ -39,6 +39,9 @@ export const SelectorPopperContent = ({
|
||||
const handleCloseWorkSpace = () => {
|
||||
setSettingWorkspaceId(null);
|
||||
};
|
||||
const settingWorkspace = settingWorkspaceId
|
||||
? workspacesMeta.find(workspace => workspace.id === settingWorkspaceId)
|
||||
: undefined;
|
||||
|
||||
const refreshDetails = useCallback(async () => {
|
||||
const workspaceDetailList = await Promise.all(
|
||||
@@ -103,7 +106,9 @@ export const SelectorPopperContent = ({
|
||||
onClick={handleClickSettingWorkspace}
|
||||
name={
|
||||
workspaces[workspace.id]?.meta.name ||
|
||||
`workspace-${workspace.id}`
|
||||
(workspace.type === WorkspaceType.Private
|
||||
? user.name
|
||||
: `workspace-${workspace.id}`)
|
||||
}
|
||||
memberCount={workSpaceDetails[workspace.id]?.memberCount || 1}
|
||||
/>
|
||||
@@ -111,17 +116,20 @@ export const SelectorPopperContent = ({
|
||||
})}
|
||||
</WorkspaceWrapper>
|
||||
<CreateWorkspaceItem />
|
||||
<WorkspaceSetting
|
||||
isShow={Boolean(settingWorkspaceId)}
|
||||
onClose={handleCloseWorkSpace}
|
||||
workspace={
|
||||
settingWorkspaceId
|
||||
? workspacesMeta.find(
|
||||
workspace => workspace.id === settingWorkspaceId
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
{settingWorkspace ? (
|
||||
<WorkspaceSetting
|
||||
isShow={Boolean(settingWorkspaceId)}
|
||||
onClose={handleCloseWorkSpace}
|
||||
workspace={settingWorkspace}
|
||||
owner={
|
||||
(settingWorkspaceId &&
|
||||
workSpaceDetails[settingWorkspaceId]?.owner) || {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
}
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
<StyledDivider />
|
||||
<ListItem
|
||||
icon={<InformationIcon />}
|
||||
|
||||
+10
-5
@@ -8,6 +8,7 @@ import {
|
||||
import { FooterSetting } from './FooterSetting';
|
||||
import { FooterUsers } from './FooterUsers';
|
||||
import { WorkspaceType } from '@pathfinder/data-services';
|
||||
import { useAppState } from '@/providers/app-state-provider';
|
||||
|
||||
interface WorkspaceItemProps {
|
||||
id: string;
|
||||
@@ -28,6 +29,8 @@ export const WorkspaceItem = ({
|
||||
}: WorkspaceItemProps) => {
|
||||
const router = useRouter();
|
||||
|
||||
const { currentWorkspaceId } = useAppState();
|
||||
|
||||
const handleClickSetting = async () => {
|
||||
onClick && onClick(id);
|
||||
};
|
||||
@@ -37,7 +40,9 @@ export const WorkspaceItem = ({
|
||||
onClick={() => {
|
||||
router.push(`/workspace/${id}`);
|
||||
}}
|
||||
isPrivate={type === WorkspaceType.Private}
|
||||
canSet={
|
||||
type !== WorkspaceType.Private && currentWorkspaceId === String(id)
|
||||
}
|
||||
>
|
||||
<WorkspaceItemAvatar alt={name} src={icon}>
|
||||
{name.charAt(0)}
|
||||
@@ -64,17 +69,17 @@ const Name = styled('div')(({ theme }) => {
|
||||
};
|
||||
});
|
||||
|
||||
const StyledWrapper = styled(WorkspaceItemWrapper)<{ isPrivate: boolean }>(
|
||||
({ isPrivate }) => {
|
||||
const StyledWrapper = styled(WorkspaceItemWrapper)<{ canSet: boolean }>(
|
||||
({ canSet }) => {
|
||||
return {
|
||||
'& .footer-setting': {
|
||||
display: 'none',
|
||||
},
|
||||
':hover .footer-users': {
|
||||
display: isPrivate ? 'block' : 'none',
|
||||
display: canSet ? 'none' : '',
|
||||
},
|
||||
':hover .footer-setting': {
|
||||
display: isPrivate ? 'none' : 'block',
|
||||
display: canSet ? 'block' : 'none',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ type inputProps = {
|
||||
disabled?: boolean;
|
||||
width?: number;
|
||||
maxLength?: number;
|
||||
minLength?: number;
|
||||
onChange?: (value: string) => void;
|
||||
onBlur?: (e: any) => void;
|
||||
};
|
||||
@@ -17,6 +18,7 @@ export const Input = (props: inputProps) => {
|
||||
value: valueProp,
|
||||
placeholder,
|
||||
maxLength,
|
||||
minLength,
|
||||
width = 260,
|
||||
onChange,
|
||||
onBlur,
|
||||
@@ -39,6 +41,7 @@ export const Input = (props: inputProps) => {
|
||||
placeholder={placeholder}
|
||||
width={width}
|
||||
maxLength={maxLength}
|
||||
minLength={minLength}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
></StyledInput>
|
||||
|
||||
Reference in New Issue
Block a user