@parallelworks/tandem-web 0.138.2 → 0.139.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/components/AgentWork.js +35 -35
- package/components/AppRoot.js +4 -4
- package/components/AreaWork.js +1 -1
- package/components/BlockHandle.js +3 -3
- package/components/CommandPalette.js +27 -27
- package/components/DateChip.js +27 -27
- package/components/DocLinkPicker.js +17 -17
- package/components/Graph.js +6 -6
- package/components/HoverCards.js +30 -29
- package/components/IssueListBlock.js +83 -83
- package/components/LinkCard.js +20 -20
- package/components/MentionPicker.js +12 -12
- package/components/NewIssueDialog.js +116 -116
- package/components/NewProjectDialog.js +5 -4
- package/components/Planning.js +31 -43
- package/components/RouterLink.js +4 -4
- package/components/ShareDialog.js +12 -12
- package/components/SharedUI.js +19 -19
- package/components/SlashMenu.js +11 -11
- package/components/SubPages.js +10 -10
- package/components/UnlinkedMentions.js +10 -10
- package/components/WorkCounts.js +8 -8
- package/components/settings.js +26 -26
- package/hostedApp.js +36 -36
- package/hosting.d.ts +24 -11
- package/index.js +58 -27
- package/lib/base.js +1 -14
- package/lib/docs.js +6 -6
- package/lib/issueMenu.js +33 -33
- package/lib/knowledge.js +90 -101
- package/lib/knowledgeKinds.js +14 -0
- package/lib/projectList.js +1 -1
- package/lib/projectStates.js +15 -0
- package/lib/router.js +20 -34
- package/package.json +2 -2
- package/pages/areas.js +147 -147
- package/pages/decisions.js +40 -40
- package/pages/issues.js +4 -4
- package/pages/projects.js +232 -231
- package/pages/triage.js +86 -86
- package/pages.js +21 -0
- package/routes/__root.js +6 -6
- package/routes/_workspace/docs/_doc2.js +12 -12
- package/routes/_workspace/docs2.js +8 -8
- package/routes/_workspace/graph2.js +9 -9
- package/routes/_workspace/issues/_identifier2.js +327 -327
- package/routes/_workspace/issues/index.js +6 -6
- package/routes/_workspace/knowledge/_term2.js +125 -124
- package/routes/_workspace/knowledge/index.js +8 -8
- package/routes/_workspace/knowledge/index2.js +22 -21
- package/routes/_workspace/measures2.js +4 -4
- package/routes/_workspace/people/_username.js +4 -4
- package/routes/_workspace/projects/_projectId3.js +264 -263
- package/routes/_workspace/projects/index.js +7 -7
- package/routes/_workspace/settings/account2.js +3 -3
- package/routes/_workspace/settings/audit-log2.js +4 -4
- package/routes/_workspace/settings/audit-log3.js +51 -51
- package/routes/_workspace/settings/labels2.js +14 -14
- package/routes/_workspace/settings/members2.js +9 -9
- package/routes/_workspace/settings/runners2.js +11 -11
- package/routes/_workspace/settings/teams2.js +15 -15
- package/routes/_workspace/settings/tokens2.js +5 -5
- package/routes/_workspace/settings/webhooks2.js +7 -7
- package/routes/_workspace/settings2.js +3 -3
- package/routes/_workspace/teams/_key/cycles/_number2.js +8 -8
- package/routes/_workspace/teams/_key/cycles/index2.js +20 -20
- package/routes/_workspace/teams/_key/issues.js +4 -4
- package/routes/_workspace/teams/_key/projects.js +4 -4
- package/routes/_workspace/teams/_key/settings2.js +8 -8
- package/routes/_workspace2.js +319 -319
- package/routes/docs/route2.js +15 -15
package/components/settings.js
CHANGED
|
@@ -3,14 +3,14 @@ import { usePageTitle as t } from "../lib/pageTitle.js";
|
|
|
3
3
|
import { useCan as n } from "../lib/roles.js";
|
|
4
4
|
import { useSettingsPages as r } from "./SettingsNav.js";
|
|
5
5
|
import { Callout as i, PageHeader as a } from "@parallelworks/ui";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
6
|
+
import { useParams as o } from "@tanstack/react-router";
|
|
7
|
+
import { useState as s } from "react";
|
|
8
|
+
import { useErrorMessage as c } from "@parallelworks/problem/react";
|
|
9
|
+
import { useTranslations as l } from "use-intl";
|
|
10
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
11
11
|
// src/components/settings.tsx
|
|
12
12
|
function f() {
|
|
13
|
-
let e =
|
|
13
|
+
let e = c(), [t, n] = s(null);
|
|
14
14
|
return {
|
|
15
15
|
error: t,
|
|
16
16
|
clear: () => n(null),
|
|
@@ -18,50 +18,50 @@ function f() {
|
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
function p(t) {
|
|
21
|
-
let n =
|
|
21
|
+
let n = l("settingsNav"), { workspace: i = "" } = o({ strict: !1 }), a = e(), s = r(), c = [{
|
|
22
22
|
label: n("label"),
|
|
23
23
|
href: `/${i}/settings`
|
|
24
|
-
}],
|
|
25
|
-
for (let e of
|
|
24
|
+
}], u;
|
|
25
|
+
for (let e of s) for (let t of e.items) {
|
|
26
26
|
let n = t.to.replace("$workspace", i);
|
|
27
|
-
(a === n || a.startsWith(`${n}/`)) && n.length > (
|
|
27
|
+
(a === n || a.startsWith(`${n}/`)) && n.length > (u?.href.length ?? 0) && (u = {
|
|
28
28
|
group: e.label,
|
|
29
29
|
label: t.label,
|
|
30
30
|
href: n
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
|
-
return
|
|
34
|
-
label:
|
|
35
|
-
href:
|
|
36
|
-
})),
|
|
33
|
+
return u && (c.push({ label: u.group }), u.label !== t && c.push({
|
|
34
|
+
label: u.label,
|
|
35
|
+
href: u.href
|
|
36
|
+
})), c.push({ label: t }), c;
|
|
37
37
|
}
|
|
38
38
|
function m({ title: e, description: n, wide: r = !1, actions: i, toolbar: o, children: s }) {
|
|
39
|
-
let
|
|
40
|
-
return t(e,
|
|
39
|
+
let c = p(e);
|
|
40
|
+
return t(e, l("workspace")("settings")), /* @__PURE__ */ d("div", {
|
|
41
41
|
className: "flex h-full min-h-0 flex-col",
|
|
42
|
-
children: [/* @__PURE__ */
|
|
43
|
-
breadcrumbs:
|
|
42
|
+
children: [/* @__PURE__ */ u(a, {
|
|
43
|
+
breadcrumbs: c,
|
|
44
44
|
heading: !1,
|
|
45
45
|
actions: i
|
|
46
|
-
}), /* @__PURE__ */
|
|
46
|
+
}), /* @__PURE__ */ d("div", {
|
|
47
47
|
className: "min-h-0 flex-1 overflow-y-auto py-6 md:py-8",
|
|
48
|
-
children: [/* @__PURE__ */
|
|
48
|
+
children: [/* @__PURE__ */ d("header", {
|
|
49
49
|
className: "group/title mb-6 flex flex-wrap items-start gap-x-3 gap-y-2 px-4 max-sm:has-[input]:mb-2",
|
|
50
50
|
children: [
|
|
51
|
-
/* @__PURE__ */
|
|
51
|
+
/* @__PURE__ */ u("h1", {
|
|
52
52
|
className: "min-w-0 flex-[1_1_6rem] text-xl font-semibold tracking-tight group-has-[input]/title:basis-auto",
|
|
53
53
|
children: e
|
|
54
54
|
}),
|
|
55
|
-
o && /* @__PURE__ */
|
|
55
|
+
o && /* @__PURE__ */ u("div", {
|
|
56
56
|
className: "-my-1.5 ml-auto min-w-0 max-w-full max-sm:group-has-[input]/title:order-last max-sm:group-has-[input]/title:mt-2 max-sm:group-has-[input]/title:mb-0 max-sm:group-has-[input]/title:basis-full",
|
|
57
57
|
children: o
|
|
58
58
|
}),
|
|
59
|
-
n && /* @__PURE__ */
|
|
59
|
+
n && /* @__PURE__ */ u("p", {
|
|
60
60
|
className: "-mt-1 basis-full text-sm text-muted-foreground",
|
|
61
61
|
children: n
|
|
62
62
|
})
|
|
63
63
|
]
|
|
64
|
-
}), r ? s : /* @__PURE__ */
|
|
64
|
+
}), r ? s : /* @__PURE__ */ u("div", {
|
|
65
65
|
className: "border-t border-border px-4 pt-6",
|
|
66
66
|
children: s
|
|
67
67
|
})]
|
|
@@ -70,8 +70,8 @@ function m({ title: e, description: n, wide: r = !1, actions: i, toolbar: o, chi
|
|
|
70
70
|
}
|
|
71
71
|
var h = "divide-y divide-border", g = "flex gap-2 border-t border-border px-3 py-2";
|
|
72
72
|
function _({ workspace: e, permission: t = "manage_workspace" }) {
|
|
73
|
-
let r = n(e, t), a =
|
|
74
|
-
return r ? null : /* @__PURE__ */
|
|
73
|
+
let r = n(e, t), a = l("settings");
|
|
74
|
+
return r ? null : /* @__PURE__ */ u(i, {
|
|
75
75
|
tone: "muted",
|
|
76
76
|
className: "mb-6",
|
|
77
77
|
children: a("adminOnly")
|
package/hostedApp.js
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
1
|
+
import { SharedUI as e } from "./components/SharedUI.js";
|
|
2
|
+
import { loadMessages as t, locales as n } from "./_virtual/_virtual_i18n.js";
|
|
3
|
+
import { HostProvider as r } from "./lib/host.js";
|
|
4
|
+
import { setShownPath as i } from "./lib/listSearch.js";
|
|
5
|
+
import { useRouter as a } from "@tanstack/react-router";
|
|
6
|
+
import { use as o, useEffect as s, useRef as c } from "react";
|
|
7
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
8
|
+
import { LocaleProvider as d, useSetLocale as f } from "@parallelworks/i18n/react";
|
|
9
|
+
import { QueryClientProvider as p } from "@tanstack/react-query";
|
|
10
10
|
// src/hostedApp.tsx
|
|
11
|
-
function m({ host:
|
|
12
|
-
return /* @__PURE__ */
|
|
13
|
-
host:
|
|
14
|
-
children: /* @__PURE__ */
|
|
15
|
-
locale:
|
|
16
|
-
children: /* @__PURE__ */
|
|
11
|
+
function m({ host: t, queryClient: n, children: i }) {
|
|
12
|
+
return /* @__PURE__ */ l(r, {
|
|
13
|
+
host: t,
|
|
14
|
+
children: /* @__PURE__ */ l(v, {
|
|
15
|
+
locale: t.locale,
|
|
16
|
+
children: /* @__PURE__ */ u(p, {
|
|
17
17
|
client: n,
|
|
18
18
|
children: [
|
|
19
|
-
/* @__PURE__ */
|
|
20
|
-
identity:
|
|
19
|
+
/* @__PURE__ */ l(b, {
|
|
20
|
+
identity: t.identity,
|
|
21
21
|
queryClient: n
|
|
22
22
|
}),
|
|
23
|
-
/* @__PURE__ */
|
|
24
|
-
/* @__PURE__ */
|
|
25
|
-
/* @__PURE__ */
|
|
23
|
+
/* @__PURE__ */ l(x, {}),
|
|
24
|
+
/* @__PURE__ */ l(S, {}),
|
|
25
|
+
/* @__PURE__ */ l(e, { children: /* @__PURE__ */ l("div", {
|
|
26
26
|
className: "tandem flex h-full min-h-0 flex-col",
|
|
27
|
-
children:
|
|
27
|
+
children: i
|
|
28
28
|
}) })
|
|
29
29
|
]
|
|
30
30
|
})
|
|
@@ -33,40 +33,40 @@ function m({ host: e, queryClient: n, children: r }) {
|
|
|
33
33
|
}
|
|
34
34
|
var h = /* @__PURE__ */ new Map();
|
|
35
35
|
function g(e) {
|
|
36
|
-
let
|
|
37
|
-
return
|
|
36
|
+
let n = h.get(e);
|
|
37
|
+
return n || (n = t(e).catch(() => t("en")), h.set(e, n)), n;
|
|
38
38
|
}
|
|
39
|
-
var _ = (e) =>
|
|
40
|
-
function v({ locale: e, children:
|
|
41
|
-
let r =
|
|
42
|
-
return /* @__PURE__ */
|
|
39
|
+
var _ = (e) => n.includes(e) ? e : "en";
|
|
40
|
+
function v({ locale: e, children: n }) {
|
|
41
|
+
let r = c(_(e)), i = o(g(r.current));
|
|
42
|
+
return /* @__PURE__ */ u(d, {
|
|
43
43
|
initial: {
|
|
44
44
|
locale: r.current,
|
|
45
45
|
messages: i
|
|
46
46
|
},
|
|
47
|
-
load:
|
|
47
|
+
load: t,
|
|
48
48
|
fallbackLocale: "en",
|
|
49
|
-
children: [/* @__PURE__ */
|
|
49
|
+
children: [/* @__PURE__ */ l(y, { locale: _(e) }), n]
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
function y({ locale: e }) {
|
|
53
|
-
let t =
|
|
54
|
-
return
|
|
53
|
+
let t = f();
|
|
54
|
+
return s(() => {
|
|
55
55
|
t(e);
|
|
56
56
|
}, [e, t]), null;
|
|
57
57
|
}
|
|
58
58
|
function b({ identity: e, queryClient: t }) {
|
|
59
|
-
let n =
|
|
60
|
-
return
|
|
59
|
+
let n = c(e);
|
|
60
|
+
return s(() => {
|
|
61
61
|
n.current !== e && t.clear(), n.current = e;
|
|
62
62
|
}, [e, t]), null;
|
|
63
63
|
}
|
|
64
64
|
function x() {
|
|
65
|
-
let
|
|
66
|
-
return
|
|
65
|
+
let e = a();
|
|
66
|
+
return s(() => (i(e.state.location.pathname), e.subscribe("onResolved", ({ toLocation: e }) => i(e.pathname))), [e]), null;
|
|
67
67
|
}
|
|
68
68
|
function S() {
|
|
69
|
-
return
|
|
69
|
+
return s(() => (document.body.dataset.tandem = "", () => {
|
|
70
70
|
delete document.body.dataset.tandem;
|
|
71
71
|
}), []), null;
|
|
72
72
|
}
|
package/hosting.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnyRoute, LocationRewrite } from '@tanstack/react-router';
|
|
1
|
+
import type { AnyRoute, AnyRouter, LocationRewrite } from '@tanstack/react-router';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
/** Something the host offers from anywhere in Tandem, such as opening a terminal. */
|
|
4
4
|
export interface HostControl {
|
|
@@ -15,7 +15,7 @@ export interface HostControl {
|
|
|
15
15
|
* follows and whose menu button it shows on a phone.
|
|
16
16
|
*/
|
|
17
17
|
export interface TandemHost {
|
|
18
|
-
/** Who is signed in. When it changes, Tandem forgets what it loaded for anyone else. */
|
|
18
|
+
/** Who is signed in, or "" for no one. When it changes, Tandem forgets what it loaded for anyone else. */
|
|
19
19
|
identity: string;
|
|
20
20
|
/** The language the host shows, one of Tandem's or else Tandem's default. */
|
|
21
21
|
locale: string;
|
|
@@ -34,19 +34,32 @@ export interface Tandem {
|
|
|
34
34
|
mountPath: string;
|
|
35
35
|
/** Whether pathname is under mountPath. */
|
|
36
36
|
contains: (pathname: string) => boolean;
|
|
37
|
-
/**
|
|
38
|
-
* Whether pathname is one of the pages the host renders. Tandem's own pages,
|
|
39
|
-
* such as sign-in and share links, are full page loads from Tandem's server.
|
|
40
|
-
*/
|
|
37
|
+
/** Whether pathname is one of Tandem's pages, rather than its server's API or files. */
|
|
41
38
|
hosts: (pathname: string) => boolean;
|
|
42
39
|
/**
|
|
43
|
-
* The options for the
|
|
44
|
-
* not-found pages stay inside
|
|
45
|
-
* host's frame around
|
|
40
|
+
* The options for the two routes mount takes. Their pending, error and
|
|
41
|
+
* not-found pages stay inside them, so nothing Tandem does reaches the
|
|
42
|
+
* host's frame around them.
|
|
46
43
|
*/
|
|
47
44
|
route: Pick<AnyRoute['options'], 'beforeLoad' | 'pendingComponent' | 'errorComponent' | 'notFoundComponent'>;
|
|
48
|
-
/**
|
|
49
|
-
|
|
45
|
+
/**
|
|
46
|
+
* The options for the host's route at mountPath + "/$" under the frameless
|
|
47
|
+
* route. It stands for all of Tandem's pages until one is opened, so the
|
|
48
|
+
* host's first page load carries none of their routes; opening one loads
|
|
49
|
+
* them, adds them to the router and opens the same address again. After,
|
|
50
|
+
* it's the not-found page for addresses none of them matches.
|
|
51
|
+
*/
|
|
52
|
+
placeholder: Pick<AnyRoute['options'], 'beforeLoad' | 'pendingComponent'>;
|
|
53
|
+
/**
|
|
54
|
+
* Says where Tandem's pages go, before the router is created: framed is the
|
|
55
|
+
* host's route at mountPath, in its frame and behind its sign-in; frameless
|
|
56
|
+
* is a pathless route of the host's with neither, for the pages that fill
|
|
57
|
+
* the window, such as sign-in and share links. Both render Provider around
|
|
58
|
+
* their outlet.
|
|
59
|
+
*/
|
|
60
|
+
mount: (framed: AnyRoute, frameless: AnyRoute) => void;
|
|
61
|
+
/** Lets Tandem add its pages to the host's router when they load. Call it once the router is created. */
|
|
62
|
+
connect: (router: AnyRouter) => void;
|
|
50
63
|
/**
|
|
51
64
|
* Writes an issue's address with its title, and reads it back. Give it to
|
|
52
65
|
* the host's router; it leaves every path outside mountPath alone.
|
package/index.js
CHANGED
|
@@ -1,45 +1,70 @@
|
|
|
1
|
-
import { appPath as e, mountAt as t, routerBase as n
|
|
2
|
-
import { ErrorMessage as
|
|
3
|
-
import { issueAddresses as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { appPath as e, mountAt as t, routerBase as n } from "./lib/base.js";
|
|
2
|
+
import { ErrorMessage as r, Pending as i } from "./components/status.js";
|
|
3
|
+
import { issueAddresses as a } from "./lib/branch.js";
|
|
4
|
+
import { ErrorPage as o } from "@parallelworks/ui";
|
|
5
|
+
import { notFound as s, redirect as c } from "@tanstack/react-router";
|
|
6
6
|
import { lazy as l, use as u } from "react";
|
|
7
7
|
import { jsx as d } from "react/jsx-runtime";
|
|
8
8
|
// src/integration.tsx
|
|
9
9
|
var f = l(() => import("./hostedApp.js")), p = /* @__PURE__ */ new Set([
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
10
|
+
"api",
|
|
11
|
+
"auth",
|
|
12
|
+
".well-known",
|
|
13
|
+
"jwks",
|
|
14
|
+
"token",
|
|
15
|
+
"revoke",
|
|
16
|
+
"healthz",
|
|
17
|
+
"readyz",
|
|
18
|
+
"problems"
|
|
14
19
|
]);
|
|
15
20
|
function m({ mountPath: l }) {
|
|
16
21
|
t(l);
|
|
17
|
-
let m,
|
|
22
|
+
let m, g = () => (m ||= import("./lib/queryClient.js").then((e) => e.createQueryClient()), m), v, y, b, x = !1, S = async (e) => {
|
|
23
|
+
let t = v, r = y;
|
|
24
|
+
throw !t || !r ? Error("Tandem: call mount and connect before opening a page") : (b ??= import("./pages.js").then(({ splitPages: e }) => {
|
|
25
|
+
let i = e();
|
|
26
|
+
for (let e of i.frameless) Object.assign(e.options, { path: n + e.options.path });
|
|
27
|
+
h(r.framed, i.framed), h(r.frameless, i.frameless), t.setRoutes(t.buildRouteTree()), x = !0;
|
|
28
|
+
}), await b, c({
|
|
29
|
+
href: e,
|
|
30
|
+
replace: !0
|
|
31
|
+
}));
|
|
32
|
+
};
|
|
18
33
|
return {
|
|
19
34
|
mountPath: n,
|
|
20
|
-
contains:
|
|
21
|
-
hosts: (t) =>
|
|
35
|
+
contains: _,
|
|
36
|
+
hosts: (t) => _(t) && !p.has(e(t).split("/")[1] ?? ""),
|
|
22
37
|
route: {
|
|
23
|
-
beforeLoad: async () => ({ queryClient: await
|
|
24
|
-
pendingComponent:
|
|
25
|
-
errorComponent: ({ error: e }) => /* @__PURE__ */ d(
|
|
38
|
+
beforeLoad: async ({ location: e }) => (x || await S(e.href), { queryClient: await g() }),
|
|
39
|
+
pendingComponent: i,
|
|
40
|
+
errorComponent: ({ error: e }) => /* @__PURE__ */ d(r, { error: e }),
|
|
26
41
|
notFoundComponent: (e) => /* @__PURE__ */ d("div", {
|
|
27
42
|
className: "flex h-full",
|
|
28
|
-
children: /* @__PURE__ */ d(
|
|
43
|
+
children: /* @__PURE__ */ d(o, { status: 404 })
|
|
29
44
|
})
|
|
30
45
|
},
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
46
|
+
placeholder: {
|
|
47
|
+
beforeLoad: async ({ location: e }) => {
|
|
48
|
+
if (x) throw s();
|
|
49
|
+
await S(e.href);
|
|
50
|
+
},
|
|
51
|
+
pendingComponent: i
|
|
52
|
+
},
|
|
53
|
+
mount(e, t) {
|
|
54
|
+
y = {
|
|
55
|
+
framed: e,
|
|
56
|
+
frameless: t
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
connect(e) {
|
|
60
|
+
v = e;
|
|
36
61
|
},
|
|
37
62
|
rewrite: {
|
|
38
|
-
input: (e) =>
|
|
39
|
-
output: (e) =>
|
|
63
|
+
input: (e) => _(e.url.pathname) ? a.input?.(e) : void 0,
|
|
64
|
+
output: (e) => _(e.url.pathname) ? a.output?.(e) : void 0
|
|
40
65
|
},
|
|
41
66
|
Provider({ host: e, children: t }) {
|
|
42
|
-
let n = u(
|
|
67
|
+
let n = u(g());
|
|
43
68
|
return /* @__PURE__ */ d(f, {
|
|
44
69
|
host: e,
|
|
45
70
|
queryClient: n,
|
|
@@ -48,8 +73,14 @@ function m({ mountPath: l }) {
|
|
|
48
73
|
}
|
|
49
74
|
};
|
|
50
75
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
76
|
+
function h(e, t) {
|
|
77
|
+
for (let n of t) Object.assign(n.options, { getParentRoute: () => e });
|
|
78
|
+
e.addChildren([...g(e), ...t]), v(t, (e) => {
|
|
79
|
+
e.options.preloadStaleTime ??= 0, e.options.pendingComponent ??= i, e.options.errorComponent ??= ({ error: e }) => /* @__PURE__ */ d(r, { error: e });
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
var g = (e) => Array.isArray(e.children) ? e.children : Object.values(e.children ?? {}), _ = (e) => e === n || e.startsWith(`${n}/`);
|
|
83
|
+
function v(e, t) {
|
|
84
|
+
for (let n of e) t(n), n.children && v(g(n), t);
|
|
54
85
|
}
|
|
55
86
|
export { m as createTandem };
|
package/lib/base.js
CHANGED
|
@@ -15,17 +15,4 @@ function i(e) {
|
|
|
15
15
|
function a(t) {
|
|
16
16
|
return window.location.origin + e + t;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
"login",
|
|
20
|
-
"device",
|
|
21
|
-
"docs",
|
|
22
|
-
"request",
|
|
23
|
-
"share",
|
|
24
|
-
"sites"
|
|
25
|
-
];
|
|
26
|
-
function s(e) {
|
|
27
|
-
if (!t) return !1;
|
|
28
|
-
let n = e.split(/[/?#]/)[1] ?? "";
|
|
29
|
-
return o.includes(n);
|
|
30
|
-
}
|
|
31
|
-
export { i as appPath, a as appURL, e as basePath, n as mountAt, o as ownPages, t as routerBase, r as routerPath, s as servedByTandem };
|
|
18
|
+
export { i as appPath, a as appURL, e as basePath, n as mountAt, t as routerBase, r as routerPath };
|
package/lib/docs.js
CHANGED
|
@@ -2,8 +2,8 @@ import { appURL as e, basePath as t } from "./base.js";
|
|
|
2
2
|
import { api as n, unwrap as r } from "../api/client.js";
|
|
3
3
|
import { useNavigate as i } from "./router.js";
|
|
4
4
|
import { docsQuery as a, teamsQuery as o } from "../api/queries.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { useFavorites as s } from "./favorites.js";
|
|
6
|
+
import { copyItem as c, useLinkItems as l } from "./menus.js";
|
|
7
7
|
import { openShare as u } from "./share.js";
|
|
8
8
|
import { menuDivider as d } from "@parallelworks/ui";
|
|
9
9
|
import { useCallback as f } from "react";
|
|
@@ -138,9 +138,9 @@ function b(e) {
|
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
140
|
function x(e) {
|
|
141
|
-
let t = i(), n = p("docs"), r = p("common"), m = p("favorites"), g =
|
|
141
|
+
let t = i(), n = p("docs"), r = p("common"), m = p("favorites"), g = l(), v = s(e), x = b(e), { data: S = [] } = h(o(e)), { data: w = [] } = h(a(e, { top: !0 }));
|
|
142
142
|
return f((i, { onRename: a } = {}) => {
|
|
143
|
-
let o = S.find((e) => e.id === i.teamId),
|
|
143
|
+
let o = S.find((e) => e.id === i.teamId), s = o?.key ?? "workspace", l = {
|
|
144
144
|
label: r("open"),
|
|
145
145
|
onClick: () => t({
|
|
146
146
|
to: "/$workspace/docs/$doc",
|
|
@@ -149,7 +149,7 @@ function x(e) {
|
|
|
149
149
|
doc: _(i)
|
|
150
150
|
}
|
|
151
151
|
})
|
|
152
|
-
}, f = [...g(y(e, i)),
|
|
152
|
+
}, f = [...g(y(e, i)), c(n("copyKey"), i.key)];
|
|
153
153
|
if (i.archivedAt) return [
|
|
154
154
|
l,
|
|
155
155
|
{
|
|
@@ -187,7 +187,7 @@ function x(e) {
|
|
|
187
187
|
label: n("moveTo"),
|
|
188
188
|
items: [
|
|
189
189
|
...h.map((e) => {
|
|
190
|
-
let t = !i.parentId && e.key ===
|
|
190
|
+
let t = !i.parentId && e.key === s;
|
|
191
191
|
return {
|
|
192
192
|
label: n("topOf", { space: e.name }),
|
|
193
193
|
checked: t,
|
package/lib/issueMenu.js
CHANGED
|
@@ -3,12 +3,12 @@ import { api as t, unwrap as n } from "../api/client.js";
|
|
|
3
3
|
import { branchName as r, issuePath as i } from "./branch.js";
|
|
4
4
|
import { useNavigate as a } from "./router.js";
|
|
5
5
|
import { cyclesQuery as o, issueQuery as s, labelsQuery as c, projectsQuery as l, statusesQuery as u, teamsQuery as d } from "../api/queries.js";
|
|
6
|
-
import { CalendarIcon as f, CycleIcon as
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
6
|
+
import { CalendarIcon as f, CycleIcon as p, EstimateIcon as ee, FolderIcon as te, PriorityIcon as m, ProjectIcon as h, StatusIcon as g, TagIcon as _, UserIcon as v, usePriorityNames as y } from "../components/icons.js";
|
|
7
|
+
import { useFavorites as b } from "./favorites.js";
|
|
8
|
+
import { copyItem as x } from "./menus.js";
|
|
9
|
+
import { invalidateIssueViews as S } from "../api/mutations.js";
|
|
10
|
+
import { addDays as C, today as w } from "./time.js";
|
|
11
|
+
import { ProjectStatusIcon as T, scalePoints as E, useEstimateLabel as D } from "../components/Planning.js";
|
|
12
12
|
import { assigneeKey as O, parseAssigneeKey as k, useAssigneeOptions as A } from "./assignees.js";
|
|
13
13
|
import { menuDivider as j } from "@parallelworks/ui";
|
|
14
14
|
import { useCallback as M } from "react";
|
|
@@ -20,7 +20,7 @@ function R(t, n) {
|
|
|
20
20
|
return e(i(t, n));
|
|
21
21
|
}
|
|
22
22
|
function z(e) {
|
|
23
|
-
let i = L(), z = a(), { data: B = [] } = I(d(e)), { data: V = [] } = I(c(e)), H = A(e), U =
|
|
23
|
+
let i = L(), z = a(), { data: B = [] } = I(d(e)), { data: V = [] } = I(c(e)), H = A(e), U = b(e), W = y(), G = N("issueMenu"), K = N("common"), q = N("favorites"), J = F({ queries: B.map((t) => u(e, t.key)) }), Y = N("planning"), X = D(), { data: Z = [] } = I(l(e)), Q = F({ queries: B.map((t) => ({
|
|
24
24
|
...o(e, t.key),
|
|
25
25
|
enabled: t.cyclesEnabled
|
|
26
26
|
})) });
|
|
@@ -41,7 +41,7 @@ function z(e) {
|
|
|
41
41
|
} },
|
|
42
42
|
body: o
|
|
43
43
|
}));
|
|
44
|
-
i.setQueryData(s(e, a.identifier).queryKey, c),
|
|
44
|
+
i.setQueryData(s(e, a.identifier).queryKey, c), S(i, e, a.identifier);
|
|
45
45
|
}));
|
|
46
46
|
}, d = async (r) => {
|
|
47
47
|
await Promise.all(a.filter((e) => e.identifier.split("-")[0] !== r).map(async (a) => {
|
|
@@ -52,7 +52,7 @@ function z(e) {
|
|
|
52
52
|
} },
|
|
53
53
|
body: { team: r }
|
|
54
54
|
}));
|
|
55
|
-
i.setQueryData(s(e, o.identifier).queryKey, o),
|
|
55
|
+
i.setQueryData(s(e, o.identifier).queryKey, o), S(i, e, a.identifier), window.location.pathname.toLowerCase().includes(a.identifier.toLowerCase()) && z({
|
|
56
56
|
to: "/$workspace/issues/$identifier",
|
|
57
57
|
params: {
|
|
58
58
|
workspace: e,
|
|
@@ -67,35 +67,35 @@ function z(e) {
|
|
|
67
67
|
workspace: e,
|
|
68
68
|
identifier: a.identifier
|
|
69
69
|
} } }, c = n(r ? await t.POST("/api/v1/workspaces/{workspace}/issues/{identifier}/archive", o) : await t.POST("/api/v1/workspaces/{workspace}/issues/{identifier}/restore", o));
|
|
70
|
-
i.setQueryData(s(e, a.identifier).queryKey, c),
|
|
70
|
+
i.setQueryData(s(e, a.identifier).queryKey, c), S(i, e, a.identifier);
|
|
71
71
|
}));
|
|
72
|
-
},
|
|
72
|
+
}, b = (e, t) => {
|
|
73
73
|
let n = c(t.teamId);
|
|
74
74
|
return (n.find((t) => t.name === e.name) ?? n.find((t) => t.category === e.category))?.id;
|
|
75
|
-
},
|
|
75
|
+
}, D = a.length === 1, A = l((e) => e.teamId === o.teamId) ? B.findIndex((e) => e.id === o.teamId) : -1, M = B[A], N = (M?.cyclesEnabled ? Q[A]?.data ?? [] : []).filter((e) => e.state !== "past"), F = M?.estimateScale ?? "none", I = l((e) => e.project?.id === o.project?.id) ? o.project?.id : void 0, L = Z.find((e) => e.id === I)?.milestones ?? [], ne = (e) => e.name ? Y("cycleNamed", {
|
|
76
76
|
number: e.number,
|
|
77
77
|
name: e.name
|
|
78
|
-
}) : Y("cycle", { number: e.number }), $ =
|
|
78
|
+
}) : Y("cycle", { number: e.number }), $ = w(), re = [
|
|
79
79
|
{
|
|
80
80
|
label: Y("dueToday"),
|
|
81
81
|
date: $
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
label: Y("dueTomorrow"),
|
|
85
|
-
date:
|
|
85
|
+
date: C($, 1)
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
label: Y("dueInAWeek"),
|
|
89
|
-
date:
|
|
89
|
+
date: C($, 7)
|
|
90
90
|
},
|
|
91
91
|
{
|
|
92
92
|
label: Y("dueInTwoWeeks"),
|
|
93
|
-
date:
|
|
93
|
+
date: C($, 14)
|
|
94
94
|
}
|
|
95
95
|
], ie = [
|
|
96
96
|
{
|
|
97
97
|
label: Y("project"),
|
|
98
|
-
icon: /* @__PURE__ */ P(
|
|
98
|
+
icon: /* @__PURE__ */ P(h, { className: "size-4" }),
|
|
99
99
|
disabled: Z.length === 0,
|
|
100
100
|
items: [{
|
|
101
101
|
label: Y("noProject"),
|
|
@@ -103,7 +103,7 @@ function z(e) {
|
|
|
103
103
|
onClick: () => u((e) => e.project ? { projectId: "" } : null)
|
|
104
104
|
}, ...Z.map((e) => ({
|
|
105
105
|
label: e.name,
|
|
106
|
-
icon: /* @__PURE__ */ P(
|
|
106
|
+
icon: /* @__PURE__ */ P(T, { status: e.status }),
|
|
107
107
|
checked: l((t) => t.project?.id === e.id),
|
|
108
108
|
onClick: () => u((t) => t.project?.id === e.id ? null : { projectId: e.id })
|
|
109
109
|
}))]
|
|
@@ -122,7 +122,7 @@ function z(e) {
|
|
|
122
122
|
}] : [],
|
|
123
123
|
...M?.cyclesEnabled ? [{
|
|
124
124
|
label: Y("cycleLabel"),
|
|
125
|
-
icon: /* @__PURE__ */ P(
|
|
125
|
+
icon: /* @__PURE__ */ P(p, { className: "size-4" }),
|
|
126
126
|
items: [{
|
|
127
127
|
label: Y("noCycle"),
|
|
128
128
|
checked: l((e) => !e.cycle),
|
|
@@ -138,8 +138,8 @@ function z(e) {
|
|
|
138
138
|
}] : [],
|
|
139
139
|
...F === "none" ? [] : [{
|
|
140
140
|
label: Y("estimate"),
|
|
141
|
-
icon: /* @__PURE__ */ P(
|
|
142
|
-
items: [0, ...
|
|
141
|
+
icon: /* @__PURE__ */ P(ee, { className: "size-4" }),
|
|
142
|
+
items: [0, ...E(F)].map((e) => ({
|
|
143
143
|
label: e ? X(e, F) : Y("noEstimate"),
|
|
144
144
|
checked: l((t) => (t.estimate ?? 0) === e),
|
|
145
145
|
onClick: () => u((t) => (t.estimate ?? 0) === e ? null : { estimate: e })
|
|
@@ -166,21 +166,21 @@ function z(e) {
|
|
|
166
166
|
return [
|
|
167
167
|
{
|
|
168
168
|
label: K("status"),
|
|
169
|
-
icon: /* @__PURE__ */ P(
|
|
169
|
+
icon: /* @__PURE__ */ P(g, { category: o.status.category }),
|
|
170
170
|
shortcut: "S",
|
|
171
171
|
items: c(o.teamId).map((e) => ({
|
|
172
172
|
label: e.name,
|
|
173
|
-
icon: /* @__PURE__ */ P(
|
|
173
|
+
icon: /* @__PURE__ */ P(g, { category: e.category }),
|
|
174
174
|
checked: l((t) => t.status.name === e.name),
|
|
175
175
|
onClick: () => u((t) => {
|
|
176
|
-
let n =
|
|
176
|
+
let n = b(e, t);
|
|
177
177
|
return n && n !== t.status.id ? { statusId: n } : null;
|
|
178
178
|
})
|
|
179
179
|
}))
|
|
180
180
|
},
|
|
181
181
|
{
|
|
182
182
|
label: K("priority"),
|
|
183
|
-
icon: /* @__PURE__ */ P(
|
|
183
|
+
icon: /* @__PURE__ */ P(m, { priority: o.priority }),
|
|
184
184
|
shortcut: "P",
|
|
185
185
|
items: [
|
|
186
186
|
1,
|
|
@@ -190,7 +190,7 @@ function z(e) {
|
|
|
190
190
|
0
|
|
191
191
|
].map((e) => ({
|
|
192
192
|
label: W[e] ?? "",
|
|
193
|
-
icon: /* @__PURE__ */ P(
|
|
193
|
+
icon: /* @__PURE__ */ P(m, { priority: e }),
|
|
194
194
|
checked: l((t) => t.priority === e),
|
|
195
195
|
onClick: () => u((t) => t.priority === e ? null : { priority: e })
|
|
196
196
|
}))
|
|
@@ -211,7 +211,7 @@ function z(e) {
|
|
|
211
211
|
},
|
|
212
212
|
{
|
|
213
213
|
label: K("labels"),
|
|
214
|
-
icon: /* @__PURE__ */ P(
|
|
214
|
+
icon: /* @__PURE__ */ P(_, {}),
|
|
215
215
|
shortcut: "L",
|
|
216
216
|
disabled: V.length === 0,
|
|
217
217
|
items: V.map((e) => {
|
|
@@ -230,7 +230,7 @@ function z(e) {
|
|
|
230
230
|
...ie,
|
|
231
231
|
{
|
|
232
232
|
label: G("moveToTeam"),
|
|
233
|
-
icon: /* @__PURE__ */ P(
|
|
233
|
+
icon: /* @__PURE__ */ P(te, {}),
|
|
234
234
|
disabled: B.length < 2,
|
|
235
235
|
items: B.filter((e) => !e.archivedAt).map((e) => ({
|
|
236
236
|
label: e.name,
|
|
@@ -239,7 +239,7 @@ function z(e) {
|
|
|
239
239
|
}))
|
|
240
240
|
},
|
|
241
241
|
j,
|
|
242
|
-
...
|
|
242
|
+
...D ? [
|
|
243
243
|
{
|
|
244
244
|
label: K("open"),
|
|
245
245
|
onClick: () => z({
|
|
@@ -257,10 +257,10 @@ function z(e) {
|
|
|
257
257
|
},
|
|
258
258
|
j
|
|
259
259
|
] : [],
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
...
|
|
263
|
-
...
|
|
260
|
+
x(G("copyLinks", { count: a.length }), a.map((t) => R(e, t.identifier)).join("\n")),
|
|
261
|
+
x(G("copyIds", { count: a.length }), a.map((e) => e.identifier).join(", ")),
|
|
262
|
+
...D ? [x(G("copyTitle"), o.title), x(G("copyBranch"), r(o.identifier, o.title))] : [],
|
|
263
|
+
...D ? [j, {
|
|
264
264
|
label: U.find("issue", o.id) ? q("remove") : q("add"),
|
|
265
265
|
onClick: () => U.toggle("issue", o.id)
|
|
266
266
|
}] : [],
|