clock/weather etc. default to 1/6 width; sizes store an integer span 1-12 (legacy s/m/l still accepted by /api/dashboard/layout). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
28 lines
851 B
JavaScript
28 lines
851 B
JavaScript
import { Router } from 'express';
|
||
import { z } from 'zod';
|
||
import { validate } from '../validate.js';
|
||
import { asyncWrap } from '../errors.js';
|
||
import { requireOwner } from '../cap.js';
|
||
import * as repo from '../../db/repos/dashboard_layout.js';
|
||
|
||
export const router = Router();
|
||
router.use(requireOwner);
|
||
|
||
const layoutSchema = z.object({
|
||
card_order: z.array(z.string()).default([]),
|
||
hidden: z.array(z.string()).default([]),
|
||
// Per-card width: an integer column span 1–12 (legacy 's'|'m'|'l' still accepted).
|
||
sizes: z.record(z.union([z.number().int().min(1).max(12), z.enum(['s', 'm', 'l'])])).default({})
|
||
});
|
||
|
||
router.get('/layout', asyncWrap(async (_req, res) => {
|
||
res.json(await repo.get());
|
||
}));
|
||
|
||
router.put('/layout',
|
||
validate({ body: layoutSchema }),
|
||
asyncWrap(async (req, res) => {
|
||
res.json(await repo.put(req.body));
|
||
})
|
||
);
|