태그 관리 자동 저장 정리
This commit is contained in:
@@ -54,7 +54,7 @@ const filteredGeneralTags = computed(() => {
|
||||
)
|
||||
})
|
||||
|
||||
/** 서버 기준 메인 태그 id 순서(정렬 저장 버튼 활성 비교용) */
|
||||
/** 서버 기준 메인 태그 id 순서(자동 저장 필요 여부 비교용) */
|
||||
const baselineManagedTagIds = ref([])
|
||||
|
||||
/**
|
||||
@@ -77,7 +77,7 @@ const refreshTagsFromServer = async () => {
|
||||
resetManagedOrderBaseline()
|
||||
|
||||
/**
|
||||
* 메인 태그 드래그 순서가 기준선과 다른지 여부
|
||||
* 메인 태그 드래그 순서가 서버 기준선과 다른지 여부
|
||||
* @returns {boolean} 변경 여부
|
||||
*/
|
||||
const isManagedOrderDirty = computed(() => {
|
||||
@@ -116,6 +116,11 @@ const showToast = (type, message) => {
|
||||
* @returns {void}
|
||||
*/
|
||||
const handleDragStart = (event, tagId) => {
|
||||
if (savingOrder.value) {
|
||||
event.preventDefault()
|
||||
return
|
||||
}
|
||||
|
||||
if (!event.dataTransfer) {
|
||||
return
|
||||
}
|
||||
@@ -130,6 +135,10 @@ const handleDragStart = (event, tagId) => {
|
||||
* @returns {void}
|
||||
*/
|
||||
const handleDragOver = (event, tagId) => {
|
||||
if (savingOrder.value) {
|
||||
return
|
||||
}
|
||||
|
||||
event.preventDefault()
|
||||
dragOverTagId.value = tagId
|
||||
}
|
||||
@@ -172,15 +181,17 @@ const moveManagedTag = (sourceId, targetId) => {
|
||||
* 관리용 태그 드롭 처리
|
||||
* @param {DragEvent} event - 드래그 이벤트
|
||||
* @param {string} targetId - 대상 태그 ID
|
||||
* @returns {void}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const handleDrop = (event, targetId) => {
|
||||
const handleDrop = async (event, targetId) => {
|
||||
event.preventDefault()
|
||||
if (!draggingTagId.value) {
|
||||
if (!draggingTagId.value || savingOrder.value) {
|
||||
return
|
||||
}
|
||||
moveManagedTag(draggingTagId.value, targetId)
|
||||
handleDragEnd()
|
||||
await nextTick()
|
||||
await saveManagedOrder()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,9 +215,10 @@ const saveManagedOrder = async () => {
|
||||
|
||||
tags.value = [...reordered]
|
||||
await refreshTagsFromServer()
|
||||
showToast('success', '메인 태그 순서가 저장되었습니다.')
|
||||
showToast('success', '메인 태그 순서가 자동 저장되었습니다.')
|
||||
} catch (error) {
|
||||
showToast('error', error?.data?.message || '정렬 순서를 저장하지 못했습니다.')
|
||||
await refreshTagsFromServer()
|
||||
} finally {
|
||||
savingOrder.value = false
|
||||
}
|
||||
@@ -328,7 +340,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
<template>
|
||||
<section class="admin-tags bg-paper p-6">
|
||||
<div class="admin-tags__header flex items-center justify-between gap-4">
|
||||
<div class="admin-tags__header">
|
||||
<div>
|
||||
<p class="admin-tags__eyebrow text-xs font-semibold uppercase text-muted">
|
||||
Tags
|
||||
@@ -337,9 +349,6 @@ onBeforeUnmount(() => {
|
||||
태그 관리
|
||||
</h1>
|
||||
</div>
|
||||
<NuxtLink class="admin-tags__new rounded bg-[#15171a] px-4 py-2 text-sm font-semibold text-white" to="/admin/tags/new">
|
||||
태그 추가
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<p class="mt-3 text-xs text-muted">
|
||||
메인 태그는 홈페이지 카테고리 영역에서 사용되며 드래그 정렬이 가능합니다. 일반 태그는 아래 목록에서 확인하고 필요할 때 메인 태그로 전환할 수 있습니다.
|
||||
@@ -348,14 +357,10 @@ onBeforeUnmount(() => {
|
||||
<div class="admin-tags__table mt-6 overflow-hidden border border-line">
|
||||
<div class="flex items-center justify-between border-b border-line bg-[#f7f7f5] px-4 py-2.5">
|
||||
<p class="text-xs font-semibold uppercase text-muted">메인 태그</p>
|
||||
<button
|
||||
class="rounded border border-line bg-white px-3 py-1.5 text-xs font-semibold disabled:opacity-50"
|
||||
type="button"
|
||||
:disabled="savingOrder || managedTags.length === 0 || !isManagedOrderDirty"
|
||||
@click="saveManagedOrder"
|
||||
>
|
||||
{{ savingOrder ? '저장 중' : '정렬 저장' }}
|
||||
</button>
|
||||
<span v-if="savingOrder" class="inline-flex items-center gap-2 text-xs font-semibold text-muted">
|
||||
<span class="size-3 animate-spin rounded-full border-2 border-line border-t-[#15171a]" />
|
||||
저장 중
|
||||
</span>
|
||||
</div>
|
||||
<table class="admin-tags__table-inner w-full border-collapse text-left text-sm">
|
||||
<thead class="admin-tags__table-head bg-[#f5f5f2] text-xs uppercase text-muted">
|
||||
@@ -372,12 +377,13 @@ onBeforeUnmount(() => {
|
||||
<tr
|
||||
v-for="(tag, index) in managedTags"
|
||||
:key="tag.id"
|
||||
class="admin-tags__row cursor-move"
|
||||
class="admin-tags__row"
|
||||
:class="[
|
||||
dragOverTagId === tag.id ? 'bg-[#f9f9f7]' : '',
|
||||
draggingTagId === tag.id ? 'opacity-50' : ''
|
||||
draggingTagId === tag.id ? 'opacity-50' : '',
|
||||
savingOrder ? 'cursor-not-allowed opacity-60' : 'cursor-move'
|
||||
]"
|
||||
draggable="true"
|
||||
:draggable="!savingOrder"
|
||||
@dragstart="handleDragStart($event, tag.id)"
|
||||
@dragover="handleDragOver($event, tag.id)"
|
||||
@drop="handleDrop($event, tag.id)"
|
||||
@@ -422,8 +428,11 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
|
||||
<div class="admin-tags__table mt-8 overflow-hidden border border-line">
|
||||
<div class="border-b border-line bg-[#f7f7f5] px-4 py-2.5">
|
||||
<div class="flex items-center justify-between gap-3 border-b border-line bg-[#f7f7f5] px-4 py-2.5">
|
||||
<p class="text-xs font-semibold uppercase text-muted">일반 태그</p>
|
||||
<NuxtLink class="admin-tags__new rounded bg-[#15171a] px-3 py-1.5 text-xs font-semibold text-white" to="/admin/tags/new">
|
||||
태그 추가
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div class="space-y-3 bg-white p-4">
|
||||
<div class="flex flex-col gap-3 xl:flex-row xl:items-center xl:justify-between">
|
||||
|
||||
Reference in New Issue
Block a user