diff --git a/src/components/account-page.tsx b/src/components/account-page.tsx index 43e1b78..7f93138 100644 --- a/src/components/account-page.tsx +++ b/src/components/account-page.tsx @@ -198,11 +198,11 @@ export function AccountPage({ return ( - +
diff --git a/src/components/extension-management-dialog.tsx b/src/components/extension-management-dialog.tsx index 35cfa5d..133432f 100644 --- a/src/components/extension-management-dialog.tsx +++ b/src/components/extension-management-dialog.tsx @@ -1101,7 +1101,7 @@ export function ExtensionManagementDialog({ return ( <> - + {!subPage && ( diff --git a/src/components/group-management-dialog.tsx b/src/components/group-management-dialog.tsx index 9dd0f99..a8a9625 100644 --- a/src/components/group-management-dialog.tsx +++ b/src/components/group-management-dialog.tsx @@ -557,7 +557,7 @@ export function GroupManagementDialog({ return ( <> - + {!subPage && ( {t("groups.management")} @@ -567,15 +567,13 @@ export function GroupManagementDialog({ )} -
-
-
-

- {t("groups.pageTitle")} -

-

- {t("groups.pageDescription")} -

+
+
+
+ {t("groups.pageTitle")} + + {groups.length} +
- {t("proxies.management.create")} + + {t("proxies.management.create")} +
{error && ( -
+
{error}
)} {/* Groups list */} {isLoading ? ( -
+
{t("common.buttons.loading")}
) : groups.length === 0 ? ( -
+
{t("groups.noGroupsDescription")}
) : ( 0 && "pb-16", )} style={ diff --git a/src/components/profile-data-table.tsx b/src/components/profile-data-table.tsx index 2d3920d..8c757fd 100644 --- a/src/components/profile-data-table.tsx +++ b/src/components/profile-data-table.tsx @@ -1665,6 +1665,30 @@ export function ProfilesDataTable({ }; }, [browserState.isClient, loadAllTags]); + // A running browser keeps the name it launched with, so close any inline + // rename that was open when the profile entered a runtime transition. + React.useEffect(() => { + if (!profileToRename) return; + + const profileId = profileToRename.id; + const isRuntimeLocked = + (browserState.isClient && runningProfiles.has(profileId)) || + launchingProfiles.has(profileId) || + stoppingProfiles.has(profileId); + + if (isRuntimeLocked) { + setProfileToRename(null); + setNewProfileName(""); + setRenameError(null); + } + }, [ + profileToRename, + runningProfiles, + launchingProfiles, + stoppingProfiles, + browserState.isClient, + ]); + // Automatically deselect profiles that become running, updating, launching, or stopping React.useEffect(() => { const newSet = new Set(selectedProfiles); @@ -2479,7 +2503,15 @@ export function ProfilesDataTable({ const profile = row.original as BrowserProfile; const rawName: string = row.getValue("name"); const name = getBrowserDisplayName(rawName); - const isEditing = meta.profileToRename?.id === profile.id; + const isRuntimeLocked = + (meta.isClient && meta.runningProfiles.has(profile.id)) || + meta.launchingProfiles.has(profile.id) || + meta.stoppingProfiles.has(profile.id); + const isCrossOsBlocked = isCrossOsProfile(profile); + const isEditing = + meta.profileToRename?.id === profile.id && + !isRuntimeLocked && + !isCrossOsBlocked; if (isEditing) { return ( @@ -2530,45 +2562,44 @@ export function ProfilesDataTable({ /> ); - const isCrossOs = isCrossOsProfile(profile); - const isCrossOsBlocked = isCrossOs; - const isRunning = - meta.isClient && meta.runningProfiles.has(profile.id); - const isLaunching = meta.launchingProfiles.has(profile.id); - const isStopping = meta.stoppingProfiles.has(profile.id); - const isDisabled = - isRunning || isLaunching || isStopping || isCrossOsBlocked; const lockedEmail = meta.getProfileLockEmail(profile.id); const isLocked = meta.isProfileLockedByAnother(profile.id); - - return ( -
- + } + }} + > + {display} + + ); + + return ( +
+ {nameControl} {isLocked && ( @@ -2595,14 +2626,7 @@ export function ProfilesDataTable({ cell: ({ row, table }) => { const meta = table.options.meta as TableMeta; const profile = row.original; - const isCrossOs = isCrossOsProfile(profile); - const isCrossOsBlocked = isCrossOs; - const isRunning = - meta.isClient && meta.runningProfiles.has(profile.id); - const isLaunching = meta.launchingProfiles.has(profile.id); - const isStopping = meta.stoppingProfiles.has(profile.id); - const isDisabled = - isRunning || isLaunching || isStopping || isCrossOsBlocked; + const isDisabled = isCrossOsProfile(profile); return ( { const meta = table.options.meta as TableMeta; const profile = row.original; - const isCrossOs = isCrossOsProfile(profile); - const isCrossOsBlocked = isCrossOs; - const isRunning = - meta.isClient && meta.runningProfiles.has(profile.id); - const isLaunching = meta.launchingProfiles.has(profile.id); - const isStopping = meta.stoppingProfiles.has(profile.id); - const isDisabled = - isRunning || isLaunching || isStopping || isCrossOsBlocked; + const isDisabled = isCrossOsProfile(profile); return ( { @@ -120,7 +120,7 @@ function AnimatedTabsTrigger({ onMouseEnter?.(event); }} className={cn( - "relative isolate inline-flex h-7 cursor-pointer items-center justify-center gap-1.5 rounded-md px-3 text-sm font-medium whitespace-nowrap transition-colors duration-150", + "relative inline-flex h-7 cursor-pointer items-center justify-center gap-1.5 rounded-md px-3 text-sm font-medium whitespace-nowrap transition-colors duration-150", "text-muted-foreground hover:text-foreground", isActive && "text-foreground", "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background focus-visible:outline-none", @@ -132,7 +132,7 @@ function AnimatedTabsTrigger({ {showIndicator && ( )}