@burdenoff/microfe-planmagnet 2026.1001.6 → 2026.1001.8

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.
Files changed (94) hide show
  1. package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
  2. package/dist/planmagnet/PlanMagnetRoutes.js +10 -6
  3. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  4. package/dist/planmagnet/automation/automationRuleTypes.d.ts +31 -19
  5. package/dist/planmagnet/automation/automationRuleTypes.d.ts.map +1 -1
  6. package/dist/planmagnet/automation/automationRuleTypes.js +4 -8
  7. package/dist/planmagnet/automation/automationRuleTypes.js.map +1 -1
  8. package/dist/planmagnet/controls/FeatureControls.d.ts +18 -1
  9. package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -1
  10. package/dist/planmagnet/controls/FeatureControls.js +259 -202
  11. package/dist/planmagnet/controls/FeatureControls.js.map +1 -1
  12. package/dist/planmagnet/controls/FeedbackControls.d.ts +70 -0
  13. package/dist/planmagnet/controls/FeedbackControls.d.ts.map +1 -0
  14. package/dist/planmagnet/controls/FeedbackControls.js +153 -0
  15. package/dist/planmagnet/controls/FeedbackControls.js.map +1 -0
  16. package/dist/planmagnet/controls/SyncControls.d.ts.map +1 -1
  17. package/dist/planmagnet/controls/SyncControls.js +1 -0
  18. package/dist/planmagnet/controls/SyncControls.js.map +1 -1
  19. package/dist/planmagnet/controls/WebhookSubscriptionControls.d.ts +47 -0
  20. package/dist/planmagnet/controls/WebhookSubscriptionControls.d.ts.map +1 -0
  21. package/dist/planmagnet/controls/WebhookSubscriptionControls.js +542 -0
  22. package/dist/planmagnet/controls/WebhookSubscriptionControls.js.map +1 -0
  23. package/dist/planmagnet/dashboards/DashboardUI.js +7 -7
  24. package/dist/planmagnet/dashboards/cards/RiskSeverityCard.js +4 -4
  25. package/dist/planmagnet/forecast/DeliveryForecastCard.js +8 -8
  26. package/dist/planmagnet/forecast/ProjectOutlookCard.js +10 -10
  27. package/dist/planmagnet/forecast/ProjectRiskSummaryCard.js +9 -9
  28. package/dist/planmagnet/forecast/ResourceForecastCard.js +6 -6
  29. package/dist/planmagnet/hooks/useLiveRefresh.d.ts +33 -2
  30. package/dist/planmagnet/hooks/useLiveRefresh.d.ts.map +1 -1
  31. package/dist/planmagnet/hooks/useLiveRefresh.js +71 -42
  32. package/dist/planmagnet/hooks/useLiveRefresh.js.map +1 -1
  33. package/dist/planmagnet/integrations/syncTypes.d.ts +2 -1
  34. package/dist/planmagnet/integrations/syncTypes.d.ts.map +1 -1
  35. package/dist/planmagnet/integrations/syncTypes.js +19 -9
  36. package/dist/planmagnet/integrations/syncTypes.js.map +1 -1
  37. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +8 -8
  38. package/dist/planmagnet/pages/DashboardDashboardPagePage.js +23 -23
  39. package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
  40. package/dist/planmagnet/pages/DocsDocDetailPagePage.js +340 -248
  41. package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
  42. package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.d.ts.map +1 -1
  43. package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js +172 -167
  44. package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js.map +1 -1
  45. package/dist/planmagnet/pages/IntegrationsSyncsPagePage.d.ts.map +1 -1
  46. package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js +92 -83
  47. package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js.map +1 -1
  48. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.d.ts +2 -0
  49. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.d.ts.map +1 -0
  50. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js +175 -0
  51. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js.map +1 -0
  52. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
  53. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +151 -126
  54. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
  55. package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +1 -1
  56. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +136 -129
  57. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js.map +1 -1
  58. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
  59. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +149 -119
  60. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
  61. package/dist/planmagnet/pages/ProductsProductsPagePage.js +13 -13
  62. package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.d.ts.map +1 -1
  63. package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js +153 -117
  64. package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js.map +1 -1
  65. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
  66. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +173 -138
  67. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
  68. package/dist/planmagnet/pages/ProjectsAtRiskPagePage.js +9 -9
  69. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +8 -8
  70. package/dist/planmagnet/pages/ProjectsProjectsPagePage.js +12 -12
  71. package/dist/planmagnet/pages/ReportsReportsPagePage.js +23 -23
  72. package/dist/planmagnet/pages/TasksMyDashboardPagePage.js +18 -18
  73. package/dist/planmagnet/pages/TasksMyWorkPagePage.js +10 -10
  74. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js +5 -5
  75. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +8 -8
  76. package/dist/planmagnet/pages/analytics/DeliveryKpisCard.js +6 -6
  77. package/dist/planmagnet/pages/analytics/MetricsCard.js +6 -6
  78. package/dist/planmagnet/pages/analytics/QualityMetricsCard.js +6 -6
  79. package/dist/planmagnet/pages/analytics/SprintDeliveryCards.js +8 -8
  80. package/dist/planmagnet/pages/analytics/StatusFlowCard.js +7 -7
  81. package/dist/planmagnet/pages/analytics/ThroughputCard.js +7 -7
  82. package/dist/planmagnet/pages/analytics/WorkBreakdownCard.js +7 -7
  83. package/dist/planmagnet/people/People.d.ts +14 -0
  84. package/dist/planmagnet/people/People.d.ts.map +1 -1
  85. package/dist/planmagnet/people/People.js +36 -22
  86. package/dist/planmagnet/people/People.js.map +1 -1
  87. package/dist/planmagnet/roadmaps/RoadmapNowNextLater.d.ts.map +1 -1
  88. package/dist/planmagnet/roadmaps/RoadmapNowNextLater.js +171 -153
  89. package/dist/planmagnet/roadmaps/RoadmapNowNextLater.js.map +1 -1
  90. package/dist/planmagnet/webhooks/webhookTypes.d.ts +54 -0
  91. package/dist/planmagnet/webhooks/webhookTypes.d.ts.map +1 -0
  92. package/dist/planmagnet/webhooks/webhookTypes.js +17 -0
  93. package/dist/planmagnet/webhooks/webhookTypes.js.map +1 -0
  94. package/package.json +1 -1
@@ -2,26 +2,26 @@ import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/Pla
2
2
  import { PersonName as n } from "../people/People.js";
3
3
  import { isForbidden as r, mutationErrorMessage as i } from "../utils/graphqlErrors.js";
4
4
  import { LEAVES_PAGE_CONTEXT as a, throwOnError as o } from "../utils/mutationResult.js";
5
- import { WorkItemSearchSelect as s } from "../controls/Pickers.js";
6
- import { MarkdownEditor as c } from "../../components/MarkdownEditor.js";
7
- import { DOC_STATUSES as ee, DocStatusBadge as te } from "../docs/DocStatusBadge.js";
8
- import { PresenceAvatars as ne } from "../presence/PresenceAvatars.js";
9
- import { DocComments as re } from "../comments/TargetComments.js";
10
- import { usePresence as ie } from "../hooks/usePresence.js";
11
- import { DocSuggestionsPanel as ae } from "../docs/DocSuggestionsPanel.js";
12
- import { DocVersionCompare as oe } from "../docs/DocVersionCompare.js";
13
- import { useEffect as l, useRef as se, useState as u } from "react";
14
- import { ArrowLeft as ce, History as le, Link2 as ue, Lock as d, X as de } from "lucide-react";
15
- import { useSearchParams as fe } from "react-router";
5
+ import { WorkItemSearchSelect as ee } from "../controls/Pickers.js";
6
+ import { MarkdownEditor as s } from "../../components/MarkdownEditor.js";
7
+ import { DOC_STATUSES as te, DocStatusBadge as ne } from "../docs/DocStatusBadge.js";
8
+ import { PresenceAvatars as re } from "../presence/PresenceAvatars.js";
9
+ import { DocComments as ie } from "../comments/TargetComments.js";
10
+ import { usePresence as ae } from "../hooks/usePresence.js";
11
+ import { DocSuggestionsPanel as oe } from "../docs/DocSuggestionsPanel.js";
12
+ import { DocVersionCompare as se } from "../docs/DocVersionCompare.js";
13
+ import { useEffect as c, useRef as ce, useState as l } from "react";
14
+ import { ArrowLeft as le, BadgeCheck as ue, History as de, Link2 as u, Lock as d, ShieldCheck as fe, X as pe } from "lucide-react";
15
+ import { useSearchParams as me } from "react-router";
16
16
  import { gql as f } from "@apollo/client";
17
- import { useApolloClient as pe, useMutation as p, useQuery as me, useSubscription as he } from "@apollo/client/react";
18
- import { jsx as m, jsxs as h } from "react/jsx-runtime";
19
- import { AlertDialog as ge, AlertDialogAction as g, AlertDialogCancel as _, AlertDialogContent as v, AlertDialogDescription as _e, AlertDialogFooter as ve, AlertDialogHeader as ye, AlertDialogTitle as be, AlertDialogTrigger as xe, Button as y, Card as b, CardContent as x, CardHeader as S, CardTitle as C, Input as w } from "@burdenoff/fe-libs/ui";
20
- import { clearGraphqlFetchResponseCache as Se } from "@burdenoff/fe-libs/shared/graphql";
21
- import { Markdown as T } from "@burdenoff/fe-libs/shared/components";
17
+ import { useApolloClient as he, useMutation as p, useQuery as ge, useSubscription as _e } from "@apollo/client/react";
18
+ import { Fragment as ve, jsx as m, jsxs as h } from "react/jsx-runtime";
19
+ import { AlertDialog as ye, AlertDialogAction as be, AlertDialogCancel as xe, AlertDialogContent as Se, AlertDialogDescription as Ce, AlertDialogFooter as we, AlertDialogHeader as Te, AlertDialogTitle as Ee, AlertDialogTrigger as De, Badge as Oe, Button as g, Card as _, CardContent as v, CardHeader as y, CardTitle as b, Checkbox as ke, Input as x } from "@burdenoff/fe-libs/ui";
20
+ import { clearGraphqlFetchResponseCache as S } from "@burdenoff/fe-libs/shared/graphql";
21
+ import { Markdown as C } from "@burdenoff/fe-libs/shared/components";
22
22
  //#region src/planmagnet/pages/DocsDocDetailPagePage.tsx
23
- var E = f`
24
- query DocDetail($id: ID!) {
23
+ var w = f`
24
+ query DocDetail($id: ID!, $approvedOnly: Boolean) {
25
25
  planmagnetDoc(id: $id) {
26
26
  id
27
27
  title
@@ -37,7 +37,15 @@ var E = f`
37
37
  acquiredAt
38
38
  expiresAt
39
39
  }
40
- revisions {
40
+ # GAP-07: the spec-of-record — null until any revision has ever been approved.
41
+ approvedRevision {
42
+ id
43
+ version
44
+ title
45
+ approvedBy
46
+ approvedAt
47
+ }
48
+ revisions(approvedOnly: $approvedOnly) {
41
49
  id
42
50
  version
43
51
  title
@@ -45,6 +53,8 @@ var E = f`
45
53
  changeNote
46
54
  createdBy
47
55
  createdAt
56
+ approvedBy
57
+ approvedAt
48
58
  }
49
59
  linkedWorkItems {
50
60
  id
@@ -53,7 +63,7 @@ var E = f`
53
63
  }
54
64
  }
55
65
  }
56
- `, Ce = f`
66
+ `, Ae = f`
57
67
  mutation DocUpdate($id: ID!, $input: PlanmagnetUpdateDocInput!) {
58
68
  planmagnetUpdateDoc(id: $id, input: $input) {
59
69
  id
@@ -61,28 +71,37 @@ var E = f`
61
71
  status
62
72
  }
63
73
  }
64
- `, we = f`
74
+ `, je = f`
65
75
  mutation DocRevert($id: ID!, $toVersion: Int!, $expectedVersion: Int) {
66
76
  planmagnetRevertDoc(id: $id, toVersion: $toVersion, expectedVersion: $expectedVersion) {
67
77
  id
68
78
  version
69
79
  }
70
80
  }
71
- `, Te = f`
81
+ `, Me = f`
72
82
  mutation DocDelete($id: ID!) {
73
83
  planmagnetDeleteDoc(id: $id)
74
84
  }
75
- `, Ee = f`
85
+ `, Ne = f`
76
86
  mutation DocLinkWorkItem($docId: ID!, $workItemId: ID!) {
77
87
  planmagnetLinkDocToWorkItem(docId: $docId, workItemId: $workItemId) {
78
88
  id
79
89
  }
80
90
  }
81
- `, De = f`
91
+ `, Pe = f`
82
92
  mutation DocUnlinkWorkItem($docId: ID!, $workItemId: ID!) {
83
93
  planmagnetUnlinkDocFromWorkItem(docId: $docId, workItemId: $workItemId)
84
94
  }
85
- `, Oe = f`
95
+ `, Fe = f`
96
+ mutation DocApproveRevision($revisionId: ID!) {
97
+ planmagnetApproveDocRevision(revisionId: $revisionId) {
98
+ id
99
+ version
100
+ approvedBy
101
+ approvedAt
102
+ }
103
+ }
104
+ `, Ie = f`
86
105
  mutation DocCheckout($docId: ID!) {
87
106
  planmagnetCheckoutDoc(docId: $docId) {
88
107
  id
@@ -93,7 +112,7 @@ var E = f`
93
112
  }
94
113
  }
95
114
  }
96
- `, D = f`
115
+ `, T = f`
97
116
  mutation DocReleaseLock($docId: ID!) {
98
117
  planmagnetReleaseDoc(docId: $docId) {
99
118
  id
@@ -104,7 +123,7 @@ var E = f`
104
123
  }
105
124
  }
106
125
  }
