# BanGUI — Task List
This document breaks the entire BanGUI project into development stages, ordered so that each stage builds on the previous one. Every task is described in prose with enough detail for a developer to begin work. References point to the relevant documentation.
---
## Stage: Config Page Cleanup & Improvements
These tasks refine the Configuration page UI. Each task is self-contained and can be completed independently. References point to the specific files that need modification.
---
### ✅ Task 1 — Remove the Export tab from the Config page
**Status:** Done — Removed `ExportTab` import, `"export"` from `TabValue`, the `` element, and the conditional render. `DocumentArrowDown24Regular` icon import also cleaned up.
**Goal:** Remove the "Export" tab entirely from the Configuration page. Users should no longer see the Export option in the tab bar, and its rendering logic should be cleaned up.
**Files to modify:**
- `frontend/src/pages/ConfigPage.tsx`
**What to do:**
1. Remove the `"export"` value from the `TabValue` union type.
2. Remove the `}>Export` element from the ``.
3. Remove the `{tab === "export" && }` conditional render from the tab content area.
4. Remove the `ExportTab` import from the component imports.
5. Remove the `DocumentArrowDown24Regular` icon import if it is no longer used elsewhere.
**Verification:** The Config page should render without the Export tab. No TypeScript errors. All other tabs continue to work.
---
### ✅ Task 2 — Remove "Refresh" and "Reload fail2ban" buttons from the Jails tab
**Status:** Done — Removed `buttonRow` div with both buttons, the `reloadMsg` `MessageBar`, all associated state (`reloading`, `reloadMsg`, `deactivating`) and handlers (`handleRefresh`, `handleReload`). Cleaned up `reloadAll` from `useJailConfigs()` destructure and `ArrowClockwise24Regular` icon import.
**Goal:** Remove the two action buttons ("Refresh" and "Reload fail2ban") that appear at the top of the Jails tab.
**Files to modify:**
- `frontend/src/components/config/JailsTab.tsx`
**What to do:**
1. In the `JailsTab` component (the public export, starting around line 584), locate the `
` block that renders the "Refresh" and "Reload fail2ban" buttons (around lines 722–740).
2. Remove the entire `
...
` block containing both buttons.
3. Remove the `reloadMsg` `` block that follows the button row (around lines 741–748), since it only displays messages from the reload action.
4. Clean up the now-unused state variables and handlers: `reloading`, `reloadMsg`, `setReloading`, `setReloadMsg`, `handleRefresh`, and `handleReload`.
5. Remove the `reloadAll` destructured value from the `useJailConfigs()` call if it is no longer used.
6. Remove the `ArrowClockwise24Regular` icon import if it is no longer used elsewhere in this file.
7. Keep `refresh` and `loadInactive` — they are still used by `handleDeactivate` and `handleActivated`.
**Verification:** The Jails tab no longer shows the two buttons or any reload message bar. Active and inactive jails still load and display correctly. Deactivate and activate flows still work.
---
### ✅ Task 3 — Add a "Create Config" button to the Jails tab
**Status:** Done — Created `CreateJailDialog.tsx`, wired `listHeader` prop into `ConfigListDetail` with an `Add24Regular` button, added `createDialogOpen` state. Dialog calls `createJailConfigFile` API and refreshes list on success. Exported from `config/index.ts`.
**Goal:** Add a button at the top of the Jails tab list pane that opens a dialog to create a new jail configuration file by name. This is analogous to the "Create Filter" button already present in the Filters tab.
**Files to modify:**
- `frontend/src/components/config/JailsTab.tsx` — add button + dialog trigger
- Optionally create a new `frontend/src/components/config/CreateJailDialog.tsx` dialog component
**What to do:**
1. Add a "Create Config" button at the top of the Jails tab. The recommended approach is to use the `listHeader` prop of ``, the same pattern used in `FiltersTab.tsx` (see lines 233–240). Pass a `} size="small">Create Config` as the `listHeader`.
2. Create a `CreateJailDialog` component (or inline the logic). The dialog should:
- Accept a name input from the user (the jail config file name, e.g. `my-custom-jail`).
- On confirm, call the existing `createJailConfigFile` API function from `frontend/src/api/config.ts` with `{ name, content: "# \n" }` as the payload.
- Show a loading state while the request is in flight.
- Display any errors from the API.
- On success, close the dialog and refresh the jail list (call `refresh()` and `loadInactive()`).
3. Wire the button's `onClick` to open the dialog, and handle the `onCreated` callback to refresh data.
**Reference:** See `CreateFilterDialog.tsx` for the established dialog pattern, and `JailFilesTab.tsx` lines 98–110 for the `createJailConfigFile` API usage.
**Verification:** Clicking "Create Config" opens a dialog. Entering a name and confirming creates a new jail config file. The new file appears in the jail list after creation.
---
### ✅ Task 4 — Remove the "Active" badge from the Filter and Action detail panes
**Status:** Done — Removed the `
` wrapper with Active/Inactive and "Has local override" badges from `FilterDetail` in `FiltersTab.tsx` and from `ActionDetail` in `ActionsTab.tsx`. Removed unused `Badge` import from both files.
**Goal:** Remove the `` component that shows "Active" or "Inactive" in the detail (right) pane of both the Filters tab and the Actions tab. The badge in the list pane (left side, inside `ConfigListDetail`) should remain — only the one in the detail section needs to be removed.
**Files to modify:**
- `frontend/src/components/config/FiltersTab.tsx`
- `frontend/src/components/config/ActionsTab.tsx`
**What to do in `FiltersTab.tsx`:**
1. In the `FilterDetail` component (around lines 90–112), locate the `
` block that wraps the Active/Inactive `` and the optional "Has local override" ``.
2. Remove this entire `
` block, including both badges inside it.
3. If the `Badge` import from `@fluentui/react-components` is no longer used in this file, remove it.
**What to do in `ActionsTab.tsx`:**
1. In the `ActionDetail` component (around lines 115–137), locate the same `
` block with the Active/Inactive badge and the "Has local override" badge.
2. Remove this entire `
` block, including both badges.
3. Clean up unused `Badge` import if applicable.
**Verification:** Selecting a filter or action in the list still works. The detail pane no longer shows the Active/Inactive badge or the "Has local override" badge. The list pane badges are unaffected.
---
### ✅ Task 5 — Fix Jail log paths: remove path text spans, populate editable fields
**Status:** Done — Replaced the read-only `` elements for existing log paths with editable `` fields, each with an `onChange` handler that updates the corresponding index in `logPaths` state. Delete button preserved.
**Goal:** In the active jail detail pane, the "Log Paths" field currently renders each existing log path as a read-only `` text element with a delete button. The actual `` field below is always empty and is only used for adding new paths. The user wants to remove the read-only text spans and instead make each log path an editable field.
**Files to modify:**
- `frontend/src/components/config/JailsTab.tsx`
**What to do:**
1. In the `JailConfigDetail` component, locate the `` block (around lines 292–350).
2. Remove the read-only span list that renders existing log paths:
```tsx
{logPaths.length === 0 ? (
(none)
) : (
logPaths.map((p) => (
{p}
))
)}
```
3. Replace it with editable `` fields for each existing log path. Each row should have:
- An `` pre-filled with the path value (`value={p}`), editable.
- An `onChange` handler that updates the corresponding entry in the `logPaths` state array.
- The same delete button (reuse the existing `handleDeleteLogPath` callback).
4. Keep the "Add new log path" form at the bottom unchanged (the `` with placeholder, `` for tail/head, and "Add" button).
5. Ensure the `logPaths` state is properly initialized from `jail.log_paths` (this is already the case at line 87).
**Implementation hint:** Map over `logPaths` with an index, render an `` for each, and on change update the array at that index. Example:
```tsx
logPaths.map((p, i) => (
))
```
**Verification:** When selecting an active jail that has log paths configured, the paths appear as editable input fields (not plain text). The input values can be modified. The delete button still works. The "Add" form at the bottom still works for adding new paths.