@scalar/api-client 3.21.5 → 3.23.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.
Files changed (150) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/hooks/use-file-dialog.js +1 -1
  3. package/dist/hooks/use-file-dialog.js.map +1 -1
  4. package/dist/style.css +1226 -69
  5. package/dist/styles/tailwind.config.css +1 -0
  6. package/dist/v2/blocks/operation-block/helpers/persist-response-cookies.d.ts +3 -3
  7. package/dist/v2/blocks/operation-block/helpers/persist-response-cookies.d.ts.map +1 -1
  8. package/dist/v2/blocks/operation-block/helpers/persist-response-cookies.js +4 -4
  9. package/dist/v2/blocks/operation-block/helpers/persist-response-cookies.js.map +1 -1
  10. package/dist/v2/blocks/operation-block/helpers/validate-path-parameters.js +1 -1
  11. package/dist/v2/blocks/operation-block/helpers/validate-path-parameters.js.map +1 -1
  12. package/dist/v2/blocks/request-block/RequestBlock.vue.d.ts.map +1 -1
  13. package/dist/v2/blocks/request-block/RequestBlock.vue.js +1 -1
  14. package/dist/v2/blocks/request-block/RequestBlock.vue.js.map +1 -1
  15. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js +13 -8
  16. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
  17. package/dist/v2/blocks/request-block/components/RequestBody.vue.d.ts.map +1 -1
  18. package/dist/v2/blocks/request-block/components/RequestBody.vue.js +1 -1
  19. package/dist/v2/blocks/request-block/components/RequestBody.vue.js.map +1 -1
  20. package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js +64 -13
  21. package/dist/v2/blocks/request-block/components/RequestBody.vue.script.js.map +1 -1
  22. package/dist/v2/blocks/request-block/components/RequestBodyForm.vue.d.ts +2 -0
  23. package/dist/v2/blocks/request-block/components/RequestBodyForm.vue.d.ts.map +1 -1
  24. package/dist/v2/blocks/request-block/components/RequestBodyForm.vue.js.map +1 -1
  25. package/dist/v2/blocks/request-block/components/RequestBodyForm.vue.script.js +5 -3
  26. package/dist/v2/blocks/request-block/components/RequestBodyForm.vue.script.js.map +1 -1
  27. package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.d.ts +9 -3
  28. package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.d.ts.map +1 -1
  29. package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.js.map +1 -1
  30. package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.script.js +44 -16
  31. package/dist/v2/blocks/request-block/components/RequestBodyViewToggle.vue.script.js.map +1 -1
  32. package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts +12 -0
  33. package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts.map +1 -1
  34. package/dist/v2/blocks/request-block/components/RequestParams.vue.js.map +1 -1
  35. package/dist/v2/blocks/request-block/components/RequestParams.vue.script.js +132 -32
  36. package/dist/v2/blocks/request-block/components/RequestParams.vue.script.js.map +1 -1
  37. package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts +3 -1
  38. package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts.map +1 -1
  39. package/dist/v2/blocks/request-block/components/RequestTable.vue.js +1 -1
  40. package/dist/v2/blocks/request-block/components/RequestTable.vue.js.map +1 -1
  41. package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js +13 -2
  42. package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js.map +1 -1
  43. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts +3 -1
  44. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts.map +1 -1
  45. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.js.map +1 -1
  46. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js +6 -2
  47. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js.map +1 -1
  48. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.d.ts.map +1 -1
  49. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.js +10 -3
  50. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.js.map +1 -1
  51. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.d.ts.map +1 -1
  52. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js +10 -1
  53. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js.map +1 -1
  54. package/dist/v2/blocks/request-block/helpers/get-form-body-rows.d.ts +3 -2
  55. package/dist/v2/blocks/request-block/helpers/get-form-body-rows.d.ts.map +1 -1
  56. package/dist/v2/blocks/request-block/helpers/get-form-body-rows.js +14 -11
  57. package/dist/v2/blocks/request-block/helpers/get-form-body-rows.js.map +1 -1
  58. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBarHistory.vue.d.ts.map +1 -1
  59. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBarHistory.vue.js +1 -1
  60. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBarHistory.vue.js.map +1 -1
  61. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBarHistory.vue.script.js +3 -3
  62. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBarHistory.vue.script.js.map +1 -1
  63. package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.script.js.map +1 -1
  64. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.d.ts.map +1 -1
  65. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.js.map +1 -1
  66. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js +55 -16
  67. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js.map +1 -1
  68. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.d.ts +3 -3
  69. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.d.ts.map +1 -1
  70. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.js.map +1 -1
  71. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.script.js +20 -7
  72. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.script.js.map +1 -1
  73. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.d.ts.map +1 -1
  74. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.js.map +1 -1
  75. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js +32 -27
  76. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js.map +1 -1
  77. package/dist/v2/blocks/scalar-auth-selector-block/helpers/openid-discovery-to-flows.d.ts.map +1 -1
  78. package/dist/v2/blocks/scalar-auth-selector-block/helpers/openid-discovery-to-flows.js +2 -1
  79. package/dist/v2/blocks/scalar-auth-selector-block/helpers/openid-discovery-to-flows.js.map +1 -1
  80. package/dist/v2/components/code-input/CodeInput.vue.d.ts.map +1 -1
  81. package/dist/v2/components/code-input/CodeInput.vue.js +1 -1
  82. package/dist/v2/components/code-input/CodeInput.vue.js.map +1 -1
  83. package/dist/v2/components/code-input/CodeInput.vue.script.js.map +1 -1
  84. package/dist/v2/components/code-input/PillTooltipHost.vue.d.ts.map +1 -1
  85. package/dist/v2/components/code-input/PillTooltipHost.vue.js.map +1 -1
  86. package/dist/v2/components/code-input/PillTooltipHost.vue.script.js +4 -1
  87. package/dist/v2/components/code-input/PillTooltipHost.vue.script.js.map +1 -1
  88. package/dist/v2/components/code-input/code-variable-widget.js +1 -1
  89. package/dist/v2/components/code-input/code-variable-widget.js.map +1 -1
  90. package/dist/v2/components/data-table/DataTableInput.vue.d.ts +3 -1
  91. package/dist/v2/components/data-table/DataTableInput.vue.d.ts.map +1 -1
  92. package/dist/v2/components/data-table/DataTableInput.vue.js +1 -1
  93. package/dist/v2/components/data-table/DataTableInput.vue.js.map +1 -1
  94. package/dist/v2/components/data-table/DataTableInput.vue.script.js +46 -15
  95. package/dist/v2/components/data-table/DataTableInput.vue.script.js.map +1 -1
  96. package/dist/v2/components/server/ServerDropdown.vue.d.ts.map +1 -1
  97. package/dist/v2/components/server/ServerDropdown.vue.js.map +1 -1
  98. package/dist/v2/components/server/ServerDropdown.vue.script.js +7 -9
  99. package/dist/v2/components/server/ServerDropdown.vue.script.js.map +1 -1
  100. package/dist/v2/constants.js +1 -1
  101. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.d.ts.map +1 -1
  102. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.js.map +1 -1
  103. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.script.js +27 -31
  104. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.script.js.map +1 -1
  105. package/dist/v2/features/localization/index.d.ts.map +1 -1
  106. package/dist/v2/features/localization/index.js +2 -0
  107. package/dist/v2/features/localization/index.js.map +1 -1
  108. package/dist/v2/features/localization/locales/ar.d.ts +4 -0
  109. package/dist/v2/features/localization/locales/ar.d.ts.map +1 -1
  110. package/dist/v2/features/localization/locales/ar.js +4 -0
  111. package/dist/v2/features/localization/locales/ar.js.map +1 -1
  112. package/dist/v2/features/localization/locales/de.d.ts +4 -0
  113. package/dist/v2/features/localization/locales/de.d.ts.map +1 -1
  114. package/dist/v2/features/localization/locales/de.js +4 -0
  115. package/dist/v2/features/localization/locales/de.js.map +1 -1
  116. package/dist/v2/features/localization/locales/es.d.ts +4 -0
  117. package/dist/v2/features/localization/locales/es.d.ts.map +1 -1
  118. package/dist/v2/features/localization/locales/es.js +4 -0
  119. package/dist/v2/features/localization/locales/es.js.map +1 -1
  120. package/dist/v2/features/localization/locales/fr.d.ts +4 -0
  121. package/dist/v2/features/localization/locales/fr.d.ts.map +1 -1
  122. package/dist/v2/features/localization/locales/fr.js +4 -0
  123. package/dist/v2/features/localization/locales/fr.js.map +1 -1
  124. package/dist/v2/features/localization/locales/pt.d.ts +4 -0
  125. package/dist/v2/features/localization/locales/pt.d.ts.map +1 -1
  126. package/dist/v2/features/localization/locales/pt.js +4 -0
  127. package/dist/v2/features/localization/locales/pt.js.map +1 -1
  128. package/dist/v2/features/localization/locales/ru.d.ts +4 -0
  129. package/dist/v2/features/localization/locales/ru.d.ts.map +1 -1
  130. package/dist/v2/features/localization/locales/ru.js +4 -0
  131. package/dist/v2/features/localization/locales/ru.js.map +1 -1
  132. package/dist/v2/features/localization/locales/zh-cn.d.ts +4 -0
  133. package/dist/v2/features/localization/locales/zh-cn.d.ts.map +1 -1
  134. package/dist/v2/features/localization/locales/zh-cn.js +4 -0
  135. package/dist/v2/features/localization/locales/zh-cn.js.map +1 -1
  136. package/dist/v2/features/localization/locales/zh-tw.d.ts +398 -0
  137. package/dist/v2/features/localization/locales/zh-tw.d.ts.map +1 -0
  138. package/dist/v2/features/localization/locales/zh-tw.js +360 -0
  139. package/dist/v2/features/localization/locales/zh-tw.js.map +1 -0
  140. package/dist/v2/features/localization/translations.d.ts +4 -0
  141. package/dist/v2/features/localization/translations.d.ts.map +1 -1
  142. package/dist/v2/features/localization/translations.js +4 -0
  143. package/dist/v2/features/localization/translations.js.map +1 -1
  144. package/dist/v2/features/modal/index.d.ts +1 -1
  145. package/dist/v2/features/modal/index.d.ts.map +1 -1
  146. package/dist/v2/helpers/handle-hotkeys.d.ts.map +1 -1
  147. package/dist/v2/helpers/handle-hotkeys.js +4 -1
  148. package/dist/v2/helpers/handle-hotkeys.js.map +1 -1
  149. package/dist/vue-styles.css +39 -40
  150. package/package.json +13 -13
@@ -1,32 +1,60 @@
1
1
  import { useLocalization } from "../../../features/localization/index.js";
2
- import { createElementBlock, createElementVNode, defineComponent, normalizeClass, openBlock, toDisplayString, unref, withModifiers } from "vue";
2
+ import { createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, openBlock, toDisplayString, unref, withModifiers } from "vue";
3
3
  //#region src/v2/blocks/request-block/components/RequestBodyViewToggle.vue?vue&type=script&setup=true&lang.ts
4
4
  var _hoisted_1 = { class: "text-c-3 text-xxs -my-1 mr-2 flex justify-center gap-0.5 rounded p-0.5" };
5
- var _hoisted_2 = ["disabled", "title"];
5
+ var _hoisted_2 = [
6
+ "aria-pressed",
7
+ "disabled",
8
+ "title"
9
+ ];
10
+ var _hoisted_3 = ["aria-pressed"];
11
+ var _hoisted_4 = ["aria-pressed"];
6
12
  var RequestBodyViewToggle_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
7
13
  __name: "RequestBodyViewToggle",
8
14
  props: {
9
15
  modelValue: {},
16
+ showForm: {
17
+ type: Boolean,
18
+ default: true
19
+ },
20
+ showSchema: {
21
+ type: Boolean,
22
+ default: false
23
+ },
24
+ rawLabel: {},
10
25
  disabled: { type: Boolean }
11
26
  },
12
27
  emits: ["update:modelValue"],
