pxengine 0.1.116 → 0.1.117

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/index.d.cts CHANGED
@@ -3558,6 +3558,8 @@ interface DeckOutlineSlide {
3558
3558
  message?: string;
3559
3559
  /** Informational review flag (DEV-194) — never gates Approve & Build. */
3560
3560
  approved?: boolean;
3561
+ /** Per-slide design template override (DEV-194) — unset means "inherit the deck's template". */
3562
+ template_id?: string;
3561
3563
  [key: string]: unknown;
3562
3564
  }
3563
3565
  /** The planned deck outline (deck_plan) shown for approval before rendering. */
@@ -3647,6 +3649,18 @@ interface PresentationJobCardProps {
3647
3649
  * never gates the whole-outline Approve & Build action.
3648
3650
  */
3649
3651
  approveSlideUrl?: string;
3652
+ /**
3653
+ * Set-slide-template endpoint (POST), DEV-194 "slide-level design
3654
+ * templates". Defaults to `/api/presentations/{job_id}/outline/set-slide-template`.
3655
+ * Gives one outline slide its own design template, overriding the deck's
3656
+ * overall template for just that slide.
3657
+ */
3658
+ setSlideTemplateUrl?: string;
3659
+ /**
3660
+ * Templates list endpoint (GET), used to populate the per-slide template
3661
+ * override <select>. Defaults to `/api/presentations/templates`.
3662
+ */
3663
+ templatesUrl?: string;
3650
3664
  /** Regenerate endpoint (POST). Defaults to `/api/presentations/{job_id}/regenerate`. */
3651
3665
  regenerateUrl?: string;
3652
3666
  /**
package/dist/index.d.ts CHANGED
@@ -3558,6 +3558,8 @@ interface DeckOutlineSlide {
3558
3558
  message?: string;
3559
3559
  /** Informational review flag (DEV-194) — never gates Approve & Build. */
3560
3560
  approved?: boolean;
3561
+ /** Per-slide design template override (DEV-194) — unset means "inherit the deck's template". */
3562
+ template_id?: string;
3561
3563
  [key: string]: unknown;
3562
3564
  }
3563
3565
  /** The planned deck outline (deck_plan) shown for approval before rendering. */