107
- `, ke = f`
126
+ `, Le = f`
108
127
  mutation DocBreakLock($docId: ID!) {
109
128
  planmagnetBreakDocLock(docId: $docId) {
110
129
  id
@@ -115,14 +134,14 @@ var E = f`
115
134
  }
116
135
  }
117
136
  }
118
- `, Ae = f`
137
+ `, Re = f`
119
138
  mutation DocSuggestEdit($input: PlanmagnetSuggestDocEditInput!) {
120
139
  planmagnetSuggestDocEdit(input: $input) {
121
140
  id
122
141
  status
123
142
  }
124
143
  }
125
- `, je = f`
144
+ `, ze = f`
126
145
  subscription PlanmagnetOnDocUpdatedFeed($docId: ID!, $workspaceId: ID!) {
127
146
  planmagnetOnDocUpdated(docId: $docId, workspaceId: $workspaceId) {
128
147
  id
@@ -132,9 +151,9 @@ var E = f`
132
151
  at
133
152
  }
134
153
  }
135
- `, Me = (e, t) => e instanceof Error ? e.message : t, O = (e) => new Date(e).toLocaleString();
136
- function Ne({ lock: e, currentUserId: t, now: r, onBreakLock: i, breaking: a }) {
137
- let o = e.holderId === t, s = Math.max(0, Math.round((new Date(e.expiresAt).getTime() - r) / 6e4)), c = new Date(e.expiresAt).toLocaleTimeString([], {
154
+ `, Be = (e, t) => e instanceof Error ? e.message : t, E = (e) => new Date(e).toLocaleString();
155
+ function Ve({ lock: e, currentUserId: t, now: r, onBreakLock: i, breaking: a }) {
156
+ let o = e.holderId === t, ee = Math.max(0, Math.round((new Date(e.expiresAt).getTime() - r) / 6e4)), s = new Date(e.expiresAt).toLocaleTimeString([], {
138
157
  hour: "2-digit",
139
158
  minute: "2-digit"
140
159
  });
@@ -148,7 +167,7 @@ function Ne({ lock: e, currentUserId: t, now: r, onBreakLock: i, breaking: a })
148
167
  "aria-hidden": "true"
149
168
  }),
150
169
  "You are editing — lock expires in ",
151
- s,
170
+ ee,
152
171
  " min."
153
172
  ]
154
173
  }) : /* @__PURE__ */ h("div", {
@@ -164,10 +183,10 @@ function Ne({ lock: e, currentUserId: t, now: r, onBreakLock: i, breaking: a })
164
183
  "Being edited by ",
165
184
  /* @__PURE__ */ m(n, { id: e.holderId }),
166
185
  " until ",
167
- c,
186
+ s,
168
187
  "."
169
188
  ]
170
- }), /* @__PURE__ */ m(y, {
189
+ }), /* @__PURE__ */ m(g, {
171
190
  size: "sm",
172
191
  variant: "outline",
173
192
  disabled: a,
@@ -177,52 +196,55 @@ function Ne({ lock: e, currentUserId: t, now: r, onBreakLock: i, breaking: a })
177
196
  })]
178
197
  });
179
198
  }
