미디어 필터와 이미지 액션 정리

This commit is contained in:
2026-06-17 10:28:53 +09:00
parent 11f8402cb6
commit 54d32af617
9 changed files with 68 additions and 93 deletions

View File

@@ -215,14 +215,23 @@ const mediaKindFilterOptions = computed(() => {
]
})
const unusedMediaCount = computed(() => scopeItems.value.filter((item) => {
const mediaUsageFilterOptions = computed(() => {
const folder = activeFolder.value
const matchesFolder = systemManagedTab.value
? true
: (!folder || item.category === folder || item.category?.startsWith(`${folder}/`))
const mediaKind = activeMediaKind.value
const baseItems = scopeItems.value.filter((item) => {
const matchesFolder = systemManagedTab.value
? true
: (!folder || item.category === folder || item.category?.startsWith(`${folder}/`))
const matchesKind = mediaKind === 'all' || getMediaItemKind(item) === mediaKind
return matchesFolder && !isMediaItemLocked(item)
}).length)
return matchesFolder && matchesKind
})
return [
{ id: 'all', label: '전체', count: baseItems.length, unusedOnly: false },
{ id: 'unused', label: '미사용', count: baseItems.filter((item) => !isMediaItemLocked(item)).length, unusedOnly: true }
]
})
/**
* 상단 탭 전환 시 목록 상태를 초기화한다.
@@ -254,11 +263,16 @@ const setMediaKindFilter = (kind) => {
}
/**
* 미사용 미디어만 보기 필터를 토글한다.
* 미디어 사용 상태 필터를 선택한다.
* @param {boolean} unusedOnly - 미사용 항목만 볼지 여부
* @returns {void}
*/
const toggleUnusedMediaFilter = () => {
showUnusedOnly.value = !showUnusedOnly.value
const setMediaUsageFilter = (unusedOnly) => {
if (showUnusedOnly.value === unusedOnly) {
return
}
showUnusedOnly.value = unusedOnly
clearMediaSelection()
}
@@ -995,31 +1009,32 @@ watch(filteredMediaUrls, (urls) => {
>
</div>
</div>
<div
v-if="activeTab === 'library'"
class="admin-media__filters flex flex-wrap gap-1.5"
>
<div class="admin-media__filters flex flex-wrap gap-1.5">
<template v-if="activeTab === 'library'">
<button
v-for="option in mediaKindFilterOptions"
:key="option.id"
class="admin-media__kind-filter rounded-full border px-3 py-1.5 text-xs font-semibold transition"
:class="activeMediaKind === option.id ? 'border-[#15171a] bg-[#15171a] text-white' : 'border-line bg-white text-muted hover:text-ink'"
type="button"
@click="setMediaKindFilter(option.id)"
>
{{ option.label }}
<span class="ml-1 opacity-70">{{ option.count }}</span>
</button>
</template>
<button
v-for="option in mediaKindFilterOptions"
:key="option.id"
class="admin-media__kind-filter rounded-full border px-3 py-1.5 text-xs font-semibold transition"
:class="activeMediaKind === option.id ? 'border-[#15171a] bg-[#15171a] text-white' : 'border-line bg-white text-muted hover:text-ink'"
v-for="option in mediaUsageFilterOptions"
:key="`usage-${option.id}`"
class="admin-media__usage-filter rounded-full border px-3 py-1.5 text-xs font-semibold transition"
:class="showUnusedOnly === option.unusedOnly ? 'border-[#15171a] bg-[#15171a] text-white' : 'border-line bg-white text-muted hover:text-ink'"
type="button"
@click="setMediaKindFilter(option.id)"
:aria-pressed="showUnusedOnly === option.unusedOnly"
@click="setMediaUsageFilter(option.unusedOnly)"
>
{{ option.label }}
<span class="ml-1 opacity-70">{{ option.count }}</span>
</button>
<button
class="admin-media__unused-filter rounded-full border px-3 py-1.5 text-xs font-semibold transition"
:class="showUnusedOnly ? 'border-[#15171a] bg-[#15171a] text-white' : 'border-line bg-white text-muted hover:text-ink'"
type="button"
:aria-pressed="showUnusedOnly"
@click="toggleUnusedMediaFilter"
>
미사용
<span class="ml-1 opacity-70">{{ unusedMediaCount }}</span>
</button>
</div>
</div>