feat: SQL filtering, Users admin tab, dashboard polish
- Move ticket filtering from in-memory to SQL WHERE clauses (queue_id, status, owner use Drizzle eq/isNull; text search uses ilike; custom field filters use EXISTS subqueries) - Add limit param to GET /tickets - Add POST/PATCH/DELETE /users routes - Add Users tab to admin page with create/edit/delete - Smart widget positioning in dashboard (3-column grid fill) - Show pattern hint below CF inputs in New Ticket dialog Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -97,7 +97,15 @@ export default function DashboardPage({ params }: { params: Promise<{ id: string
|
||||
const handleAddWidget = async () => {
|
||||
if (!addViewId || !addTitle.trim()) return;
|
||||
setAdding(true);
|
||||
const pos = { x: 0, y: widgets.length, w: 4, h: 2 };
|
||||
// Smart positioning: fill a 3-column grid (4 units each in 12-col grid)
|
||||
const COLS = 3; const W = 4; const H = 2;
|
||||
const occupied = new Set(widgets.map((w) => `${w.position.x},${w.position.y}`));
|
||||
let x = 0; let y = 0;
|
||||
while (occupied.has(`${x},${y}`)) {
|
||||
x += W;
|
||||
if (x >= COLS * W) { x = 0; y += H; }
|
||||
}
|
||||
const pos = { x, y, w: W, h: H };
|
||||
const config = addType === "grouped_counts" ? { group_by: addGroupBy } : {};
|
||||
const { data, error } = await createWidget(id, {
|
||||
view_id: addViewId,
|
||||
|
||||
Reference in New Issue
Block a user