180
- function k() {
181
- let [d] = fe(), f = d.get("docId") ?? "", k = t(), { workspaceId: A, currentUser: j } = e(), [M, N] = u("view"), [P, Pe] = u(""), [Fe, Ie] = u(""), [F, Le] = u(""), [Re, I] = u(null), [L, ze] = u(null), [R, Be] = u(null), [z, Ve] = u(""), [B, He] = u(""), [V, Ue] = u(""), [We, H] = u(null), [Ge, Ke] = u(null), [qe, Je] = u(""), U = ie("DOC", f || null), { data: Ye, loading: Xe, error: Ze } = me(E, {
182
- variables: { id: f },
199
+ function D() {
200
+ let [d] = me(), f = d.get("docId") ?? "", D = t(), { workspaceId: O, currentUser: k } = e(), [A, j] = l("view"), [M, N] = l(""), [He, Ue] = l(""), [P, We] = l(""), [Ge, F] = l(null), [I, Ke] = l(null), [L, qe] = l(null), [R, Je] = l(!1), [Ye, Xe] = l(null), [z, Ze] = l(""), [B, Qe] = l(""), [V, $e] = l(""), [et, H] = l(null), [tt, nt] = l(null), [rt, it] = l(""), U = ae("DOC", f || null), { data: at, loading: ot, error: st } = ge(w, {
201
+ variables: {
202
+ id: f,
203
+ approvedOnly: R
204
+ },
183
205
  skip: !f,
184
206
  fetchPolicy: "cache-and-network"
185
- }), W = pe(), G = {
207
+ }), W = he(), G = {
186
208
  refetchQueries: ["DocDetail"],
187
209
  awaitRefetchQueries: !0
188
- }, [Qe, K] = p(Ce, G), [$e, et] = p(we, G), [tt, nt] = p(Te, {
210
+ }, [ct, K] = p(Ae, G), [lt, ut] = p(je, G), [dt, ft] = p(Fe, G), [pt, mt] = p(Me, {
189
211
  refetchQueries: ["DocsList"],
190
212
  context: a
191
- }), [rt, it] = p(De, G), [at, ot] = p(Ee, {
213
+ }), [ht, gt] = p(Pe, G), [_t, vt] = p(Ne, {
192
214
  ...G,
193
215
  refetchQueries: ["DocDetail", "GetWorkItemDocs"]
194
- }), [q, st] = u(""), [ct, lt] = p(Oe, G), [ut] = p(D, G), [dt, ft] = p(ke, G), [pt, J] = p(Ae, {
216
+ }), [q, yt] = l(""), [bt, xt] = p(Ie, G), [St] = p(T, G), [Ct, wt] = p(Le, G), [Tt, J] = p(Re, {
195
217
  refetchQueries: ["DocDetail", "DocSuggestionsPanel"],
196
218
  awaitRefetchQueries: !0
197
- }), Y = Ye?.planmagnetDoc, X = K.loading || et.loading || nt.loading, [mt, ht] = u(() => Date.now());
198
- l(() => {
199
- if (M !== "edit") return;
200
- let e = setInterval(() => ht(Date.now()), 3e4);
219
+ }), Y = at?.planmagnetDoc, X = K.loading || ut.loading || mt.loading, [Et, Dt] = l(() => Date.now());
220
+ c(() => {
221
+ if (A !== "edit") return;
222
+ let e = setInterval(() => Dt(Date.now()), 3e4);
201
223
  return () => clearInterval(e);
202
- }, [M]), l(() => {
203
- if (M !== "edit" || !f) return;
224
+ }, [A]), c(() => {
225
+ if (A !== "edit" || !f) return;
204
226
  let e = setInterval(() => {
205
- ct({ variables: { docId: f } }).catch(() => void 0);
227
+ bt({ variables: { docId: f } }).catch(() => void 0);
206
228
  }, 5 * 6e4);
207
229
  return () => clearInterval(e);
208
- }, [M, f]);
209
- let gt = se(!1);
210
- l(() => {
211
- gt.current = M === "edit";
212
- }, [M]), l(() => () => {
213
- gt.current && f && W.mutate({
214
- mutation: D,
230
+ }, [A, f]);
231
+ let Ot = ce(!1);
232
+ c(() => {
233
+ Ot.current = A === "edit";
234
+ }, [A]), c(() => () => {
235
+ Ot.current && f && W.mutate({
236
+ mutation: T,
215
237
  variables: { docId: f }
216
238
  }).catch(() => void 0);
217
- }, []), he(je, {
239
+ }, []), _e(ze, {
218
240
  variables: {
219
241
  docId: f,
220
- workspaceId: A ?? ""
242
+ workspaceId: O ?? ""
221
243
  },
222
- skip: !f || !A,
244
+ skip: !f || !O,
223
245
  onData: () => {
224
- Se(), W.query({
225
- query: E,
246
+ S(), W.query({
247
+ query: w,
226
248
  variables: { id: f },
227
249
  fetchPolicy: "network-only"
228
250
  }).catch(() => void 0);
@@ -232,12 +254,12 @@ function k() {
232
254
  }
233
255
  });
234
256
  let Z = async (e, t) => {
235
- I(null);
257
+ F(null);
236
258
  try {
237
259
  return await o(e()), !0;
238
260
  } catch (e) {
239
- return I(Me(e, t)), Se(), await W.query({
240
- query: E,
261
+ return F(Be(e, t)), S(), await W.query({
262
+ query: w,
241
263
  variables: { id: f },
242
264
  fetchPolicy: "network-only"
243
265
  }).catch(() => void 0), !1;
@@ -247,82 +269,89 @@ function k() {
247
269
  className: "p-6 text-sm text-muted-foreground",
248
270
  children: "No doc selected."
249
271
  });
250
- if (Xe && !Ye) return /* @__PURE__ */ m("div", {
272
+ if (ot && !at) return /* @__PURE__ */ m("div", {
251
273
  className: "p-6 text-sm text-muted-foreground",
252
274
  children: "Loading doc…"
253
275
  });
254
- if (Ze && !Y) return /* @__PURE__ */ h("p", {
276
+ if (st && !Y) return /* @__PURE__ */ h("p", {
255
277
  role: "alert",
256
278
  className: "p-6 text-sm text-destructive",
257
- children: ["The doc could not be loaded: ", Ze.message]
279
+ children: ["The doc could not be loaded: ", st.message]
258
280
  });
259
281
  if (!Y) return /* @__PURE__ */ h("div", {
260
282
  className: "space-y-3 p-6",
261
283
  children: [/* @__PURE__ */ m("p", {
262
284
  className: "text-sm text-muted-foreground",
263
285
  children: "This doc does not exist in this workspace, or it was deleted."
264
- }), /* @__PURE__ */ m(y, {
286
+ }), /* @__PURE__ */ m(g, {
265
287
  size: "sm",
266
288
  variant: "outline",
267
- onClick: () => k("/docs/docs-page"),
289
+ onClick: () => D("/docs/docs-page"),
268
290
  children: "Back to docs"
269
291
  })]
270
292
  });
271
- let _t = async () => {
272
- I(null);
293
+ let kt = async () => {
294
+ F(null);
273
295
  try {
274
- await o(ct({ variables: { docId: Y.id } }));
296
+ await o(bt({ variables: { docId: Y.id } }));
275
297
  } catch (e) {
276
- I(r(e) ? "Your role cannot edit this doc." : i(e, "The doc could not be checked out for editing."));
298
+ F(r(e) ? "Your role cannot edit this doc." : i(e, "The doc could not be checked out for editing."));
277
299
  return;
278
300
  }
279
- Pe(Y.title), Ie(Y.content), Le(""), Be(Y.version), N("edit");
280
- }, vt = () => {
281
- N("view"), I(null), ut({ variables: { docId: Y.id } }).catch(() => void 0);
282
- }, yt = async () => {
283
- await Z(() => Qe({ variables: {
301
+ N(Y.title), Ue(Y.content), We(""), qe(Y.version), j("edit");
302
+ }, At = () => {
303
+ j("view"), F(null), St({ variables: { docId: Y.id } }).catch(() => void 0);
304
+ }, jt = async () => {
305
+ await Z(() => ct({ variables: {
284
306
  id: Y.id,
285
307
  input: {
286
- title: P.trim(),
287
- content: Fe,
288
- ...F.trim() ? { changeNote: F.trim() } : {},
289
- expectedVersion: R
308
+ title: M.trim(),
309
+ content: He,
310
+ ...P.trim() ? { changeNote: P.trim() } : {},
311
+ expectedVersion: L
290
312
  }
291
- } }), "The doc could not be saved.") && (N("view"), ut({ variables: { docId: Y.id } }).catch(() => void 0));
292
- }, bt = async () => {
293
- I(null);
313
+ } }), "The doc could not be saved.") && (j("view"), St({ variables: { docId: Y.id } }).catch(() => void 0));
314
+ }, Mt = async () => {
315
+ F(null);
316
+ try {
317
+ await o(Ct({ variables: { docId: Y.id } }));
318
+ } catch (e) {
319
+ F(r(e) ? "Your role cannot force-release this lock." : i(e, "The lock could not be broken."));
320
+ }
321
+ }, Nt = async (e) => {
322
+ Xe(null);
294
323
  try {
295
- await o(dt({ variables: { docId: Y.id } }));
324
+ await o(dt({ variables: { revisionId: e } }));
296
325
  } catch (e) {
297
- I(r(e) ? "Your role cannot force-release this lock." : i(e, "The lock could not be broken."));
326
+ Xe(r(e) ? "Your role cannot approve a revision as the spec of record." : i(e, "The revision could not be approved."));
298
327
  }
299
- }, xt = () => {
300
- Ve(Y.title), He(Y.content), Ue(""), H(null), Ke(Y.version), Je(Y.title), N("suggest");
301
- }, St = () => {
302
- N("view"), H(null);
303
- }, Ct = async () => {
328
+ }, Pt = () => {
329
+ Ze(Y.title), Qe(Y.content), $e(""), H(null), nt(Y.version), it(Y.title), j("suggest");
330
+ }, Ft = () => {
331
+ j("view"), H(null);
332
+ }, It = async () => {
304
333
  H(null);
305
334
  try {
306
- await o(pt({ variables: { input: {
335
+ await o(Tt({ variables: { input: {
307
336
  docId: Y.id,
308
- baseVersion: Ge ?? Y.version,
337
+ baseVersion: tt ?? Y.version,
309
338
  proposedContent: B,
310
- ...z.trim() === qe ? {} : { proposedTitle: z.trim() },
339
+ ...z.trim() === rt ? {} : { proposedTitle: z.trim() },
311
340
  ...V.trim() ? { note: V.trim() } : {}
312
- } } })), N("view");
341
+ } } })), j("view");
313
342
  } catch (e) {
314
343
  H(r(e) ? "Your role cannot suggest edits on this doc." : i(e, "The suggestion could not be submitted."));
315
344
  }
316
- }, wt = !!Y.lock && Y.lock.holderId !== j?.id, Q = [...Y.revisions].sort((e, t) => t.version - e.version), $ = L === null ? null : Q.find((e) => e.version === L);
345
+ }, Lt = !!Y.lock && Y.lock.holderId !== k?.id, Q = [...Y.revisions].sort((e, t) => t.version - e.version), $ = I === null ? null : Q.find((e) => e.version === I);
317
346
  return /* @__PURE__ */ h("div", {
318
347
  className: "space-y-6 p-6",
319
348
  "data-testid": "doc-detail",
320
349
  children: [
321
- /* @__PURE__ */ h(y, {
350
+ /* @__PURE__ */ h(g, {
322
351
  size: "sm",
323
352
  variant: "ghost",
324
- onClick: () => k("/docs/docs-page"),
325
- children: [/* @__PURE__ */ m(ce, { className: "mr-1 h-4 w-4" }), "All docs"]
353
+ onClick: () => D("/docs/docs-page"),
354
+ children: [/* @__PURE__ */ m(le, { className: "mr-1 h-4 w-4" }), "All docs"]
326
355
  }),
327
356
  /* @__PURE__ */ h("div", {
328
357
  className: "flex flex-wrap items-start justify-between gap-3",
@@ -337,26 +366,41 @@ function k() {
337
366
  /* @__PURE__ */ h("p", {
338
367
  className: "text-xs text-muted-foreground",
339
368
  children: [
340
- /* @__PURE__ */ m(te, { status: Y.status }),
369
+ /* @__PURE__ */ m(ne, { status: Y.status }),
341
370
  " · version ",
342
371
  Y.version,
343
372
  " · updated",
344
373
  " ",
345
- O(Y.updatedAt),
374
+ E(Y.updatedAt),
346
375
  " by ",
347
376
  /* @__PURE__ */ m(n, { id: Y.updatedBy ?? Y.createdBy })
348
377
  ]
349
378
  }),
350
- /* @__PURE__ */ m(ne, { others: U.others })
379
+ /* @__PURE__ */ h("p", {
380
+ className: "flex items-center gap-1.5 text-xs text-muted-foreground",
381
+ "data-testid": "doc-approved-revision",
382
+ children: [/* @__PURE__ */ m(fe, {
383
+ className: "h-3.5 w-3.5",
384
+ "aria-hidden": "true"
385
+ }), Y.approvedRevision ? /* @__PURE__ */ h(ve, { children: [
386
+ "Spec of record: v",
387
+ Y.approvedRevision.version,
388
+ ", approved by",
389
+ " ",
390
+ /* @__PURE__ */ m(n, { id: Y.approvedRevision.approvedBy }),
391
+ Y.approvedRevision.approvedAt ? ` on ${E(Y.approvedRevision.approvedAt)}` : ""
392
+ ] }) : "No approved revision yet"]
393
+ }),
394
+ /* @__PURE__ */ m(re, { others: U.others })
351
395
  ]
352
- }), M === "view" && /* @__PURE__ */ h("div", {
396
+ }), A === "view" && /* @__PURE__ */ h("div", {
353
397
  className: "flex flex-wrap gap-2",
354
398
  children: [
355
- ee.filter((e) => e !== Y.status).map((e) => /* @__PURE__ */ m(y, {
399
+ te.filter((e) => e !== Y.status).map((e) => /* @__PURE__ */ m(g, {
356
400
  size: "sm",
357
401
  variant: "outline",
358
402
  disabled: X,
359
- onClick: () => Z(() => Qe({ variables: {
403
+ onClick: () => Z(() => ct({ variables: {
360
404
  id: Y.id,
361
405
  input: {
362
406
  status: e,
@@ -365,157 +409,157 @@ function k() {
365
409
  } }), "The status could not be changed."),
366
410
  children: e === "PUBLISHED" ? "Publish" : e === "ARCHIVED" ? "Archive" : "Back to draft"
367
411
  }, e)),
368
- /* @__PURE__ */ m(y, {
412
+ /* @__PURE__ */ m(g, {
369
413
  size: "sm",
370
414
  variant: "outline",
371
- onClick: xt,
415
+ onClick: Pt,
372
416
  disabled: J.loading,
373
417
  "data-testid": "doc-suggest",
374
418
  children: "Suggest an edit"
375
419
  }),
376
- /* @__PURE__ */ m(y, {
420
+ /* @__PURE__ */ m(g, {
377
421
  size: "sm",
378
- onClick: () => void _t(),
379
- disabled: wt || lt.loading,
422
+ onClick: () => void kt(),
423
+ disabled: Lt || xt.loading,
380
424
  "data-testid": "doc-edit",
381
- children: lt.loading ? "Checking out…" : "Edit"
425
+ children: xt.loading ? "Checking out…" : "Edit"
382
426
  }),
383
- /* @__PURE__ */ h(ge, { children: [/* @__PURE__ */ m(xe, {
427
+ /* @__PURE__ */ h(ye, { children: [/* @__PURE__ */ m(De, {
384
428
  asChild: !0,
385
- children: /* @__PURE__ */ m(y, {
429
+ children: /* @__PURE__ */ m(g, {
386
430
  size: "sm",
387
431
  variant: "outline",
388
432
  disabled: X,
389
433
  children: "Delete"
390
434
  })
391
- }), /* @__PURE__ */ h(v, { children: [/* @__PURE__ */ h(ye, { children: [/* @__PURE__ */ h(be, { children: [
435
+ }), /* @__PURE__ */ h(Se, { children: [/* @__PURE__ */ h(Te, { children: [/* @__PURE__ */ h(Ee, { children: [
392
436
  "Delete “",
393
437
  Y.title,
394
438
  "”?"
395
- ] }), /* @__PURE__ */ h(_e, { children: [
439
+ ] }), /* @__PURE__ */ h(Ce, { children: [
396
440
  "The doc and its history are removed for everyone, and it is unlinked from",
397
441
  " ",
398
442
  Y.linkedWorkItems.length,
399
443
  " work item",
400
444
  Y.linkedWorkItems.length === 1 ? "" : "s",
401
445
  "."
402
- ] })] }), /* @__PURE__ */ h(ve, { children: [/* @__PURE__ */ m(_, { children: "Keep it" }), /* @__PURE__ */ m(g, {
446
+ ] })] }), /* @__PURE__ */ h(we, { children: [/* @__PURE__ */ m(xe, { children: "Keep it" }), /* @__PURE__ */ m(be, {
403
447
  className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
404
448
  onClick: async () => {
405
- await Z(() => tt({ variables: { id: Y.id } }), "The doc could not be deleted.") && k("/docs/docs-page");
449
+ await Z(() => pt({ variables: { id: Y.id } }), "The doc could not be deleted.") && D("/docs/docs-page");
406
450
  },
407
451
  children: "Delete"
408
452
  })] })] })] })
409
453
  ]
410
454
  })]
411
455
  }),
412
- Y.lock && /* @__PURE__ */ m(Ne, {
456
+ Y.lock && /* @__PURE__ */ m(Ve, {
413
457
  lock: Y.lock,
414
- currentUserId: j?.id,
415
- now: mt,
416
- onBreakLock: () => void bt(),
417
- breaking: ft.loading
458
+ currentUserId: k?.id,
459
+ now: Et,
460
+ onBreakLock: () => void Mt(),
461
+ breaking: wt.loading
418
462
  }),
419
- Re && /* @__PURE__ */ m("p", {
463
+ Ge && /* @__PURE__ */ m("p", {
420
464
  role: "alert",
421
465
  className: "text-sm text-destructive",
422
466
  "data-testid": "doc-error",
423
- children: Re
467
+ children: Ge
424
468
  }),
425
- M === "edit" && R !== Y.version && /* @__PURE__ */ h("p", {
469
+ A === "edit" && L !== Y.version && /* @__PURE__ */ h("p", {
426
470
  className: "text-sm text-status-warning-text",
427
471
  "data-testid": "doc-moved-on",
428
472
  children: [
429
473
  "Someone saved version ",
430
474
  Y.version,
431
475
  " after you started editing version ",
432
- R,
476
+ L,
433
477
  ". Your text is kept below; copy what you need, then discard and edit the latest."
434
478
  ]
435
479
  }),
436
- M === "edit" && /* @__PURE__ */ m(b, { children: /* @__PURE__ */ h(x, {
480
+ A === "edit" && /* @__PURE__ */ m(_, { children: /* @__PURE__ */ h(v, {
437
481
  className: "space-y-3 pt-6",
438
482
  children: [
439
- /* @__PURE__ */ m(w, {
483
+ /* @__PURE__ */ m(x, {
440
484
  "aria-label": "Doc title",
441
- value: P,
442
- onChange: (e) => Pe(e.target.value)
485
+ value: M,
486
+ onChange: (e) => N(e.target.value)
443
487
  }),
444
- /* @__PURE__ */ m(c, {
445
- value: Fe,
446
- onChange: Ie,
488
+ /* @__PURE__ */ m(s, {
489
+ value: He,
490
+ onChange: Ue,
447
491
  minHeight: 240
448
492
  }),
449
- /* @__PURE__ */ m(w, {
493
+ /* @__PURE__ */ m(x, {
450
494
  "aria-label": "Change note",
451
495
  placeholder: "What changed? (optional, shown in the history)",
452
- value: F,
453
- onChange: (e) => Le(e.target.value)
496
+ value: P,
497
+ onChange: (e) => We(e.target.value)
454
498
  }),
455
499
  /* @__PURE__ */ h("div", {
456
500
  className: "flex justify-end gap-2",
457
- children: [/* @__PURE__ */ m(y, {
501
+ children: [/* @__PURE__ */ m(g, {
458
502
  size: "sm",
459
503
  variant: "ghost",
460
- onClick: vt,
461
- children: R === Y.version ? "Cancel" : "Discard my edits"
462
- }), /* @__PURE__ */ m(y, {
504
+ onClick: At,
505
+ children: L === Y.version ? "Cancel" : "Discard my edits"
506
+ }), /* @__PURE__ */ m(g, {
463
507
  size: "sm",
464
- onClick: yt,
465
- disabled: K.loading || R !== Y.version,
508
+ onClick: jt,
509
+ disabled: K.loading || L !== Y.version,
466
510
  "data-testid": "doc-save",
467
511
  children: K.loading ? "Saving…" : "Save new version"
468
512
  })]
469
513
  })
470
514
  ]
471
515
  }) }),
472
- M === "suggest" && /* @__PURE__ */ h(b, {
516
+ A === "suggest" && /* @__PURE__ */ h(_, {
473
517
  "data-testid": "doc-suggest-form",
474
- children: [/* @__PURE__ */ m(S, { children: /* @__PURE__ */ m(C, {
518
+ children: [/* @__PURE__ */ m(y, { children: /* @__PURE__ */ m(b, {
475
519
  className: "text-base",
476
520
  children: "Suggest an edit"
477
- }) }), /* @__PURE__ */ h(x, {
521
+ }) }), /* @__PURE__ */ h(v, {
478
522
  className: "space-y-3",
479
523
  children: [
480
524
  /* @__PURE__ */ h("p", {
481
525
  className: "text-xs text-muted-foreground",
482
526
  children: [
483
527
  "Proposed against version ",
484
- Ge ?? Y.version,
528
+ tt ?? Y.version,
485
529
  ". It does not change the doc — someone with edit rights accepts or rejects it below."
486
530
  ]
487
531
  }),
488
- /* @__PURE__ */ m(w, {
532
+ /* @__PURE__ */ m(x, {
489
533
  "aria-label": "Suggested title",
490
534
  value: z,
491
- onChange: (e) => Ve(e.target.value)
535
+ onChange: (e) => Ze(e.target.value)
492
536
  }),
493
- /* @__PURE__ */ m(c, {
537
+ /* @__PURE__ */ m(s, {
494
538
  value: B,
495
- onChange: He,
539
+ onChange: Qe,
496
540
  minHeight: 240
497
541
  }),
498
- /* @__PURE__ */ m(w, {
542
+ /* @__PURE__ */ m(x, {
499
543
  "aria-label": "Note (optional)",
500
544
  placeholder: "Why this change? (optional)",
501
545
  value: V,
502
- onChange: (e) => Ue(e.target.value)
546
+ onChange: (e) => $e(e.target.value)
503
547
  }),
504
- We && /* @__PURE__ */ m("p", {
548
+ et && /* @__PURE__ */ m("p", {
505
549
  role: "alert",
506
550
  className: "text-sm text-destructive",
507
- children: We
551
+ children: et
508
552
  }),
509
553
  /* @__PURE__ */ h("div", {
510
554
  className: "flex justify-end gap-2",
511
- children: [/* @__PURE__ */ m(y, {
555
+ children: [/* @__PURE__ */ m(g, {
512
556
  size: "sm",
513
557
  variant: "ghost",
514
- onClick: St,
558
+ onClick: Ft,
515
559
  children: "Cancel"
516
- }), /* @__PURE__ */ m(y, {
560
+ }), /* @__PURE__ */ m(g, {
517
561
  size: "sm",
518
- onClick: () => void Ct(),
562
+ onClick: () => void It(),
519
563
  disabled: J.loading || !B.trim() || !z.trim(),
520
564
  "data-testid": "doc-suggest-submit",
521
565
  children: J.loading ? "Submitting…" : "Submit suggestion"
@@ -524,91 +568,139 @@ function k() {
524
568
  ]
525
569
  })]
526
570
  }),
527
- M === "view" && /* @__PURE__ */ m(b, { children: /* @__PURE__ */ m(x, {
571
+ A === "view" && /* @__PURE__ */ m(_, { children: /* @__PURE__ */ m(v, {
528
572
  className: "prose prose-sm max-w-none pt-6 dark:prose-invert",
529
- children: Y.content.trim() ? /* @__PURE__ */ m(T, { children: Y.content }) : /* @__PURE__ */ m("p", {
573
+ children: Y.content.trim() ? /* @__PURE__ */ m(C, { children: Y.content }) : /* @__PURE__ */ m("p", {
530
574
  className: "text-sm text-muted-foreground",
531
575
  children: "This doc is empty."
532
576
  })
533
577
  }) }),
534
578
  /* @__PURE__ */ h("div", {
535
579
  className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
536
- children: [/* @__PURE__ */ h(b, {
580
+ children: [/* @__PURE__ */ h(_, {
537
581
  "data-testid": "doc-history",
538
- children: [/* @__PURE__ */ m(S, { children: /* @__PURE__ */ h(C, {
539
- className: "flex items-center gap-2",
540
- children: [
541
- /* @__PURE__ */ m(le, { className: "h-4 w-4" }),
542
- " History (",
543
- Q.length,
544
- ")"
545
- ]
546
- }) }), /* @__PURE__ */ h(x, {
582
+ children: [/* @__PURE__ */ h(y, {
583
+ className: "flex flex-row flex-wrap items-center justify-between gap-2",
584
+ children: [/* @__PURE__ */ h(b, {
585
+ className: "flex items-center gap-2",
586
+ children: [
587
+ /* @__PURE__ */ m(de, { className: "h-4 w-4" }),
588
+ " History (",
589
+ Q.length,
590
+ ")"
591
+ ]
592
+ }), /* @__PURE__ */ h("label", {
593
+ className: "flex items-center gap-1.5 text-xs font-normal text-muted-foreground",
594
+ children: [/* @__PURE__ */ m(ke, {
595
+ checked: R,
596
+ onCheckedChange: (e) => Je(e === !0),
597
+ "data-testid": "doc-approved-only-toggle"
598
+ }), "Approved only"]
599
+ })]
600
+ }), /* @__PURE__ */ h(v, {
547
601
  className: "space-y-2",
548
602
  children: [
603
+ Ye && /* @__PURE__ */ m("p", {
604
+ role: "alert",
605
+ className: "text-sm text-destructive",
606
+ children: Ye
607
+ }),
549
608
  /* @__PURE__ */ m("ol", {
550
609
  className: "space-y-2",
551
610
  children: Q.map((e) => {
552
- let t = e.version === Y.version;
611
+ let t = e.version === Y.version, r = !!e.approvedAt;
553
612
  return /* @__PURE__ */ h("li", {
554
613
  className: "space-y-1 rounded-md border p-2",
555
614
  "data-testid": "doc-revision",
556
- children: [/* @__PURE__ */ h("div", {
557
- className: "flex flex-wrap items-center justify-between gap-2",
558
- children: [/* @__PURE__ */ h("span", {
559
- className: "text-sm font-medium",
615
+ children: [
616
+ /* @__PURE__ */ h("div", {
617
+ className: "flex flex-wrap items-center justify-between gap-2",
618
+ children: [/* @__PURE__ */ h("span", {
619
+ className: "flex flex-wrap items-center gap-1.5 text-sm font-medium",
620
+ children: [
621
+ "Version ",
622
+ e.version,
623
+ t ? " (current)" : "",
624
+ r && /* @__PURE__ */ h(Oe, {
625
+ variant: "success",
626
+ className: "gap-1 text-xs font-normal",
627
+ "data-testid": "doc-revision-approved-badge",
628
+ children: [/* @__PURE__ */ m(ue, {
629
+ className: "h-3 w-3",
630
+ "aria-hidden": "true"
631
+ }), "Approved"]
632
+ })
633
+ ]
634
+ }), /* @__PURE__ */ h("span", {
635
+ className: "flex flex-wrap gap-1",
636
+ children: [
637
+ /* @__PURE__ */ m(g, {
638
+ size: "sm",
639
+ variant: "ghost",
640
+ className: "h-7 text-xs",
641
+ "aria-expanded": I === e.version,
642
+ onClick: () => Ke(I === e.version ? null : e.version),
643
+ children: I === e.version ? "Hide" : "View"
644
+ }),
645
+ A === "view" && /* @__PURE__ */ m(g, {
646
+ size: "sm",
647
+ variant: "outline",
648
+ className: "h-7 text-xs",
649
+ disabled: ft.loading,
650
+ onClick: () => void Nt(e.id),
651
+ "data-testid": "doc-approve-revision",
652
+ children: r ? "Re-approve" : "Approve this revision"
653
+ }),
654
+ !t && A === "view" && /* @__PURE__ */ h(ye, { children: [/* @__PURE__ */ m(De, {
655
+ asChild: !0,
656
+ children: /* @__PURE__ */ m(g, {
657
+ size: "sm",
658
+ variant: "outline",
659
+ className: "h-7 text-xs",
660
+ disabled: X,
661
+ "data-testid": "doc-restore",
662
+ children: "Restore"
663
+ })
664
+ }), /* @__PURE__ */ h(Se, { children: [/* @__PURE__ */ h(Te, { children: [/* @__PURE__ */ h(Ee, { children: [
665
+ "Restore version ",
666
+ e.version,
667
+ "?"
668
+ ] }), /* @__PURE__ */ h(Ce, { children: [
669
+ "Its title and text become version ",
670
+ Y.version + 1,
671
+ ". Nothing is deleted: version ",
672
+ Y.version,
673
+ " stays in the history."
674
+ ] })] }), /* @__PURE__ */ h(we, { children: [/* @__PURE__ */ m(xe, { children: "Cancel" }), /* @__PURE__ */ m(be, {
675
+ onClick: () => Z(() => lt({ variables: {
676
+ id: Y.id,
677
+ toVersion: e.version,
678
+ expectedVersion: Y.version
679
+ } }), "The version could not be restored."),
680
+ children: "Restore"
681
+ })] })] })] })
682
+ ]
683
+ })]
684
+ }),
685
+ /* @__PURE__ */ h("p", {
686
+ className: "text-xs text-muted-foreground",
687
+ children: [
688
+ E(e.createdAt),
689
+ " · ",
690
+ /* @__PURE__ */ m(n, { id: e.createdBy }),
691
+ e.changeNote ? ` · ${e.changeNote}` : ""
692
+ ]
693
+ }),
694
+ r && /* @__PURE__ */ h("p", {
695
+ className: "text-xs text-status-success-text",
696
+ "data-testid": "doc-revision-approved-by",
560
697
  children: [
561
- "Version ",
562
- e.version,
563
- t ? " (current)" : ""
698
+ "Approved by ",
699
+ /* @__PURE__ */ m(n, { id: e.approvedBy }),
700
+ e.approvedAt ? ` on ${E(e.approvedAt)}` : ""
564
701
  ]
565
- }), /* @__PURE__ */ h("span", {
566
- className: "flex gap-1",
567
- children: [/* @__PURE__ */ m(y, {
568
- size: "sm",
569
- variant: "ghost",
570
- className: "h-7 text-xs",
571
- "aria-expanded": L === e.version,
572
- onClick: () => ze(L === e.version ? null : e.version),
573
- children: L === e.version ? "Hide" : "View"
574
- }), !t && M === "view" && /* @__PURE__ */ h(ge, { children: [/* @__PURE__ */ m(xe, {
575
- asChild: !0,
576
- children: /* @__PURE__ */ m(y, {
577
- size: "sm",
578
- variant: "outline",
579
- className: "h-7 text-xs",
580
- disabled: X,
581
- "data-testid": "doc-restore",
582
- children: "Restore"
583
- })
584
- }), /* @__PURE__ */ h(v, { children: [/* @__PURE__ */ h(ye, { children: [/* @__PURE__ */ h(be, { children: [
585
- "Restore version ",
586
- e.version,
587
- "?"
588
- ] }), /* @__PURE__ */ h(_e, { children: [
589
- "Its title and text become version ",
590
- Y.version + 1,
591
- ". Nothing is deleted: version ",
592
- Y.version,
593
- " stays in the history."
594
- ] })] }), /* @__PURE__ */ h(ve, { children: [/* @__PURE__ */ m(_, { children: "Cancel" }), /* @__PURE__ */ m(g, {
595
- onClick: () => Z(() => $e({ variables: {
596
- id: Y.id,
597
- toVersion: e.version,
598
- expectedVersion: Y.version
599
- } }), "The version could not be restored."),
600
- children: "Restore"
601
- })] })] })] })]
602
- })]
603
- }), /* @__PURE__ */ h("p", {
604
- className: "text-xs text-muted-foreground",
605
- children: [
606
- O(e.createdAt),
607
- " · ",
608
- /* @__PURE__ */ m(n, { id: e.createdBy }),
609
- e.changeNote ? ` · ${e.changeNote}` : ""
610
- ]
611
- })]
702
+ })
703
+ ]
612
704
  }, e.id);
613
705
  })
614
706
  }),
@@ -625,26 +717,26 @@ function k() {
625
717
  ]
626
718
  }), /* @__PURE__ */ m("div", {
627
719
  className: "prose prose-sm max-w-none dark:prose-invert",
628
- children: /* @__PURE__ */ m(T, { children: $.content })
720
+ children: /* @__PURE__ */ m(C, { children: $.content })
629
721
  })]
630
722
  }),
631
- /* @__PURE__ */ m(oe, {
723
+ /* @__PURE__ */ m(se, {
632
724
  docId: Y.id,
633
725
  versions: Q
634
726
  })
635
727
  ]
636
728
  })]
637
- }), /* @__PURE__ */ h(b, {
729
+ }), /* @__PURE__ */ h(_, {
638
730
  "data-testid": "doc-linked-items",
639
- children: [/* @__PURE__ */ m(S, { children: /* @__PURE__ */ h(C, {
731
+ children: [/* @__PURE__ */ m(y, { children: /* @__PURE__ */ h(b, {
640
732
  className: "flex items-center gap-2",
641
733
  children: [
642
- /* @__PURE__ */ m(ue, { className: "h-4 w-4" }),
734
+ /* @__PURE__ */ m(u, { className: "h-4 w-4" }),
643
735
  " Linked work items (",
644
736
  Y.linkedWorkItems.length,
645
737
  ")"
646
738
  ]
647
- }) }), /* @__PURE__ */ h(x, {
739
+ }) }), /* @__PURE__ */ h(v, {
648
740
  className: "space-y-2",
649
741
  children: [
650
742
  Y.linkedWorkItems.length === 0 && /* @__PURE__ */ m("p", {
@@ -656,7 +748,7 @@ function k() {
656
748
  children: [/* @__PURE__ */ h("button", {
657
749
  type: "button",
658
750
  className: "min-w-0 truncate text-left text-sm hover:underline",
659
- onClick: () => k(`/tasks/task-detail-page?taskId=${encodeURIComponent(e.id)}`),
751
+ onClick: () => D(`/tasks/task-detail-page?taskId=${encodeURIComponent(e.id)}`),
660
752
  children: [
661
753
  /* @__PURE__ */ m("span", {
662
754
  className: "text-muted-foreground",
@@ -665,51 +757,51 @@ function k() {
665
757
  " ",
666
758
  e.title
667
759
  ]
668
- }), /* @__PURE__ */ m(y, {
760
+ }), /* @__PURE__ */ m(g, {
669
761
  size: "icon",
670
762
  variant: "ghost",
671
- disabled: it.loading,
763
+ disabled: gt.loading,
672
764
  "aria-label": `Unlink ${e.title}`,
673
- onClick: () => Z(() => rt({ variables: {
765
+ onClick: () => Z(() => ht({ variables: {
674
766
  docId: Y.id,
675
767
  workItemId: e.id
676
768
  } }), "The work item could not be unlinked."),
677
- children: /* @__PURE__ */ m(de, { className: "h-4 w-4" })
769
+ children: /* @__PURE__ */ m(pe, { className: "h-4 w-4" })
678
770
  })]
679
771
  }, e.id)),
680
772
  /* @__PURE__ */ h("div", {
681
773
  className: "space-y-2 pt-2",
682
774
  "data-testid": "doc-link-work-item",
683
- children: [/* @__PURE__ */ m(s, {
775
+ children: [/* @__PURE__ */ m(ee, {
684
776
  id: "doc-link-work-item-select",
685
777
  value: q,
686
- onChange: st,
778
+ onChange: yt,
687
779
  exclude: Y.linkedWorkItems.map((e) => e.id)
688
- }), /* @__PURE__ */ h(y, {
780
+ }), /* @__PURE__ */ h(g, {
689
781
  size: "sm",
690
782
  variant: "outline",
691
- disabled: !q || ot.loading,
783
+ disabled: !q || vt.loading,
692
784
  onClick: async () => {
693
- await Z(() => at({ variables: {
785
+ await Z(() => _t({ variables: {
694
786
  docId: Y.id,
695
787
  workItemId: q
696
- } }), "The work item could not be linked.") && st("");
788
+ } }), "The work item could not be linked.") && yt("");
697
789
  },
698
- children: [/* @__PURE__ */ m(ue, { className: "mr-1 h-4 w-4" }), "Link work item"]
790
+ children: [/* @__PURE__ */ m(u, { className: "mr-1 h-4 w-4" }), "Link work item"]
699
791
  })]
700
792
  })
701
793
  ]
702
794
  })]
703
795
  })]
704
796
  }),
705
- /* @__PURE__ */ m(ae, {
797
+ /* @__PURE__ */ m(oe, {
706
798
  docId: Y.id,
707
799
  docTitle: Y.title,
708
800
  docContent: Y.content,
709
801
  revisions: Q,
710
- currentUserId: j?.id
802
+ currentUserId: k?.id
711
803
  }),
712
- /* @__PURE__ */ m(re, {
804
+ /* @__PURE__ */ m(ie, {
713
805
  docId: Y.id,
714
806
  presence: {
715
807
  typingActorIds: U.typingActorIds,
@@ -720,6 +812,6 @@ function k() {
720
812
  });
721
813
  }
722
814
  //#endregion
723
- export { k as DocsDocDetailPagePage };
815
+ export { D as DocsDocDetailPagePage };
724
816
 
725
817
  //# sourceMappingURL=DocsDocDetailPagePage.js.map