13
28
  setup(__props) {
14
29
  const { translate } = useLocalization();
15
30
  return (_ctx, _cache) => {
16
- return openBlock(), createElementBlock("div", _hoisted_1, [createElementVNode("button", {
17
- class: normalizeClass(["rounded px-1", __props.disabled ? "cursor-not-allowed opacity-50" : {
18
- "bg-b-3 text-c-1 cursor-default": __props.modelValue === "form",
19
- "hover:bg-b-3": __props.modelValue !== "form"
20
- }]),
21
- disabled: __props.disabled,
22
- title: __props.disabled ? unref(translate)("apiClient.requestBodyViewToggle.fixBody") : void 0,
23
- type: "button",
24
- onClick: _cache[0] || (_cache[0] = withModifiers(($event) => _ctx.$emit("update:modelValue", "form"), ["stop"]))
25
- }, toDisplayString(unref(translate)("apiClient.requestBodyViewToggle.form")), 11, _hoisted_2), createElementVNode("button", {
26
- class: normalizeClass(["hover:bg-b-3 rounded px-1", { "bg-b-3 text-c-1 cursor-default": __props.modelValue === "raw" }]),
27
- type: "button",
28
- onClick: _cache[1] || (_cache[1] = withModifiers(($event) => _ctx.$emit("update:modelValue", "raw"), ["stop"]))
29
- }, toDisplayString(unref(translate)("apiClient.requestBodyViewToggle.raw")), 3)]);
31
+ return openBlock(), createElementBlock("div", _hoisted_1, [
32
+ __props.showForm ? (openBlock(), createElementBlock("button", {
33
+ key: 0,
34
+ "aria-pressed": __props.modelValue === "form",
35
+ class: normalizeClass(["rounded px-1", __props.disabled ? "cursor-not-allowed opacity-50" : {
36
+ "bg-b-3 text-c-1 cursor-default": __props.modelValue === "form",
37
+ "hover:bg-b-3": __props.modelValue !== "form"
38
+ }]),
39
+ disabled: __props.disabled,
40
+ title: __props.disabled ? unref(translate)("apiClient.requestBodyViewToggle.fixBody") : void 0,
41
+ type: "button",
42
+ onClick: _cache[0] || (_cache[0] = withModifiers(($event) => _ctx.$emit("update:modelValue", "form"), ["stop"]))
43
+ }, toDisplayString(unref(translate)("apiClient.requestBodyViewToggle.form")), 11, _hoisted_2)) : createCommentVNode("", true),
44
+ createElementVNode("button", {
45
+ "aria-pressed": __props.modelValue === "raw",
46
+ class: normalizeClass(["hover:bg-b-3 rounded px-1", { "bg-b-3 text-c-1 cursor-default": __props.modelValue === "raw" }]),
47
+ type: "button",
48
+ onClick: _cache[1] || (_cache[1] = withModifiers(($event) => _ctx.$emit("update:modelValue", "raw"), ["stop"]))
49
+ }, toDisplayString(__props.rawLabel ?? unref(translate)("apiClient.requestBodyViewToggle.raw")), 11, _hoisted_3),
50
+ __props.showSchema ? (openBlock(), createElementBlock("button", {
51
+ key: 1,
52
+ "aria-pressed": __props.modelValue === "schema",
53
+ class: normalizeClass(["hover:bg-b-3 rounded px-1", { "bg-b-3 text-c-1 cursor-default": __props.modelValue === "schema" }]),
54
+ type: "button",
55
+ onClick: _cache[2] || (_cache[2] = withModifiers(($event) => _ctx.$emit("update:modelValue", "schema"), ["stop"]))
56
+ }, toDisplayString(unref(translate)("apiClient.requestBodyViewToggle.schema")), 11, _hoisted_4)) : createCommentVNode("", true)
57
+ ]);
30
58
  };
31
59
  }
32
60
  });
@@ -1 +1 @@
1
- {"version":3,"file":"RequestBodyViewToggle.vue.script.js","names":["$emit"],"sources":["../../../../../src/v2/blocks/request-block/components/RequestBodyViewToggle.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { useLocalization } from '@/v2/features/localization'\n\ndefineProps<{\n modelValue: 'form' | 'raw'\n /** Disable switching to the form view (e.g. while the raw body is not parseable) */\n disabled?: boolean\n}>()\n\ndefineEmits<{\n (e: 'update:modelValue', v: 'form' | 'raw'): void\n}>()\n\nconst { translate } = useLocalization()\n</script>\n<template>\n <div\n class=\"text-c-3 text-xxs -my-1 mr-2 flex justify-center gap-0.5 rounded p-0.5\">\n <button\n class=\"rounded px-1\"\n :class=\"\n disabled\n ? 'cursor-not-allowed opacity-50'\n : {\n 'bg-b-3 text-c-1 cursor-default': modelValue === 'form',\n 'hover:bg-b-3': modelValue !== 'form',\n }\n \"\n :disabled=\"disabled\"\n :title=\"\n disabled\n ? translate('apiClient.requestBodyViewToggle.fixBody')\n : undefined\n \"\n type=\"button\"\n @click.stop=\"$emit('update:modelValue', 'form')\">\n {{ translate('apiClient.requestBodyViewToggle.form') }}\n </button>\n <button\n class=\"hover:bg-b-3 rounded px-1\"\n :class=\"{ 'bg-b-3 text-c-1 cursor-default': modelValue === 'raw' }\"\n type=\"button\"\n @click.stop=\"$emit('update:modelValue', 'raw')\">\n {{ translate('apiClient.requestBodyViewToggle.raw') }}\n </button>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;EAaA,MAAM,EAAE,cAAc,gBAAgB;;uBAGpC,mBA6BM,OA7BN,YA6BM,CA3BJ,mBAmBS,UAAA;IAlBP,OAAK,eAAA,CAAC,gBACW,QAAA,WAAA,kCAAA;uCAAmH,QAAA,eAAU;qBAA2C,QAAA,eAAU;;IAQlM,UAAU,QAAA;IACV,OAAgB,QAAA,WAAqB,MAAA,SAAA,CAAS,CAAA,yCAAA,IAAwD,KAAA;IAKvG,MAAK;IACJ,SAAK,OAAA,OAAA,OAAA,KAAA,eAAA,WAAOA,KAAAA,MAAK,qBAAA,MAAA,GAAA,CAAA,MAAA,CAAA;sBACf,MAAA,SAAA,CAAS,CAAA,sCAAA,CAAA,GAAA,IAAA,UAAA,GAEd,mBAMS,UAAA;IALP,OAAK,eAAA,CAAC,6BAA2B,EAAA,kCACW,QAAA,eAAU,MAAA,CAAA,CAAA;IACtD,MAAK;IACJ,SAAK,OAAA,OAAA,OAAA,KAAA,eAAA,WAAOA,KAAAA,MAAK,qBAAA,KAAA,GAAA,CAAA,MAAA,CAAA;sBACf,MAAA,SAAA,CAAS,CAAA,qCAAA,CAAA,GAAA,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"RequestBodyViewToggle.vue.script.js","names":["$emit"],"sources":["../../../../../src/v2/blocks/request-block/components/RequestBodyViewToggle.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { useLocalization } from '@/v2/features/localization'\n\nconst { showForm = true, showSchema = false } = defineProps<{\n modelValue: 'form' | 'raw' | 'schema'\n /** Offer the structured form editor when the body supports it. */\n showForm?: boolean\n /** Offer read-only schema inspection when a schema exists. */\n showSchema?: boolean\n /** Non-text editors use Body instead of Raw. */\n rawLabel?: string\n /** Disable switching to the form view (e.g. while the raw body is not parseable) */\n disabled?: boolean\n}>()\n\ndefineEmits<{\n (e: 'update:modelValue', v: 'form' | 'raw' | 'schema'): void\n}>()\n\nconst { translate } = useLocalization()\n</script>\n<template>\n <div\n class=\"text-c-3 text-xxs -my-1 mr-2 flex justify-center gap-0.5 rounded p-0.5\">\n <button\n v-if=\"showForm\"\n :aria-pressed=\"modelValue === 'form'\"\n class=\"rounded px-1\"\n :class=\"\n disabled\n ? 'cursor-not-allowed opacity-50'\n : {\n 'bg-b-3 text-c-1 cursor-default': modelValue === 'form',\n 'hover:bg-b-3': modelValue !== 'form',\n }\n \"\n :disabled=\"disabled\"\n :title=\"\n disabled\n ? translate('apiClient.requestBodyViewToggle.fixBody')\n : undefined\n \"\n type=\"button\"\n @click.stop=\"$emit('update:modelValue', 'form')\">\n {{ translate('apiClient.requestBodyViewToggle.form') }}\n </button>\n <button\n :aria-pressed=\"modelValue === 'raw'\"\n class=\"hover:bg-b-3 rounded px-1\"\n :class=\"{ 'bg-b-3 text-c-1 cursor-default': modelValue === 'raw' }\"\n type=\"button\"\n @click.stop=\"$emit('update:modelValue', 'raw')\">\n {{ rawLabel ?? translate('apiClient.requestBodyViewToggle.raw') }}\n </button>\n <button\n v-if=\"showSchema\"\n :aria-pressed=\"modelValue === 'schema'\"\n class=\"hover:bg-b-3 rounded px-1\"\n :class=\"{ 'bg-b-3 text-c-1 cursor-default': modelValue === 'schema' }\"\n type=\"button\"\n @click.stop=\"$emit('update:modelValue', 'schema')\">\n {{ translate('apiClient.requestBodyViewToggle.schema') }}\n </button>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBA,MAAM,EAAE,cAAc,gBAAgB;;uBAGpC,mBAyCM,OAzCN,YAyCM;IAtCI,QAAA,YAAA,UAAA,GADR,mBAqBS,UAAA;;KAnBN,gBAAc,QAAA,eAAU;KACzB,OAAK,eAAA,CAAC,gBACW,QAAA,WAAA,kCAAA;wCAAmH,QAAA,eAAU;sBAA2C,QAAA,eAAU;;KAQlM,UAAU,QAAA;KACV,OAAgB,QAAA,WAAqB,MAAA,SAAA,CAAS,CAAA,yCAAA,IAAwD,KAAA;KAKvG,MAAK;KACJ,SAAK,OAAA,OAAA,OAAA,KAAA,eAAA,WAAOA,KAAAA,MAAK,qBAAA,MAAA,GAAA,CAAA,MAAA,CAAA;uBACf,MAAA,SAAA,CAAS,CAAA,sCAAA,CAAA,GAAA,IAAA,UAAA,KAAA,mBAAA,IAAA,IAAA;IAEd,mBAOS,UAAA;KANN,gBAAc,QAAA,eAAU;KACzB,OAAK,eAAA,CAAC,6BAA2B,EAAA,kCACW,QAAA,eAAU,MAAA,CAAA,CAAA;KACtD,MAAK;KACJ,SAAK,OAAA,OAAA,OAAA,KAAA,eAAA,WAAOA,KAAAA,MAAK,qBAAA,KAAA,GAAA,CAAA,MAAA,CAAA;uBACf,QAAA,YAAY,MAAA,SAAA,CAAS,CAAA,qCAAA,CAAA,GAAA,IAAA,UAAA;IAGlB,QAAA,cAAA,UAAA,GADR,mBAQS,UAAA;;KANN,gBAAc,QAAA,eAAU;KACzB,OAAK,eAAA,CAAC,6BAA2B,EAAA,kCACW,QAAA,eAAU,SAAA,CAAA,CAAA;KACtD,MAAK;KACJ,SAAK,OAAA,OAAA,OAAA,KAAA,eAAA,WAAOA,KAAAA,MAAK,qBAAA,QAAA,GAAA,CAAA,MAAA,CAAA;uBACf,MAAA,SAAA,CAAS,CAAA,wCAAA,CAAA,GAAA,IAAA,UAAA,KAAA,mBAAA,IAAA,IAAA"}
@@ -13,6 +13,8 @@ type __VLS_Props = {
13
13
  showAddRowPlaceholder?: boolean;
14
14
  environment: XScalarEnvironment;
15
15
  eventBus: WorkspaceEventBus;
16
+ /** Offer empty object query fields on demand without changing the complete editing context. */
17
+ selectExpandedParameters?: boolean;
16
18
  };
17
19
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
18
20
  delete: (payload: {
@@ -22,6 +24,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
22
24
  name: string;
23
25
  value: string | Record<string, unknown>;
24
26
  isDisabled: boolean;
27
+ propertyState?: {
28
+ path: string[];
29
+ isDisabled?: boolean;
30
+ previousPath?: string[];
31
+ };
25
32
  } & {
26
33
  shouldRenameExpandedRow?: boolean;
27
34
  }) => any;
@@ -35,6 +42,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
35
42
  name: string;
36
43
  value: string | Record<string, unknown>;
37
44
  isDisabled: boolean;
45
+ propertyState?: {
46
+ path: string[];
47
+ isDisabled?: boolean;
48
+ previousPath?: string[];
49
+ };
38
50
  } & {
39
51
  shouldRenameExpandedRow?: boolean;
40
52
  }) => any) | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"RequestParams.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/request-block/components/RequestParams.vue"],"names":[],"mappings":"AAyHA,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAOnH,OAAO,KAAK,EAAE,QAAQ,EAAyB,MAAM,uBAAuB,CAAA;AAE5E,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,QAAQ,EAAE,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,WAAW,EAAE,kBAAkB,CAAA;IAC/B,QAAQ,EAAE,iBAAiB,CAAA;CAC5B,CAAC;AA0OF,QAAA,MAAM,YAAY;;eAtNgB,MAAM;;;;;;;kCAHR,OAAO;;;;;;eAGL,MAAM;;;;;;;kCAHR,OAAO;;;;kFA4NrC,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"RequestParams.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/request-block/components/RequestParams.vue"],"names":[],"mappings":"AAiRA,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAOnH,OAAO,KAAK,EAAE,QAAQ,EAAyB,MAAM,uBAAuB,CAAA;AAE5E,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,QAAQ,EAAE,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,WAAW,EAAE,kBAAkB,CAAA;IAC/B,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,+FAA+F;IAC/F,wBAAwB,CAAC,EAAE,OAAO,CAAA;CACnC,CAAC;AA0cF,QAAA,MAAM,YAAY;;eArbgB,MAAM;;;;;;;;sBApDxC,CAlCG;wBAkCH,CAjCmB;;;kCAkFa,OAAO;;;;;;eAGL,MAAM;;;;;;;;sBApDxC,CAlCG;wBAkCH,CAjCmB;;;kCAkFa,OAAO;;;;kFA2brC,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1 +1 @@
