fix: restore ntfyDashboardHost setting and add schema protection for global settings
The ntfyDashboardHost field was incorrectly removed in 6346e22b as part of
an unrelated FN-672 commit. This restores the setting to GlobalSettings (moved
from ProjectSettings where it was misplaced), re-adds the UI field and deep
link handling, and adds schema protection so unknown keys in settings.json
survive code-level schema changes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -190,6 +190,27 @@ function AppInner() {
|
||||
.catch(() => {/* keep empty array on failure */});
|
||||
}, []);
|
||||
|
||||
// Handle deep link to task on mount (from ntfy Click URLs)
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const taskId = params.get("task");
|
||||
if (!taskId) return;
|
||||
|
||||
// Clean URL immediately without reloading
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.delete("task");
|
||||
url.searchParams.delete("project");
|
||||
window.history.replaceState({}, "", url.toString());
|
||||
|
||||
fetchTaskDetail(taskId)
|
||||
.then((task) => {
|
||||
handleDetailOpen(task);
|
||||
})
|
||||
.catch(() => {
|
||||
addToast(`Task ${taskId} not found`, "error");
|
||||
});
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
// Favorite provider/model toggle handlers (shared by ListView bulk edit)
|
||||
const handleToggleFavorite = useCallback(async (provider: string) => {
|
||||
const currentFavorites = favoriteProviders;
|
||||
|
||||
@@ -1584,6 +1584,28 @@ export function SettingsModal({
|
||||
<small>When a task fails during execution (high priority)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="ntfyDashboardHost">Dashboard Hostname</label>
|
||||
<input
|
||||
id="ntfyDashboardHost"
|
||||
type="text"
|
||||
placeholder="http://localhost:3000"
|
||||
value={form.ntfyDashboardHost || ""}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
setForm((f) => ({ ...f, ntfyDashboardHost: val || undefined }));
|
||||
}}
|
||||
/>
|
||||
<small>
|
||||
Base URL for deep links in notifications. When set, clicking a notification
|
||||
opens the dashboard directly to the task.
|
||||
</small>
|
||||
{form.ntfyDashboardHost && !/^https?:\/\/.+/.test(form.ntfyDashboardHost) && (
|
||||
<small className="field-error">
|
||||
Must be a valid URL starting with http:// or https://
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user