feat(agent): 소속 추가 다이얼로그 크리에이터 검색 디바운스 적용
- onSearchCreators에 300ms 디바운스 로직 추가 - assignDialog.searchDebounceTimer 상태 추가 및 다이얼로그/소멸 시 정리 - 최신 검색어와 응답 불일치 시 결과 반영 방지 가드 - 검색어 비었을 때 로딩/결과 초기화 처리 강화
This commit is contained in:
@@ -289,6 +289,8 @@ export default {
|
|||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
searchItems: [],
|
searchItems: [],
|
||||||
searchLoading: false,
|
searchLoading: false,
|
||||||
|
// 디바운스 타이머 보관
|
||||||
|
searchDebounceTimer: null,
|
||||||
},
|
},
|
||||||
|
|
||||||
unassignDialog: {
|
unassignDialog: {
|
||||||
@@ -316,6 +318,13 @@ export default {
|
|||||||
created() {
|
created() {
|
||||||
this.fetchList(1)
|
this.fetchList(1)
|
||||||
},
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
// 검색 디바운스 타이머 정리
|
||||||
|
if (this.assignDialog && this.assignDialog.searchDebounceTimer) {
|
||||||
|
clearTimeout(this.assignDialog.searchDebounceTimer)
|
||||||
|
this.assignDialog.searchDebounceTimer = null
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
notifyError(message) {
|
notifyError(message) {
|
||||||
// vuetify-dialog 플러그인을 통해 오류 노출
|
// vuetify-dialog 플러그인을 통해 오류 노출
|
||||||
@@ -366,31 +375,61 @@ export default {
|
|||||||
},
|
},
|
||||||
closeAssignDialog() {
|
closeAssignDialog() {
|
||||||
this.assignDialog.visible = false
|
this.assignDialog.visible = false
|
||||||
|
// 다이얼로그 닫힐 때 디바운스 및 로딩 상태 초기화
|
||||||
|
if (this.assignDialog.searchDebounceTimer) {
|
||||||
|
clearTimeout(this.assignDialog.searchDebounceTimer)
|
||||||
|
this.assignDialog.searchDebounceTimer = null
|
||||||
|
}
|
||||||
|
this.assignDialog.searchLoading = false
|
||||||
},
|
},
|
||||||
async onSearchCreators(q) {
|
onSearchCreators(q) {
|
||||||
const query = (q || '').trim()
|
const query = (q || '').trim()
|
||||||
this.assignDialog.searchQuery = query
|
this.assignDialog.searchQuery = query
|
||||||
|
|
||||||
|
// 기존 타이머가 있으면 취소
|
||||||
|
if (this.assignDialog.searchDebounceTimer) {
|
||||||
|
clearTimeout(this.assignDialog.searchDebounceTimer)
|
||||||
|
this.assignDialog.searchDebounceTimer = null
|
||||||
|
}
|
||||||
|
|
||||||
if (!query) {
|
if (!query) {
|
||||||
|
// 검색어 없으면 결과/로딩 초기화
|
||||||
this.assignDialog.searchItems = []
|
this.assignDialog.searchItems = []
|
||||||
|
this.assignDialog.searchLoading = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.assignDialog.searchLoading = true
|
|
||||||
try {
|
// 디바운스: 300ms 이후 최신 검색어로 요청
|
||||||
const res = await searchAdminAgentAssignableCreators(query)
|
this.assignDialog.searchDebounceTimer = setTimeout(async () => {
|
||||||
if (res && res.status === 200 && res.data && res.data.success === true) {
|
// 요청 직전 로딩 시작
|
||||||
const data = (res.data && res.data.data) || { totalCount: 0, items: [] }
|
this.assignDialog.searchLoading = true
|
||||||
this.assignDialog.searchItems = Array.isArray(data.items) ? data.items : []
|
const currentQuery = this.assignDialog.searchQuery
|
||||||
} else {
|
try {
|
||||||
this.assignDialog.searchItems = []
|
const res = await searchAdminAgentAssignableCreators(currentQuery)
|
||||||
const msg = res && res.data && (res.data.message || res.data.error || res.data.msg)
|
// 사용자가 그 사이에 검색어를 바꿨다면 이 응답은 무시
|
||||||
this.notifyError(msg || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
if (this.assignDialog.searchQuery !== currentQuery) return
|
||||||
|
|
||||||
|
if (res && res.status === 200 && res.data && res.data.success === true) {
|
||||||
|
const data = (res.data && res.data.data) || { totalCount: 0, items: [] }
|
||||||
|
this.assignDialog.searchItems = Array.isArray(data.items) ? data.items : []
|
||||||
|
} else {
|
||||||
|
this.assignDialog.searchItems = []
|
||||||
|
const msg = res && res.data && (res.data.message || res.data.error || res.data.msg)
|
||||||
|
this.notifyError(msg || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// 에러 시에도 최신 검색어와 일치할 때만 처리
|
||||||
|
if (this.assignDialog.searchQuery === currentQuery) {
|
||||||
|
this.assignDialog.searchItems = []
|
||||||
|
this.notifyError(this.getErrorMessage(e))
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// 최신 검색어와 일치할 때만 로딩 해제
|
||||||
|
if (this.assignDialog.searchQuery === currentQuery) {
|
||||||
|
this.assignDialog.searchLoading = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}, 300)
|
||||||
this.assignDialog.searchItems = []
|
|
||||||
this.notifyError(this.getErrorMessage(e))
|
|
||||||
} finally {
|
|
||||||
this.assignDialog.searchLoading = false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
async onAssign() {
|
async onAssign() {
|
||||||
if (!this.canAssign) return
|
if (!this.canAssign) return
|
||||||
|
|||||||
Reference in New Issue
Block a user