1
- {"version":3,"file":"RequestParams.vue.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestParams.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarTooltip } from '@scalar/components/tooltip'\nimport type {\n ApiReferenceEvents,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed } from 'vue'\n\nimport { CollapsibleSection } from '@/v2/components/layout'\nimport { useLocalization } from '@/v2/features/localization'\n\nimport RequestTable from './RequestTable.vue'\nimport type { TableRow, TableRowUpsertPayload } from './RequestTableRow.vue'\n\nconst {\n rows,\n exampleKey,\n environment,\n title,\n globalRoute,\n showAddRowPlaceholder = true,\n eventBus,\n} = defineProps<{\n rows: TableRow[]\n exampleKey: string\n title: string\n label?: string\n /** Explain restrictions on parameter editing when needed. */\n description?: string\n invalidParams?: Set<string>\n globalRoute?: string\n showAddRowPlaceholder?: boolean\n environment: XScalarEnvironment\n eventBus: WorkspaceEventBus\n}>()\n\nconst emit = defineEmits<{\n (\n e: 'upsert',\n index: number,\n payload: ApiReferenceEvents['operation:upsert:parameter']['payload'] & {\n shouldRenameExpandedRow?: boolean\n },\n ): void\n (e: 'delete', payload: { index: number }): void\n (e: 'deleteAll'): void\n /** Select a value for a grouped global cookie preset at the given row index. */\n (e: 'selectPreset', index: number, value: string): void\n}>()\n\nconst { translate } = useLocalization()\n\nconst showTooltip = computed(() => rows.length > 1)\n\n/** Needed for type guard */\nconst handleUpserRow = (index: number, payload: TableRowUpsertPayload) => {\n const { value, ...rest } = payload\n\n // Type guard here as we cannot add files to params\n if (value instanceof File) {\n return\n }\n\n emit('upsert', index, { ...rest, value: value ?? '' })\n}\n</script>\n<template>\n <CollapsibleSection\n class=\"group/params\"\n :itemCount=\"rows.length\">\n <template #title>{{ title }}</template>\n <template #actions>\n <div\n class=\"text-c-2 request-meta-buttons flex whitespace-nowrap opacity-0 group-hover/params:opacity-100 has-[:focus-visible]:opacity-100\">\n <ScalarTooltip\n v-if=\"showTooltip\"\n :content=\"\n translate('apiClient.requestParams.clearOptionalParameters')\n \"\n placement=\"left\">\n <ScalarButton\n :aria-label=\"\n translate('apiClient.requestParams.clearAll', { title })\n \"\n class=\"pr-0.75 pl-1 transition-none\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop=\"emit('deleteAll')\">\n {{ translate('apiClient.requestParams.clear') }}\n </ScalarButton>\n </ScalarTooltip>\n </div>\n </template>\n <p\n v-if=\"description\"\n class=\"text-c-2 px-3 py-2 text-sm\">\n {{ description }}\n </p>\n <RequestTable\n class=\"flex-1\"\n :columns=\"['32px', '', '']\"\n :data=\"rows\"\n :environment=\"environment\"\n :exampleKey=\"exampleKey\"\n :globalRoute=\"globalRoute\"\n :invalidParams=\"invalidParams\"\n :label=\"label\"\n :showAddRowPlaceholder=\"showAddRowPlaceholder\"\n @deleteRow=\"(index) => emit('delete', { index })\"\n @navigate=\"(route) => eventBus.emit('ui:navigate', route)\"\n @selectPreset=\"(index, value) => emit('selectPreset', index, value)\"\n @upsertRow=\"handleUpserRow\" />\n </CollapsibleSection>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RequestParams.vue.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestParams.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarCombobox } from '@scalar/components/combobox'\nimport { ScalarTooltip } from '@scalar/components/tooltip'\nimport { ScalarIconPlus } from '@scalar/icons'\nimport type {\n ApiReferenceEvents,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed, nextTick, ref, useTemplateRef } from 'vue'\n\nimport { CollapsibleSection } from '@/v2/components/layout'\nimport { useLocalization } from '@/v2/features/localization'\n\nimport RequestTable from './RequestTable.vue'\nimport type { TableRow, TableRowUpsertPayload } from './RequestTableRow.vue'\n\nconst {\n rows,\n exampleKey,\n environment,\n title,\n globalRoute,\n showAddRowPlaceholder = true,\n eventBus,\n selectExpandedParameters = false,\n} = defineProps<{\n rows: TableRow[]\n exampleKey: string\n title: string\n label?: string\n /** Explain restrictions on parameter editing when needed. */\n description?: string\n invalidParams?: Set<string>\n globalRoute?: string\n showAddRowPlaceholder?: boolean\n environment: XScalarEnvironment\n eventBus: WorkspaceEventBus\n /** Offer empty object query fields on demand without changing the complete editing context. */\n selectExpandedParameters?: boolean\n}>()\n\nconst emit = defineEmits<{\n (\n e: 'upsert',\n index: number,\n payload: ApiReferenceEvents['operation:upsert:parameter']['payload'] & {\n shouldRenameExpandedRow?: boolean\n },\n ): void\n (e: 'delete', payload: { index: number }): void\n (e: 'deleteAll'): void\n /** Select a value for a grouped global cookie preset at the given row index. */\n (e: 'selectPreset', index: number, value: string): void\n}>()\n\nconst { translate } = useLocalization()\n\nconst showTooltip = computed(() => rows.length > 1)\nconst table = useTemplateRef('table')\nconst pickerContainer = useTemplateRef('pickerContainer')\nconst selectedFields = ref<Set<string>>(new Set())\n\ntype IndexedRow = { row: TableRow; index: number }\ntype AvailableField = {\n id: string\n label: string\n description: TableRow['description']\n index: number\n}\n\nconst getFieldKey = (row: TableRow, name = row.name): string =>\n JSON.stringify([row.originalParameter?.in, row.originalParameter?.name, name])\n\n/** Single-field objects and ordinary parameters keep their existing presentation. */\nconst expandedParameters = computed<Set<TableRow['originalParameter']>>(() => {\n const counts = new Map<TableRow['originalParameter'], number>()\n for (const row of rows) {\n if (row.originalParameter?.in === 'query' && row.sourceParameterValuePath) {\n counts.set(\n row.originalParameter,\n (counts.get(row.originalParameter) ?? 0) + 1,\n )\n }\n }\n return new Set(\n [...counts]\n .filter(([, count]) => count > 1)\n .map(([parameter]) => parameter),\n )\n})\n\nconst isSelectable = (row: TableRow): boolean =>\n selectExpandedParameters &&\n Boolean(row.sourceParameterValuePath) &&\n expandedParameters.value.has(row.originalParameter)\n\n/** Keep original indexes: handlers rebuild object values from all rows, including hidden fields. */\nconst indexedRows = computed<IndexedRow[]>(() =>\n rows.map((row, index) => ({ row, index })),\n)\nconst visibleRows = computed<IndexedRow[]>(() =>\n indexedRows.value.filter(\n ({ row }) =>\n !isSelectable(row) ||\n row.isRequired ||\n (row.value !== '' && row.value !== null) ||\n selectedFields.value.has(getFieldKey(row)),\n ),\n)\nconst tableRows = computed<TableRow[]>(() =>\n visibleRows.value.map(({ row }) => row),\n)\nconst availableFields = computed<AvailableField[]>(() =>\n indexedRows.value\n .filter(\n (entry) => !visibleRows.value.some(({ index }) => index === entry.index),\n )\n .map(({ row, index }) => ({\n id: getFieldKey(row),\n label: row.name,\n description: row.description,\n index,\n })),\n)\n\nconst selectField = async (\n option: { id: string; index: number } | undefined,\n): Promise<void> => {\n if (!option) return\n selectedFields.value.add(option.id)\n await nextTick()\n table.value?.focusValue(\n visibleRows.value.findIndex(({ index }) => index === option.index),\n )\n}\n\n/** The appended placeholder belongs after all stored rows, including hidden fields. */\nconst getOriginalIndex = (index: number): number =>\n visibleRows.value[index]?.index ??\n rows.length + index - visibleRows.value.length\n\nconst deleteRow = (index: number): void => {\n const originalIndex = getOriginalIndex(index)\n const entry = visibleRows.value[index]\n if (entry) selectedFields.value.delete(getFieldKey(entry.row))\n emit('delete', {\n index: originalIndex,\n })\n}\n\nconst deleteAll = (): void => {\n selectedFields.value.clear()\n emit('deleteAll')\n}\n\n/** Needed for type guard */\nconst handleUpserRow = (\n index: number,\n payload: TableRowUpsertPayload,\n): void => {\n const { value, ...rest } = payload\n\n // Type guard here as we cannot add files to params\n if (value instanceof File) {\n return\n }\n\n const entry = visibleRows.value[index]\n if (entry && isSelectable(entry.row)) {\n // Editing a populated field keeps it visible even after its value is cleared.\n selectedFields.value.add(\n getFieldKey(\n entry.row,\n payload.shouldRenameExpandedRow ? payload.name : entry.row.name,\n ),\n )\n }\n emit('upsert', getOriginalIndex(index), { ...rest, value: value ?? '' })\n}\n</script>\n<template>\n <CollapsibleSection\n class=\"group/params\"\n :itemCount=\"tableRows.length\">\n <template #title>{{ title }}</template>\n <template #actions>\n <div\n class=\"text-c-2 request-meta-buttons flex whitespace-nowrap opacity-0 group-hover/params:opacity-100 has-[:focus-visible]:opacity-100\">\n <ScalarTooltip\n v-if=\"showTooltip\"\n :content=\"\n translate('apiClient.requestParams.clearOptionalParameters')\n \"\n placement=\"left\">\n <ScalarButton\n :aria-label=\"\n translate('apiClient.requestParams.clearAll', { title })\n \"\n class=\"pr-0.75 pl-1 transition-none\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop=\"deleteAll\">\n {{ translate('apiClient.requestParams.clear') }}\n </ScalarButton>\n </ScalarTooltip>\n </div>\n </template>\n <p\n v-if=\"description\"\n class=\"text-c-2 px-3 py-2 text-sm\">\n {{ description }}\n </p>\n <RequestTable\n ref=\"table\"\n class=\"flex-1\"\n :columns=\"['32px', '', '']\"\n :data=\"tableRows\"\n :environment=\"environment\"\n :exampleKey=\"exampleKey\"\n :globalRoute=\"globalRoute\"\n :invalidParams=\"invalidParams\"\n :label=\"label\"\n :showAddRowPlaceholder=\"showAddRowPlaceholder\"\n @deleteRow=\"deleteRow\"\n @navigate=\"(route) => eventBus.emit('ui:navigate', route)\"\n @selectPreset=\"(index, value) => emit('selectPreset', index, value)\"\n @upsertRow=\"handleUpserRow\" />\n <div\n v-if=\"availableFields.length\"\n class=\"border-t py-1\">\n <div\n ref=\"pickerContainer\"\n class=\"mx-2\">\n <ScalarCombobox\n :inputLabel=\"translate('apiClient.requestParams.searchParameters')\"\n :noResults=\"translate('apiClient.requestParams.noParametersFound')\"\n :options=\"availableFields\"\n :placeholder=\"translate('apiClient.requestParams.searchParameters')\"\n placement=\"bottom-start\"\n resize\n :target=\"pickerContainer ?? undefined\"\n @update:modelValue=\"selectField\">\n <ScalarButton\n class=\"gap-1.5\"\n size=\"sm\"\n variant=\"ghost\">\n <ScalarIconPlus class=\"size-3.5\" />\n {{ translate('apiClient.requestParams.addParameter') }}\n </ScalarButton>\n <template #option=\"{ option }\">\n <span class=\"min-w-0\">\n <span class=\"block break-all\">{{ option.label }}</span>\n <span\n v-if=\"option.description\"\n class=\"text-c-2 block text-xs\"\n >{{ option.description }}</span\n >\n </span>\n </template>\n </ScalarCombobox>\n </div>\n </div>\n </CollapsibleSection>\n</template>\n"],"mappings":""}
@@ -1,8 +1,10 @@
1
1
  import { useLocalization } from "../../../features/localization/index.js";
2
2
  import RequestTable_default from "./RequestTable.vue.js";
3
3
  import CollapsibleSection_default from "../../../components/layout/CollapsibleSection.vue.js";
4
- import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, openBlock, toDisplayString, unref, withCtx, withModifiers } from "vue";
4
+ import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, openBlock, ref, toDisplayString, unref, useTemplateRef, withCtx, withModifiers } from "vue";
5
5
  import { ScalarButton } from "@scalar/components/button";
