Arrange priority
This commit is contained in:
parent
74583a1c73
commit
c907f40508
2 changed files with 82 additions and 17 deletions
|
|
@ -7,6 +7,7 @@
|
||||||
use App\Models\Scenario;
|
use App\Models\Scenario;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
|
||||||
class BucketController extends Controller
|
class BucketController extends Controller
|
||||||
|
|
@ -198,20 +199,28 @@ private function updateBucketPriority(Bucket $bucket, int $newPriority): void
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($newPriority < $oldPriority) {
|
// Use database transaction to handle constraint conflicts
|
||||||
// Moving up - shift others down
|
DB::transaction(function () use ($bucket, $scenario, $oldPriority, $newPriority) {
|
||||||
$scenario->buckets()
|
// Temporarily set the moving bucket to a high priority to avoid conflicts
|
||||||
->where('id', '!=', $bucket->id)
|
$tempPriority = $scenario->buckets()->max('priority') + 100;
|
||||||
->whereBetween('priority', [$newPriority, $oldPriority - 1])
|
$bucket->update(['priority' => $tempPriority]);
|
||||||
->increment('priority');
|
|
||||||
} else {
|
|
||||||
// Moving down - shift others up
|
|
||||||
$scenario->buckets()
|
|
||||||
->where('id', '!=', $bucket->id)
|
|
||||||
->whereBetween('priority', [$oldPriority + 1, $newPriority])
|
|
||||||
->decrement('priority');
|
|
||||||
}
|
|
||||||
|
|
||||||
$bucket->update(['priority' => $newPriority]);
|
if ($newPriority < $oldPriority) {
|
||||||
|
// Moving up - shift others down
|
||||||
|
$scenario->buckets()
|
||||||
|
->where('id', '!=', $bucket->id)
|
||||||
|
->whereBetween('priority', [$newPriority, $oldPriority - 1])
|
||||||
|
->increment('priority');
|
||||||
|
} else {
|
||||||
|
// Moving down - shift others up
|
||||||
|
$scenario->buckets()
|
||||||
|
->where('id', '!=', $bucket->id)
|
||||||
|
->whereBetween('priority', [$oldPriority + 1, $newPriority])
|
||||||
|
->decrement('priority');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, set the bucket to its new priority
|
||||||
|
$bucket->update(['priority' => $newPriority]);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,40 @@ export default function Show({ scenario, buckets }: Props) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handlePriorityChange = async (bucketId: number, direction: 'up' | 'down') => {
|
||||||
|
const bucket = buckets.find(b => b.id === bucketId);
|
||||||
|
if (!bucket) return;
|
||||||
|
|
||||||
|
const newPriority = direction === 'up' ? bucket.priority - 1 : bucket.priority + 1;
|
||||||
|
|
||||||
|
// Don't allow moving beyond bounds
|
||||||
|
if (newPriority < 1 || newPriority > buckets.length) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/buckets/${bucketId}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: bucket.name,
|
||||||
|
allocation_type: bucket.allocation_type,
|
||||||
|
allocation_value: bucket.allocation_value,
|
||||||
|
priority: newPriority
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
router.reload({ only: ['buckets'] });
|
||||||
|
} else {
|
||||||
|
console.error('Failed to update bucket priority');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error updating bucket priority:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head title={scenario.name} />
|
<Head title={scenario.name} />
|
||||||
|
|
@ -123,9 +157,31 @@ export default function Show({ scenario, buckets }: Props) {
|
||||||
Priority {bucket.priority} • {bucket.allocation_type_label}
|
Priority {bucket.priority} • {bucket.allocation_type_label}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<span className="rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800">
|
<div className="flex items-center gap-1">
|
||||||
#{bucket.priority}
|
<button
|
||||||
</span>
|
onClick={() => handlePriorityChange(bucket.id, 'up')}
|
||||||
|
disabled={bucket.priority === 1}
|
||||||
|
className="p-1 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
|
title="Move up in priority"
|
||||||
|
>
|
||||||
|
<svg className="w-3 h-3 text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handlePriorityChange(bucket.id, 'down')}
|
||||||
|
disabled={bucket.priority === buckets.length}
|
||||||
|
className="p-1 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
|
title="Move down in priority"
|
||||||
|
>
|
||||||
|
<svg className="w-3 h-3 text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<span className="rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800">
|
||||||
|
#{bucket.priority}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue