Create management portal in Flutter #39

This commit is contained in:
Scott E. Graves 2025-03-04 13:32:15 -06:00
parent 820617b3ff
commit badd098fe0
4 changed files with 97 additions and 59 deletions

View File

@ -1,6 +0,0 @@
class DuplicateMountException implements Exception {
final String _name;
const DuplicateMountException({required name}) : _name = name, super();
String get name => _name;
}

View File

@ -73,6 +73,10 @@ class MyHomePage extends StatefulWidget {
}
class _MyHomePageState extends State<MyHomePage> {
bool _allowAdd = true;
String _mountType = "S3";
String _mountName = "";
@override
Widget build(BuildContext context) {
return Scaffold(
@ -86,40 +90,74 @@ class _MyHomePageState extends State<MyHomePage> {
child: MountListWidget(),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Add Mount'),
content: Consumer<MountList>(
builder: (_, mountList, __) {
return AddMountWidget(
allowEncrypt:
!mountList.items.contains(
(item) => item.type == "encrypt",
onPressed:
_allowAdd
? () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Add Mount'),
content: Consumer<MountList>(
builder: (_, mountList, __) {
return AddMountWidget(
allowEncrypt:
!mountList.items.contains(
(item) => item.type == "encrypt",
),
mountName: _mountName,
mountType: _mountType,
onNameChanged:
(mountName) => setState(
() => _mountName = mountName ?? "",
),
onTypeChanged:
(mountType) => setState(
() => _mountType = mountType ?? "S3",
),
);
},
),
actions: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
setState(() {
_mountType = "S3";
_mountName = "";
});
Navigator.of(context).pop();
},
),
);
},
),
actions: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
TextButton(
child: const Text('OK'),
onPressed: () {
setState(() => _allowAdd = false);
Provider.of<MountList>(context, listen: false)
.add(_mountType, _mountName)
.then((_) {
setState(() {
_allowAdd = true;
_mountType = "S3";
_mountName = "";
});
})
.catchError((_) {
setState(() {
_allowAdd = true;
});
});
Navigator.of(context).pop();
},
),
],
);
},
),
TextButton(
child: const Text('Add'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
},
);
}
: null,
tooltip: 'Add Mount',
child: const Icon(Icons.add),
),

View File

@ -3,7 +3,6 @@ import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:repertory/errors/duplicate_mount_exception.dart';
import 'package:repertory/types/mount_config.dart';
class MountList with ChangeNotifier {
@ -47,16 +46,14 @@ class MountList with ChangeNotifier {
});
}
void add(MountConfig config) {
var item = _mountList.firstWhereOrNull((cfg) => cfg.name == config.name);
if (item != null) {
throw DuplicateMountException(name: config.name);
}
Future<void> add(String type, String name) async {
await http.post(
Uri.parse(
Uri.encodeFull('${Uri.base.origin}/api/v1/mount?name=$name&type=$type'),
),
);
_mountList.add(config);
_sort(_mountList);
notifyListeners();
return _fetch();
}
void remove(String name) {

View File

@ -1,18 +1,24 @@
import 'package:flutter/material.dart';
class AddMountWidget extends StatefulWidget {
class AddMountWidget extends StatelessWidget {
final bool allowEncrypt;
const AddMountWidget({super.key, required this.allowEncrypt});
final String mountName;
final String mountType;
final void Function(String? newName) onNameChanged;
final void Function(String? newType) onTypeChanged;
const AddMountWidget({
super.key,
required this.allowEncrypt,
required this.mountName,
required this.mountType,
required this.onNameChanged,
required this.onTypeChanged,
});
@override
State<AddMountWidget> createState() => _AddMountWidgetState();
}
class _AddMountWidgetState extends State<AddMountWidget> {
@override
Widget build(BuildContext context) {
var items = ["S3", "Sia"];
if (widget.allowEncrypt) {
if (allowEncrypt) {
items.insert(0, "Encrypt");
}
@ -20,14 +26,17 @@ class _AddMountWidgetState extends State<AddMountWidget> {
mainAxisSize: MainAxisSize.min,
children: [
DropdownButton<String>(
value: "S3",
onChanged: (newValue) {},
value: mountType,
onChanged: onTypeChanged,
items:
items.map<DropdownMenuItem<String>>((item) {
return DropdownMenuItem<String>(value: item, child: Text(item));
}).toList(),
),
TextField(decoration: InputDecoration(labelText: 'Name')),
TextField(
decoration: InputDecoration(labelText: 'Name'),
onChanged: onNameChanged,
),
],
);
}