@parallelworks/tandem-web 0.142.0 → 0.143.0
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/_virtual/_virtual_i18n/en/common.js +105 -6
- package/_virtual/_virtual_i18n/es/common.js +105 -6
- package/_virtual/_virtual_i18n/ja/common.js +105 -6
- package/_virtual/_virtual_i18n/ko/common.js +105 -6
- package/_virtual/_virtual_i18n/zh/common.js +105 -6
- package/components/AccessGrants.js +6 -6
- package/components/ActivityTimeline.js +2 -0
- package/components/CodeHostSettings.js +25 -25
- package/components/CustomFields.js +349 -0
- package/components/DocProperties.js +8 -2
- package/components/GitHub.js +22 -22
- package/components/IssueBoard.js +48 -43
- package/components/IssueEvent.js +2 -0
- package/components/IssueFilters.js +210 -122
- package/components/IssueImport.js +1 -1
- package/components/IssueRow.js +96 -79
- package/components/IssueTemplates.js +216 -156
- package/components/IssueTypes.js +318 -0
- package/components/NewIssueDialog.js +254 -216
- package/components/SettingsNav.js +40 -35
- package/components/TeamForm.js +49 -35
- package/components/TeamRepositories.js +51 -51
- package/components/TeamWorkflow.js +8 -8
- package/components/Updates.js +8 -8
- package/lib/boardMove.js +69 -47
- package/lib/customFields.js +113 -0
- package/lib/issueDisplay.js +27 -12
- package/lib/issueList.js +166 -62
- package/lib/issueTypes.js +50 -0
- package/lib/teamTree.js +24 -0
- package/lib/views.js +13 -11
- package/package.json +1 -1
- package/pages/issues.js +331 -291
- package/routeTree.gen.js +151 -145
- package/routes/_workspace/agents/index2.js +9 -9
- package/routes/_workspace/issues/_identifier2.js +433 -370
- package/routes/_workspace/projects/_projectId3.js +213 -201
- package/routes/_workspace/settings/audit-log3.js +2 -0
- package/routes/_workspace/settings/fields.js +6 -0
- package/routes/_workspace/settings/fields2.js +30 -0
- package/routes/_workspace/settings/fields3.js +5 -0
- package/routes/_workspace/settings/groups2.js +74 -74
- package/routes/_workspace/settings/labels2.js +33 -33
- package/routes/_workspace/settings/members2.js +35 -35
- package/routes/_workspace/settings/roles2.js +24 -24
- package/routes/_workspace/settings/runners2.js +18 -18
- package/routes/_workspace/settings/sessions2.js +9 -9
- package/routes/_workspace/settings/slack2.js +8 -8
- package/routes/_workspace/settings/sso2.js +50 -50
- package/routes/_workspace/settings/tokens2.js +15 -15
- package/routes/_workspace/settings/webhooks2.js +42 -42
- package/routes/_workspace/teams/_key/settings2.js +138 -76
- package/routes/_workspace2.js +320 -318
package/components/Updates.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { meQuery as e } from "../api/queries.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { useConfirm as t } from "../lib/confirm.js";
|
|
3
|
+
import { HealthIcon as n } from "./Planning.js";
|
|
4
|
+
import { usePeople as r } from "../lib/people.js";
|
|
5
5
|
import { ActionMenu as i, Avatar as a, Button as o, Card as s, ErrorText as c, RelativeTime as l, Select as u, Textarea as d, buttonClasses as f, cx as p, fieldBox as m } from "@parallelworks/ui";
|
|
6
6
|
import { useState as h } from "react";
|
|
7
7
|
import { useErrorMessage as g } from "@parallelworks/problem/react";
|
|
@@ -16,13 +16,13 @@ var S = [
|
|
|
16
16
|
"off_track"
|
|
17
17
|
];
|
|
18
18
|
function C({ workspace: C, state: w, health: T, updates: E, canWrite: D, placeholder: O, post: k, remove: A }) {
|
|
19
|
-
let j = _("planning"), M = _("common"), { data: N } = b(e), { confirm: P, dialog: F } =
|
|
19
|
+
let j = _("planning"), M = _("common"), { data: N } = b(e), { confirm: P, dialog: F } = t(), I = g(), { actorName: L, avatarOf: R } = r(C), [z, B] = h(T ?? "on_track"), [V, H] = h("");
|
|
20
20
|
return /* @__PURE__ */ y("section", { children: [
|
|
21
21
|
/* @__PURE__ */ y("h2", {
|
|
22
22
|
className: "flex items-center gap-2 text-base font-semibold",
|
|
23
23
|
children: [j("updates"), /* @__PURE__ */ y("span", {
|
|
24
24
|
className: "flex items-center gap-1 text-xs font-normal text-muted-foreground",
|
|
25
|
-
children: [/* @__PURE__ */ v(
|
|
25
|
+
children: [/* @__PURE__ */ v(n, { state: w }), j(`health.${w}`)]
|
|
26
26
|
})]
|
|
27
27
|
}),
|
|
28
28
|
D && /* @__PURE__ */ y("form", {
|
|
@@ -54,12 +54,12 @@ function C({ workspace: C, state: w, health: T, updates: E, canWrite: D, placeho
|
|
|
54
54
|
items: S.map((e) => ({
|
|
55
55
|
value: e,
|
|
56
56
|
label: j(`health.${e}`),
|
|
57
|
-
icon: /* @__PURE__ */ v(
|
|
57
|
+
icon: /* @__PURE__ */ v(n, { state: e })
|
|
58
58
|
})),
|
|
59
59
|
trigger: /* @__PURE__ */ y("button", {
|
|
60
60
|
type: "button",
|
|
61
61
|
className: f({ size: "sm" }),
|
|
62
|
-
children: [/* @__PURE__ */ v(
|
|
62
|
+
children: [/* @__PURE__ */ v(n, { state: z }), j(`health.${z}`)]
|
|
63
63
|
})
|
|
64
64
|
}),
|
|
65
65
|
k.isError && /* @__PURE__ */ v(c, {
|
|
@@ -90,7 +90,7 @@ function C({ workspace: C, state: w, health: T, updates: E, canWrite: D, placeho
|
|
|
90
90
|
children: [/* @__PURE__ */ y("div", {
|
|
91
91
|
className: "flex items-center gap-2 text-xs",
|
|
92
92
|
children: [
|
|
93
|
-
/* @__PURE__ */ v(
|
|
93
|
+
/* @__PURE__ */ v(n, { state: e.health }),
|
|
94
94
|
/* @__PURE__ */ v("span", {
|
|
95
95
|
className: "font-medium",
|
|
96
96
|
children: j(`health.${e.health}`)
|
package/lib/boardMove.js
CHANGED
|
@@ -1,100 +1,122 @@
|
|
|
1
1
|
import { api as e, unwrap as t } from "../api/client.js";
|
|
2
2
|
import { issueQuery as n, statusesQuery as r } from "../api/queries.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
3
|
+
import { setIssueFields as i } from "./customFields.js";
|
|
4
|
+
import { invalidateIssueViews as a } from "../api/mutations.js";
|
|
5
|
+
import { toast as o } from "@parallelworks/ui";
|
|
6
|
+
import { useCallback as s } from "react";
|
|
7
|
+
import { useErrorMessage as c } from "@parallelworks/problem/react";
|
|
8
|
+
import { useQueries as l, useQueryClient as u } from "@tanstack/react-query";
|
|
8
9
|
// src/lib/boardMove.ts
|
|
9
|
-
function
|
|
10
|
-
let
|
|
11
|
-
return
|
|
12
|
-
let
|
|
13
|
-
if (
|
|
14
|
-
let e =
|
|
10
|
+
function d(d, f) {
|
|
11
|
+
let p = u(), m = c(), h = l({ queries: f.map((e) => r(d, e.key)) });
|
|
12
|
+
return s(async (r, s, c, l, u, g) => {
|
|
13
|
+
let _, v, y;
|
|
14
|
+
if (g) {
|
|
15
|
+
let e = l === "none" ? null : l;
|
|
16
|
+
if (g.kind === "checkbox" && (e = l === "true"), g.kind === "multi_select") {
|
|
17
|
+
let t = r.fields[g.id] ?? [];
|
|
18
|
+
e = l === "none" ? [] : [...t.filter((e) => e !== c && e !== l), l];
|
|
19
|
+
}
|
|
20
|
+
v = { [g.id]: e }, y = {
|
|
21
|
+
...r,
|
|
22
|
+
fields: {
|
|
23
|
+
...r.fields,
|
|
24
|
+
[g.id]: e
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
} else if (s === "type") {
|
|
28
|
+
let e = l === "none" ? void 0 : u?.type;
|
|
29
|
+
_ = { typeId: l === "none" ? "" : l };
|
|
30
|
+
let { type: t, ...n } = r;
|
|
31
|
+
y = e ? {
|
|
32
|
+
...n,
|
|
33
|
+
type: e
|
|
34
|
+
} : n;
|
|
35
|
+
} else if (s === "status") {
|
|
36
|
+
let e = (h[f.findIndex((e) => e.id === r.teamId)]?.data ?? []).filter((e) => e.category === l).sort((e, t) => e.position - t.position)[0];
|
|
15
37
|
if (!e) return;
|
|
16
|
-
|
|
38
|
+
_ = { statusId: e.id }, y = {
|
|
17
39
|
...r,
|
|
18
40
|
status: e
|
|
19
41
|
};
|
|
20
|
-
} else if (
|
|
42
|
+
} else if (s === "priority") _ = { priority: Number(l) }, y = {
|
|
21
43
|
...r,
|
|
22
|
-
priority: Number(
|
|
44
|
+
priority: Number(l)
|
|
23
45
|
};
|
|
24
|
-
else if (
|
|
25
|
-
let e =
|
|
26
|
-
if (
|
|
27
|
-
|
|
46
|
+
else if (s === "project") {
|
|
47
|
+
let e = l === "none" ? void 0 : u?.project;
|
|
48
|
+
if (l !== "none" && !e) return;
|
|
49
|
+
_ = { projectId: e?.id ?? "" };
|
|
28
50
|
let { project: t, ...n } = r;
|
|
29
|
-
|
|
51
|
+
y = e ? {
|
|
30
52
|
...n,
|
|
31
53
|
project: e
|
|
32
54
|
} : n;
|
|
33
|
-
} else if (
|
|
34
|
-
let e = (e) => `${e.kind}:${e.handle}`, t =
|
|
35
|
-
if (
|
|
36
|
-
let n = r.assignees.find((t) => e(t) ===
|
|
55
|
+
} else if (s === "assignee") {
|
|
56
|
+
let e = (e) => `${e.kind}:${e.handle}`, t = l === "none" ? void 0 : u?.assignees.find((t) => e(t) === l);
|
|
57
|
+
if (l !== "none" && !t) return;
|
|
58
|
+
let n = r.assignees.find((t) => e(t) === c);
|
|
37
59
|
if (t) {
|
|
38
60
|
let e = r.assignees.filter((e) => e !== n);
|
|
39
|
-
|
|
61
|
+
_ = {
|
|
40
62
|
addAssignees: [t],
|
|
41
63
|
...n && { removeAssignees: [n] }
|
|
42
|
-
},
|
|
64
|
+
}, y = {
|
|
43
65
|
...r,
|
|
44
66
|
assignees: [...e, t]
|
|
45
67
|
};
|
|
46
|
-
} else
|
|
68
|
+
} else _ = { removeAssignees: r.assignees }, y = {
|
|
47
69
|
...r,
|
|
48
70
|
assignees: []
|
|
49
71
|
};
|
|
50
72
|
} else {
|
|
51
|
-
let e =
|
|
52
|
-
if (
|
|
53
|
-
let t = r.labels.find((e) => e.id ===
|
|
73
|
+
let e = l === "none" ? void 0 : u?.labels.find((e) => e.id === l);
|
|
74
|
+
if (l !== "none" && !e) return;
|
|
75
|
+
let t = r.labels.find((e) => e.id === c);
|
|
54
76
|
if (e) {
|
|
55
77
|
let n = r.labels.filter((e) => e !== t);
|
|
56
|
-
|
|
78
|
+
_ = {
|
|
57
79
|
addLabels: [e.id],
|
|
58
80
|
...t && { removeLabels: [t.id] }
|
|
59
|
-
},
|
|
81
|
+
}, y = {
|
|
60
82
|
...r,
|
|
61
83
|
labels: [...n, e]
|
|
62
84
|
};
|
|
63
|
-
} else
|
|
85
|
+
} else _ = { removeLabels: r.labels.map((e) => e.id) }, y = {
|
|
64
86
|
...r,
|
|
65
87
|
labels: []
|
|
66
88
|
};
|
|
67
89
|
}
|
|
68
|
-
let
|
|
90
|
+
let b = { queryKey: [
|
|
69
91
|
"workspace",
|
|
70
|
-
|
|
92
|
+
d,
|
|
71
93
|
"issues",
|
|
72
94
|
"list"
|
|
73
95
|
] };
|
|
74
|
-
|
|
96
|
+
p.setQueriesData(b, (e) => e && {
|
|
75
97
|
...e,
|
|
76
|
-
issues: e.issues.map((e) => e.id === r.id ?
|
|
98
|
+
issues: e.issues.map((e) => e.id === r.id ? y : e)
|
|
77
99
|
});
|
|
78
100
|
try {
|
|
79
|
-
let
|
|
101
|
+
let a = v ? await i(d, r.identifier, v) : t(await e.PATCH("/api/v1/workspaces/{workspace}/issues/{identifier}", {
|
|
80
102
|
params: { path: {
|
|
81
|
-
workspace:
|
|
103
|
+
workspace: d,
|
|
82
104
|
identifier: r.identifier
|
|
83
105
|
} },
|
|
84
|
-
body:
|
|
106
|
+
body: _ ?? {}
|
|
85
107
|
}));
|
|
86
|
-
|
|
108
|
+
p.setQueryData(n(d, r.identifier).queryKey, a);
|
|
87
109
|
} catch (e) {
|
|
88
|
-
|
|
110
|
+
o.error(m(e));
|
|
89
111
|
} finally {
|
|
90
|
-
|
|
112
|
+
a(p, d, r.identifier);
|
|
91
113
|
}
|
|
92
114
|
}, [
|
|
93
|
-
|
|
94
|
-
u,
|
|
115
|
+
p,
|
|
95
116
|
d,
|
|
96
|
-
|
|
97
|
-
|
|
117
|
+
f,
|
|
118
|
+
h,
|
|
119
|
+
m
|
|
98
120
|
]);
|
|
99
121
|
}
|
|
100
|
-
export {
|
|
122
|
+
export { d as useBoardMove };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { api as e, unwrap as t } from "../api/client.js";
|
|
2
|
+
import { queryOptions as n, useMutation as r, useQueryClient as i } from "@tanstack/react-query";
|
|
3
|
+
// src/lib/customFields.ts
|
|
4
|
+
var a = [
|
|
5
|
+
"text",
|
|
6
|
+
"number",
|
|
7
|
+
"select",
|
|
8
|
+
"multi_select",
|
|
9
|
+
"person",
|
|
10
|
+
"date",
|
|
11
|
+
"checkbox",
|
|
12
|
+
"url"
|
|
13
|
+
], o = [
|
|
14
|
+
"select",
|
|
15
|
+
"multi_select",
|
|
16
|
+
"person",
|
|
17
|
+
"checkbox"
|
|
18
|
+
], s = [
|
|
19
|
+
"number",
|
|
20
|
+
"date",
|
|
21
|
+
"select",
|
|
22
|
+
"text"
|
|
23
|
+
], c = [
|
|
24
|
+
"select",
|
|
25
|
+
"multi_select",
|
|
26
|
+
"person",
|
|
27
|
+
"checkbox"
|
|
28
|
+
], l = (r) => n({
|
|
29
|
+
queryKey: [
|
|
30
|
+
"workspace",
|
|
31
|
+
r,
|
|
32
|
+
"fields"
|
|
33
|
+
],
|
|
34
|
+
queryFn: async ({ signal: n }) => t(await e.GET("/api/v1/workspaces/{workspace}/fields", {
|
|
35
|
+
params: { path: { workspace: r } },
|
|
36
|
+
signal: n
|
|
37
|
+
})).fields
|
|
38
|
+
});
|
|
39
|
+
function u(e, t, n, r = !1) {
|
|
40
|
+
return (e ?? []).filter((e) => e.target === t && (r || !e.archivedAt) && (!e.teamId || n !== void 0 && e.teamId === n)).sort((e, t) => Number(!!e.teamId) - Number(!!t.teamId) || e.position - t.position);
|
|
41
|
+
}
|
|
42
|
+
function d(e, t) {
|
|
43
|
+
return (e ?? []).filter((e) => e.target === "issue" && !e.archivedAt && (!e.teamId || t.includes(e.teamId)));
|
|
44
|
+
}
|
|
45
|
+
var f = (e) => e != null && e !== "" && e !== !1 && !(Array.isArray(e) && e.length === 0);
|
|
46
|
+
function p(e) {
|
|
47
|
+
return (e ?? "").split(",").map((e) => {
|
|
48
|
+
let t = e.indexOf(":");
|
|
49
|
+
return {
|
|
50
|
+
field: e.slice(0, t),
|
|
51
|
+
value: e.slice(t + 1)
|
|
52
|
+
};
|
|
53
|
+
}).filter((e) => e.field && e.value);
|
|
54
|
+
}
|
|
55
|
+
var m = (e) => e.map((e) => `${e.field}:${e.value}`).join(","), h = (e) => e?.startsWith("field:") ? e.slice(6) : void 0;
|
|
56
|
+
function g(n) {
|
|
57
|
+
let a = i(), o = () => a.invalidateQueries({ queryKey: [
|
|
58
|
+
"workspace",
|
|
59
|
+
n,
|
|
60
|
+
"fields"
|
|
61
|
+
] });
|
|
62
|
+
return {
|
|
63
|
+
create: r({
|
|
64
|
+
mutationFn: async (r) => t(await e.POST("/api/v1/workspaces/{workspace}/fields", {
|
|
65
|
+
params: { path: { workspace: n } },
|
|
66
|
+
body: r
|
|
67
|
+
})),
|
|
68
|
+
onSettled: o
|
|
69
|
+
}),
|
|
70
|
+
update: r({
|
|
71
|
+
mutationFn: async ({ id: r, ...i }) => t(await e.PATCH("/api/v1/workspaces/{workspace}/fields/{field}", {
|
|
72
|
+
params: { path: {
|
|
73
|
+
workspace: n,
|
|
74
|
+
field: r
|
|
75
|
+
} },
|
|
76
|
+
body: i
|
|
77
|
+
})),
|
|
78
|
+
onSettled: () => {
|
|
79
|
+
o(), a.invalidateQueries({ queryKey: [
|
|
80
|
+
"workspace",
|
|
81
|
+
n,
|
|
82
|
+
"issues"
|
|
83
|
+
] });
|
|
84
|
+
}
|
|
85
|
+
}),
|
|
86
|
+
remove: r({
|
|
87
|
+
mutationFn: async (r) => t(await e.DELETE("/api/v1/workspaces/{workspace}/fields/{field}", { params: { path: {
|
|
88
|
+
workspace: n,
|
|
89
|
+
field: r
|
|
90
|
+
} } })),
|
|
91
|
+
onSettled: o
|
|
92
|
+
})
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
async function _(n, r, i) {
|
|
96
|
+
return t(await e.PATCH("/api/v1/workspaces/{workspace}/issues/{identifier}/fields", {
|
|
97
|
+
params: { path: {
|
|
98
|
+
workspace: n,
|
|
99
|
+
identifier: r
|
|
100
|
+
} },
|
|
101
|
+
body: { values: i }
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
async function v(n, r, i) {
|
|
105
|
+
return t(await e.PATCH("/api/v1/workspaces/{workspace}/projects/{projectId}/fields", {
|
|
106
|
+
params: { path: {
|
|
107
|
+
workspace: n,
|
|
108
|
+
projectId: r
|
|
109
|
+
} },
|
|
110
|
+
body: { values: i }
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
export { l as customFieldsQuery, a as fieldKinds, h as fieldRef, u as fieldsFor, d as fieldsForTeams, c as filterableKinds, m as formatFieldFilters, o as groupableKinds, f as hasValue, p as parseFieldFilters, _ as setIssueFields, v as setProjectFields, s as sortableKinds, g as useCustomFieldActions };
|
package/lib/issueDisplay.js
CHANGED
|
@@ -1,33 +1,48 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fieldRef as e } from "./customFields.js";
|
|
2
|
+
import { groupings as t, orders as n } from "./issueList.js";
|
|
2
3
|
// src/lib/issueDisplay.ts
|
|
3
|
-
var
|
|
4
|
+
var r = "tandem-issues-panel", i = "tandem-issues-insights", a = "tandem-issues-display", o = [
|
|
4
5
|
"assignees",
|
|
5
6
|
"labels",
|
|
6
7
|
"priority",
|
|
7
8
|
"projects"
|
|
8
9
|
];
|
|
9
|
-
function
|
|
10
|
+
function s() {
|
|
10
11
|
try {
|
|
11
|
-
let
|
|
12
|
+
let r = JSON.parse(localStorage.getItem(a) ?? "{}");
|
|
12
13
|
return {
|
|
13
|
-
...
|
|
14
|
-
...
|
|
15
|
-
...(
|
|
14
|
+
...(n.includes(r.order) || e(r.order)) && { order: r.order },
|
|
15
|
+
...(t.includes(r.group) || e(r.group)) && { group: r.group },
|
|
16
|
+
...(r.layout === "list" || r.layout === "board") && { layout: r.layout }
|
|
16
17
|
};
|
|
17
18
|
} catch {
|
|
18
19
|
return {};
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
|
-
function
|
|
22
|
+
function c(e) {
|
|
22
23
|
try {
|
|
23
|
-
localStorage.setItem(
|
|
24
|
-
...
|
|
24
|
+
localStorage.setItem(a, JSON.stringify({
|
|
25
|
+
...s(),
|
|
25
26
|
...e
|
|
26
27
|
}));
|
|
27
28
|
} catch {}
|
|
28
29
|
}
|
|
29
|
-
function
|
|
30
|
+
function l(e, t, n) {
|
|
30
31
|
let r = { ...e };
|
|
31
32
|
return n === void 0 || n === "" ? delete r[t] : r[t] = n, r;
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
var u = (e) => `tandem-issues-fields:${e}`;
|
|
35
|
+
function d(e) {
|
|
36
|
+
try {
|
|
37
|
+
let t = JSON.parse(localStorage.getItem(u(e)) ?? "[]");
|
|
38
|
+
return Array.isArray(t) ? t.filter((e) => typeof e == "string") : [];
|
|
39
|
+
} catch {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function f(e, t) {
|
|
44
|
+
try {
|
|
45
|
+
localStorage.setItem(u(e), JSON.stringify(t));
|
|
46
|
+
} catch {}
|
|
47
|
+
}
|
|
48
|
+
export { i as insightsKey, o as listTabs, r as panelKey, d as shownFields, c as storeDisplay, f as storeShownFields, s as storedDisplay, l as withParam };
|