@orion-studios/payload-studio 0.6.0-beta.24 → 0.6.0-beta.26

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.
@@ -5928,15 +5928,11 @@ var getFormTitle2 = (value) => {
5928
5928
  // src/admin/components/studio/AdminStudioFormDetailView.tsx
5929
5929
  import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
5930
5930
  var getNonEmptyText = (value, fallback = "") => typeof value === "string" && value.trim().length > 0 ? value : fallback;
5931
- var formatStepsText = (value) => {
5931
+ var normalizeSteps = (value) => {
5932
5932
  if (!Array.isArray(value)) {
5933
- return "[]";
5934
- }
5935
- try {
5936
- return JSON.stringify(value, null, 2);
5937
- } catch {
5938
- return "[]";
5933
+ return [];
5939
5934
  }
5935
+ return value.map((step) => step && typeof step === "object" && !Array.isArray(step) ? step : {});
5940
5936
  };
5941
5937
  var toEditorState = (doc) => {
5942
5938
  const emails = doc.emails && typeof doc.emails === "object" ? doc.emails : null;
@@ -5952,7 +5948,7 @@ var toEditorState = (doc) => {
5952
5948
  sendAdmin: emails?.sendAdmin !== false,
5953
5949
  sendConfirmation: emails?.sendConfirmation !== false,
5954
5950
  slug: getNonEmptyText(doc.slug),
5955
- stepsText: formatStepsText(doc.steps),
5951
+ steps: normalizeSteps(doc.steps),
5956
5952
  submitLabel: getNonEmptyText(doc.submitLabel, "Submit"),
5957
5953
  successMessage: getNonEmptyText(doc.successMessage),
5958
5954
  title: getNonEmptyText(doc.title, "Untitled Form")
@@ -5963,25 +5959,54 @@ var checkboxLabelStyle = {
5963
5959
  display: "flex",
5964
5960
  gap: "0.6rem"
5965
5961
  };
5966
- var codeStyle = {
5967
- background: "color-mix(in srgb, var(--orion-admin-card-bg) 82%, black)",
5968
- border: "1px solid var(--orion-admin-card-border)",
5969
- borderRadius: "var(--orion-admin-radius-sm)",
5970
- color: "var(--orion-admin-text)",
5971
- fontFamily: "ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, monospace",
5972
- fontSize: "0.86rem",
5973
- lineHeight: 1.55,
5974
- margin: 0,
5975
- maxHeight: "28rem",
5976
- overflow: "auto",
5977
- padding: "0.9rem",
5978
- whiteSpace: "pre-wrap"
5979
- };
5980
5962
  var sectionGridStyle = {
5981
5963
  display: "grid",
5982
5964
  gap: "1rem",
5983
5965
  gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))"
5984
5966
  };
5967
+ var fieldTypeOptions = [
5968
+ "text",
5969
+ "textarea",
5970
+ "email",
5971
+ "phone",
5972
+ "url",
5973
+ "select",
5974
+ "radio",
5975
+ "checkbox",
5976
+ "checkbox-group",
5977
+ "date",
5978
+ "file"
5979
+ ];
5980
+ var getFields = (step) => Array.isArray(step.fields) ? step.fields.map(
5981
+ (field) => field && typeof field === "object" && !Array.isArray(field) ? field : {}
5982
+ ) : [];
5983
+ var toOptionsText = (value) => Array.isArray(value) ? value.map((entry) => {
5984
+ if (entry && typeof entry === "object" && !Array.isArray(entry)) {
5985
+ const record = entry;
5986
+ const label = typeof record.label === "string" ? record.label : "";
5987
+ const optionValue = typeof record.value === "string" ? record.value : label;
5988
+ return label && optionValue && label !== optionValue ? `${label} | ${optionValue}` : label || optionValue;
5989
+ }
5990
+ return typeof entry === "string" ? entry : "";
5991
+ }).filter(Boolean).join("\n") : "";
5992
+ var fromOptionsText = (value) => value.split("\n").map((entry) => entry.trim()).filter(Boolean).map((entry) => {
5993
+ const [label, optionValue] = entry.split("|").map((part) => part.trim());
5994
+ return {
5995
+ label,
5996
+ value: optionValue || label
5997
+ };
5998
+ });
5999
+ var slugifyFieldName = (value) => value.trim().replace(/[^a-z0-9]+/gi, " ").trim().replace(/\s+([a-z0-9])/gi, (_, char) => char.toUpperCase()).replace(/^./, (char) => char.toLowerCase());
6000
+ var blankField = () => ({
6001
+ label: "New field",
6002
+ name: "newField",
6003
+ required: false,
6004
+ type: "text"
6005
+ });
6006
+ var blankStep = () => ({
6007
+ fields: [blankField()],
6008
+ title: "New step"
6009
+ });
5985
6010
  function getFormIDFromPathname(pathname) {
5986
6011
  const marker = "/forms/";
5987
6012
  const raw = getIDFromPathname(pathname, marker);
@@ -6074,10 +6099,6 @@ function AdminStudioFormDetailView(props) {
6074
6099
  setError(null);
6075
6100
  setSavedMessage(null);
6076
6101
  try {
6077
- const parsedSteps = JSON.parse(editorState.stepsText);
6078
- if (!Array.isArray(parsedSteps)) {
6079
- throw new Error("Structure JSON must be an array of steps.");
6080
- }
6081
6102
  const payload = {
6082
6103
  emails: {
6083
6104
  adminRecipients: editorState.adminRecipientsText.split("\n").map((value) => value.trim()).filter(Boolean).map((email) => ({ email })),
@@ -6089,7 +6110,7 @@ function AdminStudioFormDetailView(props) {
6089
6110
  sendConfirmation: editorState.sendConfirmation
6090
6111
  },
6091
6112
  slug: editorState.slug.trim(),
6092
- steps: parsedSteps,
6113
+ steps: editorState.steps,
6093
6114
  submitLabel: editorState.submitLabel.trim(),
6094
6115
  successMessage: editorState.successMessage,
6095
6116
  title: editorState.title.trim()
@@ -6135,8 +6156,33 @@ function AdminStudioFormDetailView(props) {
6135
6156
  const toneStyle = getFormToneStyle2(slug, title || formID || "form");
6136
6157
  const fieldLabels = doc ? buildFieldLabelMap2(doc) : /* @__PURE__ */ new Map();
6137
6158
  const latestSubmission = submissions[0];
6138
- const stepCount = doc && Array.isArray(doc.steps) ? doc.steps.length : 0;
6139
- const fieldCount = doc ? getFieldCount2(doc) : 0;
6159
+ const stepCount = editorState?.steps.length || 0;
6160
+ const fieldCount = editorState ? editorState.steps.reduce((count, step) => count + getFields(step).length, 0) : doc ? getFieldCount2(doc) : 0;
6161
+ const updateStep = (stepIndex, patch) => {
6162
+ setEditorState(
6163
+ (current) => current ? {
6164
+ ...current,
6165
+ steps: current.steps.map(
6166
+ (step, index) => index === stepIndex ? { ...step, ...patch } : step
6167
+ )
6168
+ } : current
6169
+ );
6170
+ };
6171
+ const updateField = (stepIndex, fieldIndex, patch) => {
6172
+ setEditorState((current) => {
6173
+ if (!current) return current;
6174
+ return {
6175
+ ...current,
6176
+ steps: current.steps.map((step, index) => {
6177
+ if (index !== stepIndex) return step;
6178
+ const fields = getFields(step).map(
6179
+ (field, currentFieldIndex) => currentFieldIndex === fieldIndex ? { ...field, ...patch } : field
6180
+ );
6181
+ return { ...step, fields };
6182
+ })
6183
+ };
6184
+ });
6185
+ };
6140
6186
  return /* @__PURE__ */ jsx30(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ jsxs27(
6141
6187
  AdminPage,
6142
6188
  {
@@ -6215,10 +6261,9 @@ function AdminStudioFormDetailView(props) {
6215
6261
  /* @__PURE__ */ jsxs27("div", { style: { display: "grid", gap: "1rem" }, children: [
6216
6262
  /* @__PURE__ */ jsxs27("div", { className: "orion-admin-card", children: [
6217
6263
  /* @__PURE__ */ jsx30("strong", { children: "Step preview" }),
6218
- /* @__PURE__ */ jsx30("span", { children: "Review the configured workflow structure before editing the JSON source." }),
6219
- /* @__PURE__ */ jsx30("div", { style: { display: "grid", gap: "0.85rem", marginTop: "1rem" }, children: Array.isArray(doc.steps) && doc.steps.length > 0 ? doc.steps.map((step, stepIndex) => {
6220
- const record = step && typeof step === "object" && !Array.isArray(step) ? step : null;
6221
- const fields = Array.isArray(record?.fields) ? record.fields : [];
6264
+ /* @__PURE__ */ jsx30("span", { children: "Review the public workflow as visitors will move through it." }),
6265
+ /* @__PURE__ */ jsx30("div", { style: { display: "grid", gap: "0.85rem", marginTop: "1rem" }, children: editorState.steps.length > 0 ? editorState.steps.map((record, stepIndex) => {
6266
+ const fields = getFields(record);
6222
6267
  return /* @__PURE__ */ jsxs27("div", { className: "orion-admin-form", children: [
6223
6268
  /* @__PURE__ */ jsxs27("div", { children: [
6224
6269
  /* @__PURE__ */ jsxs27("strong", { children: [
@@ -6270,7 +6315,7 @@ function AdminStudioFormDetailView(props) {
6270
6315
  ] }, `step-${stepIndex}`);
6271
6316
  }) : /* @__PURE__ */ jsxs27("div", { className: "orion-admin-empty-state", children: [
6272
6317
  /* @__PURE__ */ jsx30("strong", { children: "No steps configured" }),
6273
- /* @__PURE__ */ jsx30("span", { children: "Add at least one step in the JSON editor to publish this form." })
6318
+ /* @__PURE__ */ jsx30("span", { children: "Add at least one step in Form settings to publish this form." })
6274
6319
  ] }) })
6275
6320
  ] }),
6276
6321
  /* @__PURE__ */ jsxs27("div", { className: "orion-admin-card", children: [
@@ -6452,32 +6497,226 @@ function AdminStudioFormDetailView(props) {
6452
6497
  ] })
6453
6498
  ] })
6454
6499
  ] }),
6455
- /* @__PURE__ */ jsxs27("label", { children: [
6456
- "Structure JSON",
6457
- /* @__PURE__ */ jsx30(
6458
- "textarea",
6459
- {
6460
- onChange: (event) => setEditorState(
6461
- (current) => current ? { ...current, stepsText: event.target.value } : current
6462
- ),
6463
- rows: 18,
6464
- spellCheck: false,
6465
- style: {
6466
- fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
6467
- minHeight: "24rem"
6468
- },
6469
- value: editorState.stepsText
6470
- }
6471
- )
6500
+ /* @__PURE__ */ jsxs27("div", { className: "orion-admin-card", children: [
6501
+ /* @__PURE__ */ jsx30("strong", { children: "Form steps" }),
6502
+ /* @__PURE__ */ jsx30("span", { children: "Edit the public workflow with plain labels and field settings." }),
6503
+ /* @__PURE__ */ jsxs27("div", { style: { display: "grid", gap: "1rem", marginTop: "1rem" }, children: [
6504
+ editorState.steps.map((step, stepIndex) => {
6505
+ const fields = getFields(step);
6506
+ const title2 = getNonEmptyText(step.title, `Step ${stepIndex + 1}`);
6507
+ return /* @__PURE__ */ jsxs27("div", { className: "orion-admin-form", children: [
6508
+ /* @__PURE__ */ jsxs27("div", { className: "orion-admin-inline-actions", style: { justifyContent: "space-between" }, children: [
6509
+ /* @__PURE__ */ jsx30("strong", { children: title2 }),
6510
+ /* @__PURE__ */ jsx30(
6511
+ "button",
6512
+ {
6513
+ className: "orion-admin-action-button orion-admin-action-button--ghost",
6514
+ onClick: () => setEditorState(
6515
+ (current) => current ? {
6516
+ ...current,
6517
+ steps: current.steps.filter((_, index) => index !== stepIndex)
6518
+ } : current
6519
+ ),
6520
+ type: "button",
6521
+ children: "Remove step"
6522
+ }
6523
+ )
6524
+ ] }),
6525
+ /* @__PURE__ */ jsxs27("label", { children: [
6526
+ "Step title",
6527
+ /* @__PURE__ */ jsx30(
6528
+ "input",
6529
+ {
6530
+ onChange: (event) => updateStep(stepIndex, { title: event.target.value }),
6531
+ type: "text",
6532
+ value: getNonEmptyText(step.title)
6533
+ }
6534
+ )
6535
+ ] }),
6536
+ /* @__PURE__ */ jsxs27("label", { children: [
6537
+ "Step intro text",
6538
+ /* @__PURE__ */ jsx30(
6539
+ "textarea",
6540
+ {
6541
+ onChange: (event) => updateStep(stepIndex, { subtitle: event.target.value }),
6542
+ rows: 3,
6543
+ value: getNonEmptyText(step.subtitle)
6544
+ }
6545
+ )
6546
+ ] }),
6547
+ /* @__PURE__ */ jsxs27("label", { children: [
6548
+ "Next button label",
6549
+ /* @__PURE__ */ jsx30(
6550
+ "input",
6551
+ {
6552
+ onChange: (event) => updateStep(stepIndex, { nextLabel: event.target.value }),
6553
+ placeholder: "Next",
6554
+ type: "text",
6555
+ value: getNonEmptyText(step.nextLabel)
6556
+ }
6557
+ )
6558
+ ] }),
6559
+ /* @__PURE__ */ jsxs27("label", { style: checkboxLabelStyle, children: [
6560
+ /* @__PURE__ */ jsx30(
6561
+ "input",
6562
+ {
6563
+ checked: step.allowSkip === true,
6564
+ onChange: (event) => updateStep(stepIndex, { allowSkip: event.target.checked }),
6565
+ type: "checkbox"
6566
+ }
6567
+ ),
6568
+ "Allow visitors to skip this step"
6569
+ ] }),
6570
+ /* @__PURE__ */ jsxs27("div", { style: { display: "grid", gap: "0.85rem" }, children: [
6571
+ /* @__PURE__ */ jsx30("strong", { children: "Fields" }),
6572
+ fields.map((field, fieldIndex) => {
6573
+ const label = getNonEmptyText(field.label, `Field ${fieldIndex + 1}`);
6574
+ const fieldType = getNonEmptyText(field.type, "text");
6575
+ return /* @__PURE__ */ jsxs27("div", { className: "orion-admin-card", children: [
6576
+ /* @__PURE__ */ jsxs27(
6577
+ "div",
6578
+ {
6579
+ className: "orion-admin-inline-actions",
6580
+ style: { justifyContent: "space-between" },
6581
+ children: [
6582
+ /* @__PURE__ */ jsx30("strong", { children: label }),
6583
+ /* @__PURE__ */ jsx30(
6584
+ "button",
6585
+ {
6586
+ className: "orion-admin-action-button orion-admin-action-button--ghost",
6587
+ onClick: () => setEditorState((current) => {
6588
+ if (!current) return current;
6589
+ return {
6590
+ ...current,
6591
+ steps: current.steps.map(
6592
+ (currentStep, index) => index === stepIndex ? {
6593
+ ...currentStep,
6594
+ fields: getFields(currentStep).filter(
6595
+ (_, currentFieldIndex) => currentFieldIndex !== fieldIndex
6596
+ )
6597
+ } : currentStep
6598
+ )
6599
+ };
6600
+ }),
6601
+ type: "button",
6602
+ children: "Remove field"
6603
+ }
6604
+ )
6605
+ ]
6606
+ }
6607
+ ),
6608
+ /* @__PURE__ */ jsxs27("label", { children: [
6609
+ "Field label",
6610
+ /* @__PURE__ */ jsx30(
6611
+ "input",
6612
+ {
6613
+ onChange: (event) => {
6614
+ const nextLabel = event.target.value;
6615
+ const currentName = getNonEmptyText(field.name);
6616
+ updateField(stepIndex, fieldIndex, {
6617
+ label: nextLabel,
6618
+ name: currentName || slugifyFieldName(nextLabel)
6619
+ });
6620
+ },
6621
+ type: "text",
6622
+ value: label
6623
+ }
6624
+ )
6625
+ ] }),
6626
+ /* @__PURE__ */ jsxs27("label", { children: [
6627
+ "Field key",
6628
+ /* @__PURE__ */ jsx30(
6629
+ "input",
6630
+ {
6631
+ onChange: (event) => updateField(stepIndex, fieldIndex, { name: event.target.value }),
6632
+ type: "text",
6633
+ value: getNonEmptyText(field.name)
6634
+ }
6635
+ )
6636
+ ] }),
6637
+ /* @__PURE__ */ jsxs27("label", { children: [
6638
+ "Field type",
6639
+ /* @__PURE__ */ jsx30(
6640
+ "select",
6641
+ {
6642
+ onChange: (event) => updateField(stepIndex, fieldIndex, { type: event.target.value }),
6643
+ value: fieldType,
6644
+ children: fieldTypeOptions.map((option) => /* @__PURE__ */ jsx30("option", { value: option, children: option }, option))
6645
+ }
6646
+ )
6647
+ ] }),
6648
+ /* @__PURE__ */ jsxs27("label", { style: checkboxLabelStyle, children: [
6649
+ /* @__PURE__ */ jsx30(
6650
+ "input",
6651
+ {
6652
+ checked: field.required === true,
6653
+ onChange: (event) => updateField(stepIndex, fieldIndex, { required: event.target.checked }),
6654
+ type: "checkbox"
6655
+ }
6656
+ ),
6657
+ "Required"
6658
+ ] }),
6659
+ /* @__PURE__ */ jsxs27("label", { children: [
6660
+ "Help text",
6661
+ /* @__PURE__ */ jsx30(
6662
+ "textarea",
6663
+ {
6664
+ onChange: (event) => updateField(stepIndex, fieldIndex, { helpText: event.target.value }),
6665
+ rows: 2,
6666
+ value: getNonEmptyText(field.helpText)
6667
+ }
6668
+ )
6669
+ ] }),
6670
+ ["select", "radio", "checkbox-group"].includes(fieldType) ? /* @__PURE__ */ jsxs27("label", { children: [
6671
+ "Options",
6672
+ /* @__PURE__ */ jsx30(
6673
+ "textarea",
6674
+ {
6675
+ onChange: (event) => updateField(stepIndex, fieldIndex, {
6676
+ options: fromOptionsText(event.target.value)
6677
+ }),
6678
+ placeholder: "Option one\nOption two",
6679
+ rows: 4,
6680
+ value: toOptionsText(field.options)
6681
+ }
6682
+ )
6683
+ ] }) : null
6684
+ ] }, `edit-field-${stepIndex}-${fieldIndex}`);
6685
+ }),
6686
+ /* @__PURE__ */ jsx30(
6687
+ "button",
6688
+ {
6689
+ className: "orion-admin-action-button orion-admin-action-button--ghost",
6690
+ onClick: () => setEditorState(
6691
+ (current) => current ? {
6692
+ ...current,
6693
+ steps: current.steps.map(
6694
+ (currentStep, index) => index === stepIndex ? { ...currentStep, fields: [...getFields(currentStep), blankField()] } : currentStep
6695
+ )
6696
+ } : current
6697
+ ),
6698
+ type: "button",
6699
+ children: "Add field"
6700
+ }
6701
+ )
6702
+ ] })
6703
+ ] }, `edit-step-${stepIndex}`);
6704
+ }),
6705
+ /* @__PURE__ */ jsx30(
6706
+ "button",
6707
+ {
6708
+ className: "orion-admin-action-button orion-admin-action-button--ghost",
6709
+ onClick: () => setEditorState(
6710
+ (current) => current ? { ...current, steps: [...current.steps, blankStep()] } : current
6711
+ ),
6712
+ type: "button",
6713
+ children: "Add step"
6714
+ }
6715
+ )
6716
+ ] })
6472
6717
  ] }),
6473
- /* @__PURE__ */ jsx30("div", { className: "orion-admin-list-meta", children: "Edit the public workflow as JSON. The saved payload must remain an array of step objects compatible with the form collection schema." }),
6474
6718
  /* @__PURE__ */ jsx30("button", { disabled: saving, type: "submit", children: saving ? "Saving..." : "Save Form" })
6475
6719
  ] })
6476
- ] }),
6477
- /* @__PURE__ */ jsxs27("div", { className: "orion-admin-card", children: [
6478
- /* @__PURE__ */ jsx30("strong", { children: "Current structure payload" }),
6479
- /* @__PURE__ */ jsx30("span", { children: "Reference snapshot of the form steps that will be written back on save." }),
6480
- /* @__PURE__ */ jsx30("pre", { style: { ...codeStyle, marginTop: "1rem" }, children: editorState.stepsText })
6481
6720
  ] })
6482
6721
  ] }) : null
6483
6722
  ]
@@ -6489,25 +6728,17 @@ function AdminStudioFormDetailView(props) {
6489
6728
  import Link5 from "next/link";
6490
6729
  import { useEffect as useEffect19, useMemo as useMemo15, useState as useState20 } from "react";
6491
6730
  import { Fragment as Fragment6, jsx as jsx31, jsxs as jsxs28 } from "react/jsx-runtime";
6492
- var codeStyle2 = {
6493
- background: "color-mix(in srgb, var(--orion-admin-card-bg) 82%, black)",
6494
- border: "1px solid var(--orion-admin-card-border)",
6495
- borderRadius: "var(--orion-admin-radius-sm)",
6496
- color: "var(--orion-admin-text)",
6497
- fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
6498
- fontSize: "0.86rem",
6499
- lineHeight: 1.55,
6500
- margin: 0,
6501
- maxHeight: "28rem",
6502
- overflow: "auto",
6503
- padding: "0.9rem",
6504
- whiteSpace: "pre-wrap"
6505
- };
6506
6731
  var sectionGridStyle2 = {
6507
6732
  display: "grid",
6508
6733
  gap: "1rem",
6509
6734
  gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))"
6510
6735
  };
6736
+ var nestedListStyle = {
6737
+ display: "grid",
6738
+ gap: "0.45rem",
6739
+ margin: 0,
6740
+ padding: 0
6741
+ };
6511
6742
  var renderFieldValue = (value) => {
6512
6743
  if (value === null || value === void 0) {
6513
6744
  return /* @__PURE__ */ jsx31("span", { className: "orion-admin-list-meta", children: "No value" });
@@ -6521,7 +6752,26 @@ var renderFieldValue = (value) => {
6521
6752
  if (typeof value === "string") {
6522
6753
  return value.trim().length > 0 ? value : /* @__PURE__ */ jsx31("span", { className: "orion-admin-list-meta", children: "No value" });
6523
6754
  }
6524
- return /* @__PURE__ */ jsx31("pre", { style: codeStyle2, children: JSON.stringify(value, null, 2) });
6755
+ if (Array.isArray(value)) {
6756
+ const entries = value.filter((entry) => entry !== null && entry !== void 0 && entry !== "");
6757
+ if (entries.length === 0) {
6758
+ return /* @__PURE__ */ jsx31("span", { className: "orion-admin-list-meta", children: "No value" });
6759
+ }
6760
+ return /* @__PURE__ */ jsx31("ul", { style: nestedListStyle, children: entries.map((entry, index) => /* @__PURE__ */ jsx31("li", { children: renderFieldValue(entry) }, index)) });
6761
+ }
6762
+ if (typeof value === "object") {
6763
+ const entries = Object.entries(value).filter(
6764
+ ([, entryValue]) => entryValue !== null && entryValue !== void 0 && entryValue !== ""
6765
+ );
6766
+ if (entries.length === 0) {
6767
+ return /* @__PURE__ */ jsx31("span", { className: "orion-admin-list-meta", children: "No value" });
6768
+ }
6769
+ return /* @__PURE__ */ jsx31("div", { style: { display: "grid", gap: "0.65rem" }, children: entries.map(([key, entryValue]) => /* @__PURE__ */ jsxs28("div", { className: "orion-admin-meta-row", children: [
6770
+ /* @__PURE__ */ jsx31("span", { className: "orion-admin-meta-label", children: humanizeKey2(key) }),
6771
+ /* @__PURE__ */ jsx31("span", { className: "orion-admin-meta-value", children: renderFieldValue(entryValue) })
6772
+ ] }, key)) });
6773
+ }
6774
+ return String(value);
6525
6775
  };
6526
6776
  function getSubmissionIDFromPathname(pathname) {
6527
6777
  return getIDFromPathname(pathname, "/forms/submissions/");
@@ -6673,31 +6923,24 @@ function AdminStudioFormSubmissionView(props) {
6673
6923
  /* @__PURE__ */ jsxs28("article", { className: "orion-admin-overview-stat", children: [
6674
6924
  /* @__PURE__ */ jsx31("span", { className: "orion-admin-overview-stat-label", children: "Highlighted answers" }),
6675
6925
  /* @__PURE__ */ jsx31("strong", { children: previewFields.length }),
6676
- /* @__PURE__ */ jsx31("p", { children: "Readable answer previews surfaced from the structured payload." })
6926
+ /* @__PURE__ */ jsx31("p", { children: "Readable answer previews from this response." })
6677
6927
  ] })
6678
6928
  ] }),
6679
6929
  /* @__PURE__ */ jsxs28("div", { style: sectionGridStyle2, children: [
6680
- /* @__PURE__ */ jsxs28("div", { style: { display: "grid", gap: "1rem" }, children: [
6681
- /* @__PURE__ */ jsxs28("div", { className: "orion-admin-card", children: [
6682
- /* @__PURE__ */ jsx31("strong", { children: "Response details" }),
6683
- /* @__PURE__ */ jsx31("span", { children: "Formatted answers using the current form field labels when available." }),
6684
- /* @__PURE__ */ jsx31("div", { style: { display: "grid", gap: "0.85rem", marginTop: "1rem" }, children: answerEntries.length > 0 ? answerEntries.map(([key, value]) => /* @__PURE__ */ jsxs28("div", { className: "orion-admin-form", children: [
6685
- /* @__PURE__ */ jsxs28("div", { children: [
6686
- /* @__PURE__ */ jsx31("strong", { children: fieldLabels.get(key) || humanizeKey2(key) }),
6687
- /* @__PURE__ */ jsx31("div", { className: "orion-admin-list-meta", children: key })
6688
- ] }),
6689
- /* @__PURE__ */ jsx31("div", { children: renderFieldValue(value) })
6690
- ] }, key)) : /* @__PURE__ */ jsxs28("div", { className: "orion-admin-empty-state", children: [
6691
- /* @__PURE__ */ jsx31("strong", { children: "No response payload" }),
6692
- /* @__PURE__ */ jsx31("span", { children: "This submission does not contain a structured data object." })
6693
- ] }) })
6694
- ] }),
6695
- /* @__PURE__ */ jsxs28("div", { className: "orion-admin-card", children: [
6696
- /* @__PURE__ */ jsx31("strong", { children: "Raw payload" }),
6697
- /* @__PURE__ */ jsx31("span", { children: "Verbatim submission data for troubleshooting or export checks." }),
6698
- /* @__PURE__ */ jsx31("pre", { style: { ...codeStyle2, marginTop: "1rem" }, children: JSON.stringify(doc.data ?? {}, null, 2) })
6699
- ] })
6700
- ] }),
6930
+ /* @__PURE__ */ jsx31("div", { style: { display: "grid", gap: "1rem" }, children: /* @__PURE__ */ jsxs28("div", { className: "orion-admin-card", children: [
6931
+ /* @__PURE__ */ jsx31("strong", { children: "Response details" }),
6932
+ /* @__PURE__ */ jsx31("span", { children: "Formatted answers using the current form field labels when available." }),
6933
+ /* @__PURE__ */ jsx31("div", { style: { display: "grid", gap: "0.85rem", marginTop: "1rem" }, children: answerEntries.length > 0 ? answerEntries.map(([key, value]) => /* @__PURE__ */ jsxs28("div", { className: "orion-admin-form", children: [
6934
+ /* @__PURE__ */ jsxs28("div", { children: [
6935
+ /* @__PURE__ */ jsx31("strong", { children: fieldLabels.get(key) || humanizeKey2(key) }),
6936
+ /* @__PURE__ */ jsx31("div", { className: "orion-admin-list-meta", children: key })
6937
+ ] }),
6938
+ /* @__PURE__ */ jsx31("div", { children: renderFieldValue(value) })
6939
+ ] }, key)) : /* @__PURE__ */ jsxs28("div", { className: "orion-admin-empty-state", children: [
6940
+ /* @__PURE__ */ jsx31("strong", { children: "No answers available" }),
6941
+ /* @__PURE__ */ jsx31("span", { children: "This submission does not contain visible response details." })
6942
+ ] }) })
6943
+ ] }) }),
6701
6944
  /* @__PURE__ */ jsxs28("div", { style: { display: "grid", gap: "1rem" }, children: [
6702
6945
  /* @__PURE__ */ jsxs28("div", { className: "orion-admin-card orion-admin-meta-table", children: [
6703
6946
  /* @__PURE__ */ jsxs28("div", { className: "orion-admin-meta-row", children: [
@@ -957,6 +957,12 @@ var toMediaLibraryItem = (value) => {
957
957
  };
958
958
  };
959
959
  var mediaLabel = (item) => item.filename || item.alt || `Media #${item.id}`;
960
+ var findMediaLibraryItem = (library, id) => {
961
+ if (id === null) {
962
+ return null;
963
+ }
964
+ return library.find((item) => String(item.id) === String(id)) || null;
965
+ };
960
966
  var groupLabel = (key) => commonInspectorGroups.find((group) => group.key === key)?.label || key;
961
967
  function BlockInspectorRenderer({
962
968
  block,
@@ -1080,8 +1086,9 @@ function BlockInspectorRenderer({
1080
1086
  title: group.label,
1081
1087
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "orion-builder-settings-field-list", children: [
1082
1088
  group.key === "media" ? effectiveMediaSources.map((source) => {
1083
- const selectedSourceMedia = toMediaLibraryItem(source.value);
1084
1089
  const selectedSourceMediaID = getRelationID(source.value);
1090
+ const selectedRelationMedia = toMediaLibraryItem(source.value);
1091
+ const selectedSourceMedia = selectedRelationMedia ?? findMediaLibraryItem(source.library, selectedSourceMediaID);
1085
1092
  const sourceOptions = selectedSourceMedia && !source.library.some((item) => String(item.id) === String(selectedSourceMedia.id)) ? [selectedSourceMedia, ...source.library] : source.library;
1086
1093
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1087
1094
  "div",
@@ -1106,6 +1113,10 @@ function BlockInspectorRenderer({
1106
1113
  }
1107
1114
  )
1108
1115
  ] }),
1116
+ selectedSourceMedia?.alt ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "orion-builder-settings-label", children: [
1117
+ "Media Description",
1118
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { className: "orion-builder-settings-input", readOnly: true, type: "text", value: selectedSourceMedia.alt })
1119
+ ] }) : selectedSourceMediaID !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "orion-builder-settings-note", children: "This media item does not have a description yet." }) : null,
1109
1120
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1110
1121
  "button",
1111
1122
  {
@@ -2998,6 +3009,12 @@ var toMediaLibraryItem2 = (value) => {
2998
3009
  };
2999
3010
  };
3000
3011
  var mediaLabel2 = (item) => item.filename || item.alt || `Media #${item.id}`;
3012
+ var findMediaLibraryItem2 = (library, id) => {
3013
+ if (id === null) {
3014
+ return null;
3015
+ }
3016
+ return library.find((item) => String(item.id) === String(id)) || null;
3017
+ };
3001
3018
  var normalizeImageFit = (value) => value === "contain" ? "contain" : "cover";
3002
3019
  var normalizeImageCornerStyle = (value) => value === "square" ? "square" : "rounded";
3003
3020
  var getItemMediaSettings = (item) => {
@@ -3088,8 +3105,9 @@ function ItemMediaControl({
3088
3105
  uploadLabel,
3089
3106
  uploading
3090
3107
  }) {
3091
- const selectedMedia = toMediaLibraryItem2(item[fieldName]);
3092
3108
  const selectedMediaID = getRelationID2(item[fieldName]);
3109
+ const selectedRelationMedia = toMediaLibraryItem2(item[fieldName]);
3110
+ const selectedMedia = selectedRelationMedia ?? findMediaLibraryItem2(mediaLibrary, selectedMediaID);
3093
3111
  const directImageURL = normalizeText(item[imageURLFieldName]);
3094
3112
  const previewURL = selectedMedia?.url || directImageURL;
3095
3113
  const mediaSettings = getItemMediaSettings(item);
@@ -3135,6 +3153,10 @@ function ItemMediaControl({
3135
3153
  }
3136
3154
  )
3137
3155
  ] }),
3156
+ selectedMedia?.alt ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "orion-builder-settings-label", children: [
3157
+ "Media Description",
3158
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { className: "orion-builder-settings-input", readOnly: true, type: "text", value: selectedMedia.alt })
3159
+ ] }) : selectedMediaID !== null ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "orion-builder-settings-note", children: "This media item does not have a description yet." }) : null,
3138
3160
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3139
3161
  "button",
3140
3162
  {
@@ -6968,12 +6990,12 @@ function BuilderPageEditor({
6968
6990
  }
6969
6991
  ) : null,
6970
6992
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { style: sidebarLabelStyle, children: [
6971
- "Upload Alt Text",
6993
+ "New Upload Alt Text",
6972
6994
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6973
6995
  "input",
6974
6996
  {
6975
6997
  onChange: (event) => setUploadAltText(event.target.value),
6976
- placeholder: "Describe the image",
6998
+ placeholder: "Used only when uploading a new image",
6977
6999
  style: sidebarInputStyle,
6978
7000
  type: "text",
6979
7001
  value: uploadAltText