Merge branch 'foss42:main' into add-request-cancellation

This commit is contained in:
Sasank Tumpati
2024-12-12 13:15:16 +05:30
committed by GitHub
48 changed files with 572 additions and 407 deletions

View File

@ -1,4 +1,5 @@
import 'package:apidash_core/apidash_core.dart';
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:spot/spot.dart';
@ -103,7 +104,7 @@ class ApidashTestRequestHelper {
Future<void> unCheckFirstHeader() async {
final headerCells = find.descendant(
of: find.byType(EditRequestHeaders), matching: find.byType(CheckBox));
of: find.byType(EditRequestHeaders), matching: find.byType(ADCheckBox));
await tester.tap(headerCells.at(0));
await tester.pumpAndSettle();
}

View File

@ -1,20 +0,0 @@
import 'package:flutter/material.dart';
import 'package:apidash/utils/utils.dart';
import 'package:apidash/widgets/widgets.dart';
Future<void> saveCollection(
Map<String, dynamic> data, ScaffoldMessengerState sm) async {
var message = "";
try {
var pth = await getFileDownloadpath(null, "har");
if (pth != null) {
await saveFile(pth, jsonMapToBytes(data));
var sp = getShortPath(pth);
message = 'Saved to $sp';
}
} catch (e) {
message = "An error occurred while exporting.";
}
sm.hideCurrentSnackBar();
sm.showSnackBar(getSnackBar(message, small: false));
}

View File

@ -1,3 +1,4 @@
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:apidash/providers/providers.dart';

View File

