-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat-fe: 여러 지원자 선택 토글 UI 및 기능 구현 #820
Open
github-actions
wants to merge
13
commits into
fe/develop
Choose a base branch
from
fe-819-TOGGLE_MULTI_01
base: fe/develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+233
−4
Open
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
18e3a96
Create draft PR for #819
github-actions[bot] 6090cde
feat: 여러 지원자 선택 토글 UI 컴포넌트 구현
seongjinme 31a1db8
refactor: ProcessBoard에 토글 요소 임시 적용
seongjinme b885afa
Merge remote-tracking branch 'upstream/fe/develop' into fe-819-TOGGLE…
seongjinme 2425050
Merge remote-tracking branch 'upstream/fe/develop' into fe-819-TOGGLE…
seongjinme 3e39dab
Merge remote-tracking branch 'upstream/fe/develop' into fe-819-TOGGLE…
seongjinme 05635c1
test: MultiSelectToggle 컴포넌트 스토리북 추가
seongjinme 45cdfb8
feat: 토글시 드롭다운 기능 구현 및 애니메이션 UI 적용
seongjinme fce4301
Merge remote-tracking branch 'upstream/fe/develop' into fe-819-TOGGLE…
seongjinme 6fc640f
fix: fe/develop의 최신 커밋 내역 적용
seongjinme a6a885c
Merge remote-tracking branch 'upstream/fe/develop' into fe-819-TOGGLE…
seongjinme 030f3b7
fix: 로컬 테스트를 위해 작성했던 코드 삭제
seongjinme 138cb12
Merge branch 'fe/develop' into fe-819-TOGGLE_MULTI_01
seongjinme File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
81 changes: 81 additions & 0 deletions
81
frontend/src/components/dashboard/MultiSelectToggle/MultiSelectToggle.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import { MultiApplicantContextProvider } from '@contexts/MultiApplicantContext'; | ||
import { DropdownProvider } from '@contexts/DropdownContext'; | ||
import MultiSelectToggle from '.'; | ||
|
||
const meta = { | ||
title: 'Organisms/Dashboard/MultiSelectToggle', | ||
component: MultiSelectToggle, | ||
parameters: { | ||
layout: 'centered', | ||
docs: { | ||
description: { | ||
component: | ||
'MultiSelectToggle 컴포넌트는 여러 지원자의 선택 여부를 토글하고, 선택시 실행할 공통 작업을 제공하는 컴포넌트입니다.', | ||
}, | ||
}, | ||
}, | ||
argTypes: { | ||
isToggled: { control: 'boolean', description: '여러 지원자 선택 토글 여부를 나타냅니다.' }, | ||
selectedApplicantIds: { | ||
description: '선택된 지원자들의 ID값 목록을 나타냅니다.', | ||
}, | ||
}, | ||
tags: ['autodocs'], | ||
decorators: [ | ||
(Child) => ( | ||
<div | ||
style={{ | ||
width: '60rem', | ||
height: '3.6rem', | ||
display: 'flex', | ||
flexDirection: 'row', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
}} | ||
> | ||
<MultiApplicantContextProvider> | ||
<DropdownProvider> | ||
<Child /> | ||
</DropdownProvider> | ||
</MultiApplicantContextProvider> | ||
</div> | ||
), | ||
], | ||
} satisfies Meta<typeof MultiSelectToggle>; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof meta>; | ||
|
||
const processes = [ | ||
{ | ||
processName: '지원서', | ||
processId: 1, | ||
}, | ||
{ | ||
processName: '프로세스 1', | ||
processId: 4, | ||
}, | ||
{ | ||
processName: '프로세스 2', | ||
processId: 2, | ||
}, | ||
{ | ||
processName: '프로세스 3', | ||
processId: 5, | ||
}, | ||
{ | ||
processName: '최종 합격', | ||
processId: 6, | ||
}, | ||
]; | ||
|
||
const selectedApplicantIds = [1, 2, 3]; | ||
|
||
export const MultiSelectToggleDefault: Story = { | ||
args: { | ||
isToggled: false, | ||
processes, | ||
selectedApplicantIds, | ||
}, | ||
}; |
107 changes: 107 additions & 0 deletions
107
frontend/src/components/dashboard/MultiSelectToggle/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import { useEffect, useState } from 'react'; | ||
|
||
import { useMultiApplicant } from '@contexts/MultiApplicantContext'; | ||
import { DropdownProvider } from '@contexts/DropdownContext'; | ||
import type { SimpleProcess } from '@hooks/useProcess'; | ||
|
||
import useApplicant from '@hooks/useApplicant'; | ||
import ToggleSwitch from '@components/_common/atoms/ToggleSwitch'; | ||
import Dropdown from '@components/_common/molecules/Dropdown'; | ||
import DropdownItemRenderer, { DropdownItemType } from '@components/_common/molecules/DropdownItemRenderer'; | ||
|
||
import S from './style'; | ||
|
||
interface MultiSelectToggleProps { | ||
isToggled: boolean; | ||
processes: SimpleProcess[]; | ||
selectedApplicantIds: number[]; | ||
} | ||
|
||
export default function MultiSelectToggle({ isToggled, processes, selectedApplicantIds }: MultiSelectToggleProps) { | ||
const { toggleIsMultiType, resetApplicants } = useMultiApplicant(); | ||
const { mutate: moveApplicantProcess } = useApplicant({}); | ||
|
||
const [isDropdownVisible, setIsDropdownVisible] = useState<boolean>(false); | ||
const [isToggleVisible, setIsToggleVisible] = useState<boolean>(true); | ||
|
||
useEffect(() => { | ||
if (isToggled) { | ||
setIsToggleVisible(false); | ||
const timer = setTimeout(() => setIsDropdownVisible(true), 200); | ||
return () => clearTimeout(timer); | ||
} | ||
|
||
setIsDropdownVisible(false); | ||
const timer = setTimeout(() => setIsToggleVisible(true), 300); | ||
return () => clearTimeout(timer); | ||
}, [isToggled]); | ||
|
||
const handleToggleMultiType = () => { | ||
if (isToggled) resetApplicants(); | ||
toggleIsMultiType(); | ||
}; | ||
|
||
const menuItems: DropdownItemType[] = [ | ||
{ | ||
type: 'subTrigger', | ||
id: 'moveProcess', | ||
name: '단계 이동', | ||
items: processes.map(({ processName, processId }) => ({ | ||
type: 'clickable', | ||
id: processId, | ||
name: processName, | ||
onClick: ({ targetProcessId }) => { | ||
moveApplicantProcess({ processId: targetProcessId, applicants: selectedApplicantIds }); | ||
}, | ||
})), | ||
}, | ||
{ | ||
type: 'clickable', | ||
id: 'emailButton', | ||
name: '이메일 보내기', | ||
hasSeparate: true, | ||
onClick: () => { | ||
// TODO: 복수 지원자에 대한 이메일 전송 구현이 필요합니다. (24/10/16 아르) | ||
console.log(`${selectedApplicantIds.join(', ')} 지원자들에게 이메일을 보냅니다.`); | ||
}, | ||
}, | ||
{ | ||
type: 'clickable', | ||
id: 'rejectButton', | ||
name: '불합격 처리', | ||
isHighlight: true, | ||
hasSeparate: true, | ||
onClick: () => { | ||
// TODO: 일괄 불합격/불합격 해제에 해당하는 API 연결 Mutation 구현이 필요합니다. (24/10/16 아르) | ||
console.log(`${selectedApplicantIds.join(', ')} 지원자들을 모두 불합격 처리합니다.`); | ||
}, | ||
}, | ||
]; | ||
|
||
return ( | ||
<S.Wrapper> | ||
<S.ToggleWrapper isVisible={isToggleVisible}> | ||
<S.ToggleLabel>여러 지원자 선택</S.ToggleLabel> | ||
<ToggleSwitch | ||
width="4rem" | ||
onChange={handleToggleMultiType} | ||
isChecked={isToggled} | ||
isDisabled={false} | ||
/> | ||
</S.ToggleWrapper> | ||
|
||
<S.DropdownWrapper isVisible={isDropdownVisible}> | ||
<DropdownProvider> | ||
<Dropdown | ||
initValue="실행할 작업" | ||
width={120} | ||
isShadow={false} | ||
disabled={selectedApplicantIds.length === 0} | ||
> | ||
<DropdownItemRenderer items={menuItems} /> | ||
</Dropdown> | ||
</DropdownProvider> | ||
</S.DropdownWrapper> | ||
</S.Wrapper> | ||
); | ||
} |
41 changes: 41 additions & 0 deletions
41
frontend/src/components/dashboard/MultiSelectToggle/style.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
const Wrapper = styled.div` | ||
display: flex; | ||
justify-content: flex-end; | ||
`; | ||
|
||
const ToggleWrapper = styled.div<{ isVisible: boolean }>` | ||
display: flex; | ||
gap: 1.2rem; | ||
align-items: center; | ||
transition: transform 0.3s ease-in-out; | ||
transform: ${({ isVisible }) => (isVisible ? 'translateX(0)' : 'translateX(-13.8rem)')}; | ||
`; | ||
|
||
const ToggleLabel = styled.span` | ||
${({ theme }) => theme.typography.heading[200]}; | ||
color: ${({ theme }) => theme.baseColors.grayscale[800]}; | ||
`; | ||
|
||
const DropdownWrapper = styled.div<{ isVisible: boolean }>` | ||
position: absolute; | ||
transform: translateX(0); | ||
opacity: ${({ isVisible }) => (isVisible ? 1 : 0.01)}; | ||
visibility: ${({ isVisible }) => (isVisible ? 'visible' : 'hidden')}; | ||
transition: | ||
opacity 0.3s ease-in-out, | ||
visibility 0.3s ease-in-out; | ||
color: ${({ theme }) => theme.baseColors.grayscale[800]}; | ||
`; | ||
|
||
const S = { | ||
Wrapper, | ||
ToggleWrapper, | ||
ToggleLabel, | ||
DropdownWrapper, | ||
}; | ||
|
||
export default S; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
애니메이션이 유려하네요🫢👍
토글이 오픈되었을 때 두 요소의 정렬을 가운데로 맞춰주실 수 있으실까요?