6
+ import { ScalarIconPlus } from "@scalar/icons";
7
+ import { ScalarCombobox } from "@scalar/components/combobox";
6
8
  import { ScalarTooltip } from "@scalar/components/tooltip";
7
9
  //#region src/v2/blocks/request-block/components/RequestParams.vue?vue&type=script&setup=true&lang.ts
8
10
  var _hoisted_1 = { class: "text-c-2 request-meta-buttons flex whitespace-nowrap opacity-0 group-hover/params:opacity-100 has-[:focus-visible]:opacity-100" };
@@ -10,6 +12,16 @@ var _hoisted_2 = {
10
12
  key: 0,
11
13
  class: "text-c-2 px-3 py-2 text-sm"
12
14
  };
15
+ var _hoisted_3 = {
16
+ key: 1,
17
+ class: "border-t py-1"
18
+ };
19
+ var _hoisted_4 = { class: "min-w-0" };
20
+ var _hoisted_5 = { class: "block break-all" };
21
+ var _hoisted_6 = {
22
+ key: 0,
23
+ class: "text-c-2 block text-xs"
24
+ };
13
25
  var RequestParams_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
14
26
  __name: "RequestParams",
15
27
  props: {
@@ -25,7 +37,11 @@ var RequestParams_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
25
37
  default: true
26
38
  },
27
39
  environment: {},
28
- eventBus: {}
40
+ eventBus: {},
41
+ selectExpandedParameters: {
42
+ type: Boolean,
43
+ default: false
44
+ }
29
45
  },
30
46
  emits: [
31
47
  "upsert",
@@ -37,11 +53,59 @@ var RequestParams_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
37
53
  const emit = __emit;
38
54
  const { translate } = useLocalization();
39
55
  const showTooltip = computed(() => __props.rows.length > 1);
56
+ const table = useTemplateRef("table");
57
+ const pickerContainer = useTemplateRef("pickerContainer");
58
+ const selectedFields = ref(/* @__PURE__ */ new Set());
59
+ const getFieldKey = (row, name = row.name) => JSON.stringify([
60
+ row.originalParameter?.in,
61
+ row.originalParameter?.name,
62
+ name
63
+ ]);
64
+ /** Single-field objects and ordinary parameters keep their existing presentation. */
65
+ const expandedParameters = computed(() => {
66
+ const counts = /* @__PURE__ */ new Map();
67
+ for (const row of __props.rows) if (row.originalParameter?.in === "query" && row.sourceParameterValuePath) counts.set(row.originalParameter, (counts.get(row.originalParameter) ?? 0) + 1);
68
+ return new Set([...counts].filter(([, count]) => count > 1).map(([parameter]) => parameter));
69
+ });
70
+ const isSelectable = (row) => __props.selectExpandedParameters && Boolean(row.sourceParameterValuePath) && expandedParameters.value.has(row.originalParameter);
71
+ /** Keep original indexes: handlers rebuild object values from all rows, including hidden fields. */
72
+ const indexedRows = computed(() => __props.rows.map((row, index) => ({
73
+ row,
74
+ index
75
+ })));
76
+ const visibleRows = computed(() => indexedRows.value.filter(({ row }) => !isSelectable(row) || row.isRequired || row.value !== "" && row.value !== null || selectedFields.value.has(getFieldKey(row))));
77
+ const tableRows = computed(() => visibleRows.value.map(({ row }) => row));
78
+ const availableFields = computed(() => indexedRows.value.filter((entry) => !visibleRows.value.some(({ index }) => index === entry.index)).map(({ row, index }) => ({
79
+ id: getFieldKey(row),
80
+ label: row.name,
81
+ description: row.description,
82
+ index
83
+ })));
84
+ const selectField = async (option) => {
85
+ if (!option) return;
86
+ selectedFields.value.add(option.id);
87
+ await nextTick();
88
+ table.value?.focusValue(visibleRows.value.findIndex(({ index }) => index === option.index));
89
+ };
90
+ /** The appended placeholder belongs after all stored rows, including hidden fields. */
91
+ const getOriginalIndex = (index) => visibleRows.value[index]?.index ?? __props.rows.length + index - visibleRows.value.length;
92
+ const deleteRow = (index) => {
93
+ const originalIndex = getOriginalIndex(index);
94
+ const entry = visibleRows.value[index];
95
+ if (entry) selectedFields.value.delete(getFieldKey(entry.row));
96
+ emit("delete", { index: originalIndex });
97
+ };
98
+ const deleteAll = () => {
99
+ selectedFields.value.clear();
100
+ emit("deleteAll");
101
+ };
40
102
  /** Needed for type guard */
41
103
  const handleUpserRow = (index, payload) => {
42
104
  const { value, ...rest } = payload;
43
105
  if (value instanceof File) return;
44
- emit("upsert", index, {
106
+ const entry = visibleRows.value[index];
107
+ if (entry && isSelectable(entry.row)) selectedFields.value.add(getFieldKey(entry.row, payload.shouldRenameExpandedRow ? payload.name : entry.row.name));
108
+ emit("upsert", getOriginalIndex(index), {
45
109
  ...rest,
46
110
  value: value ?? ""
47
111
  });
@@ -49,7 +113,7 @@ var RequestParams_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
49
113
  return (_ctx, _cache) => {
50
114
  return openBlock(), createBlock(unref(CollapsibleSection_default), {
51
115
  class: "group/params",
52
- itemCount: __props.rows.length
116
+ itemCount: tableRows.value.length
53
117
  }, {
54
118
  title: withCtx(() => [createTextVNode(toDisplayString(__props.title), 1)]),
55
119
  actions: withCtx(() => [createElementVNode("div", _hoisted_1, [showTooltip.value ? (openBlock(), createBlock(unref(ScalarTooltip), {
@@ -62,40 +126,76 @@ var RequestParams_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
62
126
  class: "pr-0.75 pl-1 transition-none",
63
127
  size: "sm",
64
128
  variant: "ghost",
65
- onClick: _cache[0] || (_cache[0] = withModifiers(($event) => emit("deleteAll"), ["stop"]))
129
+ onClick: withModifiers(deleteAll, ["stop"])
66
130
  }, {
67
131
  default: withCtx(() => [createTextVNode(toDisplayString(unref(translate)("apiClient.requestParams.clear")), 1)]),
68
132
  _: 1
69
133
  }, 8, ["aria-label"])]),
70
134
  _: 1
71
135
  }, 8, ["content"])) : createCommentVNode("", true)])]),
72
- default: withCtx(() => [__props.description ? (openBlock(), createElementBlock("p", _hoisted_2, toDisplayString(__props.description), 1)) : createCommentVNode("", true), createVNode(RequestTable_default, {
73
- class: "flex-1",
74
- columns: [
75
- "32px",
76
- "",
77
- ""
78
- ],
79
- data: __props.rows,
80
- environment: __props.environment,
81
- exampleKey: __props.exampleKey,
82
- globalRoute: __props.globalRoute,
83
- invalidParams: __props.invalidParams,
84
- label: __props.label,
85
- showAddRowPlaceholder: __props.showAddRowPlaceholder,
86
- onDeleteRow: _cache[1] || (_cache[1] = (index) => emit("delete", { index })),
87
- onNavigate: _cache[2] || (_cache[2] = (route) => __props.eventBus.emit("ui:navigate", route)),
88
- onSelectPreset: _cache[3] || (_cache[3] = (index, value) => emit("selectPreset", index, value)),
89
- onUpsertRow: handleUpserRow
90
- }, null, 8, [
91
- "data",
92
- "environment",
93
- "exampleKey",
94
- "globalRoute",
95
- "invalidParams",
96
- "label",
97
- "showAddRowPlaceholder"
98
- ])]),
136
+ default: withCtx(() => [
137
+ __props.description ? (openBlock(), createElementBlock("p", _hoisted_2, toDisplayString(__props.description), 1)) : createCommentVNode("", true),
138
+ createVNode(RequestTable_default, {
139
+ ref_key: "table",
140
+ ref: table,
141
+ class: "flex-1",
142
+ columns: [
143
+ "32px",
144
+ "",
145
+ ""
146
+ ],
147
+ data: tableRows.value,
148
+ environment: __props.environment,
149
+ exampleKey: __props.exampleKey,
150
+ globalRoute: __props.globalRoute,
151
+ invalidParams: __props.invalidParams,
152
+ label: __props.label,
153
+ showAddRowPlaceholder: __props.showAddRowPlaceholder,
154
+ onDeleteRow: deleteRow,
155
+ onNavigate: _cache[0] || (_cache[0] = (route) => __props.eventBus.emit("ui:navigate", route)),
156
+ onSelectPreset: _cache[1] || (_cache[1] = (index, value) => emit("selectPreset", index, value)),
157
+ onUpsertRow: handleUpserRow
158
+ }, null, 8, [
159
+ "data",
160
+ "environment",
161
+ "exampleKey",
162
+ "globalRoute",
163
+ "invalidParams",
164
+ "label",
165
+ "showAddRowPlaceholder"
166
+ ]),
167
+ availableFields.value.length ? (openBlock(), createElementBlock("div", _hoisted_3, [createElementVNode("div", {
168
+ ref_key: "pickerContainer",
169
+ ref: pickerContainer,
170
+ class: "mx-2"
171
+ }, [createVNode(unref(ScalarCombobox), {
172
+ inputLabel: unref(translate)("apiClient.requestParams.searchParameters"),
173
+ noResults: unref(translate)("apiClient.requestParams.noParametersFound"),
174
+ options: availableFields.value,
175
+ placeholder: unref(translate)("apiClient.requestParams.searchParameters"),
176
+ placement: "bottom-start",
177
+ resize: "",
178
+ target: pickerContainer.value ?? void 0,
179
+ "onUpdate:modelValue": selectField
180
+ }, {
181
+ option: withCtx(({ option }) => [createElementVNode("span", _hoisted_4, [createElementVNode("span", _hoisted_5, toDisplayString(option.label), 1), option.description ? (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(option.description), 1)) : createCommentVNode("", true)])]),
182
+ default: withCtx(() => [createVNode(unref(ScalarButton), {
183
+ class: "gap-1.5",
184
+ size: "sm",
185
+ variant: "ghost"
186
+ }, {
187
+ default: withCtx(() => [createVNode(unref(ScalarIconPlus), { class: "size-3.5" }), createTextVNode(" " + toDisplayString(unref(translate)("apiClient.requestParams.addParameter")), 1)]),
188
+ _: 1
189
+ })]),
190
+ _: 1
191
+ }, 8, [
192
+ "inputLabel",
193
+ "noResults",
194
+ "options",
195
+ "placeholder",
196
+ "target"
197
+ ])], 512)])) : createCommentVNode("", true)
198
+ ]),
99
199
  _: 1
100
200
  }, 8, ["itemCount"]);
101
201
  };
