# Organizr Service Control Widget A beautiful, responsive widget for managing on-demand services from your Organizr dashboard. ## Features - ✨ **Real-time Status** - Live service status with container counts - 🎮 **One-Click Control** - Start/Stop services with a single click - 🔒 **Safety First** - Always-on services are protected and clearly marked - 🎨 **Beautiful UI** - Dark theme that matches Organizr - ⚡ **Auto-Refresh** - Updates every 10 seconds - 📱 **Responsive** - Works on desktop, tablet, and mobile ## Installation ### Method 1: Organizr Custom Homepage Item (Recommended) 1. **Copy the widget file** to a web-accessible location: ```bash # If you have a web server serving files from /var/www/html: sudo cp organizr-widgets/service-control.html /var/www/html/widgets/ # Or use Organizr's public directory: cp organizr-widgets/service-control.html /path/to/organizr/plugins/widgets/ ``` 2. **Add to Organizr Homepage**: - Open Organizr - Go to **Settings** → **Customize** → **Homepage Items** - Click **Add New Item** - Configure: - **Name**: "Service Control" - **Category**: Custom - **Type**: iFrame - **URL**: `http://localhost/widgets/service-control.html` (adjust path) - **Minimum Authentication**: User - **Enabled**: Yes - Save 3. **Add to Homepage**: - Go to **Settings** → **Customize** → **Appearance** - Edit your homepage layout - Add the "Service Control" item to desired location - Save ### Method 2: Organizr Custom HTML Tab 1. **Open Organizr Settings**: - Settings → **Tab Editor** 2. **Add New Tab**: - Click **Add Tab** - Configure: - **Tab Name**: "Services" - **Tab URL**: Leave empty - **Category**: Custom - **Type**: iFrame - **Image**: `images/tabs/services.png` (or your choice) 3. **Add Custom HTML**: - In the same tab configuration, find **Custom HTML** section - Copy and paste the entire contents of `service-control.html` - Save 4. **Access the Tab**: - The "Services" tab will now appear in your Organizr sidebar ### Method 3: Nginx Reverse Proxy Integration If you want to serve the widget through Nginx Proxy Manager: 1. **Create a location** in your Organizr proxy host: ```nginx location /widgets/ { alias /path/to/portainer-core/organizr-widgets/; autoindex off; } ``` 2. **Access via**: `https://your-organizr-domain.com/widgets/service-control.html` ## Configuration ### Changing API Endpoint If your core-api is not on `localhost:8083`, edit the widget file: ```javascript const API_BASE = 'http://your-server:8083'; // Change this line ``` ### Adjusting Auto-Refresh Interval Default is 10 seconds. To change: ```javascript setInterval(fetchServices, 10000); // Change 10000 to desired milliseconds ``` ### Customizing Displayed Services By default, the widget shows all stoppable services (excludes always-on infrastructure). To filter specific services, modify the `renderServices()` function: ```javascript const stoppableServices = services.filter(s => !isAlwaysOn(s.name) && ['jellyfin', 'nextcloud', 'gitea', 'ai-stack'].includes(s.name) // Add this line ); ``` ## Service Groups The following service groups are defined (stopping one stops all in group): - **jellyfin**: jellyfin - **nextcloud**: nextcloud (uses shared postgres-shared + redis-shared) - **gitea**: gitea, gitea-db - **ai-stack**: open-webui, ollama, qdrant - **samba**: samba ## Always-On Services (Cannot be stopped) These infrastructure services are protected: - portainer - nginx-proxy-manager - core-api - uptime-kuma - organizr - headscale - watchtower - netdata - maintenance - postgres-shared (shared database infrastructure) - redis-shared (shared cache infrastructure) ## Troubleshooting ### "Failed to connect to API" **Problem**: Widget shows red error message **Solutions**: 1. Verify core-api is running: `docker ps | grep core-api` 2. Check core-api URL is correct (localhost vs IP address) 3. If accessing from remote, change `API_BASE` to full URL 4. Check browser console for CORS errors ### CORS Issues If accessing widget from a different domain than core-api: **Option 1**: Update core-api CORS settings in `services/core-api/src/config.py`: ```python cors_origins: list[str] = ["http://your-organizr-domain.com"] ``` **Option 2**: Proxy the API through same domain using Nginx ### Services Not Appearing **Check**: 1. Services are deployed as Portainer stacks 2. Services have proper labels: `com.docker.compose.project` 3. Core-API can connect to Portainer 4. Check browser console for errors ### Buttons Disabled **Expected Behavior**: - Start button disabled when service is running - Stop button disabled when service is stopped - All buttons disabled for always-on services ## API Endpoints Used The widget consumes these core-api endpoints: - `GET /infrastructure/services` - Fetch service list with status - `GET /infrastructure/service-groups` - Fetch service groups and always-on list - `POST /infrastructure/services/{name}/start` - Start a service - `POST /infrastructure/services/{name}/stop` - Stop a service See [Core API Documentation](core-api.md) for full API reference. ## Advanced Customization ### Colors Edit the CSS variables in the `