mirror of
https://github.com/hwanny1128/HGZero.git
synced 2026-06-13 05:59:11 +00:00
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:
@@ -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}`);
|
||||
|
||||
Reference in New Issue
Block a user