From 543ee6628d1d426b02499cff70a18f505028d532 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Fri, 31 Jul 2026 11:11:47 +0300 Subject: [PATCH] add media order controls --- frontend/rabbi_gerzi/src/stores/mediaSets.ts | 28 +++++ frontend/rabbi_gerzi/src/views/MediaPage.vue | 107 ++++++++++++++++++- 2 files changed, 130 insertions(+), 5 deletions(-) diff --git a/frontend/rabbi_gerzi/src/stores/mediaSets.ts b/frontend/rabbi_gerzi/src/stores/mediaSets.ts index e669e85..f265fe7 100644 --- a/frontend/rabbi_gerzi/src/stores/mediaSets.ts +++ b/frontend/rabbi_gerzi/src/stores/mediaSets.ts @@ -43,6 +43,7 @@ export const useMediaSetsStore = defineStore('mediaSets', () => { const isCreating = ref(false) const isUpdating = ref(false) const isDeleting = ref(false) + const isReordering = ref(false) const createError = ref(null) const updateError = ref(null) const deleteError = ref(null) @@ -187,6 +188,31 @@ export const useMediaSetsStore = defineStore('mediaSets', () => { } } + async function reorderSets(setIds: number[]): Promise { + isReordering.value = true + + try { + const response = await fetch(`${API_BASE_URL}/api/sets/order`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + credentials: 'include', + body: JSON.stringify({ setIds }), + }) + + if (!response.ok) { + return false + } + + const data: SetsResponse = await response.json() + sets.value = data.sets + return true + } catch { + return false + } finally { + isReordering.value = false + } + } + async function errorMessage( response: Response, fallbackMessage: string, @@ -206,6 +232,7 @@ export const useMediaSetsStore = defineStore('mediaSets', () => { isCreating, isUpdating, isDeleting, + isReordering, createError, updateError, deleteError, @@ -213,5 +240,6 @@ export const useMediaSetsStore = defineStore('mediaSets', () => { createSet, updateSet, deleteSet, + reorderSets, } }) diff --git a/frontend/rabbi_gerzi/src/views/MediaPage.vue b/frontend/rabbi_gerzi/src/views/MediaPage.vue index 07f407b..1e04fa9 100644 --- a/frontend/rabbi_gerzi/src/views/MediaPage.vue +++ b/frontend/rabbi_gerzi/src/views/MediaPage.vue @@ -3,6 +3,8 @@ import { storeToRefs } from 'pinia' import { computed, onMounted, reactive, ref } from 'vue' import { AlertTriangle as AlertTriangleIcon, + ChevronDown as ChevronDownIcon, + ChevronUp as ChevronUpIcon, Pencil as PencilIcon, Plus as PlusIcon, Trash2 as TrashIcon, @@ -18,6 +20,8 @@ interface CreateSetForm { description: string } +type SetMoveDirection = 'up' | 'down' + const router = useRouter() const authStore = useAuthStore() const mediaSetsStore = useMediaSetsStore() @@ -28,6 +32,7 @@ const { isCreating, isUpdating, isDeleting, + isReordering, createError, updateError, deleteError, @@ -42,6 +47,7 @@ const localCreateError = ref(null) const localEditError = ref(null) const editingSet = ref(null) const deletingSet = ref(null) +const setOrderStatus = ref(null) const createSetForm = reactive({ name: '', @@ -231,6 +237,42 @@ async function handleDeleteSet(): Promise { deletingSet.value = null } +async function handleMoveSet( + setId: number, + direction: SetMoveDirection, +): Promise { + const currentIndex = sets.value.findIndex((mediaSet) => { + return mediaSet.id === setId + }) + if (currentIndex === -1) { + return + } + + const targetIndex = direction === 'up' ? currentIndex - 1 : currentIndex + 1 + if (targetIndex < 0 || targetIndex >= sets.value.length) { + return + } + + const reorderedSets = [...sets.value] + const movingSet = reorderedSets[currentIndex] + const targetSet = reorderedSets[targetIndex] + if (movingSet === undefined || targetSet === undefined) { + return + } + + reorderedSets[currentIndex] = targetSet + reorderedSets[targetIndex] = movingSet + const setIds = reorderedSets.map((mediaSet) => { + return mediaSet.id + }) + + setOrderStatus.value = null + const saved = await mediaSetsStore.reorderSets(setIds) + if (saved) { + setOrderStatus.value = 'Set order saved' + } +} + function openSet(mediaSet: MediaSet): void { if (mediaSet.rootElementId === null) { return @@ -287,6 +329,14 @@ function resetEditSetForm(): void {
+

+ {{ setOrderStatus }} +

Loading media sets...

-