Choose whose account a shared tool uses with a compact switch

The two large picker tiles become a small My account / Each member's own
switch; the line under it still says what the choice means.
This commit is contained in:
arc53-machine committed 2026-09-29 12:05:35 +01:00
1 parent 301a59ef51
commit e29ea53837
9 files changed
+54 -29

No files matched your search

+3 -1
View File
@@ -1316,7 +1316,9 @@
},
"sharing": {
"owner": "Teammitglieder nutzen mein Konto",
"member": "Jedes Mitglied verbindet sein eigenes Konto"
"member": "Jedes Mitglied verbindet sein eigenes Konto",
"ownerShort": "Mein Konto",
"memberShort": "Jeweils eigenes"
},
"share": {
"heading": "Welches Konto Teammitglieder nutzen",
+3 -1
View File
@@ -1322,7 +1322,9 @@
},
"sharing": {
"owner": "Team members use my account",
"member": "Each member connects their own account"
"member": "Each member connects their own account",
"ownerShort": "My account",
"memberShort": "Each member's own"
},
"share": {
"heading": "Whose account team members use",
+3 -1
View File
@@ -1316,7 +1316,9 @@
},
"sharing": {
"owner": "Los miembros usan mi cuenta",
"member": "Cada miembro conecta su propia cuenta"
"member": "Cada miembro conecta su propia cuenta",
"ownerShort": "Mi cuenta",
"memberShort": "La de cada miembro"
},
"share": {
"heading": "Qué cuenta usan los miembros del equipo",
+3 -1
View File
@@ -1298,7 +1298,9 @@
},
"sharing": {
"owner": "メンバーは自分のアカウントを使う",
"member": "各メンバーが自分のアカウントを接続する"
"member": "各メンバーが自分のアカウントを接続する",
"ownerShort": "自分のアカウント",
"memberShort": "各メンバーのもの"
},
"share": {
"heading": "チームメンバーが使うアカウント",
+3 -1
View File
@@ -1390,7 +1390,9 @@
},
"sharing": {
"owner": "Участники используют мой аккаунт",
"member": "Каждый участник подключает свой аккаунт"
"member": "Каждый участник подключает свой аккаунт",
"ownerShort": "Мой аккаунт",
"memberShort": "У каждого свой"
},
"share": {
"heading": "Чей аккаунт используют участники команды",
+3 -1
View File
@@ -1298,7 +1298,9 @@
},
"sharing": {
"owner": "團隊成員使用我的帳號",
"member": "每位成員連線自己的帳號"
"member": "每位成員連線自己的帳號",
"ownerShort": "我的帳號",
"memberShort": "各自的帳號"
},
"share": {
"heading": "團隊成員使用誰的帳號",
+3 -1
View File
@@ -1298,7 +1298,9 @@
},
"sharing": {
"owner": "团队成员使用我的账号",
"member": "每位成员连接自己的账号"
"member": "每位成员连接自己的账号",
"ownerShort": "我的账号",
"memberShort": "各自的账号"
},
"share": {
"heading": "团队成员使用谁的账号",
+6 -3
View File
@@ -79,13 +79,15 @@ describe('ShareToTeamModal credentials', () => {
});
};
// A compact segmented choice, not a pair of picker tiles.
const toggle = (value: 'owner' | 'member') =>
Array.from(
document.body.querySelectorAll<HTMLButtonElement>(
'[data-slot="option-card"]',
'[data-slot="toggle-group-item"]',
),
).find((item) =>
item.textContent?.includes(`settings.connectors.sharing.${value}`),
).find(
(item) =>
item.textContent === `settings.connectors.sharing.${value}Short`,
)!;
const picker = () =>
document.body.querySelector<HTMLButtonElement>('[role="combobox"]')!;
@@ -99,6 +101,7 @@ describe('ShareToTeamModal credentials', () => {
it('warns that members act as the owner in owner mode', async () => {
await render(credentials());
expect(document.body.querySelector('[data-slot="option-card"]')).toBeNull();
expect(toggle('owner').getAttribute('aria-checked')).toBe('true');
expect(document.body.textContent).toContain(
'settings.connectors.share.ownerWarning|lena@meridian.example',
+27 -19
View File
@@ -19,7 +19,6 @@ import connectorsService from '../api/services/connectorsService';
import { Alert, AlertDescription } from '../components/ui/alert';
import { Checkbox } from '../components/ui/checkbox';
import { Label } from '../components/ui/label';
import { OptionCard } from '../components/ui/option-card';
import { Avatar } from '../components/ui/avatar';
import { Button } from '../components/ui/button';
import {
@@ -50,6 +49,7 @@ import { selectToken } from '../preferences/preferenceSlice';
import { AppDispatch } from '../store';
import { decodeJwtPayload } from '../utils/jwtUtils';
import { loadTeams, selectTeams } from './teamsSlice';
import { ToggleGroup, ToggleGroupItem } from '../components/ui/toggle-group';
/** A connection-backed tool: whose account shares of it run with. */
export type ShareCredentials = {
@@ -560,24 +560,32 @@ export default function ShareToTeamModal({
size="xs"
title={t('settings.connectors.share.heading')}
/>
<div
role="radiogroup"
aria-label={t('settings.connectors.share.heading')}
className="grid gap-3 sm:grid-cols-2"
>
{(['owner', 'member'] as const).map((mode) => (
<OptionCard
key={mode}
icon={mode === 'owner' ? <UserRound /> : <UsersRound />}
title={t(`settings.connectors.sharing.${mode}`)}
selected={credentialMode === mode}
disabled={
!!credentials.forcedMode &&
credentials.forcedMode !== mode
}
onClick={() => changeCredentialMode(mode)}
/>
))}
{/* A compact one-of-two; the line under it says what the
choice means. */}
<div className="bg-muted self-start rounded-full p-1">
<ToggleGroup
type="single"
size="xs"
value={credentialMode}
aria-label={t('settings.connectors.share.heading')}
onValueChange={(value) =>
value && changeCredentialMode(value as 'owner' | 'member')
}
>
{(['owner', 'member'] as const).map((mode) => (
<ToggleGroupItem
key={mode}
value={mode}
disabled={
!!credentials.forcedMode &&
credentials.forcedMode !== mode
}
>
{mode === 'owner' ? <UserRound /> : <UsersRound />}
{t(`settings.connectors.sharing.${mode}Short`)}
</ToggleGroupItem>
))}
</ToggleGroup>
</div>
{credentials.forcedMode && (
<p className="text-muted-foreground text-xs">