feat: set workspace names

This commit is contained in:
MingLiang Wang
2022-12-22 18:03:34 +08:00
parent 4e0aa31af4
commit cf95f0abaf
8 changed files with 164 additions and 86 deletions
@@ -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[]>([]);
@@ -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 />}
@@ -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',
},
};
}
+3
View File
@@ -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>