Todo 수정 기능 개선 (UFR-TODO-040)

- 09-Todo관리 프로토타입: 권한별 담당자 필드 표시/숨김 기능 추가
  - 일반 담당자: 담당자 필드 숨김 (본인 Todo만 수정)
  - 회의 생성자: 담당자 필드 표시 (모든 Todo 수정 가능)
- 담당자 변경 시 알림 발송 로직 추가
- checkIfUserIsCreator() 함수 추가 (회의 생성자 권한 확인)
- 권한별 동적 UI 메시지 표시
- 설계서 Option 1 준수: 09-Todo관리에서 일반 담당자는 담당자 변경 불가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
yabo0812
2025-10-23 15:25:28 +09:00
parent 0e4c4a90da
commit 461dc4f524
4 changed files with 331 additions and 22 deletions
+188
View File
@@ -555,6 +555,60 @@
</div>
</div>
<!-- Todo 편집 모달 (UFR-TODO-040) -->
<div class="modal-overlay" id="editTodoModal">
<div class="modal">
<div class="modal-header">
<h3 class="modal-title">Todo 편집</h3>
<button class="modal-close">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label">Todo 제목 <span class="text-error">*</span></label>
<input type="text" id="editTodoTitle" class="form-control" placeholder="할 일을 입력하세요">
</div>
<!-- 담당자 필드 (회의 생성자만 표시) -->
<div class="form-group" id="editTodoAssigneeGroup" style="display: none;">
<label class="form-label">담당자 <span class="text-error">*</span></label>
<select id="editTodoAssignee" class="form-control">
<option value="김민준">김민준</option>
<option value="이서연">이서연</option>
<option value="박준호">박준호</option>
<option value="정수진">정수진</option>
</select>
<p class="form-hint">👤 담당자 변경 시 이전/새 담당자에게 알림이 전송됩니다</p>
</div>
<div class="form-group">
<label class="form-label">마감일 <span class="text-error">*</span></label>
<div class="date-input-wrapper">
<input type="date" id="editTodoDueDate" class="form-control">
</div>
<p class="form-hint">📅 마감일 변경 시 캘린더가 자동 업데이트됩니다</p>
</div>
<div class="form-group">
<label class="form-label">우선순위 <span class="text-error">*</span></label>
<select id="editTodoPriority" class="form-control">
<option value="high">높음</option>
<option value="medium">보통</option>
<option value="low">낮음</option>
</select>
</div>
<!-- 권한 안내 (동적 메시지) -->
<div class="alert alert-info" id="editTodoPermissionInfo">
<span class="material-icons" style="font-size: 20px;">info</span>
<div>
<strong>권한 안내</strong>
<p style="margin: 4px 0 0 0; font-size: 14px;" id="editTodoPermissionText">본인에게 할당된 Todo만 수정할 수 있습니다. 담당자는 변경할 수 없습니다.</p>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-ghost" onclick="closeModal('editTodoModal')">취소</button>
<button class="btn btn-primary" onclick="saveTodoEdit()">저장</button>
</div>
</div>
</div>
<script src="common.js"></script>
<script>
let currentFilter = 'all';
@@ -674,6 +728,14 @@
${createProgressBar(todo.progress)}
</div>
` : ''}
${!isCompleted ? `
<div class="todo-actions">
<button class="btn btn-ghost btn-sm" onclick="editTodo('${todo.id}')">
<span class="material-icons" style="font-size: 16px;">edit</span>
편집
</button>
</div>
` : ''}
</div>
</div>
`);
@@ -735,6 +797,132 @@
// 실제로는 폼 데이터를 수집하여 allTodos에 추가
}
// Todo 편집 (UFR-TODO-040)
let editingTodoId = null;
function editTodo(todoId) {
const todo = allTodos.find(t => t.id === todoId);
if (!todo) return;
editingTodoId = todoId;
// 편집 모달에 현재 값 채우기
$('#editTodoTitle').value = todo.title;
$('#editTodoDueDate').value = todo.dueDate;
$('#editTodoPriority').value = todo.priority;
// 회의 생성자 여부 확인 (실제로는 서버에서 확인)
const currentUser = '김민준'; // 현재 로그인 사용자
const isCreator = checkIfUserIsCreator(todo.meetingId, currentUser);
// 담당자 필드 표시 여부 결정
const assigneeGroup = $('#editTodoAssigneeGroup');
const permissionText = $('#editTodoPermissionText');
if (isCreator) {
// 회의 생성자: 담당자 변경 가능
assigneeGroup.style.display = 'block';
$('#editTodoAssignee').value = todo.assignee.name;
permissionText.textContent = '회의 생성자로서 모든 항목을 수정할 수 있습니다. 담당자 변경 시 알림이 전송됩니다.';
} else {
// 일반 담당자: 담당자 변경 불가
assigneeGroup.style.display = 'none';
permissionText.textContent = '본인에게 할당된 Todo만 수정할 수 있습니다. 담당자는 변경할 수 없습니다.';
}
openModal('editTodoModal');
}
/**
* 회의 생성자 여부 확인
* @param {string} meetingId - 회의 ID
* @param {string} userName - 사용자 이름
* @returns {boolean} 회의 생성자 여부
*/
function checkIfUserIsCreator(meetingId, userName) {
// 실제로는 서버 API를 호출하여 확인
// 프로토타입에서는 샘플 데이터로 시뮬레이션
const meetingCreators = {
'meeting-001': '김민준',
'meeting-002': '이서연',
'meeting-003': '박준호'
};
return meetingCreators[meetingId] === userName;
}
function saveTodoEdit() {
if (!editingTodoId) return;
const todo = allTodos.find(t => t.id === editingTodoId);
if (!todo) return;
// 수정된 값 가져오기
const newTitle = $('#editTodoTitle').value.trim();
const newDueDate = $('#editTodoDueDate').value;
const newPriority = $('#editTodoPriority').value;
// 유효성 검사
if (!newTitle) {
showToast('Todo 제목을 입력해주세요', 'error');
return;
}
if (!newDueDate) {
showToast('마감일을 선택해주세요', 'error');
return;
}
// 회의 생성자 여부 확인
const currentUser = '김민준';
const isCreator = checkIfUserIsCreator(todo.meetingId, currentUser);
// 담당자 변경 여부 확인 (회의 생성자만 가능)
let assigneeChanged = false;
let oldAssignee = '';
let newAssignee = '';
if (isCreator) {
const assigneeGroup = $('#editTodoAssigneeGroup');
if (assigneeGroup.style.display !== 'none') {
newAssignee = $('#editTodoAssignee').value;
oldAssignee = todo.assignee.name;
assigneeChanged = (oldAssignee !== newAssignee);
}
}
// Todo 업데이트
const oldDueDate = todo.dueDate;
todo.title = newTitle;
todo.dueDate = newDueDate;
todo.priority = newPriority;
if (assigneeChanged) {
todo.assignee.name = newAssignee;
}
showToast('Todo가 수정되었습니다', 'success');
closeModal('editTodoModal');
// 담당자 변경 시 알림 발송
if (assigneeChanged) {
setTimeout(() => {
showToast(`${oldAssignee}${newAssignee}에게 알림이 전송되었습니다`, 'info');
}, 1000);
}
// 마감일 변경 시 캘린더 업데이트 메시지
if (oldDueDate !== newDueDate) {
setTimeout(() => {
showToast('캘린더가 업데이트되었습니다', 'info');
}, assigneeChanged ? 2000 : 1000);
}
updateStats();
renderTodoList();
editingTodoId = null;
}
// 카운터 애니메이션
function animateCounter(elementId, target) {
const element = $(`#${elementId}`);