feat(ui): Contact Management v2 - existing contacts display and delete

Implements MVP v2 requirements from docs/UI-Contact-Management-MVP-v2.md:
- Display all contact types (CLI, REP, ROOM, SENS)
- Delete contacts with confirmation modal
- Capacity counter with color-coded warnings (green/yellow/red)
- Search by name or public key
- Filter by contact type
- Mobile-first responsive design

Backend changes:
- Add get_all_contacts_detailed() parser for meshcli contacts output
  - Handles Unicode characters, emoji, spaces in names
  - Backward parsing strategy using public_key_prefix as anchor
  - Returns detailed metadata for all contact types
- Add delete_contact() wrapper for remove_contact command
- Add GET /api/contacts/detailed endpoint
- Add POST /api/contacts/delete endpoint

Frontend changes:
- Add Existing Contacts section to contacts.html
  - Real-time search input
  - Type filter dropdown (All/CLI/REP/ROOM/SENS)
  - Color-coded type badges
  - Capacity counter with pulse animation for critical levels
- Add delete confirmation modal with danger styling
- Add complete contact management logic to contacts.js
  - loadExistingContacts(), applyFilters(), confirmDelete()
  - Copy public key to clipboard functionality

Documentation:
- Update README.md with usage instructions
- Add technotes/UI-Contact-Management-MVP-v2-completed.md
- Add docs/UI-Contact-Management-MVP-v2.md (specification)
- Add technotes/UI-Contact-Management-MVP-v1-completed.md (retroactive)

Tested with 263 real contacts including Unicode and edge cases.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2025-12-29 11:45:47 +01:00
parent 77c72ba62e
commit 8b709b9136
8 changed files with 2615 additions and 5 deletions
+134
View File
@@ -0,0 +1,134 @@
## Prompt dla Claude Code: Contact Management v2 (Existing Contacts + Delete + Counter)
Pracujesz w repo `mc-webui`. Mamy już działający moduł UI **Contact Management (MVP v1)**: toggle `manual_add_contacts` + lista `pending_contacts` + approve. Teraz robimy etap v2: zarządzanie istniejącymi kontaktami.
### Cel (v2)
Rozbuduj moduł **Contact Management** o:
1. Panel **Existing Contacts**
* wyświetla listę kontaktów, które są już na urządzeniu (CLI/REP/ROOM — wszystkie)
* umożliwia **usuwanie** wybranego kontaktu
* pokazuje licznik kontaktów `X / 350` (limit MeshCore)
* ma podstawowe filtrowanie i wyszukiwanie (lekko, bez frameworków)
2. UX:
* mobile-first (przyciski dotykowe, brak gęstych tabel)
* szybkie odświeżanie listy, spinner/placeholder
* potwierdzenie usunięcia (modal lub confirm), bo to operacja destrukcyjna
### Wymagania techniczne / integracja
* Frontend: Flask templates + Bootstrap5 + vanilla JS.
* Backend: mc-webui komunikuje się z meshcore-bridge przez HTTP (nie przez lokalny meshcli).
* Mamy już wzorzec: mc-webui ma endpointy `/api/...` i JS robi fetch do mc-webui, a mc-webui proxyuje do bridge.
### Dane i API
1. **Pobranie listy kontaktów**
* Dodaj w mc-webui endpoint:
* `GET /api/contacts/list`
* On powinien pobierać listę kontaktów z bridgea przez mechanizm CLI:
* albo istniejący endpoint w mc-webui (jeśli jest), który wykonuje `meshcli contacts` i zwraca JSON,
* albo dodaj nowy “proxy” do `/cli` z komendą `contacts` i następnie sparsuj output.
* Zależy mi na JSON po stronie mc-webui w formacie:
```json
{
"success": true,
"count": 123,
"limit": 350,
"contacts": [
{
"name": "BBKr",
"public_key_prefix": "efa30de66fce",
"type_label": "CLI|REP|ROOM|UNKNOWN",
"path_or_mode": "Flood|<path_hex>|",
"raw_line": "..."
}
]
}
```
* Parser:
* ma być odporny na emoji i spacje w nazwach
* nie zakładaj stałej liczby spacji — użyj regex / split z głową
* `raw_line` zachowaj do debugowania
2. **Usuwanie kontaktu**
* Dodaj w mc-webui endpoint:
* `POST /api/contacts/delete` body: `{ "name": "...", "public_key_prefix": "..." }`
* Na backendzie wywołaj komendę meshcli, która usuwa kontakt.
* Najpierw sprawdź w `meshcli -h` / dokumentacji projektu jak brzmi komenda (np. `del_contact` / `rm_contact` / `remove_contact` / `contact_del` — NIE zakładaj nazwy).
* Jeśli usuwanie po nazwie jest niepewne (kolizje), użyj najbezpieczniejszego selektora dostępnego w CLI (prefiks klucza jeśli wspierany).
* Po sukcesie: zwróć `{success:true}` i na froncie odśwież listę.
3. **Licznik 350**
* `count = len(contacts)` po parsowaniu.
* `limit = 350` stała w UI (do ewentualnej zmiany później).
* UI ma pokazywać badge:
* OK: zielony/neutralny
* ostrzegawczy gdy `count >= 300`
* alarm gdy `count >= 340`
(prosta logika, bez przesady)
### UI: Contact Management v2
W istniejącym widoku `Contact Management` dodaj pod sekcją pending nową sekcję:
**Existing Contacts**
* Toolbar:
* Search input (client-side filter po `name` i `public_key_prefix`)
* Filter dropdown: All / CLI / REP / ROOM / Unknown
* Refresh button
* Lista (list-group/cards):
* name (bold)
* type_label badge (CLI/REP/ROOM)
* public_key_prefix + copy
* optional: “path_or_mode” (jeśli masz z outputu)
* Delete button (danger, ikonka kosza)
* Delete flow:
* confirm (Bootstrap modal albo `confirm()`; prefer modal)
* po delete: toast + refresh
### Ograniczenia / bezpieczeństwo
* Nie zmieniaj bridgea jeśli nie musisz. Preferuj: mc-webui proxy do istniejącego `/cli` w bridge.
* Nie dodawaj WebSocketów. Refresh ręczny wystarczy.
* Wszystkie komentarze i nazwy w kodzie: po angielsku.
### Test plan
Dodaj do README sekcję “Contact Management v2”:
* jak odświeżyć listę kontaktów
* jak filtrować
* jak usunąć kontakt
* jak sprawdzić w logach, że komenda delete poszła do bridge
### Post-task checklist
1. Update README.md
2. Jeśli projekt ma plik notatek/technotes, dopisz krótką notkę o parsowaniu outputu `contacts`
3. Conventional commit: `feat: contact management v2 (existing contacts + delete + counter)`
---
### Drobna wskazówka
Output `meshcli contacts` wygląda zwykle jak tabela (kolumny: name / type / pubkey_prefix / path lub “Flood”). Parser ma być “best effort”: nie musisz perfekcyjnie odtwarzać wszystkich pól, ale **name + pubkey_prefix + type** muszą być wiarygodne.