upd
This commit is contained in:
@@ -223,7 +223,7 @@ itemsRouter.post('/deselect', (req, res) => {
|
||||
* @openapi
|
||||
* /api/items/reorder:
|
||||
* put:
|
||||
* summary: Queue a reorder of selected items
|
||||
* summary: Move a selected item after another item (works with filtered lists)
|
||||
* tags: [Items]
|
||||
* requestBody:
|
||||
* required: true
|
||||
@@ -231,12 +231,15 @@ itemsRouter.post('/deselect', (req, res) => {
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required: [ids]
|
||||
* required: [id]
|
||||
* properties:
|
||||
* ids:
|
||||
* type: array
|
||||
* items:
|
||||
* type: integer
|
||||
* id:
|
||||
* type: integer
|
||||
* description: ID of the item being moved
|
||||
* afterId:
|
||||
* type: integer
|
||||
* nullable: true
|
||||
* description: ID of the item to place the moved item after. Null moves to the beginning.
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Reorder queued
|
||||
@@ -247,13 +250,19 @@ itemsRouter.post('/deselect', (req, res) => {
|
||||
* properties:
|
||||
* queued:
|
||||
* type: boolean
|
||||
* 400:
|
||||
* description: Invalid parameters
|
||||
*/
|
||||
itemsRouter.put('/reorder', (req, res) => {
|
||||
const ids = req.body?.ids
|
||||
if (!Array.isArray(ids)) {
|
||||
res.status(400).json({ error: 'ids must be an array' })
|
||||
const { id, afterId } = req.body ?? {}
|
||||
if (typeof id !== 'number' || !Number.isInteger(id)) {
|
||||
res.status(400).json({ error: 'id must be an integer' })
|
||||
return
|
||||
}
|
||||
queue.enqueue({ type: 'reorder', ids })
|
||||
if (afterId !== null && afterId !== undefined && (typeof afterId !== 'number' || !Number.isInteger(afterId))) {
|
||||
res.status(400).json({ error: 'afterId must be an integer or null' })
|
||||
return
|
||||
}
|
||||
queue.enqueue({ type: 'reorder', id, afterId: afterId ?? null })
|
||||
res.json({ queued: true })
|
||||
})
|
||||
|
||||
@@ -71,9 +71,15 @@ export function deselectItem(id: number): boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
export function reorderSelected(ids: number[]): void {
|
||||
orderedSelected.length = 0
|
||||
for (const id of ids) {
|
||||
if (selectedIds.has(id)) orderedSelected.push(id)
|
||||
export function reorderItem(id: number, afterId: number | null): void {
|
||||
const idx = orderedSelected.indexOf(id)
|
||||
if (idx === -1) return
|
||||
orderedSelected.splice(idx, 1)
|
||||
if (afterId === null) {
|
||||
orderedSelected.unshift(id)
|
||||
}
|
||||
else {
|
||||
const afterIdx = orderedSelected.indexOf(afterId)
|
||||
orderedSelected.splice(afterIdx === -1 ? orderedSelected.length : afterIdx + 1, 0, id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,26 +3,23 @@ import * as store from './itemsStore.js'
|
||||
interface AddTask { type: 'add', id: number }
|
||||
interface SelectTask { type: 'select', id: number }
|
||||
interface DeselectTask { type: 'deselect', id: number }
|
||||
interface ReorderTask { type: 'reorder', ids: number[] }
|
||||
interface ReorderTask { type: 'reorder', id: number, afterId: number | null }
|
||||
|
||||
type Task = AddTask | SelectTask | DeselectTask | ReorderTask
|
||||
|
||||
class RequestQueue {
|
||||
private addQueue: AddTask[] = []
|
||||
private actionQueue: ReorderTask[] = []
|
||||
private reorderQueue: ReorderTask[] = []
|
||||
private pendingKeys = new Set<string>()
|
||||
private pendingReorder: ReorderTask | null = null
|
||||
|
||||
constructor() {
|
||||
setInterval(() => this.flushAdd(), 10_000)
|
||||
setInterval(() => this.flushActions(), 1_000)
|
||||
setInterval(() => this.flushReorder(), 1_000)
|
||||
}
|
||||
|
||||
enqueue(task: Task): boolean {
|
||||
if (task.type === 'reorder') {
|
||||
this.pendingReorder = task
|
||||
this.actionQueue = this.actionQueue.filter(t => t.type !== 'reorder')
|
||||
this.actionQueue.push(task)
|
||||
this.reorderQueue.push(task)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -51,13 +48,10 @@ class RequestQueue {
|
||||
}
|
||||
}
|
||||
|
||||
private flushActions(): void {
|
||||
const batch = this.actionQueue.splice(0)
|
||||
this.pendingReorder = null
|
||||
private flushReorder(): void {
|
||||
const batch = this.reorderQueue.splice(0)
|
||||
for (const task of batch) {
|
||||
if (task.type === 'reorder') {
|
||||
store.reorderSelected(task.ids)
|
||||
}
|
||||
store.reorderItem(task.id, task.afterId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user