94 lines
2.9 KiB
JavaScript
94 lines
2.9 KiB
JavaScript
import { nextTick } from 'vue'
|
|
import Sortable from 'sortablejs'
|
|
|
|
export function useAdminFeaturedTemplates({
|
|
api,
|
|
featuredListEl,
|
|
featuredSortable,
|
|
featuredTemplateIds,
|
|
templates,
|
|
resetMessages,
|
|
success,
|
|
error,
|
|
}) {
|
|
function destroyFeaturedSortable() {
|
|
if (featuredSortable.value) {
|
|
featuredSortable.value.destroy()
|
|
featuredSortable.value = null
|
|
}
|
|
}
|
|
|
|
async function syncFeaturedSortable() {
|
|
await nextTick()
|
|
destroyFeaturedSortable()
|
|
if (!featuredListEl.value) return
|
|
|
|
featuredSortable.value = Sortable.create(featuredListEl.value, {
|
|
animation: 160,
|
|
draggable: '[data-featured-id]',
|
|
handle: '[data-featured-handle]',
|
|
ghostClass: 'ghost',
|
|
chosenClass: 'chosen',
|
|
onEnd: (evt) => {
|
|
if (evt.oldIndex == null || evt.newIndex == null || evt.oldIndex === evt.newIndex) return
|
|
const nextIds = [...featuredTemplateIds.value]
|
|
const [moved] = nextIds.splice(evt.oldIndex, 1)
|
|
nextIds.splice(evt.newIndex, 0, moved)
|
|
featuredTemplateIds.value = nextIds
|
|
},
|
|
})
|
|
}
|
|
|
|
function addFeaturedTemplate(templateId) {
|
|
resetMessages()
|
|
if (!templateId || featuredTemplateIds.value.includes(templateId)) return
|
|
if (featuredTemplateIds.value.length >= 50) {
|
|
error.value = '상단 고정 템플릿은 최대 50개까지만 설정할 수 있어요.'
|
|
return
|
|
}
|
|
featuredTemplateIds.value = [...featuredTemplateIds.value, templateId]
|
|
syncFeaturedSortable()
|
|
}
|
|
|
|
function removeFeaturedTemplate(templateId) {
|
|
resetMessages()
|
|
featuredTemplateIds.value = featuredTemplateIds.value.filter((id) => id !== templateId)
|
|
syncFeaturedSortable()
|
|
}
|
|
|
|
function moveFeaturedTemplate(templateId, direction) {
|
|
const currentIndex = featuredTemplateIds.value.indexOf(templateId)
|
|
const nextIndex = currentIndex + direction
|
|
if (currentIndex < 0 || nextIndex < 0 || nextIndex >= featuredTemplateIds.value.length) return
|
|
const nextIds = [...featuredTemplateIds.value]
|
|
const [moved] = nextIds.splice(currentIndex, 1)
|
|
nextIds.splice(nextIndex, 0, moved)
|
|
featuredTemplateIds.value = nextIds
|
|
syncFeaturedSortable()
|
|
}
|
|
|
|
async function saveFeaturedOrder() {
|
|
resetMessages()
|
|
try {
|
|
const data = await api.updateAdminTemplateDisplayOrder({ topicIds: featuredTemplateIds.value })
|
|
templates.value = data.templates || []
|
|
featuredTemplateIds.value = templates.value
|
|
.filter((template) => template.displayRank != null)
|
|
.sort((a, b) => a.displayRank - b.displayRank)
|
|
.map((template) => template.id)
|
|
success.value = '홈 화면 템플릿 순서를 저장했어요.'
|
|
} catch (e) {
|
|
error.value = '템플릿 순서 저장에 실패했어요.'
|
|
}
|
|
}
|
|
|
|
return {
|
|
destroyFeaturedSortable,
|
|
syncFeaturedSortable,
|
|
addFeaturedTemplate,
|
|
removeFeaturedTemplate,
|
|
moveFeaturedTemplate,
|
|
saveFeaturedOrder,
|
|
}
|
|
}
|