@cqa-lib/cqa-ui 1.1.191 → 1.1.192

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.
@@ -17483,7 +17483,20 @@ class TestCaseDetailsRendererComponent {
17483
17483
  wire('descriptionChange', this.descriptionChange);
17484
17484
  wire('reusableChange', this.reusableChange);
17485
17485
  wire('openExternal', this.openExternal);
17486
- wire('edit', this.edit);
17486
+ wire('edit', {
17487
+ emit: (v) => {
17488
+ // If child component emits void or nothing, use current step and index
17489
+ // If child component already emits an object, merge it with step and index
17490
+ if (v != null && typeof v === 'object' && 'step' in v && 'index' in v) {
17491
+ // Already has step and index, emit as-is
17492
+ this.edit.emit(v);
17493
+ }
17494
+ else {
17495
+ // Emit with current step and index
17496
+ this.edit.emit({ step: this.step, index: this.index });
17497
+ }
17498
+ },
17499
+ });
17487
17500
  wire('link', this.link);
17488
17501
  wire('duplicate', this.duplicate);
17489
17502
  wire('delete', this.delete);
@@ -19616,6 +19629,152 @@ const API_EDIT_STEP_LABELS = {
19616
19629
  const METHODS_WITHOUT_BODY = ['GET', 'HEAD', 'DELETE'];
19617
19630
  /** Auto-close pairs for payload JSON editor: opening char -> closing char. */
19618
19631
  const PAYLOAD_AUTO_CLOSE_PAIRS = { '{': '}', '[': ']', '"': '"', "'": "'" };
19632
+ function isSingleQuote(ch) {
19633
+ return ch === "'" || ch === '\u2018' || ch === '\u2019';
19634
+ }
19635
+ function isDoubleQuote(ch) {
19636
+ return ch === '"' || ch === '\u201C' || ch === '\u201D';
19637
+ }
19638
+ function isClosingQuote(ch, openQuote) {
19639
+ if (isSingleQuote(openQuote))
19640
+ return isSingleQuote(ch);
19641
+ if (isDoubleQuote(openQuote))
19642
+ return isDoubleQuote(ch);
19643
+ return ch === openQuote;
19644
+ }
19645
+ /**
19646
+ * Tokenize a string respecting single- and double-quoted segments (for cURL args).
19647
+ * Handles straight and smart/curly quotes so pasted cURLs from browsers/docs work.
19648
+ */
19649
+ function tokenizeCurlLine(line) {
19650
+ const tokens = [];
19651
+ let i = 0;
19652
+ const n = line.length;
19653
+ while (i < n) {
19654
+ while (i < n && /\s/.test(line[i]))
19655
+ i++;
19656
+ if (i >= n)
19657
+ break;
19658
+ const ch = line[i];
19659
+ if (isSingleQuote(ch) || isDoubleQuote(ch)) {
19660
+ const quote = ch;
19661
+ i++;
19662
+ let value = '';
19663
+ while (i < n && !isClosingQuote(line[i], quote)) {
19664
+ if (line[i] === '\\') {
19665
+ i++;
19666
+ if (i < n)
19667
+ value += line[i++];
19668
+ }
19669
+ else {
19670
+ value += line[i++];
19671
+ }
19672
+ }
19673
+ if (i < n)
19674
+ i++;
19675
+ tokens.push(value);
19676
+ continue;
19677
+ }
19678
+ let word = '';
19679
+ while (i < n && !/\s/.test(line[i]) && !isSingleQuote(line[i]) && !isDoubleQuote(line[i])) {
19680
+ word += line[i++];
19681
+ }
19682
+ if (word)
19683
+ tokens.push(word);
19684
+ }
19685
+ return tokens;
19686
+ }
19687
+ /** Strip one layer of surrounding single or double quotes from a string (e.g. '{"x":1}' -> {"x":1}). */
19688
+ function stripSurroundingQuotes(s) {
19689
+ if (s.length >= 2 && (s.startsWith("'") && s.endsWith("'")) || (s.startsWith('"') && s.endsWith('"'))) {
19690
+ return s.slice(1, -1);
19691
+ }
19692
+ return s;
19693
+ }
19694
+ /**
19695
+ * Parse a cURL command string and return method, url, headers, and body.
19696
+ * Supports -X/--request, -H/--header, -d/--data/--data-raw/--data-binary, and URL.
19697
+ * Handles line continuations (backslash-newline) and quoted body payloads.
19698
+ */
19699
+ function parseCurl(curlString) {
19700
+ const raw = (curlString !== null && curlString !== void 0 ? curlString : '').trim();
19701
+ if (!raw)
19702
+ return null;
19703
+ // Remove line continuations (backslash followed by newline) so they don't break tokenization
19704
+ const noContinuations = raw.replace(/\\\s*\r?\n\s*/g, ' ');
19705
+ const normalized = noContinuations.replace(/\r?\n/g, ' ').replace(/\s+/g, ' ');
19706
+ const tokens = tokenizeCurlLine(normalized);
19707
+ let method = 'GET';
19708
+ let url = '';
19709
+ const headers = [];
19710
+ let body = '';
19711
+ const urlPattern = /^https?:\/\//i;
19712
+ for (let i = 0; i < tokens.length; i++) {
19713
+ const t = tokens[i];
19714
+ const consumeNext = () => {
19715
+ i++;
19716
+ return tokens[i];
19717
+ };
19718
+ if (t === '-X' || t === '--request') {
19719
+ const value = consumeNext();
19720
+ if (value)
19721
+ method = value.toUpperCase();
19722
+ continue;
19723
+ }
19724
+ if (t === '-H' || t === '--header') {
19725
+ const value = consumeNext();
19726
+ if (value) {
19727
+ const colon = value.indexOf(':');
19728
+ if (colon !== -1) {
19729
+ const name = value.slice(0, colon).trim();
19730
+ const headerValue = value.slice(colon + 1).trim();
19731
+ if (name)
19732
+ headers.push({ name, type: 'string', value: headerValue });
19733
+ }
19734
+ }
19735
+ continue;
19736
+ }
19737
+ if (t === '-d' || t === '--data' || t === '--data-raw' || t === '--data-binary' || t === '--data-ascii') {
19738
+ const value = consumeNext();
19739
+ if (value != null && !String(value).startsWith('@'))
19740
+ body = stripSurroundingQuotes(value);
19741
+ continue;
19742
+ }
19743
+ if (t.startsWith('--data=')) {
19744
+ const value = t.slice(7);
19745
+ if (!value.startsWith('@'))
19746
+ body = stripSurroundingQuotes(value.replace(/^["']|["']$/g, ''));
19747
+ continue;
19748
+ }
19749
+ if (t.startsWith('--data-raw=')) {
19750
+ const value = t.slice(11);
19751
+ if (!value.startsWith('@'))
19752
+ body = stripSurroundingQuotes(value.replace(/^["']|["']$/g, ''));
19753
+ continue;
19754
+ }
19755
+ if (t.startsWith('-d')) {
19756
+ const value = t.length > 2 ? t.slice(2) : consumeNext();
19757
+ if (value != null && !value.startsWith('@'))
19758
+ body = stripSurroundingQuotes(value);
19759
+ continue;
19760
+ }
19761
+ if (urlPattern.test(t)) {
19762
+ if (!url)
19763
+ url = t;
19764
+ }
19765
+ }
19766
+ if (!url) {
19767
+ const firstUrl = tokens.find((tok) => urlPattern.test(tok));
19768
+ if (firstUrl)
19769
+ url = firstUrl;
19770
+ }
19771
+ // Many cURLs (e.g. from browser devtools) omit -X POST when sending a body; infer POST
19772
+ const finalMethod = (method || 'GET').toUpperCase();
19773
+ if (body && (finalMethod === 'GET' || finalMethod === 'HEAD')) {
19774
+ return { method: 'POST', url, headers, body };
19775
+ }
19776
+ return { method: finalMethod, url, headers, body };
19777
+ }
19619
19778
  class ApiEditStepComponent {
19620
19779
  constructor(fb, cdr) {
19621
19780
  this.fb = fb;
@@ -19627,6 +19786,8 @@ class ApiEditStepComponent {
19627
19786
  /** Emits when user clicks Send Request, with environment, method, url, and headers. */
19628
19787
  this.sendRequest = new EventEmitter();
19629
19788
  this.back = new EventEmitter();
19789
+ /** Emits when user clicks the Cancel button (step 1). */
19790
+ this.cancel = new EventEmitter();
19630
19791
  this.next = new EventEmitter();
19631
19792
  /** Emits when user clicks Create with all entered details: step1 (environment, HTTP method, URL, headers, body), step2 (variable name), step3 (verifications). */
19632
19793
  this.create = new EventEmitter();
@@ -19664,16 +19825,41 @@ class ApiEditStepComponent {
19664
19825
  searchable: false,
19665
19826
  options: [],
19666
19827
  };
19828
+ /** Auth type options: array of strings or objects with id, name, value, label (passed from parent). Falls back to built-in list when empty. */
19829
+ this.authTypeOptions = [];
19830
+ /** Config for Auth Type dropdown (updated when authTypeOptions changes, like environment) */
19831
+ this.authTypeSelectConfig = {
19832
+ key: 'authType',
19833
+ placeholder: 'No Auth',
19834
+ searchable: false,
19835
+ options: [],
19836
+ };
19837
+ /** Bearer token value (Authorization tab, when auth type is Bearer Token). */
19838
+ this.bearerToken = '';
19839
+ this.oauth2GrantTypeSelectConfig = {
19840
+ key: 'grantType',
19841
+ placeholder: 'Select grant type',
19842
+ searchable: false,
19843
+ options: [...ApiEditStepComponent.OAUTH_GRANT_TYPE_OPTIONS],
19844
+ };
19845
+ this.oauth2ClientAuthSelectConfig = {
19846
+ key: 'clientAuthentication',
19847
+ placeholder: 'Select method',
19848
+ searchable: false,
19849
+ options: [...ApiEditStepComponent.OAUTH_CLIENT_AUTH_OPTIONS],
19850
+ };
19667
19851
  /** Cached environment value from last selection (so Create payload has the selected value). */
19668
19852
  this.currentEnvironmentValue = '';
19669
19853
  /** Cached HTTP method from last selection (so Create payload has the selected value). */
19670
19854
  this.currentMethodValue = '';
19671
- this.url = '';
19855
+ this._url = '';
19856
+ /** When true, params form changes should not update the URL (we're syncing from URL). */
19857
+ this.paramsSyncingFromUrl = false;
19672
19858
  this.payloadTabs = [
19859
+ { value: 'authorization', label: 'Authorization' },
19673
19860
  { value: 'headers', label: 'Headers' },
19674
19861
  { value: 'body', label: 'Body' },
19675
19862
  { value: 'params', label: 'Params' },
19676
- { value: 'scripts', label: 'Scripts' },
19677
19863
  ];
19678
19864
  this.activePayloadTab = 'headers';
19679
19865
  /** Step 3: Response verification tabs */
@@ -19682,7 +19868,7 @@ class ApiEditStepComponent {
19682
19868
  { value: 'status', label: 'Status' },
19683
19869
  ];
19684
19870
  this.activeResponseVerificationTab = 'response-body';
19685
- /** Payload type for Body/Params/Scripts: raw, x-www-form-urlencoded, form-data */
19871
+ /** Payload type for Body/Params/Authorization: raw, x-www-form-urlencoded, form-data */
19686
19872
  this.payloadType = 'raw';
19687
19873
  /** Segment options for payload type (used by cqa-segment-control) */
19688
19874
  this.payloadTypeSegments = [
@@ -19699,7 +19885,7 @@ class ApiEditStepComponent {
19699
19885
  searchable: false,
19700
19886
  options: [...ApiEditStepComponent.DEFAULT_FORMAT_OPTIONS],
19701
19887
  };
19702
- /** Payload text area value for Body/Params/Scripts */
19888
+ /** Payload text area value for Body/Params/Authorization */
19703
19889
  this.payloadText = '';
19704
19890
  /** JSON parse error when format is JSON and payload is invalid; null when valid or not JSON. */
19705
19891
  this.payloadJsonError = null;
@@ -19797,16 +19983,16 @@ class ApiEditStepComponent {
19797
19983
  .filter((v) => v != null);
19798
19984
  }
19799
19985
  static toSelectOption(item) {
19800
- var _a, _b, _c, _d, _e, _f, _g, _h;
19986
+ var _a, _c, _d, _e, _f, _g, _h, _j;
19801
19987
  if (typeof item === 'string') {
19802
19988
  return { id: item, value: item, name: item, label: item };
19803
19989
  }
19804
19990
  const o = item;
19805
19991
  return {
19806
19992
  id: (_a = o.id) !== null && _a !== void 0 ? _a : o.value,
19807
- value: (_b = o.value) !== null && _b !== void 0 ? _b : o.id,
19808
- name: (_d = (_c = o.name) !== null && _c !== void 0 ? _c : o.label) !== null && _d !== void 0 ? _d : String((_e = o.value) !== null && _e !== void 0 ? _e : o.id),
19809
- label: (_g = (_f = o.label) !== null && _f !== void 0 ? _f : o.name) !== null && _g !== void 0 ? _g : String((_h = o.value) !== null && _h !== void 0 ? _h : o.id),
19993
+ value: (_c = o.value) !== null && _c !== void 0 ? _c : o.id,
19994
+ name: (_e = (_d = o.name) !== null && _d !== void 0 ? _d : o.label) !== null && _e !== void 0 ? _e : String((_f = o.value) !== null && _f !== void 0 ? _f : o.id),
19995
+ label: (_h = (_g = o.label) !== null && _g !== void 0 ? _g : o.name) !== null && _h !== void 0 ? _h : String((_j = o.value) !== null && _j !== void 0 ? _j : o.id),
19810
19996
  };
19811
19997
  }
19812
19998
  static getOptionValue(item) {
@@ -19828,15 +20014,39 @@ class ApiEditStepComponent {
19828
20014
  .map((e) => ApiEditStepComponent.getOptionValue(e))
19829
20015
  .filter((v) => v != null);
19830
20016
  }
20017
+ updateAuthTypeSelectConfig() {
20018
+ var _a;
20019
+ const options = ((_a = this.authTypeOptions) === null || _a === void 0 ? void 0 : _a.length) > 0
20020
+ ? this.authTypeOptions.map((a) => ApiEditStepComponent.toSelectOption(a))
20021
+ : [...ApiEditStepComponent.DEFAULT_AUTH_TYPE_OPTIONS];
20022
+ this.authTypeSelectConfig = Object.assign(Object.assign({}, this.authTypeSelectConfig), { options });
20023
+ }
20024
+ getAuthTypeValues() {
20025
+ var _a;
20026
+ const source = ((_a = this.authTypeOptions) === null || _a === void 0 ? void 0 : _a.length) > 0
20027
+ ? this.authTypeOptions
20028
+ : ApiEditStepComponent.DEFAULT_AUTH_TYPE_OPTIONS;
20029
+ return source
20030
+ .map((a) => ApiEditStepComponent.getOptionValue(a))
20031
+ .filter((v) => v != null);
20032
+ }
20033
+ /** Current auth type value (e.g. 'no-auth') for template */
20034
+ get selectedAuthType() {
20035
+ var _a, _c, _d, _e;
20036
+ const v = (_c = (_a = this.authTypeForm) === null || _a === void 0 ? void 0 : _a.get('authType')) === null || _c === void 0 ? void 0 : _c.value;
20037
+ if (v == null || v === '')
20038
+ return 'no-auth';
20039
+ return typeof v === 'object' ? ((_e = (_d = v === null || v === void 0 ? void 0 : v.value) !== null && _d !== void 0 ? _d : v === null || v === void 0 ? void 0 : v.id) !== null && _e !== void 0 ? _e : 'no-auth') : String(v);
20040
+ }
19831
20041
  /** Current HTTP method (from form or default: first of httpMethodOptions). Treats empty string as unset. */
19832
20042
  get selectedMethod() {
19833
- var _a, _b, _c, _d;
19834
- const value = (_b = (_a = this.methodForm) === null || _a === void 0 ? void 0 : _a.get('method')) === null || _b === void 0 ? void 0 : _b.value;
19835
- const firstValue = ((_c = this.httpMethodOptions) === null || _c === void 0 ? void 0 : _c.length)
20043
+ var _a, _c, _d, _e;
20044
+ const value = (_c = (_a = this.methodForm) === null || _a === void 0 ? void 0 : _a.get('method')) === null || _c === void 0 ? void 0 : _c.value;
20045
+ const firstValue = ((_d = this.httpMethodOptions) === null || _d === void 0 ? void 0 : _d.length)
19836
20046
  ? ApiEditStepComponent.getOptionValue(this.httpMethodOptions[0])
19837
20047
  : undefined;
19838
20048
  const resolved = value != null && value !== '' ? (typeof value === 'object' ? ApiEditStepComponent.getOptionValue(value) : String(value)) : undefined;
19839
- return (_d = resolved !== null && resolved !== void 0 ? resolved : firstValue) !== null && _d !== void 0 ? _d : 'GET';
20049
+ return (_e = resolved !== null && resolved !== void 0 ? resolved : firstValue) !== null && _e !== void 0 ? _e : 'GET';
19840
20050
  }
19841
20051
  set selectedMethod(v) {
19842
20052
  var _a;
@@ -19849,13 +20059,13 @@ class ApiEditStepComponent {
19849
20059
  }
19850
20060
  /** Current environment (from form or default: first of environmentOptions). Treats empty string as unset. */
19851
20061
  get selectedEnvironment() {
19852
- var _a, _b, _c, _d;
19853
- const value = (_b = (_a = this.environmentForm) === null || _a === void 0 ? void 0 : _a.get('environment')) === null || _b === void 0 ? void 0 : _b.value;
19854
- const firstValue = ((_c = this.environmentOptions) === null || _c === void 0 ? void 0 : _c.length)
20062
+ var _a, _c, _d, _e;
20063
+ const value = (_c = (_a = this.environmentForm) === null || _a === void 0 ? void 0 : _a.get('environment')) === null || _c === void 0 ? void 0 : _c.value;
20064
+ const firstValue = ((_d = this.environmentOptions) === null || _d === void 0 ? void 0 : _d.length)
19855
20065
  ? ApiEditStepComponent.getOptionValue(this.environmentOptions[0])
19856
20066
  : undefined;
19857
20067
  const resolved = value != null && value !== '' ? (typeof value === 'object' ? ApiEditStepComponent.getOptionValue(value) : String(value)) : undefined;
19858
- return (_d = resolved !== null && resolved !== void 0 ? resolved : firstValue) !== null && _d !== void 0 ? _d : 'Development';
20068
+ return (_e = resolved !== null && resolved !== void 0 ? resolved : firstValue) !== null && _e !== void 0 ? _e : 'Development';
19859
20069
  }
19860
20070
  set selectedEnvironment(v) {
19861
20071
  var _a;
@@ -19883,6 +20093,21 @@ class ApiEditStepComponent {
19883
20093
  : String(v)
19884
20094
  : '';
19885
20095
  }
20096
+ /** URL for the request. Getter/setter syncs query params with the Params tab (Postman-style). */
20097
+ get url() {
20098
+ return this._url;
20099
+ }
20100
+ set url(value) {
20101
+ const next = value !== null && value !== void 0 ? value : '';
20102
+ if (this._url === next)
20103
+ return;
20104
+ this._url = next;
20105
+ if (this.paramsFormArray) {
20106
+ this.paramsSyncingFromUrl = true;
20107
+ this.syncParamsFromUrl();
20108
+ this.paramsSyncingFromUrl = false;
20109
+ }
20110
+ }
19886
20111
  onPayloadTypeChange(val) {
19887
20112
  this.payloadType = val;
19888
20113
  }
@@ -19909,8 +20134,8 @@ class ApiEditStepComponent {
19909
20134
  }
19910
20135
  /** Whether current payload format is JSON (so we validate and show JSON editor behavior). */
19911
20136
  get isPayloadFormatJson() {
19912
- var _a, _b;
19913
- const format = (_b = (_a = this.payloadFormatForm) === null || _a === void 0 ? void 0 : _a.get('format')) === null || _b === void 0 ? void 0 : _b.value;
20137
+ var _a, _c;
20138
+ const format = (_c = (_a = this.payloadFormatForm) === null || _a === void 0 ? void 0 : _a.get('format')) === null || _c === void 0 ? void 0 : _c.value;
19914
20139
  return format === 'json';
19915
20140
  }
19916
20141
  /** Error messages for the payload textarea (red border + bottom line). */
@@ -19935,7 +20160,7 @@ class ApiEditStepComponent {
19935
20160
  this.onPayloadTextChange((_a = target === null || target === void 0 ? void 0 : target.value) !== null && _a !== void 0 ? _a : '');
19936
20161
  }
19937
20162
  onPayloadKeydown(event) {
19938
- var _a, _b;
20163
+ var _a, _c;
19939
20164
  if (!this.isPayloadFormatJson)
19940
20165
  return;
19941
20166
  const key = event.key;
@@ -19947,7 +20172,7 @@ class ApiEditStepComponent {
19947
20172
  return;
19948
20173
  event.preventDefault();
19949
20174
  const start = (_a = target.selectionStart) !== null && _a !== void 0 ? _a : 0;
19950
- const end = (_b = target.selectionEnd) !== null && _b !== void 0 ? _b : start;
20175
+ const end = (_c = target.selectionEnd) !== null && _c !== void 0 ? _c : start;
19951
20176
  const before = this.payloadText.slice(0, start);
19952
20177
  const after = this.payloadText.slice(end);
19953
20178
  const insertPos = start + 1;
@@ -19955,13 +20180,13 @@ class ApiEditStepComponent {
19955
20180
  this.payloadText = newValue;
19956
20181
  this.validatePayloadJson();
19957
20182
  setTimeout(() => {
19958
- var _a, _b;
19959
- (_b = (_a = this.payloadTextareaRef) === null || _a === void 0 ? void 0 : _a.nativeElement) === null || _b === void 0 ? void 0 : _b.setSelectionRange(insertPos, insertPos);
20183
+ var _a, _c;
20184
+ (_c = (_a = this.payloadTextareaRef) === null || _a === void 0 ? void 0 : _a.nativeElement) === null || _c === void 0 ? void 0 : _c.setSelectionRange(insertPos, insertPos);
19960
20185
  }, 0);
19961
20186
  }
19962
20187
  /** Validate payload when format is JSON; sets payloadJsonError or clears it. */
19963
20188
  validatePayloadJson() {
19964
- var _a, _b;
20189
+ var _a, _c;
19965
20190
  if (!this.isPayloadFormatJson) {
19966
20191
  this.payloadJsonError = null;
19967
20192
  return;
@@ -19981,7 +20206,7 @@ class ApiEditStepComponent {
19981
20206
  const { line, column } = this.positionToLineColumn(text, position);
19982
20207
  const lines = text.split(/\r?\n/);
19983
20208
  const lineIndex = Math.max(0, line - 1);
19984
- const lineContent = (_b = lines[lineIndex]) !== null && _b !== void 0 ? _b : '';
20209
+ const lineContent = (_c = lines[lineIndex]) !== null && _c !== void 0 ? _c : '';
19985
20210
  const excerpt = lineContent || ' ';
19986
20211
  const caretOffset = lineIndex === line - 1 ? Math.min(column - 1, lineContent.length) : 0;
19987
20212
  this.payloadJsonError = {
@@ -20016,8 +20241,8 @@ class ApiEditStepComponent {
20016
20241
  }
20017
20242
  /** Typed accessor for template (FormArray.controls is AbstractControl[]) */
20018
20243
  get headerRows() {
20019
- var _a, _b;
20020
- return ((_b = (_a = this.headersFormArray) === null || _a === void 0 ? void 0 : _a.controls) !== null && _b !== void 0 ? _b : []);
20244
+ var _a, _c;
20245
+ return ((_c = (_a = this.headersFormArray) === null || _a === void 0 ? void 0 : _a.controls) !== null && _c !== void 0 ? _c : []);
20021
20246
  }
20022
20247
  updateHeaderNameSelectConfig() {
20023
20248
  var _a;
@@ -20025,7 +20250,7 @@ class ApiEditStepComponent {
20025
20250
  ? this.headerNameOptions
20026
20251
  : ApiEditStepComponent.DEFAULT_HEADER_NAME_OPTIONS;
20027
20252
  const baseOptions = source.map((h) => ApiEditStepComponent.toSelectOption(h));
20028
- const baseValues = new Set(baseOptions.map((o) => { var _a, _b; return String((_b = (_a = o.value) !== null && _a !== void 0 ? _a : o.id) !== null && _b !== void 0 ? _b : '').trim(); }).filter(Boolean));
20253
+ const baseValues = new Set(baseOptions.map((o) => { var _a, _c; return String((_c = (_a = o.value) !== null && _a !== void 0 ? _a : o.id) !== null && _c !== void 0 ? _c : '').trim(); }).filter(Boolean));
20029
20254
  const currentNamesFromForm = this.getCurrentHeaderNamesFromForm();
20030
20255
  const extraOptions = [];
20031
20256
  for (const name of currentNamesFromForm) {
@@ -20040,13 +20265,13 @@ class ApiEditStepComponent {
20040
20265
  }
20041
20266
  /** Collects distinct non-empty header names currently in the headers form (for dynamic options). */
20042
20267
  getCurrentHeaderNamesFromForm() {
20043
- var _a, _b, _c;
20268
+ var _a, _c, _d;
20044
20269
  const names = [];
20045
20270
  const seen = new Set();
20046
- if (!((_b = (_a = this.headersFormArray) === null || _a === void 0 ? void 0 : _a.controls) === null || _b === void 0 ? void 0 : _b.length))
20271
+ if (!((_c = (_a = this.headersFormArray) === null || _a === void 0 ? void 0 : _a.controls) === null || _c === void 0 ? void 0 : _c.length))
20047
20272
  return names;
20048
20273
  for (const control of this.headersFormArray.controls) {
20049
- const name = (_c = control.get('name')) === null || _c === void 0 ? void 0 : _c.value;
20274
+ const name = (_d = control.get('name')) === null || _d === void 0 ? void 0 : _d.value;
20050
20275
  const str = name != null ? String(name).trim() : '';
20051
20276
  if (str && !seen.has(str)) {
20052
20277
  seen.add(str);
@@ -20056,16 +20281,20 @@ class ApiEditStepComponent {
20056
20281
  return names;
20057
20282
  }
20058
20283
  get keyValueRows() {
20059
- var _a, _b;
20060
- return ((_b = (_a = this.keyValueFormArray) === null || _a === void 0 ? void 0 : _a.controls) !== null && _b !== void 0 ? _b : []);
20284
+ var _a, _c;
20285
+ return ((_c = (_a = this.keyValueFormArray) === null || _a === void 0 ? void 0 : _a.controls) !== null && _c !== void 0 ? _c : []);
20061
20286
  }
20062
20287
  get keyTypeValueRows() {
20063
- var _a, _b;
20064
- return ((_b = (_a = this.keyTypeValueFormArray) === null || _a === void 0 ? void 0 : _a.controls) !== null && _b !== void 0 ? _b : []);
20288
+ var _a, _c;
20289
+ return ((_c = (_a = this.keyTypeValueFormArray) === null || _a === void 0 ? void 0 : _a.controls) !== null && _c !== void 0 ? _c : []);
20290
+ }
20291
+ get paramsRows() {
20292
+ var _a, _c;
20293
+ return ((_c = (_a = this.paramsFormArray) === null || _a === void 0 ? void 0 : _a.controls) !== null && _c !== void 0 ? _c : []);
20065
20294
  }
20066
20295
  get verificationRows() {
20067
- var _a, _b;
20068
- return ((_b = (_a = this.verificationFormArray) === null || _a === void 0 ? void 0 : _a.controls) !== null && _b !== void 0 ? _b : []);
20296
+ var _a, _c;
20297
+ return ((_c = (_a = this.verificationFormArray) === null || _a === void 0 ? void 0 : _a.controls) !== null && _c !== void 0 ? _c : []);
20069
20298
  }
20070
20299
  updateVerificationSelectConfig() {
20071
20300
  var _a;
@@ -20108,8 +20337,8 @@ class ApiEditStepComponent {
20108
20337
  return values.length > 0 ? values[0] : 'string';
20109
20338
  }
20110
20339
  get statusVerificationRows() {
20111
- var _a, _b;
20112
- return ((_b = (_a = this.statusVerificationFormArray) === null || _a === void 0 ? void 0 : _a.controls) !== null && _b !== void 0 ? _b : []);
20340
+ var _a, _c;
20341
+ return ((_c = (_a = this.statusVerificationFormArray) === null || _a === void 0 ? void 0 : _a.controls) !== null && _c !== void 0 ? _c : []);
20113
20342
  }
20114
20343
  updateStatusVerificationSelectConfig() {
20115
20344
  var _a;
@@ -20132,36 +20361,50 @@ class ApiEditStepComponent {
20132
20361
  return values.length > 0 ? values[0] : 'equals';
20133
20362
  }
20134
20363
  ngOnInit() {
20135
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
20364
+ var _a, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
20136
20365
  this.applyInitialStep(this.initialStep);
20137
20366
  this.updateMethodSelectConfig();
20138
20367
  this.updateHeaderNameSelectConfig();
20139
20368
  const firstMethodValue = ((_a = this.httpMethodOptions) === null || _a === void 0 ? void 0 : _a.length)
20140
20369
  ? ApiEditStepComponent.getOptionValue(this.httpMethodOptions[0])
20141
20370
  : undefined;
20142
- const defaultMethod = (_c = (_b = this.initialMethod) !== null && _b !== void 0 ? _b : firstMethodValue) !== null && _c !== void 0 ? _c : 'GET';
20143
- this.currentMethodValue = typeof defaultMethod === 'string' ? defaultMethod : ((_d = ApiEditStepComponent.getOptionValue(defaultMethod)) !== null && _d !== void 0 ? _d : '');
20371
+ const defaultMethod = (_d = (_c = this.initialMethod) !== null && _c !== void 0 ? _c : firstMethodValue) !== null && _d !== void 0 ? _d : 'GET';
20372
+ this.currentMethodValue = typeof defaultMethod === 'string' ? defaultMethod : ((_e = ApiEditStepComponent.getOptionValue(defaultMethod)) !== null && _e !== void 0 ? _e : '');
20144
20373
  this.methodForm = this.fb.group({
20145
20374
  method: [defaultMethod],
20146
20375
  });
20147
- const firstValue = ((_e = this.environmentOptions) === null || _e === void 0 ? void 0 : _e.length)
20376
+ const firstValue = ((_f = this.environmentOptions) === null || _f === void 0 ? void 0 : _f.length)
20148
20377
  ? ApiEditStepComponent.getOptionValue(this.environmentOptions[0])
20149
20378
  : undefined;
20150
- const defaultEnv = (_g = (_f = this.initialEnvironment) !== null && _f !== void 0 ? _f : firstValue) !== null && _g !== void 0 ? _g : 'Development';
20151
- this.currentEnvironmentValue = typeof defaultEnv === 'string' ? defaultEnv : ((_h = ApiEditStepComponent.getOptionValue(defaultEnv)) !== null && _h !== void 0 ? _h : '');
20379
+ const defaultEnv = (_h = (_g = this.initialEnvironment) !== null && _g !== void 0 ? _g : firstValue) !== null && _h !== void 0 ? _h : 'Development';
20380
+ this.currentEnvironmentValue = typeof defaultEnv === 'string' ? defaultEnv : ((_j = ApiEditStepComponent.getOptionValue(defaultEnv)) !== null && _j !== void 0 ? _j : '');
20152
20381
  this.environmentForm = this.fb.group({
20153
20382
  environment: [defaultEnv],
20154
20383
  });
20155
- this.environmentFormChangesSub = (_k = (_j = this.environmentForm.get('environment')) === null || _j === void 0 ? void 0 : _j.valueChanges) === null || _k === void 0 ? void 0 : _k.subscribe((v) => {
20384
+ this.updateAuthTypeSelectConfig();
20385
+ const firstAuthValue = this.getAuthTypeValues()[0];
20386
+ const defaultAuthType = (_l = (_k = this.initialAuthType) !== null && _k !== void 0 ? _k : firstAuthValue) !== null && _l !== void 0 ? _l : 'no-auth';
20387
+ this.authTypeForm = this.fb.group({
20388
+ authType: [defaultAuthType],
20389
+ });
20390
+ this.oauth2Form = this.fb.group({
20391
+ grantType: ['client_credentials'],
20392
+ accessTokenUrl: [''],
20393
+ clientId: [''],
20394
+ clientSecret: [''],
20395
+ scope: [''],
20396
+ clientAuthentication: ['basic'],
20397
+ });
20398
+ this.environmentFormChangesSub = (_o = (_m = this.environmentForm.get('environment')) === null || _m === void 0 ? void 0 : _m.valueChanges) === null || _o === void 0 ? void 0 : _o.subscribe((v) => {
20156
20399
  const s = v != null && v !== '' ? (typeof v === 'object' ? ApiEditStepComponent.getOptionValue(v) : String(v)) : '';
20157
20400
  this.currentEnvironmentValue = s !== null && s !== void 0 ? s : '';
20158
20401
  });
20159
- this.methodFormChangesSub = (_m = (_l = this.methodForm.get('method')) === null || _l === void 0 ? void 0 : _l.valueChanges) === null || _m === void 0 ? void 0 : _m.subscribe((v) => {
20402
+ this.methodFormChangesSub = (_q = (_p = this.methodForm.get('method')) === null || _p === void 0 ? void 0 : _p.valueChanges) === null || _q === void 0 ? void 0 : _q.subscribe((v) => {
20160
20403
  const s = v != null && v !== '' ? (typeof v === 'object' ? ApiEditStepComponent.getOptionValue(v) : String(v)) : '';
20161
20404
  this.currentMethodValue = s !== null && s !== void 0 ? s : '';
20162
20405
  });
20163
- this.buildHeadersFormArray((_o = this.initialHeaders) !== null && _o !== void 0 ? _o : [{ name: '', type: 'string', value: '' }]);
20164
- this.headerNameOptionsChangesSub = (_q = (_p = this.headersFormArray) === null || _p === void 0 ? void 0 : _p.valueChanges) === null || _q === void 0 ? void 0 : _q.subscribe(() => {
20406
+ this.buildHeadersFormArray((_r = this.initialHeaders) !== null && _r !== void 0 ? _r : [{ name: '', type: 'string', value: '' }]);
20407
+ this.headerNameOptionsChangesSub = (_t = (_s = this.headersFormArray) === null || _s === void 0 ? void 0 : _s.valueChanges) === null || _t === void 0 ? void 0 : _t.subscribe(() => {
20165
20408
  this.updateHeaderNameSelectConfig();
20166
20409
  this.headersChange.emit(this.headers);
20167
20410
  });
@@ -20170,23 +20413,33 @@ class ApiEditStepComponent {
20170
20413
  this.updateEnvironmentSelectConfig();
20171
20414
  this.updatePayloadFormatSelectConfig();
20172
20415
  const firstFormatValue = this.getFormatValues()[0];
20173
- const defaultFormat = (_s = (_r = this.initialFormat) !== null && _r !== void 0 ? _r : firstFormatValue) !== null && _s !== void 0 ? _s : 'json';
20416
+ const defaultFormat = (_v = (_u = this.initialFormat) !== null && _u !== void 0 ? _u : firstFormatValue) !== null && _v !== void 0 ? _v : 'json';
20174
20417
  this.payloadFormatForm = this.fb.group({ format: [defaultFormat] });
20175
20418
  this.buildKeyValueFormArray();
20176
20419
  this.buildKeyTypeValueFormArray();
20420
+ this.buildParamsFormArray();
20421
+ this.paramsFormArrayChangesSub = (_w = this.paramsFormArray.valueChanges) === null || _w === void 0 ? void 0 : _w.subscribe(() => this.syncUrlFromParams());
20422
+ if (this.initialUrl != null && this.initialUrl !== '') {
20423
+ this._url = this.initialUrl;
20424
+ this.syncParamsFromUrl();
20425
+ }
20426
+ // Initialize variableName from initialVariableName
20427
+ if (this.initialVariableName != null && this.initialVariableName !== '') {
20428
+ this.variableName = this.initialVariableName;
20429
+ }
20177
20430
  this.updateVerificationSelectConfig();
20178
20431
  this.updateVerificationDataTypeSelectConfig();
20179
20432
  this.buildVerificationFormArray();
20180
20433
  this.updateStatusVerificationSelectConfig();
20181
20434
  this.buildStatusVerificationFormArray();
20182
- this.methodChangesSub = (_u = (_t = this.methodForm.get('method')) === null || _t === void 0 ? void 0 : _t.valueChanges) === null || _u === void 0 ? void 0 : _u.subscribe((value) => {
20435
+ this.methodChangesSub = (_y = (_x = this.methodForm.get('method')) === null || _x === void 0 ? void 0 : _x.valueChanges) === null || _y === void 0 ? void 0 : _y.subscribe((value) => {
20183
20436
  const method = value != null ? String(value).toUpperCase() : '';
20184
20437
  if (METHODS_WITHOUT_BODY.includes(method) && this.activePayloadTab !== 'headers') {
20185
20438
  this.activePayloadTab = 'headers';
20186
20439
  this.cdr.detectChanges();
20187
20440
  }
20188
20441
  });
20189
- this.formatChangesSub = (_w = (_v = this.payloadFormatForm.get('format')) === null || _v === void 0 ? void 0 : _v.valueChanges) === null || _w === void 0 ? void 0 : _w.subscribe(() => {
20442
+ this.formatChangesSub = (_0 = (_z = this.payloadFormatForm.get('format')) === null || _z === void 0 ? void 0 : _z.valueChanges) === null || _0 === void 0 ? void 0 : _0.subscribe(() => {
20190
20443
  this.validatePayloadJson();
20191
20444
  });
20192
20445
  this.validatePayloadJson();
@@ -20195,12 +20448,13 @@ class ApiEditStepComponent {
20195
20448
  this.setupPayloadTextareaScrollSync();
20196
20449
  }
20197
20450
  ngOnDestroy() {
20198
- var _a, _b, _c, _d, _e;
20451
+ var _a, _c, _d, _e, _f, _g;
20199
20452
  (_a = this.methodChangesSub) === null || _a === void 0 ? void 0 : _a.unsubscribe();
20200
- (_b = this.formatChangesSub) === null || _b === void 0 ? void 0 : _b.unsubscribe();
20201
- (_c = this.headerNameOptionsChangesSub) === null || _c === void 0 ? void 0 : _c.unsubscribe();
20202
- (_d = this.environmentFormChangesSub) === null || _d === void 0 ? void 0 : _d.unsubscribe();
20203
- (_e = this.methodFormChangesSub) === null || _e === void 0 ? void 0 : _e.unsubscribe();
20453
+ (_c = this.formatChangesSub) === null || _c === void 0 ? void 0 : _c.unsubscribe();
20454
+ (_d = this.headerNameOptionsChangesSub) === null || _d === void 0 ? void 0 : _d.unsubscribe();
20455
+ (_e = this.environmentFormChangesSub) === null || _e === void 0 ? void 0 : _e.unsubscribe();
20456
+ (_f = this.methodFormChangesSub) === null || _f === void 0 ? void 0 : _f.unsubscribe();
20457
+ (_g = this.paramsFormArrayChangesSub) === null || _g === void 0 ? void 0 : _g.unsubscribe();
20204
20458
  }
20205
20459
  /** Sync line numbers column scroll with payload textarea scroll (Postman-style). */
20206
20460
  setupPayloadTextareaScrollSync() {
@@ -20216,6 +20470,9 @@ class ApiEditStepComponent {
20216
20470
  textarea.addEventListener('scroll', () => {
20217
20471
  lineNumbersEl.scrollTop = textarea.scrollTop;
20218
20472
  });
20473
+ lineNumbersEl.addEventListener('scroll', () => {
20474
+ textarea.scrollTop = lineNumbersEl.scrollTop;
20475
+ });
20219
20476
  }, 0);
20220
20477
  }
20221
20478
  buildKeyValueFormArray(rows) {
@@ -20228,6 +20485,111 @@ class ApiEditStepComponent {
20228
20485
  const groups = initial.map((r) => this.fb.group({ key: [r.key], type: [r.type], value: [r.value] }));
20229
20486
  this.keyTypeValueFormArray = this.fb.array(groups);
20230
20487
  }
20488
+ buildParamsFormArray(rows) {
20489
+ const initial = rows !== null && rows !== void 0 ? rows : [{ key: '', value: '' }];
20490
+ const groups = initial.map((r) => this.fb.group({ key: [r.key], value: [r.value] }));
20491
+ if (this.paramsFormArray) {
20492
+ this.paramsFormArray.clear();
20493
+ groups.forEach((g) => this.paramsFormArray.push(g));
20494
+ }
20495
+ else {
20496
+ this.paramsFormArray = this.fb.array(groups);
20497
+ }
20498
+ }
20499
+ /** Parse URL into base (without query/fragment) and query key-value pairs. Preserves relative URLs. */
20500
+ parseQueryParamsFromUrl(urlStr) {
20501
+ const empty = { baseUrl: urlStr, rows: [{ key: '', value: '' }] };
20502
+ if (!urlStr || !urlStr.trim())
20503
+ return empty;
20504
+ try {
20505
+ const isAbsolute = /^https?:\/\//i.test(urlStr.trim());
20506
+ const url = new URL(urlStr, 'http://localhost');
20507
+ const baseUrl = isAbsolute ? url.origin + url.pathname : url.pathname;
20508
+ const rows = [];
20509
+ url.searchParams.forEach((value, key) => {
20510
+ rows.push({ key, value });
20511
+ });
20512
+ if (rows.length === 0)
20513
+ rows.push({ key: '', value: '' });
20514
+ return { baseUrl, rows };
20515
+ }
20516
+ catch (_a) {
20517
+ return empty;
20518
+ }
20519
+ }
20520
+ /** Get base URL (without query/fragment) for building URL from params. Preserves relative URLs. */
20521
+ getBaseUrl(urlStr) {
20522
+ if (!urlStr || !urlStr.trim())
20523
+ return urlStr;
20524
+ try {
20525
+ const isAbsolute = /^https?:\/\//i.test(urlStr.trim());
20526
+ const url = new URL(urlStr, 'http://localhost');
20527
+ return isAbsolute ? url.origin + url.pathname : url.pathname;
20528
+ }
20529
+ catch (_a) {
20530
+ return urlStr;
20531
+ }
20532
+ }
20533
+ /** Parse application/x-www-form-urlencoded body (key=value&...) into key-value rows. */
20534
+ parseFormUrlEncodedBody(body) {
20535
+ const trimmed = (body !== null && body !== void 0 ? body : '').trim();
20536
+ if (!trimmed)
20537
+ return [];
20538
+ try {
20539
+ const params = new URLSearchParams(trimmed);
20540
+ const rows = [];
20541
+ params.forEach((value, key) => rows.push({ key, value }));
20542
+ return rows;
20543
+ }
20544
+ catch (_a) {
20545
+ return [];
20546
+ }
20547
+ }
20548
+ /**
20549
+ * If form body has a single key whose value is URL-decoded JSON, return it pretty-printed for Raw body.
20550
+ * Otherwise return null (caller keeps x-www-form-urlencoded view).
20551
+ */
20552
+ tryFormBodyValueAsRawJson(rows) {
20553
+ var _a;
20554
+ if (rows.length !== 1 || !((_a = rows[0].value) === null || _a === void 0 ? void 0 : _a.trim()))
20555
+ return null;
20556
+ const value = rows[0].value.trim();
20557
+ if (!(value.startsWith('{') || value.startsWith('[')))
20558
+ return null;
20559
+ try {
20560
+ const parsed = JSON.parse(value);
20561
+ return JSON.stringify(parsed, null, 2);
20562
+ }
20563
+ catch (_c) {
20564
+ return null;
20565
+ }
20566
+ }
20567
+ /** Update Params table from current URL query string (Postman-style). */
20568
+ syncParamsFromUrl() {
20569
+ const { baseUrl: _b, rows } = this.parseQueryParamsFromUrl(this._url);
20570
+ this.buildParamsFormArray(rows);
20571
+ this.cdr.markForCheck();
20572
+ }
20573
+ /** Update URL query string from Params table (Postman-style). */
20574
+ syncUrlFromParams() {
20575
+ var _a, _c, _d, _e;
20576
+ if (this.paramsSyncingFromUrl || !this.paramsFormArray)
20577
+ return;
20578
+ const baseUrl = this.getBaseUrl(this._url);
20579
+ const params = new URLSearchParams();
20580
+ for (const c of this.paramsFormArray.controls) {
20581
+ const key = ((_c = (_a = c.get('key')) === null || _a === void 0 ? void 0 : _a.value) !== null && _c !== void 0 ? _c : '').trim();
20582
+ const value = (_e = (_d = c.get('value')) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : '';
20583
+ if (key !== '')
20584
+ params.set(key, value);
20585
+ }
20586
+ const queryString = params.toString();
20587
+ const newUrl = queryString ? `${baseUrl}?${queryString}` : baseUrl;
20588
+ if (this._url !== newUrl) {
20589
+ this._url = newUrl;
20590
+ this.cdr.markForCheck();
20591
+ }
20592
+ }
20231
20593
  buildVerificationFormArray(rows) {
20232
20594
  const defaultVerification = this.getDefaultVerification();
20233
20595
  const defaultDataType = this.getDefaultDataType();
@@ -20262,16 +20624,154 @@ class ApiEditStepComponent {
20262
20624
  this.headersFormArray = this.fb.array(groups);
20263
20625
  }
20264
20626
  }
20265
- /** Handler: show import cURL panel (called when user clicks "Import API cURL"). */
20627
+ /** Reset all three steps and all entered data to initial/default state. Used when user cancels on step 1. */
20628
+ resetAllStepsAndData() {
20629
+ var _a, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
20630
+ this.currentStep = 1;
20631
+ const firstMethodValue = ((_a = this.httpMethodOptions) === null || _a === void 0 ? void 0 : _a.length)
20632
+ ? ApiEditStepComponent.getOptionValue(this.httpMethodOptions[0])
20633
+ : undefined;
20634
+ const defaultMethod = (_d = (_c = this.initialMethod) !== null && _c !== void 0 ? _c : firstMethodValue) !== null && _d !== void 0 ? _d : 'GET';
20635
+ const methodVal = typeof defaultMethod === 'string' ? defaultMethod : ((_e = ApiEditStepComponent.getOptionValue(defaultMethod)) !== null && _e !== void 0 ? _e : '');
20636
+ this.currentMethodValue = methodVal !== null && methodVal !== void 0 ? methodVal : '';
20637
+ if (this.methodForm)
20638
+ this.methodForm.patchValue({ method: defaultMethod });
20639
+ const firstEnvValue = ((_f = this.environmentOptions) === null || _f === void 0 ? void 0 : _f.length)
20640
+ ? ApiEditStepComponent.getOptionValue(this.environmentOptions[0])
20641
+ : undefined;
20642
+ const defaultEnv = (_h = (_g = this.initialEnvironment) !== null && _g !== void 0 ? _g : firstEnvValue) !== null && _h !== void 0 ? _h : 'Development';
20643
+ const envVal = typeof defaultEnv === 'string' ? defaultEnv : ((_j = ApiEditStepComponent.getOptionValue(defaultEnv)) !== null && _j !== void 0 ? _j : '');
20644
+ this.currentEnvironmentValue = envVal !== null && envVal !== void 0 ? envVal : '';
20645
+ if (this.environmentForm)
20646
+ this.environmentForm.patchValue({ environment: defaultEnv });
20647
+ this.url = (_k = this.initialUrl) !== null && _k !== void 0 ? _k : '';
20648
+ this.buildHeadersFormArray((_l = this.initialHeaders) !== null && _l !== void 0 ? _l : [{ name: '', type: 'string', value: '' }]);
20649
+ this.updateHeaderNameSelectConfig();
20650
+ this.headersChange.emit(this.headers);
20651
+ this.bodyView = 'headers';
20652
+ this.activePayloadTab = 'headers';
20653
+ this.payloadType = 'raw';
20654
+ this.payloadText = '';
20655
+ this.payloadJsonError = null;
20656
+ const defaultFormat = (_o = (_m = this.initialFormat) !== null && _m !== void 0 ? _m : this.getFormatValues()[0]) !== null && _o !== void 0 ? _o : 'json';
20657
+ if (this.payloadFormatForm)
20658
+ this.payloadFormatForm.patchValue({ format: defaultFormat });
20659
+ this.buildKeyValueFormArray();
20660
+ this.buildKeyTypeValueFormArray();
20661
+ this.buildParamsFormArray();
20662
+ this.importCurlControl.setValue('');
20663
+ this.variableName = '';
20664
+ this.variableNameError = '';
20665
+ this.buildVerificationFormArray();
20666
+ this.buildStatusVerificationFormArray();
20667
+ this.activeResponseVerificationTab = 'response-body';
20668
+ this.validatePayloadJson();
20669
+ this.cdr.detectChanges();
20670
+ }
20671
+ /** Handler: show import cURL panel (called when user clicks "Import API cURL"). Resets textarea so it is cleared each time. */
20266
20672
  openImportCurlPanel() {
20673
+ this.importCurlControl.setValue('');
20267
20674
  this.bodyView = 'import-curl';
20268
20675
  this.cdr.detectChanges();
20269
20676
  }
20270
- /** Handler: emit cURL value from control and close panel. Called when user clicks Import button. */
20677
+ /** Reset URL, method, headers, body, and params to empty/default before applying imported cURL. */
20678
+ resetRequestFieldsBeforeCurlImport() {
20679
+ var _a, _c, _d, _e, _f, _g, _h;
20680
+ const firstMethodValue = ((_a = this.httpMethodOptions) === null || _a === void 0 ? void 0 : _a.length)
20681
+ ? ApiEditStepComponent.getOptionValue(this.httpMethodOptions[0])
20682
+ : undefined;
20683
+ const defaultMethod = (_d = (_c = this.initialMethod) !== null && _c !== void 0 ? _c : firstMethodValue) !== null && _d !== void 0 ? _d : 'GET';
20684
+ this.selectedMethod = typeof defaultMethod === 'string' ? defaultMethod : (_f = ((_e = ApiEditStepComponent.getOptionValue(defaultMethod)) !== null && _e !== void 0 ? _e : '')) !== null && _f !== void 0 ? _f : 'GET';
20685
+ this.currentMethodValue = this.selectedMethod;
20686
+ if (this.methodForm)
20687
+ this.methodForm.patchValue({ method: defaultMethod });
20688
+ this.url = '';
20689
+ this.buildHeadersFormArray([{ name: '', type: 'string', value: '' }]);
20690
+ this.updateHeaderNameSelectConfig();
20691
+ this.headersChange.emit(this.headers);
20692
+ this.payloadType = 'raw';
20693
+ this.payloadText = '';
20694
+ this.payloadJsonError = null;
20695
+ const defaultFormat = (_h = (_g = this.initialFormat) !== null && _g !== void 0 ? _g : this.getFormatValues()[0]) !== null && _h !== void 0 ? _h : 'json';
20696
+ if (this.payloadFormatForm)
20697
+ this.payloadFormatForm.patchValue({ format: defaultFormat });
20698
+ this.buildKeyValueFormArray([{ key: '', value: '' }]);
20699
+ this.buildKeyTypeValueFormArray([{ key: '', type: 'text', value: '' }]);
20700
+ this.buildParamsFormArray([{ key: '', value: '' }]);
20701
+ this.validatePayloadJson();
20702
+ this.cdr.detectChanges();
20703
+ }
20704
+ /** Handler: parse cURL from control, bind to form fields, emit and close panel. Called when user clicks Import button. */
20271
20705
  onImportCurlConfirm() {
20272
- var _a;
20706
+ var _a, _c, _d, _e, _f;
20273
20707
  const value = (_a = this.importCurlControl.value) !== null && _a !== void 0 ? _a : '';
20274
- this.importCurl.emit(typeof value === 'string' ? value : '');
20708
+ const curlStr = typeof value === 'string' ? value : '';
20709
+ this.importCurl.emit(curlStr);
20710
+ this.resetRequestFieldsBeforeCurlImport();
20711
+ const parsed = parseCurl(curlStr);
20712
+ if (parsed) {
20713
+ const methodValue = parsed.method && this.getMethodValues().includes(parsed.method)
20714
+ ? parsed.method
20715
+ : parsed.method || 'GET';
20716
+ this.selectedMethod = methodValue;
20717
+ this.currentMethodValue = methodValue;
20718
+ if (parsed.url)
20719
+ this.url = parsed.url;
20720
+ // Bind Authorization header to Authorization section when present (Bearer or other scheme)
20721
+ let headerRows = parsed.headers;
20722
+ const authHeader = headerRows.find((h) => h.name.toLowerCase() === 'authorization');
20723
+ if ((_c = authHeader === null || authHeader === void 0 ? void 0 : authHeader.value) === null || _c === void 0 ? void 0 : _c.trim()) {
20724
+ const authValue = authHeader.value.trim();
20725
+ const bearerMatch = /^Bearer\s+(.+)$/i.exec(authValue);
20726
+ if (bearerMatch) {
20727
+ const token = bearerMatch[1].trim();
20728
+ if (this.getAuthTypeValues().includes('bearer') && this.authTypeForm) {
20729
+ this.authTypeForm.patchValue({ authType: 'bearer' });
20730
+ this.bearerToken = token;
20731
+ }
20732
+ headerRows = headerRows.filter((h) => h.name.toLowerCase() !== 'authorization');
20733
+ }
20734
+ }
20735
+ headerRows = headerRows.length > 0 ? headerRows : [{ name: '', type: 'string', value: '' }];
20736
+ this.buildHeadersFormArray(headerRows);
20737
+ this.updateHeaderNameSelectConfig();
20738
+ this.headersChange.emit(this.headers);
20739
+ if (parsed.body) {
20740
+ const contentType = (_f = (_e = (_d = parsed.headers
20741
+ .find((h) => h.name.toLowerCase() === 'content-type')) === null || _d === void 0 ? void 0 : _d.value) === null || _e === void 0 ? void 0 : _e.toLowerCase()) !== null && _f !== void 0 ? _f : '';
20742
+ const isFormUrlEncoded = contentType.includes('application/x-www-form-urlencoded');
20743
+ if (isFormUrlEncoded) {
20744
+ const rows = this.parseFormUrlEncodedBody(parsed.body);
20745
+ this.buildKeyValueFormArray(rows.length > 0 ? rows : [{ key: '', value: '' }]);
20746
+ const decodedAsJson = this.tryFormBodyValueAsRawJson(rows);
20747
+ if (decodedAsJson != null) {
20748
+ this.payloadType = 'raw';
20749
+ this.payloadText = decodedAsJson;
20750
+ if (this.payloadFormatForm)
20751
+ this.payloadFormatForm.patchValue({ format: 'json' });
20752
+ this.validatePayloadJson();
20753
+ this.payloadJsonError = null;
20754
+ }
20755
+ else {
20756
+ this.payloadType = 'x-www-form-urlencoded';
20757
+ this.payloadText = '';
20758
+ this.payloadJsonError = null;
20759
+ }
20760
+ }
20761
+ else {
20762
+ this.payloadText = parsed.body;
20763
+ this.validatePayloadJson();
20764
+ const trimmed = parsed.body.trim();
20765
+ if ((trimmed.startsWith('{') && trimmed.endsWith('}')) || (trimmed.startsWith('[') && trimmed.endsWith(']'))) {
20766
+ const formatValues = this.getFormatValues();
20767
+ if (formatValues.includes('json') && this.payloadFormatForm) {
20768
+ this.payloadFormatForm.patchValue({ format: 'json' });
20769
+ }
20770
+ }
20771
+ }
20772
+ }
20773
+ this.cdr.detectChanges();
20774
+ }
20275
20775
  this.closeImportCurlPanel();
20276
20776
  }
20277
20777
  /** Handler: emit cancel and close panel. Called when user clicks Cancel in import cURL panel. */
@@ -20303,9 +20803,15 @@ class ApiEditStepComponent {
20303
20803
  this.setStep(this.currentStep - 1);
20304
20804
  }
20305
20805
  else {
20806
+ this.resetAllStepsAndData();
20306
20807
  this.back.emit();
20307
20808
  }
20308
20809
  }
20810
+ /** Called when user clicks the Cancel button (step 1). Emits cancel then runs normal back flow. */
20811
+ onCancel() {
20812
+ this.cancel.emit();
20813
+ this.onBack();
20814
+ }
20309
20815
  onNext() {
20310
20816
  var _a;
20311
20817
  if (this.currentStep === 2 && !((_a = this.variableName) === null || _a === void 0 ? void 0 : _a.trim())) {
@@ -20360,6 +20866,15 @@ class ApiEditStepComponent {
20360
20866
  trackByKeyTypeValue(index) {
20361
20867
  return index;
20362
20868
  }
20869
+ addParamsRow() {
20870
+ this.paramsFormArray.push(this.fb.group({ key: [''], value: [''] }));
20871
+ }
20872
+ removeParamsRow(index) {
20873
+ this.paramsFormArray.removeAt(index);
20874
+ }
20875
+ trackByParams(index) {
20876
+ return index;
20877
+ }
20363
20878
  addVerificationRow() {
20364
20879
  this.verificationFormArray.push(this.fb.group({
20365
20880
  jsonPath: [''],
@@ -20405,21 +20920,25 @@ class ApiEditStepComponent {
20405
20920
  }
20406
20921
  /** Minimal payload when getCreatePayload throws (so create always emits). */
20407
20922
  getCreatePayloadFallback() {
20408
- var _a, _b, _c;
20923
+ var _a, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
20924
+ const authType = this.selectedAuthType;
20925
+ const bearerToken = authType === 'bearer' ? ((_a = this.bearerToken) !== null && _a !== void 0 ? _a : '') : undefined;
20926
+ let oauth2;
20927
+ if (authType === 'oauth2' && this.oauth2Form) {
20928
+ const grantType = ApiEditStepComponent.getControlValue(this.oauth2Form.get('grantType'));
20929
+ const clientAuth = ApiEditStepComponent.getControlValue(this.oauth2Form.get('clientAuthentication'));
20930
+ oauth2 = {
20931
+ grantType: grantType !== '' ? grantType : 'client_credentials',
20932
+ accessTokenUrl: ((_d = (_c = this.oauth2Form.get('accessTokenUrl')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : ''),
20933
+ clientId: ((_f = (_e = this.oauth2Form.get('clientId')) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : ''),
20934
+ clientSecret: ((_h = (_g = this.oauth2Form.get('clientSecret')) === null || _g === void 0 ? void 0 : _g.value) !== null && _h !== void 0 ? _h : ''),
20935
+ scope: ((_k = (_j = this.oauth2Form.get('scope')) === null || _j === void 0 ? void 0 : _j.value) !== null && _k !== void 0 ? _k : ''),
20936
+ clientAuthentication: clientAuth !== '' ? clientAuth : 'basic',
20937
+ };
20938
+ }
20409
20939
  return {
20410
- step1: {
20411
- environment: '',
20412
- method: '',
20413
- url: (_a = this.url) !== null && _a !== void 0 ? _a : '',
20414
- headers: [],
20415
- activePayloadTab: this.activePayloadTab,
20416
- payloadType: this.payloadType,
20417
- payloadFormat: '',
20418
- payloadText: (_b = this.payloadText) !== null && _b !== void 0 ? _b : '',
20419
- keyValueRows: [],
20420
- keyTypeValueRows: [],
20421
- },
20422
- step2: { variableName: (_c = this.variableName) !== null && _c !== void 0 ? _c : '' },
20940
+ step1: Object.assign(Object.assign(Object.assign({ environment: '', method: '', url: (_l = this.url) !== null && _l !== void 0 ? _l : '', headers: [], authType }, (bearerToken !== undefined && { bearerToken })), (oauth2 !== undefined && { oauth2 })), { activePayloadTab: this.activePayloadTab, payloadType: this.payloadType, payloadFormat: '', payloadText: (_m = this.payloadText) !== null && _m !== void 0 ? _m : '', keyValueRows: [], keyTypeValueRows: [], paramsRows: [] }),
20941
+ step2: { variableName: (_o = this.variableName) !== null && _o !== void 0 ? _o : '' },
20423
20942
  step3: {
20424
20943
  activeResponseVerificationTab: this.activeResponseVerificationTab,
20425
20944
  responseBodyVerifications: [],
@@ -20437,62 +20956,77 @@ class ApiEditStepComponent {
20437
20956
  }
20438
20957
  /** Build full create payload: environment, HTTP method, URL, headers, body (step1), variable name (step2), verifications (step3). */
20439
20958
  getCreatePayload() {
20440
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
20959
+ var _a, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
20441
20960
  const envFromForm = ApiEditStepComponent.getControlValue((_a = this.environmentForm) === null || _a === void 0 ? void 0 : _a.get('environment'));
20442
20961
  const environment = envFromForm !== '' ? envFromForm : (this.currentEnvironmentValue !== '' ? this.currentEnvironmentValue : this.selectedEnvironment);
20443
- const methodFromForm = ApiEditStepComponent.getControlValue((_b = this.methodForm) === null || _b === void 0 ? void 0 : _b.get('method'));
20962
+ const methodFromForm = ApiEditStepComponent.getControlValue((_c = this.methodForm) === null || _c === void 0 ? void 0 : _c.get('method'));
20444
20963
  const method = methodFromForm !== '' ? methodFromForm : (this.currentMethodValue !== '' ? this.currentMethodValue : this.selectedMethod);
20445
- const format = (_e = (_d = (_c = this.payloadFormatForm) === null || _c === void 0 ? void 0 : _c.get('format')) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : '';
20964
+ const format = (_f = (_e = (_d = this.payloadFormatForm) === null || _d === void 0 ? void 0 : _d.get('format')) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : '';
20446
20965
  const keyValueFormArray = this.keyValueFormArray;
20447
- const keyValueRows = ((_f = keyValueFormArray === null || keyValueFormArray === void 0 ? void 0 : keyValueFormArray.controls) !== null && _f !== void 0 ? _f : []).map((c) => {
20448
- var _a, _b, _c, _d;
20966
+ const keyValueRows = ((_g = keyValueFormArray === null || keyValueFormArray === void 0 ? void 0 : keyValueFormArray.controls) !== null && _g !== void 0 ? _g : []).map((c) => {
20967
+ var _a, _c, _d, _e;
20449
20968
  return ({
20450
- key: (_b = (_a = c.get('key')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '',
20451
- value: (_d = (_c = c.get('value')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : '',
20969
+ key: (_c = (_a = c.get('key')) === null || _a === void 0 ? void 0 : _a.value) !== null && _c !== void 0 ? _c : '',
20970
+ value: (_e = (_d = c.get('value')) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : '',
20452
20971
  });
20453
20972
  });
20454
20973
  const keyTypeValueFormArray = this.keyTypeValueFormArray;
20455
- const keyTypeValueRows = ((_g = keyTypeValueFormArray === null || keyTypeValueFormArray === void 0 ? void 0 : keyTypeValueFormArray.controls) !== null && _g !== void 0 ? _g : []).map((c) => {
20456
- var _a, _b, _c, _d, _e, _f;
20974
+ const keyTypeValueRows = ((_h = keyTypeValueFormArray === null || keyTypeValueFormArray === void 0 ? void 0 : keyTypeValueFormArray.controls) !== null && _h !== void 0 ? _h : []).map((c) => {
20975
+ var _a, _c, _d, _e, _f, _g;
20457
20976
  return ({
20458
- key: (_b = (_a = c.get('key')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '',
20459
- type: (_d = (_c = c.get('type')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : 'text',
20460
- value: (_f = (_e = c.get('value')) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : '',
20977
+ key: (_c = (_a = c.get('key')) === null || _a === void 0 ? void 0 : _a.value) !== null && _c !== void 0 ? _c : '',
20978
+ type: (_e = (_d = c.get('type')) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : 'text',
20979
+ value: (_g = (_f = c.get('value')) === null || _f === void 0 ? void 0 : _f.value) !== null && _g !== void 0 ? _g : '',
20980
+ });
20981
+ });
20982
+ const paramsFormArray = this.paramsFormArray;
20983
+ const paramsRows = ((_j = paramsFormArray === null || paramsFormArray === void 0 ? void 0 : paramsFormArray.controls) !== null && _j !== void 0 ? _j : []).map((c) => {
20984
+ var _a, _c, _d, _e;
20985
+ return ({
20986
+ key: (_c = (_a = c.get('key')) === null || _a === void 0 ? void 0 : _a.value) !== null && _c !== void 0 ? _c : '',
20987
+ value: (_e = (_d = c.get('value')) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : '',
20461
20988
  });
20462
20989
  });
20463
20990
  const verificationFormArray = this.verificationFormArray;
20464
- const responseBodyVerifications = ((_h = verificationFormArray === null || verificationFormArray === void 0 ? void 0 : verificationFormArray.controls) !== null && _h !== void 0 ? _h : []).map((c) => {
20465
- var _a, _b, _c, _d, _e, _f, _g, _h;
20991
+ const responseBodyVerifications = ((_k = verificationFormArray === null || verificationFormArray === void 0 ? void 0 : verificationFormArray.controls) !== null && _k !== void 0 ? _k : []).map((c) => {
20992
+ var _a, _c, _d, _e, _f, _g, _h, _j;
20466
20993
  return ({
20467
- jsonPath: (_b = (_a = c.get('jsonPath')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '',
20468
- verification: (_d = (_c = c.get('verification')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : '',
20469
- dataType: (_f = (_e = c.get('dataType')) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : '',
20470
- expectedValue: (_h = (_g = c.get('expectedValue')) === null || _g === void 0 ? void 0 : _g.value) !== null && _h !== void 0 ? _h : '',
20994
+ jsonPath: (_c = (_a = c.get('jsonPath')) === null || _a === void 0 ? void 0 : _a.value) !== null && _c !== void 0 ? _c : '',
20995
+ verification: (_e = (_d = c.get('verification')) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : '',
20996
+ dataType: (_g = (_f = c.get('dataType')) === null || _f === void 0 ? void 0 : _f.value) !== null && _g !== void 0 ? _g : '',
20997
+ expectedValue: (_j = (_h = c.get('expectedValue')) === null || _h === void 0 ? void 0 : _h.value) !== null && _j !== void 0 ? _j : '',
20471
20998
  });
20472
20999
  });
20473
21000
  const statusVerificationFormArray = this.statusVerificationFormArray;
20474
- const statusVerifications = ((_j = statusVerificationFormArray === null || statusVerificationFormArray === void 0 ? void 0 : statusVerificationFormArray.controls) !== null && _j !== void 0 ? _j : []).map((c) => {
20475
- var _a, _b, _c, _d;
21001
+ const statusVerifications = ((_l = statusVerificationFormArray === null || statusVerificationFormArray === void 0 ? void 0 : statusVerificationFormArray.controls) !== null && _l !== void 0 ? _l : []).map((c) => {
21002
+ var _a, _c, _d, _e;
20476
21003
  return ({
20477
- verification: (_b = (_a = c.get('verification')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '',
20478
- expectedValue: (_d = (_c = c.get('expectedValue')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : '',
21004
+ verification: (_c = (_a = c.get('verification')) === null || _a === void 0 ? void 0 : _a.value) !== null && _c !== void 0 ? _c : '',
21005
+ expectedValue: (_e = (_d = c.get('expectedValue')) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : '',
20479
21006
  });
20480
21007
  });
21008
+ const authType = this.selectedAuthType;
21009
+ const bearerToken = authType === 'bearer' ? ((_m = this.bearerToken) !== null && _m !== void 0 ? _m : '') : undefined;
21010
+ let oauth2;
21011
+ if (authType === 'oauth2' && this.oauth2Form) {
21012
+ const grantType = ApiEditStepComponent.getControlValue(this.oauth2Form.get('grantType'));
21013
+ const clientAuth = ApiEditStepComponent.getControlValue(this.oauth2Form.get('clientAuthentication'));
21014
+ oauth2 = {
21015
+ grantType: grantType !== '' ? grantType : 'client_credentials',
21016
+ accessTokenUrl: ((_p = (_o = this.oauth2Form.get('accessTokenUrl')) === null || _o === void 0 ? void 0 : _o.value) !== null && _p !== void 0 ? _p : ''),
21017
+ clientId: ((_r = (_q = this.oauth2Form.get('clientId')) === null || _q === void 0 ? void 0 : _q.value) !== null && _r !== void 0 ? _r : ''),
21018
+ clientSecret: ((_t = (_s = this.oauth2Form.get('clientSecret')) === null || _s === void 0 ? void 0 : _s.value) !== null && _t !== void 0 ? _t : ''),
21019
+ scope: ((_v = (_u = this.oauth2Form.get('scope')) === null || _u === void 0 ? void 0 : _u.value) !== null && _v !== void 0 ? _v : ''),
21020
+ clientAuthentication: clientAuth !== '' ? clientAuth : 'basic',
21021
+ };
21022
+ }
20481
21023
  return {
20482
- step1: {
20483
- environment,
20484
- method,
20485
- url: (_k = this.url) !== null && _k !== void 0 ? _k : '',
20486
- headers: this.headers,
20487
- activePayloadTab: this.activePayloadTab,
20488
- payloadType: this.payloadType,
20489
- payloadFormat: format,
20490
- payloadText: (_l = this.payloadText) !== null && _l !== void 0 ? _l : '',
20491
- keyValueRows,
21024
+ step1: Object.assign(Object.assign(Object.assign({ environment,
21025
+ method, url: (_w = this.url) !== null && _w !== void 0 ? _w : '', headers: this.headers, authType }, (bearerToken !== undefined && { bearerToken })), (oauth2 !== undefined && { oauth2 })), { activePayloadTab: this.activePayloadTab, payloadType: this.payloadType, payloadFormat: format, payloadText: (_x = this.payloadText) !== null && _x !== void 0 ? _x : '', keyValueRows,
20492
21026
  keyTypeValueRows,
20493
- },
21027
+ paramsRows }),
20494
21028
  step2: {
20495
- variableName: (_m = this.variableName) !== null && _m !== void 0 ? _m : '',
21029
+ variableName: (_y = this.variableName) !== null && _y !== void 0 ? _y : '',
20496
21030
  },
20497
21031
  step3: {
20498
21032
  activeResponseVerificationTab: this.activeResponseVerificationTab,
@@ -20506,25 +21040,25 @@ class ApiEditStepComponent {
20506
21040
  if (!this.headersFormArray)
20507
21041
  return [];
20508
21042
  return this.headersFormArray.controls.map((c) => {
20509
- var _a, _b, _c, _d;
21043
+ var _a, _c, _d, _e;
20510
21044
  return ({
20511
- name: (_b = (_a = c.get('name')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '',
21045
+ name: (_c = (_a = c.get('name')) === null || _a === void 0 ? void 0 : _a.value) !== null && _c !== void 0 ? _c : '',
20512
21046
  type: 'string',
20513
- value: (_d = (_c = c.get('value')) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : '',
21047
+ value: (_e = (_d = c.get('value')) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : '',
20514
21048
  });
20515
21049
  });
20516
21050
  }
20517
21051
  ngOnChanges(changes) {
20518
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
21052
+ var _a, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
20519
21053
  if (((_a = changes['initialMethod']) === null || _a === void 0 ? void 0 : _a.currentValue) != null && this.methodForm) {
20520
21054
  const v = changes['initialMethod'].currentValue;
20521
- this.currentMethodValue = typeof v === 'string' ? v : ((_b = ApiEditStepComponent.getOptionValue(v)) !== null && _b !== void 0 ? _b : '');
21055
+ this.currentMethodValue = typeof v === 'string' ? v : ((_c = ApiEditStepComponent.getOptionValue(v)) !== null && _c !== void 0 ? _c : '');
20522
21056
  this.methodForm.patchValue({ method: v });
20523
21057
  }
20524
21058
  if (changes['httpMethodOptions']) {
20525
21059
  this.updateMethodSelectConfig();
20526
- if (this.methodForm && ((_c = this.httpMethodOptions) === null || _c === void 0 ? void 0 : _c.length)) {
20527
- const current = (_d = this.methodForm.get('method')) === null || _d === void 0 ? void 0 : _d.value;
21060
+ if (this.methodForm && ((_d = this.httpMethodOptions) === null || _d === void 0 ? void 0 : _d.length)) {
21061
+ const current = (_e = this.methodForm.get('method')) === null || _e === void 0 ? void 0 : _e.value;
20528
21062
  const values = this.getMethodValues();
20529
21063
  const valid = values.includes(current);
20530
21064
  if (!valid) {
@@ -20536,15 +21070,15 @@ class ApiEditStepComponent {
20536
21070
  }
20537
21071
  }
20538
21072
  }
20539
- if (((_e = changes['initialEnvironment']) === null || _e === void 0 ? void 0 : _e.currentValue) != null && this.environmentForm) {
21073
+ if (((_f = changes['initialEnvironment']) === null || _f === void 0 ? void 0 : _f.currentValue) != null && this.environmentForm) {
20540
21074
  const v = changes['initialEnvironment'].currentValue;
20541
- this.currentEnvironmentValue = typeof v === 'string' ? v : ((_f = ApiEditStepComponent.getOptionValue(v)) !== null && _f !== void 0 ? _f : '');
21075
+ this.currentEnvironmentValue = typeof v === 'string' ? v : ((_g = ApiEditStepComponent.getOptionValue(v)) !== null && _g !== void 0 ? _g : '');
20542
21076
  this.environmentForm.patchValue({ environment: v });
20543
21077
  }
20544
21078
  if (changes['environmentOptions']) {
20545
21079
  this.updateEnvironmentSelectConfig();
20546
- if (this.environmentForm && ((_g = this.environmentOptions) === null || _g === void 0 ? void 0 : _g.length)) {
20547
- const current = (_h = this.environmentForm.get('environment')) === null || _h === void 0 ? void 0 : _h.value;
21080
+ if (this.environmentForm && ((_h = this.environmentOptions) === null || _h === void 0 ? void 0 : _h.length)) {
21081
+ const current = (_j = this.environmentForm.get('environment')) === null || _j === void 0 ? void 0 : _j.value;
20548
21082
  const values = this.getEnvironmentValues();
20549
21083
  const valid = values.includes(current);
20550
21084
  if (!valid) {
@@ -20556,32 +21090,62 @@ class ApiEditStepComponent {
20556
21090
  }
20557
21091
  }
20558
21092
  }
21093
+ if (((_k = changes['initialAuthType']) === null || _k === void 0 ? void 0 : _k.currentValue) != null && this.authTypeForm) {
21094
+ const v = changes['initialAuthType'].currentValue;
21095
+ const resolved = typeof v === 'string' ? v : ApiEditStepComponent.getOptionValue(v);
21096
+ if (resolved != null)
21097
+ this.authTypeForm.patchValue({ authType: v });
21098
+ }
21099
+ if (changes['authTypeOptions']) {
21100
+ this.updateAuthTypeSelectConfig();
21101
+ if (this.authTypeForm) {
21102
+ const values = this.getAuthTypeValues();
21103
+ if (values.length > 0) {
21104
+ const current = (_l = this.authTypeForm.get('authType')) === null || _l === void 0 ? void 0 : _l.value;
21105
+ const currentVal = current != null && current !== ''
21106
+ ? typeof current === 'object'
21107
+ ? ApiEditStepComponent.getOptionValue(current)
21108
+ : String(current)
21109
+ : null;
21110
+ const valid = currentVal != null && values.includes(currentVal);
21111
+ if (!valid) {
21112
+ const firstValue = values[0];
21113
+ if (firstValue != null) {
21114
+ this.authTypeForm.patchValue({ authType: firstValue });
21115
+ }
21116
+ }
21117
+ }
21118
+ }
21119
+ }
20559
21120
  if (changes['initialStep']) {
20560
21121
  this.applyInitialStep(changes['initialStep'].currentValue);
20561
21122
  }
20562
- if (((_j = changes['initialUrl']) === null || _j === void 0 ? void 0 : _j.currentValue) != null) {
21123
+ if (((_m = changes['initialUrl']) === null || _m === void 0 ? void 0 : _m.currentValue) != null) {
20563
21124
  this.url = changes['initialUrl'].currentValue;
20564
21125
  }
20565
- if (((_k = changes['initialPayloadTab']) === null || _k === void 0 ? void 0 : _k.currentValue) != null) {
21126
+ if (((_o = changes['initialPayloadTab']) === null || _o === void 0 ? void 0 : _o.currentValue) != null) {
20566
21127
  this.activePayloadTab = changes['initialPayloadTab'].currentValue;
20567
21128
  }
20568
21129
  if (changes['headerNameOptions']) {
20569
21130
  this.updateHeaderNameSelectConfig();
20570
21131
  }
20571
- if (((_l = changes['initialHeaders']) === null || _l === void 0 ? void 0 : _l.currentValue) != null) {
21132
+ if (((_p = changes['initialHeaders']) === null || _p === void 0 ? void 0 : _p.currentValue) != null) {
20572
21133
  this.buildHeadersFormArray(changes['initialHeaders'].currentValue);
20573
21134
  this.updateHeaderNameSelectConfig();
20574
21135
  }
20575
- if (((_m = changes['initialResponsePreview']) === null || _m === void 0 ? void 0 : _m.currentValue) != null) {
21136
+ if (((_q = changes['initialResponsePreview']) === null || _q === void 0 ? void 0 : _q.currentValue) != null) {
20576
21137
  this.responsePreview = changes['initialResponsePreview'].currentValue;
20577
21138
  }
20578
- if (((_o = changes['initialFormat']) === null || _o === void 0 ? void 0 : _o.currentValue) != null && this.payloadFormatForm) {
21139
+ if (((_r = changes['initialFormat']) === null || _r === void 0 ? void 0 : _r.currentValue) != null && this.payloadFormatForm) {
20579
21140
  this.payloadFormatForm.patchValue({ format: changes['initialFormat'].currentValue });
20580
21141
  }
21142
+ if (((_s = changes['initialVariableName']) === null || _s === void 0 ? void 0 : _s.currentValue) != null) {
21143
+ this.variableName = changes['initialVariableName'].currentValue;
21144
+ }
20581
21145
  if (changes['formatOptions']) {
20582
21146
  this.updatePayloadFormatSelectConfig();
20583
21147
  if (this.payloadFormatForm) {
20584
- const current = (_p = this.payloadFormatForm.get('format')) === null || _p === void 0 ? void 0 : _p.value;
21148
+ const current = (_t = this.payloadFormatForm.get('format')) === null || _t === void 0 ? void 0 : _t.value;
20585
21149
  const values = this.getFormatValues();
20586
21150
  const valid = values.includes(current);
20587
21151
  if (!valid && values.length > 0) {
@@ -20634,6 +21198,24 @@ class ApiEditStepComponent {
20634
21198
  }
20635
21199
  }
20636
21200
  }
21201
+ /** Default options when authTypeOptions is empty (same shape as environment) */
21202
+ ApiEditStepComponent.DEFAULT_AUTH_TYPE_OPTIONS = [
21203
+ { id: 'no-auth', value: 'no-auth', name: 'No Auth', label: 'No Auth' },
21204
+ { id: 'bearer', value: 'bearer', name: 'Bearer Token', label: 'Bearer Token' },
21205
+ { id: 'oauth2', value: 'oauth2', name: 'OAuth 2.0', label: 'OAuth 2.0' },
21206
+ ];
21207
+ /** Grant type options for OAuth 2.0 */
21208
+ ApiEditStepComponent.OAUTH_GRANT_TYPE_OPTIONS = [
21209
+ { id: 'client_credentials', value: 'client_credentials', name: 'Client Credentials', label: 'Client Credentials' },
21210
+ { id: 'authorization_code', value: 'authorization_code', name: 'Authorization Code', label: 'Authorization Code' },
21211
+ { id: 'password', value: 'password', name: 'Password', label: 'Password' },
21212
+ { id: 'implicit', value: 'implicit', name: 'Implicit', label: 'Implicit' },
21213
+ ];
21214
+ /** Client authentication method options for OAuth 2.0 */
21215
+ ApiEditStepComponent.OAUTH_CLIENT_AUTH_OPTIONS = [
21216
+ { id: 'basic', value: 'basic', name: 'Send as Basic Auth header', label: 'Send as Basic Auth header' },
21217
+ { id: 'body', value: 'body', name: 'Send in body', label: 'Send in body' },
21218
+ ];
20637
21219
  ApiEditStepComponent.DEFAULT_FORMAT_OPTIONS = [
20638
21220
  { id: 'json', value: 'json', name: 'JSON', label: 'JSON' },
20639
21221
  { id: 'xml', value: 'xml', name: 'XML', label: 'XML' },
@@ -20647,7 +21229,7 @@ ApiEditStepComponent.DEFAULT_HEADER_NAME_OPTIONS = [
20647
21229
  'Accept-Language',
20648
21230
  'Access-Control-Request-Headers',
20649
21231
  'Access-Control-Request-Method',
20650
- 'Authorization',
21232
+ 'Scripts',
20651
21233
  'Cache-Control',
20652
21234
  'Content-MD5',
20653
21235
  'Content-Length',
@@ -20705,10 +21287,10 @@ ApiEditStepComponent.DEFAULT_STATUS_VERIFICATION_OPTIONS = [
20705
21287
  { id: 'greater-than', value: 'greater-than', name: 'Greater than', label: 'Greater than' },
20706
21288
  ];
20707
21289
  ApiEditStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ApiEditStepComponent, deps: [{ token: i1$1.FormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
20708
- ApiEditStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ApiEditStepComponent, selector: "cqa-api-edit-step", inputs: { initialMethod: "initialMethod", initialEnvironment: "initialEnvironment", initialStep: "initialStep", initialUrl: "initialUrl", initialPayloadTab: "initialPayloadTab", initialHeaders: "initialHeaders", initialResponsePreview: "initialResponsePreview", httpMethodOptions: "httpMethodOptions", environmentOptions: "environmentOptions", formatOptions: "formatOptions", initialFormat: "initialFormat", headerNameOptions: "headerNameOptions", verificationOptions: "verificationOptions", verificationDataTypeOptions: "verificationDataTypeOptions", statusVerificationOptions: "statusVerificationOptions" }, outputs: { importCurl: "importCurl", importCurlCancel: "importCurlCancel", sendRequest: "sendRequest", back: "back", next: "next", create: "create", headersChange: "headersChange" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "payloadEditorWithLinesRef", first: true, predicate: ["payloadEditorWithLinesRef"], descendants: true }, { propertyName: "payloadTextareaRef", first: true, predicate: ["payloadTextareaRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-api-edit-step-container\">\n <!-- Title -->\n <h2\n class=\"cqa-api-edit-step-title cqa-font-inter cqa-text-[12px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal cqa-text-[#000000]\">\n Create API Test Step</h2>\n\n <!-- Step indicator: all three steps visible, active step highlighted (Postman-style) -->\n <div class=\"cqa-api-edit-step-indicator\">\n <ng-container *ngFor=\"let step of stepLabels; let i = index\">\n <cqa-button type=\"button\" variant=\"text\"\n customClass=\"cqa-api-edit-step-indicator-item cqa-api-edit-step-indicator-item--clickable\"\n [attr.aria-label]=\"'Step ' + step.index + ': ' + step.label\" [attr.aria-pressed]=\"step.index === currentStep\"\n (clicked)=\"setStep(step.index)\">\n <span class=\"cqa-api-edit-step-indicator-circle\"\n [class.cqa-api-edit-step-indicator-circle--active]=\"step.index === currentStep\">\n {{ step.index }}\n </span>\n <span class=\"cqa-api-edit-step-indicator-label\"\n [class.cqa-api-edit-step-indicator-label--active]=\"step.index === currentStep\">\n {{ step.label }}\n </span>\n <div *ngIf=\"i < stepLabels.length - 1\" class=\"cqa-api-edit-step-indicator-line\" aria-hidden=\"true\"></div>\n </cqa-button>\n </ng-container>\n </div>\n\n <!-- Step content viewport: smooth slide between steps -->\n <div class=\"cqa-api-edit-step-viewport\">\n <div class=\"cqa-api-edit-step-strip\" [style.transform]=\"'translateX(' + stripTranslatePercent + '%)'\">\n <!-- Step 1: Environment, request, body, response -->\n <div class=\"cqa-api-edit-step-panel\">\n <!-- Environment row: new line, select aligned right -->\n <div class=\"cqa-api-edit-step-environment-row\">\n <cqa-dynamic-select *ngIf=\"environmentForm\" [form]=\"environmentForm\" [config]=\"environmentSelectConfig\"\n class=\"cqa-api-edit-step-environment-select\" aria-label=\"Environment\"\n (selectionChange)=\"onEnvironmentSelectionChange($event)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Request row: method, URL, buttons -->\n <div class=\"cqa-api-edit-step-request-row\">\n <cqa-dynamic-select *ngIf=\"methodForm\" [form]=\"methodForm\" [config]=\"methodSelectConfig\"\n class=\"cqa-api-edit-step-method-select\" aria-label=\"HTTP method\"\n (selectionChange)=\"onMethodSelectionChange($event)\">\n </cqa-dynamic-select>\n <div class=\"cqa-api-edit-step-url-wrap\">\n <cqa-custom-input [(value)]=\"url\" [label]=\"''\" placeholder=\"\" [fullWidth]=\"true\" size=\"md\">\n </cqa-custom-input>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-trigger\" style=\"display: contents\" (click)=\"openImportCurlPanel()\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Import API cURL\"\n customClass=\"cqa-api-edit-step-btn-outline cqa-font-inter cqa-text-[14px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal cqa-text-[#414146]\">\n </cqa-button>\n </div>\n <cqa-button variant=\"filled\" btnSize=\"lg\" text=\"Send Request\" (clicked)=\"onSendRequest()\"\n customClass=\"cqa-api-edit-step-btn-primary cqa-font-inter cqa-text-[14px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal cqa-text-[#FBFCFF]\">\n </cqa-button>\n </div>\n\n\n\n <!-- Body content: header section (default) OR import cURL section -->\n <ng-container *ngIf=\"bodyView === 'import-curl'\">\n <div class=\"cqa-api-edit-step-import-curl-panel\">\n <div class=\"cqa-api-edit-step-import-curl-header\">\n <h3 class=\"cqa-api-edit-step-import-curl-title\">Import API cURL</h3>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-separator\"></div>\n <div class=\"cqa-api-edit-step-import-curl-body\">\n <cqa-custom-textarea [value]=\"importCurlControl.value\"\n (valueChange)=\"importCurlControl.setValue($event)\"\n placeholder=\"Paste your cURL command here (e.g., curl -X POST https://api.example.com/users)\"\n [fullWidth]=\"true\" [rows]=\"8\" resize=\"vertical\" size=\"md\"\n class=\"cqa-api-edit-step-import-curl-textarea\">\n </cqa-custom-textarea>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-footer\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Cancel\"\n customClass=\"cqa-api-edit-step-import-curl-btn-cancel\" (clicked)=\"onCancelImportCurl()\"></cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Import\"\n customClass=\"cqa-api-edit-step-import-curl-btn-import\" (clicked)=\"onImportCurlConfirm()\"></cqa-button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"bodyView === 'headers'\">\n <div class=\"cqa-api-edit-step-tabs-wrapper\">\n <div class=\"cqa-api-edit-step-tabs\">\n <cqa-button *ngFor=\"let tab of payloadTabs\" type=\"button\" variant=\"text\" [text]=\"tab.label\"\n [customClass]=\"'cqa-api-edit-step-tab' + (activePayloadTab === tab.value ? ' cqa-api-edit-step-tab--active' : '') + (isMethodWithoutBody && tab.value !== 'headers' ? ' cqa-api-edit-step-tab--disabled' : '')\"\n [disabled]=\"isMethodWithoutBody && tab.value !== 'headers'\"\n (clicked)=\"setPayloadTab(tab.value)\">\n </cqa-button>\n </div>\n\n <!-- Payload content (Headers) -->\n <div *ngIf=\"activePayloadTab === 'headers'\" class=\"cqa-api-edit-step-payload\">\n <div class=\"cqa-api-edit-step-headers-grid\">\n <span class=\"cqa-api-edit-step-headers-label\">Header Name</span>\n <span class=\"cqa-api-edit-step-headers-label\">Header Value</span>\n <span class=\"cqa-api-edit-step-headers-label cqa-api-edit-step-headers-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of headerRows; let i = index; trackBy: trackByHeader\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-header-row\">\n <cqa-dynamic-select [form]=\"row\" [config]=\"headerNameSelectConfig\"\n (addCustomValue)=\"onHeaderNameAddCustomValue($event, row)\"\n class=\"cqa-api-edit-step-header-type-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-header-value-input\" ariaLabel=\"Header value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-header-delete'\"\n [tooltip]=\"'Remove header'\" (clicked)=\"removeHeader(i)\">\n <svg class=\"cqa-api-edit-step-header-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-add-header-wrap\">\n <cqa-button type=\"button\" variant=\"text\" text=\"+ Add Header\"\n [customClass]=\"'cqa-api-edit-step-add-header-link'\" (clicked)=\"addHeader()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Payload content (Body only): type, format, text area, Back/Next -->\n <div *ngIf=\"activePayloadTab === 'body'\"\n class=\"cqa-api-edit-step-payload cqa-api-edit-step-payload-editor\">\n <div class=\"cqa-api-edit-step-payload-type-row\">\n <span class=\"cqa-api-edit-step-payload-type-label\">Type</span>\n <div class=\"cqa-api-edit-step-payload-type-radios\">\n <cqa-segment-control [value]=\"payloadType\" [segments]=\"payloadTypeSegments\"\n (valueChange)=\"onPayloadTypeChange($event)\"\n class=\"cqa-api-edit-step-payload-type-segment\">\n </cqa-segment-control>\n </div>\n <div *ngIf=\"payloadType === 'raw'\" class=\"cqa-api-edit-step-payload-format-wrap\">\n <span class=\"cqa-api-edit-step-payload-format-label\">Format:</span>\n <cqa-dynamic-select *ngIf=\"payloadFormatForm\" [form]=\"payloadFormatForm\"\n [config]=\"payloadFormatSelectConfig\" class=\"cqa-api-edit-step-payload-format-select\"\n aria-label=\"Format\">\n </cqa-dynamic-select>\n </div>\n </div>\n <!-- Raw: text area with line numbers (Postman-style payload body) -->\n <div *ngIf=\"payloadType === 'raw'\" class=\"cqa-api-edit-step-payload-body\" #payloadEditorWithLinesRef>\n <div class=\"cqa-api-edit-step-payload-editor-with-lines\">\n <div class=\"cqa-api-edit-step-payload-line-numbers\" aria-hidden=\"true\">\n <span *ngFor=\"let n of payloadLineNumbers\" class=\"cqa-api-edit-step-payload-line-num\">\n <span *ngIf=\"payloadJsonError && payloadJsonError.line === n\"\n class=\"cqa-api-edit-step-payload-line-error-icon\" [title]=\"payloadJsonErrorTooltip\"\n aria-label=\"Parse error on this line\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#EF4444\"/>\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n <span class=\"cqa-api-edit-step-payload-line-num-text\">{{ n }}</span>\n </span>\n </div>\n <div class=\"cqa-api-edit-step-payload-textarea-cell\">\n <div class=\"cqa-api-edit-step-payload-textarea cqa-w-full cqa-flex cqa-flex-col cqa-min-h-0\"\n [ngClass]=\"{'cqa-api-edit-step-payload-textarea--error': payloadJsonError}\">\n <textarea #payloadTextareaRef\n class=\"cqa-api-edit-step-payload-textarea-input cqa-w-full cqa-resize-y cqa-outline-none cqa-box-border\"\n [ngClass]=\"{'cqa-api-edit-step-payload-textarea-input--error': payloadJsonError}\"\n [value]=\"payloadText\"\n [attr.rows]=\"10\"\n placeholder=\"\"\n [attr.aria-label]=\"'Payload'\"\n [attr.aria-invalid]=\"!!payloadJsonError\"\n (input)=\"onPayloadInput($event)\"\n (keydown)=\"onPayloadKeydown($event)\">\n </textarea>\n </div>\n </div>\n </div>\n <p *ngIf=\"payloadJsonError\" class=\"cqa-api-edit-step-payload-json-error-msg\">\n Invalid JSON format. Please check your syntax.\n </p>\n </div>\n\n <!-- x-www-form-urlencoded: Key\u2013Value rows, add/remove dynamically -->\n <div *ngIf=\"payloadType === 'x-www-form-urlencoded'\" class=\"cqa-api-edit-step-key-value\">\n <div class=\"cqa-api-edit-step-key-value-grid cqa-api-edit-step-key-value-header\">\n <span class=\"cqa-api-edit-step-key-value-label\">Key</span>\n <span class=\"cqa-api-edit-step-key-value-label\">Value</span>\n <span class=\"cqa-api-edit-step-key-value-label cqa-api-edit-step-key-value-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of keyValueRows; let i = index; trackBy: trackByKeyValue\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-key-value-row\">\n <cqa-custom-input [value]=\"row.get('key')?.value ?? ''\"\n (valueChange)=\"row.get('key')?.setValue($event)\" placeholder=\"Key\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Key\">\n </cqa-custom-input>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-key-value-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeKeyValueRow(i)\">\n <svg class=\"cqa-api-edit-step-key-value-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-key-value-add-wrap\">\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"+ Add Row\"\n customClass=\"cqa-api-edit-step-key-value-add-btn\" (clicked)=\"addKeyValueRow()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Form Data: Key\u2013Type\u2013Value rows; Type is a dropdown (Text/File), add/remove dynamically -->\n <div *ngIf=\"payloadType === 'form-data'\" class=\"cqa-api-edit-step-key-type-value\">\n <div class=\"cqa-api-edit-step-key-type-value-header\">\n <span class=\"cqa-api-edit-step-key-type-value-label\">Key</span>\n <span class=\"cqa-api-edit-step-key-type-value-label\">Type</span>\n <span class=\"cqa-api-edit-step-key-type-value-label\">Value</span>\n <span class=\"cqa-api-edit-step-key-type-value-label cqa-api-edit-step-key-type-value-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of keyTypeValueRows; let i = index; trackBy: trackByKeyTypeValue\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-key-type-value-row\">\n <cqa-custom-input [value]=\"row.get('key')?.value ?? ''\"\n (valueChange)=\"row.get('key')?.setValue($event)\" placeholder=\"Key\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-type-value-input\" ariaLabel=\"Key\">\n </cqa-custom-input>\n <cqa-dynamic-select [form]=\"row\" [config]=\"keyTypeValueTypeSelectConfig\"\n class=\"cqa-api-edit-step-key-type-value-type-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-type-value-input\" ariaLabel=\"Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-key-type-value-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeKeyTypeValueRow(i)\">\n <svg class=\"cqa-api-edit-step-key-type-value-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-key-type-value-add-wrap\">\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"+ Add Row\"\n customClass=\"cqa-api-edit-step-key-type-value-add-btn\" (clicked)=\"addKeyTypeValueRow()\">\n </cqa-button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n </div>\n <!-- Step 2: Variable Name: input, validation, Back / Next -->\n <div class=\"cqa-api-edit-step-panel\">\n <div class=\"cqa-api-edit-step-variable-section\">\n <div class=\"cqa-api-edit-step-variable-input-wrap\">\n <cqa-custom-input [(value)]=\"variableName\" [label]=\"''\" placeholder=\"Variable Name\" [fullWidth]=\"true\"\n size=\"md\" (valueChange)=\"onVariableNameChange()\" aria-label=\"Variable Name\">\n </cqa-custom-input>\n </div>\n <p *ngIf=\"variableNameError\" class=\"cqa-api-edit-step-variable-error\" role=\"alert\">{{ variableNameError }}</p>\n </div>\n </div>\n <!-- Step 3: Response Body / Status tabs -->\n <div class=\"cqa-api-edit-step-panel\">\n <div class=\"cqa-api-edit-step-tabs-wrapper\">\n <div class=\"cqa-api-edit-step-tabs\">\n <cqa-button *ngFor=\"let tab of responseVerificationTabs\" type=\"button\" variant=\"text\" [text]=\"tab.label\"\n [customClass]=\"'cqa-api-edit-step-tab' + (activeResponseVerificationTab === tab.value ? ' cqa-api-edit-step-tab--active' : '')\"\n (clicked)=\"setResponseVerificationTab(tab.value)\">\n </cqa-button>\n </div>\n\n <!-- Response Body tab content: verification grid -->\n <div *ngIf=\"activeResponseVerificationTab === 'response-body'\" class=\"cqa-api-edit-step-step3-content\">\n <div class=\"cqa-api-edit-step-verification-header-row\">\n <span></span>\n <cqa-button type=\"button\" variant=\"text\" text=\"Add Verification\"\n customClass=\"cqa-api-edit-step-verification-add-link\" (clicked)=\"addVerificationRow()\">\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-verification\">\n <div class=\"cqa-api-edit-step-verification-grid cqa-api-edit-step-verification-grid-header\">\n <span class=\"cqa-api-edit-step-verification-label\">S.no</span>\n <span class=\"cqa-api-edit-step-verification-label\">JSON Path</span>\n <span class=\"cqa-api-edit-step-verification-label\">Verification</span>\n <span class=\"cqa-api-edit-step-verification-label\">Data Type</span>\n <span class=\"cqa-api-edit-step-verification-label\">Expected Value</span>\n <span class=\"cqa-api-edit-step-verification-label cqa-api-edit-step-verification-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of verificationRows; let i = index; trackBy: trackByVerification\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-verification-row\">\n <span class=\"cqa-api-edit-step-verification-sno\">{{ i + 1 }}</span>\n <cqa-custom-input [value]=\"row.get('jsonPath')?.value ?? ''\"\n (valueChange)=\"row.get('jsonPath')?.setValue($event)\" placeholder=\"Json Path\" [fullWidth]=\"true\"\n size=\"sm\" class=\"cqa-api-edit-step-verification-input\" ariaLabel=\"JSON Path\">\n </cqa-custom-input>\n <cqa-dynamic-select [form]=\"row\" [config]=\"verificationSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"row\" [config]=\"verificationDataTypeSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-w-full\"\n (selectionChange)=\"onVerificationDataTypeChange(row, $event)\">\n </cqa-dynamic-select>\n <!-- Expected Value: text for String/Array/Object, number for Number, dropdown for Boolean -->\n <ng-container [ngSwitch]=\"row.get('dataType')?.value\">\n <cqa-dynamic-select *ngSwitchCase=\"'boolean'\" [form]=\"row\"\n [config]=\"verificationExpectedValueBooleanSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-api-edit-step-verification-expected-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input *ngSwitchCase=\"'number'\" [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\" placeholder=\"Expected Value (number)\"\n type=\"number\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-verification-input cqa-api-edit-step-verification-expected-number\"\n ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n <cqa-custom-input *ngSwitchDefault [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\"\n placeholder=\"Expected Value in String\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-verification-input\" ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n </ng-container>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-verification-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeVerificationRow(i)\">\n <svg class=\"cqa-api-edit-step-verification-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n </div>\n </div>\n\n <!-- Status tab content: S.no, Verification dropdown, Expected Value, add/remove rows -->\n <div *ngIf=\"activeResponseVerificationTab === 'status'\" class=\"cqa-api-edit-step-step3-content\">\n <div class=\"cqa-api-edit-step-verification-header-row\">\n <span></span>\n <cqa-button type=\"button\" variant=\"text\" text=\"Add Verification\"\n customClass=\"cqa-api-edit-step-verification-add-link\" (clicked)=\"addStatusVerificationRow()\">\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-status-verification\">\n <div class=\"cqa-api-edit-step-status-verification-header\">\n <span class=\"cqa-api-edit-step-verification-label\">S.no</span>\n <span class=\"cqa-api-edit-step-verification-label\">Verification</span>\n <span class=\"cqa-api-edit-step-verification-label\">Expected Value</span>\n <span class=\"cqa-api-edit-step-verification-label cqa-api-edit-step-verification-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of statusVerificationRows; let i = index; trackBy: trackByStatusVerification\"\n [formGroup]=\"row\" class=\"cqa-api-edit-step-status-verification-row\">\n <span class=\"cqa-api-edit-step-verification-sno\">{{ i + 1 }}</span>\n <cqa-dynamic-select [form]=\"row\" [config]=\"statusVerificationSelectConfig\"\n class=\"cqa-api-edit-step-status-verification-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\" placeholder=\"Expected Value\"\n type=\"number\" [fullWidth]=\"true\" size=\"sm\" class=\"cqa-api-edit-step-verification-input\"\n ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-verification-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeStatusVerificationRow(i)\">\n <svg class=\"cqa-api-edit-step-verification-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Response Preview -->\n <div class=\"cqa-api-edit-step-response\">\n <h3 class=\"cqa-api-edit-step-response-title\">Response Preview</h3>\n <pre class=\"cqa-api-edit-step-response-content\">{{ responsePreview }}</pre>\n </div>\n\n <!-- Step actions: one row, full width. Step 1: Cancel + Next; Step 2: Back + Next; Step 3: Back + Create -->\n <div class=\"cqa-api-edit-step-actions\">\n <ng-container [ngSwitch]=\"currentStep\">\n <ng-container *ngSwitchCase=\"1\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Cancel\"\n customClass=\"cqa-api-edit-step-actions-btn-cancel\" (clicked)=\"onBack()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Next\"\n customClass=\"cqa-api-edit-step-actions-btn-next\" (clicked)=\"onNext()\">\n </cqa-button>\n </ng-container>\n <ng-container *ngSwitchCase=\"2\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Back\"\n customClass=\"cqa-api-edit-step-actions-btn-back\" (clicked)=\"onBack()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Next\"\n customClass=\"cqa-api-edit-step-actions-btn-next\" (clicked)=\"onNext()\">\n </cqa-button>\n </ng-container>\n <ng-container *ngSwitchCase=\"3\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Back\"\n customClass=\"cqa-api-edit-step-actions-btn-back\" (clicked)=\"onBack()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Create\"\n customClass=\"cqa-api-edit-step-actions-btn-create\" (clicked)=\"onCreate()\">\n </cqa-button>\n </ng-container>\n </ng-container>\n </div>\n</div>", components: [{ type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: CustomInputComponent, selector: "cqa-custom-input", inputs: ["label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }, { type: CustomTextareaComponent, selector: "cqa-custom-textarea", inputs: ["label", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "rows", "cols", "resize", "textareaInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused"] }, { type: SegmentControlComponent, selector: "cqa-segment-control", inputs: ["segments", "value", "disabled", "containerBgColor"], outputs: ["valueChange"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }], changeDetection: i0.ChangeDetectionStrategy.Default });
21290
+ ApiEditStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ApiEditStepComponent, selector: "cqa-api-edit-step", inputs: { initialMethod: "initialMethod", initialEnvironment: "initialEnvironment", initialStep: "initialStep", initialUrl: "initialUrl", initialPayloadTab: "initialPayloadTab", initialHeaders: "initialHeaders", initialResponsePreview: "initialResponsePreview", initialVariableName: "initialVariableName", editMode: "editMode", httpMethodOptions: "httpMethodOptions", environmentOptions: "environmentOptions", authTypeOptions: "authTypeOptions", initialAuthType: "initialAuthType", formatOptions: "formatOptions", initialFormat: "initialFormat", headerNameOptions: "headerNameOptions", verificationOptions: "verificationOptions", verificationDataTypeOptions: "verificationDataTypeOptions", statusVerificationOptions: "statusVerificationOptions" }, outputs: { importCurl: "importCurl", importCurlCancel: "importCurlCancel", sendRequest: "sendRequest", back: "back", cancel: "cancel", next: "next", create: "create", headersChange: "headersChange" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "payloadEditorWithLinesRef", first: true, predicate: ["payloadEditorWithLinesRef"], descendants: true }, { propertyName: "payloadTextareaRef", first: true, predicate: ["payloadTextareaRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-api-edit-step-container cqa-bg-[#ffffff] cqa-flex cqa-flex-col cqa-w-full cqa-h-full cqa-p-[16px] cqa-gap-[12px] cqa-overflow-y-auto cqa-overflow-x-hidden cqa-box-border\">\n\n <h2 class=\"cqa-api-edit-step-title cqa-font-inter cqa-text-[12px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal cqa-text-[#000000] cqa-m-0\">\n {{ editMode ? 'Update API Test Step' : 'Create API Test Step' }}\n </h2>\n\n <div class=\"cqa-api-edit-step-indicator cqa-flex cqa-items-center cqa-gap-0 cqa-max-[767px]:cqa-flex-wrap cqa-max-[767px]:cqa-gap-2 cqa-max-[767px]:cqa-justify-start\"\n [class.cqa-justify-start]=\"stepLabels.length === 1\"\n [class.cqa-justify-between]=\"stepLabels.length !== 1\">\n <ng-container *ngFor=\"let step of stepLabels; let i = index\">\n <cqa-button type=\"button\" variant=\"text\"\n customClass=\"cqa-api-edit-step-indicator-item cqa-api-edit-step-indicator-item--clickable cqa-flex cqa-items-center cqa-gap-[10px] cqa-cursor-pointer cqa-border-none cqa-p-0 cqa-font-inherit cqa-text-inherit cqa-text-left !cqa-bg-transparent\"\n [attr.aria-label]=\"'Step ' + step.index + ': ' + step.label\" [attr.aria-pressed]=\"step.index === currentStep\"\n (clicked)=\"setStep(step.index)\">\n <span class=\"cqa-api-edit-step-indicator-circle cqa-w-8 cqa-h-8 cqa-rounded-full cqa-inline-flex cqa-items-center cqa-justify-center cqa-text-sm cqa-font-medium cqa-leading-none cqa-border-none cqa-shrink-0\"\n [ngClass]=\"step.index === currentStep ? 'cqa-bg-[#4F46E5] cqa-text-white' : 'cqa-bg-[#E0E0E0] cqa-text-[#666666]'\">\n {{ step.index }}\n </span>\n <span class=\"cqa-api-edit-step-indicator-label cqa-text-sm cqa-leading-[18px] cqa-font-normal cqa-max-[767px]:cqa-text-xs\"\n [ngClass]=\"step.index === currentStep ? 'cqa-text-[#4F46E5]' : 'cqa-text-[#666666]'\">\n {{ step.label }}\n </span>\n <div *ngIf=\"i < stepLabels.length - 1\" class=\"cqa-api-edit-step-indicator-line cqa-w-[96px] cqa-h-[2px] cqa-bg-[#E0E0E0] cqa-my-0 cqa-mx-[6px] cqa-shrink-0 cqa-self-center cqa-max-[767px]:cqa-w-[24px] cqa-max-[767px]:cqa-mx-1\" aria-hidden=\"true\"></div>\n </cqa-button>\n </ng-container>\n </div>\n\n <!-- Step content viewport: only the active step body is shown (*ngIf) -->\n <div class=\"cqa-api-edit-step-viewport cqa-w-full\">\n <!-- Step 1: Environment, request, body, response -->\n <div *ngIf=\"currentStep === 1\" class=\"cqa-api-edit-step-panel cqa-flex cqa-flex-col cqa-gap-6 cqa-box-border cqa-w-full\">\n <!-- Environment row: new line, select aligned right -->\n <div class=\"cqa-api-edit-step-environment-row cqa-flex cqa-justify-end cqa-items-center\">\n <cqa-dynamic-select *ngIf=\"environmentForm\" [form]=\"environmentForm\" [config]=\"environmentSelectConfig\"\n class=\"cqa-api-edit-step-environment-select cqa-shrink-0 cqa-w-auto cqa-min-w-[315px] cqa-max-w-[315px] cqa-max-[767px]:cqa-min-w-0 cqa-max-[767px]:cqa-max-w-full cqa-max-[767px]:cqa-w-full [&_.mat-form-field-wrapper]:cqa-pb-0\" aria-label=\"Environment\"\n (selectionChange)=\"onEnvironmentSelectionChange($event)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Request row: method, URL, buttons -->\n <div class=\"cqa-api-edit-step-request-row cqa-flex cqa-items-center cqa-gap-3 cqa-flex-wrap cqa-max-[767px]:cqa-flex-col cqa-max-[767px]:cqa-items-stretch cqa-max-[767px]:cqa-gap-2.5\">\n <cqa-dynamic-select *ngIf=\"methodForm\" [form]=\"methodForm\" [config]=\"methodSelectConfig\"\n class=\"cqa-api-edit-step-method-select cqa-shrink-0 cqa-w-auto cqa-min-w-[152px] cqa-max-w-[152px] cqa-max-[767px]:cqa-min-w-0 cqa-max-[767px]:cqa-max-w-full cqa-max-[767px]:cqa-w-full\" aria-label=\"HTTP method\"\n (selectionChange)=\"onMethodSelectionChange($event)\">\n </cqa-dynamic-select>\n <div class=\"cqa-api-edit-step-url-wrap cqa-flex-1 cqa-min-w-[200px] cqa-max-[767px]:cqa-min-w-0 cqa-max-[767px]:cqa-w-full [&_cqa-custom-input_.cqa-relative_input]:cqa-h-[40px] [&_cqa-custom-input_.cqa-relative_input]:cqa-bg-white [&_cqa-custom-input_.cqa-relative_input]:cqa-border [&_cqa-custom-input_.cqa-relative_input]:cqa-border-solid [&_cqa-custom-input_.cqa-relative_input]:cqa-border-[#D1D5DB] [&_cqa-custom-input_.cqa-relative_input]:cqa-rounded-md [&_cqa-custom-input_.cqa-relative_input]:cqa-text-sm [&_cqa-custom-input_.cqa-relative_input]:cqa-text-[#374151]\">\n <cqa-custom-input [(value)]=\"url\" [label]=\"''\" placeholder=\"\" [fullWidth]=\"true\" size=\"md\">\n </cqa-custom-input>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-trigger cqa-contents cqa-max-[767px]:cqa-w-full cqa-max-[767px]:!cqa-flex\" (click)=\"openImportCurlPanel()\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Import API cURL\"\n customClass=\"cqa-api-edit-step-btn-outline !cqa-bg-white !cqa-border !cqa-border-solid !cqa-border-[#6B7280] cqa-text-[#414146] cqa-font-inter cqa-text-[14px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal hover:!cqa-bg-[#F9FAFB] hover:!cqa-text-[#414146] cqa-max-[767px]:cqa-w-full\">\n </cqa-button>\n </div>\n <cqa-button variant=\"filled\" btnSize=\"lg\" text=\"Send Request\" (clicked)=\"onSendRequest()\"\n customClass=\"cqa-api-edit-step-btn-primary cqa-font-inter cqa-text-[14px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal !cqa-bg-[#3F43EE] cqa-text-[#FBFCFF] !cqa-border-none cqa-py-2.5 cqa-px-6 cqa-gap-2 cqa-rounded-lg cqa-min-h-[37px] cqa-box-border hover:!cqa-bg-[#1B1FEB] cqa-max-[767px]:cqa-w-full\">\n </cqa-button>\n </div>\n\n\n\n <!-- Body content: header section (default) OR import cURL section -->\n <ng-container *ngIf=\"bodyView === 'import-curl'\">\n <div class=\"cqa-api-edit-step-import-curl-panel cqa-flex cqa-flex-col cqa-bg-white cqa-rounded-lg cqa-border cqa-border-solid cqa-border-[#E5E7EB] cqa-shadow-[0_1px_3px_rgba(0,0,0,0.08)] cqa-overflow-hidden\">\n <div class=\"cqa-api-edit-step-import-curl-header cqa-flex cqa-items-center cqa-justify-between cqa-py-3 cqa-px-5 cqa-border-b cqa-border-solid cqa-border-[#E2E8F0] cqa-bg-[#F9FAFB] cqa-rounded-t-lg cqa-max-[767px]:cqa-px-4\">\n <h3 class=\"cqa-api-edit-step-import-curl-title cqa-m-0 cqa-text-xs cqa-font-bold cqa-leading-[18px] cqa-text-[#374151]\">Import API cURL</h3>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-separator cqa-h-px cqa-bg-[#E2E8F0] cqa-my-0 cqa-mx-5\"></div>\n <div class=\"cqa-api-edit-step-import-curl-body\">\n <cqa-custom-textarea [value]=\"importCurlControl.value\"\n (valueChange)=\"importCurlControl.setValue($event)\"\n placeholder=\"Paste your cURL command here (e.g., curl -X POST https://api.example.com/users)\"\n [fullWidth]=\"true\" [rows]=\"8\" resize=\"vertical\" size=\"md\"\n class=\"cqa-api-edit-step-import-curl-textarea\">\n </cqa-custom-textarea>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-footer\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Cancel\"\n customClass=\"cqa-api-edit-step-import-curl-btn-cancel\" (clicked)=\"onCancelImportCurl()\"></cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Import\"\n customClass=\"cqa-api-edit-step-import-curl-btn-import\" (clicked)=\"onImportCurlConfirm()\"></cqa-button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"bodyView === 'headers'\">\n <div class=\"cqa-api-edit-step-tabs-wrapper\">\n <div class=\"cqa-api-edit-step-tabs\">\n <cqa-button *ngFor=\"let tab of payloadTabs\" type=\"button\" variant=\"text\" [text]=\"tab.label\"\n [customClass]=\"'cqa-api-edit-step-tab' + (activePayloadTab === tab.value ? ' cqa-api-edit-step-tab--active' : '') + (isMethodWithoutBody && (tab.value === 'body' || tab.value === 'params') ? ' cqa-api-edit-step-tab--disabled' : '')\"\n [disabled]=\"isMethodWithoutBody && (tab.value === 'body' || tab.value === 'params')\"\n (clicked)=\"setPayloadTab(tab.value)\">\n </cqa-button>\n </div>\n\n <!-- Payload content (Authorization) -->\n <div *ngIf=\"activePayloadTab === 'authorization'\" class=\"cqa-api-edit-step-payload\"\n [attr.style]=\"'padding: 20px; min-height: 200px;'\">\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 20px;'\">\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 8px; width: fit-content;'\">\n <span [attr.style]=\"'font-size: 11px; font-weight: 600; letter-spacing: 0.02em; color: #6B7280; text-transform: uppercase; line-height: 1.25;'\">AUTH TYPE</span>\n <cqa-dynamic-select *ngIf=\"authTypeForm\" [form]=\"authTypeForm\" [config]=\"authTypeSelectConfig\"\n class=\"cqa-api-edit-step-auth-type-select\" aria-label=\"Auth type\"\n [attr.style]=\"'min-width: 160px;'\">\n </cqa-dynamic-select>\n </div>\n <!-- No Auth: centered message -->\n <div *ngIf=\"selectedAuthType === 'no-auth'\"\n [attr.style]=\"'flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; min-width: 0; text-align: center;'\">\n <div aria-hidden=\"true\"\n [attr.style]=\"'width: 48px; height: 48px; border-radius: 10px; background: #F3F4F6; display: flex; align-items: center; justify-content: center; flex-shrink: 0;'\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style=\"display: block;\">\n <rect x=\"5\" y=\"11\" width=\"14\" height=\"2\" rx=\"1\" fill=\"#9CA3AF\"/>\n </svg>\n </div>\n <span [attr.style]=\"'font-size: 16px; font-weight: 600; color: #374151; line-height: 1.25;'\">No Auth</span>\n <div [attr.style]=\"'display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap;'\">\n <span [attr.style]=\"'font-size: 14px; font-weight: 400; color: #9CA3AF; line-height: 1.4;'\">This request does not use any authorization.</span>\n <span role=\"img\" aria-label=\"More information\" title=\"This request does not use any authorization.\"\n [attr.style]=\"'display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; color: #9CA3AF; flex-shrink: 0;'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style=\"display: block;\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"#9CA3AF\" stroke-width=\"1.5\" fill=\"none\"/>\n <path d=\"M8 7v4M8 5v.5\" stroke=\"#9CA3AF\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n </div>\n </div>\n <!-- Bearer Token: Token label + textarea -->\n <div *ngIf=\"selectedAuthType === 'bearer'\"\n [attr.style]=\"'flex: 1; display: flex; flex-direction: column; gap: 10px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Token</span>\n <cqa-custom-textarea [(value)]=\"bearerToken\"\n placeholder=\"Enter bearer token\"\n [fullWidth]=\"true\" [rows]=\"6\" resize=\"vertical\" size=\"md\"\n class=\"cqa-api-edit-step-auth-token-textarea\" ariaLabel=\"Bearer token\">\n </cqa-custom-textarea>\n </div>\n <!-- OAuth 2.0: Grant Type, Access Token URL, Client ID, Client Secret, Scope, Client Authentication -->\n <div *ngIf=\"selectedAuthType === 'oauth2' && oauth2Form\"\n class=\"cqa-api-edit-step-oauth2-grid\"\n [attr.style]=\"'display: grid; grid-template-columns: 1fr 1fr; gap: 16px 24px; width: 100%;'\">\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Grant Type</span>\n <cqa-dynamic-select *ngIf=\"oauth2Form\" [form]=\"oauth2Form\" [config]=\"oauth2GrantTypeSelectConfig\"\n class=\"cqa-api-edit-step-auth-oauth-select\" aria-label=\"OAuth grant type\"\n [attr.style]=\"'min-width: 0; width: 100%;'\">\n </cqa-dynamic-select>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">OAuth grant type</span>\n </div>\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Access Token URL</span>\n <cqa-custom-input [value]=\"oauth2Form.get('accessTokenUrl')?.value\"\n (valueChange)=\"oauth2Form.get('accessTokenUrl')?.setValue($event)\"\n [label]=\"''\" placeholder=\"Enter OAuth token endpoint\" [fullWidth]=\"true\" size=\"md\"\n ariaLabel=\"Access Token URL\">\n </cqa-custom-input>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">OAuth token endpoint</span>\n </div>\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Client ID</span>\n <cqa-custom-input [value]=\"oauth2Form.get('clientId')?.value\"\n (valueChange)=\"oauth2Form.get('clientId')?.setValue($event)\"\n [label]=\"''\" placeholder=\"Enter OAuth client identifier\" [fullWidth]=\"true\" size=\"md\"\n ariaLabel=\"Client ID\">\n </cqa-custom-input>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">OAuth client identifier</span>\n </div>\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Client Secret</span>\n <cqa-custom-input [value]=\"oauth2Form.get('clientSecret')?.value\"\n (valueChange)=\"oauth2Form.get('clientSecret')?.setValue($event)\"\n type=\"password\" [label]=\"''\" placeholder=\"Enter OAuth client secret\" [fullWidth]=\"true\" size=\"md\"\n ariaLabel=\"Client Secret\">\n </cqa-custom-input>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">OAuth client secret</span>\n </div>\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Scope</span>\n <cqa-custom-input [value]=\"oauth2Form.get('scope')?.value\"\n (valueChange)=\"oauth2Form.get('scope')?.setValue($event)\"\n [label]=\"''\" placeholder=\"Enter space-separated scopes\" [fullWidth]=\"true\" size=\"md\"\n ariaLabel=\"Scope\">\n </cqa-custom-input>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">Space-separated scopes</span>\n </div>\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Client Authentication</span>\n <cqa-dynamic-select *ngIf=\"oauth2Form\" [form]=\"oauth2Form\" [config]=\"oauth2ClientAuthSelectConfig\"\n class=\"cqa-api-edit-step-auth-oauth-select\" aria-label=\"Client authentication method\"\n [attr.style]=\"'min-width: 0; width: 100%;'\">\n </cqa-dynamic-select>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">Client authentication method</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Payload content (Headers) -->\n <div *ngIf=\"activePayloadTab === 'headers'\" class=\"cqa-api-edit-step-payload\">\n <div class=\"cqa-api-edit-step-headers-grid\">\n <span class=\"cqa-api-edit-step-headers-label\">Header Name</span>\n <span class=\"cqa-api-edit-step-headers-label\">Header Value</span>\n <span class=\"cqa-api-edit-step-headers-label cqa-api-edit-step-headers-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of headerRows; let i = index; trackBy: trackByHeader\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-header-row\">\n <cqa-dynamic-select [form]=\"row\" [config]=\"headerNameSelectConfig\"\n (addCustomValue)=\"onHeaderNameAddCustomValue($event, row)\"\n class=\"cqa-api-edit-step-header-type-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-header-value-input\" ariaLabel=\"Header value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-header-delete'\"\n [tooltip]=\"'Remove header'\" (clicked)=\"removeHeader(i)\">\n <svg class=\"cqa-api-edit-step-header-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-add-header-wrap\">\n <cqa-button type=\"button\" variant=\"text\" text=\"+ Add Header\"\n [customClass]=\"'cqa-api-edit-step-add-header-link'\" (clicked)=\"addHeader()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Payload content (Params): Key\u2013Value table with add/delete rows -->\n <div *ngIf=\"activePayloadTab === 'params'\" class=\"cqa-api-edit-step-payload\">\n <div class=\"cqa-api-edit-step-key-value-grid cqa-api-edit-step-key-value-header\">\n <span class=\"cqa-api-edit-step-key-value-label\">Key</span>\n <span class=\"cqa-api-edit-step-key-value-label\">Value</span>\n <span class=\"cqa-api-edit-step-key-value-label cqa-api-edit-step-key-value-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of paramsRows; let i = index; trackBy: trackByParams\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-key-value-row\">\n <cqa-custom-input [value]=\"row.get('key')?.value ?? ''\"\n (valueChange)=\"row.get('key')?.setValue($event)\" placeholder=\"Key\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Key\">\n </cqa-custom-input>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-key-value-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeParamsRow(i)\">\n <svg class=\"cqa-api-edit-step-key-value-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-key-value-add-wrap\">\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"+ Add Row\"\n customClass=\"cqa-api-edit-step-key-value-add-btn\" (clicked)=\"addParamsRow()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Payload content (Body only): type, format, text area, Back/Next -->\n <div *ngIf=\"activePayloadTab === 'body'\"\n class=\"cqa-api-edit-step-payload cqa-api-edit-step-payload-editor\">\n <div class=\"cqa-api-edit-step-payload-type-row\">\n <span class=\"cqa-api-edit-step-payload-type-label\">Type</span>\n <div class=\"cqa-api-edit-step-payload-type-radios\">\n <cqa-segment-control [value]=\"payloadType\" [segments]=\"payloadTypeSegments\"\n (valueChange)=\"onPayloadTypeChange($event)\"\n class=\"cqa-api-edit-step-payload-type-segment\">\n </cqa-segment-control>\n </div>\n <div *ngIf=\"payloadType === 'raw'\" class=\"cqa-api-edit-step-payload-format-wrap\">\n <span class=\"cqa-api-edit-step-payload-format-label\">Format:</span>\n <cqa-dynamic-select *ngIf=\"payloadFormatForm\" [form]=\"payloadFormatForm\"\n [config]=\"payloadFormatSelectConfig\" class=\"cqa-api-edit-step-payload-format-select\"\n aria-label=\"Format\">\n </cqa-dynamic-select>\n </div>\n </div>\n <!-- Raw: text area with line numbers (Postman-style payload body) -->\n <div *ngIf=\"payloadType === 'raw'\" class=\"cqa-api-edit-step-payload-body\" #payloadEditorWithLinesRef>\n <div class=\"cqa-api-edit-step-payload-editor-with-lines\">\n <div class=\"cqa-api-edit-step-payload-line-numbers\" aria-hidden=\"true\">\n <span *ngFor=\"let n of payloadLineNumbers\" class=\"cqa-api-edit-step-payload-line-num\">\n <span *ngIf=\"payloadJsonError && payloadJsonError.line === n\"\n class=\"cqa-api-edit-step-payload-line-error-icon\" [title]=\"payloadJsonErrorTooltip\"\n aria-label=\"Parse error on this line\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#EF4444\"/>\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n <span class=\"cqa-api-edit-step-payload-line-num-text\">{{ n }}</span>\n </span>\n </div>\n <div class=\"cqa-api-edit-step-payload-textarea-cell\">\n <div class=\"cqa-api-edit-step-payload-textarea cqa-w-full cqa-flex cqa-flex-col cqa-min-h-0\"\n [ngClass]=\"{'cqa-api-edit-step-payload-textarea--error': payloadJsonError}\">\n <textarea #payloadTextareaRef\n class=\"cqa-api-edit-step-payload-textarea-input cqa-w-full cqa-outline-none cqa-box-border\"\n [ngClass]=\"{'cqa-api-edit-step-payload-textarea-input--error': payloadJsonError}\"\n [value]=\"payloadText\"\n placeholder=\"\"\n [attr.aria-label]=\"'Payload'\"\n [attr.aria-invalid]=\"!!payloadJsonError\"\n (input)=\"onPayloadInput($event)\"\n (keydown)=\"onPayloadKeydown($event)\">\n </textarea>\n </div>\n </div>\n </div>\n <p *ngIf=\"payloadJsonError\" class=\"cqa-api-edit-step-payload-json-error-msg\">\n Invalid JSON format. Please check your syntax.\n </p>\n </div>\n\n <!-- x-www-form-urlencoded: Key\u2013Value rows, add/remove dynamically -->\n <div *ngIf=\"payloadType === 'x-www-form-urlencoded'\" class=\"cqa-api-edit-step-key-value\">\n <div class=\"cqa-api-edit-step-key-value-grid cqa-api-edit-step-key-value-header\">\n <span class=\"cqa-api-edit-step-key-value-label\">Key</span>\n <span class=\"cqa-api-edit-step-key-value-label\">Value</span>\n <span class=\"cqa-api-edit-step-key-value-label cqa-api-edit-step-key-value-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of keyValueRows; let i = index; trackBy: trackByKeyValue\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-key-value-row\">\n <cqa-custom-input [value]=\"row.get('key')?.value ?? ''\"\n (valueChange)=\"row.get('key')?.setValue($event)\" placeholder=\"Key\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Key\">\n </cqa-custom-input>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-key-value-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeKeyValueRow(i)\">\n <svg class=\"cqa-api-edit-step-key-value-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-key-value-add-wrap\">\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"+ Add Row\"\n customClass=\"cqa-api-edit-step-key-value-add-btn\" (clicked)=\"addKeyValueRow()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Form Data: Key\u2013Type\u2013Value rows; Type is a dropdown (Text/File), add/remove dynamically -->\n <div *ngIf=\"payloadType === 'form-data'\" class=\"cqa-api-edit-step-key-type-value\">\n <div class=\"cqa-api-edit-step-key-type-value-header\">\n <span class=\"cqa-api-edit-step-key-type-value-label\">Key</span>\n <span class=\"cqa-api-edit-step-key-type-value-label\">Type</span>\n <span class=\"cqa-api-edit-step-key-type-value-label\">Value</span>\n <span class=\"cqa-api-edit-step-key-type-value-label cqa-api-edit-step-key-type-value-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of keyTypeValueRows; let i = index; trackBy: trackByKeyTypeValue\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-key-type-value-row\">\n <cqa-custom-input [value]=\"row.get('key')?.value ?? ''\"\n (valueChange)=\"row.get('key')?.setValue($event)\" placeholder=\"Key\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-type-value-input\" ariaLabel=\"Key\">\n </cqa-custom-input>\n <cqa-dynamic-select [form]=\"row\" [config]=\"keyTypeValueTypeSelectConfig\"\n class=\"cqa-api-edit-step-key-type-value-type-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-type-value-input\" ariaLabel=\"Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-key-type-value-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeKeyTypeValueRow(i)\">\n <svg class=\"cqa-api-edit-step-key-type-value-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-key-type-value-add-wrap\">\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"+ Add Row\"\n customClass=\"cqa-api-edit-step-key-type-value-add-btn\" (clicked)=\"addKeyTypeValueRow()\">\n </cqa-button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n </div>\n <!-- Step 2: Variable Name: input, validation, Back / Next -->\n <div *ngIf=\"currentStep === 2\" class=\"cqa-api-edit-step-panel cqa-flex cqa-flex-col cqa-gap-6 cqa-box-border cqa-w-full\">\n <div class=\"cqa-api-edit-step-variable-section\">\n <div class=\"cqa-api-edit-step-variable-input-wrap\">\n <cqa-custom-input [(value)]=\"variableName\" [label]=\"''\" placeholder=\"Variable Name\" [fullWidth]=\"true\"\n size=\"md\" (valueChange)=\"onVariableNameChange()\" aria-label=\"Variable Name\">\n </cqa-custom-input>\n </div>\n <p *ngIf=\"variableNameError\" class=\"cqa-api-edit-step-variable-error\" role=\"alert\">{{ variableNameError }}</p>\n </div>\n </div>\n <!-- Step 3: Response Body / Status tabs -->\n <div *ngIf=\"currentStep === 3\" class=\"cqa-api-edit-step-panel cqa-flex cqa-flex-col cqa-gap-6 cqa-box-border cqa-w-full\">\n <div class=\"cqa-api-edit-step-tabs-wrapper\">\n <div class=\"cqa-api-edit-step-tabs\">\n <cqa-button *ngFor=\"let tab of responseVerificationTabs\" type=\"button\" variant=\"text\" [text]=\"tab.label\"\n [customClass]=\"'cqa-api-edit-step-tab' + (activeResponseVerificationTab === tab.value ? ' cqa-api-edit-step-tab--active' : '')\"\n (clicked)=\"setResponseVerificationTab(tab.value)\">\n </cqa-button>\n </div>\n\n <!-- Response Body tab content: verification grid -->\n <div *ngIf=\"activeResponseVerificationTab === 'response-body'\" class=\"cqa-api-edit-step-step3-content\">\n <div class=\"cqa-api-edit-step-verification-header-row\">\n <span></span>\n <cqa-button type=\"button\" variant=\"text\" text=\"Add Verification\"\n customClass=\"cqa-api-edit-step-verification-add-link\" (clicked)=\"addVerificationRow()\">\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-verification\">\n <div class=\"cqa-api-edit-step-verification-grid cqa-api-edit-step-verification-grid-header\">\n <span class=\"cqa-api-edit-step-verification-label\">S.no</span>\n <span class=\"cqa-api-edit-step-verification-label\">JSON Path</span>\n <span class=\"cqa-api-edit-step-verification-label\">Verification</span>\n <span class=\"cqa-api-edit-step-verification-label\">Data Type</span>\n <span class=\"cqa-api-edit-step-verification-label\">Expected Value</span>\n <span class=\"cqa-api-edit-step-verification-label cqa-api-edit-step-verification-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of verificationRows; let i = index; trackBy: trackByVerification\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-verification-row\">\n <span class=\"cqa-api-edit-step-verification-sno\">{{ i + 1 }}</span>\n <cqa-custom-input [value]=\"row.get('jsonPath')?.value ?? ''\"\n (valueChange)=\"row.get('jsonPath')?.setValue($event)\" placeholder=\"Json Path\" [fullWidth]=\"true\"\n size=\"sm\" class=\"cqa-api-edit-step-verification-input\" ariaLabel=\"JSON Path\">\n </cqa-custom-input>\n <cqa-dynamic-select [form]=\"row\" [config]=\"verificationSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"row\" [config]=\"verificationDataTypeSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-w-full\"\n (selectionChange)=\"onVerificationDataTypeChange(row, $event)\">\n </cqa-dynamic-select>\n <!-- Expected Value: text for String/Array/Object, number for Number, dropdown for Boolean -->\n <ng-container [ngSwitch]=\"row.get('dataType')?.value\">\n <cqa-dynamic-select *ngSwitchCase=\"'boolean'\" [form]=\"row\"\n [config]=\"verificationExpectedValueBooleanSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-api-edit-step-verification-expected-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input *ngSwitchCase=\"'number'\" [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\" placeholder=\"Expected Value (number)\"\n type=\"number\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-verification-input cqa-api-edit-step-verification-expected-number\"\n ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n <cqa-custom-input *ngSwitchDefault [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\"\n placeholder=\"Expected Value in String\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-verification-input\" ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n </ng-container>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-verification-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeVerificationRow(i)\">\n <svg class=\"cqa-api-edit-step-verification-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n </div>\n </div>\n\n <!-- Status tab content: S.no, Verification dropdown, Expected Value, add/remove rows -->\n <div *ngIf=\"activeResponseVerificationTab === 'status'\" class=\"cqa-api-edit-step-step3-content\">\n <div class=\"cqa-api-edit-step-verification-header-row\">\n <span></span>\n <cqa-button type=\"button\" variant=\"text\" text=\"Add Verification\"\n customClass=\"cqa-api-edit-step-verification-add-link\" (clicked)=\"addStatusVerificationRow()\">\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-status-verification\">\n <div class=\"cqa-api-edit-step-status-verification-header\">\n <span class=\"cqa-api-edit-step-verification-label\">S.no</span>\n <span class=\"cqa-api-edit-step-verification-label\">Verification</span>\n <span class=\"cqa-api-edit-step-verification-label\">Expected Value</span>\n <span class=\"cqa-api-edit-step-verification-label cqa-api-edit-step-verification-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of statusVerificationRows; let i = index; trackBy: trackByStatusVerification\"\n [formGroup]=\"row\" class=\"cqa-api-edit-step-status-verification-row\">\n <span class=\"cqa-api-edit-step-verification-sno\">{{ i + 1 }}</span>\n <cqa-dynamic-select [form]=\"row\" [config]=\"statusVerificationSelectConfig\"\n class=\"cqa-api-edit-step-status-verification-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\" placeholder=\"Expected Value\"\n type=\"number\" [fullWidth]=\"true\" size=\"sm\" class=\"cqa-api-edit-step-verification-input\"\n ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-verification-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeStatusVerificationRow(i)\">\n <svg class=\"cqa-api-edit-step-verification-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Response Preview -->\n <div class=\"cqa-api-edit-step-response\">\n <h3 class=\"cqa-api-edit-step-response-title cqa-text-[14px] cqa-font-bold cqa-leading-[20px] cqa-text-[#111827] cqa-m-0 cqa-mb-[12px] cqa-shrink-0\">Response Preview</h3>\n <pre class=\"cqa-api-edit-step-response-content\">{{ responsePreview }}</pre>\n </div>\n\n <!-- Step actions: one row, full width. Step 1: Cancel + Next; Step 2: Back + Next; Step 3: Back + Create -->\n <div class=\"cqa-api-edit-step-actions\">\n <ng-container [ngSwitch]=\"currentStep\">\n <ng-container *ngSwitchCase=\"1\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Cancel\"\n customClass=\"cqa-api-edit-step-actions-btn-cancel\" (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Next\"\n customClass=\"cqa-api-edit-step-actions-btn-next\" (clicked)=\"onNext()\">\n </cqa-button>\n </ng-container>\n <ng-container *ngSwitchCase=\"2\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Back\"\n customClass=\"cqa-api-edit-step-actions-btn-back\" (clicked)=\"onBack()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Next\"\n customClass=\"cqa-api-edit-step-actions-btn-next\" (clicked)=\"onNext()\">\n </cqa-button>\n </ng-container>\n <ng-container *ngSwitchCase=\"3\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Back\"\n customClass=\"cqa-api-edit-step-actions-btn-back\" (clicked)=\"onBack()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" [text]=\"editMode ? 'Update' : 'Create'\"\n customClass=\"cqa-api-edit-step-actions-btn-create\" (clicked)=\"onCreate()\">\n </cqa-button>\n </ng-container>\n </ng-container>\n </div>\n</div>", components: [{ type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: CustomInputComponent, selector: "cqa-custom-input", inputs: ["label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }, { type: CustomTextareaComponent, selector: "cqa-custom-textarea", inputs: ["label", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "rows", "cols", "resize", "textareaInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused"] }, { type: SegmentControlComponent, selector: "cqa-segment-control", inputs: ["segments", "value", "disabled", "containerBgColor"], outputs: ["valueChange"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }], changeDetection: i0.ChangeDetectionStrategy.Default });
20709
21291
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ApiEditStepComponent, decorators: [{
20710
21292
  type: Component,
20711
- args: [{ selector: 'cqa-api-edit-step', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.Default, template: "<div class=\"cqa-api-edit-step-container\">\n <!-- Title -->\n <h2\n class=\"cqa-api-edit-step-title cqa-font-inter cqa-text-[12px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal cqa-text-[#000000]\">\n Create API Test Step</h2>\n\n <!-- Step indicator: all three steps visible, active step highlighted (Postman-style) -->\n <div class=\"cqa-api-edit-step-indicator\">\n <ng-container *ngFor=\"let step of stepLabels; let i = index\">\n <cqa-button type=\"button\" variant=\"text\"\n customClass=\"cqa-api-edit-step-indicator-item cqa-api-edit-step-indicator-item--clickable\"\n [attr.aria-label]=\"'Step ' + step.index + ': ' + step.label\" [attr.aria-pressed]=\"step.index === currentStep\"\n (clicked)=\"setStep(step.index)\">\n <span class=\"cqa-api-edit-step-indicator-circle\"\n [class.cqa-api-edit-step-indicator-circle--active]=\"step.index === currentStep\">\n {{ step.index }}\n </span>\n <span class=\"cqa-api-edit-step-indicator-label\"\n [class.cqa-api-edit-step-indicator-label--active]=\"step.index === currentStep\">\n {{ step.label }}\n </span>\n <div *ngIf=\"i < stepLabels.length - 1\" class=\"cqa-api-edit-step-indicator-line\" aria-hidden=\"true\"></div>\n </cqa-button>\n </ng-container>\n </div>\n\n <!-- Step content viewport: smooth slide between steps -->\n <div class=\"cqa-api-edit-step-viewport\">\n <div class=\"cqa-api-edit-step-strip\" [style.transform]=\"'translateX(' + stripTranslatePercent + '%)'\">\n <!-- Step 1: Environment, request, body, response -->\n <div class=\"cqa-api-edit-step-panel\">\n <!-- Environment row: new line, select aligned right -->\n <div class=\"cqa-api-edit-step-environment-row\">\n <cqa-dynamic-select *ngIf=\"environmentForm\" [form]=\"environmentForm\" [config]=\"environmentSelectConfig\"\n class=\"cqa-api-edit-step-environment-select\" aria-label=\"Environment\"\n (selectionChange)=\"onEnvironmentSelectionChange($event)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Request row: method, URL, buttons -->\n <div class=\"cqa-api-edit-step-request-row\">\n <cqa-dynamic-select *ngIf=\"methodForm\" [form]=\"methodForm\" [config]=\"methodSelectConfig\"\n class=\"cqa-api-edit-step-method-select\" aria-label=\"HTTP method\"\n (selectionChange)=\"onMethodSelectionChange($event)\">\n </cqa-dynamic-select>\n <div class=\"cqa-api-edit-step-url-wrap\">\n <cqa-custom-input [(value)]=\"url\" [label]=\"''\" placeholder=\"\" [fullWidth]=\"true\" size=\"md\">\n </cqa-custom-input>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-trigger\" style=\"display: contents\" (click)=\"openImportCurlPanel()\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Import API cURL\"\n customClass=\"cqa-api-edit-step-btn-outline cqa-font-inter cqa-text-[14px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal cqa-text-[#414146]\">\n </cqa-button>\n </div>\n <cqa-button variant=\"filled\" btnSize=\"lg\" text=\"Send Request\" (clicked)=\"onSendRequest()\"\n customClass=\"cqa-api-edit-step-btn-primary cqa-font-inter cqa-text-[14px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal cqa-text-[#FBFCFF]\">\n </cqa-button>\n </div>\n\n\n\n <!-- Body content: header section (default) OR import cURL section -->\n <ng-container *ngIf=\"bodyView === 'import-curl'\">\n <div class=\"cqa-api-edit-step-import-curl-panel\">\n <div class=\"cqa-api-edit-step-import-curl-header\">\n <h3 class=\"cqa-api-edit-step-import-curl-title\">Import API cURL</h3>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-separator\"></div>\n <div class=\"cqa-api-edit-step-import-curl-body\">\n <cqa-custom-textarea [value]=\"importCurlControl.value\"\n (valueChange)=\"importCurlControl.setValue($event)\"\n placeholder=\"Paste your cURL command here (e.g., curl -X POST https://api.example.com/users)\"\n [fullWidth]=\"true\" [rows]=\"8\" resize=\"vertical\" size=\"md\"\n class=\"cqa-api-edit-step-import-curl-textarea\">\n </cqa-custom-textarea>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-footer\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Cancel\"\n customClass=\"cqa-api-edit-step-import-curl-btn-cancel\" (clicked)=\"onCancelImportCurl()\"></cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Import\"\n customClass=\"cqa-api-edit-step-import-curl-btn-import\" (clicked)=\"onImportCurlConfirm()\"></cqa-button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"bodyView === 'headers'\">\n <div class=\"cqa-api-edit-step-tabs-wrapper\">\n <div class=\"cqa-api-edit-step-tabs\">\n <cqa-button *ngFor=\"let tab of payloadTabs\" type=\"button\" variant=\"text\" [text]=\"tab.label\"\n [customClass]=\"'cqa-api-edit-step-tab' + (activePayloadTab === tab.value ? ' cqa-api-edit-step-tab--active' : '') + (isMethodWithoutBody && tab.value !== 'headers' ? ' cqa-api-edit-step-tab--disabled' : '')\"\n [disabled]=\"isMethodWithoutBody && tab.value !== 'headers'\"\n (clicked)=\"setPayloadTab(tab.value)\">\n </cqa-button>\n </div>\n\n <!-- Payload content (Headers) -->\n <div *ngIf=\"activePayloadTab === 'headers'\" class=\"cqa-api-edit-step-payload\">\n <div class=\"cqa-api-edit-step-headers-grid\">\n <span class=\"cqa-api-edit-step-headers-label\">Header Name</span>\n <span class=\"cqa-api-edit-step-headers-label\">Header Value</span>\n <span class=\"cqa-api-edit-step-headers-label cqa-api-edit-step-headers-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of headerRows; let i = index; trackBy: trackByHeader\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-header-row\">\n <cqa-dynamic-select [form]=\"row\" [config]=\"headerNameSelectConfig\"\n (addCustomValue)=\"onHeaderNameAddCustomValue($event, row)\"\n class=\"cqa-api-edit-step-header-type-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-header-value-input\" ariaLabel=\"Header value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-header-delete'\"\n [tooltip]=\"'Remove header'\" (clicked)=\"removeHeader(i)\">\n <svg class=\"cqa-api-edit-step-header-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-add-header-wrap\">\n <cqa-button type=\"button\" variant=\"text\" text=\"+ Add Header\"\n [customClass]=\"'cqa-api-edit-step-add-header-link'\" (clicked)=\"addHeader()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Payload content (Body only): type, format, text area, Back/Next -->\n <div *ngIf=\"activePayloadTab === 'body'\"\n class=\"cqa-api-edit-step-payload cqa-api-edit-step-payload-editor\">\n <div class=\"cqa-api-edit-step-payload-type-row\">\n <span class=\"cqa-api-edit-step-payload-type-label\">Type</span>\n <div class=\"cqa-api-edit-step-payload-type-radios\">\n <cqa-segment-control [value]=\"payloadType\" [segments]=\"payloadTypeSegments\"\n (valueChange)=\"onPayloadTypeChange($event)\"\n class=\"cqa-api-edit-step-payload-type-segment\">\n </cqa-segment-control>\n </div>\n <div *ngIf=\"payloadType === 'raw'\" class=\"cqa-api-edit-step-payload-format-wrap\">\n <span class=\"cqa-api-edit-step-payload-format-label\">Format:</span>\n <cqa-dynamic-select *ngIf=\"payloadFormatForm\" [form]=\"payloadFormatForm\"\n [config]=\"payloadFormatSelectConfig\" class=\"cqa-api-edit-step-payload-format-select\"\n aria-label=\"Format\">\n </cqa-dynamic-select>\n </div>\n </div>\n <!-- Raw: text area with line numbers (Postman-style payload body) -->\n <div *ngIf=\"payloadType === 'raw'\" class=\"cqa-api-edit-step-payload-body\" #payloadEditorWithLinesRef>\n <div class=\"cqa-api-edit-step-payload-editor-with-lines\">\n <div class=\"cqa-api-edit-step-payload-line-numbers\" aria-hidden=\"true\">\n <span *ngFor=\"let n of payloadLineNumbers\" class=\"cqa-api-edit-step-payload-line-num\">\n <span *ngIf=\"payloadJsonError && payloadJsonError.line === n\"\n class=\"cqa-api-edit-step-payload-line-error-icon\" [title]=\"payloadJsonErrorTooltip\"\n aria-label=\"Parse error on this line\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#EF4444\"/>\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n <span class=\"cqa-api-edit-step-payload-line-num-text\">{{ n }}</span>\n </span>\n </div>\n <div class=\"cqa-api-edit-step-payload-textarea-cell\">\n <div class=\"cqa-api-edit-step-payload-textarea cqa-w-full cqa-flex cqa-flex-col cqa-min-h-0\"\n [ngClass]=\"{'cqa-api-edit-step-payload-textarea--error': payloadJsonError}\">\n <textarea #payloadTextareaRef\n class=\"cqa-api-edit-step-payload-textarea-input cqa-w-full cqa-resize-y cqa-outline-none cqa-box-border\"\n [ngClass]=\"{'cqa-api-edit-step-payload-textarea-input--error': payloadJsonError}\"\n [value]=\"payloadText\"\n [attr.rows]=\"10\"\n placeholder=\"\"\n [attr.aria-label]=\"'Payload'\"\n [attr.aria-invalid]=\"!!payloadJsonError\"\n (input)=\"onPayloadInput($event)\"\n (keydown)=\"onPayloadKeydown($event)\">\n </textarea>\n </div>\n </div>\n </div>\n <p *ngIf=\"payloadJsonError\" class=\"cqa-api-edit-step-payload-json-error-msg\">\n Invalid JSON format. Please check your syntax.\n </p>\n </div>\n\n <!-- x-www-form-urlencoded: Key\u2013Value rows, add/remove dynamically -->\n <div *ngIf=\"payloadType === 'x-www-form-urlencoded'\" class=\"cqa-api-edit-step-key-value\">\n <div class=\"cqa-api-edit-step-key-value-grid cqa-api-edit-step-key-value-header\">\n <span class=\"cqa-api-edit-step-key-value-label\">Key</span>\n <span class=\"cqa-api-edit-step-key-value-label\">Value</span>\n <span class=\"cqa-api-edit-step-key-value-label cqa-api-edit-step-key-value-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of keyValueRows; let i = index; trackBy: trackByKeyValue\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-key-value-row\">\n <cqa-custom-input [value]=\"row.get('key')?.value ?? ''\"\n (valueChange)=\"row.get('key')?.setValue($event)\" placeholder=\"Key\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Key\">\n </cqa-custom-input>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-key-value-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeKeyValueRow(i)\">\n <svg class=\"cqa-api-edit-step-key-value-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-key-value-add-wrap\">\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"+ Add Row\"\n customClass=\"cqa-api-edit-step-key-value-add-btn\" (clicked)=\"addKeyValueRow()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Form Data: Key\u2013Type\u2013Value rows; Type is a dropdown (Text/File), add/remove dynamically -->\n <div *ngIf=\"payloadType === 'form-data'\" class=\"cqa-api-edit-step-key-type-value\">\n <div class=\"cqa-api-edit-step-key-type-value-header\">\n <span class=\"cqa-api-edit-step-key-type-value-label\">Key</span>\n <span class=\"cqa-api-edit-step-key-type-value-label\">Type</span>\n <span class=\"cqa-api-edit-step-key-type-value-label\">Value</span>\n <span class=\"cqa-api-edit-step-key-type-value-label cqa-api-edit-step-key-type-value-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of keyTypeValueRows; let i = index; trackBy: trackByKeyTypeValue\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-key-type-value-row\">\n <cqa-custom-input [value]=\"row.get('key')?.value ?? ''\"\n (valueChange)=\"row.get('key')?.setValue($event)\" placeholder=\"Key\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-type-value-input\" ariaLabel=\"Key\">\n </cqa-custom-input>\n <cqa-dynamic-select [form]=\"row\" [config]=\"keyTypeValueTypeSelectConfig\"\n class=\"cqa-api-edit-step-key-type-value-type-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-type-value-input\" ariaLabel=\"Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-key-type-value-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeKeyTypeValueRow(i)\">\n <svg class=\"cqa-api-edit-step-key-type-value-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-key-type-value-add-wrap\">\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"+ Add Row\"\n customClass=\"cqa-api-edit-step-key-type-value-add-btn\" (clicked)=\"addKeyTypeValueRow()\">\n </cqa-button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n </div>\n <!-- Step 2: Variable Name: input, validation, Back / Next -->\n <div class=\"cqa-api-edit-step-panel\">\n <div class=\"cqa-api-edit-step-variable-section\">\n <div class=\"cqa-api-edit-step-variable-input-wrap\">\n <cqa-custom-input [(value)]=\"variableName\" [label]=\"''\" placeholder=\"Variable Name\" [fullWidth]=\"true\"\n size=\"md\" (valueChange)=\"onVariableNameChange()\" aria-label=\"Variable Name\">\n </cqa-custom-input>\n </div>\n <p *ngIf=\"variableNameError\" class=\"cqa-api-edit-step-variable-error\" role=\"alert\">{{ variableNameError }}</p>\n </div>\n </div>\n <!-- Step 3: Response Body / Status tabs -->\n <div class=\"cqa-api-edit-step-panel\">\n <div class=\"cqa-api-edit-step-tabs-wrapper\">\n <div class=\"cqa-api-edit-step-tabs\">\n <cqa-button *ngFor=\"let tab of responseVerificationTabs\" type=\"button\" variant=\"text\" [text]=\"tab.label\"\n [customClass]=\"'cqa-api-edit-step-tab' + (activeResponseVerificationTab === tab.value ? ' cqa-api-edit-step-tab--active' : '')\"\n (clicked)=\"setResponseVerificationTab(tab.value)\">\n </cqa-button>\n </div>\n\n <!-- Response Body tab content: verification grid -->\n <div *ngIf=\"activeResponseVerificationTab === 'response-body'\" class=\"cqa-api-edit-step-step3-content\">\n <div class=\"cqa-api-edit-step-verification-header-row\">\n <span></span>\n <cqa-button type=\"button\" variant=\"text\" text=\"Add Verification\"\n customClass=\"cqa-api-edit-step-verification-add-link\" (clicked)=\"addVerificationRow()\">\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-verification\">\n <div class=\"cqa-api-edit-step-verification-grid cqa-api-edit-step-verification-grid-header\">\n <span class=\"cqa-api-edit-step-verification-label\">S.no</span>\n <span class=\"cqa-api-edit-step-verification-label\">JSON Path</span>\n <span class=\"cqa-api-edit-step-verification-label\">Verification</span>\n <span class=\"cqa-api-edit-step-verification-label\">Data Type</span>\n <span class=\"cqa-api-edit-step-verification-label\">Expected Value</span>\n <span class=\"cqa-api-edit-step-verification-label cqa-api-edit-step-verification-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of verificationRows; let i = index; trackBy: trackByVerification\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-verification-row\">\n <span class=\"cqa-api-edit-step-verification-sno\">{{ i + 1 }}</span>\n <cqa-custom-input [value]=\"row.get('jsonPath')?.value ?? ''\"\n (valueChange)=\"row.get('jsonPath')?.setValue($event)\" placeholder=\"Json Path\" [fullWidth]=\"true\"\n size=\"sm\" class=\"cqa-api-edit-step-verification-input\" ariaLabel=\"JSON Path\">\n </cqa-custom-input>\n <cqa-dynamic-select [form]=\"row\" [config]=\"verificationSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"row\" [config]=\"verificationDataTypeSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-w-full\"\n (selectionChange)=\"onVerificationDataTypeChange(row, $event)\">\n </cqa-dynamic-select>\n <!-- Expected Value: text for String/Array/Object, number for Number, dropdown for Boolean -->\n <ng-container [ngSwitch]=\"row.get('dataType')?.value\">\n <cqa-dynamic-select *ngSwitchCase=\"'boolean'\" [form]=\"row\"\n [config]=\"verificationExpectedValueBooleanSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-api-edit-step-verification-expected-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input *ngSwitchCase=\"'number'\" [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\" placeholder=\"Expected Value (number)\"\n type=\"number\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-verification-input cqa-api-edit-step-verification-expected-number\"\n ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n <cqa-custom-input *ngSwitchDefault [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\"\n placeholder=\"Expected Value in String\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-verification-input\" ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n </ng-container>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-verification-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeVerificationRow(i)\">\n <svg class=\"cqa-api-edit-step-verification-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n </div>\n </div>\n\n <!-- Status tab content: S.no, Verification dropdown, Expected Value, add/remove rows -->\n <div *ngIf=\"activeResponseVerificationTab === 'status'\" class=\"cqa-api-edit-step-step3-content\">\n <div class=\"cqa-api-edit-step-verification-header-row\">\n <span></span>\n <cqa-button type=\"button\" variant=\"text\" text=\"Add Verification\"\n customClass=\"cqa-api-edit-step-verification-add-link\" (clicked)=\"addStatusVerificationRow()\">\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-status-verification\">\n <div class=\"cqa-api-edit-step-status-verification-header\">\n <span class=\"cqa-api-edit-step-verification-label\">S.no</span>\n <span class=\"cqa-api-edit-step-verification-label\">Verification</span>\n <span class=\"cqa-api-edit-step-verification-label\">Expected Value</span>\n <span class=\"cqa-api-edit-step-verification-label cqa-api-edit-step-verification-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of statusVerificationRows; let i = index; trackBy: trackByStatusVerification\"\n [formGroup]=\"row\" class=\"cqa-api-edit-step-status-verification-row\">\n <span class=\"cqa-api-edit-step-verification-sno\">{{ i + 1 }}</span>\n <cqa-dynamic-select [form]=\"row\" [config]=\"statusVerificationSelectConfig\"\n class=\"cqa-api-edit-step-status-verification-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\" placeholder=\"Expected Value\"\n type=\"number\" [fullWidth]=\"true\" size=\"sm\" class=\"cqa-api-edit-step-verification-input\"\n ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-verification-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeStatusVerificationRow(i)\">\n <svg class=\"cqa-api-edit-step-verification-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Response Preview -->\n <div class=\"cqa-api-edit-step-response\">\n <h3 class=\"cqa-api-edit-step-response-title\">Response Preview</h3>\n <pre class=\"cqa-api-edit-step-response-content\">{{ responsePreview }}</pre>\n </div>\n\n <!-- Step actions: one row, full width. Step 1: Cancel + Next; Step 2: Back + Next; Step 3: Back + Create -->\n <div class=\"cqa-api-edit-step-actions\">\n <ng-container [ngSwitch]=\"currentStep\">\n <ng-container *ngSwitchCase=\"1\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Cancel\"\n customClass=\"cqa-api-edit-step-actions-btn-cancel\" (clicked)=\"onBack()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Next\"\n customClass=\"cqa-api-edit-step-actions-btn-next\" (clicked)=\"onNext()\">\n </cqa-button>\n </ng-container>\n <ng-container *ngSwitchCase=\"2\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Back\"\n customClass=\"cqa-api-edit-step-actions-btn-back\" (clicked)=\"onBack()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Next\"\n customClass=\"cqa-api-edit-step-actions-btn-next\" (clicked)=\"onNext()\">\n </cqa-button>\n </ng-container>\n <ng-container *ngSwitchCase=\"3\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Back\"\n customClass=\"cqa-api-edit-step-actions-btn-back\" (clicked)=\"onBack()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Create\"\n customClass=\"cqa-api-edit-step-actions-btn-create\" (clicked)=\"onCreate()\">\n </cqa-button>\n </ng-container>\n </ng-container>\n </div>\n</div>" }]
21293
+ args: [{ selector: 'cqa-api-edit-step', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.Default, template: "<div class=\"cqa-api-edit-step-container cqa-bg-[#ffffff] cqa-flex cqa-flex-col cqa-w-full cqa-h-full cqa-p-[16px] cqa-gap-[12px] cqa-overflow-y-auto cqa-overflow-x-hidden cqa-box-border\">\n\n <h2 class=\"cqa-api-edit-step-title cqa-font-inter cqa-text-[12px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal cqa-text-[#000000] cqa-m-0\">\n {{ editMode ? 'Update API Test Step' : 'Create API Test Step' }}\n </h2>\n\n <div class=\"cqa-api-edit-step-indicator cqa-flex cqa-items-center cqa-gap-0 cqa-max-[767px]:cqa-flex-wrap cqa-max-[767px]:cqa-gap-2 cqa-max-[767px]:cqa-justify-start\"\n [class.cqa-justify-start]=\"stepLabels.length === 1\"\n [class.cqa-justify-between]=\"stepLabels.length !== 1\">\n <ng-container *ngFor=\"let step of stepLabels; let i = index\">\n <cqa-button type=\"button\" variant=\"text\"\n customClass=\"cqa-api-edit-step-indicator-item cqa-api-edit-step-indicator-item--clickable cqa-flex cqa-items-center cqa-gap-[10px] cqa-cursor-pointer cqa-border-none cqa-p-0 cqa-font-inherit cqa-text-inherit cqa-text-left !cqa-bg-transparent\"\n [attr.aria-label]=\"'Step ' + step.index + ': ' + step.label\" [attr.aria-pressed]=\"step.index === currentStep\"\n (clicked)=\"setStep(step.index)\">\n <span class=\"cqa-api-edit-step-indicator-circle cqa-w-8 cqa-h-8 cqa-rounded-full cqa-inline-flex cqa-items-center cqa-justify-center cqa-text-sm cqa-font-medium cqa-leading-none cqa-border-none cqa-shrink-0\"\n [ngClass]=\"step.index === currentStep ? 'cqa-bg-[#4F46E5] cqa-text-white' : 'cqa-bg-[#E0E0E0] cqa-text-[#666666]'\">\n {{ step.index }}\n </span>\n <span class=\"cqa-api-edit-step-indicator-label cqa-text-sm cqa-leading-[18px] cqa-font-normal cqa-max-[767px]:cqa-text-xs\"\n [ngClass]=\"step.index === currentStep ? 'cqa-text-[#4F46E5]' : 'cqa-text-[#666666]'\">\n {{ step.label }}\n </span>\n <div *ngIf=\"i < stepLabels.length - 1\" class=\"cqa-api-edit-step-indicator-line cqa-w-[96px] cqa-h-[2px] cqa-bg-[#E0E0E0] cqa-my-0 cqa-mx-[6px] cqa-shrink-0 cqa-self-center cqa-max-[767px]:cqa-w-[24px] cqa-max-[767px]:cqa-mx-1\" aria-hidden=\"true\"></div>\n </cqa-button>\n </ng-container>\n </div>\n\n <!-- Step content viewport: only the active step body is shown (*ngIf) -->\n <div class=\"cqa-api-edit-step-viewport cqa-w-full\">\n <!-- Step 1: Environment, request, body, response -->\n <div *ngIf=\"currentStep === 1\" class=\"cqa-api-edit-step-panel cqa-flex cqa-flex-col cqa-gap-6 cqa-box-border cqa-w-full\">\n <!-- Environment row: new line, select aligned right -->\n <div class=\"cqa-api-edit-step-environment-row cqa-flex cqa-justify-end cqa-items-center\">\n <cqa-dynamic-select *ngIf=\"environmentForm\" [form]=\"environmentForm\" [config]=\"environmentSelectConfig\"\n class=\"cqa-api-edit-step-environment-select cqa-shrink-0 cqa-w-auto cqa-min-w-[315px] cqa-max-w-[315px] cqa-max-[767px]:cqa-min-w-0 cqa-max-[767px]:cqa-max-w-full cqa-max-[767px]:cqa-w-full [&_.mat-form-field-wrapper]:cqa-pb-0\" aria-label=\"Environment\"\n (selectionChange)=\"onEnvironmentSelectionChange($event)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Request row: method, URL, buttons -->\n <div class=\"cqa-api-edit-step-request-row cqa-flex cqa-items-center cqa-gap-3 cqa-flex-wrap cqa-max-[767px]:cqa-flex-col cqa-max-[767px]:cqa-items-stretch cqa-max-[767px]:cqa-gap-2.5\">\n <cqa-dynamic-select *ngIf=\"methodForm\" [form]=\"methodForm\" [config]=\"methodSelectConfig\"\n class=\"cqa-api-edit-step-method-select cqa-shrink-0 cqa-w-auto cqa-min-w-[152px] cqa-max-w-[152px] cqa-max-[767px]:cqa-min-w-0 cqa-max-[767px]:cqa-max-w-full cqa-max-[767px]:cqa-w-full\" aria-label=\"HTTP method\"\n (selectionChange)=\"onMethodSelectionChange($event)\">\n </cqa-dynamic-select>\n <div class=\"cqa-api-edit-step-url-wrap cqa-flex-1 cqa-min-w-[200px] cqa-max-[767px]:cqa-min-w-0 cqa-max-[767px]:cqa-w-full [&_cqa-custom-input_.cqa-relative_input]:cqa-h-[40px] [&_cqa-custom-input_.cqa-relative_input]:cqa-bg-white [&_cqa-custom-input_.cqa-relative_input]:cqa-border [&_cqa-custom-input_.cqa-relative_input]:cqa-border-solid [&_cqa-custom-input_.cqa-relative_input]:cqa-border-[#D1D5DB] [&_cqa-custom-input_.cqa-relative_input]:cqa-rounded-md [&_cqa-custom-input_.cqa-relative_input]:cqa-text-sm [&_cqa-custom-input_.cqa-relative_input]:cqa-text-[#374151]\">\n <cqa-custom-input [(value)]=\"url\" [label]=\"''\" placeholder=\"\" [fullWidth]=\"true\" size=\"md\">\n </cqa-custom-input>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-trigger cqa-contents cqa-max-[767px]:cqa-w-full cqa-max-[767px]:!cqa-flex\" (click)=\"openImportCurlPanel()\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Import API cURL\"\n customClass=\"cqa-api-edit-step-btn-outline !cqa-bg-white !cqa-border !cqa-border-solid !cqa-border-[#6B7280] cqa-text-[#414146] cqa-font-inter cqa-text-[14px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal hover:!cqa-bg-[#F9FAFB] hover:!cqa-text-[#414146] cqa-max-[767px]:cqa-w-full\">\n </cqa-button>\n </div>\n <cqa-button variant=\"filled\" btnSize=\"lg\" text=\"Send Request\" (clicked)=\"onSendRequest()\"\n customClass=\"cqa-api-edit-step-btn-primary cqa-font-inter cqa-text-[14px] cqa-font-semibold cqa-leading-[100%] cqa-tracking-normal !cqa-bg-[#3F43EE] cqa-text-[#FBFCFF] !cqa-border-none cqa-py-2.5 cqa-px-6 cqa-gap-2 cqa-rounded-lg cqa-min-h-[37px] cqa-box-border hover:!cqa-bg-[#1B1FEB] cqa-max-[767px]:cqa-w-full\">\n </cqa-button>\n </div>\n\n\n\n <!-- Body content: header section (default) OR import cURL section -->\n <ng-container *ngIf=\"bodyView === 'import-curl'\">\n <div class=\"cqa-api-edit-step-import-curl-panel cqa-flex cqa-flex-col cqa-bg-white cqa-rounded-lg cqa-border cqa-border-solid cqa-border-[#E5E7EB] cqa-shadow-[0_1px_3px_rgba(0,0,0,0.08)] cqa-overflow-hidden\">\n <div class=\"cqa-api-edit-step-import-curl-header cqa-flex cqa-items-center cqa-justify-between cqa-py-3 cqa-px-5 cqa-border-b cqa-border-solid cqa-border-[#E2E8F0] cqa-bg-[#F9FAFB] cqa-rounded-t-lg cqa-max-[767px]:cqa-px-4\">\n <h3 class=\"cqa-api-edit-step-import-curl-title cqa-m-0 cqa-text-xs cqa-font-bold cqa-leading-[18px] cqa-text-[#374151]\">Import API cURL</h3>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-separator cqa-h-px cqa-bg-[#E2E8F0] cqa-my-0 cqa-mx-5\"></div>\n <div class=\"cqa-api-edit-step-import-curl-body\">\n <cqa-custom-textarea [value]=\"importCurlControl.value\"\n (valueChange)=\"importCurlControl.setValue($event)\"\n placeholder=\"Paste your cURL command here (e.g., curl -X POST https://api.example.com/users)\"\n [fullWidth]=\"true\" [rows]=\"8\" resize=\"vertical\" size=\"md\"\n class=\"cqa-api-edit-step-import-curl-textarea\">\n </cqa-custom-textarea>\n </div>\n <div class=\"cqa-api-edit-step-import-curl-footer\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Cancel\"\n customClass=\"cqa-api-edit-step-import-curl-btn-cancel\" (clicked)=\"onCancelImportCurl()\"></cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Import\"\n customClass=\"cqa-api-edit-step-import-curl-btn-import\" (clicked)=\"onImportCurlConfirm()\"></cqa-button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"bodyView === 'headers'\">\n <div class=\"cqa-api-edit-step-tabs-wrapper\">\n <div class=\"cqa-api-edit-step-tabs\">\n <cqa-button *ngFor=\"let tab of payloadTabs\" type=\"button\" variant=\"text\" [text]=\"tab.label\"\n [customClass]=\"'cqa-api-edit-step-tab' + (activePayloadTab === tab.value ? ' cqa-api-edit-step-tab--active' : '') + (isMethodWithoutBody && (tab.value === 'body' || tab.value === 'params') ? ' cqa-api-edit-step-tab--disabled' : '')\"\n [disabled]=\"isMethodWithoutBody && (tab.value === 'body' || tab.value === 'params')\"\n (clicked)=\"setPayloadTab(tab.value)\">\n </cqa-button>\n </div>\n\n <!-- Payload content (Authorization) -->\n <div *ngIf=\"activePayloadTab === 'authorization'\" class=\"cqa-api-edit-step-payload\"\n [attr.style]=\"'padding: 20px; min-height: 200px;'\">\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 20px;'\">\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 8px; width: fit-content;'\">\n <span [attr.style]=\"'font-size: 11px; font-weight: 600; letter-spacing: 0.02em; color: #6B7280; text-transform: uppercase; line-height: 1.25;'\">AUTH TYPE</span>\n <cqa-dynamic-select *ngIf=\"authTypeForm\" [form]=\"authTypeForm\" [config]=\"authTypeSelectConfig\"\n class=\"cqa-api-edit-step-auth-type-select\" aria-label=\"Auth type\"\n [attr.style]=\"'min-width: 160px;'\">\n </cqa-dynamic-select>\n </div>\n <!-- No Auth: centered message -->\n <div *ngIf=\"selectedAuthType === 'no-auth'\"\n [attr.style]=\"'flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; min-width: 0; text-align: center;'\">\n <div aria-hidden=\"true\"\n [attr.style]=\"'width: 48px; height: 48px; border-radius: 10px; background: #F3F4F6; display: flex; align-items: center; justify-content: center; flex-shrink: 0;'\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style=\"display: block;\">\n <rect x=\"5\" y=\"11\" width=\"14\" height=\"2\" rx=\"1\" fill=\"#9CA3AF\"/>\n </svg>\n </div>\n <span [attr.style]=\"'font-size: 16px; font-weight: 600; color: #374151; line-height: 1.25;'\">No Auth</span>\n <div [attr.style]=\"'display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap;'\">\n <span [attr.style]=\"'font-size: 14px; font-weight: 400; color: #9CA3AF; line-height: 1.4;'\">This request does not use any authorization.</span>\n <span role=\"img\" aria-label=\"More information\" title=\"This request does not use any authorization.\"\n [attr.style]=\"'display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; color: #9CA3AF; flex-shrink: 0;'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style=\"display: block;\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" stroke=\"#9CA3AF\" stroke-width=\"1.5\" fill=\"none\"/>\n <path d=\"M8 7v4M8 5v.5\" stroke=\"#9CA3AF\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n </div>\n </div>\n <!-- Bearer Token: Token label + textarea -->\n <div *ngIf=\"selectedAuthType === 'bearer'\"\n [attr.style]=\"'flex: 1; display: flex; flex-direction: column; gap: 10px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Token</span>\n <cqa-custom-textarea [(value)]=\"bearerToken\"\n placeholder=\"Enter bearer token\"\n [fullWidth]=\"true\" [rows]=\"6\" resize=\"vertical\" size=\"md\"\n class=\"cqa-api-edit-step-auth-token-textarea\" ariaLabel=\"Bearer token\">\n </cqa-custom-textarea>\n </div>\n <!-- OAuth 2.0: Grant Type, Access Token URL, Client ID, Client Secret, Scope, Client Authentication -->\n <div *ngIf=\"selectedAuthType === 'oauth2' && oauth2Form\"\n class=\"cqa-api-edit-step-oauth2-grid\"\n [attr.style]=\"'display: grid; grid-template-columns: 1fr 1fr; gap: 16px 24px; width: 100%;'\">\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Grant Type</span>\n <cqa-dynamic-select *ngIf=\"oauth2Form\" [form]=\"oauth2Form\" [config]=\"oauth2GrantTypeSelectConfig\"\n class=\"cqa-api-edit-step-auth-oauth-select\" aria-label=\"OAuth grant type\"\n [attr.style]=\"'min-width: 0; width: 100%;'\">\n </cqa-dynamic-select>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">OAuth grant type</span>\n </div>\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Access Token URL</span>\n <cqa-custom-input [value]=\"oauth2Form.get('accessTokenUrl')?.value\"\n (valueChange)=\"oauth2Form.get('accessTokenUrl')?.setValue($event)\"\n [label]=\"''\" placeholder=\"Enter OAuth token endpoint\" [fullWidth]=\"true\" size=\"md\"\n ariaLabel=\"Access Token URL\">\n </cqa-custom-input>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">OAuth token endpoint</span>\n </div>\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Client ID</span>\n <cqa-custom-input [value]=\"oauth2Form.get('clientId')?.value\"\n (valueChange)=\"oauth2Form.get('clientId')?.setValue($event)\"\n [label]=\"''\" placeholder=\"Enter OAuth client identifier\" [fullWidth]=\"true\" size=\"md\"\n ariaLabel=\"Client ID\">\n </cqa-custom-input>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">OAuth client identifier</span>\n </div>\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Client Secret</span>\n <cqa-custom-input [value]=\"oauth2Form.get('clientSecret')?.value\"\n (valueChange)=\"oauth2Form.get('clientSecret')?.setValue($event)\"\n type=\"password\" [label]=\"''\" placeholder=\"Enter OAuth client secret\" [fullWidth]=\"true\" size=\"md\"\n ariaLabel=\"Client Secret\">\n </cqa-custom-input>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">OAuth client secret</span>\n </div>\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Scope</span>\n <cqa-custom-input [value]=\"oauth2Form.get('scope')?.value\"\n (valueChange)=\"oauth2Form.get('scope')?.setValue($event)\"\n [label]=\"''\" placeholder=\"Enter space-separated scopes\" [fullWidth]=\"true\" size=\"md\"\n ariaLabel=\"Scope\">\n </cqa-custom-input>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">Space-separated scopes</span>\n </div>\n <div [attr.style]=\"'display: flex; flex-direction: column; gap: 6px; min-width: 0;'\">\n <span [attr.style]=\"'font-size: 12px; font-weight: 600; color: #374151; line-height: 1.25;'\">Client Authentication</span>\n <cqa-dynamic-select *ngIf=\"oauth2Form\" [form]=\"oauth2Form\" [config]=\"oauth2ClientAuthSelectConfig\"\n class=\"cqa-api-edit-step-auth-oauth-select\" aria-label=\"Client authentication method\"\n [attr.style]=\"'min-width: 0; width: 100%;'\">\n </cqa-dynamic-select>\n <span [attr.style]=\"'font-size: 11px; font-style: italic; color: #6B7280; line-height: 1.3;'\">Client authentication method</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Payload content (Headers) -->\n <div *ngIf=\"activePayloadTab === 'headers'\" class=\"cqa-api-edit-step-payload\">\n <div class=\"cqa-api-edit-step-headers-grid\">\n <span class=\"cqa-api-edit-step-headers-label\">Header Name</span>\n <span class=\"cqa-api-edit-step-headers-label\">Header Value</span>\n <span class=\"cqa-api-edit-step-headers-label cqa-api-edit-step-headers-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of headerRows; let i = index; trackBy: trackByHeader\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-header-row\">\n <cqa-dynamic-select [form]=\"row\" [config]=\"headerNameSelectConfig\"\n (addCustomValue)=\"onHeaderNameAddCustomValue($event, row)\"\n class=\"cqa-api-edit-step-header-type-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-header-value-input\" ariaLabel=\"Header value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-header-delete'\"\n [tooltip]=\"'Remove header'\" (clicked)=\"removeHeader(i)\">\n <svg class=\"cqa-api-edit-step-header-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-add-header-wrap\">\n <cqa-button type=\"button\" variant=\"text\" text=\"+ Add Header\"\n [customClass]=\"'cqa-api-edit-step-add-header-link'\" (clicked)=\"addHeader()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Payload content (Params): Key\u2013Value table with add/delete rows -->\n <div *ngIf=\"activePayloadTab === 'params'\" class=\"cqa-api-edit-step-payload\">\n <div class=\"cqa-api-edit-step-key-value-grid cqa-api-edit-step-key-value-header\">\n <span class=\"cqa-api-edit-step-key-value-label\">Key</span>\n <span class=\"cqa-api-edit-step-key-value-label\">Value</span>\n <span class=\"cqa-api-edit-step-key-value-label cqa-api-edit-step-key-value-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of paramsRows; let i = index; trackBy: trackByParams\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-key-value-row\">\n <cqa-custom-input [value]=\"row.get('key')?.value ?? ''\"\n (valueChange)=\"row.get('key')?.setValue($event)\" placeholder=\"Key\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Key\">\n </cqa-custom-input>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-key-value-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeParamsRow(i)\">\n <svg class=\"cqa-api-edit-step-key-value-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-key-value-add-wrap\">\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"+ Add Row\"\n customClass=\"cqa-api-edit-step-key-value-add-btn\" (clicked)=\"addParamsRow()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Payload content (Body only): type, format, text area, Back/Next -->\n <div *ngIf=\"activePayloadTab === 'body'\"\n class=\"cqa-api-edit-step-payload cqa-api-edit-step-payload-editor\">\n <div class=\"cqa-api-edit-step-payload-type-row\">\n <span class=\"cqa-api-edit-step-payload-type-label\">Type</span>\n <div class=\"cqa-api-edit-step-payload-type-radios\">\n <cqa-segment-control [value]=\"payloadType\" [segments]=\"payloadTypeSegments\"\n (valueChange)=\"onPayloadTypeChange($event)\"\n class=\"cqa-api-edit-step-payload-type-segment\">\n </cqa-segment-control>\n </div>\n <div *ngIf=\"payloadType === 'raw'\" class=\"cqa-api-edit-step-payload-format-wrap\">\n <span class=\"cqa-api-edit-step-payload-format-label\">Format:</span>\n <cqa-dynamic-select *ngIf=\"payloadFormatForm\" [form]=\"payloadFormatForm\"\n [config]=\"payloadFormatSelectConfig\" class=\"cqa-api-edit-step-payload-format-select\"\n aria-label=\"Format\">\n </cqa-dynamic-select>\n </div>\n </div>\n <!-- Raw: text area with line numbers (Postman-style payload body) -->\n <div *ngIf=\"payloadType === 'raw'\" class=\"cqa-api-edit-step-payload-body\" #payloadEditorWithLinesRef>\n <div class=\"cqa-api-edit-step-payload-editor-with-lines\">\n <div class=\"cqa-api-edit-step-payload-line-numbers\" aria-hidden=\"true\">\n <span *ngFor=\"let n of payloadLineNumbers\" class=\"cqa-api-edit-step-payload-line-num\">\n <span *ngIf=\"payloadJsonError && payloadJsonError.line === n\"\n class=\"cqa-api-edit-step-payload-line-error-icon\" [title]=\"payloadJsonErrorTooltip\"\n aria-label=\"Parse error on this line\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#EF4444\"/>\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n <span class=\"cqa-api-edit-step-payload-line-num-text\">{{ n }}</span>\n </span>\n </div>\n <div class=\"cqa-api-edit-step-payload-textarea-cell\">\n <div class=\"cqa-api-edit-step-payload-textarea cqa-w-full cqa-flex cqa-flex-col cqa-min-h-0\"\n [ngClass]=\"{'cqa-api-edit-step-payload-textarea--error': payloadJsonError}\">\n <textarea #payloadTextareaRef\n class=\"cqa-api-edit-step-payload-textarea-input cqa-w-full cqa-outline-none cqa-box-border\"\n [ngClass]=\"{'cqa-api-edit-step-payload-textarea-input--error': payloadJsonError}\"\n [value]=\"payloadText\"\n placeholder=\"\"\n [attr.aria-label]=\"'Payload'\"\n [attr.aria-invalid]=\"!!payloadJsonError\"\n (input)=\"onPayloadInput($event)\"\n (keydown)=\"onPayloadKeydown($event)\">\n </textarea>\n </div>\n </div>\n </div>\n <p *ngIf=\"payloadJsonError\" class=\"cqa-api-edit-step-payload-json-error-msg\">\n Invalid JSON format. Please check your syntax.\n </p>\n </div>\n\n <!-- x-www-form-urlencoded: Key\u2013Value rows, add/remove dynamically -->\n <div *ngIf=\"payloadType === 'x-www-form-urlencoded'\" class=\"cqa-api-edit-step-key-value\">\n <div class=\"cqa-api-edit-step-key-value-grid cqa-api-edit-step-key-value-header\">\n <span class=\"cqa-api-edit-step-key-value-label\">Key</span>\n <span class=\"cqa-api-edit-step-key-value-label\">Value</span>\n <span class=\"cqa-api-edit-step-key-value-label cqa-api-edit-step-key-value-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of keyValueRows; let i = index; trackBy: trackByKeyValue\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-key-value-row\">\n <cqa-custom-input [value]=\"row.get('key')?.value ?? ''\"\n (valueChange)=\"row.get('key')?.setValue($event)\" placeholder=\"Key\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Key\">\n </cqa-custom-input>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-value-input\" ariaLabel=\"Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-key-value-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeKeyValueRow(i)\">\n <svg class=\"cqa-api-edit-step-key-value-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-key-value-add-wrap\">\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"+ Add Row\"\n customClass=\"cqa-api-edit-step-key-value-add-btn\" (clicked)=\"addKeyValueRow()\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Form Data: Key\u2013Type\u2013Value rows; Type is a dropdown (Text/File), add/remove dynamically -->\n <div *ngIf=\"payloadType === 'form-data'\" class=\"cqa-api-edit-step-key-type-value\">\n <div class=\"cqa-api-edit-step-key-type-value-header\">\n <span class=\"cqa-api-edit-step-key-type-value-label\">Key</span>\n <span class=\"cqa-api-edit-step-key-type-value-label\">Type</span>\n <span class=\"cqa-api-edit-step-key-type-value-label\">Value</span>\n <span class=\"cqa-api-edit-step-key-type-value-label cqa-api-edit-step-key-type-value-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of keyTypeValueRows; let i = index; trackBy: trackByKeyTypeValue\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-key-type-value-row\">\n <cqa-custom-input [value]=\"row.get('key')?.value ?? ''\"\n (valueChange)=\"row.get('key')?.setValue($event)\" placeholder=\"Key\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-type-value-input\" ariaLabel=\"Key\">\n </cqa-custom-input>\n <cqa-dynamic-select [form]=\"row\" [config]=\"keyTypeValueTypeSelectConfig\"\n class=\"cqa-api-edit-step-key-type-value-type-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('value')?.value ?? ''\"\n (valueChange)=\"row.get('value')?.setValue($event)\" placeholder=\"Value\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-key-type-value-input\" ariaLabel=\"Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-key-type-value-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeKeyTypeValueRow(i)\">\n <svg class=\"cqa-api-edit-step-key-type-value-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-key-type-value-add-wrap\">\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"+ Add Row\"\n customClass=\"cqa-api-edit-step-key-type-value-add-btn\" (clicked)=\"addKeyTypeValueRow()\">\n </cqa-button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n </div>\n <!-- Step 2: Variable Name: input, validation, Back / Next -->\n <div *ngIf=\"currentStep === 2\" class=\"cqa-api-edit-step-panel cqa-flex cqa-flex-col cqa-gap-6 cqa-box-border cqa-w-full\">\n <div class=\"cqa-api-edit-step-variable-section\">\n <div class=\"cqa-api-edit-step-variable-input-wrap\">\n <cqa-custom-input [(value)]=\"variableName\" [label]=\"''\" placeholder=\"Variable Name\" [fullWidth]=\"true\"\n size=\"md\" (valueChange)=\"onVariableNameChange()\" aria-label=\"Variable Name\">\n </cqa-custom-input>\n </div>\n <p *ngIf=\"variableNameError\" class=\"cqa-api-edit-step-variable-error\" role=\"alert\">{{ variableNameError }}</p>\n </div>\n </div>\n <!-- Step 3: Response Body / Status tabs -->\n <div *ngIf=\"currentStep === 3\" class=\"cqa-api-edit-step-panel cqa-flex cqa-flex-col cqa-gap-6 cqa-box-border cqa-w-full\">\n <div class=\"cqa-api-edit-step-tabs-wrapper\">\n <div class=\"cqa-api-edit-step-tabs\">\n <cqa-button *ngFor=\"let tab of responseVerificationTabs\" type=\"button\" variant=\"text\" [text]=\"tab.label\"\n [customClass]=\"'cqa-api-edit-step-tab' + (activeResponseVerificationTab === tab.value ? ' cqa-api-edit-step-tab--active' : '')\"\n (clicked)=\"setResponseVerificationTab(tab.value)\">\n </cqa-button>\n </div>\n\n <!-- Response Body tab content: verification grid -->\n <div *ngIf=\"activeResponseVerificationTab === 'response-body'\" class=\"cqa-api-edit-step-step3-content\">\n <div class=\"cqa-api-edit-step-verification-header-row\">\n <span></span>\n <cqa-button type=\"button\" variant=\"text\" text=\"Add Verification\"\n customClass=\"cqa-api-edit-step-verification-add-link\" (clicked)=\"addVerificationRow()\">\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-verification\">\n <div class=\"cqa-api-edit-step-verification-grid cqa-api-edit-step-verification-grid-header\">\n <span class=\"cqa-api-edit-step-verification-label\">S.no</span>\n <span class=\"cqa-api-edit-step-verification-label\">JSON Path</span>\n <span class=\"cqa-api-edit-step-verification-label\">Verification</span>\n <span class=\"cqa-api-edit-step-verification-label\">Data Type</span>\n <span class=\"cqa-api-edit-step-verification-label\">Expected Value</span>\n <span class=\"cqa-api-edit-step-verification-label cqa-api-edit-step-verification-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of verificationRows; let i = index; trackBy: trackByVerification\" [formGroup]=\"row\"\n class=\"cqa-api-edit-step-verification-row\">\n <span class=\"cqa-api-edit-step-verification-sno\">{{ i + 1 }}</span>\n <cqa-custom-input [value]=\"row.get('jsonPath')?.value ?? ''\"\n (valueChange)=\"row.get('jsonPath')?.setValue($event)\" placeholder=\"Json Path\" [fullWidth]=\"true\"\n size=\"sm\" class=\"cqa-api-edit-step-verification-input\" ariaLabel=\"JSON Path\">\n </cqa-custom-input>\n <cqa-dynamic-select [form]=\"row\" [config]=\"verificationSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-dynamic-select [form]=\"row\" [config]=\"verificationDataTypeSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-w-full\"\n (selectionChange)=\"onVerificationDataTypeChange(row, $event)\">\n </cqa-dynamic-select>\n <!-- Expected Value: text for String/Array/Object, number for Number, dropdown for Boolean -->\n <ng-container [ngSwitch]=\"row.get('dataType')?.value\">\n <cqa-dynamic-select *ngSwitchCase=\"'boolean'\" [form]=\"row\"\n [config]=\"verificationExpectedValueBooleanSelectConfig\"\n class=\"cqa-api-edit-step-verification-select cqa-api-edit-step-verification-expected-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input *ngSwitchCase=\"'number'\" [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\" placeholder=\"Expected Value (number)\"\n type=\"number\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-verification-input cqa-api-edit-step-verification-expected-number\"\n ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n <cqa-custom-input *ngSwitchDefault [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\"\n placeholder=\"Expected Value in String\" [fullWidth]=\"true\" size=\"sm\"\n class=\"cqa-api-edit-step-verification-input\" ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n </ng-container>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-verification-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeVerificationRow(i)\">\n <svg class=\"cqa-api-edit-step-verification-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n </div>\n </div>\n\n <!-- Status tab content: S.no, Verification dropdown, Expected Value, add/remove rows -->\n <div *ngIf=\"activeResponseVerificationTab === 'status'\" class=\"cqa-api-edit-step-step3-content\">\n <div class=\"cqa-api-edit-step-verification-header-row\">\n <span></span>\n <cqa-button type=\"button\" variant=\"text\" text=\"Add Verification\"\n customClass=\"cqa-api-edit-step-verification-add-link\" (clicked)=\"addStatusVerificationRow()\">\n </cqa-button>\n </div>\n <div class=\"cqa-api-edit-step-status-verification\">\n <div class=\"cqa-api-edit-step-status-verification-header\">\n <span class=\"cqa-api-edit-step-verification-label\">S.no</span>\n <span class=\"cqa-api-edit-step-verification-label\">Verification</span>\n <span class=\"cqa-api-edit-step-verification-label\">Expected Value</span>\n <span class=\"cqa-api-edit-step-verification-label cqa-api-edit-step-verification-label--empty\"\n aria-hidden=\"true\"></span>\n </div>\n <div *ngFor=\"let row of statusVerificationRows; let i = index; trackBy: trackByStatusVerification\"\n [formGroup]=\"row\" class=\"cqa-api-edit-step-status-verification-row\">\n <span class=\"cqa-api-edit-step-verification-sno\">{{ i + 1 }}</span>\n <cqa-dynamic-select [form]=\"row\" [config]=\"statusVerificationSelectConfig\"\n class=\"cqa-api-edit-step-status-verification-select cqa-w-full\">\n </cqa-dynamic-select>\n <cqa-custom-input [value]=\"row.get('expectedValue')?.value ?? ''\"\n (valueChange)=\"row.get('expectedValue')?.setValue($event)\" placeholder=\"Expected Value\"\n type=\"number\" [fullWidth]=\"true\" size=\"sm\" class=\"cqa-api-edit-step-verification-input\"\n ariaLabel=\"Expected Value\">\n </cqa-custom-input>\n <cqa-button type=\"button\" variant=\"text\" [customClass]=\"'cqa-api-edit-step-verification-delete'\"\n [tooltip]=\"'Remove row'\" (clicked)=\"removeStatusVerificationRow(i)\">\n <svg class=\"cqa-api-edit-step-verification-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\"\n fill=\"#F9BFBF\" />\n </svg>\n </cqa-button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Response Preview -->\n <div class=\"cqa-api-edit-step-response\">\n <h3 class=\"cqa-api-edit-step-response-title cqa-text-[14px] cqa-font-bold cqa-leading-[20px] cqa-text-[#111827] cqa-m-0 cqa-mb-[12px] cqa-shrink-0\">Response Preview</h3>\n <pre class=\"cqa-api-edit-step-response-content\">{{ responsePreview }}</pre>\n </div>\n\n <!-- Step actions: one row, full width. Step 1: Cancel + Next; Step 2: Back + Next; Step 3: Back + Create -->\n <div class=\"cqa-api-edit-step-actions\">\n <ng-container [ngSwitch]=\"currentStep\">\n <ng-container *ngSwitchCase=\"1\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Cancel\"\n customClass=\"cqa-api-edit-step-actions-btn-cancel\" (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Next\"\n customClass=\"cqa-api-edit-step-actions-btn-next\" (clicked)=\"onNext()\">\n </cqa-button>\n </ng-container>\n <ng-container *ngSwitchCase=\"2\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Back\"\n customClass=\"cqa-api-edit-step-actions-btn-back\" (clicked)=\"onBack()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" text=\"Next\"\n customClass=\"cqa-api-edit-step-actions-btn-next\" (clicked)=\"onNext()\">\n </cqa-button>\n </ng-container>\n <ng-container *ngSwitchCase=\"3\">\n <cqa-button type=\"button\" variant=\"outlined\" btnSize=\"lg\" text=\"Back\"\n customClass=\"cqa-api-edit-step-actions-btn-back\" (clicked)=\"onBack()\">\n </cqa-button>\n <cqa-button type=\"button\" variant=\"filled\" btnSize=\"lg\" [text]=\"editMode ? 'Update' : 'Create'\"\n customClass=\"cqa-api-edit-step-actions-btn-create\" (clicked)=\"onCreate()\">\n </cqa-button>\n </ng-container>\n </ng-container>\n </div>\n</div>" }]
20712
21294
  }], ctorParameters: function () { return [{ type: i1$1.FormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { initialMethod: [{
20713
21295
  type: Input
20714
21296
  }], initialEnvironment: [{
@@ -20723,6 +21305,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
20723
21305
  type: Input
20724
21306
  }], initialResponsePreview: [{
20725
21307
  type: Input
21308
+ }], initialVariableName: [{
21309
+ type: Input
21310
+ }], editMode: [{
21311
+ type: Input
20726
21312
  }], importCurl: [{
20727
21313
  type: Output
20728
21314
  }], importCurlCancel: [{
@@ -20731,6 +21317,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
20731
21317
  type: Output
20732
21318
  }], back: [{
20733
21319
  type: Output
21320
+ }], cancel: [{
21321
+ type: Output
20734
21322
  }], next: [{
20735
21323
  type: Output
20736
21324
  }], create: [{
@@ -20741,6 +21329,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
20741
21329
  type: Input
20742
21330
  }], environmentOptions: [{
20743
21331
  type: Input
21332
+ }], authTypeOptions: [{
21333
+ type: Input
21334
+ }], initialAuthType: [{
21335
+ type: Input
20744
21336
  }], formatOptions: [{
20745
21337
  type: Input
20746
21338
  }], initialFormat: [{