[개발 회고] allDay 플래그 하나로 갈리는 캘린더 이벤트 렌더링 분기
allDay 플래그 하나로 갈리는 캘린더 이벤트 렌더링 분기
설계 노트 — 캘린더 이벤트 시작시간 표기 및 멀티데이 “(전체 N일)” 표기
배경
캘린더(월/주/일 뷰)의 이벤트 표시 방식을 개선하기로 했다. 개선 항목은 세 가지다.
- 월뷰 이벤트 title 앞에 시작시간을 표기한다.
- 주뷰(및 일뷰) 종일줄에서 여러 날에 걸친 이벤트는 title 옆에 “(전체 N일)”을 표기한다.
- 월뷰에서 종료시간이 있는(하루종일이 아닌) 이벤트가 여러 날에 걸쳐 “긴 바” 형태로 표시될 때, 디자인을 종일뷰 이벤트와 동일하게(호버 효과 제외) 바꾼다.
현재 구조 확인
- 이벤트 생성 로직이 각 일정에
allDay,start_time,end_time,start_date,end_date등을 계산해 담고, 캘린더 컴포넌트가 이를 그대로 FullCalendar의eventsprop에 넘긴다.title/start/end/allDay외 필드는 FullCalendar가 자동으로event.extendedProps에 담아준다. - 이벤트 콘텐츠 렌더링은 캘린더 컴포넌트의 커스텀 이벤트 콘텐츠 함수 한 곳에서 처리한다.
- 주뷰/일뷰의
timeGrid에서!allDay(시간이 있는 이벤트)인 경우: 전용 분기를 탄다. - 그 외 모든 경우(월뷰 전체 + 주/일뷰 종일줄): 공용 fallback 분기(title만 렌더링)를 탄다.
- 즉 fallback 분기에서
!event.allDay이면 항상 “월뷰(단일일자 또는 멀티데이 바)”이고,event.allDay이면 항상 “주/일뷰의 종일줄 또는 월뷰의 all-day 이벤트”다. 뷰 타입을 별도로 검사하지 않아도allDay플래그만으로 대상이 정확히 갈린다.
- 주뷰/일뷰의
- 주/일뷰 종일줄 이벤트는 이미 전용 스타일(가운데정렬, 스트라이프 없음, 둥근모서리, inset box-shadow, hover 시 배경색 변경)을 갖고 있는데, 이 스타일이 각 뷰별로 스타일시트에 중복 정의되어 있다. 반면 월뷰 이벤트는 좌측 스트라이프가 있는 별도 스타일 하나만 존재하며, all-day/timed/단일/멀티 구분 없이 전부 동일한 스타일을 공유한다.
- 이벤트가 종일 이벤트인지 판단하는 로직은 시작시각이 자정이 아니면 무조건 “시간 있는 이벤트”로 판단한다. 따라서
allDay=false인 이벤트는 항상 “실제로 의미 있는 시작시각”을 가진다(우연히 00:00:00인 극단적 케이스가 있어도,allDay=false이면 시간 표기 규칙을 그대로 적용한다).
결정된 규칙
1) 월뷰 시작시간 표기
fallback 분기에서 !event.allDay일 때, 시작시각 문자열(“HH:mm:ss.SSS”)을 앞 5글자(HH:mm)만 잘라 title 앞에 붙인다. 판단 기준은 allDay 플래그뿐이다(개별 시각 문자열이 우연히 “00:00”이어도 allDay=false면 표기한다). 단일일자 이벤트와 멀티데이 바 이벤트에 동일하게 적용되므로 별도 분기가 필요 없다.
2) “(전체 N일)” 표기
같은 fallback 분기에서, FullCalendar가 넘겨주는 event.start/event.end(end는 exclusive)로 전체 일수를 계산한다.
totalDays = Math.round((end - start) / 86400000)
totalDays > 1이면 title 뒤에 (전체 N일)을 이어붙인다. title과 동일한 엘리먼트/스타일을 그대로 사용하므로(문자열만 이어붙임) 별도 CSS가 필요 없다.
적용 대상은 “여러 날에 걸치는 모든 이벤트”로 일관되게 정했다: 주뷰 종일줄(원 요청), 일뷰 종일줄, 월뷰의 기존 all-day 멀티데이 바, 그리고 월뷰의 새로 디자인이 바뀌는 timed 멀티데이 바(3번 항목)까지 전부 포함한다. 월뷰 all-day 바의 기존 디자인(좌측 스트라이프)은 변경하지 않고 텍스트만 추가된다.
3) 월뷰 timed 멀티데이 바 디자인 변경
적용 대상은 월뷰이면서 !event.allDay이고 totalDays > 1인 이벤트만이다. 기존 all-day 멀티데이 바(월뷰)는 지금의 좌측 스트라이프 디자인을 그대로 유지한다.
- 이벤트 클래스명을 결정하는 콜백에 위 조건을 추가해 새 클래스를 부여한다.
- 스타일시트에 해당 클래스 전용 규칙을 추가한다. 주/일뷰 종일줄 스타일(가운데정렬, 스트라이프 없음, 둥근모서리, inset box-shadow)을 그대로 재사용하되, hover 시 배경색/box-shadow가 바뀌는 규칙은 포함하지 않는다(“hover 기능 제외” 요구사항).
- 시간 표기(1번)와 “(전체 N일)” 표기(2번)는 별도 구현 없이 동일 fallback 분기 로직이 그대로 적용된다.
영향 범위 (Blast Radius)
- 캘린더 컴포넌트
- 커스텀 이벤트 콘텐츠 함수: fallback 분기 로직 추가(시간 prefix, 일수 suffix)
- 이벤트 클래스명 콜백: 월뷰 timed 멀티데이 바 전용 클래스 추가
- 캘린더 스타일시트
- 새 클래스용 규칙 추가(주/일뷰 종일줄 스타일 재사용, hover 제외)
- 주의: 리스트뷰의 “오늘” 행 관련 스타일 블록은 수동 관리 중이므로 건드리지 않는다
- 이벤트 데이터 생성 로직: 수정 불필요(필요한 데이터는 이미 충분함)
Non-goals
- 리스트/agenda 뷰의 표기 방식(
(dayIndex/totalDays일)형식)은 이번 변경 대상이 아니다. 별개 뷰, 별개 포맷이며 그대로 둔다. - 이벤트 드래그/리사이즈 등 상호작용 로직은 변경하지 않는다(디자인만 변경, “hover 기능 제외”는 시각 효과 제거를 의미하며 드래그/리사이즈 가능 여부 자체는 건드리지 않는다).
- 종일 이벤트 판단 로직 등 이벤트 데이터 생성 로직은 변경하지 않는다.
테스트 시나리오
- 월뷰 단일일자 이벤트(시작 09:00): title 앞에 “09:00 “ 표기
- 월뷰 단일일자 종일 이벤트(allDay=true): 시간 표기 없음(기존과 동일)
- 월뷰 멀티데이 all-day 바(예: 3일): 좌측 스트라이프 디자인 유지, title 뒤에 “(전체 3일)” 추가
- 월뷰 멀티데이 timed 바(시작 09:00, 여러 날): 종일뷰와 동일한 가운데정렬/스트라이프없음 디자인 + 호버 효과 없음 + “09:00 “ 접두 + “(전체 N일)” 접미
- 주뷰 종일줄, 여러 날짜에 걸친 이벤트: title 뒤에 “(전체 N일)” 표기, 디자인은 기존 그대로
- 주뷰 종일줄, 단일일자 이벤트: 일수 표기 없음(기존과 동일)
- 일뷰 종일줄, 여러 날짜에 걸친 이벤트: 5번과 동일하게 “(전체 N일)” 표기
- 주/일뷰의 시간 있는(timed, 종일줄 아님) 이벤트: 이번 변경으로 영향받지 않음(기존 timed 이벤트 분기 그대로)
댓글남기기