Skip to content

Commit e2fa184

Browse files
committed
Improve issue list sort handling and team view open
- Respect --sort flag and pass sort through to fetch - Default workspace from viewer when unset - Allow specifying team when opening assignee view - Add test to ensure sort flag bypasses validation
1 parent f3acdd0 commit e2fa184

File tree

7 files changed

+60
-20
lines changed

7 files changed

+60
-20
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Fixed
6+
7+
- various issues with issue list: --team, --sort flags work now, workspace doesn't need to be set (useful when running unconfigured)
8+
59
### Changed
610

711
- removed uneccessary double prompt around adding labels

src/commands/issue/issue-list.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export const listCommand = new Command()
8383
) => {
8484
const usePager = pager !== false
8585
if (web || app) {
86-
await openTeamAssigneeView({ app: app })
86+
await openTeamAssigneeView({ app: app, team })
8787
return
8888
}
8989

@@ -110,8 +110,10 @@ export const listCommand = new Command()
110110
Deno.exit(1)
111111
}
112112

113-
const sort = sortFlag ||
114-
getOption("issue_sort") as "manual" | "priority" | undefined
113+
const sort = getOption("issue_sort", sortFlag) as
114+
| "manual"
115+
| "priority"
116+
| undefined
115117
if (!sort) {
116118
console.error(
117119
"Sort must be provided via command line flag, configuration file, or LINEAR_ISSUE_SORT environment variable",
@@ -142,6 +144,7 @@ export const listCommand = new Command()
142144
assignee,
143145
unassigned,
144146
allAssignees,
147+
sort,
145148
)
146149
spinner?.stop()
147150
const issues = result.issues?.nodes || []

src/utils/actions.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,34 @@ export async function openProjectPage(
5555
await open(url, options.app ? { app: { name: "Linear" } } : undefined)
5656
}
5757

58-
export async function openTeamAssigneeView(options: { app?: boolean } = {}) {
59-
const teamId = getTeamKey()
58+
export async function openTeamAssigneeView(
59+
options: { app?: boolean; team?: string } = {},
60+
) {
61+
const teamId = options.team || getTeamKey()
6062
if (!teamId) {
6163
console.error(
6264
"Could not determine team id from configuration or directory name.",
6365
)
6466
Deno.exit(1)
6567
}
6668

67-
const workspace = getOption("workspace")
69+
let workspace = getOption("workspace")
6870
if (!workspace) {
69-
console.error(
70-
"workspace is not set via command line, configuration file, or environment.",
71-
)
72-
Deno.exit(1)
71+
// Get workspace from viewer if not configured
72+
const { gql } = await import("../__codegen__/gql.ts")
73+
const { getGraphQLClient } = await import("./graphql.ts")
74+
const client = getGraphQLClient()
75+
const viewerQuery = gql(`
76+
query GetViewer {
77+
viewer {
78+
organization {
79+
urlKey
80+
}
81+
}
82+
}
83+
`)
84+
const result = await client.request(viewerQuery)
85+
workspace = result.viewer.organization.urlKey
7386
}
7487

7588
const filterObj = {

src/utils/linear.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,11 @@ export async function fetchIssuesForState(
304304
assignee?: string,
305305
unassigned = false,
306306
allAssignees = false,
307+
sort?: "manual" | "priority",
307308
) {
308-
const sort = getOption("issue_sort") as "manual" | "priority" | undefined
309-
if (!sort) {
309+
const sortValue = sort ||
310+
getOption("issue_sort") as "manual" | "priority" | undefined
311+
if (!sortValue) {
310312
console.error(
311313
"Sort must be provided via configuration file or LINEAR_ISSUE_SORT environment variable",
312314
)
@@ -369,7 +371,7 @@ export async function fetchIssuesForState(
369371
`)
370372

371373
let sortPayload: Array<IssueSortInput>
372-
switch (sort) {
374+
switch (sortValue) {
373375
case "manual":
374376
sortPayload = [
375377
{ workflowState: { order: "Descending" } },
@@ -383,7 +385,7 @@ export async function fetchIssuesForState(
383385
]
384386
break
385387
default:
386-
throw new Error(`Unknown sort type: ${sort}`)
388+
throw new Error(`Unknown sort type: ${sortValue}`)
387389
}
388390

389391
const client = getGraphQLClient()

test/commands/issue/__snapshots__/issue-view.test.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ stderr:
2424

2525
snapshot[`Issue View Command - With Issue ID 1`] = `
2626
stdout:
27-
"Error: error sending request for url (http://127.0.0.1:3000/graphql): client error (Connect): tcp connect error: Connection refused: Connection refused
28-
"
27+
'Error: GraphQL Error (Code: 401): {"response":{"status":401,"headers":{}},"request":{"query":"query GetIssueDetailsWithComments(\$id: String!) {\\\\n issue(id: \$id) {\\\\n title\\\\n description\\\\n url\\\\n branchName\\\\n comments(first: 50, orderBy: createdAt) {\\\\n nodes {\\\\n id\\\\n body\\\\n createdAt\\\\n user {\\\\n name\\\\n displayName\\\\n }\\\\n externalUser {\\\\n name\\\\n displayName\\\\n }\\\\n parent {\\\\n id\\\\n }\\\\n }\\\\n }\\\\n }\\\\n}","variables":{"id":"TEST-123"}}}
28+
'
2929
stderr:
3030
"✗ Failed to fetch issue details
3131
"

test/commands/issue/issue-list.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { snapshotTest } from "@cliffy/testing"
2+
import { assertEquals } from "@std/assert"
23
import { listCommand } from "../../../src/commands/issue/issue-list.ts"
34
import { commonDenoArgs } from "../../utils/test-helpers.ts"
45

@@ -13,3 +14,21 @@ await snapshotTest({
1314
await listCommand.parse()
1415
},
1516
})
17+
18+
Deno.test("Issue List Command - sort flag should work", async () => {
19+
const args = ["--team", "pre", "-A", "--sort", "priority"]
20+
21+
// This should not throw an error about sort being required
22+
try {
23+
await listCommand.parse(args)
24+
} catch (error) {
25+
// We expect it to fail for other reasons (like API calls), but not for sort validation
26+
if (error instanceof Error) {
27+
assertEquals(
28+
error.message.includes("Sort must be provided"),
29+
false,
30+
"Sort flag was provided but validation still failed",
31+
)
32+
}
33+
}
34+
})

test/commands/issue/issue-view.test.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,9 @@ await snapshotTest({
4545
// Expected to fail with mock endpoint, capture the error for snapshot
4646
// Normalize error message to be consistent across platforms
4747
const message = (error as Error).message
48-
const normalizedMessage = message.replace(
49-
/Connection refused \(os error \d+\)/g,
50-
"Connection refused",
51-
)
48+
const normalizedMessage = message
49+
.replace(/Connection refused \(os error \d+\)/g, "Connection refused")
50+
.replace(/: Connection refused$/g, "")
5251
console.log(`Error: ${normalizedMessage}`)
5352
} finally {
5453
// Clean up environment

0 commit comments

Comments
 (0)