Fix queue loading, null-safe models, autofill, and add outbound dialer
All checks were successful
Create Release / build (push) Successful in 4s

- Fix queue queries in mobile API and SSE to use twp_group_members
  (matching browser phone) instead of twp_queue_assignments
- Auto-create personal queues if user has no extension
- Make all model JSON parsing null-safe (handle null, string ints, bools)
- Add AutofillGroup and autofill hints to login form
- Add outbound calling with dialpad bottom sheet on dashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-03-06 15:32:22 -08:00
parent d41b6aa535
commit 8cc6fa8c3c
9 changed files with 186 additions and 60 deletions

View File

@@ -17,11 +17,11 @@ class AgentStatus {
factory AgentStatus.fromJson(Map<String, dynamic> json) {
return AgentStatus(
status: _parseStatus(json['status'] as String),
isLoggedIn: json['is_logged_in'] as bool,
status: _parseStatus((json['status'] ?? 'offline') as String),
isLoggedIn: json['is_logged_in'] == true || json['is_logged_in'] == 1 || json['is_logged_in'] == '1',
currentCallSid: json['current_call_sid'] as String?,
lastActivity: json['last_activity'] as String?,
availableForQueues: json['available_for_queues'] as bool? ?? true,
availableForQueues: json['available_for_queues'] != false && json['available_for_queues'] != 0 && json['available_for_queues'] != '0',
);
}

View File

@@ -15,13 +15,19 @@ class QueueInfo {
factory QueueInfo.fromJson(Map<String, dynamic> json) {
return QueueInfo(
id: json['id'] as int,
name: json['name'] as String,
type: json['type'] as String,
id: _toInt(json['id']),
name: (json['name'] ?? '') as String,
type: (json['type'] ?? '') as String,
extension: json['extension'] as String?,
waitingCount: json['waiting_count'] as int,
waitingCount: _toInt(json['waiting_count']),
);
}
static int _toInt(dynamic value) {
if (value is int) return value;
if (value is String) return int.tryParse(value) ?? 0;
return 0;
}
}
class QueueCall {
@@ -43,12 +49,18 @@ class QueueCall {
factory QueueCall.fromJson(Map<String, dynamic> json) {
return QueueCall(
callSid: json['call_sid'] as String,
fromNumber: json['from_number'] as String,
toNumber: json['to_number'] as String,
position: json['position'] as int,
status: json['status'] as String,
waitTime: json['wait_time'] as int,
callSid: (json['call_sid'] ?? '') as String,
fromNumber: (json['from_number'] ?? '') as String,
toNumber: (json['to_number'] ?? '') as String,
position: _toInt(json['position']),
status: (json['status'] ?? '') as String,
waitTime: _toInt(json['wait_time']),
);
}
static int _toInt(dynamic value) {
if (value is int) return value;
if (value is String) return int.tryParse(value) ?? 0;
return 0;
}
}

View File

@@ -13,10 +13,16 @@ class User {
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['user_id'] as int,
login: json['user_login'] as String,
displayName: json['display_name'] as String,
id: _toInt(json['user_id']),
login: (json['user_login'] ?? '') as String,
displayName: (json['display_name'] ?? '') as String,
email: json['email'] as String?,
);
}
static int _toInt(dynamic value) {
if (value is int) return value;
if (value is String) return int.tryParse(value) ?? 0;
return 0;
}
}