mirror of
https://github.com/foss42/apidash.git
synced 2025-06-30 21:06:43 +08:00
wip: environment pane
This commit is contained in:
@ -1,81 +0,0 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
|
||||||
|
|
||||||
import 'environment_model.dart';
|
|
||||||
|
|
||||||
@immutable
|
|
||||||
class EnvironmentListModel {
|
|
||||||
const EnvironmentListModel({
|
|
||||||
this.actveEnvironment,
|
|
||||||
this.globalEnvironment = const EnvironmentModel(id: "global"),
|
|
||||||
this.environments = const [],
|
|
||||||
});
|
|
||||||
|
|
||||||
final EnvironmentModel? actveEnvironment;
|
|
||||||
final EnvironmentModel globalEnvironment;
|
|
||||||
final List<EnvironmentModel> environments;
|
|
||||||
|
|
||||||
EnvironmentListModel copyWith({
|
|
||||||
EnvironmentModel? actveEnvironment,
|
|
||||||
EnvironmentModel? globalEnvironment,
|
|
||||||
List<EnvironmentModel>? environments,
|
|
||||||
}) {
|
|
||||||
return EnvironmentListModel(
|
|
||||||
actveEnvironment: actveEnvironment ?? this.actveEnvironment,
|
|
||||||
globalEnvironment: globalEnvironment ?? this.globalEnvironment,
|
|
||||||
environments: environments ?? this.environments,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
factory EnvironmentListModel.fromJson(Map<dynamic, dynamic> data) {
|
|
||||||
final actveEnvironment = data["actveEnvironment"] != null
|
|
||||||
? EnvironmentModel.fromJson(
|
|
||||||
data["actveEnvironment"] as Map<String, dynamic>)
|
|
||||||
: null;
|
|
||||||
final globalEnvironment = EnvironmentModel.fromJson(
|
|
||||||
data["globalEnvironment"] as Map<String, dynamic>);
|
|
||||||
final List<dynamic> environments = data["environments"] as List<dynamic>;
|
|
||||||
|
|
||||||
const em = EnvironmentListModel();
|
|
||||||
|
|
||||||
return em.copyWith(
|
|
||||||
actveEnvironment: actveEnvironment,
|
|
||||||
globalEnvironment: globalEnvironment,
|
|
||||||
environments: environments
|
|
||||||
.map((dynamic e) =>
|
|
||||||
EnvironmentModel.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return {
|
|
||||||
"actveEnvironment": actveEnvironment?.toJson(),
|
|
||||||
"globalEnvironment": globalEnvironment.toJson(),
|
|
||||||
"environments": environments.map((e) => e.toJson()).toList(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
EnvironmentModel getEnvironment(String id) {
|
|
||||||
if (id == "global") {
|
|
||||||
return globalEnvironment;
|
|
||||||
}
|
|
||||||
return environments.firstWhere((e) => e.id == id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return other is EnvironmentListModel &&
|
|
||||||
other.actveEnvironment == actveEnvironment &&
|
|
||||||
other.globalEnvironment == globalEnvironment &&
|
|
||||||
listEquals(other.environments, environments);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode {
|
|
||||||
return Object.hash(
|
|
||||||
actveEnvironment,
|
|
||||||
globalEnvironment,
|
|
||||||
environments,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,7 +9,7 @@ part 'environment_model.g.dart';
|
|||||||
class EnvironmentModel with _$EnvironmentModel {
|
class EnvironmentModel with _$EnvironmentModel {
|
||||||
const factory EnvironmentModel({
|
const factory EnvironmentModel({
|
||||||
required String id,
|
required String id,
|
||||||
@Default("") String name,
|
@Default("New Environment") String name,
|
||||||
@Default([]) List<EnvironmentVariableModel> values,
|
@Default([]) List<EnvironmentVariableModel> values,
|
||||||
}) = _EnvironmentModel;
|
}) = _EnvironmentModel;
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ class __$$EnvironmentModelImplCopyWithImpl<$Res>
|
|||||||
class _$EnvironmentModelImpl implements _EnvironmentModel {
|
class _$EnvironmentModelImpl implements _EnvironmentModel {
|
||||||
const _$EnvironmentModelImpl(
|
const _$EnvironmentModelImpl(
|
||||||
{required this.id,
|
{required this.id,
|
||||||
this.name = "",
|
this.name = "New Environment",
|
||||||
final List<EnvironmentVariableModel> values = const []})
|
final List<EnvironmentVariableModel> values = const []})
|
||||||
: _values = values;
|
: _values = values;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ _$EnvironmentModelImpl _$$EnvironmentModelImplFromJson(
|
|||||||
Map<String, dynamic> json) =>
|
Map<String, dynamic> json) =>
|
||||||
_$EnvironmentModelImpl(
|
_$EnvironmentModelImpl(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
name: json['name'] as String? ?? "",
|
name: json['name'] as String? ?? "New Environment",
|
||||||
values: (json['values'] as List<dynamic>?)
|
values: (json['values'] as List<dynamic>?)
|
||||||
?.map((e) =>
|
?.map((e) =>
|
||||||
EnvironmentVariableModel.fromJson(e as Map<String, dynamic>))
|
EnvironmentVariableModel.fromJson(e as Map<String, dynamic>))
|
||||||
|
@ -8,7 +8,7 @@ part of 'http_response_model.dart';
|
|||||||
|
|
||||||
_$HttpResponseModelImpl _$$HttpResponseModelImplFromJson(Map json) =>
|
_$HttpResponseModelImpl _$$HttpResponseModelImplFromJson(Map json) =>
|
||||||
_$HttpResponseModelImpl(
|
_$HttpResponseModelImpl(
|
||||||
statusCode: json['statusCode'] as int?,
|
statusCode: (json['statusCode'] as num?)?.toInt(),
|
||||||
headers: (json['headers'] as Map?)?.map(
|
headers: (json['headers'] as Map?)?.map(
|
||||||
(k, e) => MapEntry(k as String, e as String),
|
(k, e) => MapEntry(k as String, e as String),
|
||||||
),
|
),
|
||||||
@ -19,7 +19,7 @@ _$HttpResponseModelImpl _$$HttpResponseModelImplFromJson(Map json) =>
|
|||||||
formattedBody: json['formattedBody'] as String?,
|
formattedBody: json['formattedBody'] as String?,
|
||||||
bodyBytes:
|
bodyBytes:
|
||||||
const Uint8ListConverter().fromJson(json['bodyBytes'] as List<int>?),
|
const Uint8ListConverter().fromJson(json['bodyBytes'] as List<int>?),
|
||||||
time: const DurationConverter().fromJson(json['time'] as int?),
|
time: const DurationConverter().fromJson((json['time'] as num?)?.toInt()),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$HttpResponseModelImplToJson(
|
Map<String, dynamic> _$$HttpResponseModelImplToJson(
|
||||||
|
@ -15,7 +15,7 @@ _$RequestModelImpl _$$RequestModelImplFromJson(Map json) => _$RequestModelImpl(
|
|||||||
? null
|
? null
|
||||||
: HttpRequestModel.fromJson(
|
: HttpRequestModel.fromJson(
|
||||||
Map<String, Object?>.from(json['httpRequestModel'] as Map)),
|
Map<String, Object?>.from(json['httpRequestModel'] as Map)),
|
||||||
responseStatus: json['responseStatus'] as int?,
|
responseStatus: (json['responseStatus'] as num?)?.toInt(),
|
||||||
message: json['message'] as String?,
|
message: json['message'] as String?,
|
||||||
httpResponseModel: json['httpResponseModel'] == null
|
httpResponseModel: json['httpResponseModel'] == null
|
||||||
? null
|
? null
|
||||||
|
@ -5,7 +5,8 @@ import 'package:apidash/utils/file_utils.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import '../services/services.dart' show hiveHandler, HiveHandler;
|
import '../services/services.dart' show hiveHandler, HiveHandler;
|
||||||
|
|
||||||
final selectedEnvironmentIdProvider = StateProvider<String?>((ref) => null);
|
final selectedEnvironmentIdStateProvider =
|
||||||
|
StateProvider<String?>((ref) => null);
|
||||||
|
|
||||||
final environmentsStateNotifierProvider = StateNotifierProvider<
|
final environmentsStateNotifierProvider = StateNotifierProvider<
|
||||||
EnvironmentsStateNotifier, Map<String, EnvironmentModel>?>((ref) {
|
EnvironmentsStateNotifier, Map<String, EnvironmentModel>?>((ref) {
|
||||||
@ -27,8 +28,8 @@ class EnvironmentsStateNotifier
|
|||||||
state!.keys.first,
|
state!.keys.first,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
ref.read(selectedEnvironmentIdProvider.notifier).state =
|
ref.read(selectedEnvironmentIdStateProvider.notifier).state =
|
||||||
ref.read(environmentSequenceProvider)[0];
|
kGlobalEnvironmentId;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ class EnvironmentsStateNotifier
|
|||||||
ref
|
ref
|
||||||
.read(environmentSequenceProvider.notifier)
|
.read(environmentSequenceProvider.notifier)
|
||||||
.update((state) => [id, ...state]);
|
.update((state) => [id, ...state]);
|
||||||
ref.read(selectedEnvironmentIdProvider.notifier).state =
|
ref.read(selectedEnvironmentIdStateProvider.notifier).state =
|
||||||
newEnvironmentModel.id;
|
newEnvironmentModel.id;
|
||||||
ref.read(hasUnsavedChangesProvider.notifier).state = true;
|
ref.read(hasUnsavedChangesProvider.notifier).state = true;
|
||||||
}
|
}
|
||||||
@ -123,7 +124,7 @@ class EnvironmentsStateNotifier
|
|||||||
ref
|
ref
|
||||||
.read(environmentSequenceProvider.notifier)
|
.read(environmentSequenceProvider.notifier)
|
||||||
.update((state) => [...environmentIds]);
|
.update((state) => [...environmentIds]);
|
||||||
ref.read(selectedEnvironmentIdProvider.notifier).state = newId;
|
ref.read(selectedEnvironmentIdStateProvider.notifier).state = newId;
|
||||||
ref.read(hasUnsavedChangesProvider.notifier).state = true;
|
ref.read(hasUnsavedChangesProvider.notifier).state = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +143,7 @@ class EnvironmentsStateNotifier
|
|||||||
newId = kGlobalEnvironmentId;
|
newId = kGlobalEnvironmentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref.read(selectedEnvironmentIdProvider.notifier).state = newId;
|
ref.read(selectedEnvironmentIdStateProvider.notifier).state = newId;
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
...state!,
|
...state!,
|
||||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:apidash/providers/providers.dart';
|
import 'package:apidash/providers/providers.dart';
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
|
import 'envvar/environment_page.dart';
|
||||||
import 'home_page/home_page.dart';
|
import 'home_page/home_page.dart';
|
||||||
import 'intro_page.dart';
|
import 'intro_page.dart';
|
||||||
import 'settings_page.dart';
|
import 'settings_page.dart';
|
||||||
@ -43,8 +44,8 @@ class Dashboard extends ConsumerWidget {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
ref.read(navRailIndexStateProvider.notifier).state = 1;
|
ref.read(navRailIndexStateProvider.notifier).state = 1;
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.auto_awesome_mosaic_outlined),
|
icon: const Icon(Icons.computer_outlined),
|
||||||
selectedIcon: const Icon(Icons.auto_awesome_mosaic),
|
selectedIcon: const Icon(Icons.computer_rounded),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'Variables',
|
'Variables',
|
||||||
@ -94,7 +95,7 @@ class Dashboard extends ConsumerWidget {
|
|||||||
index: railIdx,
|
index: railIdx,
|
||||||
children: const [
|
children: const [
|
||||||
HomePage(),
|
HomePage(),
|
||||||
SizedBox(),
|
EnvironmentPage(),
|
||||||
IntroPage(),
|
IntroPage(),
|
||||||
SettingsPage(),
|
SettingsPage(),
|
||||||
],
|
],
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:apidash/widgets/widgets.dart';
|
||||||
|
import 'environments_pane.dart';
|
||||||
|
|
||||||
|
class EnvironmentPage extends StatelessWidget {
|
||||||
|
const EnvironmentPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: DashboardSplitView(
|
||||||
|
sidebarWidget: EnvironmentsPane(),
|
||||||
|
mainWidget: SizedBox(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@ import 'package:apidash/consts.dart';
|
|||||||
import 'package:apidash/extensions/extensions.dart';
|
import 'package:apidash/extensions/extensions.dart';
|
||||||
import 'package:apidash/models/environment_model.dart';
|
import 'package:apidash/models/environment_model.dart';
|
||||||
import 'package:apidash/providers/providers.dart';
|
import 'package:apidash/providers/providers.dart';
|
||||||
|
import 'package:apidash/widgets/cards.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
@ -13,7 +14,34 @@ class EnvironmentsPane extends ConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return const SizedBox();
|
return Padding(
|
||||||
|
padding: kIsMacOS ? kP24CollectionPane : kP8CollectionPane,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: kPe8,
|
||||||
|
child: Wrap(
|
||||||
|
alignment: WrapAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
ref
|
||||||
|
.read(environmentsStateNotifierProvider.notifier)
|
||||||
|
.addEnvironment();
|
||||||
|
},
|
||||||
|
child: const Text(
|
||||||
|
kLabelPlusNew,
|
||||||
|
style: kTextStyleButton,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Expanded(child: EnvironmentsList()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,8 +150,35 @@ class EnvironmentItem extends ConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final selectedId = ref.watch(selectedEnvironmentIdProvider);
|
final selectedId = ref.watch(selectedEnvironmentIdStateProvider);
|
||||||
|
final activeEnvironmentId = ref.watch(activeEnvironmentIdStateProvider);
|
||||||
|
final editRequestId = ref.watch(selectedIdEditStateProvider);
|
||||||
|
final mobileDrawerKey = ref.watch(mobileDrawerKeyProvider);
|
||||||
|
|
||||||
return Text(environmentModel.name);
|
return SidebarEnvironmentCard(
|
||||||
|
id: id,
|
||||||
|
isActive: id == activeEnvironmentId,
|
||||||
|
isGlobal: id == kGlobalEnvironmentId,
|
||||||
|
name: environmentModel.name,
|
||||||
|
selectedId: selectedId,
|
||||||
|
editRequestId: editRequestId,
|
||||||
|
setActive: (value) {
|
||||||
|
ref.read(activeEnvironmentIdStateProvider.notifier).state = id;
|
||||||
|
},
|
||||||
|
onTap: () {
|
||||||
|
mobileDrawerKey.currentState?.close();
|
||||||
|
ref.read(selectedEnvironmentIdStateProvider.notifier).state = id;
|
||||||
|
},
|
||||||
|
focusNode: ref.watch(nameTextFieldFocusNodeProvider),
|
||||||
|
onChangedNameEditor: (value) {
|
||||||
|
value = value.trim();
|
||||||
|
ref
|
||||||
|
.read(environmentsStateNotifierProvider.notifier)
|
||||||
|
.updateEnvironment(editRequestId!, name: value);
|
||||||
|
},
|
||||||
|
onTapOutsideNameEditor: () {
|
||||||
|
ref.read(selectedEnvironmentIdStateProvider.notifier).state = null;
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:apidash/screens/envvar/environments_pane.dart';
|
||||||
import 'package:apidash/widgets/splitviews.dart';
|
import 'package:apidash/widgets/splitviews.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@ -81,7 +82,7 @@ class PageBranch extends StatelessWidget {
|
|||||||
offset: !context.isCompactWindow
|
offset: !context.isCompactWindow
|
||||||
? const IDOffset.only(left: 0.1)
|
? const IDOffset.only(left: 0.1)
|
||||||
: const IDOffset.only(left: 0.7),
|
: const IDOffset.only(left: 0.7),
|
||||||
leftDrawerContent: const SizedBox(),
|
leftDrawerContent: const EnvironmentsPane(),
|
||||||
mainContent: const SizedBox(),
|
mainContent: const SizedBox(),
|
||||||
);
|
);
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -83,10 +83,11 @@ class NavRail extends ConsumerWidget {
|
|||||||
final railIdx = ref.watch(navRailIndexStateProvider);
|
final railIdx = ref.watch(navRailIndexStateProvider);
|
||||||
return Material(
|
return Material(
|
||||||
type: MaterialType.transparency,
|
type: MaterialType.transparency,
|
||||||
child: Container(
|
child: Ink(
|
||||||
width: 70,
|
width: 70,
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8),
|
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
border: Border(
|
border: Border(
|
||||||
right: BorderSide(
|
right: BorderSide(
|
||||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
@ -124,6 +125,7 @@ class NavRail extends ConsumerWidget {
|
|||||||
Icons.help,
|
Icons.help,
|
||||||
Icons.help_outline,
|
Icons.help_outline,
|
||||||
'About',
|
'About',
|
||||||
|
showLabel: false,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
customNavigationDestination(
|
customNavigationDestination(
|
||||||
@ -134,6 +136,7 @@ class NavRail extends ConsumerWidget {
|
|||||||
Icons.settings,
|
Icons.settings,
|
||||||
Icons.settings_outlined,
|
Icons.settings_outlined,
|
||||||
'Settings',
|
'Settings',
|
||||||
|
showLabel: false,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
|
import 'package:apidash/extensions/extensions.dart';
|
||||||
import 'package:apidash/providers/providers.dart';
|
import 'package:apidash/providers/providers.dart';
|
||||||
import 'package:apidash/widgets/window_caption.dart';
|
import 'package:apidash/widgets/window_caption.dart';
|
||||||
|
import '../navbar.dart';
|
||||||
|
|
||||||
class PageBase extends ConsumerWidget {
|
class PageBase extends ConsumerWidget {
|
||||||
final String title;
|
final String title;
|
||||||
@ -13,28 +15,40 @@ class PageBase extends ConsumerWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final isDarkMode =
|
final isDarkMode =
|
||||||
ref.watch(settingsProvider.select((value) => value.isDark));
|
ref.watch(settingsProvider.select((value) => value.isDark));
|
||||||
|
final scaffold = Container(
|
||||||
|
padding: (context.isCompactWindow
|
||||||
|
? const EdgeInsets.only(bottom: 70)
|
||||||
|
: EdgeInsets.zero) +
|
||||||
|
(kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero),
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
child: Scaffold(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.background,
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.background,
|
||||||
|
primary: true,
|
||||||
|
title: Text(title),
|
||||||
|
centerTitle: true,
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: MediaQuery.paddingOf(context).bottom,
|
||||||
|
),
|
||||||
|
child: scaffoldBody,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
!context.isCompactWindow
|
||||||
padding: const EdgeInsets.only(bottom: 70) +
|
? Row(
|
||||||
(kIsWindows || kIsMacOS ? kPt28 : EdgeInsets.zero),
|
children: [
|
||||||
color: Theme.of(context).colorScheme.surface,
|
const NavRail(),
|
||||||
child: Scaffold(
|
Expanded(
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
child: scaffold,
|
||||||
appBar: AppBar(
|
),
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
],
|
||||||
primary: true,
|
)
|
||||||
title: Text(title),
|
: scaffold,
|
||||||
centerTitle: true,
|
|
||||||
),
|
|
||||||
body: Padding(
|
|
||||||
padding: EdgeInsets.only(
|
|
||||||
bottom: MediaQuery.paddingOf(context).bottom,
|
|
||||||
),
|
|
||||||
child: scaffoldBody,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (kIsWindows)
|
if (kIsWindows)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 29,
|
height: 29,
|
||||||
|
@ -38,7 +38,6 @@ class HiveHandler {
|
|||||||
late final Box dataBox;
|
late final Box dataBox;
|
||||||
late final Box settingsBox;
|
late final Box settingsBox;
|
||||||
late final Box environmentBox;
|
late final Box environmentBox;
|
||||||
late final Box environmentIdsBox;
|
|
||||||
|
|
||||||
HiveHandler() {
|
HiveHandler() {
|
||||||
dataBox = Hive.box(kDataBox);
|
dataBox = Hive.box(kDataBox);
|
||||||
@ -59,9 +58,9 @@ class HiveHandler {
|
|||||||
|
|
||||||
void delete(String key) => dataBox.delete(key);
|
void delete(String key) => dataBox.delete(key);
|
||||||
|
|
||||||
dynamic getEnvironmentIds() => environmentIdsBox.get(kKeyEnvironmentBoxIds);
|
dynamic getEnvironmentIds() => environmentBox.get(kKeyEnvironmentBoxIds);
|
||||||
Future<void> setEnvironmentIds(List<String>? ids) =>
|
Future<void> setEnvironmentIds(List<String>? ids) =>
|
||||||
environmentIdsBox.put(kKeyEnvironmentBoxIds, ids);
|
environmentBox.put(kKeyEnvironmentBoxIds, ids);
|
||||||
|
|
||||||
dynamic getEnvironment(String id) => environmentBox.get(id);
|
dynamic getEnvironment(String id) => environmentBox.get(id);
|
||||||
Future<void> setEnvironment(
|
Future<void> setEnvironment(
|
||||||
|
@ -158,10 +158,11 @@ class SidebarEnvironmentCard extends StatelessWidget {
|
|||||||
super.key,
|
super.key,
|
||||||
required this.id,
|
required this.id,
|
||||||
this.isGlobal = false,
|
this.isGlobal = false,
|
||||||
this.isSelected = false,
|
|
||||||
this.isActive = false,
|
this.isActive = false,
|
||||||
this.name,
|
this.name,
|
||||||
|
this.selectedId,
|
||||||
this.editRequestId,
|
this.editRequestId,
|
||||||
|
this.setActive,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
this.onDoubleTap,
|
this.onDoubleTap,
|
||||||
this.onSecondaryTap,
|
this.onSecondaryTap,
|
||||||
@ -173,10 +174,11 @@ class SidebarEnvironmentCard extends StatelessWidget {
|
|||||||
|
|
||||||
final String id;
|
final String id;
|
||||||
final bool isGlobal;
|
final bool isGlobal;
|
||||||
final bool isSelected;
|
|
||||||
final bool isActive;
|
final bool isActive;
|
||||||
final String? name;
|
final String? name;
|
||||||
|
final String? selectedId;
|
||||||
final String? editRequestId;
|
final String? editRequestId;
|
||||||
|
final void Function(bool?)? setActive;
|
||||||
final void Function()? onTap;
|
final void Function()? onTap;
|
||||||
final void Function()? onDoubleTap;
|
final void Function()? onDoubleTap;
|
||||||
final void Function()? onSecondaryTap;
|
final void Function()? onSecondaryTap;
|
||||||
@ -187,6 +189,108 @@ class SidebarEnvironmentCard extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return const SizedBox();
|
final Color color = Theme.of(context).colorScheme.surface;
|
||||||
|
final Color colorVariant =
|
||||||
|
Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.5);
|
||||||
|
final Color surfaceTint = Theme.of(context).colorScheme.primary;
|
||||||
|
bool isSelected = selectedId == id;
|
||||||
|
bool inEditMode = editRequestId == id;
|
||||||
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
return Tooltip(
|
||||||
|
message: name,
|
||||||
|
triggerMode: TooltipTriggerMode.manual,
|
||||||
|
waitDuration: const Duration(seconds: 1),
|
||||||
|
child: Card(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: kBorderRadius8,
|
||||||
|
),
|
||||||
|
elevation: isSelected ? 1 : 0,
|
||||||
|
surfaceTintColor: isSelected ? surfaceTint : null,
|
||||||
|
color: isSelected
|
||||||
|
? colorScheme.brightness == Brightness.dark
|
||||||
|
? colorVariant
|
||||||
|
: color
|
||||||
|
: color,
|
||||||
|
margin: EdgeInsets.zero,
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: kBorderRadius8,
|
||||||
|
hoverColor: colorVariant,
|
||||||
|
focusColor: colorVariant.withOpacity(0.5),
|
||||||
|
onTap: inEditMode ? null : onTap,
|
||||||
|
// onDoubleTap: inEditMode ? null : onDoubleTap,
|
||||||
|
onSecondaryTap: onSecondaryTap,
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
left: 6,
|
||||||
|
right: isSelected ? 6 : 10,
|
||||||
|
top: 5,
|
||||||
|
bottom: 5,
|
||||||
|
),
|
||||||
|
child: SizedBox(
|
||||||
|
height: 20,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
isGlobal
|
||||||
|
? const SizedBox.shrink()
|
||||||
|
: Checkbox(
|
||||||
|
value: isActive,
|
||||||
|
onChanged: isActive ? null : setActive,
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
checkColor: colorScheme.onPrimary,
|
||||||
|
fillColor: MaterialStateProperty.resolveWith<Color?>(
|
||||||
|
(Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return colorScheme.primary;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
kHSpacer4,
|
||||||
|
Expanded(
|
||||||
|
child: inEditMode
|
||||||
|
? TextFormField(
|
||||||
|
key: ValueKey("$id-name"),
|
||||||
|
initialValue: name,
|
||||||
|
// controller: controller,
|
||||||
|
focusNode: focusNode,
|
||||||
|
//autofocus: true,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
onTapOutside: (_) {
|
||||||
|
onTapOutsideNameEditor?.call();
|
||||||
|
//FocusScope.of(context).unfocus();
|
||||||
|
},
|
||||||
|
onFieldSubmitted: (value) {
|
||||||
|
onTapOutsideNameEditor?.call();
|
||||||
|
},
|
||||||
|
onChanged: onChangedNameEditor,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
isCollapsed: true,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
border: InputBorder.none,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Text(
|
||||||
|
name ?? "h",
|
||||||
|
softWrap: false,
|
||||||
|
overflow: TextOverflow.fade,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: isSelected && !inEditMode,
|
||||||
|
child: SizedBox(
|
||||||
|
width: 28,
|
||||||
|
child: RequestCardMenu(
|
||||||
|
onSelected: onMenuSelected,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user