@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.
- package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js +87 -85
- package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js.map +1 -1
- package/dist/components/ai/InstructionFilesManager.js +138 -136
- package/dist/components/ai/InstructionFilesManager.js.map +1 -1
- package/dist/components/ai/PluginHarnessPicker.js +70 -64
- package/dist/components/ai/PluginHarnessPicker.js.map +1 -1
- package/dist/components/docs/DocsEditPanel.js +1 -1
- package/dist/components/docs/DocsEditPanel.js.map +1 -1
- package/dist/components/docs/DocsPageTree.js +1 -1
- package/dist/components/docs/DocsPageTree.js.map +1 -1
- package/dist/components/docs/DocsTabPanel.js +108 -106
- package/dist/components/docs/DocsTabPanel.js.map +1 -1
- package/dist/components/notes/NotesTabPanel.js +99 -99
- package/dist/components/notes/NotesTabPanel.js.map +1 -1
- package/dist/components/scorecard/ScorecardPanel.js +309 -308
- package/dist/components/scorecard/ScorecardPanel.js.map +1 -1
- package/dist/components/sessions/SessionPublicLinkPanel.js +104 -102
- package/dist/components/sessions/SessionPublicLinkPanel.js.map +1 -1
- package/dist/components/settings/AdvancedSection.js +92 -90
- package/dist/components/settings/AdvancedSection.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js +104 -102
- package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js.map +1 -1
- package/dist/constants/permissions.js +7 -0
- package/dist/constants/permissions.js.map +1 -1
- package/dist/pages/ActionsPage.js +303 -303
- package/dist/pages/ActionsPage.js.map +1 -1
- package/dist/pages/AgentDetailsPage.js +520 -516
- package/dist/pages/AgentDetailsPage.js.map +1 -1
- package/dist/pages/AgentsPage.js +287 -283
- package/dist/pages/AgentsPage.js.map +1 -1
- package/dist/pages/TargetsPage.js +554 -549
- package/dist/pages/TargetsPage.js.map +1 -1
- package/dist/pages/VibeAuditPage.js +2 -2
- package/dist/pages/VibeAuditPage.js.map +1 -1
- package/dist/pages/VibeDeckPage.js +257 -257
- package/dist/pages/VibeDeckPage.js.map +1 -1
- package/dist/pages/VibeDetailsPage.js +688 -693
- package/dist/pages/VibeDetailsPage.js.map +1 -1
- package/dist/pages/VibesPage.js +49 -41
- package/dist/pages/VibesPage.js.map +1 -1
- package/dist/pages/WebhooksPage.js +162 -138
- package/dist/pages/WebhooksPage.js.map +1 -1
- package/dist/pages/tunnels/DomainsTab.js +54 -47
- package/dist/pages/tunnels/DomainsTab.js.map +1 -1
- 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
|
|
2
|
-
import { useTr as
|
|
3
|
-
import { QuotaExhaustedDialog as
|
|
4
|
-
import { getQuotaDialogContent as
|
|
5
|
-
import { useVibeNavigate as
|
|
6
|
-
import { LoadingState as
|
|
7
|
-
import { ErrorState as
|
|
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 {
|
|
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
|
|
12
|
-
import { DocsPreviewPanel as
|
|
13
|
-
import { DocsEditPanel as
|
|
14
|
-
import { useEffect as
|
|
15
|
-
import { AlertCircle as
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
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
|
|
20
|
-
let T =
|
|
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 =
|
|
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:
|
|
32
|
+
path: I
|
|
31
33
|
},
|
|
32
34
|
skip: !G?.id || !G.currentRevisionId,
|
|
33
35
|
fetchPolicy: "network-only"
|
|
34
|
-
}),
|
|
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,
|
|
43
|
+
e && e !== q.current && (q.current = e, we());
|
|
42
44
|
}, [G?.currentRevisionId]);
|
|
43
|
-
let
|
|
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
|
|
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
|
-
}),
|
|
56
|
+
}), k("edit");
|
|
55
57
|
} catch (e) {
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
+
if (s(e)) {
|
|
59
|
+
c(), V(!0);
|
|
58
60
|
return;
|
|
59
61
|
}
|
|
60
62
|
throw e;
|
|
61
63
|
}
|
|
62
|
-
},
|
|
63
|
-
await
|
|
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
|
-
},
|
|
72
|
+
}, He = async (e, t) => {
|
|
71
73
|
if (!G) return;
|
|
72
74
|
let n = K.length, r = `page-${n + 1}`;
|
|
73
|
-
await
|
|
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
|
-
},
|
|
84
|
-
confirm("Delete this page?") && (await
|
|
85
|
-
},
|
|
85
|
+
}, Ue = async (e) => {
|
|
86
|
+
confirm("Delete this page?") && (await Fe({ variables: { id: e } }), await W());
|
|
87
|
+
}, Y = async () => {
|
|
86
88
|
if (G) {
|
|
87
|
-
|
|
89
|
+
N(!0), F(null);
|
|
88
90
|
try {
|
|
89
|
-
let e = await
|
|
91
|
+
let e = await Ie({ variables: {
|
|
90
92
|
siteId: G.id,
|
|
91
93
|
publish: !0
|
|
92
94
|
} });
|
|
93
|
-
if (e.error &&
|
|
94
|
-
|
|
95
|
+
if (e.error && s(e.error)) {
|
|
96
|
+
c(), N(!1), H(!0);
|
|
95
97
|
return;
|
|
96
98
|
}
|
|
97
|
-
e.data?.compileDocsSite ?
|
|
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 (
|
|
100
|
-
|
|
101
|
+
if (N(!1), s(e)) {
|
|
102
|
+
c(), H(!0);
|
|
101
103
|
return;
|
|
102
104
|
}
|
|
103
|
-
|
|
105
|
+
F(e instanceof Error ? e.message : "Failed to start the build. Please try again.");
|
|
104
106
|
}
|
|
105
107
|
}
|
|
106
|
-
},
|
|
107
|
-
let { data: t } = await
|
|
108
|
-
return 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) && (
|
|
113
|
-
},
|
|
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
|
|
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
|
|
126
|
+
Object.keys(t).length > 0 && await Ae({ variables: {
|
|
125
127
|
id: G.id,
|
|
126
128
|
input: t
|
|
127
129
|
} }), await W();
|
|
128
|
-
},
|
|
130
|
+
}, Ge = async () => {
|
|
129
131
|
if (!G?.currentRevisionId) return null;
|
|
130
132
|
try {
|
|
131
|
-
let { data: e } = await
|
|
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
|
-
},
|
|
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
|
|
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
|
-
},
|
|
149
|
-
G && confirm("Delete this docs site and all its pages and revisions? This cannot be undone.") && (await
|
|
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 (
|
|
152
|
-
if (U && !G) return /* @__PURE__ */
|
|
153
|
-
title:
|
|
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__ */
|
|
158
|
-
onCreate:
|
|
159
|
-
loading:
|
|
160
|
-
}), /* @__PURE__ */
|
|
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 =
|
|
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__ */
|
|
173
|
-
/* @__PURE__ */
|
|
174
|
+
/* @__PURE__ */ y(de, { className: "size-4 shrink-0" }),
|
|
175
|
+
/* @__PURE__ */ y("span", {
|
|
174
176
|
className: "flex-1",
|
|
175
|
-
children:
|
|
177
|
+
children: P
|
|
176
178
|
}),
|
|
177
|
-
/* @__PURE__ */
|
|
179
|
+
/* @__PURE__ */ y("button", {
|
|
178
180
|
type: "button",
|
|
179
|
-
onClick: () =>
|
|
181
|
+
onClick: () => F(null),
|
|
180
182
|
className: "p-0.5 hover:opacity-70",
|
|
181
|
-
children: /* @__PURE__ */
|
|
183
|
+
children: /* @__PURE__ */ y(fe, { className: "size-3.5" })
|
|
182
184
|
})
|
|
183
185
|
]
|
|
184
|
-
}) : null, Q = /* @__PURE__ */
|
|
185
|
-
isOpen:
|
|
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:
|
|
191
|
-
message:
|
|
192
|
-
}), $ = /* @__PURE__ */
|
|
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:
|
|
205
|
+
label: S("vibecontrols.docs.share", "Share")
|
|
204
206
|
});
|
|
205
|
-
return
|
|
207
|
+
return O === "edit" ? /* @__PURE__ */ b(v, { children: [
|
|
206
208
|
Z,
|
|
207
209
|
Q,
|
|
208
|
-
/* @__PURE__ */
|
|
210
|
+
/* @__PURE__ */ y(m, {
|
|
209
211
|
site: G,
|
|
210
212
|
pages: K,
|
|
211
213
|
shareSlot: $,
|
|
212
|
-
onBack: () =>
|
|
213
|
-
onSavePage:
|
|
214
|
-
onAddPage:
|
|
215
|
-
pageAdding:
|
|
216
|
-
onDeletePage:
|
|
217
|
-
onCompile:
|
|
218
|
-
onSaveSettings:
|
|
219
|
-
onRollback:
|
|
220
|
-
onDeleteSite:
|
|
221
|
-
rollingBack:
|
|
222
|
-
compileRevision:
|
|
223
|
-
onPollRevision:
|
|
224
|
-
compiling:
|
|
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__ */
|
|
228
|
+
] }) : /* @__PURE__ */ b(v, { children: [
|
|
227
229
|
Z,
|
|
228
230
|
Q,
|
|
229
|
-
/* @__PURE__ */
|
|
231
|
+
/* @__PURE__ */ y(p, {
|
|
230
232
|
site: G,
|
|
231
233
|
pages: K,
|
|
232
234
|
shareSlot: $,
|
|
233
|
-
selectedPageSlug:
|
|
234
|
-
onSelectPage:
|
|
235
|
-
docsBaseUrl: G.currentRevisionId ?
|
|
236
|
-
docsHtml: G.currentRevisionId ?
|
|
237
|
-
docsContentLoading:
|
|
238
|
-
onEdit: () =>
|
|
239
|
-
onCompile:
|
|
240
|
-
onSettings: () =>
|
|
241
|
-
onGetShareUrl:
|
|
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:
|
|
250
|
-
onPollRevision:
|
|
251
|
-
compiling:
|
|
251
|
+
compileRevision: A,
|
|
252
|
+
onPollRevision: X,
|
|
253
|
+
compiling: M
|
|
252
254
|
}),
|
|
253
|
-
/* @__PURE__ */
|
|
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 {
|
|
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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"}
|