Skip to content

Commit e482934

Browse files
Merge branch 'foss42:main' into resolve-issue-remove-add-buttons
2 parents a2c20ee + 9b40763 commit e482934

File tree

14 files changed

+268
-147
lines changed

14 files changed

+268
-147
lines changed

.github/pull_request_template.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ _Add your description_
99

1010
### Checklist
1111
- [ ] I have gone through the [contributing guide](https://github.com/foss42/apidash/blob/main/CONTRIBUTING.md)
12+
- [ ] I have updated my branch and synced it with project `main` branch before making this PR
1213
- [ ] I have run the tests (`flutter test`) and all tests are passing
1314

1415
## Added/updated tests?

CONTRIBUTING.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,27 @@ flutter test test/widgets/codegen_previewer_test.dart
129129

130130
Instead of copy pasting from pub.dev, it is recommended that you use `flutter pub add package_name` to add a new package to `pubspec.yaml`. You can read more [here](https://docs.flutter.dev/packages-and-plugins/using-packages#adding-a-package-dependency-to-an-app-using-flutter-pub-add).
131131

132-
## Troubleshooting Common Issues
132+
## Platform-specific Additional Instructions
133133

134-
### Network Connection Issues on macOS
134+
### macOS
135135

136-
If you encounter a network connection error similar to the following while running your Flutter app on macOS:
136+
Add below keys to `macos/Runner/DebugProfile.entitlements` and `macos/Runner/Release.entitlements`.
137137

138138
```
139-
ClientException with SocketException: Connection failed (OS Error: Operation not permitted, errno = 1)
139+
<key>com.apple.security.network.server</key>
140+
<true/>
141+
<key>com.apple.security.network.client</key>
142+
<true/>
143+
<key>com.apple.security.files.downloads.read-write</key>
144+
<true/>
145+
<key>com.apple.security.files.user-selected.read-write</key>
146+
<true/>
140147
```
141-
Add below key to `macos/Runner/DebugProfile.entitlements` and `macos/Runner/Release.entitlements`.
148+
149+
If not added, you can encounter a network connection error similar to the following while running your Flutter app on macOS:
142150

143151
```
144-
<key>com.apple.security.network.client</key>
145-
<true/>
152+
ClientException with SocketException: Connection failed (OS Error: Operation not permitted, errno = 1)
146153
```
147154

148155
You can read more [here](https://docs.flutter.dev/platform-integration/macos/building#setting-up-entitlements)

lib/codegen/others/curl.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class cURLCodeGen {
5858
} else if (requestModel.hasFormData) {
5959
for (var formData in requestModel.formDataList) {
6060
var templateFormData = jj.Template(kTemplateFormData);
61-
if (formData.name.isNotEmpty && formData.value.isNotEmpty) {
61+
if (formData.name.isNotEmpty) {
6262
result += templateFormData.render({
6363
"name": formData.name,
6464
"value":

lib/models/request_model.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ class RequestModel {
8080
bool get hasFormData =>
8181
kMethodsWithBody.contains(method) &&
8282
hasFormDataContentType &&
83-
(requestFormDataList ?? <FormDataModel>[]).isNotEmpty;
83+
formDataMapList.isNotEmpty;
8484
List<FormDataModel> get formDataList =>
8585
requestFormDataList ?? <FormDataModel>[];
86-
List<Map<String, dynamic>> get formDataMapList =>
86+
List<Map<String, String>> get formDataMapList =>
8787
rowsToFormDataMapList(requestFormDataList) ?? [];
8888
bool get hasFileInFormData => formDataList
8989
.map((e) => e.type == FormDataType.file)
@@ -94,12 +94,13 @@ class RequestModel {
9494

9595
RequestModel duplicate({
9696
required String id,
97+
String? name,
9798
}) {
9899
return RequestModel(
99100
id: id,
100101
method: method,
101102
url: url,
102-
name: "$name (copy)",
103+
name: name ?? "${this.name} (copy)",
103104
description: description,
104105
requestHeaders: requestHeaders != null ? [...requestHeaders!] : null,
105106
requestParams: requestParams != null ? [...requestParams!] : null,
@@ -137,6 +138,7 @@ class RequestModel {
137138
var params = requestParams ?? this.requestParams;
138139
var enabledHeaders = isHeaderEnabledList ?? this.isHeaderEnabledList;
139140
var enabledParams = isParamEnabledList ?? this.isParamEnabledList;
141+
var formDataList = requestFormDataList ?? this.requestFormDataList;
140142
return RequestModel(
141143
id: id ?? this.id,
142144
method: method ?? this.method,
@@ -151,7 +153,7 @@ class RequestModel {
151153
requestBodyContentType:
152154
requestBodyContentType ?? this.requestBodyContentType,
153155
requestBody: requestBody ?? this.requestBody,
154-
requestFormDataList: requestFormDataList ?? this.requestFormDataList,
156+
requestFormDataList: formDataList != null ? [...formDataList] : null,
155157
responseStatus: responseStatus ?? this.responseStatus,
156158
message: message ?? this.message,
157159
responseModel: responseModel ?? this.responseModel,

lib/providers/collection_providers.dart

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,18 @@ class CollectionStateNotifier
9696
state = map;
9797
}
9898

99+
void clearResponse(String? id) {
100+
if (id == null || state?[id] == null) return;
101+
var currentModel = state![id]!;
102+
final newModel = currentModel.duplicate(
103+
id: id,
104+
name: currentModel.name,
105+
);
106+
var map = {...state!};
107+
map[id] = newModel;
108+
state = map;
109+
}
110+
99111
void duplicate(String id) {
100112
final newId = getNewUuid();
101113

@@ -134,21 +146,22 @@ class CollectionStateNotifier
134146
ResponseModel? responseModel,
135147
}) {
136148
final newModel = state![id]!.copyWith(
137-
method: method,
138-
url: url,
139-
name: name,
140-
description: description,
141-
requestTabIndex: requestTabIndex,
142-
requestHeaders: requestHeaders,
143-
requestParams: requestParams,
144-
isHeaderEnabledList: isHeaderEnabledList,
145-
isParamEnabledList: isParamEnabledList,
146-
requestBodyContentType: requestBodyContentType,
147-
requestBody: requestBody,
148-
requestFormDataList: requestFormDataList,
149-
responseStatus: responseStatus,
150-
message: message,
151-
responseModel: responseModel);
149+
method: method,
150+
url: url,
151+
name: name,
152+
description: description,
153+
requestTabIndex: requestTabIndex,
154+
requestHeaders: requestHeaders,
155+
requestParams: requestParams,
156+
isHeaderEnabledList: isHeaderEnabledList,
157+
isParamEnabledList: isParamEnabledList,
158+
requestBodyContentType: requestBodyContentType,
159+
requestBody: requestBody,
160+
requestFormDataList: requestFormDataList,
161+
responseStatus: responseStatus,
162+
message: message,
163+
responseModel: responseModel,
164+
);
152165
//print(newModel);
153166
var map = {...state!};
154167
map[id] = newModel;

lib/screens/home_page/editor_pane/details_card/response_pane.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class ResponseDetails extends ConsumerWidget {
3434

3535
@override
3636
Widget build(BuildContext context, WidgetRef ref) {
37+
var sm = ScaffoldMessenger.of(context);
3738
final responseStatus = ref.watch(
3839
selectedRequestModelProvider.select((value) => value?.responseStatus));
3940
final message = ref
@@ -46,6 +47,14 @@ class ResponseDetails extends ConsumerWidget {
4647
responseStatus: responseStatus,
4748
message: message,
4849
time: responseModel?.time,
50+
onClearResponse: () {
51+
final selectedRequest = ref.read(selectedRequestModelProvider);
52+
ref
53+
.read(collectionStateNotifierProvider.notifier)
54+
.clearResponse(selectedRequest?.id);
55+
sm.hideCurrentSnackBar();
56+
sm.showSnackBar(getSnackBar('Response cleared'));
57+
},
4958
),
5059
const Expanded(
5160
child: ResponseTabs(),

lib/screens/settings_page.dart

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -66,39 +66,68 @@ class SettingsPage extends ConsumerWidget {
6666
title: const Text('Default URI Scheme'),
6767
subtitle: Text(
6868
'$kDefaultUri → ${settings.defaultUriScheme}://$kDefaultUri'),
69-
trailing: DropdownMenu(
70-
onSelected: (value) {
71-
ref
72-
.read(settingsProvider.notifier)
73-
.update(defaultUriScheme: value);
74-
},
75-
initialSelection: settings.defaultUriScheme,
76-
dropdownMenuEntries: kSupportedUriSchemes
77-
.map<DropdownMenuEntry<String>>((value) {
78-
return DropdownMenuEntry<String>(
79-
value: value,
80-
label: value,
81-
);
82-
}).toList()),
69+
trailing: Container(
70+
decoration: BoxDecoration(
71+
border: Border.all(
72+
color: Theme.of(context).colorScheme.onSurface,
73+
),
74+
borderRadius: kBorderRadius8,
75+
),
76+
child: DropdownButtonHideUnderline(
77+
child: DropdownButton<String>(
78+
borderRadius: kBorderRadius8,
79+
onChanged: (value) {
80+
ref
81+
.read(settingsProvider.notifier)
82+
.update(defaultUriScheme: value);
83+
},
84+
value: settings.defaultUriScheme,
85+
items: kSupportedUriSchemes
86+
.map<DropdownMenuItem<String>>((String value) {
87+
return DropdownMenuItem<String>(
88+
value: value,
89+
child: Padding(
90+
padding: kP10,
91+
child: Text(value),
92+
),
93+
);
94+
}).toList(),
95+
),
96+
),
97+
),
8398
),
8499
ListTile(
85100
contentPadding: kPb10,
86101
hoverColor: kColorTransparent,
87102
title: const Text('Default Code Generator'),
88-
trailing: DropdownMenu(
89-
onSelected: (value) {
90-
ref
91-
.read(settingsProvider.notifier)
92-
.update(defaultCodeGenLang: value);
93-
},
94-
initialSelection: settings.defaultCodeGenLang,
95-
dropdownMenuEntries: CodegenLanguage.values
96-
.map<DropdownMenuEntry<CodegenLanguage>>((value) {
97-
return DropdownMenuEntry<CodegenLanguage>(
98-
value: value,
99-
label: value.label,
100-
);
101-
}).toList()),
103+
trailing: Container(
104+
decoration: BoxDecoration(
105+
border: Border.all(
106+
color: Theme.of(context).colorScheme.onSurface,
107+
),
108+
borderRadius: kBorderRadius8,
109+
),
110+
child: DropdownButtonHideUnderline(
111+
child: DropdownButton<CodegenLanguage>(
112+
borderRadius: kBorderRadius8,
113+
value: settings.defaultCodeGenLang,
114+
onChanged: (value) {
115+
ref
116+
.read(settingsProvider.notifier)
117+
.update(defaultCodeGenLang: value);
118+
},
119+
items: CodegenLanguage.values.map((value) {
120+
return DropdownMenuItem<CodegenLanguage>(
121+
value: value,
122+
child: Padding(
123+
padding: kP10,
124+
child: Text(value.label),
125+
),
126+
);
127+
}).toList(),
128+
),
129+
),
130+
),
102131
),
103132
CheckboxListTile(
104133
contentPadding: EdgeInsets.zero,

lib/utils/convert_utils.dart

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:typed_data';
22
import 'dart:convert';
3+
import 'package:collection/collection.dart';
34
import '../models/models.dart';
45
import '../consts.dart';
56
import 'package:http/http.dart' as http;
@@ -90,18 +91,22 @@ List<NameValueModel>? mapToRows(Map<String, String>? kvMap) {
9091
return finalRows;
9192
}
9293

93-
List<Map<String, dynamic>>? rowsToFormDataMapList(
94+
List<Map<String, String>>? rowsToFormDataMapList(
9495
List<FormDataModel>? kvRows,
9596
) {
9697
if (kvRows == null) {
9798
return null;
9899
}
99-
List<Map<String, dynamic>> finalMap = kvRows
100-
.map((FormDataModel formData) => {
101-
"name": formData.name,
102-
"value": formData.value,
103-
"type": formData.type.name,
104-
})
100+
List<Map<String, String>> finalMap = kvRows
101+
.map((FormDataModel formData) =>
102+
(formData.name.trim().isEmpty && formData.value.trim().isEmpty)
103+
? null
104+
: {
105+
"name": formData.name,
106+
"value": formData.value,
107+
"type": formData.type.name,
108+
})
109+
.whereNotNull()
105110
.toList();
106111
return finalMap;
107112
}

lib/utils/file_utils.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ String getShortPath(String path) {
5050

5151
String getFilenameFromPath(String path) {
5252
var f = p.split(path);
53-
return f.last;
53+
return f.lastOrNull ?? "";
5454
}
5555

5656
String getTempFileName() {

lib/widgets/buttons.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,27 @@ class SaveButton extends StatelessWidget {
235235
);
236236
}
237237
}
238+
239+
class ClearResponseButton extends StatelessWidget {
240+
const ClearResponseButton({
241+
super.key,
242+
this.onPressed,
243+
});
244+
245+
final VoidCallback? onPressed;
246+
247+
@override
248+
Widget build(BuildContext context) {
249+
return Tooltip(
250+
message: 'Clear response',
251+
child: TextButton(
252+
style: TextButton.styleFrom(minimumSize: const Size(40, 40)),
253+
onPressed: onPressed,
254+
child: const Icon(
255+
Icons.delete,
256+
size: 20,
257+
),
258+
),
259+
);
260+
}
261+
}

0 commit comments

Comments
 (0)