@prenta/admin 2.4.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/AdminRoot.d.ts.map +1 -1
- package/dist/AdminRoot.js +4 -0
- package/dist/AdminRoot.js.map +1 -1
- package/dist/__tests__/views/appearance-settings.render.test.js +3 -0
- package/dist/__tests__/views/appearance-settings.render.test.js.map +1 -1
- package/dist/__tests__/views/mcp-connect.render.test.d.ts +2 -0
- package/dist/__tests__/views/mcp-connect.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/mcp-connect.render.test.js +55 -0
- package/dist/__tests__/views/mcp-connect.render.test.js.map +1 -0
- package/dist/__tests__/views/mcp-connect.test.d.ts +2 -0
- package/dist/__tests__/views/mcp-connect.test.d.ts.map +1 -0
- package/dist/__tests__/views/mcp-connect.test.js +37 -0
- package/dist/__tests__/views/mcp-connect.test.js.map +1 -0
- package/dist/lib/appearance-api.d.ts +8 -0
- package/dist/lib/appearance-api.d.ts.map +1 -1
- package/dist/lib/appearance-api.js.map +1 -1
- package/dist/prenta-admin.css +1 -1
- package/dist/router/admin-routes.d.ts.map +1 -1
- package/dist/router/admin-routes.js +1 -0
- package/dist/router/admin-routes.js.map +1 -1
- package/dist/views/ApiKeys.d.ts +1 -1
- package/dist/views/ApiKeys.d.ts.map +1 -1
- package/dist/views/ApiKeys.js +2 -2
- package/dist/views/ApiKeys.js.map +1 -1
- package/dist/views/McpConsent.d.ts +4 -0
- package/dist/views/McpConsent.d.ts.map +1 -0
- package/dist/views/McpConsent.js +48 -0
- package/dist/views/McpConsent.js.map +1 -0
- package/dist/views/Settings.d.ts.map +1 -1
- package/dist/views/Settings.js +5 -3
- package/dist/views/Settings.js.map +1 -1
- package/dist/views/page-editor/EditorCanvas.d.ts.map +1 -1
- package/dist/views/page-editor/EditorCanvas.js +2 -1
- package/dist/views/page-editor/EditorCanvas.js.map +1 -1
- package/dist/views/page-editor/SectionThemeRoot.d.ts +10 -0
- package/dist/views/page-editor/SectionThemeRoot.d.ts.map +1 -0
- package/dist/views/page-editor/SectionThemeRoot.js +27 -0
- package/dist/views/page-editor/SectionThemeRoot.js.map +1 -0
- package/dist/views/page-editor/sections/AuthorBioSection.js +1 -1
- package/dist/views/page-editor/sections/AuthorBioSection.js.map +1 -1
- package/dist/views/page-editor/sections/ByTheNumbersSection.js +1 -1
- package/dist/views/page-editor/sections/ByTheNumbersSection.js.map +1 -1
- package/dist/views/page-editor/sections/CtaBannerSection.js +1 -1
- package/dist/views/page-editor/sections/CtaBannerSection.js.map +1 -1
- package/dist/views/page-editor/sections/FeatureHighlightSection.js +2 -2
- package/dist/views/page-editor/sections/FeatureHighlightSection.js.map +1 -1
- package/dist/views/page-editor/sections/HeroBannerSection.js +1 -1
- package/dist/views/page-editor/sections/HeroBannerSection.js.map +1 -1
- package/dist/views/page-editor/sections/parts.d.ts.map +1 -1
- package/dist/views/page-editor/sections/parts.js +11 -15
- package/dist/views/page-editor/sections/parts.js.map +1 -1
- package/dist/views/post-editor/PostEditorCanvas.d.ts.map +1 -1
- package/dist/views/post-editor/PostEditorCanvas.js +3 -2
- package/dist/views/post-editor/PostEditorCanvas.js.map +1 -1
- package/dist/views/settings/AppearanceTab.d.ts.map +1 -1
- package/dist/views/settings/AppearanceTab.js +2 -1
- package/dist/views/settings/AppearanceTab.js.map +1 -1
- package/dist/views/settings/McpConnectTab.d.ts +9 -0
- package/dist/views/settings/McpConnectTab.d.ts.map +1 -0
- package/dist/views/settings/McpConnectTab.js +71 -0
- package/dist/views/settings/McpConnectTab.js.map +1 -0
- package/dist/views/settings/PhiSafeguardsCard.d.ts +9 -0
- package/dist/views/settings/PhiSafeguardsCard.d.ts.map +1 -0
- package/dist/views/settings/PhiSafeguardsCard.js +70 -0
- package/dist/views/settings/PhiSafeguardsCard.js.map +1 -0
- package/dist/views/settings/SecurityTab.d.ts.map +1 -1
- package/dist/views/settings/SecurityTab.js +2 -1
- package/dist/views/settings/SecurityTab.js.map +1 -1
- package/dist/views/settings/SiteThemeCard.d.ts +7 -0
- package/dist/views/settings/SiteThemeCard.d.ts.map +1 -0
- package/dist/views/settings/SiteThemeCard.js +23 -0
- package/dist/views/settings/SiteThemeCard.js.map +1 -0
- package/dist/views/settings/mcp-connect.d.ts +25 -0
- package/dist/views/settings/mcp-connect.d.ts.map +1 -0
- package/dist/views/settings/mcp-connect.js +166 -0
- package/dist/views/settings/mcp-connect.js.map +1 -0
- package/dist/views/settings/useAppearanceSettings.d.ts +3 -1
- package/dist/views/settings/useAppearanceSettings.d.ts.map +1 -1
- package/dist/views/settings/useAppearanceSettings.js +27 -1
- package/dist/views/settings/useAppearanceSettings.js.map +1 -1
- package/package.json +4 -4
- package/src/AdminRoot.tsx +5 -0
- package/src/__tests__/views/appearance-settings.render.test.tsx +8 -0
- package/src/__tests__/views/mcp-connect.render.test.tsx +64 -0
- package/src/__tests__/views/mcp-connect.test.ts +42 -0
- package/src/lib/appearance-api.ts +8 -0
- package/src/router/admin-routes.ts +1 -0
- package/src/views/ApiKeys.tsx +5 -4
- package/src/views/McpConsent.tsx +101 -0
- package/src/views/Settings.tsx +13 -0
- package/src/views/page-editor/EditorCanvas.tsx +2 -1
- package/src/views/page-editor/SectionThemeRoot.tsx +33 -0
- package/src/views/page-editor/sections/AuthorBioSection.tsx +2 -2
- package/src/views/page-editor/sections/ByTheNumbersSection.tsx +1 -1
- package/src/views/page-editor/sections/CtaBannerSection.tsx +1 -1
- package/src/views/page-editor/sections/FeatureHighlightSection.tsx +3 -3
- package/src/views/page-editor/sections/HeroBannerSection.tsx +2 -2
- package/src/views/page-editor/sections/parts.tsx +12 -15
- package/src/views/post-editor/PostEditorCanvas.tsx +21 -18
- package/src/views/settings/AppearanceTab.tsx +2 -0
- package/src/views/settings/McpConnectTab.tsx +212 -0
- package/src/views/settings/PhiSafeguardsCard.tsx +85 -0
- package/src/views/settings/SecurityTab.tsx +3 -0
- package/src/views/settings/SiteThemeCard.tsx +71 -0
- package/src/views/settings/mcp-connect.ts +209 -0
- package/src/views/settings/useAppearanceSettings.ts +39 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostEditorCanvas.d.ts","sourceRoot":"","sources":["../../../src/views/post-editor/PostEditorCanvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;
|
|
1
|
+
{"version":3,"file":"PostEditorCanvas.d.ts","sourceRoot":"","sources":["../../../src/views/post-editor/PostEditorCanvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AAGrF,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AAE1F,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAG7D,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,MAAM,EAAE,gBAAgB,CAAA;IACxB,OAAO,EAAE,iBAAiB,CAAA;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,EAAE,UAAU,CAAA;IACpB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IAClD,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,kFAAkF;IAClF,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACvC;;;;OAIG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,MAAM,EACN,OAAO,EACP,UAAU,EACV,QAAQ,EACR,IAAY,EACZ,QAAQ,EACR,aAAa,EACb,eAAe,EACf,YAAY,EACZ,eAAoB,EACpB,SAAiB,EACjB,iBAAiB,EACjB,SAAS,GACV,EAAE,qBAAqB,2CA4CvB"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx,
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { FileText, Plus } from 'lucide-react';
|
|
4
4
|
import { CanvasEditTip } from '../../components/CanvasEditTip.js';
|
|
5
5
|
import { CanvasScroll, CanvasSurface, useSectionRefs } from '../page-editor/CanvasSurface.js';
|
|
6
|
+
import { SectionThemeRoot } from '../page-editor/SectionThemeRoot.js';
|
|
6
7
|
import { SectionRenderer } from '../page-editor/sections/index.js';
|
|
7
8
|
import { StructureNotice } from '../page-editor/StructureNotice.js';
|
|
8
9
|
import { PostHeader } from './PostHeader.js';
|
|
@@ -21,7 +22,7 @@ import { PostHeader } from './PostHeader.js';
|
|
|
21
22
|
*/
|
|
22
23
|
export function PostEditorCanvas({ sections, header, context, selectedId, viewport, zoom = 'fit', onSelect, onScaleChange, onCanvasElement, onAddSection, structuralTypes = [], reviewing = false, changedSectionIds, reviewBar, }) {
|
|
23
24
|
const registerRef = useSectionRefs(selectedId);
|
|
24
|
-
return (_jsx(CanvasScroll, { children:
|
|
25
|
+
return (_jsx(CanvasScroll, { children: _jsx(CanvasSurface, { breakpoint: viewport, zoom: zoom, onScaleChange: onScaleChange, onCanvasElement: onCanvasElement, chrome: reviewing ? (reviewBar) : (_jsxs(_Fragment, { children: [sections.length > 0 && _jsx(CanvasEditTip, {}), _jsx(StructureNotice, { structuralTypes: structuralTypes })] })), children: _jsxs(SectionThemeRoot, { children: [_jsx(PostHeader, { config: header, context: context }), sections.length === 0 ? (_jsx(EmptyBody, { onAddSection: reviewing ? undefined : onAddSection })) : (sections.map((section) => (_jsx(SectionRenderer, { section: section, context: context, editable: true, reviewing: reviewing, changed: changedSectionIds?.has(section.id) ?? false, selected: section.id === selectedId, onSelect: onSelect, registerRef: registerRef }, section.id))))] }) }) }));
|
|
25
26
|
}
|
|
26
27
|
function EmptyBody({ onAddSection }) {
|
|
27
28
|
// This block sits inside the fixed-white preview surface, so the neutral
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostEditorCanvas.js","sourceRoot":"","sources":["../../../src/views/post-editor/PostEditorCanvas.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAA;AAGjE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAC7F,OAAO,EAAE,eAAe,EAA0B,MAAM,kCAAkC,CAAA;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AA+B5C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,QAAQ,EACR,MAAM,EACN,OAAO,EACP,UAAU,EACV,QAAQ,EACR,IAAI,GAAG,KAAK,EACZ,QAAQ,EACR,aAAa,EACb,eAAe,EACf,YAAY,EACZ,eAAe,GAAG,EAAE,EACpB,SAAS,GAAG,KAAK,EACjB,iBAAiB,EACjB,SAAS,GACa;IACtB,MAAM,WAAW,GAAG,cAAc,CAAC,UAAU,CAAC,CAAA;IAE9C,OAAO,CACL,KAAC,YAAY,cACX,
|
|
1
|
+
{"version":3,"file":"PostEditorCanvas.js","sourceRoot":"","sources":["../../../src/views/post-editor/PostEditorCanvas.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAA;AAGjE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,EAAE,eAAe,EAA0B,MAAM,kCAAkC,CAAA;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AA+B5C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,QAAQ,EACR,MAAM,EACN,OAAO,EACP,UAAU,EACV,QAAQ,EACR,IAAI,GAAG,KAAK,EACZ,QAAQ,EACR,aAAa,EACb,eAAe,EACf,YAAY,EACZ,eAAe,GAAG,EAAE,EACpB,SAAS,GAAG,KAAK,EACjB,iBAAiB,EACjB,SAAS,GACa;IACtB,MAAM,WAAW,GAAG,cAAc,CAAC,UAAU,CAAC,CAAA;IAE9C,OAAO,CACL,KAAC,YAAY,cACX,KAAC,aAAa,IACZ,UAAU,EAAE,QAAQ,EACpB,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,eAAe,EAChC,MAAM,EACJ,SAAS,CAAC,CAAC,CAAC,CACV,SAAS,CACV,CAAC,CAAC,CAAC,CACF,8BACG,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,KAAC,aAAa,KAAG,EACzC,KAAC,eAAe,IAAC,eAAe,EAAE,eAAe,GAAI,IACpD,CACJ,YAGH,MAAC,gBAAgB,eACf,KAAC,UAAU,IAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAI,EAC/C,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACvB,KAAC,SAAS,IAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,GAAI,CAClE,CAAC,CAAC,CAAC,CACF,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CACxB,KAAC,eAAe,IAEd,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,EAChB,QAAQ,QACR,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,iBAAiB,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,KAAK,EACpD,QAAQ,EAAE,OAAO,CAAC,EAAE,KAAK,UAAU,EACnC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,IARnB,OAAO,CAAC,EAAE,CASf,CACH,CAAC,CACH,IACgB,GACL,GACH,CAChB,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,YAAY,EAAiC;IAChE,yEAAyE;IACzE,2EAA2E;IAC3E,4EAA4E;IAC5E,4EAA4E;IAC5E,wEAAwE;IACxE,gEAAgE;IAChE,OAAO,CACL,eAAK,SAAS,EAAC,iGAAiG,aAC9G,eAAM,SAAS,EAAC,kEAAkE,YAChF,KAAC,QAAQ,IAAC,SAAS,EAAC,+BAA+B,wBAAe,GAC7D,EACP,YAAG,SAAS,EAAC,+BAA+B,YACzC,YAAY;oBACX,CAAC,CAAC,6HAA6H;oBAC/H,CAAC,CAAC,2LAA2L,GAC7L,EACH,YAAY,IAAI,CACf,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,YAAY,EACrB,SAAS,EAAC,kJAAkJ,aAE5J,KAAC,IAAI,IAAC,SAAS,EAAC,SAAS,wBAAe,mBAEjC,CACV,IACG,CACP,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppearanceTab.d.ts","sourceRoot":"","sources":["../../../src/views/settings/AppearanceTab.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AppearanceTab.d.ts","sourceRoot":"","sources":["../../../src/views/settings/AppearanceTab.tsx"],"names":[],"mappings":"AAYA,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC;AAMD,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,kBAAkB,2CA4DjE"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { AlertTriangle, Loader2 } from 'lucide-react';
|
|
4
4
|
import { AdminThemeCard } from './AdminThemeCard.js';
|
|
5
|
+
import { SiteThemeCard } from './SiteThemeCard.js';
|
|
5
6
|
import { BrandPreviewCard } from './BrandPreviewCard.js';
|
|
6
7
|
import { BrandingCard } from './BrandingCard.js';
|
|
7
8
|
import { SettingsSaveBar, SettingsValidationSummary } from './components.js';
|
|
@@ -19,6 +20,6 @@ export function AppearanceTab({ role, config }) {
|
|
|
19
20
|
if (s.loadError) {
|
|
20
21
|
return (_jsxs("div", { role: "alert", className: "border-destructive/30 bg-destructive/10 text-destructive flex items-center justify-between gap-4 rounded-lg border p-4 text-sm", children: [_jsxs("span", { className: "flex items-center gap-2", children: [_jsx(AlertTriangle, { size: 16, "aria-hidden": "true" }), " ", s.loadError] }), _jsxs("button", { type: "button", onClick: s.reload, className: "border-destructive/40 text-destructive hover:bg-destructive/10 inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5", children: [_jsx(Loader2, { size: 14, "aria-hidden": "true" }), " Retry"] })] }));
|
|
21
22
|
}
|
|
22
|
-
return (_jsxs("div", { className: "space-y-4", children: [!canEdit && (_jsx("p", { className: "text-muted-foreground border-border bg-muted rounded-lg border p-4 text-sm", children: "You have read-only access to appearance settings." })), _jsx(SettingsValidationSummary, { issues: s.issues }), _jsx(BrandingCard, { s: s, canEdit: canEdit }), _jsx(AdminThemeCard, { s: s, canEdit: canEdit }), _jsx(TypographyMotionCard, { s: s, canEdit: canEdit }), _jsx(BrandPreviewCard, { s: s }), _jsx(SettingsSaveBar, { dirty: s.dirty, canEdit: canEdit, hasErrors: s.issues.some((i) => i.severity === 'error'), saveState: s.saveState, onSave: s.save, onReset: s.reset })] }));
|
|
23
|
+
return (_jsxs("div", { className: "space-y-4", children: [!canEdit && (_jsx("p", { className: "text-muted-foreground border-border bg-muted rounded-lg border p-4 text-sm", children: "You have read-only access to appearance settings." })), _jsx(SettingsValidationSummary, { issues: s.issues }), _jsx(BrandingCard, { s: s, canEdit: canEdit }), _jsx(AdminThemeCard, { s: s, canEdit: canEdit }), _jsx(SiteThemeCard, { s: s, canEdit: canEdit }), _jsx(TypographyMotionCard, { s: s, canEdit: canEdit }), _jsx(BrandPreviewCard, { s: s }), _jsx(SettingsSaveBar, { dirty: s.dirty, canEdit: canEdit, hasErrors: s.issues.some((i) => i.severity === 'error'), saveState: s.saveState, onSave: s.save, onReset: s.reset })] }));
|
|
23
24
|
}
|
|
24
25
|
//# sourceMappingURL=AppearanceTab.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppearanceTab.js","sourceRoot":"","sources":["../../../src/views/settings/AppearanceTab.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAQlE,SAAS,YAAY;IACnB,OAAO,cAAK,SAAS,EAAC,4DAA4D,GAAG,CAAA;AACvF,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAE,IAAI,EAAE,MAAM,EAAsB;IAChE,MAAM,OAAO,GAAG,IAAI,KAAK,OAAO,CAAA;IAChC,MAAM,CAAC,GAAG,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAEhD,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACd,OAAO,CACL,eAAK,SAAS,EAAC,WAAW,eAAW,MAAM,aACzC,KAAC,YAAY,KAAG,EAChB,KAAC,YAAY,KAAG,EAChB,KAAC,YAAY,KAAG,IACZ,CACP,CAAA;IACH,CAAC;IAED,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;QAChB,OAAO,CACL,eACE,IAAI,EAAC,OAAO,EACZ,SAAS,EAAC,gIAAgI,aAE1I,gBAAM,SAAS,EAAC,yBAAyB,aACvC,KAAC,aAAa,IAAC,IAAI,EAAE,EAAE,iBAAc,MAAM,GAAG,OAAE,CAAC,CAAC,SAAS,IACtD,EACP,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,CAAC,CAAC,MAAM,EACjB,SAAS,EAAC,+HAA+H,aAEzI,KAAC,OAAO,IAAC,IAAI,EAAE,EAAE,iBAAc,MAAM,GAAG,cACjC,IACL,CACP,CAAA;IACH,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,WAAW,aACvB,CAAC,OAAO,IAAI,CACX,YAAG,SAAS,EAAC,4EAA4E,kEAErF,CACL,EAED,KAAC,yBAAyB,IAAC,MAAM,EAAE,CAAC,CAAC,MAAM,GAAI,EAE/C,KAAC,YAAY,IAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAI,EACxC,KAAC,cAAc,IAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAI,EAC1C,KAAC,oBAAoB,IAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAI,EAChD,KAAC,gBAAgB,IAAC,CAAC,EAAE,CAAC,GAAI,EAE1B,KAAC,eAAe,IACd,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,EACvD,SAAS,EAAE,CAAC,CAAC,SAAS,EACtB,MAAM,EAAE,CAAC,CAAC,IAAI,EACd,OAAO,EAAE,CAAC,CAAC,KAAK,GAChB,IACE,CACP,CAAA;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"AppearanceTab.js","sourceRoot":"","sources":["../../../src/views/settings/AppearanceTab.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAQlE,SAAS,YAAY;IACnB,OAAO,cAAK,SAAS,EAAC,4DAA4D,GAAG,CAAA;AACvF,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAE,IAAI,EAAE,MAAM,EAAsB;IAChE,MAAM,OAAO,GAAG,IAAI,KAAK,OAAO,CAAA;IAChC,MAAM,CAAC,GAAG,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAEhD,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACd,OAAO,CACL,eAAK,SAAS,EAAC,WAAW,eAAW,MAAM,aACzC,KAAC,YAAY,KAAG,EAChB,KAAC,YAAY,KAAG,EAChB,KAAC,YAAY,KAAG,IACZ,CACP,CAAA;IACH,CAAC;IAED,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;QAChB,OAAO,CACL,eACE,IAAI,EAAC,OAAO,EACZ,SAAS,EAAC,gIAAgI,aAE1I,gBAAM,SAAS,EAAC,yBAAyB,aACvC,KAAC,aAAa,IAAC,IAAI,EAAE,EAAE,iBAAc,MAAM,GAAG,OAAE,CAAC,CAAC,SAAS,IACtD,EACP,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,CAAC,CAAC,MAAM,EACjB,SAAS,EAAC,+HAA+H,aAEzI,KAAC,OAAO,IAAC,IAAI,EAAE,EAAE,iBAAc,MAAM,GAAG,cACjC,IACL,CACP,CAAA;IACH,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,WAAW,aACvB,CAAC,OAAO,IAAI,CACX,YAAG,SAAS,EAAC,4EAA4E,kEAErF,CACL,EAED,KAAC,yBAAyB,IAAC,MAAM,EAAE,CAAC,CAAC,MAAM,GAAI,EAE/C,KAAC,YAAY,IAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAI,EACxC,KAAC,cAAc,IAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAI,EAC1C,KAAC,aAAa,IAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAI,EACzC,KAAC,oBAAoB,IAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAI,EAChD,KAAC,gBAAgB,IAAC,CAAC,EAAE,CAAC,GAAI,EAE1B,KAAC,eAAe,IACd,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,EACvD,SAAS,EAAE,CAAC,CAAC,SAAS,EACtB,MAAM,EAAE,CAAC,CAAC,IAAI,EACd,OAAO,EAAE,CAAC,CAAC,KAAK,GAChB,IACE,CACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings → MCP. One tab per client, matching the "copy this and paste it
|
|
3
|
+
* there" setup other site builders use. The URL comes from the server so the
|
|
4
|
+
* Host header is never trusted.
|
|
5
|
+
*/
|
|
6
|
+
export declare function McpConnectTab({ onNavigate }: {
|
|
7
|
+
onNavigate?: (path: string) => void;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=McpConnectTab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"McpConnectTab.d.ts","sourceRoot":"","sources":["../../../src/views/settings/McpConnectTab.tsx"],"names":[],"mappings":"AAyFA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,EAAE;IAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,2CAqHpF"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as Tabs from '@radix-ui/react-tabs';
|
|
4
|
+
import { Copy, Loader2 } from 'lucide-react';
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
import { toast } from 'sonner';
|
|
7
|
+
import { cmsApi } from '../../lib/api.js';
|
|
8
|
+
import { SettingsCard } from './components.js';
|
|
9
|
+
import { mcpClientGuides } from './mcp-connect.js';
|
|
10
|
+
async function copyText(value, label) {
|
|
11
|
+
try {
|
|
12
|
+
await navigator.clipboard.writeText(value);
|
|
13
|
+
toast.success(`${label} copied`);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
toast.error('Could not copy. Select the text and copy it manually.');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function ClientPanel({ guide, onCreateKey }) {
|
|
20
|
+
const [manual, setManual] = useState(false);
|
|
21
|
+
return (_jsxs("div", { className: "grid gap-6 lg:grid-cols-2", children: [_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("h3", { className: "text-lg font-medium", children: guide.title }), _jsx("p", { className: "text-muted-foreground text-sm", children: guide.summary })] }), _jsxs("button", { type: "button", className: "bg-primary text-primary-foreground focus-visible:ring-ring inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium hover:opacity-90 focus-visible:ring-2 focus-visible:outline-none", onClick: () => void copyText(guide.copyText, guide.action.replace(/^Copy /, '')), children: [_jsx(Copy, { size: 16, "aria-hidden": "true" }), guide.action] }), _jsxs("div", { children: [_jsx("button", { type: "button", className: "text-primary focus-visible:ring-ring text-sm font-medium underline-offset-4 hover:underline focus-visible:ring-2 focus-visible:outline-none", "aria-expanded": manual, onClick: () => setManual((open) => !open), children: "Prefer manual configuration?" }), manual && (_jsx("ol", { className: "text-muted-foreground mt-3 list-decimal space-y-2 pl-5 text-sm", children: guide.manual.map((step) => (_jsx("li", { children: step }, step))) }))] }), guide.needsApiKey && onCreateKey && (_jsx("button", { type: "button", className: "text-foreground focus-visible:ring-ring text-sm font-medium underline-offset-4 hover:underline focus-visible:ring-2 focus-visible:outline-none", onClick: onCreateKey, children: "Create a Content API key" }))] }), _jsxs("div", { className: "border-border bg-muted relative rounded-lg border", children: [_jsx("button", { type: "button", className: "text-muted-foreground hover:text-foreground focus-visible:ring-ring absolute top-2 right-2 rounded-md p-2 focus-visible:ring-2 focus-visible:outline-none", "aria-label": guide.action, onClick: () => void copyText(guide.copyText, guide.action.replace(/^Copy /, '')), children: _jsx(Copy, { size: 16, "aria-hidden": "true" }) }), _jsx("pre", { className: "max-h-80 overflow-auto p-4 pr-12 font-mono text-sm whitespace-pre-wrap", children: guide.panel })] })] }));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Settings → MCP. One tab per client, matching the "copy this and paste it
|
|
25
|
+
* there" setup other site builders use. The URL comes from the server so the
|
|
26
|
+
* Host header is never trusted.
|
|
27
|
+
*/
|
|
28
|
+
export function McpConnectTab({ onNavigate }) {
|
|
29
|
+
const [mcpUrl, setMcpUrl] = useState('');
|
|
30
|
+
const [loadError, setLoadError] = useState(null);
|
|
31
|
+
const [loading, setLoading] = useState(true);
|
|
32
|
+
const [grants, setGrants] = useState([]);
|
|
33
|
+
const [client, setClient] = useState('claude-code');
|
|
34
|
+
function loadGrants() {
|
|
35
|
+
void cmsApi('/mcp/oauth/grants').then((res) => {
|
|
36
|
+
if (res.data)
|
|
37
|
+
setGrants(res.data.filter((grant) => !grant.revokedAt));
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
let cancelled = false;
|
|
42
|
+
void cmsApi('/mcp/oauth/setup').then((res) => {
|
|
43
|
+
if (cancelled)
|
|
44
|
+
return;
|
|
45
|
+
setLoading(false);
|
|
46
|
+
if (res.error || !res.data?.mcpUrl) {
|
|
47
|
+
setLoadError(res.error ?? 'This site has no public URL yet, so there is nothing to connect.');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
setMcpUrl(res.data.mcpUrl);
|
|
51
|
+
});
|
|
52
|
+
loadGrants();
|
|
53
|
+
return () => {
|
|
54
|
+
cancelled = true;
|
|
55
|
+
};
|
|
56
|
+
}, []);
|
|
57
|
+
async function revoke(id) {
|
|
58
|
+
const res = await cmsApi(`/mcp/oauth/grants/${encodeURIComponent(id)}`, {
|
|
59
|
+
method: 'DELETE',
|
|
60
|
+
});
|
|
61
|
+
if (res.error) {
|
|
62
|
+
toast.error(res.error);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
toast.success(res.data?.note ?? 'Disconnected');
|
|
66
|
+
loadGrants();
|
|
67
|
+
}
|
|
68
|
+
const guides = mcpUrl ? mcpClientGuides(mcpUrl) : [];
|
|
69
|
+
return (_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("h2", { className: "text-lg font-medium", children: "MCP" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Connect an AI agent to this site. It can draft and edit pages, then you approve what goes live." })] }), loading ? (_jsxs("div", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" }), "Loading connection details"] })) : loadError ? (_jsx("p", { role: "alert", className: "text-destructive text-sm", children: loadError })) : (_jsxs(Tabs.Root, { value: client, onValueChange: (value) => setClient(value), children: [_jsx(Tabs.List, { "aria-label": "AI clients", className: "border-border mb-6 flex gap-1 overflow-x-auto border-b", children: guides.map((guide) => (_jsx(Tabs.Trigger, { value: guide.id, className: "text-muted-foreground hover:text-foreground data-[state=active]:border-primary data-[state=active]:text-foreground focus-visible:ring-ring px-3 py-2 text-sm font-medium focus-visible:ring-2 focus-visible:outline-none data-[state=active]:border-b-2", children: guide.label }, guide.id))) }), guides.map((guide) => (_jsx(Tabs.Content, { value: guide.id, className: "focus-visible:outline-none", children: _jsx(ClientPanel, { guide: guide, onCreateKey: onNavigate ? () => onNavigate('/settings?tab=api-keys') : undefined }) }, guide.id)))] })), _jsx(SettingsCard, { title: "Connected apps", description: "Revoke stops new requests immediately. An access token already issued can keep working for up to 15 minutes.", children: grants.length === 0 ? (_jsx("p", { className: "text-muted-foreground text-sm", children: "No apps connected yet." })) : (_jsx("ul", { className: "space-y-2", children: grants.map((grant) => (_jsxs("li", { className: "flex items-center justify-between gap-3 text-sm", children: [_jsx("span", { className: "min-w-0 truncate", children: grant.clientId }), _jsx("button", { type: "button", className: "text-destructive focus-visible:ring-ring shrink-0 font-medium hover:underline focus-visible:ring-2 focus-visible:outline-none", onClick: () => void revoke(grant.id), children: "Revoke" })] }, grant.id))) })) })] }));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=McpConnectTab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"McpConnectTab.js","sourceRoot":"","sources":["../../../src/views/settings/McpConnectTab.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclosure boundary for form submissions. Turning this on refuses lead
|
|
3
|
+
* values to API keys, MCP, and vision alt-text. It is a technical safeguard,
|
|
4
|
+
* not a compliance certification.
|
|
5
|
+
*/
|
|
6
|
+
export declare function PhiSafeguardsCard({ canEdit }: {
|
|
7
|
+
canEdit: boolean;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
9
|
+
//# sourceMappingURL=PhiSafeguardsCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PhiSafeguardsCard.d.ts","sourceRoot":"","sources":["../../../src/views/settings/PhiSafeguardsCard.tsx"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,kDAuElE"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { toast } from 'sonner';
|
|
5
|
+
import { cmsApi } from '../../lib/api.js';
|
|
6
|
+
import { Toggle } from '../../components/ui/Toggle.js';
|
|
7
|
+
import { SettingsCard } from './components.js';
|
|
8
|
+
/**
|
|
9
|
+
* Disclosure boundary for form submissions. Turning this on refuses lead
|
|
10
|
+
* values to API keys, MCP, and vision alt-text. It is a technical safeguard,
|
|
11
|
+
* not a compliance certification.
|
|
12
|
+
*/
|
|
13
|
+
export function PhiSafeguardsCard({ canEdit }) {
|
|
14
|
+
const [enabled, setEnabled] = useState(false);
|
|
15
|
+
const [loading, setLoading] = useState(true);
|
|
16
|
+
const [saving, setSaving] = useState(false);
|
|
17
|
+
const [hidden, setHidden] = useState(false);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
let cancelled = false;
|
|
20
|
+
cmsApi('/privacy')
|
|
21
|
+
.then((res) => {
|
|
22
|
+
if (cancelled)
|
|
23
|
+
return;
|
|
24
|
+
if ('error' in res && res.error) {
|
|
25
|
+
setHidden(true);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if ('data' in res)
|
|
29
|
+
setEnabled(Boolean(res.data?.phiSafeguards));
|
|
30
|
+
})
|
|
31
|
+
.catch(() => {
|
|
32
|
+
if (!cancelled)
|
|
33
|
+
setHidden(true);
|
|
34
|
+
})
|
|
35
|
+
.finally(() => {
|
|
36
|
+
if (!cancelled)
|
|
37
|
+
setLoading(false);
|
|
38
|
+
});
|
|
39
|
+
return () => {
|
|
40
|
+
cancelled = true;
|
|
41
|
+
};
|
|
42
|
+
}, []);
|
|
43
|
+
if (hidden || loading)
|
|
44
|
+
return null;
|
|
45
|
+
async function onToggle(next) {
|
|
46
|
+
if (!canEdit || saving)
|
|
47
|
+
return;
|
|
48
|
+
setSaving(true);
|
|
49
|
+
const previous = enabled;
|
|
50
|
+
setEnabled(next);
|
|
51
|
+
try {
|
|
52
|
+
const res = await cmsApi('/privacy', {
|
|
53
|
+
method: 'PUT',
|
|
54
|
+
body: JSON.stringify({ phiSafeguards: next }),
|
|
55
|
+
});
|
|
56
|
+
if ('error' in res && res.error)
|
|
57
|
+
throw new Error(res.error);
|
|
58
|
+
toast.success(next ? 'Health-information protection is on' : 'Health-information protection is off');
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
setEnabled(previous);
|
|
62
|
+
toast.error('Could not update health-information protection');
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
setSaving(false);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return (_jsx(SettingsCard, { title: "Protect health information", description: "When on, API keys and connected AI apps cannot read form submission contents, and image alt-text generation is refused. People signed in to the admin can still open the inbox. This is a technical safeguard. It does not certify the site for any regulation.", busy: saving, children: _jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsx("label", { htmlFor: "phi-safeguards", className: "text-sm text-[var(--txt)]", children: "Hide lead contents from API keys and AI" }), _jsx(Toggle, { id: "phi-safeguards", checked: enabled, disabled: !canEdit || saving, onCheckedChange: (checked) => void onToggle(checked) })] }) }));
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=PhiSafeguardsCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PhiSafeguardsCard.js","sourceRoot":"","sources":["../../../src/views/settings/PhiSafeguardsCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityTab.d.ts","sourceRoot":"","sources":["../../../src/views/settings/SecurityTab.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SecurityTab.d.ts","sourceRoot":"","sources":["../../../src/views/settings/SecurityTab.tsx"],"names":[],"mappings":"AAiCA,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,UAAU,GACX,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC,2CAyJA"}
|
|
@@ -12,6 +12,7 @@ import { SecurityStatusCard } from './SecurityStatusCard.js';
|
|
|
12
12
|
import { CaptchaStatusCard } from './CaptchaStatusCard.js';
|
|
13
13
|
import { SessionPolicyCard } from './SessionPolicyCard.js';
|
|
14
14
|
import { useSecuritySettings } from './useSecuritySettings.js';
|
|
15
|
+
import { PhiSafeguardsCard } from './PhiSafeguardsCard.js';
|
|
15
16
|
function CardSkeleton() {
|
|
16
17
|
return (_jsxs("div", { className: "border-border bg-card animate-pulse rounded-lg border p-6", children: [_jsx("div", { className: "bg-muted mb-3 h-4 w-40 rounded" }), _jsx("div", { className: "bg-muted mb-4 h-3 w-72 rounded" }), _jsxs("div", { className: "space-y-3", children: [_jsx("div", { className: "bg-muted h-3 w-full rounded" }), _jsx("div", { className: "bg-muted h-3 w-2/3 rounded" })] })] }));
|
|
17
18
|
}
|
|
@@ -39,6 +40,6 @@ export function SecurityTab({ role, onNavigate, }) {
|
|
|
39
40
|
? 'Ask an administrator to review the Security tab.'
|
|
40
41
|
: (loadError ?? 'The security service could not be reached. Try again shortly.') })] })] }));
|
|
41
42
|
}
|
|
42
|
-
return (_jsxs("div", { className: "space-y-4 pb-4", children: [_jsx(SecurityStatusCard, { status: data.status, onNavigate: onNavigate }), _jsx(CaptchaStatusCard, {}), issues.length > 0 && _jsx(SettingsValidationSummary, { issues: issues }), !canEdit && (_jsx("p", { className: "text-muted-foreground text-sm", children: "You have read-only access. Only administrators can change security settings." })), _jsx(AuthMfaCard, { form: form, setField: setField, canEdit: canEdit, viewerHasMfa: data.viewerHasMfa, withMfa: data.users.withMfa, totalAdmins: data.users.totalAdmins, onNavigate: onNavigate }), _jsx("div", { id: "security-sessions", children: _jsx(SessionPolicyCard, { form: form, setField: setField, canEdit: canEdit, activeSessions: data.activeSessions, revokeState: revokeState, onRevokeAll: () => void revokeAllOtherSessions() }) }), _jsx("div", { id: "security-ip-allowlist", children: _jsx(AccessProtectionCard, { form: form, setField: setField, canEdit: canEdit, ipAllowlist: data.ipAllowlist, secrets: data.secrets, csrfEnabled: data.csrfEnabled, uploadValidation: data.uploadValidation, sources: data.sources, onNavigate: onNavigate }) }), _jsxs("div", { id: "security-audit", className: "space-y-4", children: [canEdit && _jsx(AuditLogExportCard, {}), _jsx(SecretsAuditCard, { secrets: data.secrets, auditEnabled: data.auditEnabled, failedLogins24h: data.failedLogins24h, users: data.users, apiKeys: data.apiKeys, sources: data.sources, onNavigate: onNavigate })] }), saveState === 'error' && (_jsx("p", { className: "text-destructive text-sm", role: "alert", children: "Failed to save security settings. Please try again." })), _jsx(ConfirmDangerousSettingDialog, { open: lockoutPrompt !== null, title: "This allowlist may lock you out", description: lockoutPrompt ?? 'Your current IP is not covered by the allowlist you are about to save.', confirmLabel: "Save anyway", onConfirm: () => void save({ confirmLockout: true }), onCancel: dismissLockoutPrompt }), _jsx(SettingsSaveBar, { dirty: dirty, canEdit: canEdit, hasErrors: hasErrors, saveState: saveState, onSave: () => void save(), onReset: reset })] }));
|
|
43
|
+
return (_jsxs("div", { className: "space-y-4 pb-4", children: [_jsx(SecurityStatusCard, { status: data.status, onNavigate: onNavigate }), _jsx(CaptchaStatusCard, {}), issues.length > 0 && _jsx(SettingsValidationSummary, { issues: issues }), !canEdit && (_jsx("p", { className: "text-muted-foreground text-sm", children: "You have read-only access. Only administrators can change security settings." })), _jsx(AuthMfaCard, { form: form, setField: setField, canEdit: canEdit, viewerHasMfa: data.viewerHasMfa, withMfa: data.users.withMfa, totalAdmins: data.users.totalAdmins, onNavigate: onNavigate }), _jsx("div", { id: "security-sessions", children: _jsx(SessionPolicyCard, { form: form, setField: setField, canEdit: canEdit, activeSessions: data.activeSessions, revokeState: revokeState, onRevokeAll: () => void revokeAllOtherSessions() }) }), _jsx("div", { id: "security-ip-allowlist", children: _jsx(AccessProtectionCard, { form: form, setField: setField, canEdit: canEdit, ipAllowlist: data.ipAllowlist, secrets: data.secrets, csrfEnabled: data.csrfEnabled, uploadValidation: data.uploadValidation, sources: data.sources, onNavigate: onNavigate }) }), _jsx(PhiSafeguardsCard, { canEdit: canEdit || role === 'OWNER' }), _jsxs("div", { id: "security-audit", className: "space-y-4", children: [canEdit && _jsx(AuditLogExportCard, {}), _jsx(SecretsAuditCard, { secrets: data.secrets, auditEnabled: data.auditEnabled, failedLogins24h: data.failedLogins24h, users: data.users, apiKeys: data.apiKeys, sources: data.sources, onNavigate: onNavigate })] }), saveState === 'error' && (_jsx("p", { className: "text-destructive text-sm", role: "alert", children: "Failed to save security settings. Please try again." })), _jsx(ConfirmDangerousSettingDialog, { open: lockoutPrompt !== null, title: "This allowlist may lock you out", description: lockoutPrompt ?? 'Your current IP is not covered by the allowlist you are about to save.', confirmLabel: "Save anyway", onConfirm: () => void save({ confirmLockout: true }), onCancel: dismissLockoutPrompt }), _jsx(SettingsSaveBar, { dirty: dirty, canEdit: canEdit, hasErrors: hasErrors, saveState: saveState, onSave: () => void save(), onReset: reset })] }));
|
|
43
44
|
}
|
|
44
45
|
//# sourceMappingURL=SecurityTab.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityTab.js","sourceRoot":"","sources":["../../../src/views/settings/SecurityTab.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAW,WAAW,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EACL,6BAA6B,EAC7B,eAAe,EACf,yBAAyB,GAC1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"SecurityTab.js","sourceRoot":"","sources":["../../../src/views/settings/SecurityTab.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { UseAppearanceSettings } from './useAppearanceSettings.js';
|
|
2
|
+
/** Public site theme. Empty fields keep the built-in section palette. */
|
|
3
|
+
export declare function SiteThemeCard({ s, canEdit }: {
|
|
4
|
+
s: UseAppearanceSettings;
|
|
5
|
+
canEdit: boolean;
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=SiteThemeCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SiteThemeCard.d.ts","sourceRoot":"","sources":["../../../src/views/settings/SiteThemeCard.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAevE,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,CAAC,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,2CAkD3F"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
const FIELDS = [
|
|
4
|
+
{ key: 'accent', label: 'Accent', hint: 'Buttons and highlights. Example: #7c3aed' },
|
|
5
|
+
{ key: 'background', label: 'Background', hint: 'Page surface. Example: #ffffff' },
|
|
6
|
+
{ key: 'foreground', label: 'Text', hint: 'Body text. Example: #18181b' },
|
|
7
|
+
{ key: 'muted', label: 'Muted text', hint: 'Secondary text. Example: #71717a' },
|
|
8
|
+
{ key: 'fontFamily', label: 'Font', hint: 'A font already on the site. Example: Georgia, serif' },
|
|
9
|
+
{ key: 'radius', label: 'Corner radius', hint: 'Example: 0.75rem' },
|
|
10
|
+
];
|
|
11
|
+
function isColorKey(key) {
|
|
12
|
+
return key === 'accent' || key === 'background' || key === 'foreground' || key === 'muted';
|
|
13
|
+
}
|
|
14
|
+
/** Public site theme. Empty fields keep the built-in section palette. */
|
|
15
|
+
export function SiteThemeCard({ s, canEdit }) {
|
|
16
|
+
return (_jsxs("section", { className: "border-border bg-card space-y-4 rounded-lg border p-6", children: [_jsx("h3", { className: "text-lg font-medium", children: "Site theme" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Colors and type for published pages. Leave a field empty to keep the default." }), _jsx("div", { className: "grid gap-4 sm:grid-cols-2", children: FIELDS.map(({ key, label, hint }) => {
|
|
17
|
+
const value = s.appearance.publicTheme[key] ?? '';
|
|
18
|
+
const issue = s.issues.find((item) => item.field === `publicTheme.${key}`);
|
|
19
|
+
const id = `site-theme-${key}`;
|
|
20
|
+
return (_jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: id, className: "text-sm font-medium", children: label }), _jsxs("div", { className: "flex items-center gap-2", children: [isColorKey(key) && value ? (_jsx("span", { "aria-hidden": true, className: "border-border size-8 shrink-0 rounded-md border", style: { background: value } })) : null, _jsx("input", { id: id, value: value, disabled: !canEdit, "aria-invalid": issue ? true : undefined, "aria-describedby": issue ? `${id}-error` : `${id}-hint`, onChange: (event) => s.setPublicTheme({ [key]: event.target.value }), className: "border-input bg-background w-full rounded-md border px-3 py-2 text-sm disabled:opacity-60" })] }), issue ? (_jsx("p", { id: `${id}-error`, className: "text-destructive text-sm", children: issue.message })) : (_jsx("p", { id: `${id}-hint`, className: "text-muted-foreground text-sm", children: hint }))] }, key));
|
|
21
|
+
}) })] }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=SiteThemeCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SiteThemeCard.js","sourceRoot":"","sources":["../../../src/views/settings/SiteThemeCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection text for Settings → MCP. Each client gets one thing to copy.
|
|
3
|
+
* OAuth clients receive the remote URL. Editors that cannot sign in receive
|
|
4
|
+
* a stdio config with a placeholder key, never a real secret.
|
|
5
|
+
*/
|
|
6
|
+
export type McpClientId = 'claude-code' | 'claude' | 'chatgpt' | 'grok' | 'cursor' | 'vscode' | 'other';
|
|
7
|
+
export interface McpClientGuide {
|
|
8
|
+
id: McpClientId;
|
|
9
|
+
label: string;
|
|
10
|
+
title: string;
|
|
11
|
+
/** One sentence under the title. */
|
|
12
|
+
summary: string;
|
|
13
|
+
/** Primary button. */
|
|
14
|
+
action: string;
|
|
15
|
+
/** Exact text the primary button and the panel copy control place on the clipboard. */
|
|
16
|
+
copyText: string;
|
|
17
|
+
/** Shown in the panel. Equals copyText except where the panel adds a label. */
|
|
18
|
+
panel: string;
|
|
19
|
+
manual: string[];
|
|
20
|
+
/** This client needs a Content API key created on the API Keys tab. */
|
|
21
|
+
needsApiKey: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare function mcpServerName(mcpUrl: string): string;
|
|
24
|
+
export declare function mcpClientGuides(mcpUrl: string): McpClientGuide[];
|
|
25
|
+
//# sourceMappingURL=mcp-connect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-connect.d.ts","sourceRoot":"","sources":["../../../src/views/settings/mcp-connect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,WAAW,GACnB,aAAa,GACb,QAAQ,GACR,SAAS,GACT,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,OAAO,CAAA;AAEX,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,WAAW,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAA;IACf,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,uFAAuF;IACvF,QAAQ,EAAE,MAAM,CAAA;IAChB,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,uEAAuE;IACvE,WAAW,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQpD;AAUD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,CA8JhE"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection text for Settings → MCP. Each client gets one thing to copy.
|
|
3
|
+
* OAuth clients receive the remote URL. Editors that cannot sign in receive
|
|
4
|
+
* a stdio config with a placeholder key, never a real secret.
|
|
5
|
+
*/
|
|
6
|
+
export function mcpServerName(mcpUrl) {
|
|
7
|
+
try {
|
|
8
|
+
const host = new URL(mcpUrl).hostname.replace(/^www\./, '');
|
|
9
|
+
const label = (host.split('.')[0] || 'site').toLowerCase().replace(/[^a-z0-9]+/g, '-');
|
|
10
|
+
return `${label.replace(/^-|-$/g, '') || 'site'}-prenta`;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return 'site-prenta';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function mcpSiteOrigin(mcpUrl) {
|
|
17
|
+
try {
|
|
18
|
+
return new URL(mcpUrl).origin;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return mcpUrl.replace(/\/mcp\/?$/, '');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function mcpClientGuides(mcpUrl) {
|
|
25
|
+
const name = mcpServerName(mcpUrl);
|
|
26
|
+
const origin = mcpSiteOrigin(mcpUrl);
|
|
27
|
+
const claudeCodePrompt = [
|
|
28
|
+
'Add this Prenta site as a remote MCP server.',
|
|
29
|
+
'',
|
|
30
|
+
'Connection details:',
|
|
31
|
+
`- Server URL: ${mcpUrl}`,
|
|
32
|
+
'- Transport: HTTP',
|
|
33
|
+
`- Server name: ${name}`,
|
|
34
|
+
'',
|
|
35
|
+
'Do not store an API key. This site signs in with OAuth. After the server is added, start the sign-in flow so I can approve it in the browser.',
|
|
36
|
+
'',
|
|
37
|
+
`Command: claude mcp add --transport http ${name} ${mcpUrl}`,
|
|
38
|
+
].join('\n');
|
|
39
|
+
const cursorConfig = JSON.stringify({
|
|
40
|
+
mcpServers: {
|
|
41
|
+
[name]: {
|
|
42
|
+
command: 'npx',
|
|
43
|
+
args: ['-y', '@prenta/mcp-server'],
|
|
44
|
+
env: {
|
|
45
|
+
PRENTA_BASE_URL: origin,
|
|
46
|
+
PRENTA_API_KEY: 'act_sk_...',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
}, null, 2);
|
|
51
|
+
const vscodeConfig = JSON.stringify({
|
|
52
|
+
servers: {
|
|
53
|
+
[name]: {
|
|
54
|
+
type: 'stdio',
|
|
55
|
+
command: 'npx',
|
|
56
|
+
args: ['-y', '@prenta/mcp-server'],
|
|
57
|
+
env: {
|
|
58
|
+
PRENTA_BASE_URL: origin,
|
|
59
|
+
PRENTA_API_KEY: 'act_sk_...',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
}, null, 2);
|
|
64
|
+
const bearer = 'Authorization: Bearer act_sk_...';
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
id: 'claude-code',
|
|
68
|
+
label: 'Claude Code',
|
|
69
|
+
title: 'Connect this site to Claude Code',
|
|
70
|
+
summary: 'Paste this prompt into Claude Code. It adds the server, then this site asks you to approve access.',
|
|
71
|
+
action: 'Copy prompt',
|
|
72
|
+
copyText: claudeCodePrompt,
|
|
73
|
+
panel: claudeCodePrompt,
|
|
74
|
+
manual: [
|
|
75
|
+
`Run: claude mcp add --transport http ${name} ${mcpUrl}`,
|
|
76
|
+
'Approve the sign-in page this site opens. Do not paste an API key into the command.',
|
|
77
|
+
],
|
|
78
|
+
needsApiKey: false,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'claude',
|
|
82
|
+
label: 'Claude',
|
|
83
|
+
title: 'Connect this site to Claude',
|
|
84
|
+
summary: 'Claude on the web, Desktop, and Cowork use this URL and sign in here.',
|
|
85
|
+
action: 'Copy URL',
|
|
86
|
+
copyText: mcpUrl,
|
|
87
|
+
panel: mcpUrl,
|
|
88
|
+
manual: [
|
|
89
|
+
'Open Claude → Settings → Connectors → Add custom connector.',
|
|
90
|
+
'Paste the URL and continue. This site opens so you can allow access.',
|
|
91
|
+
],
|
|
92
|
+
needsApiKey: false,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: 'chatgpt',
|
|
96
|
+
label: 'ChatGPT',
|
|
97
|
+
title: 'Connect this site to ChatGPT',
|
|
98
|
+
summary: 'ChatGPT signs in here. It cannot use an API key.',
|
|
99
|
+
action: 'Copy URL',
|
|
100
|
+
copyText: mcpUrl,
|
|
101
|
+
panel: mcpUrl,
|
|
102
|
+
manual: [
|
|
103
|
+
'Open ChatGPT → Settings → Connectors and add a custom connector.',
|
|
104
|
+
'Paste the URL. ChatGPT sends you back here to approve access.',
|
|
105
|
+
],
|
|
106
|
+
needsApiKey: false,
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 'grok',
|
|
110
|
+
label: 'Grok',
|
|
111
|
+
title: 'Connect this site to Grok',
|
|
112
|
+
summary: 'Grok on the web signs in here. The Grok CLI and the xAI API send a Content API key instead.',
|
|
113
|
+
action: 'Copy URL',
|
|
114
|
+
copyText: mcpUrl,
|
|
115
|
+
panel: mcpUrl,
|
|
116
|
+
manual: [
|
|
117
|
+
'On grok.com, add a connector and paste the URL, then approve access on this site.',
|
|
118
|
+
`For the Grok CLI or the xAI API, create a Content API key and send ${bearer}. Include the word Bearer.`,
|
|
119
|
+
],
|
|
120
|
+
needsApiKey: true,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
id: 'cursor',
|
|
124
|
+
label: 'Cursor',
|
|
125
|
+
title: 'Connect this site to Cursor',
|
|
126
|
+
summary: 'Cursor runs the local server. Create a Content API key and replace the placeholder.',
|
|
127
|
+
action: 'Copy config',
|
|
128
|
+
copyText: cursorConfig,
|
|
129
|
+
panel: cursorConfig,
|
|
130
|
+
manual: [
|
|
131
|
+
'Open Cursor → Settings → MCP and add a new server, or paste this into .cursor/mcp.json.',
|
|
132
|
+
'Create a Content API key and replace act_sk_... . Do not commit the file.',
|
|
133
|
+
],
|
|
134
|
+
needsApiKey: true,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: 'vscode',
|
|
138
|
+
label: 'VS Code',
|
|
139
|
+
title: 'Connect this site to VS Code',
|
|
140
|
+
summary: 'Save this as .vscode/mcp.json. Create a Content API key and replace the placeholder.',
|
|
141
|
+
action: 'Copy config',
|
|
142
|
+
copyText: vscodeConfig,
|
|
143
|
+
panel: vscodeConfig,
|
|
144
|
+
manual: [
|
|
145
|
+
'Save the config as .vscode/mcp.json.',
|
|
146
|
+
'Create a Content API key and replace act_sk_... . Do not commit the file.',
|
|
147
|
+
],
|
|
148
|
+
needsApiKey: true,
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: 'other',
|
|
152
|
+
label: 'Other',
|
|
153
|
+
title: 'Connect another client',
|
|
154
|
+
summary: 'Clients that can sign in use the URL. Clients that can set a header use a Content API key.',
|
|
155
|
+
action: 'Copy URL',
|
|
156
|
+
copyText: mcpUrl,
|
|
157
|
+
panel: mcpUrl,
|
|
158
|
+
manual: [
|
|
159
|
+
'Point the client at the server URL.',
|
|
160
|
+
'If it signs in, approve access on this site. If it sends a header, use a Content API key as Authorization: Bearer act_sk_... . Do not put the key in the query string.',
|
|
161
|
+
],
|
|
162
|
+
needsApiKey: true,
|
|
163
|
+
},
|
|
164
|
+
];
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=mcp-connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-connect.js","sourceRoot":"","sources":["../../../src/views/settings/mcp-connect.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AdminBrandingMode, type ColorMode, type ResolvedAdminBrand, type ResolvedPublicBrand, type SidebarDensity } from '@prenta/core/appearance';
|
|
1
|
+
import { type AdminBrandingMode, type ColorMode, type ResolvedAdminBrand, type PublicTheme, type ResolvedPublicBrand, type SidebarDensity } from '@prenta/core/appearance';
|
|
2
2
|
import { type AssetPreview } from '../../lib/appearance-api.js';
|
|
3
3
|
import type { SettingsSourceMetadata, ValidationIssue } from './useGeneralSettings.js';
|
|
4
4
|
type SaveState = 'idle' | 'saving' | 'success' | 'error';
|
|
@@ -9,6 +9,7 @@ interface AppearanceForm {
|
|
|
9
9
|
density: SidebarDensity;
|
|
10
10
|
font: string;
|
|
11
11
|
reduceMotion: boolean;
|
|
12
|
+
publicTheme: Required<PublicTheme>;
|
|
12
13
|
}
|
|
13
14
|
/** Brand asset references + admin branding mode (the `brand` settings blob). */
|
|
14
15
|
interface BrandForm {
|
|
@@ -67,6 +68,7 @@ export interface UseAppearanceSettings {
|
|
|
67
68
|
setDensity: (v: SidebarDensity) => void;
|
|
68
69
|
setFont: (v: string) => void;
|
|
69
70
|
setReduceMotion: (v: boolean) => void;
|
|
71
|
+
setPublicTheme: (patch: Partial<PublicTheme>) => void;
|
|
70
72
|
setBrandingMode: (v: AdminBrandingMode) => void;
|
|
71
73
|
setAltText: (v: string) => void;
|
|
72
74
|
uploadAsset: (field: BrandAssetField, file: File) => Promise<void>;
|