From 393d5f0f5fd71c8717b57810781e09a0fca864b5 Mon Sep 17 00:00:00 2001 From: rok93 Date: Tue, 14 Sep 2021 02:38:59 +0900 Subject: [PATCH 01/21] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=BC=20=EB=B0=9C?= =?UTF-8?q?=EC=86=A1=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EB=B2=A0=EC=9D=B4=EC=8A=A4=20=EB=A0=88=EC=9D=B4=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/apply/ui/admin/BaseLayout.kt | 4 +- .../apply/ui/admin/mail/GroupMailFormView.kt | 19 ++++++++ .../ui/admin/mail/IndividualMailFormView.kt | 18 ++++++++ .../apply/ui/admin/mail/MailFormView.kt | 19 ++++++++ .../apply/ui/admin/mail/MailSelectionsView.kt | 44 +++++++++++++++++++ 5 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt create mode 100644 src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt create mode 100644 src/main/kotlin/apply/ui/admin/mail/MailFormView.kt create mode 100644 src/main/kotlin/apply/ui/admin/mail/MailSelectionsView.kt diff --git a/src/main/kotlin/apply/ui/admin/BaseLayout.kt b/src/main/kotlin/apply/ui/admin/BaseLayout.kt index ed1e85598..2b7ccdbf6 100644 --- a/src/main/kotlin/apply/ui/admin/BaseLayout.kt +++ b/src/main/kotlin/apply/ui/admin/BaseLayout.kt @@ -2,6 +2,7 @@ package apply.ui.admin import apply.ui.admin.cheater.CheatersView import apply.ui.admin.evaluation.EvaluationsView +import apply.ui.admin.mail.MailSelectionsView import apply.ui.admin.recruitment.RecruitmentsView import apply.ui.admin.selections.SelectionsView import com.vaadin.flow.component.Component @@ -25,7 +26,8 @@ class BaseLayout : AppLayout() { "모집 관리" to RecruitmentsView::class.java, "평가 관리" to EvaluationsView::class.java, "선발 과정" to SelectionsView::class.java, - "부정 행위자" to CheatersView::class.java + "부정 행위자" to CheatersView::class.java, + "메일 발송" to MailSelectionsView::class.java ) init { diff --git a/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt new file mode 100644 index 000000000..957ce2ce6 --- /dev/null +++ b/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt @@ -0,0 +1,19 @@ +package apply.ui.admin.mail + +import apply.application.EvaluationService +import apply.application.MailTargetService +import apply.application.RecruitmentService +import apply.ui.admin.BaseLayout +import com.vaadin.flow.router.Route + +@Route(value = "admin/emails/group", layout = BaseLayout::class) +class GroupMailFormView( + private val recruitmentService: RecruitmentService, + private val evaluationService: EvaluationService, + private val mailTargetService: MailTargetService +) : MailFormView("그룹 발송") { + + override fun createReceiverFilter() { + TODO("Not yet implemented") + } +} diff --git a/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt new file mode 100644 index 000000000..7fc0bd7aa --- /dev/null +++ b/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt @@ -0,0 +1,18 @@ +package apply.ui.admin.mail + +import apply.application.ApplicantService +import apply.ui.admin.BaseLayout +import com.vaadin.flow.router.Route +import support.views.createSearchBar + +@Route(value = "admin/emails/personal", layout = BaseLayout::class) +class IndividualMailFormView( + private val applicantService: ApplicantService +) : MailFormView("개별 발송") { + + override fun createReceiverFilter() { + createSearchBar { + removeAll() + } + } +} diff --git a/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt new file mode 100644 index 000000000..b1d6f9a1c --- /dev/null +++ b/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt @@ -0,0 +1,19 @@ +package apply.ui.admin.mail + +import com.vaadin.flow.component.Component +import com.vaadin.flow.component.html.Div +import com.vaadin.flow.component.orderedlayout.VerticalLayout +import support.views.Title + +open abstract class MailFormView(title: String) : VerticalLayout() { + init { + add(Title(title), createMailForm()) + } + + private fun createMailForm(): Component { + + return Div() + } + + open abstract fun createReceiverFilter() +} diff --git a/src/main/kotlin/apply/ui/admin/mail/MailSelectionsView.kt b/src/main/kotlin/apply/ui/admin/mail/MailSelectionsView.kt new file mode 100644 index 000000000..9a4ec2719 --- /dev/null +++ b/src/main/kotlin/apply/ui/admin/mail/MailSelectionsView.kt @@ -0,0 +1,44 @@ +package apply.ui.admin.mail + +import apply.ui.admin.BaseLayout +import com.vaadin.flow.component.Component +import com.vaadin.flow.component.UI +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.router.Route +import support.views.Title +import support.views.createPrimaryButton + +@Route(value = "admin/emails", layout = BaseLayout::class) +class MailSelectionsView : VerticalLayout() { + init { + add(Title("메일 발송"), *createMailTypeButtons()) + } + + private fun createMailTypeButtons(): Array { + return arrayOf(createGroupMailButton(), createIndividualMailButton()) + } + + private fun createGroupMailButton(): Component { + return HorizontalLayout( + createPrimaryButton("그룹 발송") { + UI.getCurrent().navigate(GroupMailFormView::class.java) + } + ).apply { + setWidthFull() + justifyContentMode = FlexComponent.JustifyContentMode.CENTER + } + } + + private fun createIndividualMailButton(): Component { + return HorizontalLayout( + createPrimaryButton("개별 발송") { + UI.getCurrent().navigate(IndividualMailFormView::class.java) + } + ).apply { + setWidthFull() + justifyContentMode = FlexComponent.JustifyContentMode.CENTER + } + } +} From 947ac765e3b110b5484ca788c842e11904aa5c1d Mon Sep 17 00:00:00 2001 From: rok93 Date: Thu, 16 Sep 2021 01:01:40 +0900 Subject: [PATCH 02/21] =?UTF-8?q?feat:=20=EB=8C=80=EB=9E=B5=EC=A0=81?= =?UTF-8?q?=EC=9D=B8=20=EA=B0=9C=EB=B3=84,=20=EA=B7=B8=EB=A3=B9=20?= =?UTF-8?q?=EB=B0=9C=EC=86=A1=20=EA=B8=B0=EB=8A=A5=20=ED=8B=80=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apply/ui/admin/mail/GroupMailFormView.kt | 68 ++++++++++- .../ui/admin/mail/IndividualMailFormView.kt | 115 +++++++++++++++++- .../apply/ui/admin/mail/MailFormView.kt | 59 +++++++-- 3 files changed, 223 insertions(+), 19 deletions(-) diff --git a/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt index 957ce2ce6..4dfc01383 100644 --- a/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt +++ b/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt @@ -2,18 +2,78 @@ package apply.ui.admin.mail import apply.application.EvaluationService import apply.application.MailTargetService +import apply.application.RecruitmentResponse import apply.application.RecruitmentService +import apply.domain.evaluation.Evaluation +import apply.domain.evaluationtarget.EvaluationStatus import apply.ui.admin.BaseLayout +import com.vaadin.flow.component.Component +import com.vaadin.flow.component.orderedlayout.HorizontalLayout +import com.vaadin.flow.component.select.Select import com.vaadin.flow.router.Route +import support.views.Title +import support.views.createItemSelect -@Route(value = "admin/emails/group", layout = BaseLayout::class) +@Route(value = "group", layout = BaseLayout::class) class GroupMailFormView( private val recruitmentService: RecruitmentService, private val evaluationService: EvaluationService, private val mailTargetService: MailTargetService -) : MailFormView("그룹 발송") { +) : MailFormView(mailTargetService) { + private val recruitment: Select + private val evaluation: Select + private val evaluationStatus: Select - override fun createReceiverFilter() { - TODO("Not yet implemented") + init { + evaluation = createEvaluationItem() + evaluationStatus = createEvaluationStatusItem(evaluation) + recruitment = createRecruitmentItem(evaluation) + add(Title("그룹 발송"), createMailForm()) + setWidthFull() } + + override fun createReceiverFilter(): Component { + return HorizontalLayout(recruitment, evaluation, evaluationStatus) + } + + private fun createRecruitmentItem(evaluation: Select): Select { + return createItemSelect("모집").apply { + setItems(*recruitmentService.findAll().toTypedArray()) + setItemLabelGenerator { it.title } + addValueChangeListener { + evaluation.apply { + setItems(*evaluationService.findAllByRecruitmentId(it.value.id).toTypedArray()) + setItemLabelGenerator { it.title } + } + } + } + } + + private fun createEvaluationItem(): Select { + return createItemSelect("평가") + } + + private fun createEvaluationStatusItem(evaluation: Select): Select { + return createItemSelect("모집 상태").apply { + setItems(*EvaluationStatus.values()) + setItemLabelGenerator { it.toText() } + addValueChangeListener { + receivers.clear() + val mailTargets = mailTargetService.findMailTargets(evaluation.value.id, it.value).map { it.email } + receivers.addAll( + mailTargets + ) + println("조회한 mailTargets: $mailTargets") + println("현재 receivers: $receivers") + } + } + } + + private fun EvaluationStatus.toText() = + when (this) { + EvaluationStatus.WAITING -> "평가 전" + EvaluationStatus.PASS -> "합격" + EvaluationStatus.FAIL -> "탈락" + EvaluationStatus.PENDING -> "보류" + } } diff --git a/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt index 7fc0bd7aa..e3cb32da5 100644 --- a/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt +++ b/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt @@ -1,18 +1,121 @@ package apply.ui.admin.mail +import apply.application.ApplicantResponse import apply.application.ApplicantService +import apply.application.MailTargetService import apply.ui.admin.BaseLayout +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.FlexComponent +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 com.vaadin.flow.router.Route +import support.views.Title +import support.views.addSortableColumn +import support.views.createErrorButton +import support.views.createNormalButton +import support.views.createPrimaryButton import support.views.createSearchBar -@Route(value = "admin/emails/personal", layout = BaseLayout::class) +@Route(value = "personal", layout = BaseLayout::class) class IndividualMailFormView( - private val applicantService: ApplicantService -) : MailFormView("개별 발송") { + private val applicantService: ApplicantService, + mailTargetService: MailTargetService +) : MailFormView(mailTargetService) { + init { + add(Title("개별 발송"), createMailForm()) + setWidthFull() + } + + override fun createReceiverFilter(): Component { + return createNormalButton("지원자 조회") { + Dialog().apply { + width = "800px" + height = "90%" + val applicants = HorizontalLayout().apply { + setWidthFull() + } + add( + H2("지원자 정보 검색"), + HorizontalLayout( + createAddReceivers(), + HorizontalLayout( + createErrorButton("취소") { + close() + } + ).apply { + justifyContentMode = FlexComponent.JustifyContentMode.END + defaultHorizontalComponentAlignment = FlexComponent.Alignment.END + } + ), + applicants + ).apply { + setWidthFull() + } + open() + } + }.apply { isEnabled = true } + } + + private fun createAddReceivers(): Component { + val container = VerticalLayout() + return VerticalLayout( + createSearchBar { + container.removeAll() + val founds = applicantService.findAllByKeyword(it) + if (founds.isNotEmpty()) { + container.add( + createGrid(founds) + ) + } + }, + container + ) + } + + private fun createGrid(applicantResponse: List): Component { + return Grid(10).apply { + addSortableColumn("이름", ApplicantResponse::name) + addSortableColumn("이메일", ApplicantResponse::email) + addColumn(createEditAndDeleteButton()).apply { isAutoWidth = true } + setItems(applicantResponse) + } + } + + private fun createEditAndDeleteButton(): Renderer { + return ComponentRenderer { applicantResponse -> + HorizontalLayout( + createAddOrDeleteButton(applicantResponse) + ) + } + } + + private fun createAddOrDeleteButton(applicantResponse: ApplicantResponse): Component { + if (this.receivers.contains(applicantResponse.email)) { + return createDeleteButton(applicantResponse) + } + + return createAddButton(applicantResponse) + } + + private fun createAddButton(applicantResponse: ApplicantResponse): Button { + return createPrimaryButton("추가") { + this.receivers.add(applicantResponse.email) + }.apply { + isDisableOnClick = true + } + } - override fun createReceiverFilter() { - createSearchBar { - removeAll() + private fun createDeleteButton(applicantResponse: ApplicantResponse): Button { + return createErrorButton("삭제") { + this.receivers.remove(applicantResponse.email) + }.apply { + isDisableOnClick = true } } } diff --git a/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt index b1d6f9a1c..23e3a74fc 100644 --- a/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt +++ b/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt @@ -1,19 +1,60 @@ package apply.ui.admin.mail +import apply.application.MailTargetService import com.vaadin.flow.component.Component -import com.vaadin.flow.component.html.Div +import com.vaadin.flow.component.html.H3 +import com.vaadin.flow.component.html.H4 +import com.vaadin.flow.component.orderedlayout.FlexComponent import com.vaadin.flow.component.orderedlayout.VerticalLayout -import support.views.Title +import com.vaadin.flow.component.textfield.TextArea +import com.vaadin.flow.component.textfield.TextField +import com.vaadin.flow.router.RoutePrefix +import support.views.createPrimaryButton -open abstract class MailFormView(title: String) : VerticalLayout() { - init { - add(Title(title), createMailForm()) - } +@RoutePrefix(value = "admin/emails") +abstract class MailFormView( + private val mailTargetService: MailTargetService +) : VerticalLayout() { + protected val title: TextField = TextField("메일 제목", "메일 제목 입력") + protected val receivers: MutableList = mutableListOf() + protected val content: TextArea = createMailBody() + + protected fun createMailForm(): Component { + val titleText = VerticalLayout( + H3("메일 제목"), + title.apply { setSizeFull() } + ) + + val receivers = VerticalLayout(H4("수신자"), createReceiverFilter()) + val mailBody = VerticalLayout( + content + ).apply { + setSizeFull() + } - private fun createMailForm(): Component { + val sendButton = VerticalLayout( + createPrimaryButton("전송") { + println("title: ${title.value} receivers: ${this.receivers} content: ${this.content.value}") + // todo: (print 내용 지우고) mailSender로 메일 보내기! + } + ).apply { + setSizeFull() + } + + return VerticalLayout(titleText, receivers, mailBody, sendButton).apply { + setSizeFull() + justifyContentMode = FlexComponent.JustifyContentMode.CENTER + defaultHorizontalComponentAlignment = FlexComponent.Alignment.CENTER + } + } - return Div() + private fun createMailBody(): TextArea { + return TextArea("메일 본문").apply { + setSizeFull() + style.set("minHeight", "800px") + placeholder = "메일 본문 입력" + } } - open abstract fun createReceiverFilter() + abstract fun createReceiverFilter(): Component } From cf2f20ff02e2f56125c5aab584dea58c6a4bb9df Mon Sep 17 00:00:00 2001 From: rok93 Date: Thu, 16 Sep 2021 04:41:49 +0900 Subject: [PATCH 03/21] =?UTF-8?q?feat:=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=A0=9C=EC=99=B8=ED=95=9C=20=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20=EB=B0=9C=EC=86=A1=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apply/ui/admin/mail/GroupMailFormView.kt | 8 +- .../ui/admin/mail/IndividualMailFormView.kt | 56 +++++++++++--- .../apply/ui/admin/mail/MailFormView.kt | 77 ++++++++++++++++--- 3 files changed, 115 insertions(+), 26 deletions(-) diff --git a/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt index 4dfc01383..70bc52b92 100644 --- a/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt +++ b/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt @@ -58,13 +58,9 @@ class GroupMailFormView( setItems(*EvaluationStatus.values()) setItemLabelGenerator { it.toText() } addValueChangeListener { - receivers.clear() + clearCurrentReceivers() val mailTargets = mailTargetService.findMailTargets(evaluation.value.id, it.value).map { it.email } - receivers.addAll( - mailTargets - ) - println("조회한 mailTargets: $mailTargets") - println("현재 receivers: $receivers") + mailTargets.forEach { addReceiverComponent(it) } } } } diff --git a/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt index e3cb32da5..48a222490 100644 --- a/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt +++ b/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt @@ -5,13 +5,18 @@ import apply.application.ApplicantService import apply.application.MailTargetService import apply.ui.admin.BaseLayout import com.vaadin.flow.component.Component +import com.vaadin.flow.component.Key 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.Div import com.vaadin.flow.component.html.H2 +import com.vaadin.flow.component.icon.Icon +import com.vaadin.flow.component.icon.VaadinIcon 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.textfield.TextField import com.vaadin.flow.data.renderer.ComponentRenderer import com.vaadin.flow.data.renderer.Renderer import com.vaadin.flow.router.Route @@ -33,13 +38,43 @@ class IndividualMailFormView( } override fun createReceiverFilter(): Component { + return HorizontalLayout( + createDirectInsertTargetComponent { + if (it.isNotBlank()) { + addReceiverComponent(it) + } + }, + createSearchTargetComponent() + ) + } + + private fun createDirectInsertTargetComponent(eventListener: (name: String) -> Unit): Div { + val mailTarget = TextField().apply { + addKeyDownListener( + Key.ENTER, + { + eventListener(this.value) + this.value = "" + } + ) + } + + return Div( + HorizontalLayout( + mailTarget, + Button(Icon(VaadinIcon.ENTER_ARROW)) { + eventListener(mailTarget.value) + mailTarget.value = "" + } + ) + ) + } + + private fun createSearchTargetComponent(): Button { return createNormalButton("지원자 조회") { Dialog().apply { width = "800px" height = "90%" - val applicants = HorizontalLayout().apply { - setWidthFull() - } add( H2("지원자 정보 검색"), HorizontalLayout( @@ -52,8 +87,7 @@ class IndividualMailFormView( justifyContentMode = FlexComponent.JustifyContentMode.END defaultHorizontalComponentAlignment = FlexComponent.Alignment.END } - ), - applicants + ) ).apply { setWidthFull() } @@ -97,23 +131,23 @@ class IndividualMailFormView( private fun createAddOrDeleteButton(applicantResponse: ApplicantResponse): Component { if (this.receivers.contains(applicantResponse.email)) { - return createDeleteButton(applicantResponse) + return createTargetDeleteButton(applicantResponse) } - return createAddButton(applicantResponse) + return createTargetAddButton(applicantResponse) } - private fun createAddButton(applicantResponse: ApplicantResponse): Button { + private fun createTargetAddButton(applicantResponse: ApplicantResponse): Button { return createPrimaryButton("추가") { - this.receivers.add(applicantResponse.email) + addReceiverComponent(applicantResponse.email) }.apply { isDisableOnClick = true } } - private fun createDeleteButton(applicantResponse: ApplicantResponse): Button { + private fun createTargetDeleteButton(applicantResponse: ApplicantResponse): Button { return createErrorButton("삭제") { - this.receivers.remove(applicantResponse.email) + removeReceiverComponent(applicantResponse.email) }.apply { isDisableOnClick = true } diff --git a/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt index 23e3a74fc..6a8a3f8d8 100644 --- a/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt +++ b/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt @@ -2,9 +2,14 @@ package apply.ui.admin.mail import apply.application.MailTargetService import com.vaadin.flow.component.Component +import com.vaadin.flow.component.button.Button import com.vaadin.flow.component.html.H3 import com.vaadin.flow.component.html.H4 +import com.vaadin.flow.component.html.Span +import com.vaadin.flow.component.icon.Icon +import com.vaadin.flow.component.icon.VaadinIcon 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.textfield.TextArea import com.vaadin.flow.component.textfield.TextField @@ -18,6 +23,9 @@ abstract class MailFormView( protected val title: TextField = TextField("메일 제목", "메일 제목 입력") protected val receivers: MutableList = mutableListOf() protected val content: TextArea = createMailBody() + private val currentReceivers = HorizontalLayout() + + abstract fun createReceiverFilter(): Component protected fun createMailForm(): Component { val titleText = VerticalLayout( @@ -25,36 +33,87 @@ abstract class MailFormView( title.apply { setSizeFull() } ) - val receivers = VerticalLayout(H4("수신자"), createReceiverFilter()) + val receiverFilter = VerticalLayout(H4("수신자"), createReceiverFilter()) val mailBody = VerticalLayout( content ).apply { setSizeFull() } - val sendButton = VerticalLayout( - createPrimaryButton("전송") { - println("title: ${title.value} receivers: ${this.receivers} content: ${this.content.value}") - // todo: (print 내용 지우고) mailSender로 메일 보내기! - } + val sendButton = createMailSendButton() + + return VerticalLayout( + titleText, + receiverFilter, + currentReceivers.apply { setSizeFull() }, + mailBody, + sendButton ).apply { setSizeFull() + justifyContentMode = FlexComponent.JustifyContentMode.CENTER + defaultHorizontalComponentAlignment = FlexComponent.Alignment.CENTER } + } - return VerticalLayout(titleText, receivers, mailBody, sendButton).apply { + private fun createMailSendButton(): VerticalLayout { + return VerticalLayout( + createPrimaryButton("전송") { + println("title: ${title.value} receivers: ${this.receivers} content: ${this.content.value}") + // todo: emailService.메일전송(title.value, receivers, content.value) + } + ).apply { setSizeFull() justifyContentMode = FlexComponent.JustifyContentMode.CENTER defaultHorizontalComponentAlignment = FlexComponent.Alignment.CENTER } } + protected fun addReceiverComponent(email: String) { + this.currentReceivers.apply { + receivers.add(email) + add(createReceiverComponent(email)) + } + } + + protected fun clearCurrentReceivers() { + this.currentReceivers.removeAll() + this.receivers.clear() + } + + protected fun removeReceiverComponent(email: String) { + receivers.remove(email) + addAllCurrentReceiverComponent() + } + + private fun addAllCurrentReceiverComponent() { + this.currentReceivers.removeAll() + this.currentReceivers.apply { + receivers.forEach { + add(createReceiverComponent(it)) + } + } + } + private fun createMailBody(): TextArea { return TextArea("메일 본문").apply { setSizeFull() - style.set("minHeight", "800px") + style.set("minHeight", "400px") placeholder = "메일 본문 입력" } } - abstract fun createReceiverFilter(): Component + private fun createReceiverComponent(email: String): Component { + val emailTarget = TextField().apply { + value = email + isReadOnly = true + style.set("background-color", "#00B493") + } + + return Span( + emailTarget, + Button(Icon(VaadinIcon.CLOSE_SMALL)) { + removeReceiverComponent(email) + } + ) + } } From b5285708dfb826f06cf248317d3847592747a9d5 Mon Sep 17 00:00:00 2001 From: rok93 Date: Thu, 16 Sep 2021 14:41:36 +0900 Subject: [PATCH 04/21] =?UTF-8?q?feat:=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apply/ui/admin/mail/GroupMailFormView.kt | 8 +- .../ui/admin/mail/IndividualMailFormView.kt | 20 ++--- .../apply/ui/admin/mail/MailFormView.kt | 84 +++++++++++-------- src/main/kotlin/support/views/Buttons.kt | 16 ++++ 4 files changed, 78 insertions(+), 50 deletions(-) diff --git a/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt index 70bc52b92..26bf7e896 100644 --- a/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt +++ b/src/main/kotlin/apply/ui/admin/mail/GroupMailFormView.kt @@ -19,7 +19,7 @@ class GroupMailFormView( private val recruitmentService: RecruitmentService, private val evaluationService: EvaluationService, private val mailTargetService: MailTargetService -) : MailFormView(mailTargetService) { +) : MailFormView() { private val recruitment: Select private val evaluation: Select private val evaluationStatus: Select @@ -32,7 +32,7 @@ class GroupMailFormView( setWidthFull() } - override fun createReceiverFilter(): Component { + override fun createRecipientFilter(): Component { return HorizontalLayout(recruitment, evaluation, evaluationStatus) } @@ -58,9 +58,9 @@ class GroupMailFormView( setItems(*EvaluationStatus.values()) setItemLabelGenerator { it.toText() } addValueChangeListener { - clearCurrentReceivers() + clearCurrentRecipients() val mailTargets = mailTargetService.findMailTargets(evaluation.value.id, it.value).map { it.email } - mailTargets.forEach { addReceiverComponent(it) } + mailTargets.forEach { addRecipientComponent(it) } } } } diff --git a/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt index 48a222490..219c06903 100644 --- a/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt +++ b/src/main/kotlin/apply/ui/admin/mail/IndividualMailFormView.kt @@ -2,7 +2,6 @@ package apply.ui.admin.mail import apply.application.ApplicantResponse import apply.application.ApplicantService -import apply.application.MailTargetService import apply.ui.admin.BaseLayout import com.vaadin.flow.component.Component import com.vaadin.flow.component.Key @@ -29,19 +28,18 @@ import support.views.createSearchBar @Route(value = "personal", layout = BaseLayout::class) class IndividualMailFormView( - private val applicantService: ApplicantService, - mailTargetService: MailTargetService -) : MailFormView(mailTargetService) { + private val applicantService: ApplicantService +) : MailFormView() { init { add(Title("개별 발송"), createMailForm()) setWidthFull() } - override fun createReceiverFilter(): Component { + override fun createRecipientFilter(): Component { return HorizontalLayout( createDirectInsertTargetComponent { if (it.isNotBlank()) { - addReceiverComponent(it) + addRecipientComponent(it) } }, createSearchTargetComponent() @@ -78,7 +76,7 @@ class IndividualMailFormView( add( H2("지원자 정보 검색"), HorizontalLayout( - createAddReceivers(), + createAddRecipients(), HorizontalLayout( createErrorButton("취소") { close() @@ -96,7 +94,7 @@ class IndividualMailFormView( }.apply { isEnabled = true } } - private fun createAddReceivers(): Component { + private fun createAddRecipients(): Component { val container = VerticalLayout() return VerticalLayout( createSearchBar { @@ -130,7 +128,7 @@ class IndividualMailFormView( } private fun createAddOrDeleteButton(applicantResponse: ApplicantResponse): Component { - if (this.receivers.contains(applicantResponse.email)) { + if (this.recipients.contains(applicantResponse.email)) { return createTargetDeleteButton(applicantResponse) } @@ -139,7 +137,7 @@ class IndividualMailFormView( private fun createTargetAddButton(applicantResponse: ApplicantResponse): Button { return createPrimaryButton("추가") { - addReceiverComponent(applicantResponse.email) + addRecipientComponent(applicantResponse.email) }.apply { isDisableOnClick = true } @@ -147,7 +145,7 @@ class IndividualMailFormView( private fun createTargetDeleteButton(applicantResponse: ApplicantResponse): Button { return createErrorButton("삭제") { - removeReceiverComponent(applicantResponse.email) + removeRecipientComponent(applicantResponse.email) }.apply { isDisableOnClick = true } diff --git a/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt b/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt index 6a8a3f8d8..e02a14a54 100644 --- a/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt +++ b/src/main/kotlin/apply/ui/admin/mail/MailFormView.kt @@ -1,6 +1,5 @@ package apply.ui.admin.mail -import apply.application.MailTargetService import com.vaadin.flow.component.Component import com.vaadin.flow.component.button.Button import com.vaadin.flow.component.html.H3 @@ -13,29 +12,43 @@ import com.vaadin.flow.component.orderedlayout.HorizontalLayout import com.vaadin.flow.component.orderedlayout.VerticalLayout import com.vaadin.flow.component.textfield.TextArea import com.vaadin.flow.component.textfield.TextField +import com.vaadin.flow.component.upload.receivers.MultiFileMemoryBuffer import com.vaadin.flow.router.RoutePrefix +import support.views.createImageUpload import support.views.createPrimaryButton @RoutePrefix(value = "admin/emails") -abstract class MailFormView( - private val mailTargetService: MailTargetService -) : VerticalLayout() { - protected val title: TextField = TextField("메일 제목", "메일 제목 입력") - protected val receivers: MutableList = mutableListOf() - protected val content: TextArea = createMailBody() - private val currentReceivers = HorizontalLayout() +abstract class MailFormView() : VerticalLayout() { + protected val subject: TextField = TextField("메일 제목", "메일 제목 입력") + protected val recipients: MutableList = mutableListOf() + protected val body: TextArea = createMailBody() + private val currentRecipients = HorizontalLayout() - abstract fun createReceiverFilter(): Component + abstract fun createRecipientFilter(): Component protected fun createMailForm(): Component { - val titleText = VerticalLayout( + val subjectText = VerticalLayout( H3("메일 제목"), - title.apply { setSizeFull() } + subject.apply { setSizeFull() } ) - val receiverFilter = VerticalLayout(H4("수신자"), createReceiverFilter()) + val recipientFilter = VerticalLayout(H4("수신자"), createRecipientFilter()) + val uploadFile = createImageUpload("첨부파일", MultiFileMemoryBuffer()) { + /* + todo: 추후 업로드 된 파일을 메일로 첨부하는 로직이 추가되어야 함 + (uploadFiles 같은 필드를 두고 mail을 보내는 기능에 포함시키면 될 것 같음) + it.files.forEach { fileName -> + val fileData = it.getFileData(fileName) + val inputStream = it.getInputStream(fileName) + val readBytes = inputStream.readBytes() + } + */ + }.apply { + setWidthFull() + } + val mailBody = VerticalLayout( - content + body ).apply { setSizeFull() } @@ -43,9 +56,10 @@ abstract class MailFormView( val sendButton = createMailSendButton() return VerticalLayout( - titleText, - receiverFilter, - currentReceivers.apply { setSizeFull() }, + subjectText, + recipientFilter, + currentRecipients.apply { setSizeFull() }, + uploadFile, mailBody, sendButton ).apply { @@ -58,8 +72,8 @@ abstract class MailFormView( private fun createMailSendButton(): VerticalLayout { return VerticalLayout( createPrimaryButton("전송") { - println("title: ${title.value} receivers: ${this.receivers} content: ${this.content.value}") - // todo: emailService.메일전송(title.value, receivers, content.value) + // todo: emailService.메일전송(subject.value, recipients, body.value) + // MailService에 } ).apply { setSizeFull() @@ -68,28 +82,28 @@ abstract class MailFormView( } } - protected fun addReceiverComponent(email: String) { - this.currentReceivers.apply { - receivers.add(email) - add(createReceiverComponent(email)) + protected fun addRecipientComponent(email: String) { + this.currentRecipients.apply { + recipients.add(email) + add(createRecipientComponent(email)) } } - protected fun clearCurrentReceivers() { - this.currentReceivers.removeAll() - this.receivers.clear() + protected fun clearCurrentRecipients() { + this.currentRecipients.removeAll() + this.recipients.clear() } - protected fun removeReceiverComponent(email: String) { - receivers.remove(email) - addAllCurrentReceiverComponent() + protected fun removeRecipientComponent(email: String) { + recipients.remove(email) + addAllCurrentRecipientComponent() } - private fun addAllCurrentReceiverComponent() { - this.currentReceivers.removeAll() - this.currentReceivers.apply { - receivers.forEach { - add(createReceiverComponent(it)) + private fun addAllCurrentRecipientComponent() { + this.currentRecipients.removeAll() + this.currentRecipients.apply { + recipients.forEach { + add(createRecipientComponent(it)) } } } @@ -102,7 +116,7 @@ abstract class MailFormView( } } - private fun createReceiverComponent(email: String): Component { + private fun createRecipientComponent(email: String): Component { val emailTarget = TextField().apply { value = email isReadOnly = true @@ -112,7 +126,7 @@ abstract class MailFormView( return Span( emailTarget, Button(Icon(VaadinIcon.CLOSE_SMALL)) { - removeReceiverComponent(email) + removeRecipientComponent(email) } ) } diff --git a/src/main/kotlin/support/views/Buttons.kt b/src/main/kotlin/support/views/Buttons.kt index 8db338087..bce9cb10b 100644 --- a/src/main/kotlin/support/views/Buttons.kt +++ b/src/main/kotlin/support/views/Buttons.kt @@ -10,9 +10,11 @@ import com.vaadin.flow.component.orderedlayout.FlexComponent import com.vaadin.flow.component.orderedlayout.HorizontalLayout import com.vaadin.flow.component.upload.Upload import com.vaadin.flow.component.upload.receivers.MemoryBuffer +import com.vaadin.flow.component.upload.receivers.MultiFileMemoryBuffer typealias ClickListener = (ClickEvent