-
Notifications
You must be signed in to change notification settings - Fork 102
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(mail): implement the send mail view #337
Changes from 16 commits
393d5f0
947ac76
cf2f20f
b528570
c4b8f59
8e6b68f
e6322b0
47231b0
d9f5c93
24f387e
355547b
cc54a2d
c7fc6c4
cd0c86e
619dfde
e22c80a
a5a7bda
7bbad19
7ab7abb
7566eb1
97a7bd4
32f321b
98597dd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package apply.application.mail | ||
|
||
import javax.validation.constraints.NotNull | ||
|
||
data class MailSendData( | ||
@field:NotNull | ||
var subject: String = "", | ||
@field:NotNull | ||
var content: String = "", | ||
@field:NotNull | ||
var targetMails: List<String> = listOf() | ||
) |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,117 @@ | ||||||||||||||||
package apply.ui.admin.mail | ||||||||||||||||
|
||||||||||||||||
import apply.application.EvaluationService | ||||||||||||||||
import apply.application.MailTargetResponse | ||||||||||||||||
import apply.application.MailTargetService | ||||||||||||||||
import apply.application.RecruitmentResponse | ||||||||||||||||
import apply.application.RecruitmentService | ||||||||||||||||
import apply.domain.evaluation.Evaluation | ||||||||||||||||
import apply.domain.evaluationtarget.EvaluationStatus | ||||||||||||||||
import com.vaadin.flow.component.Component | ||||||||||||||||
import com.vaadin.flow.component.dialog.Dialog | ||||||||||||||||
import com.vaadin.flow.component.grid.Grid | ||||||||||||||||
import com.vaadin.flow.component.html.H2 | ||||||||||||||||
import com.vaadin.flow.component.orderedlayout.FlexComponent | ||||||||||||||||
import com.vaadin.flow.component.orderedlayout.HorizontalLayout | ||||||||||||||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout | ||||||||||||||||
import com.vaadin.flow.component.select.Select | ||||||||||||||||
import support.views.addSortableColumn | ||||||||||||||||
import support.views.createErrorButton | ||||||||||||||||
import support.views.createItemSelect | ||||||||||||||||
import support.views.createPrimaryButton | ||||||||||||||||
|
||||||||||||||||
class GroupMailTargetFormDialog( | ||||||||||||||||
private val recruitmentService: RecruitmentService, | ||||||||||||||||
private val evaluationService: EvaluationService, | ||||||||||||||||
private val mailTargetService: MailTargetService, | ||||||||||||||||
private val reloadComponent: (List<MailTargetResponse>) -> Unit | ||||||||||||||||
) : Dialog() { | ||||||||||||||||
private val evaluation = createEvaluationItem() | ||||||||||||||||
private val recruitment = createRecruitmentItem(evaluation) | ||||||||||||||||
private val evaluationStatus = createEvaluationStatusItem(evaluation) | ||||||||||||||||
private val mailTargets: MutableList<MailTargetResponse> = mutableListOf() | ||||||||||||||||
private val currentMailTargets: VerticalLayout = VerticalLayout(createContent()) | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
여기를 그리드로 바꾸고, |
||||||||||||||||
|
||||||||||||||||
init { | ||||||||||||||||
width = "800px" | ||||||||||||||||
height = "90%" | ||||||||||||||||
add( | ||||||||||||||||
H2("지원자 정보 조회"), | ||||||||||||||||
HorizontalLayout( | ||||||||||||||||
recruitment, evaluation, evaluationStatus, | ||||||||||||||||
HorizontalLayout( | ||||||||||||||||
createPrimaryButton("추가") { | ||||||||||||||||
reloadComponent(mailTargets) | ||||||||||||||||
close() | ||||||||||||||||
}, | ||||||||||||||||
createErrorButton("취소") { | ||||||||||||||||
close() | ||||||||||||||||
} | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
다른 곳과 같이 취소에는 ContrastButton을 사용하면 좋을 것 같아요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이것도 개인적인 생각인데, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 가로 폭을 줄이다보니 자연스럽게 버튼들을 하단으로 내리는게 좋을 것 같네요 🤔 |
||||||||||||||||
).apply { | ||||||||||||||||
justifyContentMode = FlexComponent.JustifyContentMode.END | ||||||||||||||||
defaultVerticalComponentAlignment = FlexComponent.Alignment.END | ||||||||||||||||
}, | ||||||||||||||||
), | ||||||||||||||||
currentMailTargets | ||||||||||||||||
).apply { | ||||||||||||||||
setWidthFull() | ||||||||||||||||
} | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
호잇 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 호잇! |
||||||||||||||||
open() | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
private fun createEvaluationItem(): Select<Evaluation> { | ||||||||||||||||
return createItemSelect("평가") | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 바로 호출을 하고 있으니 메서드로 따로 분리하지 않아도 괜찮을 것 같은데 어떠신가요?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||
private fun createRecruitmentItem(evaluation: Select<Evaluation>): Select<RecruitmentResponse> { | ||||||||||||||||
return createItemSelect<RecruitmentResponse>("모집").apply { | ||||||||||||||||
setItems(*recruitmentService.findAll().toTypedArray()) | ||||||||||||||||
setItemLabelGenerator { it.title } | ||||||||||||||||
addValueChangeListener { | ||||||||||||||||
evaluation.apply { | ||||||||||||||||
setItems(*evaluationService.findAllByRecruitmentId(it.value.id).toTypedArray()) | ||||||||||||||||
setItemLabelGenerator { it.title } | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
private fun createEvaluationStatusItem( | ||||||||||||||||
evaluation: Select<Evaluation>, | ||||||||||||||||
): Select<EvaluationStatus> { | ||||||||||||||||
return createItemSelect<EvaluationStatus>("모집 상태").apply { | ||||||||||||||||
setItems(*EvaluationStatus.values()) | ||||||||||||||||
setItemLabelGenerator { it.toText() } | ||||||||||||||||
addValueChangeListener { | ||||||||||||||||
val mailTargetResponses = mailTargetService.findMailTargets(evaluation.value.id, it.value) | ||||||||||||||||
mailTargets.clear() | ||||||||||||||||
mailTargets.addAll(mailTargetResponses) | ||||||||||||||||
|
||||||||||||||||
currentMailTargets.apply { | ||||||||||||||||
this.removeAll() | ||||||||||||||||
this.add(createContent(mailTargetResponses)) | ||||||||||||||||
} | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
setItem을 사용해 createContent() 메서드를 제거하는 방법도 있을 것 같은데 이런 방법은 어떨까요 ?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 기존에는 VerticalLayout에 Component(아마 Span 이었던걸로..)를 각각 추가하다 보니 지금처럼 removeAll, add 메서드로 되어있었는데, VerticalLayout으로 감싸지 않고 바로 Grid를 사용한다면 마찌가 제안한대로 변경할 수 있을 것 같아요! |
||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
private fun EvaluationStatus.toText() = | ||||||||||||||||
when (this) { | ||||||||||||||||
EvaluationStatus.WAITING -> "평가 전" | ||||||||||||||||
EvaluationStatus.PASS -> "합격" | ||||||||||||||||
EvaluationStatus.FAIL -> "탈락" | ||||||||||||||||
EvaluationStatus.PENDING -> "보류" | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
private fun createContent(mailTargets: List<MailTargetResponse> = emptyList()): Component { | ||||||||||||||||
val grids = createMailTargetsGrid(mailTargets) | ||||||||||||||||
return VerticalLayout(grids).apply { setWidthFull() } | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
private fun createMailTargetsGrid(mailTargets: List<MailTargetResponse>): Component { | ||||||||||||||||
return Grid<MailTargetResponse>(10).apply { | ||||||||||||||||
addSortableColumn("이메일", MailTargetResponse::email) | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 전반적인 그리드에 메일 대상자 이름도 추가했다면 여기에서도 이름 컬럼을 추가하면 어떨까요??? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그렇네요 여기에서도 이름을 추가하면 좋을 것 같아요 😃 |
||||||||||||||||
setItems(mailTargets) | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,68 @@ | ||||||||||||||||||||||||||||||
package apply.ui.admin.mail | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
import apply.application.ApplicantResponse | ||||||||||||||||||||||||||||||
import apply.application.ApplicantService | ||||||||||||||||||||||||||||||
import apply.application.MailTargetResponse | ||||||||||||||||||||||||||||||
import com.vaadin.flow.component.Component | ||||||||||||||||||||||||||||||
import com.vaadin.flow.component.button.Button | ||||||||||||||||||||||||||||||
import com.vaadin.flow.component.dialog.Dialog | ||||||||||||||||||||||||||||||
import com.vaadin.flow.component.grid.Grid | ||||||||||||||||||||||||||||||
import com.vaadin.flow.component.html.H2 | ||||||||||||||||||||||||||||||
import com.vaadin.flow.component.orderedlayout.HorizontalLayout | ||||||||||||||||||||||||||||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout | ||||||||||||||||||||||||||||||
import com.vaadin.flow.data.renderer.ComponentRenderer | ||||||||||||||||||||||||||||||
import com.vaadin.flow.data.renderer.Renderer | ||||||||||||||||||||||||||||||
import support.views.addSortableColumn | ||||||||||||||||||||||||||||||
import support.views.createPrimaryButton | ||||||||||||||||||||||||||||||
import support.views.createSearchBar | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
class IndividualMailTargetFormDialog( | ||||||||||||||||||||||||||||||
private val applicantService: ApplicantService, | ||||||||||||||||||||||||||||||
private val reloadComponent: (MailTargetResponse) -> Unit | ||||||||||||||||||||||||||||||
) : Dialog() { | ||||||||||||||||||||||||||||||
init { | ||||||||||||||||||||||||||||||
width = "800px" | ||||||||||||||||||||||||||||||
height = "90%" | ||||||||||||||||||||||||||||||
add(H2("지원자 정보 조회"), HorizontalLayout(createAddRecipients())).apply { | ||||||||||||||||||||||||||||||
setWidthFull() | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
open() | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
위 코멘트에 이어서 다른 다이얼로그처럼 너비 높이 선언을 아래로 내려주어 사이즈를 맞추고 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 앗 그리고 기존에 검색 요소가 그리드보다 튀어나온 부분도 정렬해주면 좋을 것 같아요 ! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 와 마찌... 디테일한 리뷰 🔥 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 우어ㅣ..바딘은 마스터했군욬ㅋㅋㅋㅋㅋㅋㅋㅋㅋ 👍 그리고 선택후 닫기가 애매해서 마찌가 취소 버튼을 넣어준 것처럼 닫기 버튼 등이 있어서 모달이 닫히면 좋을 듯 싶어요!ㅎㅎㅎ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그리드가 튀어나오는 부분 수정하고 취소버튼 추가했습니다 😃 |
||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
private fun createAddRecipients(): Component { | ||||||||||||||||||||||||||||||
val container = VerticalLayout() | ||||||||||||||||||||||||||||||
return VerticalLayout( | ||||||||||||||||||||||||||||||
createSearchBar { | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
여기다 다음과 같은 라벨을 주어도 좋을 것 같네요 ㅎㅎ |
||||||||||||||||||||||||||||||
container.removeAll() | ||||||||||||||||||||||||||||||
val founds = applicantService.findAllByKeyword(it) | ||||||||||||||||||||||||||||||
if (founds.isNotEmpty()) { | ||||||||||||||||||||||||||||||
container.add(createGrid(founds)) | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
container | ||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
private fun createGrid(applicantResponse: List<ApplicantResponse>): Component { | ||||||||||||||||||||||||||||||
return Grid<ApplicantResponse>(10).apply { | ||||||||||||||||||||||||||||||
addSortableColumn("이름", ApplicantResponse::name) | ||||||||||||||||||||||||||||||
addSortableColumn("이메일", ApplicantResponse::email) | ||||||||||||||||||||||||||||||
addColumn(createEditAndDeleteButton()).apply { isAutoWidth = true } | ||||||||||||||||||||||||||||||
setItems(applicantResponse) | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
private fun createEditAndDeleteButton(): Renderer<ApplicantResponse> { | ||||||||||||||||||||||||||||||
return ComponentRenderer<Component, ApplicantResponse> { applicantResponse -> | ||||||||||||||||||||||||||||||
HorizontalLayout(createTargetAddButton(applicantResponse)) | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 네이밍을 보면 수정, 삭제 버튼을 만들 것 같은데 추가 버튼을 생성하고 있어요 ~ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 에고... 원래 추가 or 삭제 버튼을 생성하게하는 기능인데... 총체적 난국이네요 add가 아닌 edit에 심지어 or가 아닌 and ... ㅋㅋㅋㅋㅋㅋㅋㅋ 대체 무슨 생각을 하면서 만든건지... 바딘의 위험성 |
||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
private fun createTargetAddButton(applicantResponse: ApplicantResponse): Button { | ||||||||||||||||||||||||||||||
return createPrimaryButton("추가") { | ||||||||||||||||||||||||||||||
reloadComponent(MailTargetResponse(applicantResponse)) | ||||||||||||||||||||||||||||||
}.apply { | ||||||||||||||||||||||||||||||
isDisableOnClick = true | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} |
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.
메서드를 제거하고 이렇게 바꾸는건 어떨까요 ? ㅎㅎ
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.
아... 메서드에 제네릭 타입을 저렇게 명시하면 바로 사용할 수 있는거였군요??
메서드에 바로 제네릭 타입을 지정할 수 있는지 전혀 몰랐네요 😧
코멘트 반영했습니다 😃