mirror of
https://github.com/foss42/apidash.git
synced 2025-06-28 20:13:46 +08:00
wip: manage history dialog
This commit is contained in:
@ -109,6 +109,7 @@ const kPv2 = EdgeInsets.symmetric(vertical: 2);
|
|||||||
const kPv6 = EdgeInsets.symmetric(vertical: 6);
|
const kPv6 = EdgeInsets.symmetric(vertical: 6);
|
||||||
const kPv8 = EdgeInsets.symmetric(vertical: 8);
|
const kPv8 = EdgeInsets.symmetric(vertical: 8);
|
||||||
const kPv10 = EdgeInsets.symmetric(vertical: 10);
|
const kPv10 = EdgeInsets.symmetric(vertical: 10);
|
||||||
|
const kPv20 = EdgeInsets.symmetric(vertical: 20);
|
||||||
const kPh2 = EdgeInsets.symmetric(horizontal: 2);
|
const kPh2 = EdgeInsets.symmetric(horizontal: 2);
|
||||||
const kPt28o8 = EdgeInsets.only(top: 28, left: 8.0, right: 8.0, bottom: 8.0);
|
const kPt28o8 = EdgeInsets.only(top: 28, left: 8.0, right: 8.0, bottom: 8.0);
|
||||||
const kPt5o10 =
|
const kPt5o10 =
|
||||||
@ -116,9 +117,8 @@ const kPt5o10 =
|
|||||||
const kPh4 = EdgeInsets.symmetric(horizontal: 4);
|
const kPh4 = EdgeInsets.symmetric(horizontal: 4);
|
||||||
const kPh8 = EdgeInsets.symmetric(horizontal: 8);
|
const kPh8 = EdgeInsets.symmetric(horizontal: 8);
|
||||||
const kPh12 = EdgeInsets.symmetric(horizontal: 12);
|
const kPh12 = EdgeInsets.symmetric(horizontal: 12);
|
||||||
const kPh20 = EdgeInsets.symmetric(
|
const kPh20 = EdgeInsets.symmetric(horizontal: 20);
|
||||||
horizontal: 20,
|
const kPh24 = EdgeInsets.symmetric(horizontal: 24);
|
||||||
);
|
|
||||||
const kPh20t40 = EdgeInsets.only(
|
const kPh20t40 = EdgeInsets.only(
|
||||||
left: 20,
|
left: 20,
|
||||||
right: 20,
|
right: 20,
|
||||||
@ -178,6 +178,7 @@ const kHSpacer40 = SizedBox(width: 40);
|
|||||||
const kVSpacer5 = SizedBox(height: 5);
|
const kVSpacer5 = SizedBox(height: 5);
|
||||||
const kVSpacer8 = SizedBox(height: 8);
|
const kVSpacer8 = SizedBox(height: 8);
|
||||||
const kVSpacer10 = SizedBox(height: 10);
|
const kVSpacer10 = SizedBox(height: 10);
|
||||||
|
const kVSpacer16 = SizedBox(height: 16);
|
||||||
const kVSpacer20 = SizedBox(height: 20);
|
const kVSpacer20 = SizedBox(height: 20);
|
||||||
const kVSpacer40 = SizedBox(height: 40);
|
const kVSpacer40 = SizedBox(height: 40);
|
||||||
|
|
||||||
@ -331,6 +332,17 @@ class ButtonData {
|
|||||||
final String tooltip;
|
final String tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum HistoryRetentionPeriod {
|
||||||
|
oneWeek("1 Week", Icons.calendar_view_week_rounded),
|
||||||
|
oneMonth("1 Month", Icons.calendar_view_month_rounded),
|
||||||
|
threeMonths("3 Months", Icons.calendar_month_rounded),
|
||||||
|
forever("Forever", Icons.all_inclusive_rounded);
|
||||||
|
|
||||||
|
const HistoryRetentionPeriod(this.label, this.icon);
|
||||||
|
final String label;
|
||||||
|
final IconData icon;
|
||||||
|
}
|
||||||
|
|
||||||
enum ItemMenuOption {
|
enum ItemMenuOption {
|
||||||
edit("Rename"),
|
edit("Rename"),
|
||||||
delete("Delete"),
|
delete("Delete"),
|
||||||
|
@ -13,6 +13,7 @@ class SettingsModel {
|
|||||||
this.saveResponses = true,
|
this.saveResponses = true,
|
||||||
this.promptBeforeClosing = true,
|
this.promptBeforeClosing = true,
|
||||||
this.activeEnvironmentId,
|
this.activeEnvironmentId,
|
||||||
|
this.historyRetentionPeriod = HistoryRetentionPeriod.oneWeek,
|
||||||
});
|
});
|
||||||
|
|
||||||
final bool isDark;
|
final bool isDark;
|
||||||
@ -24,6 +25,7 @@ class SettingsModel {
|
|||||||
final bool saveResponses;
|
final bool saveResponses;
|
||||||
final bool promptBeforeClosing;
|
final bool promptBeforeClosing;
|
||||||
final String? activeEnvironmentId;
|
final String? activeEnvironmentId;
|
||||||
|
final HistoryRetentionPeriod historyRetentionPeriod;
|
||||||
|
|
||||||
SettingsModel copyWith({
|
SettingsModel copyWith({
|
||||||
bool? isDark,
|
bool? isDark,
|
||||||
@ -35,6 +37,7 @@ class SettingsModel {
|
|||||||
bool? saveResponses,
|
bool? saveResponses,
|
||||||
bool? promptBeforeClosing,
|
bool? promptBeforeClosing,
|
||||||
String? activeEnvironmentId,
|
String? activeEnvironmentId,
|
||||||
|
HistoryRetentionPeriod? historyRetentionPeriod,
|
||||||
}) {
|
}) {
|
||||||
return SettingsModel(
|
return SettingsModel(
|
||||||
isDark: isDark ?? this.isDark,
|
isDark: isDark ?? this.isDark,
|
||||||
@ -47,6 +50,8 @@ class SettingsModel {
|
|||||||
saveResponses: saveResponses ?? this.saveResponses,
|
saveResponses: saveResponses ?? this.saveResponses,
|
||||||
promptBeforeClosing: promptBeforeClosing ?? this.promptBeforeClosing,
|
promptBeforeClosing: promptBeforeClosing ?? this.promptBeforeClosing,
|
||||||
activeEnvironmentId: activeEnvironmentId ?? this.activeEnvironmentId,
|
activeEnvironmentId: activeEnvironmentId ?? this.activeEnvironmentId,
|
||||||
|
historyRetentionPeriod:
|
||||||
|
historyRetentionPeriod ?? this.historyRetentionPeriod,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +85,18 @@ class SettingsModel {
|
|||||||
final saveResponses = data["saveResponses"] as bool?;
|
final saveResponses = data["saveResponses"] as bool?;
|
||||||
final promptBeforeClosing = data["promptBeforeClosing"] as bool?;
|
final promptBeforeClosing = data["promptBeforeClosing"] as bool?;
|
||||||
final activeEnvironmentId = data["activeEnvironmentId"] as String?;
|
final activeEnvironmentId = data["activeEnvironmentId"] as String?;
|
||||||
|
final historyRetentionPeriodStr = data["historyRetentionPeriod"] as String?;
|
||||||
|
HistoryRetentionPeriod historyRetentionPeriod =
|
||||||
|
HistoryRetentionPeriod.oneWeek;
|
||||||
|
if (historyRetentionPeriodStr != null) {
|
||||||
|
try {
|
||||||
|
historyRetentionPeriod =
|
||||||
|
HistoryRetentionPeriod.values.byName(historyRetentionPeriodStr);
|
||||||
|
} catch (e) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const sm = SettingsModel();
|
const sm = SettingsModel();
|
||||||
|
|
||||||
return sm.copyWith(
|
return sm.copyWith(
|
||||||
@ -92,6 +109,7 @@ class SettingsModel {
|
|||||||
saveResponses: saveResponses,
|
saveResponses: saveResponses,
|
||||||
promptBeforeClosing: promptBeforeClosing,
|
promptBeforeClosing: promptBeforeClosing,
|
||||||
activeEnvironmentId: activeEnvironmentId,
|
activeEnvironmentId: activeEnvironmentId,
|
||||||
|
historyRetentionPeriod: historyRetentionPeriod,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,6 +126,7 @@ class SettingsModel {
|
|||||||
"saveResponses": saveResponses,
|
"saveResponses": saveResponses,
|
||||||
"promptBeforeClosing": promptBeforeClosing,
|
"promptBeforeClosing": promptBeforeClosing,
|
||||||
"activeEnvironmentId": activeEnvironmentId,
|
"activeEnvironmentId": activeEnvironmentId,
|
||||||
|
"historyRetentionPeriod": historyRetentionPeriod.name,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +148,8 @@ class SettingsModel {
|
|||||||
other.defaultCodeGenLang == defaultCodeGenLang &&
|
other.defaultCodeGenLang == defaultCodeGenLang &&
|
||||||
other.saveResponses == saveResponses &&
|
other.saveResponses == saveResponses &&
|
||||||
other.promptBeforeClosing == promptBeforeClosing &&
|
other.promptBeforeClosing == promptBeforeClosing &&
|
||||||
other.activeEnvironmentId == activeEnvironmentId;
|
other.activeEnvironmentId == activeEnvironmentId &&
|
||||||
|
other.historyRetentionPeriod == historyRetentionPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -145,6 +165,7 @@ class SettingsModel {
|
|||||||
saveResponses,
|
saveResponses,
|
||||||
promptBeforeClosing,
|
promptBeforeClosing,
|
||||||
activeEnvironmentId,
|
activeEnvironmentId,
|
||||||
|
historyRetentionPeriod,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ class ThemeStateNotifier extends StateNotifier<SettingsModel> {
|
|||||||
bool? saveResponses,
|
bool? saveResponses,
|
||||||
bool? promptBeforeClosing,
|
bool? promptBeforeClosing,
|
||||||
String? activeEnvironmentId,
|
String? activeEnvironmentId,
|
||||||
|
HistoryRetentionPeriod? historyRetentionPeriod,
|
||||||
}) async {
|
}) async {
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
isDark: isDark,
|
isDark: isDark,
|
||||||
@ -41,6 +42,7 @@ class ThemeStateNotifier extends StateNotifier<SettingsModel> {
|
|||||||
saveResponses: saveResponses,
|
saveResponses: saveResponses,
|
||||||
promptBeforeClosing: promptBeforeClosing,
|
promptBeforeClosing: promptBeforeClosing,
|
||||||
activeEnvironmentId: activeEnvironmentId,
|
activeEnvironmentId: activeEnvironmentId,
|
||||||
|
historyRetentionPeriod: historyRetentionPeriod,
|
||||||
);
|
);
|
||||||
await hiveHandler.saveSettings(state.toJson());
|
await hiveHandler.saveSettings(state.toJson());
|
||||||
}
|
}
|
||||||
|
@ -190,8 +190,8 @@ class EnvironmentItem extends ConsumerWidget {
|
|||||||
ref.read(activeEnvironmentIdStateProvider.notifier).state = id;
|
ref.read(activeEnvironmentIdStateProvider.notifier).state = id;
|
||||||
},
|
},
|
||||||
onTap: () {
|
onTap: () {
|
||||||
ref.read(mobileScaffoldKeyStateProvider).currentState?.closeDrawer();
|
|
||||||
ref.read(selectedEnvironmentIdStateProvider.notifier).state = id;
|
ref.read(selectedEnvironmentIdStateProvider.notifier).state = id;
|
||||||
|
ref.read(mobileScaffoldKeyStateProvider).currentState?.closeDrawer();
|
||||||
},
|
},
|
||||||
focusNode: ref.watch(nameTextFieldFocusNodeProvider),
|
focusNode: ref.watch(nameTextFieldFocusNodeProvider),
|
||||||
onChangedNameEditor: (value) {
|
onChangedNameEditor: (value) {
|
||||||
|
@ -150,6 +150,10 @@ class _HistoryExpansionTileState extends ConsumerState<HistoryExpansionTile>
|
|||||||
ref
|
ref
|
||||||
.read(historyMetaStateNotifier.notifier)
|
.read(historyMetaStateNotifier.notifier)
|
||||||
.loadHistoryRequest(item.first.historyId);
|
.loadHistoryRequest(item.first.historyId);
|
||||||
|
ref
|
||||||
|
.read(mobileScaffoldKeyStateProvider)
|
||||||
|
.currentState
|
||||||
|
?.closeDrawer();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -82,7 +82,7 @@ class HistorySheetButton extends StatelessWidget {
|
|||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
constraints: const BoxConstraints(maxWidth: 500),
|
constraints: const BoxConstraints(maxWidth: 400),
|
||||||
child: const HistorRequestsScrollableSheet());
|
child: const HistorRequestsScrollableSheet());
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:apidash/extensions/extensions.dart';
|
import 'package:apidash/extensions/extensions.dart';
|
||||||
import 'package:apidash/providers/providers.dart';
|
import 'package:apidash/providers/providers.dart';
|
||||||
|
import 'package:apidash/widgets/widgets.dart';
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
class HistorySidebarHeader extends ConsumerWidget {
|
class HistorySidebarHeader extends ConsumerWidget {
|
||||||
@ -21,13 +22,22 @@ class HistorySidebarHeader extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: "Auto Delete Settings",
|
tooltip: "Manage History",
|
||||||
style: IconButton.styleFrom(
|
style: IconButton.styleFrom(
|
||||||
foregroundColor: Theme.of(context).colorScheme.primary,
|
foregroundColor: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
onPressed: () {},
|
onPressed: () {
|
||||||
|
showHistoryRetentionDialog(
|
||||||
|
context,
|
||||||
|
ref.read(settingsProvider.select(
|
||||||
|
(value) => value.historyRetentionPeriod)), (value) {
|
||||||
|
ref.read(settingsProvider.notifier).update(
|
||||||
|
historyRetentionPeriod: value,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.auto_delete_outlined,
|
Icons.manage_history_rounded,
|
||||||
size: 20,
|
size: 20,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -220,8 +220,8 @@ class RequestItem extends ConsumerWidget {
|
|||||||
selectedId: selectedId,
|
selectedId: selectedId,
|
||||||
editRequestId: editRequestId,
|
editRequestId: editRequestId,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
ref.read(mobileScaffoldKeyStateProvider).currentState?.closeDrawer();
|
|
||||||
ref.read(selectedIdStateProvider.notifier).state = id;
|
ref.read(selectedIdStateProvider.notifier).state = id;
|
||||||
|
ref.read(mobileScaffoldKeyStateProvider).currentState?.closeDrawer();
|
||||||
},
|
},
|
||||||
// onDoubleTap: () {
|
// onDoubleTap: () {
|
||||||
// ref.read(selectedIdStateProvider.notifier).state = id;
|
// ref.read(selectedIdStateProvider.notifier).state = id;
|
||||||
|
85
lib/widgets/dialog_history_retention.dart
Normal file
85
lib/widgets/dialog_history_retention.dart
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
|
showHistoryRetentionDialog(
|
||||||
|
BuildContext context,
|
||||||
|
HistoryRetentionPeriod historyRetentionPeriod,
|
||||||
|
Function(HistoryRetentionPeriod) onRetentionPeriodChange,
|
||||||
|
) {
|
||||||
|
HistoryRetentionPeriod selectedRetentionPeriod = historyRetentionPeriod;
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return AlertDialog(
|
||||||
|
icon: const Icon(Icons.manage_history_rounded),
|
||||||
|
iconColor: Theme.of(context).colorScheme.primary,
|
||||||
|
title: const Text("Manage History"),
|
||||||
|
titleTextStyle: Theme.of(context).textTheme.titleLarge,
|
||||||
|
contentPadding: kPv20,
|
||||||
|
content: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(maxWidth: 320),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: kPh24,
|
||||||
|
child: Text(
|
||||||
|
"Select the duration for which you want to retain your request history",
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onSurface
|
||||||
|
.withOpacity(0.8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
kVSpacer10,
|
||||||
|
...HistoryRetentionPeriod.values
|
||||||
|
.map((e) => RadioListTile<HistoryRetentionPeriod>(
|
||||||
|
title: Text(
|
||||||
|
e.label,
|
||||||
|
style: TextStyle(
|
||||||
|
color: selectedRetentionPeriod == e
|
||||||
|
? Theme.of(context).colorScheme.primary
|
||||||
|
: null),
|
||||||
|
),
|
||||||
|
secondary: Icon(e.icon,
|
||||||
|
color: selectedRetentionPeriod == e
|
||||||
|
? Theme.of(context).colorScheme.primary
|
||||||
|
: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onSurface
|
||||||
|
.withOpacity(0.6)),
|
||||||
|
value: e,
|
||||||
|
groupValue: selectedRetentionPeriod,
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
selectedRetentionPeriod = value;
|
||||||
|
(context as Element).markNeedsBuild();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
child: const Text('Confirm'),
|
||||||
|
onPressed: () {
|
||||||
|
onRetentionPeriodChange(selectedRetentionPeriod);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
@ -52,6 +52,10 @@ class _RequestPaneState extends State<RequestPane>
|
|||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
FilledButton.tonalIcon(
|
FilledButton.tonalIcon(
|
||||||
|
style: FilledButton.styleFrom(
|
||||||
|
padding: kPh12,
|
||||||
|
minimumSize: const Size(44, 44),
|
||||||
|
),
|
||||||
onPressed: widget.onPressedCodeButton,
|
onPressed: widget.onPressedCodeButton,
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
widget.codePaneVisible
|
widget.codePaneVisible
|
||||||
|
@ -15,6 +15,7 @@ export 'checkbox.dart';
|
|||||||
export 'code_previewer.dart';
|
export 'code_previewer.dart';
|
||||||
export 'codegen_previewer.dart';
|
export 'codegen_previewer.dart';
|
||||||
export 'dialog_about.dart';
|
export 'dialog_about.dart';
|
||||||
|
export 'dialog_history_retention.dart';
|
||||||
export 'dialog_import.dart';
|
export 'dialog_import.dart';
|
||||||
export 'dialog_rename.dart';
|
export 'dialog_rename.dart';
|
||||||
export 'drag_and_drop_area.dart';
|
export 'drag_and_drop_area.dart';
|
||||||
|
Reference in New Issue
Block a user