@burdenoff/microfe-vibecontrols 2026.709.2 → 2026.710.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js +87 -85
  2. package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js.map +1 -1
  3. package/dist/components/ai/InstructionFilesManager.js +138 -136
  4. package/dist/components/ai/InstructionFilesManager.js.map +1 -1
  5. package/dist/components/ai/PluginHarnessPicker.js +70 -64
  6. package/dist/components/ai/PluginHarnessPicker.js.map +1 -1
  7. package/dist/components/docs/DocsEditPanel.js +1 -1
  8. package/dist/components/docs/DocsEditPanel.js.map +1 -1
  9. package/dist/components/docs/DocsPageTree.js +1 -1
  10. package/dist/components/docs/DocsPageTree.js.map +1 -1
  11. package/dist/components/docs/DocsTabPanel.js +108 -106
  12. package/dist/components/docs/DocsTabPanel.js.map +1 -1
  13. package/dist/components/notes/NotesTabPanel.js +99 -99
  14. package/dist/components/notes/NotesTabPanel.js.map +1 -1
  15. package/dist/components/scorecard/ScorecardPanel.js +309 -308
  16. package/dist/components/scorecard/ScorecardPanel.js.map +1 -1
  17. package/dist/components/sessions/SessionPublicLinkPanel.js +104 -102
  18. package/dist/components/sessions/SessionPublicLinkPanel.js.map +1 -1
  19. package/dist/components/settings/AdvancedSection.js +92 -90
  20. package/dist/components/settings/AdvancedSection.js.map +1 -1
  21. package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js +104 -102
  22. package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js.map +1 -1
  23. package/dist/constants/permissions.js +7 -0
  24. package/dist/constants/permissions.js.map +1 -1
  25. package/dist/pages/ActionsPage.js +303 -303
  26. package/dist/pages/ActionsPage.js.map +1 -1
  27. package/dist/pages/AgentDetailsPage.js +520 -516
  28. package/dist/pages/AgentDetailsPage.js.map +1 -1
  29. package/dist/pages/AgentsPage.js +287 -283
  30. package/dist/pages/AgentsPage.js.map +1 -1
  31. package/dist/pages/TargetsPage.js +554 -549
  32. package/dist/pages/TargetsPage.js.map +1 -1
  33. package/dist/pages/VibeAuditPage.js +2 -2
  34. package/dist/pages/VibeAuditPage.js.map +1 -1
  35. package/dist/pages/VibeDeckPage.js +257 -257
  36. package/dist/pages/VibeDeckPage.js.map +1 -1
  37. package/dist/pages/VibeDetailsPage.js +688 -693
  38. package/dist/pages/VibeDetailsPage.js.map +1 -1
  39. package/dist/pages/VibesPage.js +49 -41
  40. package/dist/pages/VibesPage.js.map +1 -1
  41. package/dist/pages/WebhooksPage.js +162 -138
  42. package/dist/pages/WebhooksPage.js.map +1 -1
  43. package/dist/pages/tunnels/DomainsTab.js +54 -47
  44. package/dist/pages/tunnels/DomainsTab.js.map +1 -1
  45. package/package.json +1 -1
@@ -1,48 +1,50 @@
1
- import { useCompileDocsSiteMutation as e, useCreateDocsPageMutation as t, useCreateDocsSiteMutation as n, useDeleteDocsPageMutation as r, useDeleteDocsSiteMutation as ee, useDocsContentQuery as te, useGenerateDocsSignedUrlMutation as ne, useGetDocsRevisionLazyQuery as i, useGetDocsSiteQuery as a, useRollbackDocsRevisionMutation as re, useUpdateDocsPageMutation as ie, useUpdateDocsSiteMutation as ae, useUpdateDocsSiteVisibilityMutation as oe } from "../../generated/wspace-operations.js";
2
- import { useTr as se } from "../../shared/hooks/useTr.js";
3
- import { QuotaExhaustedDialog as o } from "../shared/QuotaExhaustedDialog.js";
4
- import { getQuotaDialogContent as s, isQuotaExhaustedError as c, markQuotaHandledLocally as l } from "../../utils/quotaUtils.js";
5
- import { useVibeNavigate as u } from "../../providers/VibeControlsProvider.js";
6
- import { LoadingState as d } from "../shared/LoadingState.js";
7
- import { ErrorState as f } from "../shared/ErrorState.js";
1
+ import { useCompileDocsSiteMutation as e, useCreateDocsPageMutation as t, useCreateDocsSiteMutation as n, useDeleteDocsPageMutation as r, useDeleteDocsSiteMutation as ee, useDocsContentQuery as te, useGenerateDocsSignedUrlMutation as ne, useGetDocsRevisionLazyQuery as re, useGetDocsSiteQuery as i, useRollbackDocsRevisionMutation as ie, useUpdateDocsPageMutation as ae, useUpdateDocsSiteMutation as oe, useUpdateDocsSiteVisibilityMutation as se } from "../../generated/wspace-operations.js";
2
+ import { useTr as ce } from "../../shared/hooks/useTr.js";
3
+ import { QuotaExhaustedDialog as a } from "../shared/QuotaExhaustedDialog.js";
4
+ import { getQuotaDialogContent as o, isQuotaExhaustedError as s, markQuotaHandledLocally as c } from "../../utils/quotaUtils.js";
5
+ import { useVibeNavigate as le } from "../../providers/VibeControlsProvider.js";
6
+ import { LoadingState as ue } from "../shared/LoadingState.js";
7
+ import { ErrorState as l } from "../shared/ErrorState.js";
8
8
  import "../shared/index.js";
9
- import { EntityShareButton as p } from "../sharing/EntityShareButton.js";
9
+ import { VIBE_PERMISSIONS as u } from "../../constants/permissions.js";
10
+ import { EntityShareButton as d } from "../sharing/EntityShareButton.js";
10
11
  import "../sharing/index.js";
11
- import { DocsEmptyState as m } from "./DocsEmptyState.js";
12
- import { DocsPreviewPanel as h } from "./DocsPreviewPanel.js";
13
- import { DocsEditPanel as g } from "./DocsEditPanel.js";
14
- import { useEffect as _, useRef as v, useState as y } from "react";
15
- import { AlertCircle as b, X as ce } from "lucide-react";
16
- import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
17
- import { resolveGatewayUrls as le } from "@burdenoff/fe-libs/shared/config";
12
+ import { DocsEmptyState as f } from "./DocsEmptyState.js";
13
+ import { DocsPreviewPanel as p } from "./DocsPreviewPanel.js";
14
+ import { DocsEditPanel as m } from "./DocsEditPanel.js";
15
+ import { useEffect as h, useRef as g, useState as _ } from "react";
16
+ import { AlertCircle as de, X as fe } from "lucide-react";
17
+ import { usePermissions as pe } from "@burdenoff/fe-libs/shared/providers/shell";
18
+ import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
19
+ import { resolveGatewayUrls as me } from "@burdenoff/fe-libs/shared/config";
18
20
  //#region src/components/docs/DocsTabPanel.tsx
