diff --git a/backend/src/modules/task/dto/create-task.dto.ts b/backend/src/modules/task/dto/create-task.dto.ts index a988972..d093ee0 100644 --- a/backend/src/modules/task/dto/create-task.dto.ts +++ b/backend/src/modules/task/dto/create-task.dto.ts @@ -37,17 +37,16 @@ export class CreateTaskDto { title!: string; @ApiProperty({ - description: '본문 문단 배열(선택)', + description: '본문 문단 배열(필수)', type: [String], - required: false, example: ['9월 신제품 캠페인 메인 배너를 제작합니다.'], }) - @IsOptional() @IsArray() + @ArrayNotEmpty({ message: '업무 내용을 입력해 주세요.' }) @ArrayMaxSize(200, { message: '본문 문단이 너무 많습니다.' }) @IsString({ each: true }) @MaxLength(5000, { each: true }) - content?: string[]; + content!: string[]; @ApiProperty({ description: '담당자 사용자 ID 배열(프로젝트 멤버만 가능)', diff --git a/frontend/src/pages/relay/TaskCreatePage.vue b/frontend/src/pages/relay/TaskCreatePage.vue index b23ef8c..db6a57c 100644 --- a/frontend/src/pages/relay/TaskCreatePage.vue +++ b/frontend/src/pages/relay/TaskCreatePage.vue @@ -257,12 +257,16 @@ async function uploadPendingFiles(tid: number): Promise { // --- 제출 --- const submitting = ref(false) -// 필드별 인라인 검증 — 제목·담당자 필수. 입력하면 즉시 해제. +// 필드별 인라인 검증 — 제목·내용·담당자 필수. 입력하면 즉시 해제. const titleError = ref(false) +const contentError = ref(false) const assigneeError = ref(false) watch(title, (v) => { if (v.trim().length > 0) titleError.value = false }) +watch(contentText, (v) => { + if (v.trim().length > 0) contentError.value = false +}) watch( assignees, (v) => { @@ -272,8 +276,9 @@ watch( ) function validateForm(): boolean { titleError.value = title.value.trim().length === 0 + contentError.value = contentText.value.trim().length === 0 assigneeError.value = assignees.value.length === 0 - return !titleError.value && !assigneeError.value + return !titleError.value && !contentError.value && !assigneeError.value } async function submitTask() { @@ -417,7 +422,6 @@ function goBack() {
* 업무 내용
-
+
+
+ 업무 내용을 입력해 주세요. +
@@ -981,9 +994,6 @@ function goBack() { .title-input::placeholder { color: #c4c8cf; } -.title-input.has-error::placeholder { - color: var(--red); -} .field-error { font-size: 0.75rem; color: var(--red); @@ -1023,6 +1033,12 @@ function goBack() { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); } +.editor.has-error { + border-color: var(--red); +} +.editor.has-error:focus-within { + box-shadow: 0 0 0 3px var(--red-weak); +} .editor-toolbar { display: flex; align-items: center;