@@ -3647,6 +3649,18 @@ interface PresentationJobCardProps {
3647
3649
  * never gates the whole-outline Approve & Build action.
3648
3650
  */
3649
3651
  approveSlideUrl?: string;
3652
+ /**
3653
+ * Set-slide-template endpoint (POST), DEV-194 "slide-level design
3654
+ * templates". Defaults to `/api/presentations/{job_id}/outline/set-slide-template`.
3655
+ * Gives one outline slide its own design template, overriding the deck's
3656
+ * overall template for just that slide.
3657
+ */
3658
+ setSlideTemplateUrl?: string;
3659
+ /**
3660
+ * Templates list endpoint (GET), used to populate the per-slide template
3661
+ * override <select>. Defaults to `/api/presentations/templates`.
3662
+ */
3663
+ templatesUrl?: string;
3650
3664
  /** Regenerate endpoint (POST). Defaults to `/api/presentations/{job_id}/regenerate`. */
3651
3665
  regenerateUrl?: string;
3652
3666
  /**
package/dist/index.mjs CHANGED
@@ -16030,6 +16030,8 @@ var PresentationJobCard = ({
16030
16030
  approveOutlineUrl,
16031
16031
  reorderSlidesUrl,
16032
16032
  approveSlideUrl,
16033
+ setSlideTemplateUrl,
16034
+ templatesUrl,
16033
16035
  regenerateUrl,
16034
16036
  hideApproval = false,
16035
16037
  className,
@@ -16052,6 +16054,7 @@ var PresentationJobCard = ({
16052
16054
  const [, setTemplateVersionId] = useState10(initialTemplateVersionId || "");
16053
16055
  const [reviewStatus, setReviewStatus] = useState10(initialReviewStatus || "");
16054
16056
  const [outline, setOutline] = useState10(initialOutline);
16057
+ const [slideTemplateOptions, setSlideTemplateOptions] = useState10(null);
16055
16058
  const [showExport, setShowExport] = useState10(false);
16056
16059
  const [showFullscreen, setShowFullscreen] = useState10(false);
16057
16060
  const [copied, setCopied] = useState10(false);
@@ -16106,6 +16109,33 @@ var PresentationJobCard = ({
16106
16109
  useEffect7(() => {
16107
16110
  if (initialOutline) setOutline(initialOutline);
16108
16111
  }, [initialOutlineSlideCount]);
16112
+ useEffect7(() => {
16113
+ if (reviewStatus !== "pending_outline_approval" || slideTemplateOptions !== null) return;
16114
+ let cancelled = false;
16115
+ (async () => {
16116
+ try {
16117
+ const endpoint = templatesUrl || "/api/presentations/templates";
16118
+ const headers = {};
16119
+ if (authToken) headers.Authorization = `Bearer ${authToken}`;
16120
+ const res = await fetch(endpoint, { headers });
16121
+ if (!res.ok) throw new Error(`Templates fetch failed (${res.status})`);
16122
+ const list = await res.json();
16123
+ if (!cancelled && Array.isArray(list)) {
16124
+ setSlideTemplateOptions(
16125
+ list.map((t2) => ({
16126
+ id: t2.template_id || t2.id || "",
16127
+ name: t2.name || t2.template_id || t2.id || ""
16128
+ }))
16129
+ );
16130
+ }
16131
+ } catch {
16132
+ if (!cancelled) setSlideTemplateOptions([]);
16133
+ }
16134
+ })();
16135
+ return () => {
16136
+ cancelled = true;
16137
+ };
16138
+ }, [reviewStatus, slideTemplateOptions, templatesUrl, authToken]);
16109
16139
  const updateScale = useCallback4(() => {
16110
16140
  if (previewRef.current) setPreviewScale(previewRef.current.offsetWidth / 1280);
16111
16141
  }, []);
@@ -16365,6 +16395,41 @@ var PresentationJobCard = ({
16365
16395
  setRowBusyIndex(null);
16366
16396
  }
16367
16397
  };
16398
+ const setSlideTemplate = async (index, templateId2) => {
16399
+ if (!outline || !Array.isArray(outline.slides) || rowBusyIndex !== null) return;
16400
+ const slides = outline.slides;
16401
+ const previousOutline = outline;
16402
+ const updated = slides.map((s, i) => {
16403
+ if (i !== index) return s;
16404
+ if (!templateId2) {
16405
+ const { template_id: _drop, ...rest } = s;
16406
+ return rest;
16407
+ }
16408
+ return { ...s, template_id: templateId2 };
16409
+ });
16410
+ setOutline({ ...outline, slides: updated });
16411
+ setRowBusyIndex(index);
16412
+ setRowError(null);
16413
+ try {
16414
+ const endpoint = setSlideTemplateUrl || `/api/presentations/${_job_id}/outline/set-slide-template`;
16415
+ const headers = { "Content-Type": "application/json" };
16416
+ if (authToken) headers.Authorization = `Bearer ${authToken}`;
16417
+ const res = await fetch(endpoint, {
16418
+ method: "POST",
16419
+ headers,
16420
+ body: JSON.stringify({ slide_index: index, template_id: templateId2 || null })
16421
+ });
16422
+ if (!res.ok) {
16423
+ const err = await res.json().catch(() => ({}));
16424
+ throw new Error(err.detail || err.error || `Template update failed (${res.status})`);
16425
+ }
16426
+ } catch (e) {
16427
+ setOutline(previousOutline);
16428
+ setRowError(e instanceof Error ? e.message : "Could not update slide's template");
16429
+ } finally {
16430
+ setRowBusyIndex(null);
16431
+ }
16432
+ };
16368
16433
  const handleApproveOutline = async () => {
16369
16434
  if (!_job_id || approvingOutline) return;
16370
16435
  const endpoint = approveOutlineUrl || `/api/presentations/${_job_id}/approve-outline`;
@@ -16617,6 +16682,20 @@ var PresentationJobCard = ({
16617
16682
  ]
16618
16683
  }
16619
16684
  ),
16685
+ slideTemplateOptions && slideTemplateOptions.length > 0 && /* @__PURE__ */ jsxs108(
16686
+ "select",
16687
+ {
16688
+ value: s.template_id || "",
16689
+ onChange: (e) => setSlideTemplate(i, e.target.value),
16690
+ disabled: rowBusy,
16691
+ title: "Design template for this slide only (default: deck's template)",
16692
+ className: "w-24 flex-shrink-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-1.5 h-8 text-[10px] text-zinc-300 focus:border-indigo-500 outline-none disabled:opacity-60",
16693
+ children: [
16694
+ /* @__PURE__ */ jsx147("option", { value: "", children: "Deck default" }),
16695
+ slideTemplateOptions.map((opt) => /* @__PURE__ */ jsx147("option", { value: opt.id, children: opt.name }, opt.id))
16696
+ ]
16697
+ }
16698
+ ),
16620
16699
  /* @__PURE__ */ jsx147(
16621
16700
  "input",
16622
16701
  {