import "package:sembast/sembast.dart"; import "package:inventree/helpers.dart"; import "package:inventree/preferences.dart"; class UserProfile { UserProfile({ this.key, this.name = "", this.server = "", this.token = "", this.selected = false, }); factory UserProfile.fromJson(int key, Map json, bool isSelected) => UserProfile( key: key, name: (json["name"] ?? "") as String, server: (json["server"] ?? "") as String, token: (json["token"] ?? "") as String, selected: isSelected, ); // Return true if this profile has a token bool get hasToken => token.isNotEmpty; // ID of the profile int? key; // Name of the user profile String name = ""; // Base address of the InvenTree server String server = ""; // API token String token = ""; bool selected = false; // User ID (will be provided by the server on log-in) int user_id = -1; Map toJson() => { "name": name, "server": server, "token": token, }; @override String toString() { return "<${key}> ${name} : ${server}"; } } /* * Class for storing and managing user (server) profiles */ class UserProfileDBManager { final store = StoreRef("profiles"); Future get _db async => InvenTreePreferencesDB.instance.database; /* * Check if a profile with the specified name exists in the database */ Future profileNameExists(String name) async { final profiles = await getAllProfiles(); for (var prf in profiles) { if (name == prf.name) { return true; } } // No match found! return false; } /* * Add a new UserProfile to the profiles database. */ Future addProfile(UserProfile profile) async { if (profile.name.isEmpty) { debug("addProfile() : Profile missing required values - not adding to database"); return false; } // Check if a profile already exists with the name final bool exists = await profileNameExists(profile.name); if (exists) { debug("addProfile() : UserProfile '${profile.name}' already exists"); return true; } else { debug("Adding new profile: '${profile.name}'"); } int? key = await store.add(await _db, profile.toJson()) as int?; // Record the key profile.key = key; return true; } /* * Update the selected profile in the database. * The unique integer is used to determine if the profile already exists. */ Future updateProfile(UserProfile profile) async { // Prevent invalid profile data from being updated if (profile.name.isEmpty) { debug("updateProfile() : Profile missing required values - not updating"); return false; } if (profile.key == null) { bool result = await addProfile(profile); return result; } await store.record(profile.key).update(await _db, profile.toJson()); return true; } /* * Remove a user profile from the database */ Future deleteProfile(UserProfile profile) async { debug("deleteProfile: ${profile.name}"); await store.record(profile.key).delete(await _db); } /* * Return the currently selected profile. * The key of the UserProfile should match the "selected" property */ Future getSelectedProfile() async { final selected = await store.record("selected").get(await _db); final profiles = await store.find(await _db); debug("getSelectedProfile() : ${profiles.length} profiles available - selected = ${selected}"); for (int idx = 0; idx < profiles.length; idx++) { if (profiles[idx].key is int && profiles[idx].key == selected) { return UserProfile.fromJson( profiles[idx].key! as int, profiles[idx].value! as Map, profiles[idx].key == selected, ); } } return null; } /* * Return all user profile objects */ Future> getAllProfiles() async { final selected = await store.record("selected").get(await _db); final profiles = await store.find(await _db); List profileList = []; for (int idx = 0; idx < profiles.length; idx++) { if (profiles[idx].key is int) { profileList.add( UserProfile.fromJson( profiles[idx].key! as int, profiles[idx].value! as Map, profiles[idx].key == selected, ) ); } } // If there are no available profiles, create a demo profile if (profileList.isEmpty) { bool added = await InvenTreeSettingsManager().getBool("demo_profile_added", false); // Don't add a new profile if we have added it previously if (!added) { await InvenTreeSettingsManager().setValue("demo_profile_added", true); UserProfile demoProfile = UserProfile( name: "InvenTree Demo", server: "https://demo.inventree.org", ); await addProfile(demoProfile); profileList.add(demoProfile); } } return profileList; } /* * Retrieve a profile by key (or null if no match exists) */ Future getProfileByKey(int key) async { final profiles = await getAllProfiles(); UserProfile? prf; for (UserProfile profile in profiles) { if (profile.key == key) { prf = profile; break; } } return prf; } /* * Retrieve a profile by name (or null if no match exists) */ Future getProfileByName(String name) async { final profiles = await getAllProfiles(); UserProfile? prf; for (UserProfile profile in profiles) { if (profile.name == name) { prf = profile; break; } } return prf; } /* * Mark the particular profile as selected */ Future selectProfile(int key) async { await store.record("selected").put(await _db, key); } /* * Look-up and select a profile by name. * Return true if the profile was selected */ Future selectProfileByName(String name) async { var profiles = await getAllProfiles(); for (var prf in profiles) { if (prf.name == name) { int key = prf.key ?? -1; if (key >= 0) { await selectProfile(key); return true; } } } return false; } }