Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion web/lib/flow-sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ export const ISSUE_SOURCES = [
] },
{ id: 'shortcut', label: 'Shortcut', fields: [
{ key: 'workspace', label: 'Workspace', placeholder: 'Your workspace' },
{ key: 'project', label: 'Project', placeholder: 'Web app' },
// Shortcut scopes work by Group, branded "Team" in its UI. Projects are
// legacy: `/api/v3/projects` is empty in a modern workspace and a story's
// `project_id` is null there, so a project filter could never match one —
// and the launcher compared the name typed here against a numeric id, which
// silently dropped every story. Cloud now matches this against the team
// name (or its group id), so ask for the thing a story actually carries.
{ key: 'team', label: 'Team (group)', placeholder: 'Platform' },
{ key: 'labels', label: 'Required labels', placeholder: 'ready-for-agent' },
] },
{ id: 'jira', label: 'Jira', fields: [
Expand Down
10 changes: 7 additions & 3 deletions web/lib/test/flow-sources.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@ describe('generated issue source filters', () => {
it('combines source-specific filters and allows any selected source', () => {
const matches = matcher(['linear', 'shortcut', 'jira'], {
linear: { team: 'Engineering', project: 'Web', labels: 'ready' },
shortcut: { workspace: 'acme', project: 'App', labels: 'bug, ready' },
shortcut: { workspace: 'acme', team: 'Platform', labels: 'bug, ready' },
jira: { project: 'ENG', labels: 'ready' },
});
expect(matches({ ...issue, team: 'Engineering', project: 'Web' })).toBe(true);
expect(matches({ ...issue, team: 'Design', project: 'Web' })).toBe(false);
expect(matches({ ...issue, source: 'shortcut', workspace: 'acme', project: 'App', labels: ['ready', 'bug'] })).toBe(true);
expect(matches({ ...issue, source: 'shortcut', workspace: 'other', project: 'App', labels: ['ready', 'bug'] })).toBe(false);
expect(matches({ ...issue, source: 'shortcut', workspace: 'acme', team: 'Platform', labels: ['ready', 'bug'] })).toBe(true);
expect(matches({ ...issue, source: 'shortcut', workspace: 'other', team: 'Platform', labels: ['ready', 'bug'] })).toBe(false);
// Paired negative on the field itself: same workspace, different team. A
// Shortcut story names its team by `group_id`, never by a project name, so
// this is the scoping that has to hold — and has to still reject.
expect(matches({ ...issue, source: 'shortcut', workspace: 'acme', team: 'Growth', labels: ['ready', 'bug'] })).toBe(false);
expect(matches({ ...issue, source: 'jira', project: 'ENG' })).toBe(true);
expect(matches({ ...issue, source: 'github' })).toBe(false);
});
Expand Down
Loading