19
- function w({ vibeId: w, ownerType: ue, ownerId: de }) {
20
- let T = se(), E = ue || "VIBE", D = de || w || "", [fe, O] = y("preview"), [k, A] = y(null), [j, M] = y(!1), [N, P] = y(null), [F, I] = y(""), [L, R] = y(null), z = u(), [B, V] = y(!1), [pe, H] = y(!1), { data: me, loading: he, error: U, refetch: W } = a({
21
+ function x({ vibeId: x, ownerType: he, ownerId: ge }) {
22
+ let S = ce(), { hasPermission: C, permissions: w } = pe(), T = C(u.DOCS_SITE_DELETE), _e = (Array.isArray(w) ? w : w?.permissionStrings)?.some?.((e) => e.startsWith("docs_page:")) ? C(u.DOCS_PAGE_DELETE) : T, E = he || "VIBE", D = ge || x || "", [O, k] = _("preview"), [A, j] = _(null), [M, N] = _(!1), [P, F] = _(null), [I, L] = _(""), [ve, R] = _(null), z = le(), [B, V] = _(!1), [ye, H] = _(!1), { data: be, loading: xe, error: U, refetch: W } = i({
21
23
  variables: {
22
24
  ownerType: E,
23
25
  ownerId: D
24
26
  },
25
27
  skip: !D,
26
28
  fetchPolicy: "cache-and-network"
27
- }), G = me?.vibecontrolsDocsSiteByOwner ?? null, K = G?.pages || [], { data: ge, loading: _e, refetch: ve } = te({
29
+ }), G = be?.vibecontrolsDocsSiteByOwner ?? null, K = G?.pages || [], { data: Se, loading: Ce, refetch: we } = te({
28
30
  variables: {
29
31
  siteId: G?.id || "",
30
- path: F
32
+ path: I
31
33
  },
32
34
  skip: !G?.id || !G.currentRevisionId,
33
35
  fetchPolicy: "network-only"
34
- }), ye = ge?.docsContent?.html ?? null, q = v(void 0);
35
- _(() => {
36
+ }), Te = Se?.docsContent?.html ?? null, q = g(void 0);
37
+ h(() => {
36
38
  let e = G?.currentRevisionId ?? null;
37
39
  if (q.current === void 0) {
38
40
  q.current = e;
39
41
  return;
40
42
  }
41
- e && e !== q.current && (q.current = e, ve());
43
+ e && e !== q.current && (q.current = e, we());
42
44
  }, [G?.currentRevisionId]);
43
- let be = le(), xe = G?.workspaceId ? `${be.workspaceBaseUrl}/workspaces/static/${G.workspaceId}/docs/${D}/` : null, [Se, { loading: Ce }] = n(), [we] = ae(), [Te] = oe(), [Ee, { loading: De }] = t(), [Oe] = ie(), [ke] = r(), [Ae] = e(), [je] = ne(), [Me] = re(), [Ne] = ee(), [Pe] = i({ fetchPolicy: "network-only" }), Fe = async (e = "DOCUSAURUS") => {
45
+ let Ee = me(), De = G?.workspaceId ? `${Ee.workspaceBaseUrl}/workspaces/static/${G.workspaceId}/docs/${D}/` : null, [Oe, { loading: ke }] = n(), [Ae] = oe(), [je] = se(), [Me, { loading: Ne }] = t(), [Pe] = ae(), [Fe] = r(), [Ie] = e(), [Le] = ne(), [Re] = ie(), [ze] = ee(), [J] = re({ fetchPolicy: "network-only" }), Be = async (e = "DOCUSAURUS") => {
44
46
  try {
45
- await Se({
47
+ await Oe({
46
48
  variables: { input: {
47
49
  ownerType: E,
48
50
  ownerId: D,
@@ -51,26 +53,26 @@ function w({ vibeId: w, ownerType: ue, ownerId: de }) {
51
53
  } },
52
54
  refetchQueries: ["GetDocsSite"],
53
55
  awaitRefetchQueries: !0
54
- }), O("edit");
56
+ }), k("edit");
55
57
  } catch (e) {
56
- if (c(e)) {
57
- l(), V(!0);
58
+ if (s(e)) {
59
+ c(), V(!0);
58
60
  return;
59
61
  }
60
62
  throw e;
61
63
  }
62
- }, Ie = async (e, t) => {
63
- await Oe({
64
+ }, Ve = async (e, t) => {
65
+ await Pe({
64
66
  variables: {
65
67
  id: e,
66
68
  input: t
67
69
  },
68
70
  context: { autoRefreshAfterMutation: !1 }
69
71
  });
70
- }, Le = async (e, t) => {
72
+ }, He = async (e, t) => {
71
73
  if (!G) return;
72
74
  let n = K.length, r = `page-${n + 1}`;
73
- await Ee({ variables: { input: {
75
+ await Me({ variables: { input: {
74
76
  siteId: G.id,
75
77
  parentId: e || null,
76
78
  slug: r,
@@ -80,39 +82,39 @@ function w({ vibeId: w, ownerType: ue, ownerId: de }) {
80
82
  sidebarPosition: n,
81
83
  category: t || null
82
84
  } } }), await W();
83
- }, Re = async (e) => {
84
- confirm("Delete this page?") && (await ke({ variables: { id: e } }), await W());
85
- }, J = async () => {
85
+ }, Ue = async (e) => {
86
+ confirm("Delete this page?") && (await Fe({ variables: { id: e } }), await W());
87
+ }, Y = async () => {
86
88
  if (G) {
87
- M(!0), P(null);
89
+ N(!0), F(null);
88
90
  try {
89
- let e = await Ae({ variables: {
91
+ let e = await Ie({ variables: {
90
92
  siteId: G.id,
91
93
  publish: !0
92
94
  } });
93
- if (e.error && c(e.error)) {
94
- l(), M(!1), H(!0);
95
+ if (e.error && s(e.error)) {
96
+ c(), N(!1), H(!0);
95
97
  return;
96
98
  }
97
- e.data?.compileDocsSite ? A(e.data.compileDocsSite) : (M(!1), P("Build could not be started — the server returned an empty response. Please try again."));
99
+ e.data?.compileDocsSite ? j(e.data.compileDocsSite) : (N(!1), F("Build could not be started — the server returned an empty response. Please try again."));
98
100
  } catch (e) {
99
- if (M(!1), c(e)) {
100
- l(), H(!0);
101
+ if (N(!1), s(e)) {
102
+ c(), H(!0);
101
103
  return;
102
104
  }
103
- P(e instanceof Error ? e.message : "Failed to start the build. Please try again.");
105
+ F(e instanceof Error ? e.message : "Failed to start the build. Please try again.");
104
106
  }
105
107
  }
106
- }, Y = async (e) => {
107
- let { data: t } = await Pe({ variables: { id: e } }), n = t?.docsRevision;
108
- return n && (A(n), [
108
+ }, X = async (e) => {
109
+ let { data: t } = await J({ variables: { id: e } }), n = t?.docsRevision;
110
+ return n && (j(n), [
109
111
  "SUCCEEDED",
110
112
  "PUBLISHED",
111
113
  "FAILED"
112
- ].includes(n.status) && (M(!1), (n.status === "PUBLISHED" || n.status === "SUCCEEDED") && (I(""), await W()))), n;
113
- }, ze = async (e) => {
114
+ ].includes(n.status) && (N(!1), (n.status === "PUBLISHED" || n.status === "SUCCEEDED") && (L(""), await W()))), n;
115
+ }, We = async (e) => {
114
116
  if (!G) return;
115
- e.visibility && e.visibility !== G.visibility && await Te({ variables: {
117
+ e.visibility && e.visibility !== G.visibility && await je({ variables: {
116
118
  id: G.id,
117
119
  visibility: e.visibility
118
120
  } });
@@ -121,23 +123,23 @@ function w({ vibeId: w, ownerType: ue, ownerId: de }) {
121
123
  provider: e.provider,
122
124
  providerConfig: e.providerConfig
123
125
  };
124
- Object.keys(t).length > 0 && await we({ variables: {
126
+ Object.keys(t).length > 0 && await Ae({ variables: {
125
127
  id: G.id,
126
128
  input: t
127
129
  } }), await W();
128
- }, Be = async () => {
130
+ }, Ge = async () => {
129
131
  if (!G?.currentRevisionId) return null;
130
132
  try {
131
- let { data: e } = await je({ variables: { siteId: G.id } });
133
+ let { data: e } = await Le({ variables: { siteId: G.id } });
132
134
  return e?.generateDocsSignedUrl?.url ?? null;
133
135
  } catch {
134
136
  return null;
135
137
  }
136
- }, X = async (e) => {
138
+ }, Ke = async (e) => {
137
139
  if (G && confirm("Roll back to this revision? The current published docs will be replaced.")) {
138
140
  R(e);
139
141
  try {
140
- await Me({ variables: {
142
+ await Re({ variables: {
141
143
  siteId: G.id,
142
144
  revisionId: e
143
145
  } }), await W();
@@ -145,19 +147,19 @@ function w({ vibeId: w, ownerType: ue, ownerId: de }) {
145
147
  R(null);
146
148
  }
147
149
  }
148
- }, Ve = async () => {
149
- G && confirm("Delete this docs site and all its pages and revisions? This cannot be undone.") && (await Ne({ variables: { id: G.id } }), await W());
150
+ }, qe = async () => {
151
+ G && confirm("Delete this docs site and all its pages and revisions? This cannot be undone.") && (await ze({ variables: { id: G.id } }), await W());
150
152
  };
151
- if (he && !G) return /* @__PURE__ */ S(d, { message: T("vibecontrols.docs.tab.loading", "Loading documentation...") });
152
- if (U && !G) return /* @__PURE__ */ S(f, {
153
- title: T("vibecontrols.docs.tab.loadFailed", "Failed to load docs"),
153
+ if (xe && !G) return /* @__PURE__ */ y(ue, { message: S("vibecontrols.docs.tab.loading", "Loading documentation...") });
154
+ if (U && !G) return /* @__PURE__ */ y(l, {
155
+ title: S("vibecontrols.docs.tab.loadFailed", "Failed to load docs"),
154
156
  message: U.message,
155
157
  onRetry: () => W()
156
158
  });
157
- if (!G) return /* @__PURE__ */ C(x, { children: [/* @__PURE__ */ S(m, {
158
- onCreate: Fe,
159
- loading: Ce
160
- }), /* @__PURE__ */ S(o, {
159
+ if (!G) return /* @__PURE__ */ b(v, { children: [/* @__PURE__ */ y(f, {
160
+ onCreate: Be,
161
+ loading: ke
162
+ }), /* @__PURE__ */ y(a, {
161
163
  isOpen: B,
162
164
  onClose: () => V(!1),
163
165
  onConfirm: () => {
@@ -166,30 +168,30 @@ function w({ vibeId: w, ownerType: ue, ownerId: de }) {
166
168
  title: "Docs Site Quota Reached",
167
169
  message: "You have reached the documentation site limit for your current plan. Upgrade to create more docs sites."
168
170
  })] });
169
- let Z = N ? /* @__PURE__ */ C("div", {
171
+ let Z = P ? /* @__PURE__ */ b("div", {
170
172
  className: "flex items-center gap-2 px-4 py-2 mb-2 bg-status-error-bg-subtle text-status-error-text text-sm rounded-md",
171
173
  children: [
172
- /* @__PURE__ */ S(b, { className: "size-4 shrink-0" }),
173
- /* @__PURE__ */ S("span", {
174
+ /* @__PURE__ */ y(de, { className: "size-4 shrink-0" }),
175
+ /* @__PURE__ */ y("span", {
174
176
  className: "flex-1",
175
- children: N
177
+ children: P
176
178
  }),
177
- /* @__PURE__ */ S("button", {
179
+ /* @__PURE__ */ y("button", {
178
180
  type: "button",
179
- onClick: () => P(null),
181
+ onClick: () => F(null),
180
182
  className: "p-0.5 hover:opacity-70",
181
- children: /* @__PURE__ */ S(ce, { className: "size-3.5" })
183
+ children: /* @__PURE__ */ y(fe, { className: "size-3.5" })
182
184
  })
183
185
  ]
184
- }) : null, Q = /* @__PURE__ */ S(o, {
185
- isOpen: pe,
186
+ }) : null, Q = /* @__PURE__ */ y(a, {
187
+ isOpen: ye,
186
188
  onClose: () => H(!1),
187
189
  onConfirm: () => {
188
190
  H(!1), z("/billing/plans");
189
191
  },
190
- title: s("docs-compilation").title,
191
- message: s("docs-compilation").message
192
- }), $ = /* @__PURE__ */ S(p, {
192
+ title: o("docs-compilation").title,
193
+ message: o("docs-compilation").message
194
+ }), $ = /* @__PURE__ */ y(d, {
193
195
  entity: "docs",
194
196
  resource: {
195
197
  id: G.id,
@@ -200,45 +202,45 @@ function w({ vibeId: w, ownerType: ue, ownerId: de }) {
200
202
  ownerType: E
201
203
  }
202
204
  },
203
- label: T("vibecontrols.docs.share", "Share")
205
+ label: S("vibecontrols.docs.share", "Share")
204
206
  });
205
- return fe === "edit" ? /* @__PURE__ */ C(x, { children: [
207
+ return O === "edit" ? /* @__PURE__ */ b(v, { children: [
206
208
  Z,
207
209
  Q,
208
- /* @__PURE__ */ S(g, {
210
+ /* @__PURE__ */ y(m, {
209
211
  site: G,
210
212
  pages: K,
211
213
  shareSlot: $,
212
- onBack: () => O("preview"),
213
- onSavePage: Ie,
214
- onAddPage: Le,
215
- pageAdding: De,
216
- onDeletePage: Re,
217
- onCompile: J,
218
- onSaveSettings: ze,
219
- onRollback: X,
220
- onDeleteSite: Ve,
221
- rollingBack: L,
222
- compileRevision: k,
223
- onPollRevision: Y,
224
- compiling: j
214
+ onBack: () => k("preview"),
215
+ onSavePage: Ve,
216
+ onAddPage: He,
217
+ pageAdding: Ne,
218
+ onDeletePage: _e ? Ue : void 0,
219
+ onCompile: Y,
220
+ onSaveSettings: We,
221
+ onRollback: Ke,
222
+ onDeleteSite: T ? qe : void 0,
223
+ rollingBack: ve,
224
+ compileRevision: A,
225
+ onPollRevision: X,
226
+ compiling: M
225
227
  })
226
- ] }) : /* @__PURE__ */ C(x, { children: [
228
+ ] }) : /* @__PURE__ */ b(v, { children: [
227
229
  Z,
228
230
  Q,
229
- /* @__PURE__ */ S(h, {
231
+ /* @__PURE__ */ y(p, {
230
232
  site: G,
231
233
  pages: K,
232
234
  shareSlot: $,
233
- selectedPageSlug: F,
234
- onSelectPage: I,
235
- docsBaseUrl: G.currentRevisionId ? xe ?? null : null,
236
- docsHtml: G.currentRevisionId ? ye : null,
237
- docsContentLoading: _e,
238
- onEdit: () => O("edit"),
239
- onCompile: J,
240
- onSettings: () => O("edit"),
241
- onGetShareUrl: Be,
235
+ selectedPageSlug: I,
236
+ onSelectPage: L,
237
+ docsBaseUrl: G.currentRevisionId ? De ?? null : null,
238
+ docsHtml: G.currentRevisionId ? Te : null,
239
+ docsContentLoading: Ce,
240
+ onEdit: () => k("edit"),
241
+ onCompile: Y,
242
+ onSettings: () => k("edit"),
243
+ onGetShareUrl: Ge,
242
244
  onOpenFullScreen: () => {
243
245
  z(`/${{
244
246
  VIBE: "vibes",
@@ -246,11 +248,11 @@ function w({ vibeId: w, ownerType: ue, ownerId: de }) {
246
248
  COMPONENT: "components"
247
249
  }[E] || "vibes"}/${D}/docs`);
248
250
  },
249
- compileRevision: k,
250
- onPollRevision: Y,
251
- compiling: j
251
+ compileRevision: A,
252
+ onPollRevision: X,
253
+ compiling: M
252
254
  }),
253
- /* @__PURE__ */ S(o, {
255
+ /* @__PURE__ */ y(a, {
254
256
  isOpen: B,
255
257
  onClose: () => V(!1),
256
258
  onConfirm: () => {
@@ -262,6 +264,6 @@ function w({ vibeId: w, ownerType: ue, ownerId: de }) {
262
264
  ] });
263
265
  }
264
266
  //#endregion
265
- export { w as DocsTabPanel };
267
+ export { x as DocsTabPanel };
266
268
 
267
269
  //# sourceMappingURL=DocsTabPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DocsTabPanel.js","names":[],"sources":["../../../src/components/docs/DocsTabPanel.tsx"],"sourcesContent":["import { useState, useEffect, useRef } from 'react';\nimport { AlertCircle, X } from 'lucide-react';\nimport { LoadingState, ErrorState, QuotaExhaustedDialog } from '@/components/shared';\nimport { EntityShareButton } from '@/components/sharing';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport { resolveGatewayUrls } from '@burdenoff/fe-libs/shared/config';\nimport { DocsEmptyState } from './DocsEmptyState';\nimport { DocsPreviewPanel } from './DocsPreviewPanel';\nimport { DocsEditPanel } from './DocsEditPanel';\nimport type { DocsSite, DocsRevision } from './types';\nimport {\n isQuotaExhaustedError,\n markQuotaHandledLocally,\n getQuotaDialogContent,\n} from '@/utils/quotaUtils';\nimport { useTr } from '../../shared/hooks/useTr';\nimport {\n useGetDocsSiteQuery,\n useCreateDocsSiteMutation,\n useUpdateDocsSiteMutation,\n useUpdateDocsSiteVisibilityMutation,\n useCreateDocsPageMutation,\n useUpdateDocsPageMutation,\n useDeleteDocsPageMutation,\n useCompileDocsSiteMutation,\n useDocsContentQuery,\n useGetDocsRevisionLazyQuery,\n useGenerateDocsSignedUrlMutation,\n useRollbackDocsRevisionMutation,\n useDeleteDocsSiteMutation,\n} from '@/generated/wspace-operations';\n\ninterface DocsTabPanelProps {\n vibeId?: string;\n ownerType?: string;\n ownerId?: string;\n}\n\nexport function DocsTabPanel({ vibeId, ownerType, ownerId }: DocsTabPanelProps) {\n const tr = useTr();\n const effectiveOwnerType = ownerType || 'VIBE';\n const effectiveOwnerId = ownerId || vibeId || '';\n const [mode, setMode] = useState<'preview' | 'edit'>('preview');\n const [compileRevision, setCompileRevision] = useState<DocsRevision | null>(null);\n const [compiling, setCompiling] = useState(false);\n const [compileError, setCompileError] = useState<string | null>(null);\n const [selectedPageSlug, setSelectedPageSlug] = useState('');\n const [rollingBack, setRollingBack] = useState<string | null>(null);\n const navigate = useVibeNavigate();\n const [showQuotaExhausted, setShowQuotaExhausted] = useState(false);\n const [showCompileQuotaExhausted, setShowCompileQuotaExhausted] = useState(false);\n\n // Queries\n const { data, loading, error, refetch } = useGetDocsSiteQuery({\n variables: { ownerType: effectiveOwnerType as any, ownerId: effectiveOwnerId },\n skip: !effectiveOwnerId,\n fetchPolicy: 'cache-and-network',\n });\n\n const site = (data?.vibecontrolsDocsSiteByOwner ?? null) as DocsSite | null;\n const pages = site?.pages || [];\n\n const {\n data: docsContentData,\n loading: docsContentLoading,\n refetch: refetchDocsContent,\n } = useDocsContentQuery({\n variables: { siteId: site?.id || '', path: selectedPageSlug },\n skip: !site?.id || !site.currentRevisionId,\n fetchPolicy: 'network-only',\n });\n const docsHtml = docsContentData?.docsContent?.html ?? null;\n\n // Re-fetch docs content whenever currentRevisionId changes (compile finished or first publish).\n // This runs post-render so skip:false is guaranteed — imperative calls during async handlers\n // are no-ops when skip is still true in the closure.\n const prevRevisionIdRef = useRef<string | null | undefined>(undefined);\n useEffect(() => {\n const currentId = site?.currentRevisionId ?? null;\n if (prevRevisionIdRef.current === undefined) {\n prevRevisionIdRef.current = currentId;\n return;\n }\n if (currentId && currentId !== prevRevisionIdRef.current) {\n prevRevisionIdRef.current = currentId;\n refetchDocsContent();\n }\n }, [site?.currentRevisionId]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Compute gateway docs URL for iframe src (workspaceId prefix for isolation)\n const gatewayUrls = resolveGatewayUrls();\n const docsBaseUrl = site?.workspaceId\n ? `${gatewayUrls.workspaceBaseUrl}/workspaces/static/${site.workspaceId}/docs/${effectiveOwnerId}/`\n : null;\n\n // Mutations\n const [createSiteMutation, { loading: creating }] = useCreateDocsSiteMutation();\n const [updateSiteMutation] = useUpdateDocsSiteMutation();\n const [updateVisibilityMutation] = useUpdateDocsSiteVisibilityMutation();\n const [createPageMutation, { loading: pageAdding }] = useCreateDocsPageMutation();\n const [updatePageMutation] = useUpdateDocsPageMutation();\n const [deletePageMutation] = useDeleteDocsPageMutation();\n const [compileMutation] = useCompileDocsSiteMutation();\n const [generateSignedUrl] = useGenerateDocsSignedUrlMutation();\n const [rollbackRevision] = useRollbackDocsRevisionMutation();\n const [deleteSiteMutation] = useDeleteDocsSiteMutation();\n const [fetchRevision] = useGetDocsRevisionLazyQuery({\n fetchPolicy: 'network-only',\n });\n\n // Handlers\n const handleCreateSite = async (\n provider: 'DOCUSAURUS' | 'MKDOCS' | 'VITEPRESS' = 'DOCUSAURUS'\n ) => {\n try {\n await createSiteMutation({\n variables: {\n input: {\n ownerType: effectiveOwnerType as any,\n ownerId: effectiveOwnerId,\n name: 'Documentation',\n provider: provider as any,\n },\n },\n refetchQueries: ['GetDocsSite'],\n awaitRefetchQueries: true,\n });\n setMode('edit');\n } catch (err) {\n if (isQuotaExhaustedError(err)) {\n markQuotaHandledLocally();\n setShowQuotaExhausted(true);\n return;\n }\n throw err;\n }\n };\n\n const handleSavePage = async (\n id: string,\n data: { title?: string; content?: string; slug?: string }\n ) => {\n await updatePageMutation({\n variables: { id, input: data },\n context: { autoRefreshAfterMutation: false },\n });\n };\n\n const handleAddPage = async (parentId?: string, category?: string) => {\n if (!site) return;\n const pageCount = pages.length;\n const slug = `page-${pageCount + 1}`;\n await createPageMutation({\n variables: {\n input: {\n siteId: site.id,\n parentId: parentId || null,\n slug,\n title: `New Page ${pageCount + 1}`,\n content: '# New Page\\n\\nStart writing here...',\n status: 'DRAFT',\n sidebarPosition: pageCount,\n category: category || null,\n },\n },\n });\n await refetch();\n };\n\n const handleDeletePage = async (pageId: string) => {\n if (!confirm('Delete this page?')) return;\n await deletePageMutation({ variables: { id: pageId } });\n await refetch();\n };\n\n const handleCompile = async () => {\n if (!site) return;\n setCompiling(true);\n setCompileError(null);\n try {\n const result = await compileMutation({\n variables: { siteId: site.id, publish: true },\n });\n if (result.error && isQuotaExhaustedError(result.error)) {\n markQuotaHandledLocally();\n setCompiling(false);\n setShowCompileQuotaExhausted(true);\n return;\n }\n if (result.data?.compileDocsSite) {\n setCompileRevision(result.data.compileDocsSite as DocsRevision);\n } else {\n setCompiling(false);\n setCompileError(\n 'Build could not be started — the server returned an empty response. Please try again.'\n );\n }\n } catch (err) {\n setCompiling(false);\n if (isQuotaExhaustedError(err)) {\n markQuotaHandledLocally();\n setShowCompileQuotaExhausted(true);\n return;\n }\n setCompileError(\n err instanceof Error ? err.message : 'Failed to start the build. Please try again.'\n );\n }\n };\n\n const handlePollRevision = async (revisionId: string): Promise<DocsRevision | null> => {\n const { data: revData } = await fetchRevision({ variables: { id: revisionId } });\n const rev = revData?.docsRevision as DocsRevision | null;\n if (rev) {\n setCompileRevision(rev);\n const done = ['SUCCEEDED', 'PUBLISHED', 'FAILED'].includes(rev.status);\n if (done) {\n setCompiling(false);\n if (rev.status === 'PUBLISHED' || rev.status === 'SUCCEEDED') {\n setSelectedPageSlug('');\n await refetch();\n }\n }\n }\n return rev;\n };\n\n const handleSaveSettings = async (data: {\n name?: string;\n visibility?: 'PRIVATE' | 'PUBLIC';\n provider?: 'DOCUSAURUS' | 'MKDOCS' | 'VITEPRESS';\n providerConfig?: Record<string, unknown>;\n }) => {\n if (!site) return;\n if (data.visibility && data.visibility !== site.visibility) {\n await updateVisibilityMutation({ variables: { id: site.id, visibility: data.visibility } });\n }\n const rest = {\n name: data.name,\n provider: data.provider,\n providerConfig: data.providerConfig,\n };\n if (Object.keys(rest).length > 0) {\n await updateSiteMutation({ variables: { id: site.id, input: rest } });\n }\n await refetch();\n };\n\n const handleGetShareUrl = async (): Promise<string | null> => {\n if (!site?.currentRevisionId) return null;\n try {\n const { data: urlData } = await generateSignedUrl({ variables: { siteId: site.id } });\n return urlData?.generateDocsSignedUrl?.url ?? null;\n } catch {\n return null;\n }\n };\n\n const handleRollback = async (revisionId: string) => {\n if (!site) return;\n if (!confirm('Roll back to this revision? The current published docs will be replaced.'))\n return;\n setRollingBack(revisionId);\n try {\n await rollbackRevision({ variables: { siteId: site.id, revisionId } });\n await refetch();\n } finally {\n setRollingBack(null);\n }\n };\n\n const handleDeleteSite = async () => {\n if (!site) return;\n if (!confirm('Delete this docs site and all its pages and revisions? This cannot be undone.'))\n return;\n await deleteSiteMutation({ variables: { id: site.id } });\n await refetch();\n };\n\n // Loading / Error states\n if (loading && !site) {\n return (\n <LoadingState message={tr('vibecontrols.docs.tab.loading', 'Loading documentation...')} />\n );\n }\n\n if (error && !site) {\n return (\n <ErrorState\n title={tr('vibecontrols.docs.tab.loadFailed', 'Failed to load docs')}\n message={error.message}\n onRetry={() => refetch()}\n />\n );\n }\n\n // No site yet\n if (!site) {\n return (\n <>\n <DocsEmptyState onCreate={handleCreateSite} loading={creating} />\n <QuotaExhaustedDialog\n isOpen={showQuotaExhausted}\n onClose={() => setShowQuotaExhausted(false)}\n onConfirm={() => {\n setShowQuotaExhausted(false);\n navigate('/billing/plans');\n }}\n title=\"Docs Site Quota Reached\"\n message=\"You have reached the documentation site limit for your current plan. Upgrade to create more docs sites.\"\n />\n </>\n );\n }\n\n const compileErrorBanner = compileError ? (\n <div className=\"flex items-center gap-2 px-4 py-2 mb-2 bg-status-error-bg-subtle text-status-error-text text-sm rounded-md\">\n <AlertCircle className=\"size-4 shrink-0\" />\n <span className=\"flex-1\">{compileError}</span>\n <button\n type=\"button\"\n onClick={() => setCompileError(null)}\n className=\"p-0.5 hover:opacity-70\"\n >\n <X className=\"size-3.5\" />\n </button>\n </div>\n ) : null;\n\n const compileQuotaDialog = (\n <QuotaExhaustedDialog\n isOpen={showCompileQuotaExhausted}\n onClose={() => setShowCompileQuotaExhausted(false)}\n onConfirm={() => {\n setShowCompileQuotaExhausted(false);\n navigate('/billing/plans');\n }}\n title={getQuotaDialogContent('docs-compilation').title}\n message={getQuotaDialogContent('docs-compilation').message}\n />\n );\n\n // Generic grant-based sharing for the docs site. Owner-keyed (no read-by-id\n // query) so we pass the `(ownerId, ownerType)` pair the controller reads by.\n const shareSlot = (\n <EntityShareButton\n entity=\"docs\"\n resource={{\n id: site.id,\n name: site.name,\n vibeId: site.vibeId ?? null,\n owner: { ownerId: effectiveOwnerId, ownerType: effectiveOwnerType },\n }}\n label={tr('vibecontrols.docs.share', 'Share')}\n />\n );\n\n // Edit mode\n if (mode === 'edit') {\n return (\n <>\n {compileErrorBanner}\n {compileQuotaDialog}\n <DocsEditPanel\n site={site}\n pages={pages}\n shareSlot={shareSlot}\n onBack={() => setMode('preview')}\n onSavePage={handleSavePage}\n onAddPage={handleAddPage}\n pageAdding={pageAdding}\n onDeletePage={handleDeletePage}\n onCompile={handleCompile}\n onSaveSettings={handleSaveSettings}\n onRollback={handleRollback}\n onDeleteSite={handleDeleteSite}\n rollingBack={rollingBack}\n compileRevision={compileRevision}\n onPollRevision={handlePollRevision}\n compiling={compiling}\n />\n </>\n );\n }\n\n // Preview mode\n return (\n <>\n {compileErrorBanner}\n {compileQuotaDialog}\n <DocsPreviewPanel\n site={site}\n pages={pages}\n shareSlot={shareSlot}\n selectedPageSlug={selectedPageSlug}\n onSelectPage={setSelectedPageSlug}\n docsBaseUrl={site.currentRevisionId ? (docsBaseUrl ?? null) : null}\n docsHtml={site.currentRevisionId ? docsHtml : null}\n docsContentLoading={docsContentLoading}\n onEdit={() => setMode('edit')}\n onCompile={handleCompile}\n onSettings={() => setMode('edit')}\n onGetShareUrl={handleGetShareUrl}\n onOpenFullScreen={() => {\n const pathMap: Record<string, string> = {\n VIBE: 'vibes',\n CATALOG: 'catalogs',\n COMPONENT: 'components',\n };\n const segment = pathMap[effectiveOwnerType] || 'vibes';\n navigate(`/${segment}/${effectiveOwnerId}/docs`);\n }}\n compileRevision={compileRevision}\n onPollRevision={handlePollRevision}\n compiling={compiling}\n />\n <QuotaExhaustedDialog\n isOpen={showQuotaExhausted}\n onClose={() => setShowQuotaExhausted(false)}\n onConfirm={() => {\n setShowQuotaExhausted(false);\n navigate('/billing/plans');\n }}\n title=\"Docs Site Quota Reached\"\n message=\"You have reached the documentation site limit for your current plan. Upgrade to create more docs sites.\"\n />\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DocsTabPanel.js","names":[],"sources":["../../../src/components/docs/DocsTabPanel.tsx"],"sourcesContent":["import { useState, useEffect, useRef } from 'react';\nimport { AlertCircle, X } from 'lucide-react';\nimport { LoadingState, ErrorState, QuotaExhaustedDialog } from '@/components/shared';\nimport { EntityShareButton } from '@/components/sharing';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { VIBE_PERMISSIONS } from '@/constants/permissions';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport { resolveGatewayUrls } from '@burdenoff/fe-libs/shared/config';\nimport { DocsEmptyState } from './DocsEmptyState';\nimport { DocsPreviewPanel } from './DocsPreviewPanel';\nimport { DocsEditPanel } from './DocsEditPanel';\nimport type { DocsSite, DocsRevision } from './types';\nimport {\n isQuotaExhaustedError,\n markQuotaHandledLocally,\n getQuotaDialogContent,\n} from '@/utils/quotaUtils';\nimport { useTr } from '../../shared/hooks/useTr';\nimport {\n useGetDocsSiteQuery,\n useCreateDocsSiteMutation,\n useUpdateDocsSiteMutation,\n useUpdateDocsSiteVisibilityMutation,\n useCreateDocsPageMutation,\n useUpdateDocsPageMutation,\n useDeleteDocsPageMutation,\n useCompileDocsSiteMutation,\n useDocsContentQuery,\n useGetDocsRevisionLazyQuery,\n useGenerateDocsSignedUrlMutation,\n useRollbackDocsRevisionMutation,\n useDeleteDocsSiteMutation,\n} from '@/generated/wspace-operations';\n\ninterface DocsTabPanelProps {\n vibeId?: string;\n ownerType?: string;\n ownerId?: string;\n}\n\nexport function DocsTabPanel({ vibeId, ownerType, ownerId }: DocsTabPanelProps) {\n const tr = useTr();\n const { hasPermission, permissions } = usePermissions();\n // `deleteDocsSite` is @rbac(action:\"delete\", resource:\"docs_site\") — a seeded\n // resource, so it's safe to hard-hide the Delete-site control on this grant.\n const canDeleteDocsSite = hasPermission(VIBE_PERMISSIONS.DOCS_SITE_DELETE);\n // `deleteDocsPage` enforces `docs_page:delete`, a newer resourceType whose\n // grants only reach pre-existing workspaces after a role re-sync. Enforce the\n // precise page grant only when it's registered; otherwise fall back to the\n // reliably-seeded parent `docs_site:delete` so un-backfilled workspaces don't\n // lock the control away from legitimate site admins.\n const docsPagePermsRegistered = (\n Array.isArray(permissions) ? permissions : permissions?.permissionStrings\n )?.some?.((p: string) => p.startsWith('docs_page:'));\n const canDeleteDocsPage = docsPagePermsRegistered\n ? hasPermission(VIBE_PERMISSIONS.DOCS_PAGE_DELETE)\n : canDeleteDocsSite;\n const effectiveOwnerType = ownerType || 'VIBE';\n const effectiveOwnerId = ownerId || vibeId || '';\n const [mode, setMode] = useState<'preview' | 'edit'>('preview');\n const [compileRevision, setCompileRevision] = useState<DocsRevision | null>(null);\n const [compiling, setCompiling] = useState(false);\n const [compileError, setCompileError] = useState<string | null>(null);\n const [selectedPageSlug, setSelectedPageSlug] = useState('');\n const [rollingBack, setRollingBack] = useState<string | null>(null);\n const navigate = useVibeNavigate();\n const [showQuotaExhausted, setShowQuotaExhausted] = useState(false);\n const [showCompileQuotaExhausted, setShowCompileQuotaExhausted] = useState(false);\n\n // Queries\n const { data, loading, error, refetch } = useGetDocsSiteQuery({\n variables: { ownerType: effectiveOwnerType as any, ownerId: effectiveOwnerId },\n skip: !effectiveOwnerId,\n fetchPolicy: 'cache-and-network',\n });\n\n const site = (data?.vibecontrolsDocsSiteByOwner ?? null) as DocsSite | null;\n const pages = site?.pages || [];\n\n const {\n data: docsContentData,\n loading: docsContentLoading,\n refetch: refetchDocsContent,\n } = useDocsContentQuery({\n variables: { siteId: site?.id || '', path: selectedPageSlug },\n skip: !site?.id || !site.currentRevisionId,\n fetchPolicy: 'network-only',\n });\n const docsHtml = docsContentData?.docsContent?.html ?? null;\n\n // Re-fetch docs content whenever currentRevisionId changes (compile finished or first publish).\n // This runs post-render so skip:false is guaranteed — imperative calls during async handlers\n // are no-ops when skip is still true in the closure.\n const prevRevisionIdRef = useRef<string | null | undefined>(undefined);\n useEffect(() => {\n const currentId = site?.currentRevisionId ?? null;\n if (prevRevisionIdRef.current === undefined) {\n prevRevisionIdRef.current = currentId;\n return;\n }\n if (currentId && currentId !== prevRevisionIdRef.current) {\n prevRevisionIdRef.current = currentId;\n refetchDocsContent();\n }\n }, [site?.currentRevisionId]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Compute gateway docs URL for iframe src (workspaceId prefix for isolation)\n const gatewayUrls = resolveGatewayUrls();\n const docsBaseUrl = site?.workspaceId\n ? `${gatewayUrls.workspaceBaseUrl}/workspaces/static/${site.workspaceId}/docs/${effectiveOwnerId}/`\n : null;\n\n // Mutations\n const [createSiteMutation, { loading: creating }] = useCreateDocsSiteMutation();\n const [updateSiteMutation] = useUpdateDocsSiteMutation();\n const [updateVisibilityMutation] = useUpdateDocsSiteVisibilityMutation();\n const [createPageMutation, { loading: pageAdding }] = useCreateDocsPageMutation();\n const [updatePageMutation] = useUpdateDocsPageMutation();\n const [deletePageMutation] = useDeleteDocsPageMutation();\n const [compileMutation] = useCompileDocsSiteMutation();\n const [generateSignedUrl] = useGenerateDocsSignedUrlMutation();\n const [rollbackRevision] = useRollbackDocsRevisionMutation();\n const [deleteSiteMutation] = useDeleteDocsSiteMutation();\n const [fetchRevision] = useGetDocsRevisionLazyQuery({\n fetchPolicy: 'network-only',\n });\n\n // Handlers\n const handleCreateSite = async (\n provider: 'DOCUSAURUS' | 'MKDOCS' | 'VITEPRESS' = 'DOCUSAURUS'\n ) => {\n try {\n await createSiteMutation({\n variables: {\n input: {\n ownerType: effectiveOwnerType as any,\n ownerId: effectiveOwnerId,\n name: 'Documentation',\n provider: provider as any,\n },\n },\n refetchQueries: ['GetDocsSite'],\n awaitRefetchQueries: true,\n });\n setMode('edit');\n } catch (err) {\n if (isQuotaExhaustedError(err)) {\n markQuotaHandledLocally();\n setShowQuotaExhausted(true);\n return;\n }\n throw err;\n }\n };\n\n const handleSavePage = async (\n id: string,\n data: { title?: string; content?: string; slug?: string }\n ) => {\n await updatePageMutation({\n variables: { id, input: data },\n context: { autoRefreshAfterMutation: false },\n });\n };\n\n const handleAddPage = async (parentId?: string, category?: string) => {\n if (!site) return;\n const pageCount = pages.length;\n const slug = `page-${pageCount + 1}`;\n await createPageMutation({\n variables: {\n input: {\n siteId: site.id,\n parentId: parentId || null,\n slug,\n title: `New Page ${pageCount + 1}`,\n content: '# New Page\\n\\nStart writing here...',\n status: 'DRAFT',\n sidebarPosition: pageCount,\n category: category || null,\n },\n },\n });\n await refetch();\n };\n\n const handleDeletePage = async (pageId: string) => {\n if (!confirm('Delete this page?')) return;\n await deletePageMutation({ variables: { id: pageId } });\n await refetch();\n };\n\n const handleCompile = async () => {\n if (!site) return;\n setCompiling(true);\n setCompileError(null);\n try {\n const result = await compileMutation({\n variables: { siteId: site.id, publish: true },\n });\n if (result.error && isQuotaExhaustedError(result.error)) {\n markQuotaHandledLocally();\n setCompiling(false);\n setShowCompileQuotaExhausted(true);\n return;\n }\n if (result.data?.compileDocsSite) {\n setCompileRevision(result.data.compileDocsSite as DocsRevision);\n } else {\n setCompiling(false);\n setCompileError(\n 'Build could not be started — the server returned an empty response. Please try again.'\n );\n }\n } catch (err) {\n setCompiling(false);\n if (isQuotaExhaustedError(err)) {\n markQuotaHandledLocally();\n setShowCompileQuotaExhausted(true);\n return;\n }\n setCompileError(\n err instanceof Error ? err.message : 'Failed to start the build. Please try again.'\n );\n }\n };\n\n const handlePollRevision = async (revisionId: string): Promise<DocsRevision | null> => {\n const { data: revData } = await fetchRevision({ variables: { id: revisionId } });\n const rev = revData?.docsRevision as DocsRevision | null;\n if (rev) {\n setCompileRevision(rev);\n const done = ['SUCCEEDED', 'PUBLISHED', 'FAILED'].includes(rev.status);\n if (done) {\n setCompiling(false);\n if (rev.status === 'PUBLISHED' || rev.status === 'SUCCEEDED') {\n setSelectedPageSlug('');\n await refetch();\n }\n }\n }\n return rev;\n };\n\n const handleSaveSettings = async (data: {\n name?: string;\n visibility?: 'PRIVATE' | 'PUBLIC';\n provider?: 'DOCUSAURUS' | 'MKDOCS' | 'VITEPRESS';\n providerConfig?: Record<string, unknown>;\n }) => {\n if (!site) return;\n if (data.visibility && data.visibility !== site.visibility) {\n await updateVisibilityMutation({ variables: { id: site.id, visibility: data.visibility } });\n }\n const rest = {\n name: data.name,\n provider: data.provider,\n providerConfig: data.providerConfig,\n };\n if (Object.keys(rest).length > 0) {\n await updateSiteMutation({ variables: { id: site.id, input: rest } });\n }\n await refetch();\n };\n\n const handleGetShareUrl = async (): Promise<string | null> => {\n if (!site?.currentRevisionId) return null;\n try {\n const { data: urlData } = await generateSignedUrl({ variables: { siteId: site.id } });\n return urlData?.generateDocsSignedUrl?.url ?? null;\n } catch {\n return null;\n }\n };\n\n const handleRollback = async (revisionId: string) => {\n if (!site) return;\n if (!confirm('Roll back to this revision? The current published docs will be replaced.'))\n return;\n setRollingBack(revisionId);\n try {\n await rollbackRevision({ variables: { siteId: site.id, revisionId } });\n await refetch();\n } finally {\n setRollingBack(null);\n }\n };\n\n const handleDeleteSite = async () => {\n if (!site) return;\n if (!confirm('Delete this docs site and all its pages and revisions? This cannot be undone.'))\n return;\n await deleteSiteMutation({ variables: { id: site.id } });\n await refetch();\n };\n\n // Loading / Error states\n if (loading && !site) {\n return (\n <LoadingState message={tr('vibecontrols.docs.tab.loading', 'Loading documentation...')} />\n );\n }\n\n if (error && !site) {\n return (\n <ErrorState\n title={tr('vibecontrols.docs.tab.loadFailed', 'Failed to load docs')}\n message={error.message}\n onRetry={() => refetch()}\n />\n );\n }\n\n // No site yet\n if (!site) {\n return (\n <>\n <DocsEmptyState onCreate={handleCreateSite} loading={creating} />\n <QuotaExhaustedDialog\n isOpen={showQuotaExhausted}\n onClose={() => setShowQuotaExhausted(false)}\n onConfirm={() => {\n setShowQuotaExhausted(false);\n navigate('/billing/plans');\n }}\n title=\"Docs Site Quota Reached\"\n message=\"You have reached the documentation site limit for your current plan. Upgrade to create more docs sites.\"\n />\n </>\n );\n }\n\n const compileErrorBanner = compileError ? (\n <div className=\"flex items-center gap-2 px-4 py-2 mb-2 bg-status-error-bg-subtle text-status-error-text text-sm rounded-md\">\n <AlertCircle className=\"size-4 shrink-0\" />\n <span className=\"flex-1\">{compileError}</span>\n <button\n type=\"button\"\n onClick={() => setCompileError(null)}\n className=\"p-0.5 hover:opacity-70\"\n >\n <X className=\"size-3.5\" />\n </button>\n </div>\n ) : null;\n\n const compileQuotaDialog = (\n <QuotaExhaustedDialog\n isOpen={showCompileQuotaExhausted}\n onClose={() => setShowCompileQuotaExhausted(false)}\n onConfirm={() => {\n setShowCompileQuotaExhausted(false);\n navigate('/billing/plans');\n }}\n title={getQuotaDialogContent('docs-compilation').title}\n message={getQuotaDialogContent('docs-compilation').message}\n />\n );\n\n // Generic grant-based sharing for the docs site. Owner-keyed (no read-by-id\n // query) so we pass the `(ownerId, ownerType)` pair the controller reads by.\n const shareSlot = (\n <EntityShareButton\n entity=\"docs\"\n resource={{\n id: site.id,\n name: site.name,\n vibeId: site.vibeId ?? null,\n owner: { ownerId: effectiveOwnerId, ownerType: effectiveOwnerType },\n }}\n label={tr('vibecontrols.docs.share', 'Share')}\n />\n );\n\n // Edit mode\n if (mode === 'edit') {\n return (\n <>\n {compileErrorBanner}\n {compileQuotaDialog}\n <DocsEditPanel\n site={site}\n pages={pages}\n shareSlot={shareSlot}\n onBack={() => setMode('preview')}\n onSavePage={handleSavePage}\n onAddPage={handleAddPage}\n pageAdding={pageAdding}\n onDeletePage={canDeleteDocsPage ? handleDeletePage : undefined}\n onCompile={handleCompile}\n onSaveSettings={handleSaveSettings}\n onRollback={handleRollback}\n onDeleteSite={canDeleteDocsSite ? handleDeleteSite : undefined}\n rollingBack={rollingBack}\n compileRevision={compileRevision}\n onPollRevision={handlePollRevision}\n compiling={compiling}\n />\n </>\n );\n }\n\n // Preview mode\n return (\n <>\n {compileErrorBanner}\n {compileQuotaDialog}\n <DocsPreviewPanel\n site={site}\n pages={pages}\n shareSlot={shareSlot}\n selectedPageSlug={selectedPageSlug}\n onSelectPage={setSelectedPageSlug}\n docsBaseUrl={site.currentRevisionId ? (docsBaseUrl ?? null) : null}\n docsHtml={site.currentRevisionId ? docsHtml : null}\n docsContentLoading={docsContentLoading}\n onEdit={() => setMode('edit')}\n onCompile={handleCompile}\n onSettings={() => setMode('edit')}\n onGetShareUrl={handleGetShareUrl}\n onOpenFullScreen={() => {\n const pathMap: Record<string, string> = {\n VIBE: 'vibes',\n CATALOG: 'catalogs',\n COMPONENT: 'components',\n };\n const segment = pathMap[effectiveOwnerType] || 'vibes';\n navigate(`/${segment}/${effectiveOwnerId}/docs`);\n }}\n compileRevision={compileRevision}\n onPollRevision={handlePollRevision}\n compiling={compiling}\n />\n <QuotaExhaustedDialog\n isOpen={showQuotaExhausted}\n onClose={() => setShowQuotaExhausted(false)}\n onConfirm={() => {\n setShowQuotaExhausted(false);\n navigate('/billing/plans');\n }}\n title=\"Docs Site Quota Reached\"\n message=\"You have reached the documentation site limit for your current plan. Upgrade to create more docs sites.\"\n />\n </>\n );\n}\n"],"mappings":"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"}