@ -25,8 +25,12 @@ mixin _$EnvironmentModel {
List<EnvironmentVariableModel> get values =>
throw _privateConstructorUsedError;
/// Serializes this EnvironmentModel to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
/// Create a copy of EnvironmentModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$EnvironmentModelCopyWith<EnvironmentModel> get copyWith =>
throw _privateConstructorUsedError;
}
@ -50,6 +54,8 @@ class _$EnvironmentModelCopyWithImpl<$Res, $Val extends EnvironmentModel>
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of EnvironmentModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
@ -93,6 +99,8 @@ class __$$EnvironmentModelImplCopyWithImpl<$Res>
$Res Function(_$EnvironmentModelImpl) _then)
: super(_value, _then);
/// Create a copy of EnvironmentModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
@ -159,12 +167,14 @@ class _$EnvironmentModelImpl implements _EnvironmentModel {
const DeepCollectionEquality().equals(other._values, _values));
}
@JsonKey(ignore: true)
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType, id, name, const DeepCollectionEquality().hash(_values));
@JsonKey(ignore: true)
/// Create a copy of EnvironmentModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$EnvironmentModelImplCopyWith<_$EnvironmentModelImpl> get copyWith =>
@ -194,8 +204,11 @@ abstract class _EnvironmentModel implements EnvironmentModel {
String get name;
@override
List<EnvironmentVariableModel> get values;
/// Create a copy of EnvironmentModel
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(ignore: true)
@JsonKey(includeFromJson: false, includeToJson: false)
_$$EnvironmentModelImplCopyWith<_$EnvironmentModelImpl> get copyWith =>
throw _privateConstructorUsedError;
}
@ -212,8 +225,12 @@ mixin _$EnvironmentVariableModel {
EnvironmentVariableType get type => throw _privateConstructorUsedError;
bool get enabled => throw _privateConstructorUsedError;
/// Serializes this EnvironmentVariableModel to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
/// Create a copy of EnvironmentVariableModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$EnvironmentVariableModelCopyWith<EnvironmentVariableModel> get copyWith =>
throw _privateConstructorUsedError;
}
@ -239,6 +256,8 @@ class _$EnvironmentVariableModelCopyWithImpl<$Res,
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of EnvironmentVariableModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
@ -291,6 +310,8 @@ class __$$EnvironmentVariableModelImplCopyWithImpl<$Res>
$Res Function(_$EnvironmentVariableModelImpl) _then)
: super(_value, _then);
/// Create a copy of EnvironmentVariableModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
@ -360,11 +381,13 @@ class _$EnvironmentVariableModelImpl implements _EnvironmentVariableModel {
(identical(other.enabled, enabled) || other.enabled == enabled));
}
@JsonKey(ignore: true)
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType, key, value, type, enabled);
@JsonKey(ignore: true)
/// Create a copy of EnvironmentVariableModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$EnvironmentVariableModelImplCopyWith<_$EnvironmentVariableModelImpl>
@ -397,8 +420,11 @@ abstract class _EnvironmentVariableModel implements EnvironmentVariableModel {
EnvironmentVariableType get type;
@override
bool get enabled;
/// Create a copy of EnvironmentVariableModel
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(ignore: true)
@JsonKey(includeFromJson: false, includeToJson: false)
_$$EnvironmentVariableModelImplCopyWith<_$EnvironmentVariableModelImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@ -28,8 +28,12 @@ mixin _$HistoryMetaModel {
int get responseStatus => throw _privateConstructorUsedError;
DateTime get timeStamp => throw _privateConstructorUsedError;
/// Serializes this HistoryMetaModel to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
/// Create a copy of HistoryMetaModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$HistoryMetaModelCopyWith<HistoryMetaModel> get copyWith =>
throw _privateConstructorUsedError;
}
@ -60,6 +64,8 @@ class _$HistoryMetaModelCopyWithImpl<$Res, $Val extends HistoryMetaModel>
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of HistoryMetaModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
@ -130,6 +136,8 @@ class __$$HistoryMetaModelImplCopyWithImpl<$Res>
$Res Function(_$HistoryMetaModelImpl) _then)
: super(_value, _then);
/// Create a copy of HistoryMetaModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
@ -228,12 +236,14 @@ class _$HistoryMetaModelImpl implements _HistoryMetaModel {
other.timeStamp == timeStamp));
}
@JsonKey(ignore: true)
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType, historyId, requestId, name, url,
method, responseStatus, timeStamp);
@JsonKey(ignore: true)
/// Create a copy of HistoryMetaModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$HistoryMetaModelImplCopyWith<_$HistoryMetaModelImpl> get copyWith =>
@ -275,8 +285,11 @@ abstract class _HistoryMetaModel implements HistoryMetaModel {
int get responseStatus;
@override
DateTime get timeStamp;
/// Create a copy of HistoryMetaModel
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(ignore: true)
@JsonKey(includeFromJson: false, includeToJson: false)
_$$HistoryMetaModelImplCopyWith<_$HistoryMetaModelImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -25,8 +25,12 @@ mixin _$HistoryRequestModel {
HttpRequestModel get httpRequestModel => throw _privateConstructorUsedError;
HttpResponseModel get httpResponseModel => throw _privateConstructorUsedError;
/// Serializes this HistoryRequestModel to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
/// Create a copy of HistoryRequestModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$HistoryRequestModelCopyWith<HistoryRequestModel> get copyWith =>
throw _privateConstructorUsedError;
}
@ -58,6 +62,8 @@ class _$HistoryRequestModelCopyWithImpl<$Res, $Val extends HistoryRequestModel>
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of HistoryRequestModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
@ -86,6 +92,8 @@ class _$HistoryRequestModelCopyWithImpl<$Res, $Val extends HistoryRequestModel>
) as $Val);
}
/// Create a copy of HistoryRequestModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$HistoryMetaModelCopyWith<$Res> get metaData {
@ -94,6 +102,8 @@ class _$HistoryRequestModelCopyWithImpl<$Res, $Val extends HistoryRequestModel>
});
}
/// Create a copy of HistoryRequestModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$HttpRequestModelCopyWith<$Res> get httpRequestModel {
@ -102,6 +112,8 @@ class _$HistoryRequestModelCopyWithImpl<$Res, $Val extends HistoryRequestModel>
});
}
/// Create a copy of HistoryRequestModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$HttpResponseModelCopyWith<$Res> get httpResponseModel {
@ -141,6 +153,8 @@ class __$$HistoryRequestModelImplCopyWithImpl<$Res>
$Res Function(_$HistoryRequestModelImpl) _then)
: super(_value, _then);
/// Create a copy of HistoryRequestModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
@ -212,12 +226,14 @@ class _$HistoryRequestModelImpl implements _HistoryRequestModel {
other.httpResponseModel == httpResponseModel));
}
@JsonKey(ignore: true)
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType, historyId, metaData, httpRequestModel, httpResponseModel);
@JsonKey(ignore: true)
/// Create a copy of HistoryRequestModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$HistoryRequestModelImplCopyWith<_$HistoryRequestModelImpl> get copyWith =>
@ -251,8 +267,11 @@ abstract class _HistoryRequestModel implements HistoryRequestModel {
HttpRequestModel get httpRequestModel;
@override
HttpResponseModel get httpResponseModel;
/// Create a copy of HistoryRequestModel
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(ignore: true)
@JsonKey(includeFromJson: false, includeToJson: false)
_$$HistoryRequestModelImplCopyWith<_$HistoryRequestModelImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -12,6 +12,7 @@ class RequestModel with _$RequestModel {
)
const factory RequestModel({
required String id,
@Default(APIType.rest) APIType apiType,
@Default("") String name,
@Default("") String description,
@JsonKey(includeToJson: false) @Default(0) requestTabIndex,

View File

@ -21,6 +21,7 @@ RequestModel _$RequestModelFromJson(Map<String, dynamic> json) {
/// @nodoc
mixin _$RequestModel {
String get id => throw _privateConstructorUsedError;
APIType get apiType => throw _privateConstructorUsedError;
String get name => throw _privateConstructorUsedError;
String get description => throw _privateConstructorUsedError;
@JsonKey(includeToJson: false)
@ -35,8 +36,12 @@ mixin _$RequestModel {
@JsonKey(includeToJson: false)
DateTime? get sendingTime => throw _privateConstructorUsedError;
/// Serializes this RequestModel to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
/// Create a copy of RequestModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$RequestModelCopyWith<RequestModel> get copyWith =>
throw _privateConstructorUsedError;
}
@ -49,6 +54,7 @@ abstract class $RequestModelCopyWith<$Res> {
@useResult
$Res call(
{String id,
APIType apiType,
String name,
String description,
@JsonKey(includeToJson: false) dynamic requestTabIndex,
@ -73,10 +79,13 @@ class _$RequestModelCopyWithImpl<$Res, $Val extends RequestModel>
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of RequestModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? apiType = null,
Object? name = null,
Object? description = null,
Object? requestTabIndex = freezed,
@ -92,6 +101,10 @@ class _$RequestModelCopyWithImpl<$Res, $Val extends RequestModel>
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
apiType: null == apiType
? _value.apiType
: apiType // ignore: cast_nullable_to_non_nullable
as APIType,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
@ -131,6 +144,8 @@ class _$RequestModelCopyWithImpl<$Res, $Val extends RequestModel>
) as $Val);
}
/// Create a copy of RequestModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$HttpRequestModelCopyWith<$Res>? get httpRequestModel {
@ -143,6 +158,8 @@ class _$RequestModelCopyWithImpl<$Res, $Val extends RequestModel>
});
}
/// Create a copy of RequestModel
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$HttpResponseModelCopyWith<$Res>? get httpResponseModel {
@ -166,6 +183,7 @@ abstract class _$$RequestModelImplCopyWith<$Res>
@useResult
$Res call(
{String id,
APIType apiType,
String name,
String description,
@JsonKey(includeToJson: false) dynamic requestTabIndex,
@ -190,10 +208,13 @@ class __$$RequestModelImplCopyWithImpl<$Res>
_$RequestModelImpl _value, $Res Function(_$RequestModelImpl) _then)
: super(_value, _then);
/// Create a copy of RequestModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? apiType = null,
Object? name = null,
Object? description = null,
Object? requestTabIndex = freezed,
@ -209,6 +230,10 @@ class __$$RequestModelImplCopyWithImpl<$Res>
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
apiType: null == apiType
? _value.apiType
: apiType // ignore: cast_nullable_to_non_nullable
as APIType,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
@ -254,6 +279,7 @@ class __$$RequestModelImplCopyWithImpl<$Res>
class _$RequestModelImpl implements _RequestModel {
const _$RequestModelImpl(
{required this.id,
this.apiType = APIType.rest,
this.name = "",
this.description = "",
@JsonKey(includeToJson: false) this.requestTabIndex = 0,
@ -271,6 +297,9 @@ class _$RequestModelImpl implements _RequestModel {
final String id;
@override
@JsonKey()
final APIType apiType;
@override
@JsonKey()
final String name;
@override
@JsonKey()
@ -295,7 +324,7 @@ class _$RequestModelImpl implements _RequestModel {
@override
String toString() {
return 'RequestModel(id: $id, name: $name, description: $description, requestTabIndex: $requestTabIndex, httpRequestModel: $httpRequestModel, responseStatus: $responseStatus, message: $message, httpResponseModel: $httpResponseModel, isWorking: $isWorking, sendingTime: $sendingTime)';
return 'RequestModel(id: $id, apiType: $apiType, name: $name, description: $description, requestTabIndex: $requestTabIndex, httpRequestModel: $httpRequestModel, responseStatus: $responseStatus, message: $message, httpResponseModel: $httpResponseModel, isWorking: $isWorking, sendingTime: $sendingTime)';
}
@override
@ -304,6 +333,7 @@ class _$RequestModelImpl implements _RequestModel {
(other.runtimeType == runtimeType &&
other is _$RequestModelImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.apiType, apiType) || other.apiType == apiType) &&
(identical(other.name, name) || other.name == name) &&
(identical(other.description, description) ||
other.description == description) &&
@ -322,11 +352,12 @@ class _$RequestModelImpl implements _RequestModel {
other.sendingTime == sendingTime));
}
@JsonKey(ignore: true)
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType,
id,
apiType,
name,
description,
const DeepCollectionEquality().hash(requestTabIndex),
@ -337,7 +368,9 @@ class _$RequestModelImpl implements _RequestModel {
isWorking,
sendingTime);
@JsonKey(ignore: true)
/// Create a copy of RequestModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$RequestModelImplCopyWith<_$RequestModelImpl> get copyWith =>
@ -354,6 +387,7 @@ class _$RequestModelImpl implements _RequestModel {
abstract class _RequestModel implements RequestModel {
const factory _RequestModel(
{required final String id,
final APIType apiType,
final String name,
final String description,
@JsonKey(includeToJson: false) final dynamic requestTabIndex,
@ -371,6 +405,8 @@ abstract class _RequestModel implements RequestModel {
@override
String get id;
@override
APIType get apiType;
@override
String get name;
@override
String get description;
@ -391,8 +427,11 @@ abstract class _RequestModel implements RequestModel {
@override
@JsonKey(includeToJson: false)
DateTime? get sendingTime;
/// Create a copy of RequestModel
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(ignore: true)
@JsonKey(includeFromJson: false, includeToJson: false)
_$$RequestModelImplCopyWith<_$RequestModelImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -8,6 +8,8 @@ part of 'request_model.dart';
_$RequestModelImpl _$$RequestModelImplFromJson(Map json) => _$RequestModelImpl(
id: json['id'] as String,
apiType: $enumDecodeNullable(_$APITypeEnumMap, json['apiType']) ??
APIType.rest,
name: json['name'] as String? ?? "",
description: json['description'] as String? ?? "",
requestTabIndex: json['requestTabIndex'] ?? 0,
@ -30,6 +32,7 @@ _$RequestModelImpl _$$RequestModelImplFromJson(Map json) => _$RequestModelImpl(
Map<String, dynamic> _$$RequestModelImplToJson(_$RequestModelImpl instance) =>
<String, dynamic>{
'id': instance.id,
'apiType': _$APITypeEnumMap[instance.apiType]!,
'name': instance.name,
'description': instance.description,
'httpRequestModel': instance.httpRequestModel?.toJson(),
@ -37,3 +40,7 @@ Map<String, dynamic> _$$RequestModelImplToJson(_$RequestModelImpl instance) =>
'message': instance.message,
'httpResponseModel': instance.httpResponseModel?.toJson(),
};
const _$APITypeEnumMap = {
APIType.rest: 'rest',
};

View File

@ -1,6 +1,5 @@
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'package:apidash/widgets/widgets.dart';
class SidebarFilter extends StatelessWidget {
const SidebarFilter({
@ -32,7 +31,7 @@ class SidebarFilter extends StatelessWidget {
),
kHSpacer5,
Expanded(
child: RawTextField(
child: ADRawTextField(
style: Theme.of(context).textTheme.bodyMedium,
hintText: filterHintText ?? "Filter by name",
onChanged: onFilterFieldChanged,

View File

@ -83,7 +83,7 @@ class EditEnvironmentSecretsState
key: ValueKey("$selectedId-$index-secrets-row-$seed"),
cells: <DataCell>[
DataCell(
CheckBox(
ADCheckBox(
keyId: "$selectedId-$index-secrets-c-$seed",
value: secretRows[index].enabled,
onChanged: isLast

View File

@ -83,7 +83,7 @@ class EditEnvironmentVariablesState
key: ValueKey("$selectedId-$index-variables-row-$seed"),
cells: <DataCell>[
DataCell(
CheckBox(
ADCheckBox(
keyId: "$selectedId-$index-variables-c-$seed",
value: variableRows[index].enabled,
onChanged: isLast

View File

@ -53,11 +53,14 @@ class EnvironmentEditor extends ConsumerWidget {
onDuplicatePressed: () => ref
.read(environmentsStateNotifierProvider.notifier)
.duplicateEnvironment(id!),
onDeletePressed: () {
ref
.read(environmentsStateNotifierProvider.notifier)
.removeEnvironment(id!);
},
onDeletePressed: id == kGlobalEnvironmentId
? null
: () {
ref
.read(environmentsStateNotifierProvider
.notifier)
.removeEnvironment(id!);
},
),
kHSpacer4,
],

View File

@ -90,7 +90,7 @@ class EditRequestHeadersState extends ConsumerState<EditRequestHeaders> {
key: ValueKey("$selectedId-$index-headers-row-$seed"),
cells: <DataCell>[
DataCell(
CheckBox(
ADCheckBox(
keyId: "$selectedId-$index-headers-c-$seed",
value: isRowEnabledList[index],
onChanged: isLast

View File

@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:data_table_2/data_table_2.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/consts.dart';
import 'package:apidash/screens/common_widgets/common_widgets.dart';
@ -90,7 +89,7 @@ class EditRequestURLParamsState extends ConsumerState<EditRequestURLParams> {
key: ValueKey("$selectedId-$index-params-row-$seed"),
cells: <DataCell>[
DataCell(
CheckBox(
ADCheckBox(
keyId: "$selectedId-$index-params-c-$seed",
value: isRowEnabledList[index],
onChanged: isLast

View File

@ -1,13 +1,10 @@
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/extensions/extensions.dart';
import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/consts.dart';
import 'details_card/details_card.dart';
import 'details_card/request_pane/request_pane.dart';
import '../../common_widgets/common_widgets.dart';
import 'request_editor_top_bar.dart';
import 'url_card.dart';
class RequestEditor extends StatelessWidget {
@ -42,53 +39,3 @@ class RequestEditor extends StatelessWidget {
);
}
}
class RequestEditorTopBar extends ConsumerWidget {
const RequestEditorTopBar({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final id = ref.watch(selectedIdStateProvider);
final name =
ref.watch(selectedRequestModelProvider.select((value) => value?.name));
return Padding(
padding: const EdgeInsets.only(
left: 12.0,
top: 4.0,
right: 4.0,
bottom: 4.0,
),
child: Row(
children: [
Expanded(
child: Text(
name ?? "",
style: Theme.of(context).textTheme.bodyMedium,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
const SizedBox(
width: 6,
),
EditorTitleActions(
onRenamePressed: () {
showRenameDialog(context, "Rename Request", name, (val) {
ref
.read(collectionStateNotifierProvider.notifier)
.update(id!, name: val);
});
},
onDuplicatePressed: () => ref
.read(collectionStateNotifierProvider.notifier)
.duplicate(id!),
onDeletePressed: () =>
ref.read(collectionStateNotifierProvider.notifier).remove(id!),
),
kHSpacer10,
const EnvironmentDropdown(),
],
),
);
}
}

View File

@ -0,0 +1,60 @@
import 'package:apidash_core/apidash_core.dart';
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/widgets.dart';
import '../../common_widgets/common_widgets.dart';
class RequestEditorTopBar extends ConsumerWidget {
const RequestEditorTopBar({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final id = ref.watch(selectedIdStateProvider);
final name =
ref.watch(selectedRequestModelProvider.select((value) => value?.name));
return Padding(
padding: const EdgeInsets.only(
left: 12.0,
top: 4.0,
right: 4.0,
bottom: 4.0,
),
child: Row(
children: [
DropdownButtonAPIType(
apiType: APIType.rest,
onChanged: (apiType) {},
),
kHSpacer10,
Expanded(
child: Text(
name ?? "",
style: Theme.of(context).textTheme.bodyMedium,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
kHSpacer10,
EditorTitleActions(
onRenamePressed: () {
showRenameDialog(context, "Rename Request", name, (val) {
ref
.read(collectionStateNotifierProvider.notifier)
.update(id!, name: val);
});
},
onDuplicatePressed: () => ref
.read(collectionStateNotifierProvider.notifier)
.duplicate(id!),
onDeletePressed: () =>
ref.read(collectionStateNotifierProvider.notifier).remove(id!),
),
kHSpacer10,
const EnvironmentDropdown(),
],
),
);
}
}

View File

@ -4,8 +4,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../providers/providers.dart';
import '../services/services.dart';
import '../utils/utils.dart';
import '../widgets/widgets.dart';
import '../common/utils.dart';
import '../consts.dart';
import '../extensions/extensions.dart';

50
lib/utils/save_utils.dart Normal file
View File

@ -0,0 +1,50 @@
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:apidash/utils/utils.dart';
Future<void> saveCollection(
Map<String, dynamic> data,
ScaffoldMessengerState sm,
) async {
var message = "";
try {
var pth = await getFileDownloadpath(null, "har");
if (pth != null) {
await saveFile(pth, jsonMapToBytes(data));
var sp = getShortPath(pth);
message = 'Saved to $sp';
}
} catch (e) {
message = "An error occurred while exporting.";
}
sm.hideCurrentSnackBar();
sm.showSnackBar(getSnackBar(message, small: false));
}
Future<void> saveToDownloads(
ScaffoldMessengerState sm, {
Uint8List? content,
String? mimeType,
String? ext,
String? name,
}) async {
var message = "";
var path = await getFileDownloadpath(
name,
ext ?? getFileExtension(mimeType),
);
if (path != null) {
try {
await saveFile(path, content!);
var sp = getShortPath(path);
message = 'Saved to $sp';
} catch (e) {
message = "An error occurred while saving file.";
}
} else {
message = "Unable to determine the download path.";
}
sm.hideCurrentSnackBar();
sm.showSnackBar(getSnackBar(message, small: false));
}

View File

@ -1,9 +1,10 @@
export 'ui_utils.dart';
export 'convert_utils.dart';
export 'envvar_utils.dart';
export 'file_utils.dart';
export 'har_utils.dart';
export 'header_utils.dart';
export 'history_utils.dart';
export 'http_utils.dart';
export 'file_utils.dart';
export 'save_utils.dart';
export 'ui_utils.dart';
export 'window_utils.dart';
export 'har_utils.dart';
export 'envvar_utils.dart';

View File

@ -1,3 +1,4 @@
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'package:apidash/consts.dart';
@ -11,13 +12,10 @@ class ClearResponseButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return IconButton(
tooltip: kTooltipClearResponse,
return ADIconButton(
icon: Icons.delete,
onPressed: onPressed,
icon: const Icon(
Icons.delete,
size: 16,
),
tooltip: kTooltipClearResponse,
);
}
}

View File

@ -1,7 +1,7 @@
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:apidash/consts.dart';
import "snackbars.dart";
class CopyButton extends StatelessWidget {
const CopyButton({
@ -20,7 +20,6 @@ class CopyButton extends StatelessWidget {
Icons.content_copy,
size: 18,
);
const label = kLabelCopy;
onPressed() async {
await Clipboard.setData(ClipboardData(text: toCopy));
sm.hideCurrentSnackBar();
@ -31,14 +30,15 @@ class CopyButton extends StatelessWidget {
? TextButton.icon(
onPressed: onPressed,
icon: icon,
label: const Text(label),
label: const Text(kLabelCopy),
)
: IconButton(
tooltip: label,
: ADIconButton(
icon: Icons.content_copy,
iconSize: 18,
tooltip: kLabelCopy,
color: Theme.of(context).colorScheme.primary,
visualDensity: VisualDensity.compact,
onPressed: onPressed,
icon: icon,
);
}
}

View File

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:apidash/utils/utils.dart';
import 'package:apidash/consts.dart';
import "snackbars.dart";
class SaveInDownloadsButton extends StatelessWidget {
const SaveInDownloadsButton({
@ -29,26 +28,13 @@ class SaveInDownloadsButton extends StatelessWidget {
);
const label = kLabelDownload;
final onPressed = (content != null)
? () async {
var message = "";
var path = await getFileDownloadpath(
name,
ext ?? getFileExtension(mimeType),
);
if (path != null) {
try {
await saveFile(path, content!);
var sp = getShortPath(path);
message = 'Saved to $sp';
} catch (e) {
message = "An error occurred while saving file.";
}
} else {
message = "Unable to determine the download path.";
}
sm.hideCurrentSnackBar();
sm.showSnackBar(getSnackBar(message, small: false));
}
? () => saveToDownloads(
sm,
content: content,
mimeType: mimeType,
ext: ext,
name: name,
)
: null;
return showLabel

View File

@ -0,0 +1,24 @@
import 'package:apidash_core/apidash_core.dart';
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
class DropdownButtonAPIType extends StatelessWidget {
const DropdownButtonAPIType({
super.key,
this.apiType,
this.onChanged,
});
final APIType? apiType;
final void Function(APIType?)? onChanged;
@override
Widget build(BuildContext context) {
return ADDropdownButton<APIType>(
value: apiType,
values: APIType.values.map((e) => (e, e.label)),
onChanged: onChanged,
isDense: true,
);
}
}

View File

@ -14,39 +14,12 @@ class DropdownButtonCodegenLanguage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final surfaceColor = Theme.of(context).colorScheme.surface;
return DropdownButton<CodegenLanguage>(
isExpanded: true,
focusColor: surfaceColor,
return ADDropdownButton<CodegenLanguage>(
value: codegenLanguage,
icon: const Icon(
Icons.unfold_more_rounded,
size: 16,
),
elevation: 4,
style: kCodeStyle.copyWith(
color: Theme.of(context).colorScheme.primary,
),
underline: Container(
height: 0,
),
values: CodegenLanguage.values.map((e) => (e, e.label)),
onChanged: onChanged,
borderRadius: kBorderRadius12,
items: CodegenLanguage.values
.map<DropdownMenuItem<CodegenLanguage>>((CodegenLanguage value) {
return DropdownMenuItem<CodegenLanguage>(
value: value,
child: Padding(
padding: kPs8,
child: Text(
value.label,
style: kTextStyleButton,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
);
}).toList(),
iconSize: 16,
isExpanded: true,
);
}
}

View File

@ -14,36 +14,11 @@ class DropdownButtonContentType extends StatelessWidget {
@override
Widget build(BuildContext context) {
final surfaceColor = Theme.of(context).colorScheme.surface;
return DropdownButton<ContentType>(
focusColor: surfaceColor,
return ADDropdownButton<ContentType>(
value: contentType,
icon: const Icon(
Icons.unfold_more_rounded,
size: 16,
),
elevation: 4,
style: kCodeStyle.copyWith(
color: Theme.of(context).colorScheme.primary,
),
underline: Container(
height: 0,
),
values: ContentType.values.map((e) => (e, e.name)),
onChanged: onChanged,
borderRadius: kBorderRadius12,
items: ContentType.values
.map<DropdownMenuItem<ContentType>>((ContentType value) {
return DropdownMenuItem<ContentType>(
value: value,
child: Padding(
padding: kPs8,
child: Text(
value.name,
style: kTextStyleButton,
),
),
);
}).toList(),
iconSize: 16,
);
}
}

View File

@ -14,35 +14,11 @@ class DropdownButtonFormData extends StatelessWidget {
@override
Widget build(BuildContext context) {
final surfaceColor = Theme.of(context).colorScheme.surface;
return DropdownButton<FormDataType>(
dropdownColor: surfaceColor,
focusColor: surfaceColor,
return ADDropdownButton<FormDataType>(
value: formDataType,
icon: const Icon(
Icons.unfold_more_rounded,
size: 16,
),
elevation: 4,
style: kCodeStyle.copyWith(
color: Theme.of(context).colorScheme.primary,
),
underline: const IgnorePointer(),
values: FormDataType.values.map((e) => (e, e.name)),
onChanged: onChanged,
borderRadius: kBorderRadius12,
items: FormDataType.values
.map<DropdownMenuItem<FormDataType>>((FormDataType value) {
return DropdownMenuItem<FormDataType>(
value: value,
child: Padding(
padding: kPs8,
child: Text(
value.name,
style: kTextStyleButton,
),
),
);
}).toList(),
iconSize: 16,
);
}
}

View File

@ -16,35 +16,19 @@ class DropdownButtonHttpMethod extends StatelessWidget {
@override
Widget build(BuildContext context) {
final surfaceColor = Theme.of(context).colorScheme.surface;
return DropdownButton<HTTPVerb>(
focusColor: surfaceColor,
return ADDropdownButton<HTTPVerb>(
value: method,
icon: const Icon(Icons.unfold_more_rounded),
elevation: 4,
underline: Container(
height: 0,
),
borderRadius: kBorderRadius12,
values: HTTPVerb.values.map((e) => (e, e.name.toUpperCase())),
onChanged: onChanged,
items: HTTPVerb.values.map<DropdownMenuItem<HTTPVerb>>((HTTPVerb value) {
return DropdownMenuItem<HTTPVerb>(
value: value,
child: Padding(
padding: EdgeInsets.only(left: context.isMediumWindow ? 8 : 16),
child: Text(
value.name.toUpperCase(),
style: kCodeStyle.copyWith(
fontWeight: FontWeight.bold,
color: getHTTPMethodColor(
value,
brightness: Theme.of(context).brightness,
),
),
),
),
);
}).toList(),
dropdownMenuItemPadding:
EdgeInsets.only(left: context.isMediumWindow ? 8 : 16),
dropdownMenuItemtextStyle: (HTTPVerb v) => kCodeStyle.copyWith(
fontWeight: FontWeight.bold,
color: getHTTPMethodColor(
v,
brightness: Theme.of(context).brightness,
),
),
);
}
}

View File

@ -14,39 +14,11 @@ class DropdownButtonImportFormat extends StatelessWidget {
@override
Widget build(BuildContext context) {
final surfaceColor = Theme.of(context).colorScheme.surface;
return DropdownButton<ImportFormat>(
isExpanded: false,
focusColor: surfaceColor,
return ADDropdownButton<ImportFormat>(
value: importFormat,
icon: const Icon(
Icons.unfold_more_rounded,
size: 16,
),
elevation: 4,
style: kCodeStyle.copyWith(
color: Theme.of(context).colorScheme.primary,
),
underline: Container(
height: 0,
),
values: ImportFormat.values.map((e) => (e, e.label)),
onChanged: onChanged,
borderRadius: kBorderRadius12,
items: ImportFormat.values
.map<DropdownMenuItem<ImportFormat>>((ImportFormat value) {
return DropdownMenuItem<ImportFormat>(
value: value,
child: Padding(
padding: kPs8,
child: Text(
value.label,
style: kTextStyleButton,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
);
}).toList(),
iconSize: 16,
);
}
}

View File

@ -19,35 +19,13 @@ class CellField extends StatelessWidget {
@override
Widget build(BuildContext context) {
var clrScheme = colorScheme ?? Theme.of(context).colorScheme;
return TextFormField(
key: Key(keyId),
return ADOutlinedTextField(
keyId: keyId,
initialValue: initialValue,
style: kCodeStyle.copyWith(
color: clrScheme.onSurface,
),
decoration: InputDecoration(
hintStyle: kCodeStyle.copyWith(
color: clrScheme.outline.withOpacity(
kHintOpacity,
),
),
hintText: hintText,
contentPadding: const EdgeInsets.only(bottom: 12),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: clrScheme.primary.withOpacity(
kHintOpacity,
),
),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: clrScheme.surfaceContainerHighest,
),
),
),
hintText: hintText,
hintTextFontSize: Theme.of(context).textTheme.bodySmall?.fontSize,
onChanged: onChanged,
colorScheme: colorScheme,
);
}
}

View File

@ -1,6 +1,5 @@
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'field_raw.dart';
class JsonSearchField extends StatelessWidget {
const JsonSearchField({super.key, this.onChanged, this.controller});
@ -10,7 +9,7 @@ class JsonSearchField extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RawTextField(
return ADRawTextField(
controller: controller,
onChanged: onChanged,
style: kCodeStyle,

View File

@ -1,54 +0,0 @@
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
class OutlinedField extends StatelessWidget {
const OutlinedField({
super.key,
this.keyId,
this.initialValue,
this.hintText,
this.onChanged,
this.colorScheme,
});
final String? keyId;
final String? initialValue;
final String? hintText;
final void Function(String)? onChanged;
final ColorScheme? colorScheme;
@override
Widget build(BuildContext context) {
var clrScheme = colorScheme ?? Theme.of(context).colorScheme;
return TextFormField(
key: keyId != null ? Key(keyId!) : null,
initialValue: initialValue,
style: kCodeStyle.copyWith(
color: clrScheme.onSurface,
),
decoration: InputDecoration(
hintStyle: kCodeStyle.copyWith(
color: clrScheme.outline.withOpacity(
kHintOpacity,
),
),
hintText: hintText,
contentPadding: kP10,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: clrScheme.primary.withOpacity(
kHintOpacity,
),
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: clrScheme.surfaceContainerHighest,
),
),
isDense: true,
),
onChanged: onChanged,
);
}
}

View File

@ -8,7 +8,6 @@ import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:url_launcher/url_launcher_string.dart';
import '../consts.dart';
import '../utils/ui_utils.dart';
import "snackbars.dart";
import 'field_json_search.dart';
class JsonPreviewerColor {

View File

@ -11,7 +11,6 @@ export 'card_request_details.dart';
export 'card_sidebar_environment.dart';
export 'card_sidebar_history.dart';
export 'card_sidebar_request.dart';
export 'checkbox.dart';
export 'code_previewer.dart';
export 'codegen_previewer.dart';
export 'dialog_about.dart';
@ -25,6 +24,7 @@ export 'dropdown_content_type.dart';
export 'dropdown_formdata.dart';
export 'dropdown_http_method.dart';
export 'dropdown_import_format.dart';
export 'dropdown_api_type.dart';
export 'editor_json.dart';
export 'editor.dart';
export 'error_message.dart';
@ -32,8 +32,6 @@ export 'field_cell_obscurable.dart';
export 'field_cell.dart';
export 'field_header.dart';
export 'field_json_search.dart';
export 'field_outlined.dart';
export 'field_raw.dart';
export 'field_read_only.dart';
export 'field_url.dart';
export 'intro_message.dart';
@ -49,7 +47,6 @@ export 'popup_menu_uri.dart';
export 'previewer.dart';
export 'request_widgets.dart';
export 'response_widgets.dart';
export 'snackbars.dart';
export 'splitview_drawer.dart';
export 'splitview_dashboard.dart';
export 'splitview_equal.dart';

View File

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:file_selector/file_selector.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:path/path.dart' as p;
import 'field_outlined.dart';
class WorkspaceSelector extends HookWidget {
const WorkspaceSelector({
@ -19,6 +18,7 @@ class WorkspaceSelector extends HookWidget {
@override
Widget build(BuildContext context) {
var selectedDirectory = useState<String?>(null);
var selectedDirectoryTextController = useTextEditingController();
var workspaceName = useState<String?>(null);
return Scaffold(
body: Center(
@ -46,27 +46,21 @@ class WorkspaceSelector extends HookWidget {
Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: 1,
color: Theme.of(context).colorScheme.primaryContainer,
),
borderRadius: kBorderRadius6,
),
padding: kP4,
child: Text(
style: kTextStyleButtonSmall,
selectedDirectory.value ?? "",
maxLines: 4,
overflow: TextOverflow.ellipsis,
),
child: ADOutlinedTextField(
keyId: "workspace-path",
controller: selectedDirectoryTextController,
textStyle: kTextStyleButtonSmall,
readOnly: true,
isDense: true,
maxLines: null,
),
),
kHSpacer10,
FilledButton.tonalIcon(
onPressed: () async {
selectedDirectory.value = await getDirectoryPath();
selectedDirectoryTextController.text =
selectedDirectory.value ?? "";
},
label: const Text(kLabelSelect),
icon: const Icon(Icons.folder_rounded),
@ -85,12 +79,12 @@ class WorkspaceSelector extends HookWidget {
],
),
kVSpacer5,
OutlinedField(
ADOutlinedTextField(
keyId: "workspace-name",
onChanged: (value) {
workspaceName.value = value.trim();
},
colorScheme: Theme.of(context).colorScheme,
isDense: true,
),
kVSpacer40,
Row(

View File

@ -1,5 +1,12 @@
import 'dart:convert';
enum APIType {
rest("HTTP");
const APIType(this.label);
final String label;
}
enum HTTPVerb { get, head, post, put, patch, delete }
enum SupportedUriSchemes { https, http }

View File

@ -1,4 +1,5 @@
library apidash_design_system;
export 'package:google_fonts/google_fonts.dart';
export 'widgets/widgets.dart';
export 'consts.dart';

View File

@ -21,18 +21,25 @@ final kFontFamilyFallback = !kIsWeb && (Platform.isIOS || Platform.isMacOS)
final kLightMaterialAppTheme = ThemeData(
fontFamily: kFontFamily,
fontFamilyFallback: kFontFamilyFallback,
colorSchemeSeed: kColorSchemeSeed,
useMaterial3: true,
brightness: Brightness.light,
visualDensity: VisualDensity.adaptivePlatformDensity,
colorScheme: ColorScheme.fromSeed(
seedColor: kColorSchemeSeed,
brightness: Brightness.light,
dynamicSchemeVariant: DynamicSchemeVariant.fidelity,
),
);
final kDarkMaterialAppTheme = ThemeData(
fontFamily: kFontFamily,
fontFamilyFallback: kFontFamilyFallback,
colorSchemeSeed: kColorSchemeSeed,
useMaterial3: true,
brightness: Brightness.dark,
visualDensity: VisualDensity.adaptivePlatformDensity,
colorScheme: ColorScheme.fromSeed(
seedColor: kColorSchemeSeed,
brightness: Brightness.dark,
dynamicSchemeVariant: DynamicSchemeVariant.fidelity,
),
);
final kCodeStyle = TextStyle(

View File

@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
class ADIconButton extends StatelessWidget {
const ADIconButton({
super.key,
required this.icon,
this.iconSize,
this.onPressed,
this.color,
this.visualDensity,
this.tooltip,
});
final IconData icon;
final double? iconSize;
final VoidCallback? onPressed;
final Color? color;
final VisualDensity? visualDensity;
final String? tooltip;
@override
Widget build(BuildContext context) {
return IconButton(
tooltip: tooltip,
icon: Icon(
icon,
size: iconSize ?? 16,
),
color: color,
visualDensity: visualDensity,
onPressed: onPressed,
);
}
}

View File

@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
class CheckBox extends StatelessWidget {
class ADCheckBox extends StatelessWidget {
final String keyId;
final bool value;
final ValueChanged<bool?>? onChanged;
final ColorScheme? colorScheme;
const CheckBox({
const ADCheckBox({
super.key,
required this.keyId,
required this.value,

View File

@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import '../consts.dart';
class ADDropdownButton<T> extends StatelessWidget {
const ADDropdownButton({
super.key,
this.value,
required this.values,
this.onChanged,
this.isExpanded = false,
this.isDense = false,
this.iconSize,
this.dropdownMenuItemPadding = kPs8,
this.dropdownMenuItemtextStyle,
});
final T? value;
final Iterable<(T, String?)> values;
final void Function(T?)? onChanged;
final bool isExpanded;
final bool isDense;
final double? iconSize;
final EdgeInsetsGeometry dropdownMenuItemPadding;
final TextStyle? Function(T)? dropdownMenuItemtextStyle;
@override
Widget build(BuildContext context) {
final surfaceColor = Theme.of(context).colorScheme.surface;
return DropdownButton<T>(
isExpanded: isExpanded,
isDense: isDense,
focusColor: surfaceColor,
value: value,
icon: Icon(
Icons.unfold_more_rounded,
size: iconSize,
),
elevation: 4,
style: kCodeStyle.copyWith(
color: Theme.of(context).colorScheme.primary,
),
underline: Container(
height: 0,
),
onChanged: onChanged,
borderRadius: kBorderRadius12,
items: values.map<DropdownMenuItem<T>>(((T, String?) value) {
return DropdownMenuItem<T>(
value: value.$1,
child: Padding(
padding: dropdownMenuItemPadding,
child: Text(
value.$2 ?? value.$1.toString(),
style:
dropdownMenuItemtextStyle?.call(value.$1) ?? kTextStyleButton,
overflow: isExpanded ? TextOverflow.ellipsis : null,
maxLines: isExpanded ? 1 : null,
),
),
);
}).toList(),
);
}
}

View File

@ -0,0 +1,99 @@
import 'package:flutter/material.dart';
import '../consts.dart';
class ADOutlinedTextField extends StatelessWidget {
const ADOutlinedTextField({
super.key,
this.keyId,
this.controller,
this.readOnly = false,
this.enabled,
this.maxLines = 1,
this.expands = false,
this.initialValue,
this.textStyle,
this.textColor,
this.textFontSize,
this.hintText,
this.hintTextStyle,
this.hintTextColor,
this.hintTextFontSize,
this.contentPadding,
this.fillColor,
this.focussedBorderColor,
this.enabledBorderColor,
this.isDense,
this.onChanged,
this.colorScheme,
});
final String? keyId;
final TextEditingController? controller;
final bool readOnly;
final bool? enabled;
final int? maxLines;
final bool expands;
final bool? isDense;
final String? initialValue;
final TextStyle? textStyle;
final double? textFontSize;
final Color? textColor;
final String? hintText;
final TextStyle? hintTextStyle;
final double? hintTextFontSize;
final Color? hintTextColor;
final EdgeInsetsGeometry? contentPadding;
final Color? fillColor;
final Color? focussedBorderColor;
final Color? enabledBorderColor;
final void Function(String)? onChanged;
final ColorScheme? colorScheme;
@override
Widget build(BuildContext context) {
var clrScheme = colorScheme ?? Theme.of(context).colorScheme;
return TextFormField(
key: keyId != null ? Key(keyId!) : null,
controller: controller,
readOnly: readOnly,
enabled: enabled,
maxLines: maxLines,
expands: expands,
initialValue: initialValue,
style: textStyle ??
kCodeStyle.copyWith(
fontSize: textFontSize,
color: textColor ?? clrScheme.onSurface,
),
decoration: InputDecoration(
filled: true,
fillColor: fillColor ?? clrScheme.surfaceContainerLowest,
hintStyle: hintTextStyle ??
kCodeStyle.copyWith(
fontSize: hintTextFontSize,
color: hintTextColor ??
clrScheme.outline.withOpacity(
kHintOpacity,
),
),
hintText: hintText,
contentPadding: contentPadding ?? kP10,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: focussedBorderColor ??
clrScheme.primary.withOpacity(
kHintOpacity,
),
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: enabledBorderColor ?? clrScheme.surfaceContainerHighest,
),
),
isDense: isDense,
),
onChanged: onChanged,
);
}
}

View File

@ -1,8 +1,8 @@
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
class RawTextField extends StatelessWidget {
const RawTextField({
class ADRawTextField extends StatelessWidget {
const ADRawTextField({
super.key,
this.onChanged,
this.controller,

View File

@ -0,0 +1,6 @@
export 'button_icon.dart';
export 'checkbox.dart';
export 'dropdown.dart';
export 'snackbar.dart';
export 'textfield_outlined.dart';
export 'textfield_raw.dart';

View File

@ -1,6 +1,6 @@
import 'package:apidash_design_system/widgets/checkbox.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:apidash/widgets/checkbox.dart';
void main() {
testWidgets('Testing for Checkbox', (tester) async {
@ -9,7 +9,7 @@ void main() {
MaterialApp(
title: 'Checkbox Widget',
home: Scaffold(
body: CheckBox(
body: ADCheckBox(
keyId: "1",
value: false,
onChanged: (value) {

View File

@ -180,6 +180,7 @@ RequestModel testRequestModel = RequestModel(
// JSON
Map<String, dynamic> requestModelJson = {
'id': '1',
'apiType': 'rest',
'name': '',
'description': '',
'httpRequestModel': httpRequestModelPost10Json,

View File

@ -3,7 +3,6 @@
import 'package:apidash/main.dart';
import 'package:apidash/app.dart';
import 'package:apidash/common/utils.dart';
import 'package:apidash/screens/screens.dart';
void main() {}