312 lines
6.7 KiB
Markdown
Executable File
312 lines
6.7 KiB
Markdown
Executable File
# Pawprint Wrapper - Development Tools Sidebar
|
|
|
|
A collapsible sidebar that provides development and testing tools for any pawprint-managed nest (like amar) without interfering with the managed application.
|
|
|
|
## Features
|
|
|
|
### 👤 Quick Login
|
|
- Switch between test users with one click
|
|
- Pre-configured admin, vet, and tutor accounts
|
|
- Automatic JWT token management
|
|
- Shows currently logged-in user
|
|
|
|
### 🌍 Environment Info
|
|
- Display backend and frontend URLs
|
|
- Nest name and deployment info
|
|
- Quick reference during development
|
|
|
|
### ⌨️ Keyboard Shortcuts
|
|
- **Ctrl+Shift+P** - Toggle sidebar
|
|
|
|
### 💾 State Persistence
|
|
- Sidebar remembers expanded/collapsed state
|
|
- Persists across page reloads
|
|
|
|
## Files
|
|
|
|
```
|
|
wrapper/
|
|
├── index.html # Standalone demo
|
|
├── sidebar.css # Sidebar styling
|
|
├── sidebar.js # Sidebar logic
|
|
├── config.json # Configuration (users, URLs)
|
|
└── README.md # This file
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### Standalone Demo
|
|
|
|
Open `index.html` in your browser to see the sidebar in action:
|
|
|
|
```bash
|
|
cd core_nest/wrapper
|
|
python3 -m http.server 8080
|
|
# Open http://localhost:8080
|
|
```
|
|
|
|
Click the toggle button on the right edge or press **Ctrl+Shift+P**.
|
|
|
|
### Integration with Your App
|
|
|
|
Add these two lines to your HTML:
|
|
|
|
```html
|
|
<link rel="stylesheet" href="/wrapper/sidebar.css">
|
|
<script src="/wrapper/sidebar.js"></script>
|
|
```
|
|
|
|
The sidebar will automatically:
|
|
1. Load configuration from `/wrapper/config.json`
|
|
2. Create the sidebar UI
|
|
3. Setup keyboard shortcuts
|
|
4. Check for existing logged-in users
|
|
|
|
## Configuration
|
|
|
|
Edit `config.json` to customize:
|
|
|
|
```json
|
|
{
|
|
"nest_name": "amar",
|
|
"wrapper": {
|
|
"enabled": true,
|
|
"environment": {
|
|
"backend_url": "http://localhost:8000",
|
|
"frontend_url": "http://localhost:3000"
|
|
},
|
|
"users": [
|
|
{
|
|
"id": "admin",
|
|
"label": "Admin",
|
|
"username": "admin@test.com",
|
|
"password": "Amar2025!",
|
|
"icon": "👑",
|
|
"role": "ADMIN"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### User Fields
|
|
|
|
- **id**: Unique identifier for the user
|
|
- **label**: Display name in the sidebar
|
|
- **username**: Login username (email)
|
|
- **password**: Login password
|
|
- **icon**: Emoji icon to display
|
|
- **role**: User role (ADMIN, VET, USER)
|
|
|
|
## How It Works
|
|
|
|
### Login Flow
|
|
|
|
1. User clicks a user card in the sidebar
|
|
2. `sidebar.js` calls `POST {backend_url}/api/token/` with credentials
|
|
3. Backend returns JWT tokens: `{ access, refresh, details }`
|
|
4. Tokens stored in localStorage
|
|
5. Page reloads, user is now logged in
|
|
|
|
### Token Storage
|
|
|
|
Tokens are stored in localStorage:
|
|
- `access_token` - JWT access token
|
|
- `refresh_token` - JWT refresh token
|
|
- `user_info` - User metadata (username, label, role)
|
|
|
|
### Logout Flow
|
|
|
|
1. User clicks "Logout" button
|
|
2. Tokens removed from localStorage
|
|
3. Page reloads, user is logged out
|
|
|
|
## Docker Integration
|
|
|
|
### Approach 1: Static Files
|
|
|
|
Mount wrapper as static files in docker-compose:
|
|
|
|
```yaml
|
|
services:
|
|
frontend:
|
|
volumes:
|
|
- ./ctrl/wrapper:/app/public/wrapper:ro
|
|
```
|
|
|
|
Then in your HTML:
|
|
```html
|
|
<link rel="stylesheet" href="/wrapper/sidebar.css">
|
|
<script src="/wrapper/sidebar.js"></script>
|
|
```
|
|
|
|
### Approach 2: Nginx Injection
|
|
|
|
Use nginx to inject the sidebar script automatically:
|
|
|
|
```nginx
|
|
location / {
|
|
sub_filter '</head>' '<link rel="stylesheet" href="/wrapper/sidebar.css"><script src="/wrapper/sidebar.js"></script></head>';
|
|
sub_filter_once on;
|
|
proxy_pass http://frontend:3000;
|
|
}
|
|
|
|
location /wrapper/ {
|
|
alias /app/wrapper/;
|
|
}
|
|
```
|
|
|
|
### Approach 3: Wrapper Service
|
|
|
|
Create a dedicated wrapper service:
|
|
|
|
```yaml
|
|
services:
|
|
wrapper:
|
|
image: nginx:alpine
|
|
ports:
|
|
- "80:80"
|
|
volumes:
|
|
- ./ctrl/wrapper:/usr/share/nginx/html/wrapper
|
|
environment:
|
|
- MANAGED_APP_URL=http://frontend:3000
|
|
```
|
|
|
|
See `../WRAPPER_DESIGN.md` for detailed Docker integration patterns.
|
|
|
|
## Customization
|
|
|
|
### Styling
|
|
|
|
Edit `sidebar.css` to customize appearance:
|
|
|
|
```css
|
|
:root {
|
|
--sidebar-width: 320px;
|
|
--sidebar-bg: #1e1e1e;
|
|
--sidebar-text: #e0e0e0;
|
|
--sidebar-accent: #007acc;
|
|
}
|
|
```
|
|
|
|
### Add New Panels
|
|
|
|
Add HTML to `getSidebarHTML()` in `sidebar.js`:
|
|
|
|
```javascript
|
|
getSidebarHTML() {
|
|
return `
|
|
...existing panels...
|
|
|
|
<div class="panel">
|
|
<h3>🆕 My New Panel</h3>
|
|
<p>Custom content here</p>
|
|
</div>
|
|
`;
|
|
}
|
|
```
|
|
|
|
### Add New Features
|
|
|
|
Extend the `PawprintSidebar` class in `sidebar.js`:
|
|
|
|
```javascript
|
|
class PawprintSidebar {
|
|
async fetchJiraInfo() {
|
|
const response = await fetch('https://artery.mcrn.ar/jira/VET-123');
|
|
const data = await response.json();
|
|
// Update UI with data
|
|
}
|
|
}
|
|
```
|
|
|
|
## API Requirements
|
|
|
|
The sidebar expects these endpoints from your backend:
|
|
|
|
### POST /api/token/
|
|
Login endpoint that returns JWT tokens.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"username": "admin@test.com",
|
|
"password": "Amar2025!"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
|
|
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc...",
|
|
"details": {
|
|
"role": "ADMIN",
|
|
"id": 1,
|
|
"name": "Admin User"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Sidebar not appearing
|
|
- Check browser console for errors
|
|
- Verify `sidebar.js` and `sidebar.css` are loaded
|
|
- Check that `config.json` is accessible
|
|
|
|
### Login fails
|
|
- Verify backend URL in `config.json`
|
|
- Check backend is running
|
|
- Verify credentials are correct
|
|
- Check CORS settings on backend
|
|
|
|
### Tokens not persisting
|
|
- Check localStorage is enabled
|
|
- Verify domain matches between sidebar and app
|
|
- Check browser privacy settings
|
|
|
|
## Security Considerations
|
|
|
|
⚠️ **Important:** This sidebar is for **development/testing only**.
|
|
|
|
- Passwords are stored in plain text in `config.json`
|
|
- Do NOT use in production
|
|
- Do NOT commit real credentials to git
|
|
- Add `config.json` to `.gitignore` if it contains sensitive data
|
|
|
|
For production:
|
|
- Disable wrapper via `"enabled": false` in config
|
|
- Use environment variables for URLs
|
|
- Remove or secure test user credentials
|
|
|
|
## Future Enhancements
|
|
|
|
Planned features (see `../WRAPPER_DESIGN.md`):
|
|
|
|
- 📋 **Jira Info Panel** - Fetch ticket details from artery
|
|
- 📊 **Logs Viewer** - Stream container logs
|
|
- 🎨 **Theme Switcher** - Light/dark mode
|
|
- 🔍 **Search** - Quick search across tools
|
|
- ⚙️ **Settings** - Customize sidebar behavior
|
|
- 📱 **Mobile Support** - Responsive design improvements
|
|
|
|
## Related Documentation
|
|
|
|
- `../WRAPPER_DESIGN.md` - Complete architecture design
|
|
- `../../../pawprint/CLAUDE.md` - Pawprint framework overview
|
|
- `../../README.md` - Core nest documentation
|
|
|
|
## Contributing
|
|
|
|
To add a new panel or feature:
|
|
|
|
1. Add HTML in `getSidebarHTML()`
|
|
2. Add styling in `sidebar.css`
|
|
3. Add logic as methods on `PawprintSidebar` class
|
|
4. Update this README with usage instructions
|
|
|
|
## License
|
|
|
|
Part of the Pawprint development tools ecosystem.
|