mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-16 13:49:58 +00:00
Merge branch 'refs/heads/ui-refactor' into ui-refactor-ui
# Conflicts: # client/ui/frontend/src/screens/Profiles.tsx # client/ui/main.go
This commit is contained in:
@@ -6,6 +6,7 @@ import * as Debug from "./debug.js";
|
||||
import * as Forwarding from "./forwarding.js";
|
||||
import * as Networks from "./networks.js";
|
||||
import * as Peers from "./peers.js";
|
||||
import * as ProfileSwitcher from "./profileswitcher.js";
|
||||
import * as Profiles from "./profiles.js";
|
||||
import * as Settings from "./settings.js";
|
||||
import * as Update from "./update.js";
|
||||
@@ -16,6 +17,7 @@ export {
|
||||
Forwarding,
|
||||
Networks,
|
||||
Peers,
|
||||
ProfileSwitcher,
|
||||
Profiles,
|
||||
Settings,
|
||||
Update,
|
||||
|
||||
@@ -755,6 +755,18 @@ export class Profile {
|
||||
"name": string;
|
||||
"isActive": boolean;
|
||||
|
||||
/**
|
||||
* Email is the account address associated with this profile, sourced from
|
||||
* the per-profile state file written by the CLI after a successful SSO
|
||||
* login (e.g. ~/Library/Application Support/netbird/default.state.json on
|
||||
* macOS). The daemon always runs as root, so its getConfigDir() resolves to
|
||||
* the root home directory and cannot reach the user-owned state file. The
|
||||
* UI process runs as the logged-in user and can read it directly via
|
||||
* profilemanager.ProfileManager, which is why the email is fetched here
|
||||
* instead of being returned by the ListProfiles RPC.
|
||||
*/
|
||||
"email": string;
|
||||
|
||||
/** Creates a new Profile instance. */
|
||||
constructor($$source: Partial<Profile> = {}) {
|
||||
if (!("name" in $$source)) {
|
||||
@@ -763,6 +775,9 @@ export class Profile {
|
||||
if (!("isActive" in $$source)) {
|
||||
this["isActive"] = false;
|
||||
}
|
||||
if (!("email" in $$source)) {
|
||||
this["email"] = "";
|
||||
}
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
/**
|
||||
* ProfileSwitcher encapsulates the full profile-switching reconnect policy so
|
||||
* both the tray and the React frontend use identical logic.
|
||||
*
|
||||
* Reconnect policy:
|
||||
*
|
||||
* ┌─────────────────┬──────────────────────┬────────────────────────────────────┐
|
||||
* │ Previous status │ Action │ Rationale │
|
||||
* ├─────────────────┼──────────────────────┼────────────────────────────────────┤
|
||||
* │ Connected │ Switch + Down + Up │ Reconnect with the new profile. │
|
||||
* │ Connecting │ Switch + Down + Up │ Stop old retry loop, restart. │
|
||||
* │ NeedsLogin │ Switch + Down │ Clear stale error; user logs in. │
|
||||
* │ LoginFailed │ Switch + Down │ Clear stale error; user logs in. │
|
||||
* │ SessionExpired │ Switch + Down │ Clear stale error; user logs in. │
|
||||
* │ Idle │ Switch only │ User chose offline; don't connect. │
|
||||
* └─────────────────┴──────────────────────┴────────────────────────────────────┘
|
||||
* @module
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import { Call as $Call, CancellablePromise as $CancellablePromise, Create as $Create } from "@wailsio/runtime";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as $models from "./models.js";
|
||||
|
||||
/**
|
||||
* SwitchActive switches to the named profile applying the reconnect policy.
|
||||
* All RPCs complete quickly: Up uses async mode so the daemon starts the
|
||||
* connection attempt and returns immediately; status updates flow via the
|
||||
* SubscribeStatus stream.
|
||||
*/
|
||||
export function SwitchActive(p: $models.ProfileRef): $CancellablePromise<void> {
|
||||
return $Call.ByID(4025913103, p);
|
||||
}
|
||||
@@ -3,23 +3,24 @@ import { Plus, RefreshCw } from "lucide-react";
|
||||
import {
|
||||
Profiles as ProfilesSvc,
|
||||
Connection,
|
||||
} from "@bindings/services";
|
||||
import type { Profile } from "@bindings/services/models.js";
|
||||
ProfileSwitcher,
|
||||
} from "../../bindings/github.com/netbirdio/netbird/client/ui/services";
|
||||
import type { Profile } from "../../bindings/github.com/netbirdio/netbird/client/ui/services/models.js";
|
||||
import { Button } from "../components/Button";
|
||||
import { Input } from "../components/Input";
|
||||
import { Card } from "../components/Card";
|
||||
import { useProfile } from "@/modules/profile/ProfileContext.tsx";
|
||||
|
||||
export default function Profiles() {
|
||||
const { username, loaded, refresh: refreshProfile, switchProfile } = useProfile();
|
||||
const [username, setUsername] = useState("");
|
||||
const [profiles, setProfiles] = useState<Profile[]>([]);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [adding, setAdding] = useState(false);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!username) return;
|
||||
try {
|
||||
const list = await ProfilesSvc.List(username);
|
||||
const u = username || (await ProfilesSvc.Username());
|
||||
if (!username) setUsername(u);
|
||||
const list = await ProfilesSvc.List(u);
|
||||
setProfiles(list);
|
||||
setError(null);
|
||||
} catch (e) {
|
||||
@@ -28,13 +29,12 @@ export default function Profiles() {
|
||||
}, [username]);
|
||||
|
||||
useEffect(() => {
|
||||
if (loaded) refresh();
|
||||
}, [loaded, refresh]);
|
||||
refresh();
|
||||
}, [refresh]);
|
||||
|
||||
const select = async (name: string) => {
|
||||
try {
|
||||
await switchProfile(name);
|
||||
await Connection.Up({ profileName: name, username });
|
||||
await ProfileSwitcher.SwitchActive({ profileName: name, username });
|
||||
await refresh();
|
||||
} catch (e) {
|
||||
setError(String(e));
|
||||
@@ -54,7 +54,6 @@ export default function Profiles() {
|
||||
if (name === "default") return;
|
||||
try {
|
||||
await ProfilesSvc.Remove({ profileName: name, username });
|
||||
await refreshProfile();
|
||||
await refresh();
|
||||
} catch (e) {
|
||||
setError(String(e));
|
||||
|
||||
Reference in New Issue
Block a user