added edit location
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
This commit is contained in:
parent
96827c007d
commit
1164b99e2b
@ -74,10 +74,7 @@ private:
|
|||||||
[[nodiscard]] auto data_directory_exists(provider_type prov,
|
[[nodiscard]] auto data_directory_exists(provider_type prov,
|
||||||
std::string_view name) const -> bool;
|
std::string_view name) const -> bool;
|
||||||
|
|
||||||
void handle_delete_mount_location(const httplib::Request &req,
|
static void handle_get_available_locations(httplib::Response &res);
|
||||||
httplib::Response &res) const;
|
|
||||||
|
|
||||||
void handle_get_available_locations(httplib::Response &res) const;
|
|
||||||
|
|
||||||
void handle_get_mount(const httplib::Request &req,
|
void handle_get_mount(const httplib::Request &req,
|
||||||
httplib::Response &res) const;
|
httplib::Response &res) const;
|
||||||
@ -99,6 +96,9 @@ private:
|
|||||||
|
|
||||||
void handle_post_mount(const httplib::Request &req, httplib::Response &res);
|
void handle_post_mount(const httplib::Request &req, httplib::Response &res);
|
||||||
|
|
||||||
|
void handle_put_mount_location(const httplib::Request &req,
|
||||||
|
httplib::Response &res) const;
|
||||||
|
|
||||||
void handle_put_set_value_by_name(const httplib::Request &req,
|
void handle_put_set_value_by_name(const httplib::Request &req,
|
||||||
httplib::Response &res) const;
|
httplib::Response &res) const;
|
||||||
|
|
||||||
|
@ -168,10 +168,6 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server)
|
|||||||
: http_error_codes::internal_error;
|
: http_error_codes::internal_error;
|
||||||
});
|
});
|
||||||
|
|
||||||
server->Delete("/api/v1/mount_location", [this](auto &&req, auto &&res) {
|
|
||||||
handle_delete_mount_location(req, res);
|
|
||||||
});
|
|
||||||
|
|
||||||
server->Get("/api/v1/locations", [this](auto && /* req */, auto &&res) {
|
server->Get("/api/v1/locations", [this](auto && /* req */, auto &&res) {
|
||||||
handle_get_available_locations(res);
|
handle_get_available_locations(res);
|
||||||
});
|
});
|
||||||
@ -205,6 +201,10 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server)
|
|||||||
server->Post("/api/v1/mount",
|
server->Post("/api/v1/mount",
|
||||||
[this](auto &&req, auto &&res) { handle_post_mount(req, res); });
|
[this](auto &&req, auto &&res) { handle_post_mount(req, res); });
|
||||||
|
|
||||||
|
server->Put("/api/v1/mount_location", [this](auto &&req, auto &&res) {
|
||||||
|
handle_put_mount_location(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
server->Put("/api/v1/set_value_by_name", [this](auto &&req, auto &&res) {
|
server->Put("/api/v1/set_value_by_name", [this](auto &&req, auto &&res) {
|
||||||
handle_put_set_value_by_name(req, res);
|
handle_put_set_value_by_name(req, res);
|
||||||
});
|
});
|
||||||
@ -302,23 +302,24 @@ auto handlers::data_directory_exists(provider_type prov,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlers::handle_delete_mount_location(const httplib::Request &req,
|
void handlers::handle_put_mount_location(const httplib::Request &req,
|
||||||
httplib::Response &res) const {
|
httplib::Response &res) const {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
auto prov = provider_type_from_string(req.get_param_value("type"));
|
auto prov = provider_type_from_string(req.get_param_value("type"));
|
||||||
auto name = req.get_param_value("name");
|
auto name = req.get_param_value("name");
|
||||||
|
auto location = req.get_param_value("location");
|
||||||
|
|
||||||
if (not data_directory_exists(prov, name)) {
|
if (not data_directory_exists(prov, name)) {
|
||||||
res.status = http_error_codes::not_found;
|
res.status = http_error_codes::not_found;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
config_->set_mount_location(prov, name, "");
|
config_->set_mount_location(prov, name, location);
|
||||||
res.status = http_error_codes::ok;
|
res.status = http_error_codes::ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlers::handle_get_available_locations(httplib::Response &res) const {
|
void handlers::handle_get_available_locations(httplib::Response &res) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
constexpr const std::array<std::string_view, 26U> letters{
|
constexpr const std::array<std::string_view, 26U> letters{
|
||||||
"A:", "B:", "C:", "D:", "E:", "F:", "G:", "H:", "I:",
|
"A:", "B:", "C:", "D:", "E:", "F:", "G:", "H:", "I:",
|
||||||
|
@ -329,3 +329,67 @@ Map<String, dynamic> getChanged(
|
|||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String?> editMountLocation(
|
||||||
|
context,
|
||||||
|
List<String> available, {
|
||||||
|
bool allowEmpty = false,
|
||||||
|
String? location,
|
||||||
|
}) async {
|
||||||
|
String? currentLocation = location;
|
||||||
|
final controller = TextEditingController(text: currentLocation);
|
||||||
|
return await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return StatefulBuilder(
|
||||||
|
builder: (context, setState) {
|
||||||
|
return AlertDialog(
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
onPressed: () => Navigator.of(context).pop(null),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
child: const Text('OK'),
|
||||||
|
onPressed: () {
|
||||||
|
final result = getSettingValidators('Path').firstWhereOrNull(
|
||||||
|
(validator) => !validator(currentLocation ?? ''),
|
||||||
|
);
|
||||||
|
if (result != null) {
|
||||||
|
return displayErrorMessage(
|
||||||
|
context,
|
||||||
|
"Mount location is not valid",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Navigator.of(context).pop(currentLocation);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
content:
|
||||||
|
available.isEmpty
|
||||||
|
? TextField(
|
||||||
|
autofocus: true,
|
||||||
|
controller: controller,
|
||||||
|
onChanged:
|
||||||
|
(value) => setState(() => currentLocation = value),
|
||||||
|
)
|
||||||
|
: DropdownButton<String>(
|
||||||
|
hint: const Text("Select drive"),
|
||||||
|
value: currentLocation,
|
||||||
|
onChanged:
|
||||||
|
(value) => setState(() => currentLocation = value),
|
||||||
|
items:
|
||||||
|
available.map<DropdownMenuItem<String>>((item) {
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: item,
|
||||||
|
child: Text(item),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
title: const Text('Set Mount Location'),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -101,15 +101,15 @@ class Mount with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> clearMountLocation() async {
|
Future<void> setMountLocation(String location) async {
|
||||||
try {
|
try {
|
||||||
mountConfig.path = "";
|
mountConfig.path = location;
|
||||||
|
|
||||||
final auth = await _auth.createAuth();
|
final auth = await _auth.createAuth();
|
||||||
final response = await http.delete(
|
final response = await http.put(
|
||||||
Uri.parse(
|
Uri.parse(
|
||||||
Uri.encodeFull(
|
Uri.encodeFull(
|
||||||
'${getBaseUri()}/api/v1/mount_location?auth=$auth&name=$name&type=$type',
|
'${getBaseUri()}/api/v1/mount_location?auth=$auth&name=$name&type=$type&location=$location',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -17,6 +17,7 @@ class MountWidget extends StatefulWidget {
|
|||||||
|
|
||||||
class _MountWidgetState extends State<MountWidget> {
|
class _MountWidgetState extends State<MountWidget> {
|
||||||
bool _enabled = true;
|
bool _enabled = true;
|
||||||
|
bool _editEnabled = true;
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -66,14 +67,26 @@ class _MountWidgetState extends State<MountWidget> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (mount.path.isNotEmpty &&
|
if (mount.mounted != null && !mount.mounted!)
|
||||||
mount.mounted != null &&
|
|
||||||
!mount.mounted!)
|
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.remove),
|
icon: const Icon(Icons.edit),
|
||||||
color: subTextColor,
|
color: subTextColor,
|
||||||
onPressed: () => mount.clearMountLocation(),
|
tooltip: 'Edit location',
|
||||||
tooltip: 'Clear Mount Location',
|
onPressed: () async {
|
||||||
|
setState(() => _editEnabled = false);
|
||||||
|
final available = await mount.getAvailableLocations();
|
||||||
|
if (context.mounted) {
|
||||||
|
final location = await editMountLocation(
|
||||||
|
context,
|
||||||
|
available,
|
||||||
|
location: mount.path,
|
||||||
|
);
|
||||||
|
if (location != null) {
|
||||||
|
await mount.setMountLocation(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setState(() => _editEnabled = true);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
@ -87,6 +100,12 @@ class _MountWidgetState extends State<MountWidget> {
|
|||||||
? Color.fromARGB(255, 163, 96, 76)
|
? Color.fromARGB(255, 163, 96, 76)
|
||||||
: subTextColor,
|
: subTextColor,
|
||||||
),
|
),
|
||||||
|
tooltip:
|
||||||
|
mount.mounted == null
|
||||||
|
? ''
|
||||||
|
: mount.mounted!
|
||||||
|
? 'Unmount'
|
||||||
|
: 'Mount',
|
||||||
onPressed: _createMountHandler(context, mount),
|
onPressed: _createMountHandler(context, mount),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -165,70 +184,7 @@ class _MountWidgetState extends State<MountWidget> {
|
|||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
final available = await mount.getAvailableLocations();
|
return editMountLocation(context, await mount.getAvailableLocations());
|
||||||
|
|
||||||
String? currentLocation;
|
|
||||||
return await showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) {
|
|
||||||
return StatefulBuilder(
|
|
||||||
builder: (context, setState) {
|
|
||||||
return AlertDialog(
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
child: const Text('Cancel'),
|
|
||||||
onPressed: () => Navigator.of(context).pop(null),
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
child: const Text('OK'),
|
|
||||||
onPressed: () {
|
|
||||||
final result = getSettingValidators(
|
|
||||||
'Path',
|
|
||||||
).firstWhereOrNull(
|
|
||||||
(validator) => !validator(currentLocation ?? ''),
|
|
||||||
);
|
|
||||||
if (result != null) {
|
|
||||||
return displayErrorMessage(
|
|
||||||
context,
|
|
||||||
"Mount location is not valid",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Navigator.of(context).pop(currentLocation);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
content:
|
|
||||||
available.isEmpty
|
|
||||||
? TextField(
|
|
||||||
autofocus: true,
|
|
||||||
controller: TextEditingController(
|
|
||||||
text: currentLocation,
|
|
||||||
),
|
|
||||||
inputFormatters: [
|
|
||||||
FilteringTextInputFormatter.deny(RegExp(r'\s')),
|
|
||||||
],
|
|
||||||
onChanged:
|
|
||||||
(value) => setState(() => currentLocation = value),
|
|
||||||
)
|
|
||||||
: DropdownButton<String>(
|
|
||||||
hint: const Text("Select drive"),
|
|
||||||
value: currentLocation,
|
|
||||||
onChanged:
|
|
||||||
(value) => setState(() => currentLocation = value),
|
|
||||||
items:
|
|
||||||
available.map<DropdownMenuItem<String>>((item) {
|
|
||||||
return DropdownMenuItem<String>(
|
|
||||||
value: item,
|
|
||||||
child: Text(item),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
),
|
|
||||||
title: const Text('Set Mount Location'),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user