From 87eccfe9f489260e732c63ec56074f80a021492b Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Fri, 23 Oct 2026 15:58:12 -0700 Subject: [PATCH] Pick Jira users for required Reporter and custom user fields (#31972) * fix(jira): pick real users for required create fields * test(jira): keep user picker coverage within renderer boundary * fix(jira): preserve known user identities and metadata choices * test(jira): preserve full dialog fixture model type * test(jira): target metadata Select trigger * fix(jira): show matching people before known ID action --- src/main/jira/jira-issue-create-metadata.ts | 2 +- .../src/components/jira-user-picker.tsx | 19 +- .../task-page-jira-create-fields.ts | 3 + .../components/task-page/jira/IssueDialog.tsx | 29 ++- .../task-page/jira/IssueUserField.test.tsx | 176 ++++++++++++++++++ .../task-page/jira/IssueUserField.tsx | 37 ++++ src/renderer/src/i18n/locales/en.json | 3 +- src/renderer/src/i18n/locales/es.json | 3 +- src/renderer/src/i18n/locales/fr.json | 3 +- src/renderer/src/i18n/locales/ja.json | 3 +- src/renderer/src/i18n/locales/ko.json | 3 +- src/renderer/src/i18n/locales/pt.json | 3 +- src/renderer/src/i18n/locales/zh.json | 3 +- 13 files changed, 276 insertions(+), 11 deletions(-) create mode 100644 src/renderer/src/components/task-page/jira/IssueUserField.test.tsx create mode 100644 src/renderer/src/components/task-page/jira/IssueUserField.tsx diff --git a/src/main/jira/jira-issue-create-metadata.ts b/src/main/jira/jira-issue-create-metadata.ts index bdc7f0dccdc..2e555edc723 100644 --- a/src/main/jira/jira-issue-create-metadata.ts +++ b/src/main/jira/jira-issue-create-metadata.ts @@ -175,7 +175,7 @@ export async function searchUsers(query?: string, siteId?: string | null): Promi clearToken(entry.site.id) throw error } - // Browse-users permission is optional; the dialog falls back to a text field. + // Browse-users permission is optional; the dialog allows explicit known user IDs. console.warn('[jira] searchUsers failed:', error) return [] } finally { diff --git a/src/renderer/src/components/jira-user-picker.tsx b/src/renderer/src/components/jira-user-picker.tsx index f1c21bfb4b5..74410b860c3 100644 --- a/src/renderer/src/components/jira-user-picker.tsx +++ b/src/renderer/src/components/jira-user-picker.tsx @@ -56,7 +56,8 @@ export function JiraUserPicker({ disabled, label, fixedOptions, - searchUsers + searchUsers, + allowKnownUserId }: { providerSettings: RuntimeJiraSettings siteId?: string | null @@ -69,11 +70,13 @@ export function JiraUserPicker({ fixedOptions?: JiraUserPickerFixedOption[] /** Replaces the site-wide user search, e.g. with a project-scoped assignable search. Must be referentially stable. */ searchUsers?: (query: string) => Promise + allowKnownUserId?: boolean }): React.JSX.Element { const [open, setOpen] = useState(false) const [query, setQuery] = useState('') const [users, setUsers] = useState([]) const [loading, setLoading] = useState(false) + const knownUserId = query.trim() useEffect(() => { if (!open) { @@ -166,6 +169,20 @@ export function JiraUserPicker({ }} /> )} + {allowKnownUserId && knownUserId ? ( + + ) : null} ) diff --git a/src/renderer/src/components/task-page-jira-create-fields.ts b/src/renderer/src/components/task-page-jira-create-fields.ts index d847423e3c2..d1b64069902 100644 --- a/src/renderer/src/components/task-page-jira-create-fields.ts +++ b/src/renderer/src/components/task-page-jira-create-fields.ts @@ -83,6 +83,9 @@ export function buildJiraCreateFieldValue(field: JiraCreateField, draftValue: st if (!trimmed) { return undefined } + if (isJiraScalarUserCreateField(field)) { + return trimmed + } if (field.schema?.type === 'array') { const parts = trimmed .split(',') diff --git a/src/renderer/src/components/task-page/jira/IssueDialog.tsx b/src/renderer/src/components/task-page/jira/IssueDialog.tsx index ff3c492857e..7c881e63c27 100644 --- a/src/renderer/src/components/task-page/jira/IssueDialog.tsx +++ b/src/renderer/src/components/task-page/jira/IssueDialog.tsx @@ -31,8 +31,12 @@ import { SelectItem } from '@/components/ui/select' import { Input } from '@/components/ui/input' -import { getJiraCreateAllowedValueLabel } from '@/components/task-page-jira-create-fields' +import { + getJiraCreateAllowedValueLabel, + isJiraScalarUserCreateField +} from '@/components/task-page-jira-create-fields' import { TaskPageJiraIssueAssigneeField } from './IssueAssigneeField' +import { TaskPageJiraIssueUserField } from './IssueUserField' export function TaskPageJiraIssueDialog({ model }: { @@ -265,7 +269,28 @@ export function TaskPageJiraIssueDialog({ - {field.allowedValues?.length && field.schema?.type !== 'array' ? ( + {isJiraScalarUserCreateField(field) && !field.allowedValues?.length ? ( + model.jiraTaskSourceContext ? ( + + setNewJiraIssueCustomFieldValues((prev) => ({ + ...prev, + [field.key]: id + })) + } + disabled={newJiraIssueSubmitting} + label={field.name} + /> + ) : null + ) : field.allowedValues?.length && field.schema?.type !== 'array' ? (