@@ -1 +1 @@
1
- {"version":3,"file":"RequestParams.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestParams.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarTooltip } from '@scalar/components/tooltip'\nimport type {\n ApiReferenceEvents,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed } from 'vue'\n\nimport { CollapsibleSection } from '@/v2/components/layout'\nimport { useLocalization } from '@/v2/features/localization'\n\nimport RequestTable from './RequestTable.vue'\nimport type { TableRow, TableRowUpsertPayload } from './RequestTableRow.vue'\n\nconst {\n rows,\n exampleKey,\n environment,\n title,\n globalRoute,\n showAddRowPlaceholder = true,\n eventBus,\n} = defineProps<{\n rows: TableRow[]\n exampleKey: string\n title: string\n label?: string\n /** Explain restrictions on parameter editing when needed. */\n description?: string\n invalidParams?: Set<string>\n globalRoute?: string\n showAddRowPlaceholder?: boolean\n environment: XScalarEnvironment\n eventBus: WorkspaceEventBus\n}>()\n\nconst emit = defineEmits<{\n (\n e: 'upsert',\n index: number,\n payload: ApiReferenceEvents['operation:upsert:parameter']['payload'] & {\n shouldRenameExpandedRow?: boolean\n },\n ): void\n (e: 'delete', payload: { index: number }): void\n (e: 'deleteAll'): void\n /** Select a value for a grouped global cookie preset at the given row index. */\n (e: 'selectPreset', index: number, value: string): void\n}>()\n\nconst { translate } = useLocalization()\n\nconst showTooltip = computed(() => rows.length > 1)\n\n/** Needed for type guard */\nconst handleUpserRow = (index: number, payload: TableRowUpsertPayload) => {\n const { value, ...rest } = payload\n\n // Type guard here as we cannot add files to params\n if (value instanceof File) {\n return\n }\n\n emit('upsert', index, { ...rest, value: value ?? '' })\n}\n</script>\n<template>\n <CollapsibleSection\n class=\"group/params\"\n :itemCount=\"rows.length\">\n <template #title>{{ title }}</template>\n <template #actions>\n <div\n class=\"text-c-2 request-meta-buttons flex whitespace-nowrap opacity-0 group-hover/params:opacity-100 has-[:focus-visible]:opacity-100\">\n <ScalarTooltip\n v-if=\"showTooltip\"\n :content=\"\n translate('apiClient.requestParams.clearOptionalParameters')\n \"\n placement=\"left\">\n <ScalarButton\n :aria-label=\"\n translate('apiClient.requestParams.clearAll', { title })\n \"\n class=\"pr-0.75 pl-1 transition-none\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop=\"emit('deleteAll')\">\n {{ translate('apiClient.requestParams.clear') }}\n </ScalarButton>\n </ScalarTooltip>\n </div>\n </template>\n <p\n v-if=\"description\"\n class=\"text-c-2 px-3 py-2 text-sm\">\n {{ description }}\n </p>\n <RequestTable\n class=\"flex-1\"\n :columns=\"['32px', '', '']\"\n :data=\"rows\"\n :environment=\"environment\"\n :exampleKey=\"exampleKey\"\n :globalRoute=\"globalRoute\"\n :invalidParams=\"invalidParams\"\n :label=\"label\"\n :showAddRowPlaceholder=\"showAddRowPlaceholder\"\n @deleteRow=\"(index) => emit('delete', { index })\"\n @navigate=\"(route) => eventBus.emit('ui:navigate', route)\"\n @selectPreset=\"(index, value) => emit('selectPreset', index, value)\"\n @upsertRow=\"handleUpserRow\" />\n </CollapsibleSection>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCA,MAAM,OAAO;EAcb,MAAM,EAAE,cAAc,gBAAgB;EAEtC,MAAM,cAAc,eAAe,QAAA,KAAK,SAAS,CAAC;;EAGlD,MAAM,kBAAkB,OAAe,YAAmC;GACxE,MAAM,EAAE,OAAO,GAAG,SAAS;GAG3B,IAAI,iBAAiB,MACnB;GAGF,KAAK,UAAU,OAAO;IAAE,GAAG;IAAM,OAAO,SAAS;GAAG,CAAC;EACvD;;uBAGE,YA6CqB,MAAA,0BAAA,GAAA;IA5CnB,OAAM;IACL,WAAW,QAAA,KAAK;;IACN,OAAK,cAAY,CAAA,gBAAA,gBAAR,QAAA,KAAK,GAAA,CAAA,CAAA,CAAA;IACd,SAAO,cAoBV,CAnBN,mBAmBM,OAnBN,YAmBM,CAhBI,YAAA,SAAA,UAAA,GADR,YAgBgB,MAAA,aAAA,GAAA;;KAdb,SAAsB,MAAA,SAAA,CAAS,CAAA,iDAAA;KAGhC,WAAU;;4BAUK,CATf,YASe,MAAA,YAAA,GAAA;MARZ,cAA2B,MAAA,SAAA,CAAS,CAAA,oCAAA,EAAA,OAAuC,QAAA,MAAK,CAAA;MAGjF,OAAM;MACN,MAAK;MACL,SAAQ;MACP,SAAK,OAAA,OAAA,OAAA,KAAA,eAAA,WAAO,KAAI,WAAA,GAAA,CAAA,MAAA,CAAA;;6BAC+B,CAAA,gBAAA,gBAA7C,MAAA,SAAA,CAAS,CAAA,+BAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;;;2BAShB,CAHI,QAAA,eAAA,UAAA,GADR,mBAII,KAJJ,YAII,gBADC,QAAA,WAAW,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,GAEhB,YAagC,sBAAA;KAZ9B,OAAM;KACL,SAAS;MAAA;MAAA;MAAA;KAAA;KACT,MAAM,QAAA;KACN,aAAa,QAAA;KACb,YAAY,QAAA;KACZ,aAAa,QAAA;KACb,eAAe,QAAA;KACf,OAAO,QAAA;KACP,uBAAuB,QAAA;KACvB,aAAS,OAAA,OAAA,OAAA,MAAG,UAAU,KAAI,UAAA,EAAa,MAAK,CAAA;KAC5C,YAAQ,OAAA,OAAA,OAAA,MAAG,UAAU,QAAA,SAAS,KAAI,eAAgB,KAAK;KACvD,gBAAY,OAAA,OAAA,OAAA,MAAG,OAAO,UAAU,KAAI,gBAAiB,OAAO,KAAK;KACjE,aAAW"}
1
+ {"version":3,"file":"RequestParams.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestParams.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarCombobox } from '@scalar/components/combobox'\nimport { ScalarTooltip } from '@scalar/components/tooltip'\nimport { ScalarIconPlus } from '@scalar/icons'\nimport type {\n ApiReferenceEvents,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed, nextTick, ref, useTemplateRef } from 'vue'\n\nimport { CollapsibleSection } from '@/v2/components/layout'\nimport { useLocalization } from '@/v2/features/localization'\n\nimport RequestTable from './RequestTable.vue'\nimport type { TableRow, TableRowUpsertPayload } from './RequestTableRow.vue'\n\nconst {\n rows,\n exampleKey,\n environment,\n title,\n globalRoute,\n showAddRowPlaceholder = true,\n eventBus,\n selectExpandedParameters = false,\n} = defineProps<{\n rows: TableRow[]\n exampleKey: string\n title: string\n label?: string\n /** Explain restrictions on parameter editing when needed. */\n description?: string\n invalidParams?: Set<string>\n globalRoute?: string\n showAddRowPlaceholder?: boolean\n environment: XScalarEnvironment\n eventBus: WorkspaceEventBus\n /** Offer empty object query fields on demand without changing the complete editing context. */\n selectExpandedParameters?: boolean\n}>()\n\nconst emit = defineEmits<{\n (\n e: 'upsert',\n index: number,\n payload: ApiReferenceEvents['operation:upsert:parameter']['payload'] & {\n shouldRenameExpandedRow?: boolean\n },\n ): void\n (e: 'delete', payload: { index: number }): void\n (e: 'deleteAll'): void\n /** Select a value for a grouped global cookie preset at the given row index. */\n (e: 'selectPreset', index: number, value: string): void\n}>()\n\nconst { translate } = useLocalization()\n\nconst showTooltip = computed(() => rows.length > 1)\nconst table = useTemplateRef('table')\nconst pickerContainer = useTemplateRef('pickerContainer')\nconst selectedFields = ref<Set<string>>(new Set())\n\ntype IndexedRow = { row: TableRow; index: number }\ntype AvailableField = {\n id: string\n label: string\n description: TableRow['description']\n index: number\n}\n\nconst getFieldKey = (row: TableRow, name = row.name): string =>\n JSON.stringify([row.originalParameter?.in, row.originalParameter?.name, name])\n\n/** Single-field objects and ordinary parameters keep their existing presentation. */\nconst expandedParameters = computed<Set<TableRow['originalParameter']>>(() => {\n const counts = new Map<TableRow['originalParameter'], number>()\n for (const row of rows) {\n if (row.originalParameter?.in === 'query' && row.sourceParameterValuePath) {\n counts.set(\n row.originalParameter,\n (counts.get(row.originalParameter) ?? 0) + 1,\n )\n }\n }\n return new Set(\n [...counts]\n .filter(([, count]) => count > 1)\n .map(([parameter]) => parameter),\n )\n})\n\nconst isSelectable = (row: TableRow): boolean =>\n selectExpandedParameters &&\n Boolean(row.sourceParameterValuePath) &&\n expandedParameters.value.has(row.originalParameter)\n\n/** Keep original indexes: handlers rebuild object values from all rows, including hidden fields. */\nconst indexedRows = computed<IndexedRow[]>(() =>\n rows.map((row, index) => ({ row, index })),\n)\nconst visibleRows = computed<IndexedRow[]>(() =>\n indexedRows.value.filter(\n ({ row }) =>\n !isSelectable(row) ||\n row.isRequired ||\n (row.value !== '' && row.value !== null) ||\n selectedFields.value.has(getFieldKey(row)),\n ),\n)\nconst tableRows = computed<TableRow[]>(() =>\n visibleRows.value.map(({ row }) => row),\n)\nconst availableFields = computed<AvailableField[]>(() =>\n indexedRows.value\n .filter(\n (entry) => !visibleRows.value.some(({ index }) => index === entry.index),\n )\n .map(({ row, index }) => ({\n id: getFieldKey(row),\n label: row.name,\n description: row.description,\n index,\n })),\n)\n\nconst selectField = async (\n option: { id: string; index: number } | undefined,\n): Promise<void> => {\n if (!option) return\n selectedFields.value.add(option.id)\n await nextTick()\n table.value?.focusValue(\n visibleRows.value.findIndex(({ index }) => index === option.index),\n )\n}\n\n/** The appended placeholder belongs after all stored rows, including hidden fields. */\nconst getOriginalIndex = (index: number): number =>\n visibleRows.value[index]?.index ??\n rows.length + index - visibleRows.value.length\n\nconst deleteRow = (index: number): void => {\n const originalIndex = getOriginalIndex(index)\n const entry = visibleRows.value[index]\n if (entry) selectedFields.value.delete(getFieldKey(entry.row))\n emit('delete', {\n index: originalIndex,\n })\n}\n\nconst deleteAll = (): void => {\n selectedFields.value.clear()\n emit('deleteAll')\n}\n\n/** Needed for type guard */\nconst handleUpserRow = (\n index: number,\n payload: TableRowUpsertPayload,\n): void => {\n const { value, ...rest } = payload\n\n // Type guard here as we cannot add files to params\n if (value instanceof File) {\n return\n }\n\n const entry = visibleRows.value[index]\n if (entry && isSelectable(entry.row)) {\n // Editing a populated field keeps it visible even after its value is cleared.\n selectedFields.value.add(\n getFieldKey(\n entry.row,\n payload.shouldRenameExpandedRow ? payload.name : entry.row.name,\n ),\n )\n }\n emit('upsert', getOriginalIndex(index), { ...rest, value: value ?? '' })\n}\n</script>\n<template>\n <CollapsibleSection\n class=\"group/params\"\n :itemCount=\"tableRows.length\">\n <template #title>{{ title }}</template>\n <template #actions>\n <div\n class=\"text-c-2 request-meta-buttons flex whitespace-nowrap opacity-0 group-hover/params:opacity-100 has-[:focus-visible]:opacity-100\">\n <ScalarTooltip\n v-if=\"showTooltip\"\n :content=\"\n translate('apiClient.requestParams.clearOptionalParameters')\n \"\n placement=\"left\">\n <ScalarButton\n :aria-label=\"\n translate('apiClient.requestParams.clearAll', { title })\n \"\n class=\"pr-0.75 pl-1 transition-none\"\n size=\"sm\"\n variant=\"ghost\"\n @click.stop=\"deleteAll\">\n {{ translate('apiClient.requestParams.clear') }}\n </ScalarButton>\n </ScalarTooltip>\n </div>\n </template>\n <p\n v-if=\"description\"\n class=\"text-c-2 px-3 py-2 text-sm\">\n {{ description }}\n </p>\n <RequestTable\n ref=\"table\"\n class=\"flex-1\"\n :columns=\"['32px', '', '']\"\n :data=\"tableRows\"\n :environment=\"environment\"\n :exampleKey=\"exampleKey\"\n :globalRoute=\"globalRoute\"\n :invalidParams=\"invalidParams\"\n :label=\"label\"\n :showAddRowPlaceholder=\"showAddRowPlaceholder\"\n @deleteRow=\"deleteRow\"\n @navigate=\"(route) => eventBus.emit('ui:navigate', route)\"\n @selectPreset=\"(index, value) => emit('selectPreset', index, value)\"\n @upsertRow=\"handleUpserRow\" />\n <div\n v-if=\"availableFields.length\"\n class=\"border-t py-1\">\n <div\n ref=\"pickerContainer\"\n class=\"mx-2\">\n <ScalarCombobox\n :inputLabel=\"translate('apiClient.requestParams.searchParameters')\"\n :noResults=\"translate('apiClient.requestParams.noParametersFound')\"\n :options=\"availableFields\"\n :placeholder=\"translate('apiClient.requestParams.searchParameters')\"\n placement=\"bottom-start\"\n resize\n :target=\"pickerContainer ?? undefined\"\n @update:modelValue=\"selectField\">\n <ScalarButton\n class=\"gap-1.5\"\n size=\"sm\"\n variant=\"ghost\">\n <ScalarIconPlus class=\"size-3.5\" />\n {{ translate('apiClient.requestParams.addParameter') }}\n </ScalarButton>\n <template #option=\"{ option }\">\n <span class=\"min-w-0\">\n <span class=\"block break-all\">{{ option.label }}</span>\n <span\n v-if=\"option.description\"\n class=\"text-c-2 block text-xs\"\n >{{ option.description }}</span\n >\n </span>\n </template>\n </ScalarCombobox>\n </div>\n </div>\n </CollapsibleSection>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CA,MAAM,OAAO;EAcb,MAAM,EAAE,cAAc,gBAAgB;EAEtC,MAAM,cAAc,eAAe,QAAA,KAAK,SAAS,CAAC;EAClD,MAAM,QAAQ,eAAe,OAAO;EACpC,MAAM,kBAAkB,eAAe,iBAAiB;EACxD,MAAM,iBAAiB,oBAAiB,IAAI,IAAI,CAAC;EAUjD,MAAM,eAAe,KAAe,OAAO,IAAI,SAC7C,KAAK,UAAU;GAAC,IAAI,mBAAmB;GAAI,IAAI,mBAAmB;GAAM;EAAI,CAAC;;EAG/E,MAAM,qBAAqB,eAAmD;GAC5E,MAAM,yBAAS,IAAI,IAA2C;GAC9D,KAAK,MAAM,OAAO,QAAA,MAChB,IAAI,IAAI,mBAAmB,OAAO,WAAW,IAAI,0BAC/C,OAAO,IACL,IAAI,oBACH,OAAO,IAAI,IAAI,iBAAiB,KAAK,KAAK,CAC7C;GAGJ,OAAO,IAAI,IACT,CAAC,GAAG,MAAM,CAAA,CACP,QAAQ,GAAG,WAAW,QAAQ,CAAC,CAAA,CAC/B,KAAK,CAAC,eAAe,SAAS,CACnC;EACF,CAAC;EAED,MAAM,gBAAgB,QACpB,QAAA,4BACA,QAAQ,IAAI,wBAAwB,KACpC,mBAAmB,MAAM,IAAI,IAAI,iBAAiB;;EAGpD,MAAM,cAAc,eAClB,QAAA,KAAK,KAAK,KAAK,WAAW;GAAE;GAAK;EAAM,EAAE,CAC3C;EACA,MAAM,cAAc,eAClB,YAAY,MAAM,QACf,EAAE,UACD,CAAC,aAAa,GAAG,KACjB,IAAI,cACH,IAAI,UAAU,MAAM,IAAI,UAAU,QACnC,eAAe,MAAM,IAAI,YAAY,GAAG,CAAC,CAC7C,CACF;EACA,MAAM,YAAY,eAChB,YAAY,MAAM,KAAK,EAAE,UAAU,GAAG,CACxC;EACA,MAAM,kBAAkB,eACtB,YAAY,MACT,QACE,UAAU,CAAC,YAAY,MAAM,MAAM,EAAE,YAAY,UAAU,MAAM,KAAK,CACzE,CAAA,CACC,KAAK,EAAE,KAAK,aAAa;GACxB,IAAI,YAAY,GAAG;GACnB,OAAO,IAAI;GACX,aAAa,IAAI;GACjB;EACF,EAAE,CACN;EAEA,MAAM,cAAc,OAClB,WACkB;GAClB,IAAI,CAAC,QAAQ;GACb,eAAe,MAAM,IAAI,OAAO,EAAE;GAClC,MAAM,SAAS;GACf,MAAM,OAAO,WACX,YAAY,MAAM,WAAW,EAAE,YAAY,UAAU,OAAO,KAAK,CACnE;EACF;;EAGA,MAAM,oBAAoB,UACxB,YAAY,MAAM,MAAM,EAAE,SAC1B,QAAA,KAAK,SAAS,QAAQ,YAAY,MAAM;EAE1C,MAAM,aAAa,UAAwB;GACzC,MAAM,gBAAgB,iBAAiB,KAAK;GAC5C,MAAM,QAAQ,YAAY,MAAM;GAChC,IAAI,OAAO,eAAe,MAAM,OAAO,YAAY,MAAM,GAAG,CAAC;GAC7D,KAAK,UAAU,EACb,OAAO,cACT,CAAC;EACH;EAEA,MAAM,kBAAwB;GAC5B,eAAe,MAAM,MAAM;GAC3B,KAAK,WAAW;EAClB;;EAGA,MAAM,kBACJ,OACA,YACS;GACT,MAAM,EAAE,OAAO,GAAG,SAAS;GAG3B,IAAI,iBAAiB,MACnB;GAGF,MAAM,QAAQ,YAAY,MAAM;GAChC,IAAI,SAAS,aAAa,MAAM,GAAG,GAEjC,eAAe,MAAM,IACnB,YACE,MAAM,KACN,QAAQ,0BAA0B,QAAQ,OAAO,MAAM,IAAI,IAC7D,CACF;GAEF,KAAK,UAAU,iBAAiB,KAAK,GAAG;IAAE,GAAG;IAAM,OAAO,SAAS;GAAG,CAAC;EACzE;;uBAGE,YAiFqB,MAAA,0BAAA,GAAA;IAhFnB,OAAM;IACL,WAAW,UAAA,MAAU;;IACX,OAAK,cAAY,CAAA,gBAAA,gBAAR,QAAA,KAAK,GAAA,CAAA,CAAA,CAAA;IACd,SAAO,cAoBV,CAnBN,mBAmBM,OAnBN,YAmBM,CAhBI,YAAA,SAAA,UAAA,GADR,YAgBgB,MAAA,aAAA,GAAA;;KAdb,SAAsB,MAAA,SAAA,CAAS,CAAA,iDAAA;KAGhC,WAAU;;4BAUK,CATf,YASe,MAAA,YAAA,GAAA;MARZ,cAA2B,MAAA,SAAA,CAAS,CAAA,oCAAA,EAAA,OAAuC,QAAA,MAAK,CAAA;MAGjF,OAAM;MACN,MAAK;MACL,SAAQ;MACP,SAAK,cAAO,WAAS,CAAA,MAAA,CAAA;;6BAC0B,CAAA,gBAAA,gBAA7C,MAAA,SAAA,CAAS,CAAA,+BAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;;;2BAShB;KAHI,QAAA,eAAA,UAAA,GADR,mBAII,KAJJ,YAII,gBADC,QAAA,WAAW,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;KAEhB,YAcgC,sBAAA;eAb1B;MAAJ,KAAI;MACJ,OAAM;MACL,SAAS;OAAA;OAAA;OAAA;MAAA;MACT,MAAM,UAAA;MACN,aAAa,QAAA;MACb,YAAY,QAAA;MACZ,aAAa,QAAA;MACb,eAAe,QAAA;MACf,OAAO,QAAA;MACP,uBAAuB,QAAA;MACvB,aAAW;MACX,YAAQ,OAAA,OAAA,OAAA,MAAG,UAAU,QAAA,SAAS,KAAI,eAAgB,KAAK;MACvD,gBAAY,OAAA,OAAA,OAAA,MAAG,OAAO,UAAU,KAAI,gBAAiB,OAAO,KAAK;MACjE,aAAW;;;;;;;;;;KAEN,gBAAA,MAAgB,UAAA,UAAA,GADxB,mBAkCM,OAlCN,YAkCM,CA/BJ,mBA8BM,OAAA;eA7BA;MAAJ,KAAI;MACJ,OAAM;SACN,YA0BiB,MAAA,cAAA,GAAA;MAzBd,YAAY,MAAA,SAAA,CAAS,CAAA,0CAAA;MACrB,WAAW,MAAA,SAAA,CAAS,CAAA,2CAAA;MACpB,SAAS,gBAAA;MACT,aAAa,MAAA,SAAA,CAAS,CAAA,0CAAA;MACvB,WAAU;MACV,QAAA;MACC,QAAQ,gBAAA,SAAmB,KAAA;MAC3B,uBAAmB;;MAQT,QAAM,SAQR,EARY,aAAM,CACzB,mBAOO,QAPP,YAOO,CANL,mBAAuD,QAAvD,YAAuD,gBAAtB,OAAO,KAAK,GAAA,CAAA,GAErC,OAAO,eAAA,UAAA,GADf,mBAIC,QAJD,YAIC,gBADK,OAAO,WAAW,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA,CAAA,CAAA;6BAPb,CANf,YAMe,MAAA,YAAA,GAAA;OALb,OAAM;OACN,MAAK;OACL,SAAQ;;8BAC2B,CAAnC,YAAmC,MAAA,cAAA,GAAA,EAAnB,OAAM,WAAU,CAAA,GAAA,gBAAG,MACnC,gBAAG,MAAA,SAAA,CAAS,CAAA,sCAAA,CAAA,GAAA,CAAA,CAAA,CAAA"}
@@ -12,7 +12,9 @@ type __VLS_Props = {
12
12
  showAddRowPlaceholder?: boolean;
13
13
  environment: XScalarEnvironment;
14
14
  };
