From c3c4764f59b7bc0e31204ca7a03ea102cbcae0ca Mon Sep 17 00:00:00 2001 From: Balasubramaniam12007 <balasubramaniam12007@gmail.com> Date: Thu, 13 Mar 2025 03:18:39 +0530 Subject: [PATCH] feat(status): Implement global status bar and request body in get validation - Create StatusMessage model with support for info/warning/error types - Design GlobalStatusBar UI component with dynamic styling based on status type and located at the bottom of the editorpane -Implement GlobalStatusBarManager for state management via Riverpod - Add StatusValidator with initial validation for GET requests with bodies Signed-off-by: Balasubramaniam12007 <balasubramaniam12007@gmail.com> --- lib/providers/providers.dart | 1 + lib/providers/status_message_provider.dart | 37 ++++++++++++ .../home_page/editor_pane/editor_pane.dart | 21 ++++--- .../editor_pane/global_status_bar.dart | 60 +++++++++++++++++++ lib/utils/status_validator.dart | 20 +++++++ 5 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 lib/providers/status_message_provider.dart create mode 100644 lib/screens/home_page/editor_pane/global_status_bar.dart create mode 100644 lib/utils/status_validator.dart diff --git a/lib/providers/providers.dart b/lib/providers/providers.dart index 29fc6e595..438226eba 100644 --- a/lib/providers/providers.dart +++ b/lib/providers/providers.dart @@ -3,3 +3,4 @@ export 'environment_providers.dart'; export 'history_providers.dart'; export 'settings_providers.dart'; export 'ui_providers.dart'; +export 'status_message_provider.dart'; \ No newline at end of file diff --git a/lib/providers/status_message_provider.dart b/lib/providers/status_message_provider.dart new file mode 100644 index 000000000..aeed7fc9b --- /dev/null +++ b/lib/providers/status_message_provider.dart @@ -0,0 +1,37 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:apidash_core/apidash_core.dart'; +import 'package:apidash/providers/collection_providers.dart'; +import 'package:apidash/utils/status_validator.dart'; + +enum StatusMessageType { defaultType, info, warning, error } + +class StatusMessage { + final String message; + final StatusMessageType type; + + StatusMessage(this.message, this.type); +} + +final statusMessageProvider = + StateNotifierProvider<GlobalStatusBarManager, StatusMessage>((ref) { + return GlobalStatusBarManager(ref); +}); + +class GlobalStatusBarManager extends StateNotifier<StatusMessage> { + final Ref ref; + + GlobalStatusBarManager(this.ref) + : super(StatusMessage("Global Status Bar", StatusMessageType.defaultType)) { + // Listen for request changes and validate + ref.listen(selectedRequestModelProvider, (previous, next) { + final method = next?.httpRequestModel?.method ?? HTTPVerb.get; + final body = next?.httpRequestModel?.body; + _updateStatusMessage(StatusValidator().validateRequest(method, body)); + }); + } + + // Updates the status message + void _updateStatusMessage(StatusMessage newMessage) { + state = newMessage; + } +} diff --git a/lib/screens/home_page/editor_pane/editor_pane.dart b/lib/screens/home_page/editor_pane/editor_pane.dart index 7ff67f5c1..36da4bd03 100644 --- a/lib/screens/home_page/editor_pane/editor_pane.dart +++ b/lib/screens/home_page/editor_pane/editor_pane.dart @@ -3,19 +3,24 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:apidash/providers/providers.dart'; import 'editor_default.dart'; import 'editor_request.dart'; +import 'global_status_bar.dart'; class RequestEditorPane extends ConsumerWidget { - const RequestEditorPane({ - super.key, - }); + const RequestEditorPane({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final selectedId = ref.watch(selectedIdStateProvider); - if (selectedId == null) { - return const RequestEditorDefault(); - } else { - return const RequestEditor(); - } + + return Column( + children: [ + Expanded( + child: selectedId == null + ? const RequestEditorDefault() + : const RequestEditor(), + ), + const GlobalStatusBar(), + ], + ); } } diff --git a/lib/screens/home_page/editor_pane/global_status_bar.dart b/lib/screens/home_page/editor_pane/global_status_bar.dart new file mode 100644 index 000000000..9cb3a3e1b --- /dev/null +++ b/lib/screens/home_page/editor_pane/global_status_bar.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; +import 'package:apidash_design_system/apidash_design_system.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:apidash/providers/providers.dart'; + +class GlobalStatusBar extends ConsumerWidget { + const GlobalStatusBar({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final statusMessage = ref.watch(statusMessageProvider); + + // Get color based on message type + final color = statusMessage.type == StatusMessageType.info + ? kColorSchemeSeed + : statusMessage.type == StatusMessageType.warning + ? kColorHttpMethodPut + : statusMessage.type == StatusMessageType.error + ? kColorDarkDanger + : kColorBlack; + + // Get icon based on message type + final icon = statusMessage.type == StatusMessageType.error + ? Icons.error_outline + : statusMessage.type == StatusMessageType.warning + ? Icons.warning_amber_outlined + : statusMessage.type == StatusMessageType.info + ? Icons.info_outline + : null; + + return Container( + padding: kPh12, + width: double.infinity, + height: 40, + // Use background color only for status messages (info/warning/error) + color: icon != null ? color.withOpacity(kForegroundOpacity) : kColorWhite, + child: Row( + children: [ + // Only display icons for info, warning, and error states + if (icon != null) ...[ + Icon(icon, size: kButtonIconSizeSmall, color: color), + kHSpacer8, + ], + Expanded( + child: Text( + statusMessage.message, + style: TextStyle( + color: color, + fontSize: 14, + fontWeight: FontWeight.w500, + ), + // Prevent text overflow issues + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ); + } +} diff --git a/lib/utils/status_validator.dart b/lib/utils/status_validator.dart new file mode 100644 index 000000000..75f91b838 --- /dev/null +++ b/lib/utils/status_validator.dart @@ -0,0 +1,20 @@ +import 'package:apidash_core/apidash_core.dart'; +import 'package:apidash/providers/status_message_provider.dart'; +import 'package:apidash_design_system/apidash_design_system.dart'; + +class StatusValidator { + StatusMessage validateRequest(HTTPVerb method, String? body) { + if (_isInvalidGetRequest(method, body)) { + return StatusMessage( + "GET requests cannot have a body. Remove the body or change the method to POST.", + StatusMessageType.info, + ); + } + return StatusMessage("Global Status Bar", StatusMessageType.defaultType); + } + + bool _isInvalidGetRequest(HTTPVerb method, String? body) { + return method == HTTPVerb.get && body != null && body.isNotEmpty; + } + +}