feat: Geutebruck GeViScope/GeViSoft Action Mapping System - MVP
This MVP release provides a complete full-stack solution for managing action mappings in Geutebruck's GeViScope and GeViSoft video surveillance systems. ## Features ### Flutter Web Application (Port 8081) - Modern, responsive UI for managing action mappings - Action picker dialog with full parameter configuration - Support for both GSC (GeViScope) and G-Core server actions - Consistent UI for input and output actions with edit/delete capabilities - Real-time action mapping creation, editing, and deletion - Server categorization (GSC: prefix for GeViScope, G-Core: prefix for G-Core servers) ### FastAPI REST Backend (Port 8000) - RESTful API for action mapping CRUD operations - Action template service with comprehensive action catalog (247 actions) - Server management (G-Core and GeViScope servers) - Configuration tree reading and writing - JWT authentication with role-based access control - PostgreSQL database integration ### C# SDK Bridge (gRPC, Port 50051) - Native integration with GeViSoft SDK (GeViProcAPINET_4_0.dll) - Action mapping creation with correct binary format - Support for GSC and G-Core action types - Proper Camera parameter inclusion in action strings (fixes CrossSwitch bug) - Action ID lookup table with server-specific action IDs - Configuration reading/writing via SetupClient ## Bug Fixes - **CrossSwitch Bug**: GSC and G-Core actions now correctly display camera/PTZ head parameters in GeViSet - Action strings now include Camera parameter: `@ PanLeft (Comment: "", Camera: 101028)` - Proper filter flags and VideoInput=0 for action mappings - Correct action ID assignment (4198 for GSC, 9294 for G-Core PanLeft) ## Technical Stack - **Frontend**: Flutter Web, Dart, Dio HTTP client - **Backend**: Python FastAPI, PostgreSQL, Redis - **SDK Bridge**: C# .NET 8.0, gRPC, GeViSoft SDK - **Authentication**: JWT tokens - **Configuration**: GeViSoft .set files (binary format) ## Credentials - GeViSoft/GeViScope: username=sysadmin, password=masterkey - Default admin: username=admin, password=admin123 ## Deployment All services run on localhost: - Flutter Web: http://localhost:8081 - FastAPI: http://localhost:8000 - SDK Bridge gRPC: localhost:50051 - GeViServer: localhost (default port) Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
309
integration_complete_summary.md
Normal file
309
integration_complete_summary.md
Normal file
@@ -0,0 +1,309 @@
|
||||
# ✅ Integration Complete - ActionPickerDialog in Action Mapping Form
|
||||
|
||||
## Summary
|
||||
|
||||
Successfully integrated the ActionPickerDialog into the action mapping form screen. The form now uses the native GeViSet-style action picker instead of dropdowns.
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. Updated Imports
|
||||
Added new imports for action templates and the ActionPickerDialog:
|
||||
```dart
|
||||
import '../../../data/models/action_template.dart';
|
||||
import '../../../data/services/action_template_service.dart';
|
||||
import '../../../core/constants/api_constants.dart';
|
||||
import '../../blocs/auth/auth_bloc.dart';
|
||||
import '../../blocs/auth/auth_state.dart';
|
||||
import '../../widgets/action_picker_dialog.dart';
|
||||
```
|
||||
|
||||
### 2. Refactored State Management
|
||||
**Before:**
|
||||
- Used `List<TextEditingController>` for output actions
|
||||
- Used `Map<int, Map<String, dynamic>>` for parameters
|
||||
- Manual parameter editing dialogs
|
||||
|
||||
**After:**
|
||||
- Uses `List<ActionOutput>` directly
|
||||
- Loads categories and templates on init
|
||||
- ActionPickerDialog handles all action selection and parameter editing
|
||||
|
||||
**New State Variables:**
|
||||
```dart
|
||||
bool _isLoadingTemplates = true;
|
||||
Map<String, List<String>>? _categories;
|
||||
Map<String, ActionTemplate>? _templates;
|
||||
List<ActionOutput> _outputActions = [];
|
||||
```
|
||||
|
||||
### 3. Added Template Loading
|
||||
```dart
|
||||
Future<void> _loadActionTemplates() async {
|
||||
try {
|
||||
// Get auth token from AuthBloc
|
||||
final authState = context.read<AuthBloc>().state;
|
||||
String? token;
|
||||
if (authState is Authenticated) {
|
||||
token = authState.token;
|
||||
}
|
||||
|
||||
final service = ActionTemplateService(
|
||||
baseUrl: ApiConstants.baseUrl,
|
||||
authToken: token,
|
||||
);
|
||||
|
||||
final categoriesResponse = await service.getActionCategories();
|
||||
final templates = await service.getActionTemplates();
|
||||
|
||||
setState(() {
|
||||
_categories = categoriesResponse.categories;
|
||||
_templates = templates;
|
||||
_isLoadingTemplates = false;
|
||||
});
|
||||
} catch (e) {
|
||||
// Handle error...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. New Action Management Methods
|
||||
|
||||
**Add Output Action** - Opens ActionPickerDialog:
|
||||
```dart
|
||||
Future<void> _addOutputAction() async {
|
||||
if (_categories == null || _templates == null) return;
|
||||
|
||||
final result = await showDialog<ActionOutput>(
|
||||
context: context,
|
||||
builder: (context) => ActionPickerDialog(
|
||||
categories: _categories!,
|
||||
templates: _templates!,
|
||||
),
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
setState(() {
|
||||
_outputActions.add(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Edit Output Action** - Opens ActionPickerDialog with existing action:
|
||||
```dart
|
||||
Future<void> _editOutputAction(int index) async {
|
||||
final result = await showDialog<ActionOutput>(
|
||||
context: context,
|
||||
builder: (context) => ActionPickerDialog(
|
||||
categories: _categories!,
|
||||
templates: _templates!,
|
||||
existingAction: _outputActions[index],
|
||||
),
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
setState(() {
|
||||
_outputActions[index] = result;
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Remove Output Action:**
|
||||
```dart
|
||||
void _removeOutputAction(int index) {
|
||||
setState(() {
|
||||
_outputActions.removeAt(index);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
**Reorder Output Actions** (matching native app):
|
||||
```dart
|
||||
void _moveOutputActionUp(int index) {
|
||||
if (index > 0) {
|
||||
setState(() {
|
||||
final action = _outputActions.removeAt(index);
|
||||
_outputActions.insert(index - 1, action);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _moveOutputActionDown(int index) {
|
||||
if (index < _outputActions.length - 1) {
|
||||
setState(() {
|
||||
final action = _outputActions.removeAt(index);
|
||||
_outputActions.insert(index + 1, action);
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Simplified Submit Form
|
||||
```dart
|
||||
void _submitForm() {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
setState(() {
|
||||
_isSaving = true;
|
||||
});
|
||||
|
||||
// Validate that at least one output action is provided
|
||||
if (_outputActions.isEmpty) {
|
||||
// Show error...
|
||||
return;
|
||||
}
|
||||
|
||||
final mapping = ActionMapping(
|
||||
// ...
|
||||
outputActions: _outputActions, // ← Direct use, no transformation needed!
|
||||
// ...
|
||||
);
|
||||
|
||||
// Submit...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Updated UI - Output Actions Section
|
||||
|
||||
**New Features:**
|
||||
- ✅ Loading indicator while templates are loading
|
||||
- ✅ Empty state message when no actions
|
||||
- ✅ Cards showing action name and parameters
|
||||
- ✅ Edit button opens ActionPickerDialog
|
||||
- ✅ Up/Down buttons for reordering (like native app!)
|
||||
- ✅ Remove button to delete actions
|
||||
- ✅ Clean parameter display (read-only, edited via dialog)
|
||||
|
||||
**UI Layout:**
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Output Actions * [Add Output Action] │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ Output 1 ↑ ↓ ✎ ✗ │ │
|
||||
│ │ PanStop │ │
|
||||
│ │ ─────────────────────────────────────────────── │ │
|
||||
│ │ Parameters (2) │ │
|
||||
│ │ GCoreServer: gscope-cdu-3 │ │
|
||||
│ │ PTZ head: 101027 │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ Output 2 ↑ ↓ ✎ ✗ │ │
|
||||
│ │ SystemWarning │ │
|
||||
│ │ ─────────────────────────────────────────────── │ │
|
||||
│ │ Parameters (2) │ │
|
||||
│ │ Caption: Warning message │ │
|
||||
│ │ Source: 5 │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Files Modified
|
||||
|
||||
```
|
||||
geutebruck_app/
|
||||
└── lib/
|
||||
└── presentation/
|
||||
└── screens/
|
||||
└── action_mappings/
|
||||
└── action_mapping_form_screen.dart ✅ UPDATED
|
||||
```
|
||||
|
||||
## Files Created (Previously)
|
||||
|
||||
```
|
||||
geutebruck_app/
|
||||
└── lib/
|
||||
├── data/
|
||||
│ ├── models/
|
||||
│ │ └── action_template.dart ✅ NEW
|
||||
│ └── services/
|
||||
│ └── action_template_service.dart ✅ NEW
|
||||
└── presentation/
|
||||
└── widgets/
|
||||
└── action_picker_dialog.dart ✅ NEW
|
||||
```
|
||||
|
||||
## User Experience Improvements
|
||||
|
||||
### Before
|
||||
1. Select action from dropdown (29 hardcoded options)
|
||||
2. Click "Parameters" to expand
|
||||
3. Click "+" to add each parameter manually
|
||||
4. Type parameter name and value
|
||||
5. Repeat for each parameter
|
||||
6. No way to reorder actions
|
||||
|
||||
### After
|
||||
1. Click "Add Output Action" button
|
||||
2. ActionPickerDialog opens with:
|
||||
- Category dropdown (10 categories)
|
||||
- Filtered action list (45 actions total)
|
||||
- Dynamic parameter fields based on selected action
|
||||
- Checkboxes to enable/disable optional parameters
|
||||
- Action description shown at bottom
|
||||
- Caption and delay execution fields
|
||||
3. Parameters are pre-filled and validated
|
||||
4. Actions can be reordered with up/down buttons
|
||||
5. Actions can be edited by clicking edit button
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
- [ ] Open action mapping form
|
||||
- [ ] Wait for templates to load
|
||||
- [ ] Click "Add Output Action"
|
||||
- [ ] Select a category (e.g., "Camera Control")
|
||||
- [ ] Select an action (e.g., "PanStop")
|
||||
- [ ] Enable parameters using checkboxes
|
||||
- [ ] Enter parameter values
|
||||
- [ ] Enter caption
|
||||
- [ ] Click "Ok"
|
||||
- [ ] Verify action appears in list
|
||||
- [ ] Click edit button
|
||||
- [ ] Verify ActionPickerDialog opens with existing values
|
||||
- [ ] Modify action
|
||||
- [ ] Click "Ok"
|
||||
- [ ] Verify changes are reflected
|
||||
- [ ] Add multiple actions
|
||||
- [ ] Test reordering with up/down buttons
|
||||
- [ ] Remove an action
|
||||
- [ ] Submit form
|
||||
- [ ] Verify action mapping is created/updated correctly
|
||||
|
||||
## Next Steps (Optional)
|
||||
|
||||
### Phase 3: DataTable Main List View
|
||||
Replace the card-based list with a DataTable showing:
|
||||
- Input action column
|
||||
- Output action 1, 2, 3 columns
|
||||
- Better information density
|
||||
- Matches native app exactly
|
||||
|
||||
### Future Enhancements
|
||||
1. **Browse buttons for parameters**
|
||||
- GCoreServer → Browse from server list
|
||||
- PTZ head → Browse from available cameras
|
||||
- VideoInput/Output → Browse from channels
|
||||
|
||||
2. **Parameter validation**
|
||||
- Number fields → Enforce numeric input
|
||||
- Range validation where applicable
|
||||
|
||||
3. **Search in action list**
|
||||
- Quick filter for finding actions in ActionPickerDialog
|
||||
|
||||
4. **Input action picker**
|
||||
- Use ActionPickerDialog for input actions too
|
||||
|
||||
## Status
|
||||
|
||||
**✅ INTEGRATION COMPLETE**
|
||||
|
||||
The ActionPickerDialog is fully integrated into the action mapping form. Users can now add, edit, remove, and reorder output actions using the native GeViSet-style UI with category-based navigation and dynamic parameter fields.
|
||||
|
||||
**Backend:** ✅ Complete (45 actions, 10 categories)
|
||||
**Flutter UI:** ✅ Complete (ActionPickerDialog created)
|
||||
**Integration:** ✅ Complete (Form updated)
|
||||
**Ready for:** Testing and deployment
|
||||
Reference in New Issue
Block a user