clairo 2.2.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +88 -54
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1146,25 +1146,45 @@ async function getBoardIssues(auth, boardId, opts) {
|
|
|
1146
1146
|
function escapeJql(text) {
|
|
1147
1147
|
return text.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
1148
1148
|
}
|
|
1149
|
-
function
|
|
1149
|
+
function createSearchClause(searchText) {
|
|
1150
1150
|
const escaped = escapeJql(searchText);
|
|
1151
|
-
|
|
1151
|
+
if (/^[A-Z]+-\d+$/i.test(searchText)) {
|
|
1152
|
+
return `(key = "${escaped}" OR text ~ "${escaped}")`;
|
|
1153
|
+
}
|
|
1154
|
+
if (/^\d+$/.test(searchText)) {
|
|
1155
|
+
return `(key ~ "*-${escaped}" OR text ~ "${escaped}")`;
|
|
1156
|
+
}
|
|
1157
|
+
return `text ~ "${escaped}"`;
|
|
1158
|
+
}
|
|
1159
|
+
function appendTextSearch(jql, searchText) {
|
|
1160
|
+
return `(${jql}) AND ${createSearchClause(searchText)}`;
|
|
1161
|
+
}
|
|
1162
|
+
function createAssigneeClause(filter) {
|
|
1163
|
+
if (filter === "unassigned") return "assignee is EMPTY";
|
|
1164
|
+
return "assignee = currentUser()";
|
|
1152
1165
|
}
|
|
1153
1166
|
async function fetchViewIssues(auth, view, opts) {
|
|
1154
|
-
const { searchText, ...pageOpts } = opts ?? {};
|
|
1167
|
+
const { searchText, assigneeFilter, ...pageOpts } = opts ?? {};
|
|
1155
1168
|
switch (view.source.type) {
|
|
1156
1169
|
case "jql": {
|
|
1157
|
-
|
|
1170
|
+
let jql = view.source.jql;
|
|
1171
|
+
if (searchText) jql = appendTextSearch(jql, searchText);
|
|
1172
|
+
if (assigneeFilter) jql = `(${jql}) AND ${createAssigneeClause(assigneeFilter)}`;
|
|
1158
1173
|
return searchIssues(auth, jql, pageOpts);
|
|
1159
1174
|
}
|
|
1160
1175
|
case "filter": {
|
|
1161
1176
|
const filterResult = await getFilterJql(auth, view.source.filterId);
|
|
1162
1177
|
if (!filterResult.success) return filterResult;
|
|
1163
|
-
|
|
1178
|
+
let jql = filterResult.data;
|
|
1179
|
+
if (searchText) jql = appendTextSearch(jql, searchText);
|
|
1180
|
+
if (assigneeFilter) jql = `(${jql}) AND ${createAssigneeClause(assigneeFilter)}`;
|
|
1164
1181
|
return searchIssues(auth, jql, pageOpts);
|
|
1165
1182
|
}
|
|
1166
1183
|
case "board": {
|
|
1167
|
-
const
|
|
1184
|
+
const clauses = [];
|
|
1185
|
+
if (searchText) clauses.push(createSearchClause(searchText));
|
|
1186
|
+
if (assigneeFilter) clauses.push(createAssigneeClause(assigneeFilter));
|
|
1187
|
+
const jql = clauses.length > 0 ? clauses.join(" AND ") : void 0;
|
|
1168
1188
|
return getBoardIssues(auth, view.source.boardId, { ...pageOpts, jql });
|
|
1169
1189
|
}
|
|
1170
1190
|
}
|
|
@@ -3783,6 +3803,7 @@ function JiraIssueDetailView({
|
|
|
3783
3803
|
auth,
|
|
3784
3804
|
myAccountId,
|
|
3785
3805
|
myDisplayName,
|
|
3806
|
+
onFetchCurrentUser,
|
|
3786
3807
|
isActive,
|
|
3787
3808
|
onClose,
|
|
3788
3809
|
onIssueUpdated,
|
|
@@ -3844,16 +3865,27 @@ function JiraIssueDetailView({
|
|
|
3844
3865
|
setActionLoading(null);
|
|
3845
3866
|
};
|
|
3846
3867
|
const handleAssignToMe = async () => {
|
|
3847
|
-
if (!myAccountId || !myDisplayName) return;
|
|
3848
3868
|
setActionLoading("Assigning...");
|
|
3849
3869
|
setActionError(null);
|
|
3850
|
-
|
|
3870
|
+
let accountId = myAccountId;
|
|
3871
|
+
let displayName = myDisplayName;
|
|
3872
|
+
if (!accountId || !displayName) {
|
|
3873
|
+
const user = await onFetchCurrentUser();
|
|
3874
|
+
if (!user) {
|
|
3875
|
+
setActionError("Failed to get current user");
|
|
3876
|
+
setActionLoading(null);
|
|
3877
|
+
return;
|
|
3878
|
+
}
|
|
3879
|
+
accountId = user.accountId;
|
|
3880
|
+
displayName = user.displayName;
|
|
3881
|
+
}
|
|
3882
|
+
const result = await assignIssue(auth, issueKey, accountId);
|
|
3851
3883
|
if (result.success) {
|
|
3852
|
-
const assignee = { accountId
|
|
3884
|
+
const assignee = { accountId, displayName };
|
|
3853
3885
|
setDetail((prev) => prev ? { ...prev, fields: { ...prev.fields, assignee } } : prev);
|
|
3854
3886
|
onIssueUpdated(issueKey, { assignee });
|
|
3855
|
-
duckEvents.emit("jira:assigned", { ticketKey: issueKey, assignee:
|
|
3856
|
-
logJiraAssigneeChanged(issueKey, issueSummary, "assigned",
|
|
3887
|
+
duckEvents.emit("jira:assigned", { ticketKey: issueKey, assignee: displayName });
|
|
3888
|
+
logJiraAssigneeChanged(issueKey, issueSummary, "assigned", displayName);
|
|
3857
3889
|
onLogUpdated == null ? void 0 : onLogUpdated();
|
|
3858
3890
|
} else {
|
|
3859
3891
|
setActionError(result.error);
|
|
@@ -3906,7 +3938,7 @@ function JiraIssueDetailView({
|
|
|
3906
3938
|
if (input === "s" && !actionLoading) {
|
|
3907
3939
|
openTransitionPicker();
|
|
3908
3940
|
}
|
|
3909
|
-
if (input === "a" && !actionLoading
|
|
3941
|
+
if (input === "a" && !actionLoading) {
|
|
3910
3942
|
handleAssignToMe();
|
|
3911
3943
|
}
|
|
3912
3944
|
if (input === "A" && !actionLoading) {
|
|
@@ -4054,6 +4086,7 @@ function JiraSavedViewBrowserBox({
|
|
|
4054
4086
|
auth,
|
|
4055
4087
|
myAccountId,
|
|
4056
4088
|
myDisplayName,
|
|
4089
|
+
onFetchCurrentUser,
|
|
4057
4090
|
isActive,
|
|
4058
4091
|
onInputModeChange,
|
|
4059
4092
|
onLogUpdated
|
|
@@ -4074,22 +4107,10 @@ function JiraSavedViewBrowserBox({
|
|
|
4074
4107
|
const title = "[6] Issues";
|
|
4075
4108
|
const borderColor = isActive ? "yellow" : void 0;
|
|
4076
4109
|
const displayTitle = view ? `${title} - ${view.name}` : title;
|
|
4077
|
-
const filteredIssues = useMemo2(() => {
|
|
4078
|
-
if (assigneeFilter === "unassigned") {
|
|
4079
|
-
return issues.filter((issue) => !issue.fields.assignee);
|
|
4080
|
-
}
|
|
4081
|
-
if (assigneeFilter === "me" && myAccountId) {
|
|
4082
|
-
return issues.filter((issue) => {
|
|
4083
|
-
var _a;
|
|
4084
|
-
return ((_a = issue.fields.assignee) == null ? void 0 : _a.accountId) === myAccountId;
|
|
4085
|
-
});
|
|
4086
|
-
}
|
|
4087
|
-
return issues;
|
|
4088
|
-
}, [issues, assigneeFilter, myAccountId]);
|
|
4089
4110
|
const rows = useMemo2(() => {
|
|
4090
|
-
const groups = groupBySprint(
|
|
4111
|
+
const groups = groupBySprint(issues);
|
|
4091
4112
|
return buildRows(groups);
|
|
4092
|
-
}, [
|
|
4113
|
+
}, [issues]);
|
|
4093
4114
|
const navigableIndices = useMemo2(
|
|
4094
4115
|
() => rows.map((r, i) => r.type === "issue" ? i : -1).filter((i) => i >= 0),
|
|
4095
4116
|
[rows]
|
|
@@ -4104,14 +4125,19 @@ function JiraSavedViewBrowserBox({
|
|
|
4104
4125
|
}, [rows, navigableIndices, highlightedIndex]);
|
|
4105
4126
|
const hasMore = issues.length < total;
|
|
4106
4127
|
const doFetch = useCallback9(
|
|
4107
|
-
async (search, startAt = 0, append = false) => {
|
|
4128
|
+
async (search, filter, startAt = 0, append = false) => {
|
|
4108
4129
|
if (!view || !auth) return;
|
|
4109
4130
|
setLoading(true);
|
|
4110
4131
|
setError(null);
|
|
4132
|
+
if (!append) {
|
|
4133
|
+
setIssues([]);
|
|
4134
|
+
setTotal(0);
|
|
4135
|
+
}
|
|
4111
4136
|
const result = await fetchViewIssues(auth, view, {
|
|
4112
4137
|
startAt,
|
|
4113
4138
|
maxResults: 50,
|
|
4114
|
-
searchText: search || void 0
|
|
4139
|
+
searchText: search || void 0,
|
|
4140
|
+
assigneeFilter: filter === "all" ? void 0 : filter
|
|
4115
4141
|
});
|
|
4116
4142
|
if (result.success) {
|
|
4117
4143
|
setIssues((prev) => append ? [...prev, ...result.data.issues] : result.data.issues);
|
|
@@ -4132,7 +4158,8 @@ function JiraSavedViewBrowserBox({
|
|
|
4132
4158
|
if (view && auth) {
|
|
4133
4159
|
setSearchText("");
|
|
4134
4160
|
setInputText("");
|
|
4135
|
-
|
|
4161
|
+
setAssigneeFilter("all");
|
|
4162
|
+
doFetch("", "all");
|
|
4136
4163
|
} else {
|
|
4137
4164
|
setIssues([]);
|
|
4138
4165
|
setTotal(0);
|
|
@@ -4176,7 +4203,7 @@ function JiraSavedViewBrowserBox({
|
|
|
4176
4203
|
const newSearch = inputText.trim();
|
|
4177
4204
|
if (newSearch !== searchText) {
|
|
4178
4205
|
setSearchText(newSearch);
|
|
4179
|
-
doFetch(newSearch);
|
|
4206
|
+
doFetch(newSearch, assigneeFilter);
|
|
4180
4207
|
}
|
|
4181
4208
|
return;
|
|
4182
4209
|
}
|
|
@@ -4219,31 +4246,33 @@ function JiraSavedViewBrowserBox({
|
|
|
4219
4246
|
return;
|
|
4220
4247
|
}
|
|
4221
4248
|
if (input === "u") {
|
|
4222
|
-
|
|
4249
|
+
const newFilter = assigneeFilter === "unassigned" ? "all" : "unassigned";
|
|
4250
|
+
setAssigneeFilter(newFilter);
|
|
4251
|
+
doFetch(searchText, newFilter);
|
|
4223
4252
|
setHighlightedIndex(0);
|
|
4224
4253
|
return;
|
|
4225
4254
|
}
|
|
4226
4255
|
if (input === "m") {
|
|
4227
|
-
|
|
4256
|
+
const newFilter = assigneeFilter === "me" ? "all" : "me";
|
|
4257
|
+
setAssigneeFilter(newFilter);
|
|
4258
|
+
doFetch(searchText, newFilter);
|
|
4228
4259
|
setHighlightedIndex(0);
|
|
4229
4260
|
return;
|
|
4230
4261
|
}
|
|
4231
4262
|
if (input === "x") {
|
|
4232
4263
|
setAssigneeFilter("all");
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
doFetch("");
|
|
4237
|
-
}
|
|
4264
|
+
setSearchText("");
|
|
4265
|
+
setInputText("");
|
|
4266
|
+
doFetch("", "all");
|
|
4238
4267
|
setHighlightedIndex(0);
|
|
4239
4268
|
return;
|
|
4240
4269
|
}
|
|
4241
4270
|
if (input === "l" && hasMore) {
|
|
4242
|
-
doFetch(searchText, issues.length, true);
|
|
4271
|
+
doFetch(searchText, assigneeFilter, issues.length, true);
|
|
4243
4272
|
return;
|
|
4244
4273
|
}
|
|
4245
4274
|
if (input === "r") {
|
|
4246
|
-
doFetch(searchText);
|
|
4275
|
+
doFetch(searchText, assigneeFilter);
|
|
4247
4276
|
}
|
|
4248
4277
|
},
|
|
4249
4278
|
{ isActive }
|
|
@@ -4260,6 +4289,7 @@ function JiraSavedViewBrowserBox({
|
|
|
4260
4289
|
auth,
|
|
4261
4290
|
myAccountId,
|
|
4262
4291
|
myDisplayName,
|
|
4292
|
+
onFetchCurrentUser,
|
|
4263
4293
|
isActive,
|
|
4264
4294
|
onClose: () => setDetailIssue(null),
|
|
4265
4295
|
onIssueUpdated: handleIssueUpdated,
|
|
@@ -4276,7 +4306,7 @@ function JiraSavedViewBrowserBox({
|
|
|
4276
4306
|
/* @__PURE__ */ jsxs10(Text11, { dimColor: true, children: [
|
|
4277
4307
|
" ",
|
|
4278
4308
|
"(",
|
|
4279
|
-
|
|
4309
|
+
issues.length,
|
|
4280
4310
|
"/",
|
|
4281
4311
|
total,
|
|
4282
4312
|
")"
|
|
@@ -4290,8 +4320,7 @@ function JiraSavedViewBrowserBox({
|
|
|
4290
4320
|
" Loading issues..."
|
|
4291
4321
|
] }) }),
|
|
4292
4322
|
view && error && /* @__PURE__ */ jsx12(Box10, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text11, { color: "red", children: error }) }),
|
|
4293
|
-
view && !loading && !error && issues.length === 0 && /* @__PURE__ */ jsx12(Box10, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text11, { dimColor: true, children:
|
|
4294
|
-
view && !loading && !error && filteredIssues.length === 0 && issues.length > 0 && /* @__PURE__ */ jsx12(Box10, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "No issues match filter" }) }),
|
|
4323
|
+
view && !loading && !error && issues.length === 0 && /* @__PURE__ */ jsx12(Box10, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: hasActiveFilters ? "No issues match filter" : "No issues found" }) }),
|
|
4295
4324
|
rows.length > 0 && /* @__PURE__ */ jsx12(ScrollView6, { ref: scrollRef, children: rows.map((row, rowIdx) => {
|
|
4296
4325
|
if (row.type === "header") {
|
|
4297
4326
|
const stateLabel = row.state === "active" ? " (active)" : "";
|
|
@@ -4456,6 +4485,7 @@ function JiraBrowserView({
|
|
|
4456
4485
|
const [myDisplayName, setMyDisplayName] = useState17(null);
|
|
4457
4486
|
const [inputModeActive, setInputModeActive] = useState17(false);
|
|
4458
4487
|
const lastRepoRef = useRef7(null);
|
|
4488
|
+
const fetchingUserRef = useRef7(false);
|
|
4459
4489
|
const auth = useMemo3(() => {
|
|
4460
4490
|
if (!repo.repoPath || !isJiraConfigured(repo.repoPath)) return null;
|
|
4461
4491
|
const siteUrl = getJiraSiteUrl(repo.repoPath);
|
|
@@ -4473,18 +4503,21 @@ function JiraBrowserView({
|
|
|
4473
4503
|
setSelectedViewId(loaded[0].id);
|
|
4474
4504
|
}
|
|
4475
4505
|
}, [repo.repoPath]);
|
|
4476
|
-
|
|
4477
|
-
if (
|
|
4478
|
-
|
|
4479
|
-
return;
|
|
4506
|
+
const fetchCurrentUser = useCallback10(async () => {
|
|
4507
|
+
if (myAccountId && myDisplayName) {
|
|
4508
|
+
return { accountId: myAccountId, displayName: myDisplayName };
|
|
4480
4509
|
}
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4510
|
+
if (!auth || fetchingUserRef.current) return null;
|
|
4511
|
+
fetchingUserRef.current = true;
|
|
4512
|
+
const result = await getCurrentUser(auth);
|
|
4513
|
+
fetchingUserRef.current = false;
|
|
4514
|
+
if (result.success) {
|
|
4515
|
+
setMyAccountId(result.data.accountId);
|
|
4516
|
+
setMyDisplayName(result.data.displayName);
|
|
4517
|
+
return { accountId: result.data.accountId, displayName: result.data.displayName };
|
|
4518
|
+
}
|
|
4519
|
+
return null;
|
|
4520
|
+
}, [auth, myAccountId, myDisplayName]);
|
|
4488
4521
|
useEffect13(() => {
|
|
4489
4522
|
onModalChange == null ? void 0 : onModalChange(modal.isOpen || inputModeActive);
|
|
4490
4523
|
}, [modal.isOpen, inputModeActive, onModalChange]);
|
|
@@ -4547,7 +4580,7 @@ function JiraBrowserView({
|
|
|
4547
4580
|
if (input === "5") onFocusedBoxChange("saved-views");
|
|
4548
4581
|
if (input === "6") onFocusedBoxChange("browser");
|
|
4549
4582
|
},
|
|
4550
|
-
{ isActive: isActive && !modal.isOpen }
|
|
4583
|
+
{ isActive: isActive && !modal.isOpen && !inputModeActive }
|
|
4551
4584
|
);
|
|
4552
4585
|
if (modal.type === "add") {
|
|
4553
4586
|
return /* @__PURE__ */ jsx14(Box12, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx14(
|
|
@@ -4586,6 +4619,7 @@ function JiraBrowserView({
|
|
|
4586
4619
|
auth,
|
|
4587
4620
|
myAccountId,
|
|
4588
4621
|
myDisplayName,
|
|
4622
|
+
onFetchCurrentUser: fetchCurrentUser,
|
|
4589
4623
|
isActive: isActive && focusedBox === "browser",
|
|
4590
4624
|
onInputModeChange: setInputModeActive,
|
|
4591
4625
|
onLogUpdated
|