From 03ced8e327470491fa5b27b42fbc4cc744e98a33 Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Fri, 9 Jan 2026 21:19:43 -0300 Subject: [PATCH] Fix dropdown menu duplicates and reorder items - Fix CSS breakpoints to sync header tabs with dropdown menu visibility - Add missing apps (docs, sheet, slides, social) to hide/show logic - Remove incorrect paper breakpoint (not in header tabs) - Reorder dropdown: dynamic items first (header tab apps), then static items - Move People after dynamic items (after social) - Remove duplicate Social entry from dropdown menu - All 26 suite app folders have menu entries (no orphans) --- PROMPT.md | 49 ++++++++++- botserver | 2 +- botui | 2 +- config/directory_config.json | 20 ----- scripts/check-i18n.sh | 153 ----------------------------------- 5 files changed, 49 insertions(+), 177 deletions(-) delete mode 100644 config/directory_config.json delete mode 100755 scripts/check-i18n.sh diff --git a/PROMPT.md b/PROMPT.md index 6653f71..927d020 100644 --- a/PROMPT.md +++ b/PROMPT.md @@ -219,9 +219,9 @@ match x { ``` gb/ ├── botapp/ # Desktop app (Tauri) -├── botserver/ # Main server (Axum API) +├── botserver/ # Main server (Axum API) - port 8088 ├── botlib/ # Shared library -├── botui/ # Web UI +├── botui/ # Web UI server - port 3000 ├── botbook/ # Documentation ├── bottest/ # Integration tests └── PROMPT.md # THIS FILE @@ -229,6 +229,51 @@ gb/ --- +## 🖥️ UI Architecture (botui + botserver) + +### Two Servers During Development + +| Server | Port | Purpose | +|--------|------|---------| +| **botui** | 3000 | Serves UI files + proxies API to botserver | +| **botserver** | 8088 | Backend API + embedded UI fallback | + +### How It Works + +``` +Browser → localhost:3000 → botui (serves HTML/CSS/JS) + → /api/* proxied to botserver:8088 + → /suite/* served from botui/ui/suite/ +``` + +### Adding New Suite Apps + +When adding a new app (e.g., `video`, `learn`): + +1. Create folder: `botui/ui/suite//` +2. Add to `SUITE_DIRS` in `botui/src/ui_server/mod.rs`: +```rust +const SUITE_DIRS: &[&str] = &[ + "chat", "mail", "calendar", ..., + "video", // ← add new app here + "learn", +]; +``` +3. Rebuild botui: `cargo build -p botui` +4. Add menu entry in `botui/ui/suite/index.html` + +### Hot Reload + +- **UI files (HTML/CSS/JS)**: Edit & refresh browser (no restart) +- **botui Rust code**: Rebuild + restart botui +- **botserver Rust code**: Rebuild + restart botserver + +### Production (Single Binary) + +When `botui/ui/suite/` folder not found, botserver uses **embedded UI** compiled into binary via `rust-embed`. + +--- + ## 🚀 OFFLINE ERROR FIXING WORKFLOW ### Step 1: Analyze Error List diff --git a/botserver b/botserver index a8444f0..1b0a5cb 160000 --- a/botserver +++ b/botserver @@ -1 +1 @@ -Subproject commit a8444f0d2400f60d966341c59a7a3df4577c69d2 +Subproject commit 1b0a5cbec7f4a0e8576757f36d04a89c80f9406a diff --git a/botui b/botui index cb33a75..80c91f6 160000 --- a/botui +++ b/botui @@ -1 +1 @@ -Subproject commit cb33a75d39f2cf53de952622f72e8e6ef4ea0690 +Subproject commit 80c91f63046dd5d11e2874bb355ec2d967a70b55 diff --git a/config/directory_config.json b/config/directory_config.json deleted file mode 100644 index 4b987aa..0000000 --- a/config/directory_config.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "base_url": "http://localhost:8300", - "default_org": { - "id": "353226116074307598", - "name": "default", - "domain": "default.localhost" - }, - "default_user": { - "id": "admin", - "username": "admin", - "email": "admin@localhost", - "password": "", - "first_name": "Admin", - "last_name": "User" - }, - "admin_token": "XzjmsXoVy7mDKK8gyWtJNp3w3enVW3EKGPdfLbz0nX9vMsDpg27UtAROOcKMXsoc0fDwv98", - "project_id": "", - "client_id": "353226118456737806", - "client_secret": "5uH0r2elIQ3xji4N4aTOARZjEDDUWC0cfIybGaFkvhwlA6gvygMHOdmodVg4K6PJ" -} \ No newline at end of file diff --git a/scripts/check-i18n.sh b/scripts/check-i18n.sh deleted file mode 100755 index bfea672..0000000 --- a/scripts/check-i18n.sh +++ /dev/null @@ -1,153 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -LOCALES_DIR="${1:-locales}" -BASE_LOCALE="${2:-en}" - -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' - -if [ ! -d "$LOCALES_DIR" ]; then - echo -e "${RED}Error: Locales directory not found: $LOCALES_DIR${NC}" - exit 1 -fi - -if [ ! -d "$LOCALES_DIR/$BASE_LOCALE" ]; then - echo -e "${RED}Error: Base locale not found: $LOCALES_DIR/$BASE_LOCALE${NC}" - exit 1 -fi - -extract_keys() { - local file="$1" - grep -E '^[a-z][a-z0-9-]*\s*=' "$file" 2>/dev/null | cut -d'=' -f1 | tr -d ' ' | sort -u -} - -count_keys() { - local dir="$1" - local count=0 - for file in "$dir"/*.ftl; do - if [ -f "$file" ]; then - local file_count - file_count=$(extract_keys "$file" | wc -l) - count=$((count + file_count)) - fi - done - echo "$count" -} - -echo "========================================" -echo " General Bots i18n Coverage Report" -echo "========================================" -echo "" - -base_count=$(count_keys "$LOCALES_DIR/$BASE_LOCALE") -echo -e "Base locale: ${GREEN}$BASE_LOCALE${NC} ($base_count keys)" -echo "" - -declare -A all_base_keys -for file in "$LOCALES_DIR/$BASE_LOCALE"/*.ftl; do - if [ -f "$file" ]; then - filename=$(basename "$file") - while IFS= read -r key; do - all_base_keys["$filename:$key"]=1 - done < <(extract_keys "$file") - fi -done - -total_missing=0 -total_extra=0 - -for locale_dir in "$LOCALES_DIR"/*/; do - locale=$(basename "$locale_dir") - - if [ "$locale" = "$BASE_LOCALE" ]; then - continue - fi - - locale_count=$(count_keys "$locale_dir") - - if [ "$base_count" -gt 0 ]; then - coverage=$((locale_count * 100 / base_count)) - else - coverage=0 - fi - - if [ "$coverage" -ge 90 ]; then - color=$GREEN - elif [ "$coverage" -ge 50 ]; then - color=$YELLOW - else - color=$RED - fi - - echo -e "Locale: ${color}$locale${NC} - $locale_count/$base_count keys (${coverage}%)" - - missing_keys=() - extra_keys=() - - for file in "$LOCALES_DIR/$BASE_LOCALE"/*.ftl; do - if [ -f "$file" ]; then - filename=$(basename "$file") - target_file="$locale_dir/$filename" - - if [ ! -f "$target_file" ]; then - while IFS= read -r key; do - missing_keys+=("$filename: $key") - done < <(extract_keys "$file") - else - while IFS= read -r key; do - if ! grep -q "^$key\s*=" "$target_file" 2>/dev/null; then - missing_keys+=("$filename: $key") - fi - done < <(extract_keys "$file") - - while IFS= read -r key; do - if ! grep -q "^$key\s*=" "$file" 2>/dev/null; then - extra_keys+=("$filename: $key") - fi - done < <(extract_keys "$target_file") - fi - fi - done - - if [ ${#missing_keys[@]} -gt 0 ]; then - echo -e " ${RED}Missing keys (${#missing_keys[@]}):${NC}" - for key in "${missing_keys[@]:0:10}"; do - echo " - $key" - done - if [ ${#missing_keys[@]} -gt 10 ]; then - echo " ... and $((${#missing_keys[@]} - 10)) more" - fi - total_missing=$((total_missing + ${#missing_keys[@]})) - fi - - if [ ${#extra_keys[@]} -gt 0 ]; then - echo -e " ${YELLOW}Extra keys (${#extra_keys[@]}):${NC}" - for key in "${extra_keys[@]:0:5}"; do - echo " - $key" - done - if [ ${#extra_keys[@]} -gt 5 ]; then - echo " ... and $((${#extra_keys[@]} - 5)) more" - fi - total_extra=$((total_extra + ${#extra_keys[@]})) - fi - - echo "" -done - -echo "========================================" -echo " Summary" -echo "========================================" -echo "Base keys: $base_count" -echo -e "Total missing: ${RED}$total_missing${NC}" -echo -e "Total extra: ${YELLOW}$total_extra${NC}" - -if [ "$total_missing" -eq 0 ] && [ "$total_extra" -eq 0 ]; then - echo -e "${GREEN}All translations are complete!${NC}" - exit 0 -else - exit 1 -fi