15
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
15
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
16
+ focusValue: (index: number) => void;
17
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
16
18
  deleteRow: (index: number) => any;
17
19
  navigate: (route: NonNullable<({
18
20
  replace?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"RequestTable.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/request-block/components/RequestTable.vue"],"names":[],"mappings":"AA4NA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAGnH,OAAwB,EACtB,KAAK,QAAQ,EACb,KAAK,qBAAqB,EAC3B,MAAM,0DAA0D,CAAA;AAQjE,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,QAAQ,EAAE,CAAA;IAChB,uFAAuF;IACvF,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,8BAA8B;IAC9B,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,WAAW,EAAE,kBAAkB,CAAA;CAChC,CAAC;AA2UF,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"RequestTable.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/blocks/request-block/components/RequestTable.vue"],"names":[],"mappings":"AAgPA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAGnH,OAAwB,EACtB,KAAK,QAAQ,EACb,KAAK,qBAAqB,EAC3B,MAAM,0DAA0D,CAAA;AAQjE,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,QAAQ,EAAE,CAAA;IAChB,uFAAuF;IACvF,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,8BAA8B;IAC9B,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,WAAW,EAAE,kBAAkB,CAAA;CAChC,CAAC;AAkWF,QAAA,MAAM,YAAY;wBAtMI,MAAM,KAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFA0MjC,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -2,7 +2,7 @@ import _plugin_vue_export_helper_default from "../../../../_virtual/_plugin-vue_
2
2
  import RequestTable_vue_vue_type_script_setup_true_lang_default from "./RequestTable.vue.script.js";
3
3
  /* empty css */
4
4
  //#region src/v2/blocks/request-block/components/RequestTable.vue
5
- var RequestTable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RequestTable_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-e29008b7"]]);
5
+ var RequestTable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RequestTable_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-344240b0"]]);
6
6
  //#endregion
7
7
  export { RequestTable_default as default };
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"RequestTable.vue.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed } from 'vue'\n\nimport RequestTableRow, {\n type TableRow,\n type TableRowUpsertPayload,\n} from '@/v2/blocks/request-block/components/RequestTableRow.vue'\nimport {\n DataTable,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\nimport { useLocalization } from '@/v2/features/localization'\n\nconst {\n data,\n hasCheckboxDisabled,\n deferKeyUpdates,\n showUploadButton,\n showAddRowPlaceholder = true,\n environment,\n} = defineProps<{\n data: TableRow[]\n /** Save key edits on blur so changing a body name does not replace the focused row. */\n deferKeyUpdates?: boolean\n /** Hide the enabled column */\n hasCheckboxDisabled?: boolean\n invalidParams?: Set<string>\n label?: string\n showUploadButton?: boolean\n showAddRowPlaceholder?: boolean\n environment: XScalarEnvironment\n}>()\n\n/**\n * Make this component more generic that can be used also for the operation body\n */\nconst emit = defineEmits<{\n (e: 'upsertRow', index: number, payload: TableRowUpsertPayload): void\n (e: 'deleteRow', index: number): void\n\n /**\n * File upload events\n *\n * Each row has its own upload button, so we need to know which row to update\n * when the file is selected.\n */\n (e: 'uploadFile', index: number): void\n (e: 'removeFile', index: number): void\n (e: 'navigate', route: NonNullable<TableRow['globalRoute']>): void\n /** Select a value for a grouped global cookie preset at the given row index. */\n (e: 'selectPreset', index: number, value: string): void\n}>()\n\nconst { translate } = useLocalization()\n\nconst columns = computed(() => {\n if (showUploadButton) {\n return ['36px', '', '', 'minmax(0, 1fr)']\n }\n return ['36px', '', '']\n})\n\n/** Add the last empty row (for ui purposes only) */\nconst displayData = computed(() => {\n if (!showAddRowPlaceholder) {\n return data\n }\n\n const last = data.at(-1)\n\n if (!last || last.name !== '' || last.value !== '') {\n return [...data, { name: '', value: '', isDisabled: true }]\n }\n\n return data\n})\n\n/**\n * Stable identity key for each row so Vue never reuses a RequestTableRow instance for a different\n * parameter or the appended placeholder row. Parameter rows are keyed by their parameter identity —\n * the name plus the value path for expanded object parameters. The parts are combined through\n * JSON.stringify so the name/path boundary is unambiguous (for example `ab` + `['c']` never\n * collides with `a` + `['bc']`). Form rows use the name and its occurrence so repeated\n * multipart fields remain distinct while unrelated rows can move without losing their identity.\n */\nconst getRowKey = (row: TableRow, index: number): string => {\n // Body edits retain their row when blur commits a rename after focus moves into the value.\n if (deferKeyUpdates) {\n return `body:${index}`\n }\n if (row.originalParameter) {\n return JSON.stringify([\n row.originalParameter.name,\n ...(row.sourceParameterValuePath ?? []),\n ])\n }\n\n const occurrence = displayData.value\n .slice(0, index)\n .filter(\n (other) => !other.originalParameter && other.name === row.name,\n ).length\n return `row:${JSON.stringify([row.name, occurrence])}`\n}\n\n/** Keep an edited row mounted when saving it changes its parameter identity. */\ntype DisplayRow = {\n data: TableRow\n identity: string\n key: symbol\n}\n\nconst pendingUpdates = new Map<symbol, TableRowUpsertPayload>()\n\nconst matchesPendingUpdate = (key: symbol, row: TableRow): boolean => {\n const update = pendingUpdates.get(key)\n return update?.name === row.name && update.value === row.value\n}\n\n// A saved parameter inherits the editor's key. The next placeholder gets a fresh key,\n// so it cannot retain the previous placeholder's text or focused input.\nconst keyedRows = computed<DisplayRow[]>((previous = []) => {\n const available = new Set(previous)\n // Reserve identities still present in the store before transferring an edited key.\n // The appended placeholder is excluded so a newly saved row can inherit its editor.\n const savedIdentities = new Set(data.map(getRowKey))\n const rows = displayData.value.map((row, index) => {\n const identity = getRowKey(row, index)\n const existing = [...available].find((entry) => entry.identity === identity)\n const pending = [...available].find(\n (entry) =>\n !savedIdentities.has(entry.identity) &&\n !entry.data.sourceParameterValuePath &&\n matchesPendingUpdate(entry.key, row),\n )\n const match = existing ?? pending\n\n if (match) {\n available.delete(match)\n if (matchesPendingUpdate(match.key, row)) {\n pendingUpdates.delete(match.key)\n }\n }\n\n return { data: row, identity, key: match?.key ?? Symbol() }\n })\n\n for (const removed of available) {\n pendingUpdates.delete(removed.key)\n }\n\n return rows\n})\n\nconst handleUpsertRow = (\n row: DisplayRow,\n index: number,\n payload: TableRowUpsertPayload,\n): void => {\n // The store may debounce the save. Transfer this key only when the saved row arrives.\n pendingUpdates.set(row.key, payload)\n emit('upsertRow', index, payload)\n}\n</script>\n<template>\n <DataTable\n class=\"group/table flex-1\"\n :columns=\"columns\">\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.enabled') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.key') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.value') }}\n </DataTableHeader>\n </DataTableRow>\n\n <RequestTableRow\n v-for=\"(row, index) in keyedRows\"\n :key=\"row.key\"\n :data=\"row.data\"\n :deferKeyUpdates=\"deferKeyUpdates\"\n :environment=\"environment\"\n :hasCheckboxDisabled=\"hasCheckboxDisabled\"\n :invalidParams=\"invalidParams\"\n :label=\"label\"\n :showUploadButton=\"showUploadButton\"\n @deleteRow=\"emit('deleteRow', index)\"\n @navigate=\"(route) => emit('navigate', route)\"\n @removeFile=\"emit('removeFile', index)\"\n @selectPreset=\"(value) => emit('selectPreset', index, value)\"\n @uploadFile=\"emit('uploadFile', index)\"\n @upsertRow=\"(payload) => handleUpsertRow(row, index, payload)\" />\n </DataTable>\n</template>\n<style scoped>\n:deep(.code-input-lite__editor) {\n background-color: transparent;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n}\n:deep(.scalar-pill:not(:last-of-type)) {\n margin-right: 0.15em;\n}\n:deep(.scalar-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"RequestTable.vue.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed, type ComponentPublicInstance } from 'vue'\n\nimport RequestTableRow, {\n type TableRow,\n type TableRowUpsertPayload,\n} from '@/v2/blocks/request-block/components/RequestTableRow.vue'\nimport {\n DataTable,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\nimport { useLocalization } from '@/v2/features/localization'\n\nconst {\n data,\n hasCheckboxDisabled,\n deferKeyUpdates,\n showUploadButton,\n showAddRowPlaceholder = true,\n environment,\n} = defineProps<{\n data: TableRow[]\n /** Save key edits on blur so changing a body name does not replace the focused row. */\n deferKeyUpdates?: boolean\n /** Hide the enabled column */\n hasCheckboxDisabled?: boolean\n invalidParams?: Set<string>\n label?: string\n showUploadButton?: boolean\n showAddRowPlaceholder?: boolean\n environment: XScalarEnvironment\n}>()\n\n/**\n * Make this component more generic that can be used also for the operation body\n */\nconst emit = defineEmits<{\n (e: 'upsertRow', index: number, payload: TableRowUpsertPayload): void\n (e: 'deleteRow', index: number): void\n\n /**\n * File upload events\n *\n * Each row has its own upload button, so we need to know which row to update\n * when the file is selected.\n */\n (e: 'uploadFile', index: number): void\n (e: 'removeFile', index: number): void\n (e: 'navigate', route: NonNullable<TableRow['globalRoute']>): void\n /** Select a value for a grouped global cookie preset at the given row index. */\n (e: 'selectPreset', index: number, value: string): void\n}>()\n\nconst { translate } = useLocalization()\n\nconst columns = computed(() => {\n if (showUploadButton) {\n return ['36px', '', '', 'minmax(0, 1fr)']\n }\n return ['36px', '', '']\n})\n\n/** Add the last empty row (for ui purposes only) */\nconst displayData = computed(() => {\n if (!showAddRowPlaceholder) {\n return data\n }\n\n const last = data.at(-1)\n\n if (last?.name !== '' || last.value !== '') {\n return [...data, { name: '', value: '', isDisabled: true }]\n }\n\n return data\n})\n\n/**\n * Stable identity key for each row so Vue never reuses a RequestTableRow instance for a different\n * parameter or the appended placeholder row. Parameter rows are keyed by their parameter identity —\n * the name plus the value path for expanded object parameters. The parts are combined through\n * JSON.stringify so the name/path boundary is unambiguous (for example `ab` + `['c']` never\n * collides with `a` + `['bc']`). Form rows use the name and its occurrence so repeated\n * multipart fields remain distinct while unrelated rows can move without losing their identity.\n */\nconst getRowKey = (row: TableRow, index: number): string => {\n // Body edits retain their row when blur commits a rename after focus moves into the value.\n if (deferKeyUpdates) {\n return `body:${index}`\n }\n if (row.originalParameter) {\n return JSON.stringify([\n row.originalParameter.name,\n ...(row.sourceParameterValuePath ?? []),\n ])\n }\n\n const occurrence = displayData.value\n .slice(0, index)\n .filter(\n (other) => !other.originalParameter && other.name === row.name,\n ).length\n return `row:${JSON.stringify([row.name, occurrence])}`\n}\n\n/** Keep an edited row mounted when saving it changes its parameter identity. */\ntype DisplayRow = {\n data: TableRow\n identity: string\n key: symbol\n}\n\nconst pendingUpdates = new Map<symbol, TableRowUpsertPayload>()\nconst rowRefs = new Map<symbol, InstanceType<typeof RequestTableRow>>()\n\nconst setRowRef = (\n key: symbol,\n element: Element | ComponentPublicInstance | null,\n): void => {\n if (element) {\n rowRefs.set(key, element as InstanceType<typeof RequestTableRow>)\n } else {\n rowRefs.delete(key)\n }\n}\n\nconst matchesPendingUpdate = (key: symbol, row: TableRow): boolean => {\n const update = pendingUpdates.get(key)\n return update?.name === row.name && update.value === row.value\n}\n\n// A saved parameter inherits the editor's key. The next placeholder gets a fresh key,\n// so it cannot retain the previous placeholder's text or focused input.\nconst keyedRows = computed<DisplayRow[]>((previous = []) => {\n const available = new Set(previous)\n // Reserve identities still present in the store before transferring an edited key.\n // The appended placeholder is excluded so a newly saved row can inherit its editor.\n const savedIdentities = new Set(data.map(getRowKey))\n const rows = displayData.value.map((row, index) => {\n const identity = getRowKey(row, index)\n const existing = [...available].find((entry) => entry.identity === identity)\n const pending = [...available].find(\n (entry) =>\n !savedIdentities.has(entry.identity) &&\n !entry.data.sourceParameterValuePath &&\n matchesPendingUpdate(entry.key, row),\n )\n const match = existing ?? pending\n\n if (match) {\n available.delete(match)\n if (matchesPendingUpdate(match.key, row)) {\n pendingUpdates.delete(match.key)\n }\n }\n\n return { data: row, identity, key: match?.key ?? Symbol() }\n })\n\n for (const removed of available) {\n pendingUpdates.delete(removed.key)\n }\n\n return rows\n})\n\nconst handleUpsertRow = (\n row: DisplayRow,\n index: number,\n payload: TableRowUpsertPayload,\n): void => {\n // The store may debounce the save. Transfer this key only when the saved row arrives.\n pendingUpdates.set(row.key, payload)\n emit('upsertRow', index, payload)\n}\n\ndefineExpose({\n focusValue: (index: number): void => {\n const row = keyedRows.value[index]\n if (row) rowRefs.get(row.key)?.focusValue()\n },\n})\n</script>\n<template>\n <DataTable\n class=\"group/table flex-1\"\n :columns=\"columns\">\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.enabled') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.key') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.value') }}\n </DataTableHeader>\n </DataTableRow>\n\n <RequestTableRow\n v-for=\"(row, index) in keyedRows\"\n :key=\"row.key\"\n :ref=\"(el) => setRowRef(row.key, el)\"\n :data=\"row.data\"\n :deferKeyUpdates=\"deferKeyUpdates\"\n :environment=\"environment\"\n :hasCheckboxDisabled=\"hasCheckboxDisabled\"\n :invalidParams=\"invalidParams\"\n :label=\"label\"\n :showUploadButton=\"showUploadButton\"\n @deleteRow=\"emit('deleteRow', index)\"\n @navigate=\"(route) => emit('navigate', route)\"\n @removeFile=\"emit('removeFile', index)\"\n @selectPreset=\"(value) => emit('selectPreset', index, value)\"\n @uploadFile=\"emit('uploadFile', index)\"\n @upsertRow=\"(payload) => handleUpsertRow(row, index, payload)\" />\n </DataTable>\n</template>\n<style scoped>\n:deep(.code-input-lite__editor) {\n background-color: transparent;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n}\n:deep(.scalar-pill:not(:last-of-type)) {\n margin-right: 0.15em;\n}\n:deep(.scalar-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n</style>\n"],"mappings":""}
@@ -28,7 +28,7 @@ var RequestTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
28
28
  "navigate",
29
29
  "selectPreset"
30
30
  ],
31
- setup(__props, { emit: __emit }) {
31
+ setup(__props, { expose: __expose, emit: __emit }) {
32
32
  /**
33
33
  * Make this component more generic that can be used also for the operation body
34
34
  */
@@ -51,7 +51,7 @@ var RequestTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
51
51
  const displayData = computed(() => {
52
52
  if (!__props.showAddRowPlaceholder) return __props.data;
53
53
  const last = __props.data.at(-1);
54
- if (!last || last.name !== "" || last.value !== "") return [...__props.data, {
54
+ if (last?.name !== "" || last.value !== "") return [...__props.data, {
55
55
  name: "",
56
56
  value: "",
57
57
  isDisabled: true
@@ -74,6 +74,11 @@ var RequestTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
74
74
  };
75
75
  /** Keep an edited row mounted when saving it changes its parameter identity. */
76
76
  const pendingUpdates = /* @__PURE__ */ new Map();
77
+ const rowRefs = /* @__PURE__ */ new Map();
78
+ const setRowRef = (key, element) => {
79
+ if (element) rowRefs.set(key, element);
80
+ else rowRefs.delete(key);
81
+ };
77
82
  const matchesPendingUpdate = (key, row) => {
78
83
  const update = pendingUpdates.get(key);
79
84
  return update?.name === row.name && update.value === row.value;
@@ -103,6 +108,10 @@ var RequestTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
103
108
  pendingUpdates.set(row.key, payload);
104
109
  emit("upsertRow", index, payload);
105
110
  };
111
+ __expose({ focusValue: (index) => {
112
+ const row = keyedRows.value[index];
113
+ if (row) rowRefs.get(row.key)?.focusValue();
114
+ } });
106
115
  return (_ctx, _cache) => {
107
116
  return openBlock(), createBlock(unref(DataTable_default), {
108
117
  class: "group/table flex-1",
@@ -127,6 +136,8 @@ var RequestTable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
127
136
  }), (openBlock(true), createElementBlock(Fragment, null, renderList(keyedRows.value, (row, index) => {
128
137
  return openBlock(), createBlock(RequestTableRow_default, {
129
138
  key: row.key,
139
+ ref_for: true,
140
+ ref: (el) => setRowRef(row.key, el),
130
141
  data: row.data,
131
142
  deferKeyUpdates: __props.deferKeyUpdates,
132
143
  environment: __props.environment,
@@ -1 +1 @@
1
- {"version":3,"file":"RequestTable.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed } from 'vue'\n\nimport RequestTableRow, {\n type TableRow,\n type TableRowUpsertPayload,\n} from '@/v2/blocks/request-block/components/RequestTableRow.vue'\nimport {\n DataTable,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\nimport { useLocalization } from '@/v2/features/localization'\n\nconst {\n data,\n hasCheckboxDisabled,\n deferKeyUpdates,\n showUploadButton,\n showAddRowPlaceholder = true,\n environment,\n} = defineProps<{\n data: TableRow[]\n /** Save key edits on blur so changing a body name does not replace the focused row. */\n deferKeyUpdates?: boolean\n /** Hide the enabled column */\n hasCheckboxDisabled?: boolean\n invalidParams?: Set<string>\n label?: string\n showUploadButton?: boolean\n showAddRowPlaceholder?: boolean\n environment: XScalarEnvironment\n}>()\n\n/**\n * Make this component more generic that can be used also for the operation body\n */\nconst emit = defineEmits<{\n (e: 'upsertRow', index: number, payload: TableRowUpsertPayload): void\n (e: 'deleteRow', index: number): void\n\n /**\n * File upload events\n *\n * Each row has its own upload button, so we need to know which row to update\n * when the file is selected.\n */\n (e: 'uploadFile', index: number): void\n (e: 'removeFile', index: number): void\n (e: 'navigate', route: NonNullable<TableRow['globalRoute']>): void\n /** Select a value for a grouped global cookie preset at the given row index. */\n (e: 'selectPreset', index: number, value: string): void\n}>()\n\nconst { translate } = useLocalization()\n\nconst columns = computed(() => {\n if (showUploadButton) {\n return ['36px', '', '', 'minmax(0, 1fr)']\n }\n return ['36px', '', '']\n})\n\n/** Add the last empty row (for ui purposes only) */\nconst displayData = computed(() => {\n if (!showAddRowPlaceholder) {\n return data\n }\n\n const last = data.at(-1)\n\n if (!last || last.name !== '' || last.value !== '') {\n return [...data, { name: '', value: '', isDisabled: true }]\n }\n\n return data\n})\n\n/**\n * Stable identity key for each row so Vue never reuses a RequestTableRow instance for a different\n * parameter or the appended placeholder row. Parameter rows are keyed by their parameter identity —\n * the name plus the value path for expanded object parameters. The parts are combined through\n * JSON.stringify so the name/path boundary is unambiguous (for example `ab` + `['c']` never\n * collides with `a` + `['bc']`). Form rows use the name and its occurrence so repeated\n * multipart fields remain distinct while unrelated rows can move without losing their identity.\n */\nconst getRowKey = (row: TableRow, index: number): string => {\n // Body edits retain their row when blur commits a rename after focus moves into the value.\n if (deferKeyUpdates) {\n return `body:${index}`\n }\n if (row.originalParameter) {\n return JSON.stringify([\n row.originalParameter.name,\n ...(row.sourceParameterValuePath ?? []),\n ])\n }\n\n const occurrence = displayData.value\n .slice(0, index)\n .filter(\n (other) => !other.originalParameter && other.name === row.name,\n ).length\n return `row:${JSON.stringify([row.name, occurrence])}`\n}\n\n/** Keep an edited row mounted when saving it changes its parameter identity. */\ntype DisplayRow = {\n data: TableRow\n identity: string\n key: symbol\n}\n\nconst pendingUpdates = new Map<symbol, TableRowUpsertPayload>()\n\nconst matchesPendingUpdate = (key: symbol, row: TableRow): boolean => {\n const update = pendingUpdates.get(key)\n return update?.name === row.name && update.value === row.value\n}\n\n// A saved parameter inherits the editor's key. The next placeholder gets a fresh key,\n// so it cannot retain the previous placeholder's text or focused input.\nconst keyedRows = computed<DisplayRow[]>((previous = []) => {\n const available = new Set(previous)\n // Reserve identities still present in the store before transferring an edited key.\n // The appended placeholder is excluded so a newly saved row can inherit its editor.\n const savedIdentities = new Set(data.map(getRowKey))\n const rows = displayData.value.map((row, index) => {\n const identity = getRowKey(row, index)\n const existing = [...available].find((entry) => entry.identity === identity)\n const pending = [...available].find(\n (entry) =>\n !savedIdentities.has(entry.identity) &&\n !entry.data.sourceParameterValuePath &&\n matchesPendingUpdate(entry.key, row),\n )\n const match = existing ?? pending\n\n if (match) {\n available.delete(match)\n if (matchesPendingUpdate(match.key, row)) {\n pendingUpdates.delete(match.key)\n }\n }\n\n return { data: row, identity, key: match?.key ?? Symbol() }\n })\n\n for (const removed of available) {\n pendingUpdates.delete(removed.key)\n }\n\n return rows\n})\n\nconst handleUpsertRow = (\n row: DisplayRow,\n index: number,\n payload: TableRowUpsertPayload,\n): void => {\n // The store may debounce the save. Transfer this key only when the saved row arrives.\n pendingUpdates.set(row.key, payload)\n emit('upsertRow', index, payload)\n}\n</script>\n<template>\n <DataTable\n class=\"group/table flex-1\"\n :columns=\"columns\">\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.enabled') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.key') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.value') }}\n </DataTableHeader>\n </DataTableRow>\n\n <RequestTableRow\n v-for=\"(row, index) in keyedRows\"\n :key=\"row.key\"\n :data=\"row.data\"\n :deferKeyUpdates=\"deferKeyUpdates\"\n :environment=\"environment\"\n :hasCheckboxDisabled=\"hasCheckboxDisabled\"\n :invalidParams=\"invalidParams\"\n :label=\"label\"\n :showUploadButton=\"showUploadButton\"\n @deleteRow=\"emit('deleteRow', index)\"\n @navigate=\"(route) => emit('navigate', route)\"\n @removeFile=\"emit('removeFile', index)\"\n @selectPreset=\"(value) => emit('selectPreset', index, value)\"\n @uploadFile=\"emit('uploadFile', index)\"\n @upsertRow=\"(payload) => handleUpsertRow(row, index, payload)\" />\n </DataTable>\n</template>\n<style scoped>\n:deep(.code-input-lite__editor) {\n background-color: transparent;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n}\n:deep(.scalar-pill:not(:last-of-type)) {\n margin-right: 0.15em;\n}\n:deep(.scalar-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"RequestTable.vue.script.js","names":[],"sources":["../../../../../src/v2/blocks/request-block/components/RequestTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed, type ComponentPublicInstance } from 'vue'\n\nimport RequestTableRow, {\n type TableRow,\n type TableRowUpsertPayload,\n} from '@/v2/blocks/request-block/components/RequestTableRow.vue'\nimport {\n DataTable,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\nimport { useLocalization } from '@/v2/features/localization'\n\nconst {\n data,\n hasCheckboxDisabled,\n deferKeyUpdates,\n showUploadButton,\n showAddRowPlaceholder = true,\n environment,\n} = defineProps<{\n data: TableRow[]\n /** Save key edits on blur so changing a body name does not replace the focused row. */\n deferKeyUpdates?: boolean\n /** Hide the enabled column */\n hasCheckboxDisabled?: boolean\n invalidParams?: Set<string>\n label?: string\n showUploadButton?: boolean\n showAddRowPlaceholder?: boolean\n environment: XScalarEnvironment\n}>()\n\n/**\n * Make this component more generic that can be used also for the operation body\n */\nconst emit = defineEmits<{\n (e: 'upsertRow', index: number, payload: TableRowUpsertPayload): void\n (e: 'deleteRow', index: number): void\n\n /**\n * File upload events\n *\n * Each row has its own upload button, so we need to know which row to update\n * when the file is selected.\n */\n (e: 'uploadFile', index: number): void\n (e: 'removeFile', index: number): void\n (e: 'navigate', route: NonNullable<TableRow['globalRoute']>): void\n /** Select a value for a grouped global cookie preset at the given row index. */\n (e: 'selectPreset', index: number, value: string): void\n}>()\n\nconst { translate } = useLocalization()\n\nconst columns = computed(() => {\n if (showUploadButton) {\n return ['36px', '', '', 'minmax(0, 1fr)']\n }\n return ['36px', '', '']\n})\n\n/** Add the last empty row (for ui purposes only) */\nconst displayData = computed(() => {\n if (!showAddRowPlaceholder) {\n return data\n }\n\n const last = data.at(-1)\n\n if (last?.name !== '' || last.value !== '') {\n return [...data, { name: '', value: '', isDisabled: true }]\n }\n\n return data\n})\n\n/**\n * Stable identity key for each row so Vue never reuses a RequestTableRow instance for a different\n * parameter or the appended placeholder row. Parameter rows are keyed by their parameter identity —\n * the name plus the value path for expanded object parameters. The parts are combined through\n * JSON.stringify so the name/path boundary is unambiguous (for example `ab` + `['c']` never\n * collides with `a` + `['bc']`). Form rows use the name and its occurrence so repeated\n * multipart fields remain distinct while unrelated rows can move without losing their identity.\n */\nconst getRowKey = (row: TableRow, index: number): string => {\n // Body edits retain their row when blur commits a rename after focus moves into the value.\n if (deferKeyUpdates) {\n return `body:${index}`\n }\n if (row.originalParameter) {\n return JSON.stringify([\n row.originalParameter.name,\n ...(row.sourceParameterValuePath ?? []),\n ])\n }\n\n const occurrence = displayData.value\n .slice(0, index)\n .filter(\n (other) => !other.originalParameter && other.name === row.name,\n ).length\n return `row:${JSON.stringify([row.name, occurrence])}`\n}\n\n/** Keep an edited row mounted when saving it changes its parameter identity. */\ntype DisplayRow = {\n data: TableRow\n identity: string\n key: symbol\n}\n\nconst pendingUpdates = new Map<symbol, TableRowUpsertPayload>()\nconst rowRefs = new Map<symbol, InstanceType<typeof RequestTableRow>>()\n\nconst setRowRef = (\n key: symbol,\n element: Element | ComponentPublicInstance | null,\n): void => {\n if (element) {\n rowRefs.set(key, element as InstanceType<typeof RequestTableRow>)\n } else {\n rowRefs.delete(key)\n }\n}\n\nconst matchesPendingUpdate = (key: symbol, row: TableRow): boolean => {\n const update = pendingUpdates.get(key)\n return update?.name === row.name && update.value === row.value\n}\n\n// A saved parameter inherits the editor's key. The next placeholder gets a fresh key,\n// so it cannot retain the previous placeholder's text or focused input.\nconst keyedRows = computed<DisplayRow[]>((previous = []) => {\n const available = new Set(previous)\n // Reserve identities still present in the store before transferring an edited key.\n // The appended placeholder is excluded so a newly saved row can inherit its editor.\n const savedIdentities = new Set(data.map(getRowKey))\n const rows = displayData.value.map((row, index) => {\n const identity = getRowKey(row, index)\n const existing = [...available].find((entry) => entry.identity === identity)\n const pending = [...available].find(\n (entry) =>\n !savedIdentities.has(entry.identity) &&\n !entry.data.sourceParameterValuePath &&\n matchesPendingUpdate(entry.key, row),\n )\n const match = existing ?? pending\n\n if (match) {\n available.delete(match)\n if (matchesPendingUpdate(match.key, row)) {\n pendingUpdates.delete(match.key)\n }\n }\n\n return { data: row, identity, key: match?.key ?? Symbol() }\n })\n\n for (const removed of available) {\n pendingUpdates.delete(removed.key)\n }\n\n return rows\n})\n\nconst handleUpsertRow = (\n row: DisplayRow,\n index: number,\n payload: TableRowUpsertPayload,\n): void => {\n // The store may debounce the save. Transfer this key only when the saved row arrives.\n pendingUpdates.set(row.key, payload)\n emit('upsertRow', index, payload)\n}\n\ndefineExpose({\n focusValue: (index: number): void => {\n const row = keyedRows.value[index]\n if (row) rowRefs.get(row.key)?.focusValue()\n },\n})\n</script>\n<template>\n <DataTable\n class=\"group/table flex-1\"\n :columns=\"columns\">\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.enabled') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.key') }}\n </DataTableHeader>\n <DataTableHeader>\n {{ label }}\n {{ translate('apiClient.requestTable.value') }}\n </DataTableHeader>\n </DataTableRow>\n\n <RequestTableRow\n v-for=\"(row, index) in keyedRows\"\n :key=\"row.key\"\n :ref=\"(el) => setRowRef(row.key, el)\"\n :data=\"row.data\"\n :deferKeyUpdates=\"deferKeyUpdates\"\n :environment=\"environment\"\n :hasCheckboxDisabled=\"hasCheckboxDisabled\"\n :invalidParams=\"invalidParams\"\n :label=\"label\"\n :showUploadButton=\"showUploadButton\"\n @deleteRow=\"emit('deleteRow', index)\"\n @navigate=\"(route) => emit('navigate', route)\"\n @removeFile=\"emit('removeFile', index)\"\n @selectPreset=\"(value) => emit('selectPreset', index, value)\"\n @uploadFile=\"emit('uploadFile', index)\"\n @upsertRow=\"(payload) => handleUpsertRow(row, index, payload)\" />\n </DataTable>\n</template>\n<style scoped>\n:deep(.code-input-lite__editor) {\n background-color: transparent;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n}\n:deep(.scalar-pill:not(:last-of-type)) {\n margin-right: 0.15em;\n}\n:deep(.scalar-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n</style>\n"],"mappings":"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"}