From cc4991e2111983a0fe26c485294de5a1b238f1ff Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 2 Mar 2025 17:43:11 -0600 Subject: [PATCH] added set value --- repertory/repertory/include/ui/handlers.hpp | 2 + repertory/repertory/src/ui/handlers.cpp | 16 +++ web/repertory/lib/main.dart | 8 +- web/repertory/lib/models/mount.dart | 12 ++ web/repertory/lib/widgets/mount_settings.dart | 113 +++++++++++------- web/repertory/lib/widgets/mount_widget.dart | 6 +- 6 files changed, 105 insertions(+), 52 deletions(-) diff --git a/repertory/repertory/include/ui/handlers.hpp b/repertory/repertory/include/ui/handlers.hpp index 3bfbc84c..b8cb1935 100644 --- a/repertory/repertory/include/ui/handlers.hpp +++ b/repertory/repertory/include/ui/handlers.hpp @@ -66,6 +66,8 @@ private: void handle_post_mount(auto &&req, auto &&res) const; + void handle_put_set_value_by_name(auto &&req, auto &&res); + static auto read_process(provider_type prov, std::string_view name, std::string_view command) -> std::vector; diff --git a/repertory/repertory/src/ui/handlers.cpp b/repertory/repertory/src/ui/handlers.cpp index 1f679026..d8173254 100644 --- a/repertory/repertory/src/ui/handlers.cpp +++ b/repertory/repertory/src/ui/handlers.cpp @@ -86,6 +86,10 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server) server->Post("/api/v1/mount", [this](auto &&req, auto &&res) { handle_post_mount(req, res); }); + server->Put("/api/v1/set_value_by_name", [this](auto &&req, auto &&res) { + handle_put_set_value_by_name(req, res); + }); + event_system::instance().start(); static std::atomic this_server{server_}; @@ -215,6 +219,18 @@ void handlers::handle_post_mount(auto &&req, auto &&res) const { res.status = http_error_codes::ok; } +void handlers::handle_put_set_value_by_name(auto &&req, auto &&res) { + auto type = req.get_param_value("type"); + auto name = req.get_param_value("name"); + auto prov = provider_type_from_string(type); + + auto key = req.get_param_value("key"); + auto value = req.get_param_value("value"); + + read_process(prov, name, fmt::format("-set {} \'{}\'", key, value)); + res.status = http_error_codes::ok; +} + auto handlers::read_process(provider_type prov, std::string_view name, std::string_view command) -> std::vector { diff --git a/web/repertory/lib/main.dart b/web/repertory/lib/main.dart index d13f9757..82519aa5 100644 --- a/web/repertory/lib/main.dart +++ b/web/repertory/lib/main.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:repertory/constants.dart' as constants; import 'package:repertory/helpers.dart'; +import 'package:repertory/models/mount.dart'; import 'package:repertory/models/mount_list.dart'; -import 'package:repertory/types/mount_config.dart'; import 'package:repertory/widgets/mount_list_widget.dart'; import 'package:repertory/widgets/mount_settings.dart'; @@ -40,17 +40,17 @@ class MyApp extends StatelessWidget { return null; } - final mountConfig = settings.arguments as MountConfig; + final mount = settings.arguments as Mount; return MaterialPageRoute( builder: (context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text( - '${initialCaps(mountConfig.type)} [${formatMountName(mountConfig.type, mountConfig.name)}] Settings', + '${initialCaps(mount.type)} [${formatMountName(mount.type, mount.name)}] Settings', ), ), - body: MountSettingsWidget(config: mountConfig), + body: MountSettingsWidget(mount: mount), ); }, ); diff --git a/web/repertory/lib/models/mount.dart b/web/repertory/lib/models/mount.dart index b2271f20..dbab2f62 100644 --- a/web/repertory/lib/models/mount.dart +++ b/web/repertory/lib/models/mount.dart @@ -64,4 +64,16 @@ class Mount with ChangeNotifier { await _fetch(); return _fetchStatus(); } + + Future setValue(String key, String value) async { + await http.put( + Uri.parse( + Uri.encodeFull( + '${Uri.base.origin}/api/v1/set_value_by_name?name=$name&type=$type&key=$key&value=$value', + ), + ), + ); + + return refresh(); + } } diff --git a/web/repertory/lib/widgets/mount_settings.dart b/web/repertory/lib/widgets/mount_settings.dart index 47f05c8a..8ad7e9bb 100644 --- a/web/repertory/lib/widgets/mount_settings.dart +++ b/web/repertory/lib/widgets/mount_settings.dart @@ -1,18 +1,21 @@ +import 'dart:convert'; + +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:repertory/types/mount_config.dart'; +import 'package:repertory/models/mount.dart'; import 'package:settings_ui/settings_ui.dart'; class MountSettingsWidget extends StatefulWidget { - final MountConfig config; - const MountSettingsWidget({super.key, required this.config}); + final Mount mount; + const MountSettingsWidget({super.key, required this.mount}); @override State createState() => _MountSettingsWidgetState(); } class _MountSettingsWidgetState extends State { - Map? _settings; + Map _settings = {}; void _addBooleanSetting(list, root, key, value) { list.add( @@ -22,12 +25,12 @@ class _MountSettingsWidgetState extends State { initialValue: (value as bool), onPressed: (_) { setState(() { - root?[key] = !value; + root[key] = !value; }); }, onToggle: (bool nextValue) { setState(() { - root?[key] = nextValue; + root[key] = nextValue; }); }, ), @@ -57,7 +60,7 @@ class _MountSettingsWidgetState extends State { child: Text('OK'), onPressed: () { setState(() { - root?[key] = int.parse(updatedValue); + root[key] = int.parse(updatedValue); }); Navigator.of(context).pop(); }, @@ -98,7 +101,7 @@ class _MountSettingsWidgetState extends State { value: value.toString(), onChanged: (newValue) { setState(() { - root?[key] = int.parse(newValue ?? defaultValue.toString()); + root[key] = int.parse(newValue ?? defaultValue.toString()); }); }, items: @@ -119,7 +122,7 @@ class _MountSettingsWidgetState extends State { value: value, onChanged: (newValue) { setState(() { - root?[key] = newValue; + root[key] = newValue; }); }, items: @@ -164,7 +167,7 @@ class _MountSettingsWidgetState extends State { child: Text('OK'), onPressed: () { setState(() { - root?[key] = updatedValue; + root[key] = updatedValue; }); Navigator.of(context).pop(); }, @@ -196,7 +199,7 @@ class _MountSettingsWidgetState extends State { List s3ConfigSettings = []; List siaConfigSettings = []; - _settings?.forEach((key, value) { + _settings.forEach((key, value) { if (key == "ApiAuth") { _addPasswordSetting(commonSettings, _settings, key, value); } else if (key == "ApiPort") { @@ -256,14 +259,14 @@ class _MountSettingsWidgetState extends State { if (subKey == "EncryptionToken") { _addPasswordSetting( encryptConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "Path") { _addStringSetting( encryptConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, Icons.folder, @@ -275,7 +278,7 @@ class _MountSettingsWidgetState extends State { if (subKey == "AgentString") { _addStringSetting( hostConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, Icons.support_agent, @@ -283,21 +286,21 @@ class _MountSettingsWidgetState extends State { } else if (subKey == "ApiPassword") { _addPasswordSetting( hostConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "ApiPort") { _addIntSetting( hostConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "ApiUser") { _addStringSetting( hostConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, Icons.person, @@ -305,7 +308,7 @@ class _MountSettingsWidgetState extends State { } else if (subKey == "HostNameOrIp") { _addStringSetting( hostConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, Icons.computer, @@ -313,7 +316,7 @@ class _MountSettingsWidgetState extends State { } else if (subKey == "Path") { _addStringSetting( hostConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, Icons.route, @@ -321,7 +324,7 @@ class _MountSettingsWidgetState extends State { } else if (subKey == "Protocol") { _addListSetting( hostConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ["http", "https"], @@ -330,7 +333,7 @@ class _MountSettingsWidgetState extends State { } else if (subKey == "TimeoutMs") { _addIntSetting( hostConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); @@ -341,21 +344,21 @@ class _MountSettingsWidgetState extends State { if (subKey == "ApiPort") { _addIntSetting( remoteConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "EncryptionToken") { _addPasswordSetting( remoteConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "HostNameOrIp") { _addStringSetting( remoteConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, Icons.computer, @@ -363,21 +366,21 @@ class _MountSettingsWidgetState extends State { } else if (subKey == "MaxConnections") { _addIntSetting( remoteConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "ReceiveTimeoutMs") { _addIntSetting( remoteConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "SendTimeoutMs") { _addIntSetting( remoteConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); @@ -387,26 +390,26 @@ class _MountSettingsWidgetState extends State { value.forEach((subKey, subValue) { if (subKey == "Enable") { List tempSettings = []; - _addBooleanSetting(tempSettings, _settings?[key], subKey, subValue); + _addBooleanSetting(tempSettings, _settings[key], subKey, subValue); remoteMountSettings.insertAll(0, tempSettings); } else if (subKey == "ApiPort") { _addIntSetting( remoteMountSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "ClientPoolSize") { _addIntSetting( remoteMountSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "EncryptionToken") { _addPasswordSetting( remoteMountSettings, - _settings?[key], + _settings[key], subKey, subValue, ); @@ -417,14 +420,14 @@ class _MountSettingsWidgetState extends State { if (subKey == "AccessKey") { _addPasswordSetting( s3ConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "Bucket") { _addStringSetting( s3ConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, Icons.folder, @@ -432,14 +435,14 @@ class _MountSettingsWidgetState extends State { } else if (subKey == "EncryptionToken") { _addPasswordSetting( s3ConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "Region") { _addStringSetting( s3ConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, Icons.map, @@ -447,16 +450,16 @@ class _MountSettingsWidgetState extends State { } else if (subKey == "SecretKey") { _addPasswordSetting( s3ConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "TimeoutMs") { - _addIntSetting(s3ConfigSettings, _settings?[key], subKey, subValue); + _addIntSetting(s3ConfigSettings, _settings[key], subKey, subValue); } else if (subKey == "URL") { _addStringSetting( s3ConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, Icons.http, @@ -464,14 +467,14 @@ class _MountSettingsWidgetState extends State { } else if (subKey == "UsePathStyle") { _addBooleanSetting( s3ConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); } else if (subKey == "UseRegionInURL") { _addBooleanSetting( s3ConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, ); @@ -482,7 +485,7 @@ class _MountSettingsWidgetState extends State { if (subKey == "Bucket") { _addStringSetting( siaConfigSettings, - _settings?[key], + _settings[key], subKey, subValue, Icons.folder, @@ -524,7 +527,7 @@ class _MountSettingsWidgetState extends State { SettingsSection( title: const Text('Remote Mount'), tiles: - _settings?["RemoteMount"]["Enable"] as bool + _settings["RemoteMount"]["Enable"] as bool ? remoteMountSettings : [remoteMountSettings[0]], ), @@ -533,9 +536,33 @@ class _MountSettingsWidgetState extends State { ); } + @override + void dispose() { + var settings = widget.mount.mountConfig.settings; + if (!DeepCollectionEquality().equals(_settings, settings)) { + _settings.forEach((key, value) { + if (!DeepCollectionEquality().equals(settings[key], value)) { + if (value is Map) { + value.forEach((subKey, subValue) { + if (!DeepCollectionEquality().equals( + settings[key][subKey], + subValue, + )) { + widget.mount.setValue('$key.$subKey', subValue.toString()); + } + }); + } else { + widget.mount.setValue(key, value.toString()); + } + } + }); + } + super.dispose(); + } + @override void initState() { - _settings = Map.from(widget.config.settings); + _settings = jsonDecode(jsonEncode(widget.mount.mountConfig.settings)); super.initState(); } } diff --git a/web/repertory/lib/widgets/mount_widget.dart b/web/repertory/lib/widgets/mount_widget.dart index 391d28a5..d50e11f4 100644 --- a/web/repertory/lib/widgets/mount_widget.dart +++ b/web/repertory/lib/widgets/mount_widget.dart @@ -38,11 +38,7 @@ class _MountWidgetState extends State { leading: IconButton( icon: Icon(Icons.settings, color: subTextColor), onPressed: () { - Navigator.pushNamed( - context, - '/settings', - arguments: mount.mountConfig, - ); + Navigator.pushNamed(context, '/settings', arguments: mount); }, ), subtitle: