diff --git a/Docs/Tasks.md b/Docs/Tasks.md index 621bd4a..3b3dbb3 100644 --- a/Docs/Tasks.md +++ b/Docs/Tasks.md @@ -4,203 +4,48 @@ This document breaks the entire BanGUI project into development stages, ordered --- -## ✅ Task 1 — Convert Backend, Log Encoding, and Date Pattern to Dropdowns in Jail Config +## Task 1 — Fix vertical alignment of "DNS Mode" dropdown with "Date Pattern" dropdown in Jail Configuration ✅ DONE -**Completed.** Backend and Log Encoding are now `` control sits higher. This causes the two dropdowns to be vertically misaligned. ---- +### Location in code -## ✅ Task 3 — Give Inactive Jail Configs the Same GUI as Active Ones +- Around **line 321** of `JailsTab.tsx` there is a `
` that contains both fields. +- The "Date Pattern" field (lines ~322–341) uses `` with a `hint` prop. +- The "DNS Mode" field (lines ~342–353) uses `` fields (Backend and Log Encoding are read-only, Date Pattern is a free-text input). These should be `` fields with `` fields. Wire their `onChange` to local state and include them in the auto-save payload sent to the backend. -2. The backend model at `backend/app/models/config.py` line 67 already accepts `backend: str` and `log_encoding: str`, so no backend changes are needed unless you want to add server-side validation. -3. Date Pattern should use a Fluent UI `Combobox` (editable dropdown) instead of a `Select`, so users can still type a custom pattern. -4. Follow the existing DNS Mode dropdown pattern at lines 271–280 of `JailsTab.tsx` as a reference for styling and onChange handling. - ---- - -## Task 2 — Fix Raw Action Configuration Always Blank in Actions Tab - -**Problem:** In the Config → Actions page, the **"Raw Action Configuration"** accordion section is always blank when expanded. - -**Where to look:** - -- **`frontend/src/components/config/ActionsTab.tsx`** — the `ActionDetail` component (lines 65–185). The `fetchRaw` callback (line 82) calls `fetchActionFile(action.name)` and returns `result.content`. -- **`frontend/src/components/config/RawConfigSection.tsx`** — the collapsible raw editor. It uses a `loadedRef` (line 62) to fetch content only on first accordion expansion, and never resets. -- **`frontend/src/api/config.ts`** line 257 — `fetchActionFile()` calls `GET /config/actions/{name}`. -- **`backend/app/services/file_config_service.py`** line 734 — `get_action_file()` reads from `action.d/` using `_read_conf_file()`, which tries `.conf` first, then `.local`. - -**Root cause investigation — check these two possibilities:** - -### Possibility A: Stale `loadedRef` across action switches -`ActionDetail` at line 301 of `ActionsTab.tsx` is rendered **without a `key` prop**: -```tsx - { setAssignOpen(true); }} - onRemovedFromJail={handleRemovedFromJail} -/> -``` -Without `key={selectedAction.name}`, React reuses the same component instance when switching between actions. The `RawConfigSection` inside `ActionDetail` keeps its `loadedRef.current = true` from a previous expansion, so it never re-fetches for the new action. - -**Fix:** Add `key={selectedAction.name}` to `ActionDetail` so it fully unmounts/remounts on action switch, resetting all internal state including `loadedRef`. - -### Possibility B: Backend returning empty content -The `_read_conf_file` function at `file_config_service.py` line 492 tries `.conf` first then `.local`. If the action only has a `.conf` file and it's readable, content should be returned. Verify by: -1. Checking browser DevTools Network tab for the `GET /api/config/actions/{name}` response body. -2. Confirming the response has a non-empty `content` field. - -**Implementation:** - -1. Add `key={selectedAction.name}` to the `` component in `ActionsTab.tsx` line 301. -2. Test by selecting different actions and expanding the raw config accordion — each should show the correct file content. -3. If the backend is returning empty content, debug `_read_conf_file` to check which file path it resolves and whether it can read the file. - ---- - -## Task 3 — Give Inactive Jail Configs the Same GUI as Active Ones - -**Problem:** In the Config → Jails page, **inactive jails** show a minimal read-only preview (`InactiveJailDetail` component) with only basic fields (filter, port, ban time, find time, max retry, log paths, actions, source file). **Active jails** like `bangui-sim` show a full editable form (`JailConfigDetail` component) with all fields including Backend, Log Encoding, Date Pattern, DNS Mode, Prefix Regex, editable log paths, Fail/Ignore Regex lists, Ban-time Escalation, and a Raw Configuration editor. - -The inactive jail detail should display the same rich GUI as the active one — same layout, same fields — but in read-only mode (since the jail is not running on fail2ban). - -**Where to change:** - -- **`frontend/src/components/config/JailsTab.tsx`**: - - `InactiveJailDetail` component (lines 493–580): the current minimal read-only view. - - `JailConfigDetail` component (lines ~200–490): the full editable form for active jails. - - Selection logic at lines 721–752 determines which component renders based on jail kind. - -- **`frontend/src/types/config.ts`** — `InactiveJail` type (around line 484) defines the data shape for inactive jails. Compare with `JailConfig` to see which fields are missing. - -- **Backend** — check that the inactive jail endpoint returns enough data. The backend model `InactiveJail` may need additional fields (backend, log_encoding, date_pattern, dns_mode, prefix_regex, failregex, ignoreregex, ban-time escalation settings) to match the active `JailConfig` model. - -**Implementation approach:** - -1. **Extend the `InactiveJail` model** in the backend (`backend/app/models/config.py`) to include all fields that `JailConfig` has: `backend`, `log_encoding`, `date_pattern`, `usedns`, `prefixregex`, `failregex`, `ignoreregex`, `bantime_increment` (escalation settings), etc. -2. **Update the backend service** that parses inactive jail configs to extract these additional fields from the `.conf`/`.local` files. -3. **Rewrite `InactiveJailDetail`** to mirror `JailConfigDetail`'s layout but with all fields in **read-only** mode (all `` have `readOnly`, all `