Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(status): Implement global status bar and request body in get val… #665

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/providers/providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
37 changes: 37 additions & 0 deletions lib/providers/status_message_provider.dart
Original file line number Diff line number Diff line change
@@ -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;
}
}
21 changes: 13 additions & 8 deletions lib/screens/home_page/editor_pane/editor_pane.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
],
);
}
}
60 changes: 60 additions & 0 deletions lib/screens/home_page/editor_pane/global_status_bar.dart
Original file line number Diff line number Diff line change
@@ -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,
),
),
],
),
);
}
}
20 changes: 20 additions & 0 deletions lib/utils/status_validator.dart
Original file line number Diff line number Diff line change
@@ -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;
}

}