feat(HAI-004): add settings modal with GET/PUT API endpoints
- Extend config schema and store helpers to support settings persistence - Add GET/PUT /settings REST API endpoints in dashboard routes - Create SettingsModal component with frontend API wiring - Add settings trigger button to Header and integrate into App - Add CSS styles for settings modal and header actions
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
export { COLUMNS, COLUMN_LABELS, COLUMN_DESCRIPTIONS, VALID_TRANSITIONS } from "./types.js";
|
||||
export type { Column, Task, TaskCreateInput, TaskDetail, BoardConfig, MergeResult } from "./types.js";
|
||||
export { COLUMNS, COLUMN_LABELS, COLUMN_DESCRIPTIONS, VALID_TRANSITIONS, DEFAULT_SETTINGS } from "./types.js";
|
||||
export type { Column, Task, TaskCreateInput, TaskDetail, BoardConfig, MergeResult, Settings } from "./types.js";
|
||||
export { TaskStore } from "./store.js";
|
||||
export { canTransition, getValidTransitions, resolveDependencyOrder } from "./board.js";
|
||||
|
||||
@@ -3,8 +3,8 @@ import { execSync } from "node:child_process";
|
||||
import { mkdir, readFile, writeFile, readdir } from "node:fs/promises";
|
||||
import { join, sep } from "node:path";
|
||||
import { existsSync, watch, type FSWatcher } from "node:fs";
|
||||
import type { Task, TaskDetail, TaskCreateInput, BoardConfig, Column, MergeResult } from "./types.js";
|
||||
import { VALID_TRANSITIONS } from "./types.js";
|
||||
import type { Task, TaskDetail, TaskCreateInput, BoardConfig, Column, MergeResult, Settings } from "./types.js";
|
||||
import { VALID_TRANSITIONS, DEFAULT_SETTINGS } from "./types.js";
|
||||
|
||||
export interface TaskStoreEvents {
|
||||
"task:created": [task: Task];
|
||||
@@ -44,6 +44,20 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
}
|
||||
}
|
||||
|
||||
async getSettings(): Promise<Settings> {
|
||||
const config = await this.readConfig();
|
||||
return { ...DEFAULT_SETTINGS, ...config.settings };
|
||||
}
|
||||
|
||||
async updateSettings(patch: Partial<Settings>): Promise<Settings> {
|
||||
const config = await this.readConfig();
|
||||
const current = { ...DEFAULT_SETTINGS, ...config.settings };
|
||||
const updated = { ...current, ...patch };
|
||||
config.settings = updated;
|
||||
await this.writeConfig(config);
|
||||
return updated;
|
||||
}
|
||||
|
||||
private async readConfig(): Promise<BoardConfig> {
|
||||
const data = await readFile(this.configPath, "utf-8");
|
||||
return JSON.parse(data);
|
||||
|
||||
@@ -24,8 +24,19 @@ export interface TaskCreateInput {
|
||||
dependencies?: string[];
|
||||
}
|
||||
|
||||
export interface Settings {
|
||||
maxConcurrent: number;
|
||||
pollIntervalMs: number;
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: Settings = {
|
||||
maxConcurrent: 2,
|
||||
pollIntervalMs: 15000,
|
||||
};
|
||||
|
||||
export interface BoardConfig {
|
||||
nextId: number;
|
||||
settings?: Settings;
|
||||
}
|
||||
|
||||
export interface MergeResult {
|
||||
|
||||
Reference in New Issue
Block a user