-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: solve side effects related to duplicate events #1226
Conversation
…oords of time event
…tDuplicateEvents option
@@ -107,6 +107,10 @@ | |||
/> | |||
</button> | |||
<span class="navbar--range"></span> | |||
<div class="nav-checkbox"> | |||
<input class="checkbox-collapse" type="checkbox" id="collapse" value="collapse" /> | |||
<label for="collapse">Collapse duplicate events and disable the detail popup</label> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
중복 일정이 겹쳐지고 펼쳐지는 동작이 잘 보이도록 collapseDuplicateEvents
를 활성화하면 useDetailPopup
를 끄도록 만들었습니다.
@@ -266,11 +314,11 @@ export function setRenderInfoOfUIModels( | |||
|
|||
matrices.forEach((matrix) => { | |||
const maxRowLength = Math.max(...matrix.map((row) => row.length)); | |||
const baseWidth = 100 / maxRowLength; | |||
const baseWidth = Math.round(100 / maxRowLength); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
중복 일정의 경우 preact에 스타일을 지정할 때 left와 width를 문자열값으로 넘기게 됩니다. 이 때 나누어 떨어지지 않는 baseWidth를 가지는 경우 css 스타일이 제대로 적용되지 못하는 경우가 생겨서 반올림하도록 하였습니다.
#### 기존에 문제가 발생하지 않았던 이유
기존에는 left와 width를 number
형식으로 preact에 넘기고, preact 내부에서 소숫점을 처리해주었습니다. 하지만 현재 중복된 일정의 경우 left와 width를 string
형식으로 넘기도록 변경되면서 preact에서 자동으로 처리되지 않습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그냥 궁금해서요. preact 내부에서 소숫점 처리해줬다는 부분이 여긴가요?
소숫점이 너무 많아지는 부분은 예전에도 뭔가 반올림 처리를 하거나 toFixed
를 써야 하지 않을까 생각했다가 괜찮으니까 냅뒀는데, 이런부분에서 의외의 문제가 터지는군요 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 이 부분은 제가 잘못 파악했네요. 기존에도 number가 아닌 string으로 넘기고 있었습니다. (참고 - TimeEvent.tsx L75-L79)
제 생각에는 이번에 추가된 퍼센트 값을 더하고 빼는 과정 때문에 부동소수점 오류가 난 것 같습니다.
기존에는 부동소수점의 연산이 아니라 100 / baseWidth
와 같이 결과가 부동소수점으로 나타나는 거라 문제가 없었는데, 이번에 추가된 로직은 부동소수점끼리의 연산이라 문제가 발생한 것 같아요.
/** | ||
* represent the left value of a duplicate event. | ||
* ex) calc(50% - 24px), calc(50%), ... | ||
* | ||
* @type {string} | ||
*/ | ||
duplicateLeft = ''; | ||
|
||
/** | ||
* represent the width value of a duplicate event. | ||
* ex) calc(50% - 24px), 9px, ... | ||
* | ||
* @type {string} | ||
*/ | ||
duplicateWidth = ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
기존의 left
와 width
를 수정하지 않고 새로운 프로퍼티를 만든 이유는 타입 문제 때문입니다. left
와 width
가 문자열도 가능하도록 number | string
타입으로 바꾸면 다른 많은 곳에서 타입 에러가 발생하고, 이를 모두 수정해야 합니다. 생각보다 영향을 끼치는 부분이 많아서 새로운 프로퍼티를 만들었습니다.
infos.push({ | ||
start: event.duplicateStarts as TZDate, | ||
end: event.duplicateEnds as TZDate, | ||
goingDuration: 0, | ||
comingDuration: 0, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicateStarts
에는 중복 일정 그룹 중 가장 이른 start + goingDuration을, duplicateEnds
에는 가장 늦은 end + comingDuration을 저장합니다. duplicateStarts
과 duplicateEnds
는 이미 duration을 고려한 값이기 때문에 충돌을 계산할 때는 goingDuration과 comingDuration을 0으로 설정합니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
리뷰 완료합니다. 어려운 기능 구현하느라 무척 고생하셨어요.
자잘하게 코드 다듬어주셨으면 하는 부분, 설명이 조금 더 필요하다고 생각하는 부분 등 코멘트 남겼습니다.
@@ -266,11 +314,11 @@ export function setRenderInfoOfUIModels( | |||
|
|||
matrices.forEach((matrix) => { | |||
const maxRowLength = Math.max(...matrix.map((row) => row.length)); | |||
const baseWidth = 100 / maxRowLength; | |||
const baseWidth = Math.round(100 / maxRowLength); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그냥 궁금해서요. preact 내부에서 소숫점 처리해줬다는 부분이 여긴가요?
소숫점이 너무 많아지는 부분은 예전에도 뭔가 반올림 처리를 하거나 toFixed
를 써야 하지 않을까 생각했다가 괜찮으니까 냅뒀는데, 이런부분에서 의외의 문제가 터지는군요 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
리뷰 완료합니다.
if (!isDuplicateEvent && uiModel.duplicateEvents.length > 0) { | ||
uiModel.duplicateEvents.forEach((event) => { | ||
setRenderInfo({ | ||
uiModel: event, | ||
columnIndex, | ||
baseWidth, | ||
startColumnTime, | ||
endColumnTime, | ||
isDuplicateEvent: true, | ||
}); | ||
}); | ||
|
||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
얼리리턴보다
if (!isDuplicateEvent && uiModel.duplicateEvents.length > 0) { | |
uiModel.duplicateEvents.forEach((event) => { | |
setRenderInfo({ | |
uiModel: event, | |
columnIndex, | |
baseWidth, | |
startColumnTime, | |
endColumnTime, | |
isDuplicateEvent: true, | |
}); | |
}); | |
return; | |
} | |
if (isDuplicateEvent || uiModel.duplicateEvents.length === 0) { | |
// 아래 로직 | |
} else { | |
uiModel.duplicateEvents.forEach((event) => { | |
setRenderInfo({ | |
uiModel: event, | |
columnIndex, | |
baseWidth, | |
startColumnTime, | |
endColumnTime, | |
isDuplicateEvent: true, | |
}); | |
}); | |
} |
같은 방식은 어떠신가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 개인적으로 얼리 리턴을 더 선호합니다..ㅎㅎㅎ 굳이 else 문을 만들어서 인덴테이션 한 단계를 추가하고 싶지 않기도 하고, 아래 로직에서도 return하는 로직이 없어서 어느 로직을 타더라도 리턴 타입이 동일하게 undefined
이 되거든요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
혹시 else 쓰는 걸 선호하는 이유가 있나요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금 함수는 괜찮은데 함수가 길어지고 로직이 복잡할 때 중간에 얼리리턴으로 빠져나가면 로직 파악이 쉽지 않더라구요.
개인적인 의견이라 반영 안하셔도 괜찮습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 기본적으론 얼리리턴 좋아하는데 아무것도 리턴 안하고 return
만 있는 얼리리턴보단 값이 명시적인 얼리리턴이어야 그럴만한 가치가 있다고 생각하는 편이에요.
이 함수는 약간 다른데, 재귀함수이므로 조건 종료 부분이 먼저 함수 상단에 드러나있는게 좋다고 생각해서 지금 상태로도 충분하다 봅니다.
제 코멘트에도 썼지만 이런 형태의 재귀가 아닌 다른 방식으로 풀어나갈 수 있으면 좋겠지만 마땅한 개선 아이디어가 떠오르지 않아 넘어가시죠.
Please check if the PR fulfills these requirements
fix #xxx[,#xxx]
, where "xxx" is the issue number)Description
5%
of the column.9px
.collapseDuplicateEvent
option.collapseDuplicateEvent
option.Thank you for your contribution to TOAST UI product. 🎉 😘 ✨