@digi-frontend/dgate-api-documentation 4.0.4 → 4.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1098,8 +1098,8 @@ const Sidebar$1 = ({ searchValue, setSearchValue }) => {
1098
1098
  };
1099
1099
  return wrapSSR(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(re_resizable.Resizable, {
1100
1100
  as: "aside",
1101
- minWidth: 300,
1102
- maxWidth: 386,
1101
+ minWidth: 240,
1102
+ maxWidth: 240,
1103
1103
  enable: {
1104
1104
  top: false,
1105
1105
  right: true,
@@ -1111,7 +1111,7 @@ const Sidebar$1 = ({ searchValue, setSearchValue }) => {
1111
1111
  topLeft: false
1112
1112
  },
1113
1113
  defaultSize: {
1114
- width: 333,
1114
+ width: 240,
1115
1115
  height: "100%"
1116
1116
  },
1117
1117
  className: cx("sider"),
@@ -1742,7 +1742,7 @@ const handleStatusColor = (code) => {
1742
1742
  };
1743
1743
  //#endregion
1744
1744
  //#region src/view/components/EndpointPage/EndpointPage.tsx
1745
- const { Title: Title$7, Paragraph: Paragraph$1 } = antd.Typography;
1745
+ const { Title: Title$8, Paragraph: Paragraph$1 } = antd.Typography;
1746
1746
  const requestColumns$1 = [
1747
1747
  {
1748
1748
  title: "Parameter",
@@ -1761,7 +1761,7 @@ const requestColumns$1 = [
1761
1761
  }
1762
1762
  ];
1763
1763
  const responseColumns$1 = [...requestColumns$1];
1764
- const buildRequestData$1 = (params) => [...params].sort((a, b) => a.required === b.required ? 0 : a.required ? -1 : 1).map((p, index) => {
1764
+ const buildRequestData$1 = (params, colors) => [...params].sort((a, b) => a.required === b.required ? 0 : a.required ? -1 : 1).map((p, index) => {
1765
1765
  let typeLabel = p.schema?.type;
1766
1766
  if (p.schema?.type === "array" && p.schema?.items?.type) typeLabel = `${p.schema.type}_${p.schema.items.type}`;
1767
1767
  return {
@@ -1770,17 +1770,17 @@ const buildRequestData$1 = (params) => [...params].sort((a, b) => a.required ===
1770
1770
  p.name,
1771
1771
  typeLabel && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1772
1772
  style: {
1773
- color: "rgba(0,0,0,0.45)",
1773
+ color: colors.typeLabel,
1774
1774
  marginLeft: "0.25rem",
1775
1775
  marginRight: "0.25rem"
1776
1776
  },
1777
1777
  children: typeLabel
1778
1778
  }),
1779
1779
  p.required ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1780
- style: { color: "red" },
1780
+ style: { color: colors.required },
1781
1781
  children: "*"
1782
1782
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1783
- style: { color: "#52C41A" },
1783
+ style: { color: colors.optional },
1784
1784
  children: "Optional"
1785
1785
  })
1786
1786
  ] }),
@@ -1788,7 +1788,7 @@ const buildRequestData$1 = (params) => [...params].sort((a, b) => a.required ===
1788
1788
  enum: p.schema?.enum ? p.schema.enum.map((e) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tag, { children: e }, e)) : "--"
1789
1789
  };
1790
1790
  });
1791
- const buildHeaderData$1 = (headers) => {
1791
+ const buildHeaderData$1 = (headers, colors) => {
1792
1792
  if (!headers) return [];
1793
1793
  return Object.entries(headers).sort(([, a], [, b]) => a.required === b.required ? 0 : a.required ? -1 : 1).map(([name, header], idx) => {
1794
1794
  let typeLabel = header.schema?.type;
@@ -1799,17 +1799,17 @@ const buildHeaderData$1 = (headers) => {
1799
1799
  name,
1800
1800
  typeLabel && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1801
1801
  style: {
1802
- color: "rgba(0,0,0,0.45)",
1802
+ color: colors.typeLabel,
1803
1803
  marginLeft: "0.25rem",
1804
1804
  marginRight: "0.25rem"
1805
1805
  },
1806
1806
  children: typeLabel
1807
1807
  }),
1808
1808
  header.required ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1809
- style: { color: "red" },
1809
+ style: { color: colors.required },
1810
1810
  children: "*"
1811
1811
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1812
- style: { color: "#52C41A" },
1812
+ style: { color: colors.optional },
1813
1813
  children: "Optional"
1814
1814
  })
1815
1815
  ] }, idx),
@@ -1822,7 +1822,7 @@ const EndpointPage$1 = () => {
1822
1822
  const { selectedEndpoint, selectedApi, selectedStatusCode, setSelectedNodeKey, setFocusedContent, setFocusedTag } = useStore(({ view }) => view);
1823
1823
  const [endpointTooltip, setEndpointTooltip] = (0, react$1.useState)("Copy endpoint");
1824
1824
  const [selectedServer, setSelectedServer] = (0, react$1.useState)(0);
1825
- const { cx } = useStyle("EndpointPage", (token, scope) => ({
1825
+ const { cx, token } = useStyle("EndpointPage", (token, scope) => ({
1826
1826
  [scope("docs-endpoint-container")]: {
1827
1827
  display: "flex",
1828
1828
  flexDirection: "column",
@@ -1852,12 +1852,19 @@ const EndpointPage$1 = () => {
1852
1852
  padding: "0px 0.75rem 0.75rem 0.75rem",
1853
1853
  ".ant-tabs-tab": { paddingTop: "0" }
1854
1854
  }
1855
- }
1855
+ },
1856
+ [scope("row-odd")]: { "& > td": { background: `${token.colorBgLayout} !important` } },
1857
+ [scope("row-even")]: { "& > td": { background: `${token.colorBgContainer} !important` } }
1856
1858
  }));
1857
1859
  const methodStyle = methodColors$1[selectedEndpoint?.method];
1858
- const headerParams = buildRequestData$1(selectedEndpoint?.parameters?.filter((p) => p.in === "header") || []);
1859
- const pathParams = buildRequestData$1(selectedEndpoint?.parameters?.filter((p) => p.in === "path") || []);
1860
- const queryParams = buildRequestData$1(selectedEndpoint?.parameters?.filter((p) => p.in === "query") || []);
1860
+ const paramColors = {
1861
+ typeLabel: token.colorTextQuaternary,
1862
+ required: token.colorError,
1863
+ optional: token.colorSuccess
1864
+ };
1865
+ const headerParams = buildRequestData$1(selectedEndpoint?.parameters?.filter((p) => p.in === "header") || [], paramColors);
1866
+ const pathParams = buildRequestData$1(selectedEndpoint?.parameters?.filter((p) => p.in === "path") || [], paramColors);
1867
+ const queryParams = buildRequestData$1(selectedEndpoint?.parameters?.filter((p) => p.in === "query") || [], paramColors);
1861
1868
  const requestTabs = [
1862
1869
  {
1863
1870
  key: "header",
@@ -1867,7 +1874,8 @@ const EndpointPage$1 = () => {
1867
1874
  dataSource: headerParams,
1868
1875
  pagination: false,
1869
1876
  bordered: true,
1870
- size: "small"
1877
+ size: "small",
1878
+ rowClassName: (_, idx) => cx(idx % 2 === 0 ? "row-odd" : "row-even")
1871
1879
  })
1872
1880
  },
1873
1881
  {
@@ -1878,7 +1886,8 @@ const EndpointPage$1 = () => {
1878
1886
  dataSource: pathParams,
1879
1887
  pagination: false,
1880
1888
  bordered: true,
1881
- size: "small"
1889
+ size: "small",
1890
+ rowClassName: (_, idx) => cx(idx % 2 === 0 ? "row-odd" : "row-even")
1882
1891
  })
1883
1892
  },
1884
1893
  {
@@ -1889,12 +1898,13 @@ const EndpointPage$1 = () => {
1889
1898
  dataSource: queryParams,
1890
1899
  pagination: false,
1891
1900
  bordered: true,
1892
- size: "small"
1901
+ size: "small",
1902
+ rowClassName: (_, idx) => cx(idx % 2 === 0 ? "row-odd" : "row-even")
1893
1903
  })
1894
1904
  }
1895
1905
  ].filter((t) => t !== null);
1896
1906
  const responseHeaders = (selectedEndpoint?.responses?.[selectedStatusCode || 200])?.headers;
1897
- const responseHeaderData = buildHeaderData$1(responseHeaders);
1907
+ const responseHeaderData = buildHeaderData$1(responseHeaders, paramColors);
1898
1908
  selectedApi?.servers?.map((server, index) => ({
1899
1909
  value: index,
1900
1910
  label: `${server.url}${selectedEndpoint?.path || ""}`
@@ -1938,7 +1948,7 @@ const EndpointPage$1 = () => {
1938
1948
  display: "flex",
1939
1949
  flexDirection: "row",
1940
1950
  alignItems: "center",
1941
- color: "rgba(0,0,0,0.45)",
1951
+ color: token.colorTextQuaternary,
1942
1952
  gap: "0.25rem"
1943
1953
  },
1944
1954
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: selectedEndpoint?.tagName || "default" })
@@ -1953,7 +1963,7 @@ const EndpointPage$1 = () => {
1953
1963
  }) }
1954
1964
  ] })]
1955
1965
  }),
1956
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Title$7, {
1966
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Title$8, {
1957
1967
  level: 3,
1958
1968
  children: [
1959
1969
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tag, {
@@ -2003,7 +2013,8 @@ const EndpointPage$1 = () => {
2003
2013
  dataSource: responseHeaderData,
2004
2014
  pagination: false,
2005
2015
  bordered: true,
2006
- size: "small"
2016
+ size: "small",
2017
+ rowClassName: (_, idx) => cx(idx % 2 === 0 ? "row-odd" : "row-even")
2007
2018
  })
2008
2019
  })
2009
2020
  ]
@@ -2127,8 +2138,8 @@ const MainContent$1 = ({ searchEnabled, handleResetSearch, handleVisitLandingPag
2127
2138
  //#endregion
2128
2139
  //#region src/view/components/ApiPage/components/ApiDocumentationBar.tsx
2129
2140
  const { useBreakpoint: useBreakpoint$4 } = antd.Grid;
2130
- const { Title: Title$5 } = antd.Typography;
2131
- const ApiDocumentationBar = ({ apiName, mode, onModeChange, onReset, onSave, hasChanges = false, switcherNode }) => {
2141
+ const { Title: Title$6 } = antd.Typography;
2142
+ const ApiDocumentationBar = ({ apiName, mode, onModeChange, onReset, onSave, hasChanges = false, hasErrors = false, switcherNode }) => {
2132
2143
  const isMobile = !useBreakpoint$4().md;
2133
2144
  const { wrapSSR, cx, token } = useStyle("ApiDocumentationBar", (token, scope) => ({
2134
2145
  [scope("root")]: {
@@ -2240,7 +2251,7 @@ const ApiDocumentationBar = ({ apiName, mode, onModeChange, onReset, onSave, has
2240
2251
  className: cx("title-section"),
2241
2252
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
2242
2253
  title: apiName,
2243
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Title$5, {
2254
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Title$6, {
2244
2255
  level: 3,
2245
2256
  ellipsis: true,
2246
2257
  style: {
@@ -2264,7 +2275,7 @@ const ApiDocumentationBar = ({ apiName, mode, onModeChange, onReset, onSave, has
2264
2275
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
2265
2276
  size: "large",
2266
2277
  type: "primary",
2267
- disabled: !hasChanges,
2278
+ disabled: !hasChanges || hasErrors,
2268
2279
  onClick: onSave,
2269
2280
  children: "Save"
2270
2281
  })]
@@ -2278,7 +2289,7 @@ const ApiDocumentationBar = ({ apiName, mode, onModeChange, onReset, onSave, has
2278
2289
  className: cx("title-section"),
2279
2290
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
2280
2291
  title: `${apiName} API Documentation`,
2281
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Title$5, {
2292
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Title$6, {
2282
2293
  level: 3,
2283
2294
  style: {
2284
2295
  margin: 0,
@@ -2322,7 +2333,7 @@ const ApiDocumentationBar = ({ apiName, mode, onModeChange, onReset, onSave, has
2322
2333
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
2323
2334
  size: "large",
2324
2335
  type: "primary",
2325
- disabled: !hasChanges,
2336
+ disabled: !hasChanges || hasErrors,
2326
2337
  onClick: onSave,
2327
2338
  children: "Save & Publish Changes"
2328
2339
  })]
@@ -2333,14 +2344,16 @@ const ApiDocumentationBar = ({ apiName, mode, onModeChange, onReset, onSave, has
2333
2344
  //#endregion
2334
2345
  //#region src/view/components/ApiPage/components/GeneralSection.tsx
2335
2346
  const { useBreakpoint: useBreakpoint$3 } = antd.Grid;
2336
- const GeneralSection = ({ apiName, authType, version, description, onApiNameChange, onDescriptionChange, collapsed = false, onToggleCollapse, onChangeDetected }) => {
2347
+ const GeneralSection = ({ apiName, authType, version, description, onApiNameChange, onDescriptionChange, onChangeDetected, collapsed, onToggleCollapse, apiNameError, descriptionError }) => {
2337
2348
  const isMobile = !useBreakpoint$3().md;
2338
2349
  const { wrapSSR, cx, token } = useStyle("GeneralSection", (token, scope) => ({
2339
2350
  [scope("root")]: {
2340
2351
  display: "flex",
2341
2352
  flexDirection: "column",
2342
- borderRadius: token.borderRadius,
2343
- overflow: "hidden",
2353
+ gap: token.margin,
2354
+ padding: `${token.marginLG}px ${token.marginLG}px 48px`,
2355
+ background: token.colorBgElevated,
2356
+ borderRadius: token.borderRadiusLG,
2344
2357
  width: "100%"
2345
2358
  },
2346
2359
  [scope("head")]: {
@@ -2354,15 +2367,20 @@ const GeneralSection = ({ apiName, authType, version, description, onApiNameChan
2354
2367
  [scope("body")]: {
2355
2368
  display: "flex",
2356
2369
  flexDirection: "column",
2357
- gap: token.paddingLG,
2370
+ gap: token.margin,
2358
2371
  padding: token.paddingLG,
2359
- paddingBottom: token.paddingXXL ?? 48,
2360
2372
  background: token.colorBgElevated,
2361
2373
  borderRadius: `0 0 ${token.borderRadius}px ${token.borderRadius}px`
2362
2374
  },
2375
+ [scope("fields")]: {
2376
+ display: "flex",
2377
+ flexDirection: "column",
2378
+ gap: token.margin,
2379
+ width: "100%"
2380
+ },
2363
2381
  [scope("row")]: {
2364
2382
  display: "flex",
2365
- gap: token.paddingLG,
2383
+ gap: token.margin,
2366
2384
  width: "100%"
2367
2385
  },
2368
2386
  [scope("field")]: {
@@ -2381,108 +2399,91 @@ const GeneralSection = ({ apiName, authType, version, description, onApiNameChan
2381
2399
  paddingBottom: token.paddingXS,
2382
2400
  lineHeight: "22px"
2383
2401
  },
2384
- [scope("label-required")]: {
2402
+ [scope("required")]: {
2385
2403
  color: token.colorError,
2386
2404
  fontSize: token.fontSize
2387
- },
2388
- [scope("count")]: {
2389
- alignSelf: "flex-end",
2390
- fontSize: token.fontSize,
2391
- color: token.colorTextDescription,
2392
- marginTop: token.marginXXS
2393
2405
  }
2394
2406
  }));
2395
- return wrapSSR(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2396
- className: cx("root"),
2397
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2398
- className: cx("head"),
2399
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd_es_typography_Title_js.default, {
2400
- level: 4,
2401
- style: {
2402
- margin: 0,
2403
- color: token.colorTextHeading
2404
- },
2405
- children: "General"
2406
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
2407
- type: "text",
2408
- size: "large",
2409
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.UpCircleOutlined, { style: { fontSize: 18 } }),
2410
- onClick: onToggleCollapse,
2411
- style: {
2412
- transform: collapsed ? "rotate(180deg)" : "rotate(0deg)",
2413
- transition: "transform 0.2s"
2414
- }
2415
- })]
2416
- }), !collapsed && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2417
- className: cx("body"),
2418
- style: isMobile ? {
2419
- padding: token.paddingMD,
2420
- paddingBottom: token.paddingXXL ?? 48
2421
- } : void 0,
2422
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2407
+ const fieldsContent = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2408
+ className: cx("fields"),
2409
+ children: [
2410
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2411
+ className: cx("field"),
2412
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2413
+ className: cx("label"),
2414
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "API Name" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2415
+ className: cx("required"),
2416
+ children: "*"
2417
+ })]
2418
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
2419
+ size: "large",
2420
+ value: apiName,
2421
+ status: apiNameError ? "error" : void 0,
2422
+ suffix: apiNameError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.CloseCircleOutlined, {
2423
+ style: {
2424
+ color: token.colorError,
2425
+ cursor: "pointer"
2426
+ },
2427
+ onClick: () => {
2428
+ onApiNameChange("");
2429
+ onChangeDetected?.();
2430
+ }
2431
+ }) : void 0,
2432
+ onChange: (e) => {
2433
+ onApiNameChange(e.target.value);
2434
+ onChangeDetected?.();
2435
+ },
2436
+ maxLength: 100,
2437
+ showCount: true
2438
+ })]
2439
+ }),
2440
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2423
2441
  className: cx("row"),
2424
2442
  style: isMobile ? { flexDirection: "column" } : void 0,
2425
- children: [
2426
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2427
- className: cx("field"),
2428
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2429
- className: cx("label"),
2430
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "API Name" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2431
- className: cx("label-required"),
2432
- children: "*"
2433
- })]
2434
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
2435
- size: "large",
2436
- value: apiName,
2437
- onChange: (e) => {
2438
- onApiNameChange(e.target.value);
2439
- onChangeDetected?.();
2440
- },
2441
- maxLength: 35,
2442
- showCount: true
2443
- })]
2444
- }),
2445
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2446
- className: cx("field"),
2447
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2448
- className: cx("label"),
2449
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Authentication Type" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2450
- className: cx("label-required"),
2451
- children: "*"
2452
- })]
2453
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
2454
- size: "large",
2455
- value: authType,
2456
- disabled: true
2443
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2444
+ className: cx("field"),
2445
+ style: isMobile ? void 0 : {
2446
+ flex: "none",
2447
+ width: 436
2448
+ },
2449
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2450
+ className: cx("label"),
2451
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Authentication Type" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2452
+ className: cx("required"),
2453
+ children: "*"
2457
2454
  })]
2458
- }),
2459
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2460
- className: cx("field"),
2461
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2462
- className: cx("label"),
2463
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Version" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2464
- className: cx("label-required"),
2465
- children: "*"
2466
- })]
2467
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
2468
- size: "large",
2469
- value: version,
2470
- disabled: true
2455
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
2456
+ size: "large",
2457
+ value: authType,
2458
+ disabled: true
2459
+ })]
2460
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2461
+ className: cx("field"),
2462
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2463
+ className: cx("label"),
2464
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Version" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2465
+ className: cx("required"),
2466
+ children: "*"
2471
2467
  })]
2472
- })
2473
- ]
2474
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2468
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
2469
+ size: "large",
2470
+ value: version,
2471
+ disabled: true
2472
+ })]
2473
+ })]
2474
+ }),
2475
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2475
2476
  className: cx("field"),
2476
- style: { width: "100%" },
2477
2477
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2478
2478
  className: cx("label"),
2479
2479
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Description" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2480
- className: cx("label-required"),
2480
+ className: cx("required"),
2481
2481
  children: "*"
2482
2482
  })]
2483
2483
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input.TextArea, {
2484
2484
  size: "large",
2485
2485
  value: description,
2486
+ status: descriptionError ? "error" : void 0,
2486
2487
  onChange: (e) => {
2487
2488
  onDescriptionChange(e.target.value);
2488
2489
  onChangeDetected?.();
@@ -2494,64 +2495,138 @@ const GeneralSection = ({ apiName, authType, version, description, onApiNameChan
2494
2495
  resize: "vertical"
2495
2496
  }
2496
2497
  })]
2498
+ })
2499
+ ]
2500
+ });
2501
+ return wrapSSR(isMobile ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2502
+ style: { width: "100%" },
2503
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2504
+ className: cx("head"),
2505
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd_es_typography_Title_js.default, {
2506
+ level: 4,
2507
+ style: {
2508
+ margin: 0,
2509
+ color: token.colorTextHeading
2510
+ },
2511
+ children: "General"
2512
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
2513
+ type: "text",
2514
+ size: "large",
2515
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.UpCircleOutlined, { style: { fontSize: 18 } }),
2516
+ onClick: onToggleCollapse,
2517
+ style: {
2518
+ transform: collapsed ? "rotate(180deg)" : "rotate(0deg)",
2519
+ transition: "transform 0.2s"
2520
+ }
2497
2521
  })]
2522
+ }), !collapsed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2523
+ className: cx("body"),
2524
+ children: fieldsContent
2498
2525
  })]
2526
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2527
+ className: cx("root"),
2528
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd_es_typography_Title_js.default, {
2529
+ level: 4,
2530
+ style: {
2531
+ margin: 0,
2532
+ color: token.colorTextHeading
2533
+ },
2534
+ children: "General"
2535
+ }), fieldsContent]
2499
2536
  }));
2500
2537
  };
2501
2538
  //#endregion
2502
2539
  //#region src/assets/trash.tsx
2503
- const Trash = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
2504
- viewBox: "0 0 40 40",
2540
+ const Trash = (props) => {
2541
+ const maskId = `trash-mask-${(0, react.useId)()}`;
2542
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
2543
+ viewBox: "0 0 40 40",
2544
+ fill: "none",
2545
+ xmlns: "http://www.w3.org/2000/svg",
2546
+ ...props,
2547
+ children: [
2548
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("mask", {
2549
+ id: maskId,
2550
+ fill: "white",
2551
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M0 8C0 3.58172 3.58172 0 8 0H32C36.4183 0 40 3.58172 40 8V32C40 36.4183 36.4183 40 32 40H8C3.58172 40 0 36.4183 0 32V8Z" })
2552
+ }),
2553
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2554
+ d: "M8 0V1H32V0V-1H8V0ZM40 8H39V32H40H41V8H40ZM32 40V39H8V40V41H32V40ZM0 32H1V8H0H-1V32H0ZM8 40V39C4.13401 39 1 35.866 1 32H0H-1C-1 36.9706 3.02944 41 8 41V40ZM40 32H39C39 35.866 35.866 39 32 39V40V41C36.9706 41 41 36.9706 41 32H40ZM32 0V1C35.866 1 39 4.13401 39 8H40H41C41 3.02944 36.9706 -1 32 -1V0ZM8 0V-1C3.02944 -1 -1 3.02944 -1 8H0H1C1 4.13401 4.13401 1 8 1V0Z",
2555
+ fill: "currentColor",
2556
+ mask: `url(#${maskId})`
2557
+ }),
2558
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2559
+ d: "M26.75 15.4844C24.2525 15.2369 21.74 15.1094 19.235 15.1094C17.75 15.1094 16.265 15.1844 14.78 15.3344L13.25 15.4844",
2560
+ fill: "currentColor"
2561
+ }),
2562
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2563
+ d: "M26.75 15.4844C24.2525 15.2369 21.74 15.1094 19.235 15.1094C17.75 15.1094 16.265 15.1844 14.78 15.3344L13.25 15.4844",
2564
+ stroke: "currentColor",
2565
+ strokeWidth: "1.5",
2566
+ strokeLinecap: "round",
2567
+ strokeLinejoin: "round"
2568
+ }),
2569
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2570
+ d: "M17.375 14.7275L17.54 13.745C17.66 13.0325 17.75 12.5 19.0175 12.5H20.9825C22.25 12.5 22.3475 13.0625 22.46 13.7525L22.625 14.7275",
2571
+ stroke: "currentColor",
2572
+ strokeWidth: "1.5",
2573
+ strokeLinecap: "round",
2574
+ strokeLinejoin: "round"
2575
+ }),
2576
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2577
+ d: "M25.1373 17.8555L24.6498 25.408C24.5673 26.5855 24.4998 27.5005 22.4073 27.5005H17.5923C15.4998 27.5005 15.4323 26.5855 15.3498 25.408L14.8623 17.8555",
2578
+ stroke: "currentColor",
2579
+ strokeWidth: "1.5",
2580
+ strokeLinecap: "round",
2581
+ strokeLinejoin: "round"
2582
+ }),
2583
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2584
+ d: "M18.7476 23.375H21.2451",
2585
+ stroke: "currentColor",
2586
+ strokeWidth: "1.5",
2587
+ strokeLinecap: "round",
2588
+ strokeLinejoin: "round"
2589
+ }),
2590
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2591
+ d: "M18.125 20.375H21.875",
2592
+ stroke: "currentColor",
2593
+ strokeWidth: "1.5",
2594
+ strokeLinecap: "round",
2595
+ strokeLinejoin: "round"
2596
+ })
2597
+ ]
2598
+ });
2599
+ };
2600
+ //#endregion
2601
+ //#region src/assets/icons/editTag.tsx
2602
+ const EditTag = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
2603
+ width: "18",
2604
+ height: "18",
2605
+ viewBox: "0 0 18 18",
2505
2606
  fill: "none",
2506
2607
  xmlns: "http://www.w3.org/2000/svg",
2507
2608
  ...props,
2508
2609
  children: [
2509
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("mask", {
2510
- id: "path-1-inside-1_17984_239034",
2511
- fill: "white",
2512
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M0 8C0 3.58172 3.58172 0 8 0H32C36.4183 0 40 3.58172 40 8V32C40 36.4183 36.4183 40 32 40H8C3.58172 40 0 36.4183 0 32V8Z" })
2513
- }),
2514
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2515
- d: "M8 0V1H32V0V-1H8V0ZM40 8H39V32H40H41V8H40ZM32 40V39H8V40V41H32V40ZM0 32H1V8H0H-1V32H0ZM8 40V39C4.13401 39 1 35.866 1 32H0H-1C-1 36.9706 3.02944 41 8 41V40ZM40 32H39C39 35.866 35.866 39 32 39V40V41C36.9706 41 41 36.9706 41 32H40ZM32 0V1C35.866 1 39 4.13401 39 8H40H41C41 3.02944 36.9706 -1 32 -1V0ZM8 0V-1C3.02944 -1 -1 3.02944 -1 8H0H1C1 4.13401 4.13401 1 8 1V0Z",
2516
- fill: "#FF4D4F",
2517
- mask: "url(#path-1-inside-1_17984_239034)"
2518
- }),
2519
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2520
- d: "M26.75 15.4844C24.2525 15.2369 21.74 15.1094 19.235 15.1094C17.75 15.1094 16.265 15.1844 14.78 15.3344L13.25 15.4844",
2521
- fill: "#FF4D4F"
2522
- }),
2523
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2524
- d: "M26.75 15.4844C24.2525 15.2369 21.74 15.1094 19.235 15.1094C17.75 15.1094 16.265 15.1844 14.78 15.3344L13.25 15.4844",
2525
- stroke: "#FF4D4F",
2526
- strokeWidth: "1.5",
2527
- strokeLinecap: "round",
2528
- strokeLinejoin: "round"
2529
- }),
2530
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2531
- d: "M17.375 14.7275L17.54 13.745C17.66 13.0325 17.75 12.5 19.0175 12.5H20.9825C22.25 12.5 22.3475 13.0625 22.46 13.7525L22.625 14.7275",
2532
- stroke: "#FF4D4F",
2533
- strokeWidth: "1.5",
2534
- strokeLinecap: "round",
2535
- strokeLinejoin: "round"
2536
- }),
2537
2610
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2538
- d: "M25.1373 17.8555L24.6498 25.408C24.5673 26.5855 24.4998 27.5005 22.4073 27.5005H17.5923C15.4998 27.5005 15.4323 26.5855 15.3498 25.408L14.8623 17.8555",
2539
- stroke: "#FF4D4F",
2611
+ d: "M8.25 1.5H6.75C3 1.5 1.5 3 1.5 6.75V11.25C1.5 15 3 16.5 6.75 16.5H11.25C15 16.5 16.5 15 16.5 11.25V9.75",
2612
+ stroke: "currentColor",
2540
2613
  strokeWidth: "1.5",
2541
2614
  strokeLinecap: "round",
2542
2615
  strokeLinejoin: "round"
2543
2616
  }),
2544
2617
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2545
- d: "M18.7476 23.375H21.2451",
2546
- stroke: "#FF4D4F",
2618
+ d: "M12.0299 2.26592L6.11991 8.17592C5.89491 8.40092 5.66991 8.84342 5.62491 9.16592L5.30241 11.4234C5.18241 12.2409 5.75991 12.8109 6.57741 12.6984L8.83491 12.3759C9.14991 12.3309 9.59241 12.1059 9.82491 11.8809L15.7349 5.97092C16.7549 4.95092 17.2349 3.76592 15.7349 2.26592C14.2349 0.765922 13.0499 1.24592 12.0299 2.26592Z",
2619
+ stroke: "currentColor",
2547
2620
  strokeWidth: "1.5",
2621
+ strokeMiterlimit: "10",
2548
2622
  strokeLinecap: "round",
2549
2623
  strokeLinejoin: "round"
2550
2624
  }),
2551
2625
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2552
- d: "M18.125 20.375H21.875",
2553
- stroke: "#FF4D4F",
2626
+ d: "M11.1826 3.11328C11.6851 4.90578 13.0876 6.30828 14.8876 6.81828",
2627
+ stroke: "currentColor",
2554
2628
  strokeWidth: "1.5",
2629
+ strokeMiterlimit: "10",
2555
2630
  strokeLinecap: "round",
2556
2631
  strokeLinejoin: "round"
2557
2632
  })
@@ -2623,6 +2698,7 @@ const PARAM_IN_OPTIONS = [
2623
2698
  value: "path"
2624
2699
  }
2625
2700
  ];
2701
+ const RESPONSE_PARAM_IN_OPTIONS = PARAM_IN_OPTIONS.filter((o) => o.value === "header");
2626
2702
  const PARAM_TYPE_OPTIONS = [
2627
2703
  {
2628
2704
  label: "string",
@@ -2649,7 +2725,7 @@ const PARAM_TYPE_OPTIONS = [
2649
2725
  value: "object"
2650
2726
  }
2651
2727
  ];
2652
- const AddParameterDrawer = ({ open, onClose, onAdd, onEdit, mode = "add", initialValues }) => {
2728
+ const AddParameterDrawer = ({ open, onClose, onAdd, onEdit, mode = "add", initialValues, source }) => {
2653
2729
  const [form] = antd.Form.useForm();
2654
2730
  const [messageApi, contextHolder] = antd.message.useMessage();
2655
2731
  const [confirmModalOpen, setConfirmModalOpen] = (0, react$1.useState)(false);
@@ -2867,6 +2943,7 @@ const AddParameterDrawer = ({ open, onClose, onAdd, onEdit, mode = "add", initia
2867
2943
  }
2868
2944
  }));
2869
2945
  const isAddEnabled = mode === "edit" ? hasChanges : !!(nameValue?.trim() && inValue && typeValue);
2946
+ const paramInOptions = source === "response" ? RESPONSE_PARAM_IN_OPTIONS : PARAM_IN_OPTIONS;
2870
2947
  const resetForm = () => {
2871
2948
  form.resetFields();
2872
2949
  setEnumInput("");
@@ -2971,10 +3048,11 @@ const AddParameterDrawer = ({ open, onClose, onAdd, onEdit, mode = "add", initia
2971
3048
  className: cx("form-body"),
2972
3049
  initialValues: {
2973
3050
  required: true,
2974
- in: "query",
3051
+ in: source === "response" ? "header" : "query",
2975
3052
  type: "string"
2976
3053
  },
2977
- onValuesChange: () => {
3054
+ onValuesChange: (_changed, allValues) => {
3055
+ if (allValues.in === "path") form.setFieldValue("required", true);
2978
3056
  if (mode === "edit" && initialValues) {
2979
3057
  const current = form.getFieldsValue();
2980
3058
  setHasChanges(current.name !== initialValues.name || current.in !== initialValues.in || current.type !== initialValues.type || current.required !== initialValues.required || (current.description ?? "") !== (initialValues.description ?? "") || JSON.stringify(enumValues) !== JSON.stringify(initialValues.enum ?? []));
@@ -3019,7 +3097,7 @@ const AddParameterDrawer = ({ open, onClose, onAdd, onEdit, mode = "add", initia
3019
3097
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Select, {
3020
3098
  size: "large",
3021
3099
  placeholder: "Select",
3022
- options: PARAM_IN_OPTIONS
3100
+ options: paramInOptions
3023
3101
  })
3024
3102
  }),
3025
3103
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Form.Item, {
@@ -3046,12 +3124,20 @@ const AddParameterDrawer = ({ open, onClose, onAdd, onEdit, mode = "add", initia
3046
3124
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3047
3125
  className: cx("switch-row"),
3048
3126
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Switch, {
3049
- checked: requiredValue ?? true,
3127
+ checked: inValue === "path" ? true : requiredValue ?? true,
3128
+ disabled: inValue === "path",
3050
3129
  onChange: (checked) => form.setFieldValue("required", checked),
3051
- style: { backgroundColor: requiredValue ?? true ? token.colorPrimary : void 0 }
3052
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3130
+ style: { backgroundColor: (inValue === "path" ? true : requiredValue ?? true) ? token.colorPrimary : void 0 }
3131
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3053
3132
  className: cx("switch-label"),
3054
- children: "Required?"
3133
+ children: ["Required?", inValue === "path" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3134
+ style: {
3135
+ color: token.colorTextTertiary,
3136
+ fontSize: 12,
3137
+ marginLeft: 4
3138
+ },
3139
+ children: "(Always required for path parameter)"
3140
+ })]
3055
3141
  })]
3056
3142
  })
3057
3143
  }),
@@ -3203,7 +3289,8 @@ const AddParameterDrawer = ({ open, onClose, onAdd, onEdit, mode = "add", initia
3203
3289
  //#endregion
3204
3290
  //#region src/view/components/ApiPage/components/EndpointsSection.tsx
3205
3291
  const { useBreakpoint: useBreakpoint$2 } = antd.Grid;
3206
- const PAGE_SIZE = 5;
3292
+ const PAGE_SIZE = 4;
3293
+ const VIEW_PAGE_SIZE = 4;
3207
3294
  const getStatusCodeColor = (code, token) => {
3208
3295
  const n = parseInt(code, 10);
3209
3296
  if (n >= 400 && n < 500) return {
@@ -3223,8 +3310,24 @@ const buildViewParamRows = (params) => params.map((p, idx) => ({
3223
3310
  description: p.description ?? "",
3224
3311
  enum: p.enum ?? []
3225
3312
  }));
3226
- const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse, endpointNames, endpointDescs, endpointTags, availableTags, onEndpointNameChange, onEndpointDescChange, onEndpointTagsChange, endpointParams, onAddParameter, onEditParameter, onDeleteParameter, endpointResponseParams, onAddResponseParameter, onEditResponseParameter, onDeleteResponseParameter, mode = "edit" }) => {
3313
+ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse, endpointNames, endpointDescs, endpointTags, availableTags, onEndpointNameChange, onEndpointDescChange, onEndpointTagsChange, endpointParams, onAddParameter, onEditParameter, onDeleteParameter, endpointResponseParams, onAddResponseParameter, onEditResponseParameter, onDeleteResponseParameter, onRequestContentChange, onResponseContentChange, requestBodySchemas, responseBodySchemas, mode = "edit", selectedEndpointKey }) => {
3227
3314
  const [expandedId, setExpandedId] = (0, react$1.useState)(null);
3315
+ const [activeTab, setActiveTab] = (0, react$1.useState)("general");
3316
+ (0, react$1.useEffect)(() => {
3317
+ setActiveTab("general");
3318
+ }, [selectedEndpointKey]);
3319
+ (0, react$1.useEffect)(() => {
3320
+ if (!selectedEndpointKey) return;
3321
+ if (selectedStatusCodes[selectedEndpointKey]) return;
3322
+ const ep = Object.values(endpointsByTag).flat().find((e) => e.id === selectedEndpointKey);
3323
+ if (!ep) return;
3324
+ const keys = Object.keys(ep.responses ?? {});
3325
+ const defaultCode = keys.includes("200") ? "200" : keys[0];
3326
+ if (defaultCode) setSelectedStatusCodes((prev) => ({
3327
+ ...prev,
3328
+ [selectedEndpointKey]: defaultCode
3329
+ }));
3330
+ }, [selectedEndpointKey]);
3228
3331
  const [paramDrawerOpen, setParamDrawerOpen] = (0, react$1.useState)(false);
3229
3332
  const [paramDrawerEndpointId, setParamDrawerEndpointId] = (0, react$1.useState)(null);
3230
3333
  const [paramDrawerMode, setParamDrawerMode] = (0, react$1.useState)("add");
@@ -3248,6 +3351,48 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
3248
3351
  const [showResponseSearch, setShowResponseSearch] = (0, react$1.useState)({});
3249
3352
  const debouncedRequestSearches = useDebounce(requestSearches);
3250
3353
  const debouncedResponseSearches = useDebounce(responseSearches);
3354
+ const [editableRequestContent, setEditableRequestContent] = (0, react$1.useState)({});
3355
+ const [editableResponseContent, setEditableResponseContent] = (0, react$1.useState)({});
3356
+ (0, react$1.useEffect)(() => {
3357
+ if (!openRequestPanels.size) return;
3358
+ openRequestPanels.forEach((epId) => {
3359
+ if (editableRequestContent[epId] !== void 0) return;
3360
+ const val = requestBodySchemas?.[epId];
3361
+ const json = val ? JSON.stringify(val, null, 2) : "";
3362
+ setEditableRequestContent((prev) => ({
3363
+ ...prev,
3364
+ [epId]: json
3365
+ }));
3366
+ });
3367
+ }, [openRequestPanels, requestBodySchemas]);
3368
+ (0, react$1.useEffect)(() => {
3369
+ if (!openResponsePanels.size) return;
3370
+ openResponsePanels.forEach((epId) => {
3371
+ if (editableResponseContent[epId] !== void 0) return;
3372
+ const val = responseBodySchemas?.[epId];
3373
+ const json = val ? JSON.stringify(val, null, 2) : "";
3374
+ setEditableResponseContent((prev) => ({
3375
+ ...prev,
3376
+ [epId]: json
3377
+ }));
3378
+ });
3379
+ }, [openResponsePanels, responseBodySchemas]);
3380
+ const handleValidate = (content) => {
3381
+ try {
3382
+ JSON.parse(content);
3383
+ antd.message.success("Definition is valid JSON.");
3384
+ } catch {
3385
+ antd.message.error("Invalid JSON definition.");
3386
+ }
3387
+ };
3388
+ const handleBeautify = (content, setter) => {
3389
+ try {
3390
+ const parsed = JSON.parse(content);
3391
+ setter(JSON.stringify(parsed, null, 2));
3392
+ } catch {
3393
+ antd.message.error("Could not beautify — content is not valid JSON.");
3394
+ }
3395
+ };
3251
3396
  const { selectNodeByKey } = useNodeSelection();
3252
3397
  const { token: antdToken } = antd.theme.useToken();
3253
3398
  const isMobile = !useBreakpoint$2().md;
@@ -3271,10 +3416,13 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
3271
3416
  [scope("root")]: {
3272
3417
  display: "flex",
3273
3418
  flexDirection: "column",
3274
- borderRadius: token.borderRadius,
3275
- overflow: "hidden",
3276
3419
  width: "100%",
3277
- flexShrink: 0
3420
+ flexShrink: 0,
3421
+ "& .ant-tabs-content-holder": {
3422
+ background: token.colorBgElevated,
3423
+ borderRadius: token.borderRadiusLG,
3424
+ padding: `${token.paddingLG}px ${token.paddingLG}px 48px`
3425
+ }
3278
3426
  },
3279
3427
  [scope("head")]: {
3280
3428
  display: "flex",
@@ -3323,15 +3471,12 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
3323
3471
  display: "flex",
3324
3472
  alignItems: "center",
3325
3473
  justifyContent: "center",
3326
- width: 64,
3327
- padding: `0 ${token.paddingXS}px`,
3474
+ padding: "0 15px",
3328
3475
  borderRadius: token.borderRadius,
3329
- border: "1px solid",
3330
3476
  fontSize: token.fontSize,
3331
3477
  fontWeight: 400,
3332
3478
  lineHeight: "22px",
3333
- whiteSpace: "nowrap",
3334
- alignSelf: "stretch"
3479
+ whiteSpace: "nowrap"
3335
3480
  },
3336
3481
  [scope("endpoint-path")]: {
3337
3482
  fontSize: token.fontSizeLG,
@@ -3402,6 +3547,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
3402
3547
  userSelect: "none",
3403
3548
  "&:hover": { background: token.colorFillTertiary }
3404
3549
  },
3550
+ [scope("param-row--open")]: { borderRadius: `${token.borderRadius}px ${token.borderRadius}px 0 0` },
3405
3551
  [scope("param-row-icon")]: {
3406
3552
  fontSize: 12,
3407
3553
  transition: "transform 0.2s"
@@ -3409,10 +3555,13 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
3409
3555
  [scope("param-row-icon--open")]: { transform: "rotate(180deg)" },
3410
3556
  [scope("code-panel")]: {
3411
3557
  width: "100%",
3412
- overflow: "hidden"
3558
+ overflow: "hidden",
3559
+ background: "#1D2856",
3560
+ borderBottomLeftRadius: 8,
3561
+ borderBottomRightRadius: 8
3413
3562
  },
3414
3563
  [scope("code-area")]: {
3415
- background: "#1d2856",
3564
+ background: "#1D2856",
3416
3565
  padding: "10px 12px",
3417
3566
  fontFamily: "Cairo, sans-serif",
3418
3567
  fontSize: 14,
@@ -3424,7 +3573,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
3424
3573
  display: "block"
3425
3574
  },
3426
3575
  [scope("code-footer")]: {
3427
- background: "#161d40",
3576
+ background: "#161D40",
3428
3577
  padding: 12,
3429
3578
  borderBottomLeftRadius: 8,
3430
3579
  borderBottomRightRadius: 8,
@@ -3581,26 +3730,36 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
3581
3730
  gap: 8
3582
3731
  },
3583
3732
  [scope("param-edit-btn")]: {
3584
- width: 32,
3585
- height: 32,
3733
+ width: 40,
3734
+ height: 40,
3586
3735
  padding: 0,
3736
+ lineHeight: 1,
3587
3737
  display: "flex",
3588
3738
  alignItems: "center",
3589
3739
  justifyContent: "center",
3590
- borderColor: token.colorPrimary,
3740
+ borderRadius: 8,
3741
+ borderColor: "#D9D9D9",
3742
+ background: "#FFF !important",
3743
+ boxShadow: "0 2px 0 0 rgba(0, 0, 0, 0.02) !important",
3591
3744
  color: token.colorPrimary,
3745
+ "& .ant-btn-icon": {
3746
+ display: "flex",
3747
+ alignItems: "center",
3748
+ justifyContent: "center"
3749
+ },
3592
3750
  "&:hover": {
3593
3751
  borderColor: `${token.colorPrimary} !important`,
3594
3752
  color: `${token.colorPrimary} !important`
3595
3753
  }
3596
3754
  },
3597
3755
  [scope("param-delete-btn")]: {
3598
- width: 32,
3599
- height: 32,
3756
+ width: 40,
3757
+ height: 40,
3600
3758
  padding: 0,
3601
3759
  display: "flex",
3602
3760
  alignItems: "center",
3603
- justifyContent: "center"
3761
+ justifyContent: "center",
3762
+ "& svg path[mask]": { display: "none" }
3604
3763
  },
3605
3764
  [".delete-param-confirm-modal .ant-modal-container"]: {
3606
3765
  "--ant-modal-content-padding": "0px !important",
@@ -3924,30 +4083,1185 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
3924
4083
  }
3925
4084
  }
3926
4085
  ];
3927
- return wrapSSR(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3928
- className: cx("root"),
3929
- children: [
3930
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3931
- className: cx("head"),
3932
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd_es_typography_Title_js.default, {
4086
+ if (selectedEndpointKey) {
4087
+ const ep = Object.values(endpointsByTag).flat().find((e) => e.id === selectedEndpointKey);
4088
+ if (!ep) return wrapSSR(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {}));
4089
+ const methodColor = methodColors$1[ep.method];
4090
+ const epHeader = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4091
+ style: {
4092
+ display: "flex",
4093
+ alignItems: "center",
4094
+ gap: token.marginXS,
4095
+ marginBottom: token.marginLG
4096
+ },
4097
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4098
+ className: cx("method-badge"),
4099
+ style: {
4100
+ color: methodColor?.color,
4101
+ backgroundColor: methodColor?.bg ?? "transparent"
4102
+ },
4103
+ children: ep.method
4104
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
4105
+ title: ep.path,
4106
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd_es_typography_Title_js.default, {
3933
4107
  level: 4,
3934
4108
  style: {
3935
4109
  margin: 0,
3936
4110
  color: token.colorTextHeading
3937
4111
  },
3938
- children: "Endpoints"
3939
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
3940
- type: "text",
3941
- size: "large",
3942
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.UpCircleOutlined, { style: { fontSize: 18 } }),
3943
- onClick: onToggleCollapse,
3944
- style: {
3945
- transform: collapsed ? "rotate(180deg)" : "rotate(0deg)",
3946
- transition: "transform 0.2s"
3947
- }
3948
- })]
3949
- }),
3950
- !collapsed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4112
+ children: ep.path
4113
+ })
4114
+ })]
4115
+ });
4116
+ return wrapSSR(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4117
+ className: cx("root"),
4118
+ children: [
4119
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tabs, {
4120
+ activeKey: activeTab,
4121
+ onChange: setActiveTab,
4122
+ tabBarStyle: {
4123
+ background: "transparent",
4124
+ padding: "0 16px",
4125
+ marginBottom: 16
4126
+ },
4127
+ tabBarGutter: 32,
4128
+ style: { borderRadius: `0 0 ${token.borderRadius}px ${token.borderRadius}px` },
4129
+ items: [
4130
+ {
4131
+ key: "general",
4132
+ label: "General",
4133
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [epHeader, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4134
+ style: {
4135
+ display: "flex",
4136
+ flexDirection: "column",
4137
+ gap: token.paddingLG
4138
+ },
4139
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4140
+ className: cx("form-row"),
4141
+ style: isMobile ? { flexDirection: "column" } : void 0,
4142
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4143
+ className: cx("form-field"),
4144
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4145
+ className: cx("field-label"),
4146
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Endpoint Name" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4147
+ className: cx("label-required"),
4148
+ children: "*"
4149
+ })]
4150
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
4151
+ size: "large",
4152
+ value: endpointNames[ep.id] ?? ep.summary ?? "",
4153
+ onChange: (e) => onEndpointNameChange(ep.id, e.target.value),
4154
+ maxLength: 100,
4155
+ showCount: true
4156
+ })]
4157
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4158
+ className: cx("form-field"),
4159
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4160
+ className: cx("field-label"),
4161
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Endpoint Tag" })
4162
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Select, {
4163
+ mode: "multiple",
4164
+ size: "large",
4165
+ style: { width: "100%" },
4166
+ placeholder: "Select",
4167
+ value: endpointTags[ep.id] ?? ep.tags ?? [],
4168
+ options: availableTags.map((t) => ({
4169
+ label: t,
4170
+ value: t
4171
+ })),
4172
+ onChange: (val) => onEndpointTagsChange(ep.id, val)
4173
+ })]
4174
+ })]
4175
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4176
+ className: cx("form-field"),
4177
+ style: { width: "100%" },
4178
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4179
+ className: cx("field-label"),
4180
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Description" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4181
+ className: cx("label-optional"),
4182
+ children: "(optional)"
4183
+ })]
4184
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input.TextArea, {
4185
+ value: endpointDescs[ep.id] ?? ep.description ?? "",
4186
+ onChange: (e) => onEndpointDescChange(ep.id, e.target.value),
4187
+ maxLength: 500,
4188
+ showCount: true,
4189
+ style: {
4190
+ height: 52,
4191
+ resize: "vertical"
4192
+ }
4193
+ })]
4194
+ })]
4195
+ })] })
4196
+ },
4197
+ {
4198
+ key: "request",
4199
+ label: "Request",
4200
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [epHeader, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4201
+ className: cx("form-field"),
4202
+ style: { width: "100%" },
4203
+ children: [
4204
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4205
+ className: cx("section-header"),
4206
+ children: isMobile ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4207
+ style: {
4208
+ display: "flex",
4209
+ alignItems: "center",
4210
+ gap: token.marginMD
4211
+ },
4212
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4213
+ className: cx("section-title"),
4214
+ children: "Request Details"
4215
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4216
+ ghost: true,
4217
+ type: "primary",
4218
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.SearchOutlined, {}),
4219
+ size: "large",
4220
+ style: {
4221
+ width: 40,
4222
+ height: 40,
4223
+ padding: 0
4224
+ },
4225
+ disabled: (endpointParams[ep.id] ?? []).length === 0,
4226
+ onClick: () => setShowRequestSearch((prev) => ({
4227
+ ...prev,
4228
+ [ep.id]: !prev[ep.id]
4229
+ }))
4230
+ })]
4231
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4232
+ ghost: true,
4233
+ type: "primary",
4234
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.PlusOutlined, {}),
4235
+ onClick: () => {
4236
+ setDrawerSource("request");
4237
+ setParamDrawerMode("add");
4238
+ setEditParamIdx(null);
4239
+ setParamDrawerEndpointId(ep.id);
4240
+ setParamDrawerOpen(true);
4241
+ },
4242
+ children: "Add Parameter"
4243
+ })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4244
+ style: {
4245
+ display: "flex",
4246
+ alignItems: "center",
4247
+ gap: 24
4248
+ },
4249
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4250
+ className: cx("section-title"),
4251
+ children: "Request Details"
4252
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input.Search, {
4253
+ placeholder: "Search by parameter name",
4254
+ style: { width: 310 },
4255
+ disabled: (endpointParams[ep.id] ?? []).length === 0,
4256
+ value: requestSearches[ep.id] ?? "",
4257
+ onChange: (e) => {
4258
+ const val = e.target.value;
4259
+ setRequestSearches((prev) => ({
4260
+ ...prev,
4261
+ [ep.id]: val
4262
+ }));
4263
+ setRequestPages((prev) => new Map(prev).set(ep.id, 1));
4264
+ },
4265
+ allowClear: true
4266
+ })]
4267
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4268
+ ghost: true,
4269
+ type: "primary",
4270
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.PlusOutlined, {}),
4271
+ onClick: () => {
4272
+ setDrawerSource("request");
4273
+ setParamDrawerMode("add");
4274
+ setEditParamIdx(null);
4275
+ setParamDrawerEndpointId(ep.id);
4276
+ setParamDrawerOpen(true);
4277
+ },
4278
+ children: "Add Parameter"
4279
+ })] })
4280
+ }),
4281
+ isMobile && showRequestSearch[ep.id] && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input.Search, {
4282
+ placeholder: "Search by parameter name",
4283
+ style: {
4284
+ width: "100%",
4285
+ marginTop: 8
4286
+ },
4287
+ disabled: (endpointParams[ep.id] ?? []).length === 0,
4288
+ value: requestSearches[ep.id] ?? "",
4289
+ onChange: (e) => {
4290
+ const val = e.target.value;
4291
+ setRequestSearches((prev) => ({
4292
+ ...prev,
4293
+ [ep.id]: val
4294
+ }));
4295
+ setRequestPages((prev) => new Map(prev).set(ep.id, 1));
4296
+ },
4297
+ allowClear: true,
4298
+ autoFocus: true
4299
+ }),
4300
+ (endpointParams[ep.id] ?? []).length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4301
+ className: cx("empty-wrapper"),
4302
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Empty, {
4303
+ image: antd.Empty.PRESENTED_IMAGE_SIMPLE,
4304
+ imageStyle: {
4305
+ width: 184,
4306
+ height: 117
4307
+ },
4308
+ description: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4309
+ className: cx("empty-description"),
4310
+ children: "No Data"
4311
+ })
4312
+ })
4313
+ }) : (() => {
4314
+ const reqSearch = (debouncedRequestSearches[ep.id] ?? "").toLowerCase();
4315
+ const allReqParams = (endpointParams[ep.id] ?? []).filter((p) => p.name.toLowerCase().includes(reqSearch));
4316
+ if (allReqParams.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4317
+ className: cx("empty-wrapper"),
4318
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Empty, {
4319
+ image: antd.Empty.PRESENTED_IMAGE_SIMPLE,
4320
+ imageStyle: {
4321
+ width: 184,
4322
+ height: 117
4323
+ },
4324
+ description: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4325
+ className: cx("empty-description"),
4326
+ children: "No Data"
4327
+ })
4328
+ })
4329
+ });
4330
+ const reqPage = requestPages.get(ep.id) ?? 1;
4331
+ const pagedReqParams = allReqParams.slice((reqPage - 1) * PAGE_SIZE, reqPage * PAGE_SIZE);
4332
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4333
+ className: cx("param-list"),
4334
+ style: { marginTop: token.margin },
4335
+ children: pagedReqParams.map((param, i) => {
4336
+ const idx = (reqPage - 1) * PAGE_SIZE + i;
4337
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4338
+ className: cx("param-item-row"),
4339
+ children: isMobile ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4340
+ style: {
4341
+ display: "flex",
4342
+ alignItems: "center",
4343
+ gap: 24,
4344
+ flex: 1,
4345
+ minWidth: 0
4346
+ },
4347
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4348
+ className: cx("param-detail-cell"),
4349
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4350
+ className: cx("param-detail-label"),
4351
+ children: "Parameter Name"
4352
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4353
+ className: cx("param-detail-value"),
4354
+ children: param.name
4355
+ })]
4356
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4357
+ className: cx("param-detail-cell"),
4358
+ style: {
4359
+ flex: 1,
4360
+ minWidth: 0
4361
+ },
4362
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4363
+ className: cx("param-detail-label"),
4364
+ children: "Parameter In"
4365
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4366
+ className: cx("param-detail-value"),
4367
+ children: param.in
4368
+ })]
4369
+ })]
4370
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4371
+ style: {
4372
+ display: "flex",
4373
+ alignItems: "center",
4374
+ gap: token.margin,
4375
+ background: token.colorFillTertiary,
4376
+ borderRadius: token.borderRadius,
4377
+ padding: `0 ${token.marginSM}px`,
4378
+ height: 50,
4379
+ flexShrink: 0
4380
+ },
4381
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4382
+ danger: true,
4383
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Trash, {
4384
+ width: 32,
4385
+ height: 32
4386
+ }),
4387
+ style: {
4388
+ padding: 0,
4389
+ lineHeight: 1,
4390
+ width: 40,
4391
+ height: 40
4392
+ },
4393
+ className: cx("param-delete-btn"),
4394
+ onClick: () => setDeleteParamModal({
4395
+ open: true,
4396
+ endpointId: ep.id,
4397
+ idx,
4398
+ name: param.name,
4399
+ source: "request"
4400
+ })
4401
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4402
+ ghost: true,
4403
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditTag, {
4404
+ width: 18,
4405
+ height: 18
4406
+ }),
4407
+ style: {
4408
+ width: 40,
4409
+ height: 40,
4410
+ padding: 0,
4411
+ lineHeight: 1
4412
+ },
4413
+ className: cx("param-edit-btn"),
4414
+ onClick: () => {
4415
+ setDrawerSource("request");
4416
+ setParamDrawerMode("edit");
4417
+ setEditParamIdx(idx);
4418
+ setParamDrawerEndpointId(ep.id);
4419
+ setParamDrawerOpen(true);
4420
+ }
4421
+ })]
4422
+ })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4423
+ className: cx("param-details"),
4424
+ children: [
4425
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4426
+ className: cx("param-detail-cell"),
4427
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4428
+ className: cx("param-detail-label"),
4429
+ children: "Parameter Name"
4430
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4431
+ className: cx("param-detail-value"),
4432
+ children: param.name
4433
+ })]
4434
+ }),
4435
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4436
+ className: cx("param-detail-cell"),
4437
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4438
+ className: cx("param-detail-label"),
4439
+ children: "Parameter In"
4440
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4441
+ className: cx("param-detail-value"),
4442
+ children: param.in
4443
+ })]
4444
+ }),
4445
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4446
+ className: cx("param-detail-cell"),
4447
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4448
+ className: cx("param-detail-label"),
4449
+ children: "Parameter Type"
4450
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4451
+ className: cx("param-detail-value"),
4452
+ children: param.type
4453
+ })]
4454
+ }),
4455
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4456
+ className: cx("param-detail-cell"),
4457
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4458
+ className: cx("param-detail-label"),
4459
+ children: "Enum"
4460
+ }), param.enum && param.enum.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4461
+ className: cx("param-enum-container"),
4462
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4463
+ className: cx("param-enum-tag"),
4464
+ children: param.enum[0]
4465
+ }), param.enum.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
4466
+ title: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
4467
+ style: {
4468
+ margin: 0,
4469
+ paddingLeft: 16
4470
+ },
4471
+ children: param.enum.map((e) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: e }, e))
4472
+ }),
4473
+ placement: "bottom",
4474
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4475
+ className: cx("param-enum-pill"),
4476
+ children: ["+", param.enum.length - 1]
4477
+ })
4478
+ })]
4479
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4480
+ className: cx("param-detail-value"),
4481
+ children: "—"
4482
+ })]
4483
+ }),
4484
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4485
+ className: cx("param-detail-cell"),
4486
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4487
+ className: cx("param-detail-label"),
4488
+ children: "Required?"
4489
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4490
+ className: cx("param-detail-value"),
4491
+ children: param.required ? "Yes" : "No"
4492
+ })]
4493
+ }),
4494
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4495
+ className: cx("param-detail-cell"),
4496
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4497
+ className: cx("param-detail-label"),
4498
+ children: "Description"
4499
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4500
+ className: cx("param-detail-value", "param-detail-value--ellipsis"),
4501
+ children: param.description || "—"
4502
+ })]
4503
+ })
4504
+ ]
4505
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4506
+ className: cx("param-actions"),
4507
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4508
+ danger: true,
4509
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Trash, {
4510
+ width: 32,
4511
+ height: 32
4512
+ }),
4513
+ style: {
4514
+ padding: 0,
4515
+ lineHeight: 1,
4516
+ width: 40,
4517
+ height: 40
4518
+ },
4519
+ className: cx("param-delete-btn"),
4520
+ onClick: () => setDeleteParamModal({
4521
+ open: true,
4522
+ endpointId: ep.id,
4523
+ idx,
4524
+ name: param.name,
4525
+ source: "request"
4526
+ })
4527
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4528
+ ghost: true,
4529
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditTag, {
4530
+ width: 18,
4531
+ height: 18
4532
+ }),
4533
+ style: {
4534
+ width: 40,
4535
+ height: 40,
4536
+ padding: 0,
4537
+ lineHeight: 1
4538
+ },
4539
+ className: cx("param-edit-btn"),
4540
+ onClick: () => {
4541
+ setDrawerSource("request");
4542
+ setParamDrawerMode("edit");
4543
+ setEditParamIdx(idx);
4544
+ setParamDrawerEndpointId(ep.id);
4545
+ setParamDrawerOpen(true);
4546
+ }
4547
+ })]
4548
+ })] })
4549
+ }, idx);
4550
+ })
4551
+ }), allReqParams.length > PAGE_SIZE && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Pagination, {
4552
+ current: reqPage,
4553
+ pageSize: PAGE_SIZE,
4554
+ total: allReqParams.length,
4555
+ onChange: (page) => setRequestPages((prev) => new Map(prev).set(ep.id, page)),
4556
+ showSizeChanger: false,
4557
+ className: cx("pagination")
4558
+ })] });
4559
+ })(),
4560
+ !["GET", "DELETE"].includes(ep.method) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4561
+ className: cx("param-row", openRequestPanels.has(ep.id) ? "param-row--open" : ""),
4562
+ style: { marginTop: token.margin },
4563
+ onClick: () => toggleRequestPanel(ep.id),
4564
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.DownOutlined, { className: cx("param-row-icon", openRequestPanels.has(ep.id) ? "param-row-icon--open" : "") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4565
+ style: { fontSize: token.fontSize },
4566
+ children: ["Request ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4567
+ style: { color: token.colorError },
4568
+ children: "*"
4569
+ })]
4570
+ })]
4571
+ }),
4572
+ !["GET", "DELETE"].includes(ep.method) && openRequestPanels.has(ep.id) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4573
+ className: cx("code-panel"),
4574
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input.TextArea, {
4575
+ value: editableRequestContent[ep.id] ?? "",
4576
+ onChange: (e) => {
4577
+ setEditableRequestContent((prev) => ({
4578
+ ...prev,
4579
+ [ep.id]: e.target.value
4580
+ }));
4581
+ onRequestContentChange?.(ep.id, e.target.value);
4582
+ },
4583
+ rows: Math.max(3, (editableRequestContent[ep.id] ?? "").split("\n").length),
4584
+ style: {
4585
+ fontFamily: "monospace",
4586
+ fontSize: "0.75rem",
4587
+ background: "#1D2856",
4588
+ color: "#fff",
4589
+ outline: "none",
4590
+ boxShadow: "none",
4591
+ border: "none"
4592
+ }
4593
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4594
+ className: cx("code-footer"),
4595
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4596
+ ghost: true,
4597
+ size: "small",
4598
+ className: cx("code-btn"),
4599
+ onClick: () => handleValidate(editableRequestContent[ep.id] ?? ""),
4600
+ children: "Validate"
4601
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4602
+ ghost: true,
4603
+ size: "small",
4604
+ className: cx("code-btn"),
4605
+ onClick: () => handleBeautify(editableRequestContent[ep.id] ?? "", (v) => setEditableRequestContent((prev) => ({
4606
+ ...prev,
4607
+ [ep.id]: v
4608
+ }))),
4609
+ children: "Beautify"
4610
+ })]
4611
+ })]
4612
+ })
4613
+ ]
4614
+ })] })
4615
+ },
4616
+ {
4617
+ key: "response",
4618
+ label: "Response",
4619
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [epHeader, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4620
+ className: cx("form-field"),
4621
+ style: { width: "100%" },
4622
+ children: [
4623
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4624
+ className: cx("section-header"),
4625
+ children: isMobile ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4626
+ style: {
4627
+ display: "flex",
4628
+ alignItems: "center",
4629
+ gap: token.marginMD
4630
+ },
4631
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4632
+ className: cx("section-title"),
4633
+ children: "Response Details"
4634
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4635
+ ghost: true,
4636
+ type: "primary",
4637
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.SearchOutlined, {}),
4638
+ size: "large",
4639
+ style: {
4640
+ width: 40,
4641
+ height: 40,
4642
+ padding: 0
4643
+ },
4644
+ disabled: (endpointResponseParams[ep.id] ?? []).length === 0,
4645
+ onClick: () => setShowResponseSearch((prev) => ({
4646
+ ...prev,
4647
+ [ep.id]: !prev[ep.id]
4648
+ }))
4649
+ })]
4650
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4651
+ ghost: true,
4652
+ type: "primary",
4653
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.PlusOutlined, {}),
4654
+ onClick: () => {
4655
+ setDrawerSource("response");
4656
+ setParamDrawerMode("add");
4657
+ setEditParamIdx(null);
4658
+ setParamDrawerEndpointId(ep.id);
4659
+ setParamDrawerOpen(true);
4660
+ },
4661
+ children: "Add Parameter"
4662
+ })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4663
+ style: {
4664
+ display: "flex",
4665
+ alignItems: "center",
4666
+ gap: 24
4667
+ },
4668
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4669
+ className: cx("section-title"),
4670
+ children: "Response Details"
4671
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4672
+ className: cx("response-controls"),
4673
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input.Search, {
4674
+ placeholder: "Search by parameter name",
4675
+ style: { width: 310 },
4676
+ disabled: (endpointResponseParams[ep.id] ?? []).length === 0,
4677
+ value: responseSearches[ep.id] ?? "",
4678
+ onChange: (e) => {
4679
+ const val = e.target.value;
4680
+ setResponseSearches((prev) => ({
4681
+ ...prev,
4682
+ [ep.id]: val
4683
+ }));
4684
+ setResponsePages((prev) => new Map(prev).set(ep.id, 1));
4685
+ },
4686
+ allowClear: true
4687
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
4688
+ title: selectedStatusCodes[ep.id] ? "Filled" : void 0,
4689
+ placement: "bottom",
4690
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Select, {
4691
+ className: cx("status-select"),
4692
+ popupClassName: "status-code-dropdown",
4693
+ value: selectedStatusCodes[ep.id] ?? void 0,
4694
+ onChange: (val) => setSelectedStatusCodes((prev) => ({
4695
+ ...prev,
4696
+ [ep.id]: val
4697
+ })),
4698
+ options: Object.keys(ep.responses ?? {}).map((code) => ({
4699
+ value: code,
4700
+ label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4701
+ className: cx("status-label"),
4702
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4703
+ className: cx("status-dot"),
4704
+ style: { background: getStatusCodeColor(code, antdToken).dot }
4705
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4706
+ style: { color: getStatusCodeColor(code, antdToken).text },
4707
+ children: code
4708
+ })]
4709
+ })
4710
+ })),
4711
+ optionRender: (option) => {
4712
+ const code = option.value;
4713
+ const { dot, text } = getStatusCodeColor(code, antdToken);
4714
+ const isSelected = selectedStatusCodes[ep.id] === code;
4715
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
4716
+ title: "Filled",
4717
+ placement: "bottom",
4718
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4719
+ className: cx("status-option-content"),
4720
+ children: [
4721
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4722
+ className: cx("status-dot"),
4723
+ style: { background: dot }
4724
+ }),
4725
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4726
+ style: { color: text },
4727
+ children: code
4728
+ }),
4729
+ isSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.CheckCircleOutlined, {
4730
+ className: cx("status-checkmark"),
4731
+ style: { color: text }
4732
+ })
4733
+ ]
4734
+ })
4735
+ });
4736
+ }
4737
+ })
4738
+ })]
4739
+ })]
4740
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4741
+ ghost: true,
4742
+ type: "primary",
4743
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.PlusOutlined, {}),
4744
+ onClick: () => {
4745
+ setDrawerSource("response");
4746
+ setParamDrawerMode("add");
4747
+ setEditParamIdx(null);
4748
+ setParamDrawerEndpointId(ep.id);
4749
+ setParamDrawerOpen(true);
4750
+ },
4751
+ children: "Add Parameter"
4752
+ })] })
4753
+ }),
4754
+ isMobile && showResponseSearch[ep.id] && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input.Search, {
4755
+ placeholder: "Search by parameter name",
4756
+ style: {
4757
+ width: "100%",
4758
+ marginTop: 8
4759
+ },
4760
+ disabled: (endpointResponseParams[ep.id] ?? []).length === 0,
4761
+ value: responseSearches[ep.id] ?? "",
4762
+ onChange: (e) => {
4763
+ const val = e.target.value;
4764
+ setResponseSearches((prev) => ({
4765
+ ...prev,
4766
+ [ep.id]: val
4767
+ }));
4768
+ setResponsePages((prev) => new Map(prev).set(ep.id, 1));
4769
+ },
4770
+ allowClear: true,
4771
+ autoFocus: true
4772
+ }),
4773
+ (endpointResponseParams[ep.id] ?? []).length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4774
+ className: cx("empty-wrapper"),
4775
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Empty, {
4776
+ image: antd.Empty.PRESENTED_IMAGE_SIMPLE,
4777
+ imageStyle: {
4778
+ width: 184,
4779
+ height: 117
4780
+ },
4781
+ description: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4782
+ className: cx("empty-description"),
4783
+ children: "No Data"
4784
+ })
4785
+ })
4786
+ }) : (() => {
4787
+ const resSearch = (debouncedResponseSearches[ep.id] ?? "").toLowerCase();
4788
+ const allResParams = (endpointResponseParams[ep.id] ?? []).filter((p) => p.name.toLowerCase().includes(resSearch));
4789
+ if (allResParams.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4790
+ className: cx("empty-wrapper"),
4791
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Empty, {
4792
+ image: antd.Empty.PRESENTED_IMAGE_SIMPLE,
4793
+ imageStyle: {
4794
+ width: 184,
4795
+ height: 117
4796
+ },
4797
+ description: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4798
+ className: cx("empty-description"),
4799
+ children: "No Data"
4800
+ })
4801
+ })
4802
+ });
4803
+ const resPage = responsePages.get(ep.id) ?? 1;
4804
+ const pagedResParams = allResParams.slice((resPage - 1) * PAGE_SIZE, resPage * PAGE_SIZE);
4805
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4806
+ className: cx("param-list"),
4807
+ style: { marginTop: token.margin },
4808
+ children: pagedResParams.map((param, i) => {
4809
+ const idx = (resPage - 1) * PAGE_SIZE + i;
4810
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4811
+ className: cx("param-item-row"),
4812
+ children: isMobile ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4813
+ style: {
4814
+ display: "flex",
4815
+ alignItems: "center",
4816
+ gap: 24,
4817
+ flex: 1,
4818
+ minWidth: 0
4819
+ },
4820
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4821
+ className: cx("param-detail-cell"),
4822
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4823
+ className: cx("param-detail-label"),
4824
+ children: "Parameter Name"
4825
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4826
+ className: cx("param-detail-value"),
4827
+ children: param.name
4828
+ })]
4829
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4830
+ className: cx("param-detail-cell"),
4831
+ style: {
4832
+ flex: 1,
4833
+ minWidth: 0
4834
+ },
4835
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4836
+ className: cx("param-detail-label"),
4837
+ children: "Parameter In"
4838
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4839
+ className: cx("param-detail-value"),
4840
+ children: param.in
4841
+ })]
4842
+ })]
4843
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4844
+ style: {
4845
+ display: "flex",
4846
+ alignItems: "center",
4847
+ gap: token.margin,
4848
+ background: token.colorFillTertiary,
4849
+ borderRadius: token.borderRadius,
4850
+ padding: `0 ${token.marginSM}px`,
4851
+ height: 50,
4852
+ flexShrink: 0
4853
+ },
4854
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4855
+ danger: true,
4856
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Trash, {
4857
+ width: 32,
4858
+ height: 32
4859
+ }),
4860
+ style: {
4861
+ padding: 0,
4862
+ lineHeight: 1,
4863
+ width: 40,
4864
+ height: 40
4865
+ },
4866
+ className: cx("param-delete-btn"),
4867
+ onClick: () => setDeleteParamModal({
4868
+ open: true,
4869
+ endpointId: ep.id,
4870
+ idx,
4871
+ name: param.name,
4872
+ source: "response"
4873
+ })
4874
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4875
+ ghost: true,
4876
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditTag, {
4877
+ width: 18,
4878
+ height: 18
4879
+ }),
4880
+ style: {
4881
+ width: 40,
4882
+ height: 40,
4883
+ padding: 0,
4884
+ lineHeight: 1
4885
+ },
4886
+ className: cx("param-edit-btn"),
4887
+ onClick: () => {
4888
+ setDrawerSource("response");
4889
+ setParamDrawerMode("edit");
4890
+ setEditParamIdx(idx);
4891
+ setParamDrawerEndpointId(ep.id);
4892
+ setParamDrawerOpen(true);
4893
+ }
4894
+ })]
4895
+ })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4896
+ className: cx("param-details"),
4897
+ children: [
4898
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4899
+ className: cx("param-detail-cell"),
4900
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4901
+ className: cx("param-detail-label"),
4902
+ children: "Parameter Name"
4903
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4904
+ className: cx("param-detail-value"),
4905
+ children: param.name
4906
+ })]
4907
+ }),
4908
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4909
+ className: cx("param-detail-cell"),
4910
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4911
+ className: cx("param-detail-label"),
4912
+ children: "Parameter In"
4913
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4914
+ className: cx("param-detail-value"),
4915
+ children: param.in
4916
+ })]
4917
+ }),
4918
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4919
+ className: cx("param-detail-cell"),
4920
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4921
+ className: cx("param-detail-label"),
4922
+ children: "Parameter Type"
4923
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4924
+ className: cx("param-detail-value"),
4925
+ children: param.type
4926
+ })]
4927
+ }),
4928
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4929
+ className: cx("param-detail-cell"),
4930
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4931
+ className: cx("param-detail-label"),
4932
+ children: "Enum"
4933
+ }), param.enum && param.enum.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4934
+ className: cx("param-enum-container"),
4935
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4936
+ className: cx("param-enum-tag"),
4937
+ children: param.enum[0]
4938
+ }), param.enum.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
4939
+ title: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
4940
+ style: {
4941
+ margin: 0,
4942
+ paddingLeft: 16
4943
+ },
4944
+ children: param.enum.map((e) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: e }, e))
4945
+ }),
4946
+ placement: "bottom",
4947
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4948
+ className: cx("param-enum-pill"),
4949
+ children: ["+", param.enum.length - 1]
4950
+ })
4951
+ })]
4952
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4953
+ className: cx("param-detail-value"),
4954
+ children: "—"
4955
+ })]
4956
+ }),
4957
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4958
+ className: cx("param-detail-cell"),
4959
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4960
+ className: cx("param-detail-label"),
4961
+ children: "Required?"
4962
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4963
+ className: cx("param-detail-value"),
4964
+ children: param.required ? "Yes" : "No"
4965
+ })]
4966
+ }),
4967
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4968
+ className: cx("param-detail-cell"),
4969
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4970
+ className: cx("param-detail-label"),
4971
+ children: "Description"
4972
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4973
+ className: cx("param-detail-value", "param-detail-value--ellipsis"),
4974
+ children: param.description || "—"
4975
+ })]
4976
+ })
4977
+ ]
4978
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4979
+ className: cx("param-actions"),
4980
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4981
+ danger: true,
4982
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Trash, {
4983
+ width: 32,
4984
+ height: 32
4985
+ }),
4986
+ style: {
4987
+ padding: 0,
4988
+ lineHeight: 1,
4989
+ width: 40,
4990
+ height: 40
4991
+ },
4992
+ className: cx("param-delete-btn"),
4993
+ onClick: () => setDeleteParamModal({
4994
+ open: true,
4995
+ endpointId: ep.id,
4996
+ idx,
4997
+ name: param.name,
4998
+ source: "response"
4999
+ })
5000
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
5001
+ ghost: true,
5002
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditTag, {
5003
+ width: 18,
5004
+ height: 18
5005
+ }),
5006
+ style: {
5007
+ width: 40,
5008
+ height: 40,
5009
+ padding: 0,
5010
+ lineHeight: 1
5011
+ },
5012
+ className: cx("param-edit-btn"),
5013
+ onClick: () => {
5014
+ setDrawerSource("response");
5015
+ setParamDrawerMode("edit");
5016
+ setEditParamIdx(idx);
5017
+ setParamDrawerEndpointId(ep.id);
5018
+ setParamDrawerOpen(true);
5019
+ }
5020
+ })]
5021
+ })] })
5022
+ }, idx);
5023
+ })
5024
+ }), allResParams.length > PAGE_SIZE && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Pagination, {
5025
+ current: resPage,
5026
+ pageSize: PAGE_SIZE,
5027
+ total: allResParams.length,
5028
+ onChange: (page) => setResponsePages((prev) => new Map(prev).set(ep.id, page)),
5029
+ showSizeChanger: false,
5030
+ className: cx("pagination")
5031
+ })] });
5032
+ })(),
5033
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5034
+ className: cx("param-row", openResponsePanels.has(ep.id) ? "param-row--open" : ""),
5035
+ style: { marginTop: token.margin },
5036
+ onClick: () => toggleResponsePanel(ep.id),
5037
+ children: [
5038
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.DownOutlined, { className: cx("param-row-icon", openResponsePanels.has(ep.id) ? "param-row-icon--open" : "") }),
5039
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5040
+ style: { fontSize: token.fontSize },
5041
+ children: ["Response ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5042
+ style: { color: token.colorError },
5043
+ children: "*"
5044
+ })]
5045
+ }),
5046
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoCircle, { style: {
5047
+ width: 24,
5048
+ height: 24
5049
+ } })
5050
+ ]
5051
+ }),
5052
+ openResponsePanels.has(ep.id) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5053
+ className: cx("code-panel"),
5054
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input.TextArea, {
5055
+ value: editableResponseContent[ep.id] ?? "",
5056
+ onChange: (e) => {
5057
+ setEditableResponseContent((prev) => ({
5058
+ ...prev,
5059
+ [ep.id]: e.target.value
5060
+ }));
5061
+ onResponseContentChange?.(ep.id, e.target.value);
5062
+ },
5063
+ rows: Math.max(3, (editableResponseContent[ep.id] ?? "").split("\n").length),
5064
+ style: {
5065
+ fontFamily: "monospace",
5066
+ fontSize: "0.75rem",
5067
+ background: "#1D2856",
5068
+ color: "#fff",
5069
+ outline: "none",
5070
+ boxShadow: "none",
5071
+ border: "none"
5072
+ }
5073
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5074
+ className: cx("code-footer"),
5075
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
5076
+ ghost: true,
5077
+ size: "small",
5078
+ className: cx("code-btn"),
5079
+ onClick: () => handleValidate(editableResponseContent[ep.id] ?? ""),
5080
+ children: "Validate"
5081
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
5082
+ ghost: true,
5083
+ size: "small",
5084
+ className: cx("code-btn"),
5085
+ onClick: () => handleBeautify(editableResponseContent[ep.id] ?? "", (v) => setEditableResponseContent((prev) => ({
5086
+ ...prev,
5087
+ [ep.id]: v
5088
+ }))),
5089
+ children: "Beautify"
5090
+ })]
5091
+ })]
5092
+ })
5093
+ ]
5094
+ })] })
5095
+ }
5096
+ ]
5097
+ }),
5098
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(antd.Modal, {
5099
+ open: deleteParamModal.open,
5100
+ onCancel: () => setDeleteParamModal({
5101
+ open: false,
5102
+ endpointId: "",
5103
+ idx: -1,
5104
+ name: "",
5105
+ source: "request"
5106
+ }),
5107
+ centered: true,
5108
+ title: null,
5109
+ footer: null,
5110
+ closable: false,
5111
+ width: 520,
5112
+ className: "delete-param-confirm-modal",
5113
+ styles: {
5114
+ content: {
5115
+ padding: 0,
5116
+ borderRadius: 8,
5117
+ overflow: "hidden"
5118
+ },
5119
+ body: {
5120
+ padding: 0,
5121
+ margin: 0
5122
+ }
5123
+ },
5124
+ children: [
5125
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5126
+ className: cx("deleteModalHead"),
5127
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5128
+ className: cx("deleteModalTitle"),
5129
+ children: [
5130
+ "Delete ",
5131
+ deleteParamModal.name,
5132
+ " parameter"
5133
+ ]
5134
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5135
+ className: cx("deleteModalCloseBtn"),
5136
+ onClick: () => setDeleteParamModal({
5137
+ open: false,
5138
+ endpointId: "",
5139
+ idx: -1,
5140
+ name: "",
5141
+ source: "request"
5142
+ }),
5143
+ "aria-label": "Close",
5144
+ children: "×"
5145
+ })]
5146
+ }),
5147
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5148
+ className: cx("deleteModalContent"),
5149
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5150
+ className: cx("deleteModalContentText"),
5151
+ children: [
5152
+ "Are you sure you want to delete ",
5153
+ deleteParamModal.name,
5154
+ " parameter?"
5155
+ ]
5156
+ })
5157
+ }),
5158
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5159
+ className: cx("deleteModalFooter"),
5160
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
5161
+ size: "middle",
5162
+ onClick: () => setDeleteParamModal({
5163
+ open: false,
5164
+ endpointId: "",
5165
+ idx: -1,
5166
+ name: "",
5167
+ source: "request"
5168
+ }),
5169
+ style: {
5170
+ borderRadius: 8,
5171
+ height: 32,
5172
+ paddingInline: 15
5173
+ },
5174
+ children: "Cancel"
5175
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
5176
+ type: "primary",
5177
+ danger: true,
5178
+ size: "middle",
5179
+ style: {
5180
+ borderRadius: 8,
5181
+ height: 32,
5182
+ paddingInline: 16
5183
+ },
5184
+ onClick: () => {
5185
+ const epId = deleteParamModal.endpointId;
5186
+ if (deleteParamModal.source === "response") {
5187
+ const total = (endpointResponseParams[epId] ?? []).length - 1;
5188
+ const maxPage = Math.max(1, Math.ceil(total / PAGE_SIZE));
5189
+ if ((responsePages.get(epId) ?? 1) > maxPage) setResponsePages((prev) => new Map(prev).set(epId, 1));
5190
+ onDeleteResponseParameter?.(epId, deleteParamModal.idx);
5191
+ } else {
5192
+ const total = (endpointParams[epId] ?? []).length - 1;
5193
+ const maxPage = Math.max(1, Math.ceil(total / PAGE_SIZE));
5194
+ if ((requestPages.get(epId) ?? 1) > maxPage) setRequestPages((prev) => new Map(prev).set(epId, 1));
5195
+ onDeleteParameter?.(epId, deleteParamModal.idx);
5196
+ }
5197
+ setDeleteParamModal({
5198
+ open: false,
5199
+ endpointId: "",
5200
+ idx: -1,
5201
+ name: "",
5202
+ source: "request"
5203
+ });
5204
+ },
5205
+ children: "Yes, Delete"
5206
+ })]
5207
+ })
5208
+ ]
5209
+ }),
5210
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AddParameterDrawer, {
5211
+ open: paramDrawerOpen,
5212
+ mode: paramDrawerMode,
5213
+ initialValues: paramDrawerMode === "edit" && paramDrawerEndpointId && editParamIdx !== null ? drawerSource === "response" ? endpointResponseParams[paramDrawerEndpointId]?.[editParamIdx] : endpointParams[paramDrawerEndpointId]?.[editParamIdx] : void 0,
5214
+ onClose: () => {
5215
+ setParamDrawerOpen(false);
5216
+ setParamDrawerEndpointId(null);
5217
+ setParamDrawerMode("add");
5218
+ setEditParamIdx(null);
5219
+ },
5220
+ onAdd: (param) => {
5221
+ if (paramDrawerEndpointId) if (drawerSource === "response") onAddResponseParameter?.(paramDrawerEndpointId, param);
5222
+ else onAddParameter?.(paramDrawerEndpointId, param);
5223
+ setParamDrawerOpen(false);
5224
+ setParamDrawerEndpointId(null);
5225
+ setParamDrawerMode("add");
5226
+ setEditParamIdx(null);
5227
+ },
5228
+ onEdit: (param) => {
5229
+ if (paramDrawerEndpointId && editParamIdx !== null) if (drawerSource === "response") onEditResponseParameter?.(paramDrawerEndpointId, editParamIdx, param);
5230
+ else onEditParameter?.(paramDrawerEndpointId, editParamIdx, param);
5231
+ setParamDrawerOpen(false);
5232
+ setParamDrawerEndpointId(null);
5233
+ setParamDrawerMode("add");
5234
+ setEditParamIdx(null);
5235
+ },
5236
+ source: drawerSource
5237
+ })
5238
+ ]
5239
+ }));
5240
+ }
5241
+ return wrapSSR(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5242
+ className: cx("root"),
5243
+ children: [
5244
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5245
+ className: cx("head"),
5246
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd_es_typography_Title_js.default, {
5247
+ level: 4,
5248
+ style: {
5249
+ margin: 0,
5250
+ color: token.colorTextHeading
5251
+ },
5252
+ children: "Endpoints"
5253
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
5254
+ type: "text",
5255
+ size: "large",
5256
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.UpCircleOutlined, { style: { fontSize: 18 } }),
5257
+ onClick: onToggleCollapse,
5258
+ style: {
5259
+ transform: collapsed ? "rotate(180deg)" : "rotate(0deg)",
5260
+ transition: "transform 0.2s"
5261
+ }
5262
+ })]
5263
+ }),
5264
+ !collapsed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3951
5265
  className: cx("body"),
3952
5266
  children: Object.values(endpointsByTag).flat().map((ep) => {
3953
5267
  const isExpanded = expandedId === ep.id;
@@ -3995,49 +5309,95 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
3995
5309
  className: cx("view-params-title"),
3996
5310
  children: "Request"
3997
5311
  })
3998
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Table, {
3999
- dataSource: buildViewParamRows(endpointParams[ep.id] ?? []),
4000
- columns: viewParamColumns,
4001
- pagination: false,
4002
- rowClassName: (_, idx) => cx(idx % 2 === 0 ? "view-row-odd" : "view-row-even"),
4003
- size: "small",
4004
- bordered: true
4005
- })]
5312
+ }), (() => {
5313
+ const allVReqRows = buildViewParamRows(endpointParams[ep.id] ?? []);
5314
+ const vReqPage = requestPages.get(ep.id) ?? 1;
5315
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Table, {
5316
+ dataSource: allVReqRows.slice((vReqPage - 1) * VIEW_PAGE_SIZE, vReqPage * VIEW_PAGE_SIZE),
5317
+ columns: viewParamColumns,
5318
+ pagination: false,
5319
+ rowClassName: (_, idx) => cx(idx % 2 === 0 ? "view-row-odd" : "view-row-even"),
5320
+ size: "small",
5321
+ bordered: true
5322
+ }), allVReqRows.length > VIEW_PAGE_SIZE && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5323
+ style: { paddingBottom: 12 },
5324
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Pagination, {
5325
+ current: vReqPage,
5326
+ pageSize: VIEW_PAGE_SIZE,
5327
+ total: allVReqRows.length,
5328
+ onChange: (page) => setRequestPages((prev) => new Map(prev).set(ep.id, page)),
5329
+ showSizeChanger: false,
5330
+ className: cx("pagination")
5331
+ })
5332
+ })] });
5333
+ })()]
4006
5334
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4007
5335
  className: cx("view-params-card"),
4008
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4009
- className: cx("view-params-header"),
4010
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4011
- className: cx("view-params-title"),
4012
- children: "Response"
4013
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Select, {
4014
- className: cx("view-status-select-sm"),
4015
- popupClassName: "status-code-dropdown",
4016
- value: selectedStatusCodes[ep.id] ?? (Object.keys(ep.responses ?? {}).includes("200") ? "200" : Object.keys(ep.responses ?? {})[0]),
4017
- onChange: (val) => setSelectedStatusCodes((prev) => ({
4018
- ...prev,
4019
- [ep.id]: val
4020
- })),
4021
- options: Object.keys(ep.responses ?? {}).map((code) => ({
4022
- value: code,
4023
- label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4024
- className: cx("status-label"),
4025
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4026
- className: cx("status-dot"),
4027
- style: { background: getStatusCodeColor(code, antdToken).dot }
4028
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: code })]
5336
+ children: [
5337
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5338
+ className: cx("view-params-header"),
5339
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5340
+ className: cx("view-params-title"),
5341
+ children: "Response"
5342
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Select, {
5343
+ className: cx("view-status-select-sm"),
5344
+ popupClassName: "status-code-dropdown",
5345
+ value: selectedStatusCodes[ep.id] ?? (Object.keys(ep.responses ?? {}).includes("200") ? "200" : Object.keys(ep.responses ?? {})[0]),
5346
+ onChange: (val) => setSelectedStatusCodes((prev) => ({
5347
+ ...prev,
5348
+ [ep.id]: val
5349
+ })),
5350
+ options: Object.keys(ep.responses ?? {}).map((code) => ({
5351
+ value: code,
5352
+ label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5353
+ className: cx("status-label"),
5354
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5355
+ className: cx("status-dot"),
5356
+ style: { background: getStatusCodeColor(code, antdToken).dot }
5357
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: code })]
5358
+ })
5359
+ })),
5360
+ size: "middle"
5361
+ })]
5362
+ }),
5363
+ (() => {
5364
+ const allVResRows = buildViewParamRows(endpointResponseParams[ep.id] ?? []);
5365
+ const vResPage = responsePages.get(ep.id) ?? 1;
5366
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Table, {
5367
+ dataSource: allVResRows.slice((vResPage - 1) * VIEW_PAGE_SIZE, vResPage * VIEW_PAGE_SIZE),
5368
+ columns: viewParamColumns,
5369
+ pagination: false,
5370
+ rowClassName: (_, idx) => cx(idx % 2 === 0 ? "view-row-odd" : "view-row-even"),
5371
+ size: "small",
5372
+ bordered: true
5373
+ }), allVResRows.length > VIEW_PAGE_SIZE && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5374
+ style: { paddingBottom: 12 },
5375
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Pagination, {
5376
+ current: vResPage,
5377
+ pageSize: VIEW_PAGE_SIZE,
5378
+ total: allVResRows.length,
5379
+ onChange: (page) => setResponsePages((prev) => new Map(prev).set(ep.id, page)),
5380
+ showSizeChanger: false,
5381
+ className: cx("pagination")
4029
5382
  })
4030
- })),
4031
- size: "middle"
4032
- })]
4033
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Table, {
4034
- dataSource: buildViewParamRows(endpointResponseParams[ep.id] ?? []),
4035
- columns: viewParamColumns,
4036
- pagination: false,
4037
- rowClassName: (_, idx) => cx(idx % 2 === 0 ? "view-row-odd" : "view-row-even"),
4038
- size: "small",
4039
- bordered: true
4040
- })]
5383
+ })] });
5384
+ })(),
5385
+ (() => {
5386
+ const selectedCode = selectedStatusCodes[ep.id] ?? (Object.keys(ep.responses ?? {}).includes("200") ? "200" : Object.keys(ep.responses ?? {})[0]);
5387
+ const responseContent = ep.responses?.[selectedCode]?.content;
5388
+ if (!responseContent) return null;
5389
+ const schema = Object.values(responseContent)[0]?.schema;
5390
+ if (!schema) return null;
5391
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5392
+ className: cx("code-panel"),
5393
+ style: { marginTop: token.marginSM },
5394
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
5395
+ className: cx("code-area"),
5396
+ children: JSON.stringify(schema, null, 2)
5397
+ })
5398
+ });
5399
+ })()
5400
+ ]
4041
5401
  })]
4042
5402
  }),
4043
5403
  isExpanded && mode !== "view" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -4057,7 +5417,9 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4057
5417
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
4058
5418
  size: "large",
4059
5419
  value: endpointNames[ep.id] ?? ep.summary ?? "",
4060
- onChange: (e) => onEndpointNameChange(ep.id, e.target.value)
5420
+ onChange: (e) => onEndpointNameChange(ep.id, e.target.value),
5421
+ maxLength: 100,
5422
+ showCount: true
4061
5423
  })]
4062
5424
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4063
5425
  className: cx("form-field"),
@@ -4290,9 +5652,8 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4290
5652
  style: {
4291
5653
  padding: 0,
4292
5654
  lineHeight: 1,
4293
- width: 32,
4294
- height: 32,
4295
- fontSize: 20
5655
+ width: 40,
5656
+ height: 40
4296
5657
  },
4297
5658
  className: cx("param-delete-btn"),
4298
5659
  onClick: () => setDeleteParamModal({
@@ -4304,7 +5665,16 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4304
5665
  })
4305
5666
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4306
5667
  ghost: true,
4307
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.EditOutlined, {}),
5668
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditTag, {
5669
+ width: 18,
5670
+ height: 18
5671
+ }),
5672
+ style: {
5673
+ width: 40,
5674
+ height: 40,
5675
+ padding: 0,
5676
+ lineHeight: 1
5677
+ },
4308
5678
  className: cx("param-edit-btn"),
4309
5679
  onClick: () => {
4310
5680
  setDrawerSource("request");
@@ -4401,14 +5771,15 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4401
5771
  className: cx("param-actions"),
4402
5772
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4403
5773
  danger: true,
4404
- type: "text",
4405
5774
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Trash, {
4406
- height: 32,
4407
- width: 32
5775
+ width: 32,
5776
+ height: 32
4408
5777
  }),
4409
5778
  style: {
4410
5779
  padding: 0,
4411
- lineHeight: 1
5780
+ lineHeight: 1,
5781
+ width: 40,
5782
+ height: 40
4412
5783
  },
4413
5784
  className: cx("param-delete-btn"),
4414
5785
  onClick: () => setDeleteParamModal({
@@ -4420,7 +5791,16 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4420
5791
  })
4421
5792
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4422
5793
  ghost: true,
4423
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.EditOutlined, {}),
5794
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditTag, {
5795
+ width: 18,
5796
+ height: 18
5797
+ }),
5798
+ style: {
5799
+ width: 40,
5800
+ height: 40,
5801
+ padding: 0,
5802
+ lineHeight: 1
5803
+ },
4424
5804
  className: cx("param-edit-btn"),
4425
5805
  onClick: () => {
4426
5806
  setDrawerSource("request");
@@ -4442,8 +5822,8 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4442
5822
  className: cx("pagination")
4443
5823
  })] });
4444
5824
  })(),
4445
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4446
- className: cx("param-row"),
5825
+ !["GET", "DELETE"].includes(ep.method) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5826
+ className: cx("param-row", openRequestPanels.has(ep.id) ? "param-row--open" : ""),
4447
5827
  style: { marginTop: token.margin },
4448
5828
  onClick: () => toggleRequestPanel(ep.id),
4449
5829
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.DownOutlined, { className: cx("param-row-icon", openRequestPanels.has(ep.id) ? "param-row-icon--open" : "") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
@@ -4454,29 +5834,43 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4454
5834
  })]
4455
5835
  })]
4456
5836
  }),
4457
- openRequestPanels.has(ep.id) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5837
+ !["GET", "DELETE"].includes(ep.method) && openRequestPanels.has(ep.id) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4458
5838
  className: cx("code-panel"),
4459
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
4460
- className: cx("code-area"),
4461
- children: JSON.stringify((endpointParams[ep.id] ?? []).map((p) => ({
4462
- name: p.name,
4463
- in: p.in,
4464
- type: p.type,
4465
- required: p.required,
4466
- ...p.description ? { description: p.description } : {},
4467
- ...p.enum && p.enum.length > 0 ? { enum: p.enum } : {}
4468
- })), null, 2)
5839
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input.TextArea, {
5840
+ value: editableRequestContent[ep.id] ?? "",
5841
+ onChange: (e) => {
5842
+ setEditableRequestContent((prev) => ({
5843
+ ...prev,
5844
+ [ep.id]: e.target.value
5845
+ }));
5846
+ onRequestContentChange?.(ep.id, e.target.value);
5847
+ },
5848
+ rows: Math.max(3, (editableRequestContent[ep.id] ?? "").split("\n").length),
5849
+ style: {
5850
+ fontFamily: "monospace",
5851
+ fontSize: "0.75rem",
5852
+ background: "#1D2856",
5853
+ color: "#fff",
5854
+ outline: "none",
5855
+ boxShadow: "none",
5856
+ border: "none"
5857
+ }
4469
5858
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4470
5859
  className: cx("code-footer"),
4471
5860
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4472
5861
  ghost: true,
4473
5862
  size: "small",
4474
5863
  className: cx("code-btn"),
5864
+ onClick: () => handleValidate(editableRequestContent[ep.id] ?? ""),
4475
5865
  children: "Validate"
4476
5866
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4477
5867
  ghost: true,
4478
5868
  size: "small",
4479
5869
  className: cx("code-btn"),
5870
+ onClick: () => handleBeautify(editableRequestContent[ep.id] ?? "", (v) => setEditableRequestContent((prev) => ({
5871
+ ...prev,
5872
+ [ep.id]: v
5873
+ }))),
4480
5874
  children: "Beautify"
4481
5875
  })]
4482
5876
  })]
@@ -4729,9 +6123,8 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4729
6123
  style: {
4730
6124
  padding: 0,
4731
6125
  lineHeight: 1,
4732
- width: 32,
4733
- height: 32,
4734
- fontSize: 20
6126
+ width: 40,
6127
+ height: 40
4735
6128
  },
4736
6129
  className: cx("param-delete-btn"),
4737
6130
  onClick: () => setDeleteParamModal({
@@ -4743,7 +6136,16 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4743
6136
  })
4744
6137
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4745
6138
  ghost: true,
4746
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.EditOutlined, {}),
6139
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditTag, {
6140
+ width: 18,
6141
+ height: 18
6142
+ }),
6143
+ style: {
6144
+ width: 40,
6145
+ height: 40,
6146
+ padding: 0,
6147
+ lineHeight: 1
6148
+ },
4747
6149
  className: cx("param-edit-btn"),
4748
6150
  onClick: () => {
4749
6151
  setDrawerSource("response");
@@ -4840,7 +6242,16 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4840
6242
  className: cx("param-actions"),
4841
6243
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4842
6244
  ghost: true,
4843
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.EditOutlined, {}),
6245
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditTag, {
6246
+ width: 18,
6247
+ height: 18
6248
+ }),
6249
+ style: {
6250
+ width: 40,
6251
+ height: 40,
6252
+ padding: 0,
6253
+ lineHeight: 1
6254
+ },
4844
6255
  className: cx("param-edit-btn"),
4845
6256
  onClick: () => {
4846
6257
  setDrawerSource("response");
@@ -4851,14 +6262,15 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4851
6262
  }
4852
6263
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4853
6264
  danger: true,
4854
- type: "text",
4855
6265
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Trash, {
4856
- height: 18,
4857
- width: 18
6266
+ width: 32,
6267
+ height: 32
4858
6268
  }),
4859
6269
  style: {
4860
6270
  padding: 0,
4861
- lineHeight: 1
6271
+ lineHeight: 1,
6272
+ width: 40,
6273
+ height: 40
4862
6274
  },
4863
6275
  className: cx("param-delete-btn"),
4864
6276
  onClick: () => setDeleteParamModal({
@@ -4882,7 +6294,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4882
6294
  })] });
4883
6295
  })(),
4884
6296
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4885
- className: cx("param-row"),
6297
+ className: cx("param-row", openResponsePanels.has(ep.id) ? "param-row--open" : ""),
4886
6298
  style: { marginTop: token.margin },
4887
6299
  onClick: () => toggleResponsePanel(ep.id),
4888
6300
  children: [
@@ -4902,27 +6314,41 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4902
6314
  }),
4903
6315
  openResponsePanels.has(ep.id) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4904
6316
  className: cx("code-panel"),
4905
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
4906
- className: cx("code-area"),
4907
- children: JSON.stringify((endpointResponseParams[ep.id] ?? []).map((p) => ({
4908
- name: p.name,
4909
- in: p.in,
4910
- type: p.type,
4911
- required: p.required,
4912
- ...p.description ? { description: p.description } : {},
4913
- ...p.enum && p.enum.length > 0 ? { enum: p.enum } : {}
4914
- })), null, 2)
6317
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input.TextArea, {
6318
+ value: editableResponseContent[ep.id] ?? "",
6319
+ onChange: (e) => {
6320
+ setEditableResponseContent((prev) => ({
6321
+ ...prev,
6322
+ [ep.id]: e.target.value
6323
+ }));
6324
+ onResponseContentChange?.(ep.id, e.target.value);
6325
+ },
6326
+ rows: Math.max(3, (editableResponseContent[ep.id] ?? "").split("\n").length),
6327
+ style: {
6328
+ fontFamily: "monospace",
6329
+ fontSize: "0.75rem",
6330
+ background: "#1D2856",
6331
+ color: "#fff",
6332
+ outline: "none",
6333
+ boxShadow: "none",
6334
+ border: "none"
6335
+ }
4915
6336
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4916
6337
  className: cx("code-footer"),
4917
6338
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4918
6339
  ghost: true,
4919
6340
  size: "small",
4920
6341
  className: cx("code-btn"),
6342
+ onClick: () => handleValidate(editableResponseContent[ep.id] ?? ""),
4921
6343
  children: "Validate"
4922
6344
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
4923
6345
  ghost: true,
4924
6346
  size: "small",
4925
6347
  className: cx("code-btn"),
6348
+ onClick: () => handleBeautify(editableResponseContent[ep.id] ?? "", (v) => setEditableResponseContent((prev) => ({
6349
+ ...prev,
6350
+ [ep.id]: v
6351
+ }))),
4926
6352
  children: "Beautify"
4927
6353
  })]
4928
6354
  })]
@@ -5071,7 +6497,8 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
5071
6497
  setParamDrawerEndpointId(null);
5072
6498
  setParamDrawerMode("add");
5073
6499
  setEditParamIdx(null);
5074
- }
6500
+ },
6501
+ source: drawerSource
5075
6502
  })
5076
6503
  ]
5077
6504
  }));
@@ -5099,7 +6526,7 @@ const UnsavedChangesBanner = ({ onClose }) => {
5099
6526
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Alert, {
5100
6527
  className: cx("alert"),
5101
6528
  type: "warning",
5102
- message: "There are changes you made may not be saved",
6529
+ message: "There are changes you made that may not be saved",
5103
6530
  closable: true,
5104
6531
  onClose,
5105
6532
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.ExclamationCircleFilled, {}),
@@ -5110,57 +6537,50 @@ const UnsavedChangesBanner = ({ onClose }) => {
5110
6537
  //#endregion
5111
6538
  //#region src/view/components/ApiPage/components/TagsSection.tsx
5112
6539
  const { useBreakpoint: useBreakpoint$1 } = antd.Grid;
5113
- const TagsSection = ({ tags, collapsed = false, onToggleCollapse, onAddTag, onEditTag, onDeleteTag }) => {
6540
+ const TAGS_PAGE_SIZE = 8;
6541
+ const TagsSection = ({ tags, collapsed, onToggleCollapse, onAddTag, onEditTag, onDeleteTag }) => {
5114
6542
  const isMobile = !useBreakpoint$1().md;
6543
+ const [currentPage, setCurrentPage] = (0, react$1.useState)(1);
6544
+ const sortedTags = [...tags].sort((a, b) => a.isDefault === b.isDefault ? 0 : a.isDefault ? -1 : 1);
6545
+ const maxPage = Math.max(1, Math.ceil(tags.length / TAGS_PAGE_SIZE));
6546
+ const safePage = Math.min(currentPage, maxPage);
6547
+ const paginatedTags = sortedTags.slice((safePage - 1) * TAGS_PAGE_SIZE, safePage * TAGS_PAGE_SIZE);
5115
6548
  const { wrapSSR, cx, token } = useStyle("TagsSection", (token, scope) => ({
5116
6549
  [scope("root")]: {
5117
6550
  display: "flex",
5118
6551
  flexDirection: "column",
5119
- borderRadius: token.borderRadius,
5120
- overflow: "hidden",
5121
- width: "100%",
5122
- flexShrink: 0
6552
+ gap: token.margin,
6553
+ padding: token.marginLG,
6554
+ background: token.colorBgElevated,
6555
+ borderRadius: token.borderRadiusLG,
6556
+ width: "100%"
5123
6557
  },
5124
6558
  [scope("head")]: {
5125
6559
  display: "flex",
5126
6560
  alignItems: "center",
5127
6561
  justifyContent: "space-between",
5128
- padding: `${token.paddingXS}px ${token.paddingLG}px`,
5129
- background: token.colorPrimaryBg,
5130
- borderRadius: `${token.borderRadius}px ${token.borderRadius}px 0 0`
5131
- },
5132
- [scope("head-actions")]: {
5133
- display: "flex",
5134
- alignItems: "center",
5135
- gap: token.margin
6562
+ width: "100%"
5136
6563
  },
5137
- [scope("body")]: {
6564
+ [scope("tags-list")]: {
5138
6565
  display: "flex",
5139
6566
  flexDirection: "column",
5140
- gap: 0,
5141
- padding: token.paddingLG,
5142
- background: token.colorBgElevated,
5143
- borderRadius: `0 0 ${token.borderRadius}px ${token.borderRadius}px`
6567
+ width: "100%"
5144
6568
  },
5145
6569
  [scope("tag-row")]: {
5146
6570
  display: "flex",
5147
6571
  alignItems: "center",
5148
6572
  justifyContent: "space-between",
5149
- height: 50,
5150
- paddingTop: token.controlHeightLG,
5151
- paddingBottom: token.controlHeightLG,
5152
- paddingRight: token.paddingLG,
5153
- borderBottom: `1px solid ${token.colorBorder}`,
5154
- width: "100%"
5155
- },
5156
- [scope("tag-row-last")]: {
5157
- borderBottom: "none",
5158
- paddingBottom: token.marginLG
6573
+ minHeight: 50,
6574
+ paddingTop: 12,
6575
+ paddingBottom: 12,
6576
+ width: "100%",
6577
+ borderBottom: `1px solid ${token.colorBorder}`
5159
6578
  },
6579
+ [scope("tag-row-last")]: { borderBottom: "none" },
5160
6580
  [scope("tag-info")]: {
5161
6581
  display: "flex",
5162
6582
  alignItems: "center",
5163
- gap: 32,
6583
+ gap: token.marginXL,
5164
6584
  flex: 1,
5165
6585
  minWidth: 0
5166
6586
  },
@@ -5196,32 +6616,13 @@ const TagsSection = ({ tags, collapsed = false, onToggleCollapse, onAddTag, onEd
5196
6616
  alignItems: "center",
5197
6617
  gap: token.margin
5198
6618
  },
5199
- [scope("btn-delete")]: {
5200
- width: 40,
5201
- height: 40,
5202
- border: `1px solid ${token.colorError}`,
5203
- borderRadius: token.borderRadius,
5204
- display: "flex",
5205
- alignItems: "center",
5206
- justifyContent: "center"
5207
- },
5208
- [scope("btn-edit")]: {
5209
- width: 40,
5210
- height: 40,
5211
- border: `1px solid ${token.colorBorder}`,
5212
- borderRadius: token.borderRadius,
5213
- background: token.colorBgContainer,
5214
- boxShadow: "0px 2px 0px 0px rgba(0,0,0,0.02)",
5215
- display: "flex",
5216
- alignItems: "center",
5217
- justifyContent: "center"
5218
- },
5219
6619
  [scope("tag-row-mobile")]: {
5220
6620
  display: "flex",
5221
6621
  flexDirection: "row",
5222
6622
  alignItems: "flex-start",
5223
6623
  justifyContent: "space-between",
5224
6624
  gap: 8,
6625
+ paddingTop: 12,
5225
6626
  paddingBottom: token.margin,
5226
6627
  borderBottom: `1px solid ${token.colorBorder}`,
5227
6628
  width: "100%",
@@ -5251,16 +6652,176 @@ const TagsSection = ({ tags, collapsed = false, onToggleCollapse, onAddTag, onEd
5251
6652
  display: "flex",
5252
6653
  flexDirection: "column",
5253
6654
  gap: 0,
5254
- padding: token.paddingMD,
5255
- background: token.colorBgElevated,
5256
- borderRadius: `0 0 ${token.borderRadius}px ${token.borderRadius}px`,
5257
6655
  overflowX: "auto"
6656
+ },
6657
+ [scope("head-collapse")]: {
6658
+ display: "flex",
6659
+ alignItems: "center",
6660
+ justifyContent: "space-between",
6661
+ padding: `${token.paddingXS}px ${token.paddingLG}px`,
6662
+ background: token.colorPrimaryBg,
6663
+ borderRadius: `${token.borderRadius}px ${token.borderRadius}px 0 0`
6664
+ },
6665
+ [scope("body-collapse")]: {
6666
+ display: "flex",
6667
+ flexDirection: "column",
6668
+ gap: token.margin,
6669
+ padding: token.paddingLG,
6670
+ background: token.colorBgElevated,
6671
+ borderRadius: `0 0 ${token.borderRadius}px ${token.borderRadius}px`
6672
+ },
6673
+ [scope("pagination")]: {
6674
+ display: "flex",
6675
+ justifyContent: "center",
6676
+ marginTop: token.marginMD,
6677
+ ".ant-pagination-item-active": {
6678
+ backgroundColor: token.colorBgContainer,
6679
+ borderColor: token.colorPrimary,
6680
+ borderRadius: token.borderRadius,
6681
+ display: "flex",
6682
+ alignItems: "center",
6683
+ justifyContent: "center",
6684
+ a: {
6685
+ color: token.colorPrimary,
6686
+ fontWeight: token.fontWeightStrong,
6687
+ fontSize: token.fontSize,
6688
+ lineHeight: "22px",
6689
+ display: "flex",
6690
+ alignItems: "center",
6691
+ justifyContent: "center",
6692
+ height: "100%"
6693
+ }
6694
+ },
6695
+ ".ant-pagination-item": {
6696
+ borderRadius: token.borderRadius,
6697
+ minWidth: 32,
6698
+ height: 32,
6699
+ lineHeight: "32px",
6700
+ a: {
6701
+ color: token.colorText,
6702
+ fontWeight: 400,
6703
+ fontSize: token.fontSize
6704
+ }
6705
+ },
6706
+ ".ant-pagination-prev .ant-pagination-item-link, .ant-pagination-next .ant-pagination-item-link": {
6707
+ borderRadius: token.borderRadius,
6708
+ width: 32,
6709
+ height: 32,
6710
+ display: "flex",
6711
+ alignItems: "center",
6712
+ justifyContent: "center",
6713
+ border: "none",
6714
+ background: "transparent"
6715
+ }
5258
6716
  }
5259
6717
  }));
5260
- return wrapSSR(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5261
- className: cx("root"),
6718
+ const mobileTagsList = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6719
+ className: cx("body-mobile"),
6720
+ children: paginatedTags.map((tag, index) => {
6721
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6722
+ className: cx("tag-row-mobile", index === paginatedTags.length - 1 ? "tag-row-mobile-last" : ""),
6723
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6724
+ className: cx("tag-info-mobile"),
6725
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6726
+ className: cx("tag-col-mobile"),
6727
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6728
+ className: cx("col-label"),
6729
+ style: {
6730
+ fontSize: token.fontSize,
6731
+ lineHeight: "20px"
6732
+ },
6733
+ children: "Tag Name:"
6734
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6735
+ className: cx("col-value"),
6736
+ style: {
6737
+ fontSize: token.fontSize,
6738
+ lineHeight: "20px",
6739
+ overflow: "hidden",
6740
+ textOverflow: "ellipsis",
6741
+ whiteSpace: "nowrap"
6742
+ },
6743
+ children: tag.name
6744
+ })]
6745
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6746
+ className: cx("tag-col-mobile"),
6747
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6748
+ className: cx("col-label"),
6749
+ style: {
6750
+ fontSize: token.fontSize,
6751
+ lineHeight: "20px"
6752
+ },
6753
+ children: "Description:"
6754
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
6755
+ title: tag.description && tag.description.length > 20 ? tag.description : "",
6756
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6757
+ className: cx("col-value"),
6758
+ style: {
6759
+ fontSize: token.fontSize,
6760
+ lineHeight: "20px",
6761
+ overflow: "hidden",
6762
+ textOverflow: "ellipsis",
6763
+ whiteSpace: "nowrap",
6764
+ maxWidth: 140,
6765
+ display: "block"
6766
+ },
6767
+ children: tag.description ?? "-"
6768
+ })
6769
+ })]
6770
+ })]
6771
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6772
+ className: cx("tag-actions"),
6773
+ style: {
6774
+ paddingTop: 6,
6775
+ flexShrink: 0
6776
+ },
6777
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
6778
+ title: tag.isDefault ? "The default tag cannot be deleted or edited" : "",
6779
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
6780
+ danger: true,
6781
+ type: "text",
6782
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Trash, {
6783
+ width: 32,
6784
+ height: 32
6785
+ }),
6786
+ disabled: tag.isDefault,
6787
+ onClick: () => !tag.isDefault && onDeleteTag?.(tag.name),
6788
+ style: {
6789
+ width: 40,
6790
+ height: 40,
6791
+ padding: 0,
6792
+ lineHeight: 1
6793
+ }
6794
+ })
6795
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
6796
+ title: tag.isDefault ? "The default tag cannot be deleted or edited" : "",
6797
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
6798
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditTag, {}),
6799
+ disabled: tag.isDefault,
6800
+ onClick: () => !tag.isDefault && onEditTag?.(tag),
6801
+ style: {
6802
+ width: 32,
6803
+ height: 32,
6804
+ padding: 0,
6805
+ lineHeight: 1,
6806
+ ...!tag.isDefault && { color: "#A146B3" }
6807
+ }
6808
+ })
6809
+ })]
6810
+ })]
6811
+ }, tag.name);
6812
+ })
6813
+ }), tags.length > TAGS_PAGE_SIZE && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Pagination, {
6814
+ current: safePage,
6815
+ pageSize: TAGS_PAGE_SIZE,
6816
+ total: tags.length,
6817
+ onChange: setCurrentPage,
6818
+ showSizeChanger: false,
6819
+ className: cx("pagination")
6820
+ })] });
6821
+ return wrapSSR(isMobile ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6822
+ style: { width: "100%" },
5262
6823
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5263
- className: cx("head"),
6824
+ className: cx("head-collapse"),
5264
6825
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd_es_typography_Title_js.default, {
5265
6826
  level: 4,
5266
6827
  style: {
@@ -5269,7 +6830,11 @@ const TagsSection = ({ tags, collapsed = false, onToggleCollapse, onAddTag, onEd
5269
6830
  },
5270
6831
  children: "Tags"
5271
6832
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5272
- className: cx("head-actions"),
6833
+ style: {
6834
+ display: "flex",
6835
+ alignItems: "center",
6836
+ gap: token.marginXS
6837
+ },
5273
6838
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
5274
6839
  ghost: true,
5275
6840
  type: "primary",
@@ -5288,215 +6853,156 @@ const TagsSection = ({ tags, collapsed = false, onToggleCollapse, onAddTag, onEd
5288
6853
  }
5289
6854
  })]
5290
6855
  })]
5291
- }), !collapsed && (isMobile ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5292
- className: cx("body-mobile"),
5293
- children: tags.map((tag, index) => {
5294
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5295
- className: cx("tag-row-mobile", index === tags.length - 1 ? "tag-row-mobile-last" : ""),
5296
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5297
- className: cx("tag-info-mobile"),
6856
+ }), !collapsed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6857
+ className: cx("body-collapse"),
6858
+ children: mobileTagsList
6859
+ })]
6860
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6861
+ className: cx("root"),
6862
+ children: [
6863
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6864
+ className: cx("head"),
6865
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd_es_typography_Title_js.default, {
6866
+ level: 4,
6867
+ style: {
6868
+ margin: 0,
6869
+ color: token.colorTextHeading
6870
+ },
6871
+ children: "Tags"
6872
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
6873
+ ghost: true,
6874
+ type: "primary",
6875
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.PlusOutlined, {}),
6876
+ onClick: onAddTag,
6877
+ style: { borderRadius: token.borderRadius },
6878
+ children: "Add Tag"
6879
+ })]
6880
+ }),
6881
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6882
+ className: cx("tags-list"),
6883
+ children: paginatedTags.map((tag, index) => {
6884
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6885
+ className: cx("tag-row", index === paginatedTags.length - 1 ? "tag-row-last" : ""),
5298
6886
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5299
- className: cx("tag-col-mobile"),
5300
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5301
- className: cx("col-label"),
5302
- style: {
5303
- fontSize: token.fontSize,
5304
- lineHeight: "20px"
5305
- },
5306
- children: "Tag Name:"
5307
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5308
- className: cx("col-value"),
5309
- style: {
5310
- fontSize: token.fontSize,
5311
- lineHeight: "20px",
5312
- overflow: "hidden",
5313
- textOverflow: "ellipsis",
5314
- whiteSpace: "nowrap"
5315
- },
5316
- children: tag.name
5317
- })]
5318
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5319
- className: cx("tag-col-mobile"),
5320
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5321
- className: cx("col-label"),
5322
- style: {
5323
- fontSize: token.fontSize,
5324
- lineHeight: "20px"
5325
- },
5326
- children: "Description:"
5327
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
5328
- title: tag.description && tag.description.length > 20 ? tag.description : "",
5329
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5330
- className: cx("col-value"),
5331
- style: {
5332
- fontSize: token.fontSize,
5333
- lineHeight: "20px",
5334
- overflow: "hidden",
5335
- textOverflow: "ellipsis",
5336
- whiteSpace: "nowrap",
5337
- maxWidth: 140,
5338
- display: "block"
5339
- },
5340
- children: tag.description ?? "-"
5341
- })
5342
- })]
5343
- })]
5344
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5345
- className: cx("tag-actions"),
5346
- style: {
5347
- paddingTop: 6,
5348
- flexShrink: 0
5349
- },
5350
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
5351
- title: tag.isDefault ? "The default tag cannot be deleted or edited" : "",
5352
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
5353
- danger: true,
5354
- type: "text",
5355
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Trash, {
5356
- width: 32,
5357
- height: 32
5358
- }),
5359
- disabled: tag.isDefault,
5360
- onClick: () => !tag.isDefault && onDeleteTag?.(tag.name),
5361
- style: {
5362
- width: 40,
5363
- height: 40,
5364
- padding: 0,
5365
- lineHeight: 1
5366
- }
5367
- })
5368
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
5369
- title: tag.isDefault ? "The default tag cannot be deleted or edited" : "",
5370
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
5371
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.EditOutlined, { style: { fontSize: 18 } }),
5372
- disabled: tag.isDefault,
5373
- onClick: () => !tag.isDefault && onEditTag?.(tag),
5374
- style: {
5375
- width: 32,
5376
- height: 32,
5377
- padding: 0,
5378
- lineHeight: 1
5379
- }
5380
- })
5381
- })]
5382
- })]
5383
- }, tag.name);
5384
- })
5385
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5386
- className: cx("body"),
5387
- children: tags.map((tag, index) => {
5388
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5389
- className: cx("tag-row", index === tags.length - 1 ? "tag-row-last" : ""),
5390
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5391
- className: cx("tag-info"),
5392
- children: [
5393
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5394
- className: cx("tag-col"),
5395
- style: { width: 200 },
5396
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5397
- className: cx("col-label"),
5398
- children: "Tag Name"
5399
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5400
- className: cx("col-value"),
5401
- children: tag.name
5402
- })]
5403
- }),
5404
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5405
- className: cx("tag-col"),
5406
- style: { width: 280 },
5407
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5408
- className: cx("col-label"),
5409
- children: "Description"
5410
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
5411
- title: tag.description && tag.description.length > 30 ? tag.description : "",
5412
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6887
+ className: cx("tag-info"),
6888
+ children: [
6889
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6890
+ className: cx("tag-col"),
6891
+ style: { width: 200 },
6892
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6893
+ className: cx("col-label"),
6894
+ children: "Tag Name"
6895
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5413
6896
  className: cx("col-value"),
5414
- style: {
5415
- overflow: "hidden",
5416
- textOverflow: "ellipsis",
5417
- whiteSpace: "nowrap",
5418
- maxWidth: 280,
5419
- display: "block"
5420
- },
5421
- children: tag.description ?? "-"
5422
- })
5423
- })]
5424
- }),
5425
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5426
- className: cx("tag-col"),
5427
- style: {
5428
- flex: 1,
5429
- minWidth: 0
5430
- },
5431
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5432
- className: cx("col-label"),
5433
- children: "External Docs"
5434
- }), tag.externalDocsUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
5435
- title: tag.externalDocsUrl.length > 25 ? tag.externalDocsUrl : "",
5436
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
5437
- href: tag.externalDocsUrl,
5438
- target: "_blank",
5439
- rel: "noreferrer",
5440
- className: cx("col-value-link"),
5441
- style: {
5442
- overflow: "hidden",
5443
- textOverflow: "ellipsis",
5444
- whiteSpace: "nowrap",
5445
- display: "block"
5446
- },
5447
- children: tag.externalDocsUrl
5448
- })
5449
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5450
- className: cx("col-value"),
5451
- children: "-"
5452
- })]
5453
- })
5454
- ]
5455
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5456
- className: cx("tag-actions"),
5457
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
5458
- title: tag.isDefault ? "The default tag cannot be deleted or edited" : "",
5459
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
5460
- danger: true,
5461
- type: "text",
5462
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Trash, {
5463
- width: 32,
5464
- height: 32
6897
+ children: tag.name
6898
+ })]
6899
+ }),
6900
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6901
+ className: cx("tag-col"),
6902
+ style: { width: 280 },
6903
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6904
+ className: cx("col-label"),
6905
+ children: "Description"
6906
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
6907
+ title: tag.description && tag.description.length > 30 ? tag.description : "",
6908
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6909
+ className: cx("col-value"),
6910
+ style: {
6911
+ overflow: "hidden",
6912
+ textOverflow: "ellipsis",
6913
+ whiteSpace: "nowrap",
6914
+ maxWidth: 280,
6915
+ display: "block"
6916
+ },
6917
+ children: tag.description ?? "-"
6918
+ })
6919
+ })]
5465
6920
  }),
5466
- disabled: tag.isDefault,
5467
- onClick: () => !tag.isDefault && onDeleteTag?.(tag.name),
5468
- style: {
5469
- width: 40,
5470
- height: 40,
5471
- padding: 0,
5472
- lineHeight: 1
5473
- }
5474
- })
5475
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
5476
- title: tag.isDefault ? "The default tag cannot be deleted or edited" : "",
5477
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
5478
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.EditOutlined, { style: { fontSize: 18 } }),
5479
- disabled: tag.isDefault,
5480
- onClick: () => !tag.isDefault && onEditTag?.(tag),
5481
- style: {
5482
- width: 32,
5483
- height: 32,
5484
- padding: 0,
5485
- lineHeight: 1
5486
- }
5487
- })
6921
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6922
+ className: cx("tag-col"),
6923
+ style: {
6924
+ flex: 1,
6925
+ minWidth: 0
6926
+ },
6927
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6928
+ className: cx("col-label"),
6929
+ children: "External Docs"
6930
+ }), tag.externalDocsUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
6931
+ title: tag.externalDocsUrl.length > 25 ? tag.externalDocsUrl : "",
6932
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
6933
+ href: tag.externalDocsUrl,
6934
+ target: "_blank",
6935
+ rel: "noreferrer",
6936
+ className: cx("col-value-link"),
6937
+ style: {
6938
+ overflow: "hidden",
6939
+ textOverflow: "ellipsis",
6940
+ whiteSpace: "nowrap",
6941
+ display: "block"
6942
+ },
6943
+ children: tag.externalDocsUrl
6944
+ })
6945
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6946
+ className: cx("col-value"),
6947
+ children: "-"
6948
+ })]
6949
+ })
6950
+ ]
6951
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6952
+ className: cx("tag-actions"),
6953
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
6954
+ title: tag.isDefault ? "The default tag cannot be deleted or edited" : "",
6955
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
6956
+ danger: true,
6957
+ type: "text",
6958
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Trash, {
6959
+ width: 32,
6960
+ height: 32
6961
+ }),
6962
+ disabled: tag.isDefault,
6963
+ onClick: () => !tag.isDefault && onDeleteTag?.(tag.name),
6964
+ style: {
6965
+ width: 40,
6966
+ height: 40,
6967
+ padding: 0,
6968
+ lineHeight: 1
6969
+ }
6970
+ })
6971
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
6972
+ title: tag.isDefault ? "The default tag cannot be deleted or edited" : "",
6973
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
6974
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditTag, {}),
6975
+ disabled: tag.isDefault,
6976
+ onClick: () => !tag.isDefault && onEditTag?.(tag),
6977
+ style: {
6978
+ width: 32,
6979
+ height: 32,
6980
+ padding: 0,
6981
+ lineHeight: 1,
6982
+ ...!tag.isDefault && { color: "#A146B3" }
6983
+ }
6984
+ })
6985
+ })]
5488
6986
  })]
5489
- })]
5490
- }, tag.name);
6987
+ }, tag.name);
6988
+ })
6989
+ }),
6990
+ tags.length > TAGS_PAGE_SIZE && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Pagination, {
6991
+ current: safePage,
6992
+ pageSize: TAGS_PAGE_SIZE,
6993
+ total: tags.length,
6994
+ onChange: setCurrentPage,
6995
+ showSizeChanger: false,
6996
+ className: cx("pagination")
5491
6997
  })
5492
- }))]
6998
+ ]
5493
6999
  }));
5494
7000
  };
5495
7001
  //#endregion
5496
7002
  //#region src/view/components/ApiPage/components/AddTagDrawer.tsx
5497
- const TAG_NAME_REGEX = /^[A-Za-z0-9_-]+$/;
5498
- const TAG_DESC_REGEX = /^[A-Za-z0-9_-]+$/;
5499
- const EXT_DESC_REGEX = /^[A-Za-z0-9_-]+$/;
7003
+ const TAG_NAME_REGEX = /^[A-Za-z0-9_\s-]+$/;
7004
+ const TAG_DESC_REGEX = /^[A-Za-z0-9_\s-]+$/;
7005
+ const EXTERNAL_DOCS_DESC_REGEX = /^[A-Za-z0-9_\s-]+$/;
5500
7006
  const AddTagDrawer = ({ open, onClose, mode, initialValues, onAddTag, onEditTag }) => {
5501
7007
  const [form] = antd.Form.useForm();
5502
7008
  const [messageApi, contextHolder] = antd.message.useMessage();
@@ -5633,13 +7139,6 @@ const AddTagDrawer = ({ open, onClose, mode, initialValues, onAddTag, onEditTag
5633
7139
  if (open && mode === "edit" && initialValues) form.setFieldsValue(initialValues);
5634
7140
  if (!open) form.resetFields();
5635
7141
  }, [open]);
5636
- (0, react$1.useEffect)(() => {
5637
- if (!extDocsDesc?.trim()) form.setFields([{
5638
- name: "externalDocsLink",
5639
- value: void 0,
5640
- errors: []
5641
- }]);
5642
- }, [extDocsDesc]);
5643
7142
  (0, react$1.useEffect)(() => {
5644
7143
  if (extDocsDesc?.trim()) form.validateFields(["externalDocsLink"]).catch(() => {});
5645
7144
  }, [extDocsLink, extDocsDesc]);
@@ -5744,7 +7243,7 @@ const AddTagDrawer = ({ open, onClose, mode, initialValues, onAddTag, onEditTag
5744
7243
  },
5745
7244
  {
5746
7245
  pattern: TAG_NAME_REGEX,
5747
- message: "Only letters, numbers, underscores, and hyphens"
7246
+ message: "Only letters, numbers, spaces, underscores, and hyphens"
5748
7247
  }
5749
7248
  ],
5750
7249
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
@@ -5765,10 +7264,10 @@ const AddTagDrawer = ({ open, onClose, mode, initialValues, onAddTag, onEditTag
5765
7264
  rules: [{
5766
7265
  max: 50,
5767
7266
  message: "Maximum 50 characters"
5768
- }, { validator: (_, value) => {
5769
- if (!value || TAG_DESC_REGEX.test(value)) return Promise.resolve();
5770
- return Promise.reject(/* @__PURE__ */ new Error("Only letters, numbers, underscores, and hyphens"));
5771
- } }],
7267
+ }, {
7268
+ pattern: TAG_DESC_REGEX,
7269
+ message: "Only letters, numbers, spaces, _ and - allowed"
7270
+ }],
5772
7271
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input.TextArea, {
5773
7272
  showCount: true,
5774
7273
  maxLength: 50,
@@ -5788,14 +7287,21 @@ const AddTagDrawer = ({ open, onClose, mode, initialValues, onAddTag, onEditTag
5788
7287
  rules: [{
5789
7288
  max: 25,
5790
7289
  message: "Maximum 25 characters"
5791
- }, { validator: (_, value) => {
5792
- if (!value || EXT_DESC_REGEX.test(value)) return Promise.resolve();
5793
- return Promise.reject(/* @__PURE__ */ new Error("Only letters, numbers, underscores, and hyphens"));
5794
- } }],
7290
+ }, {
7291
+ pattern: EXTERNAL_DOCS_DESC_REGEX,
7292
+ message: "Only letters, numbers, spaces, _ and - allowed"
7293
+ }],
5795
7294
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
5796
7295
  showCount: true,
5797
7296
  maxLength: 25,
5798
- placeholder: "Describe External Docs"
7297
+ placeholder: "Describe External Docs",
7298
+ onChange: (e) => {
7299
+ if (!e.target.value?.trim()) form.setFields([{
7300
+ name: "externalDocsLink",
7301
+ value: void 0,
7302
+ errors: []
7303
+ }]);
7304
+ }
5799
7305
  })
5800
7306
  }),
5801
7307
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Form.Item, {
@@ -5806,8 +7312,8 @@ const AddTagDrawer = ({ open, onClose, mode, initialValues, onAddTag, onEditTag
5806
7312
  children: "External Docs Link"
5807
7313
  }),
5808
7314
  rules: [{
5809
- max: 512,
5810
- message: "Maximum 512 characters"
7315
+ max: 500,
7316
+ message: "Maximum 500 characters"
5811
7317
  }, { validator: async () => {
5812
7318
  const desc = form.getFieldValue("externalDocsDescription");
5813
7319
  const link = form.getFieldValue("externalDocsLink");
@@ -5820,19 +7326,11 @@ const AddTagDrawer = ({ open, onClose, mode, initialValues, onAddTag, onEditTag
5820
7326
  return Promise.reject(/* @__PURE__ */ new Error("Please enter a valid URL"));
5821
7327
  }
5822
7328
  } }],
5823
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
5824
- title: !isLinkEnabled ? "You need to add the External Docs Description first." : "",
5825
- color: "rgba(0,0,0,0.85)",
5826
- placement: "topLeft",
5827
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
5828
- showCount: true,
5829
- maxLength: 512,
5830
- placeholder: "External Docs Link",
5831
- disabled: !isLinkEnabled,
5832
- onChange: (e) => {
5833
- form.setFieldValue("externalDocsLink", e.target.value);
5834
- }
5835
- })
7329
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Input, {
7330
+ showCount: true,
7331
+ maxLength: 500,
7332
+ placeholder: "External Docs Link",
7333
+ disabled: !isLinkEnabled
5836
7334
  })
5837
7335
  })
5838
7336
  ]
@@ -5909,6 +7407,251 @@ const AddTagDrawer = ({ open, onClose, mode, initialValues, onAddTag, onEditTag
5909
7407
  })
5910
7408
  ] }));
5911
7409
  };
7410
+ //#endregion
7411
+ //#region src/assets/icons/restApi.tsx
7412
+ const RestApiIcon = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
7413
+ width: "16",
7414
+ height: "16",
7415
+ viewBox: "0 0 16 16",
7416
+ fill: "none",
7417
+ xmlns: "http://www.w3.org/2000/svg",
7418
+ ...props,
7419
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
7420
+ clipPath: "url(#restapi-clip)",
7421
+ children: [
7422
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
7423
+ d: "M14.4059 7.73805H13.2601V7.23565C13.2601 7.11607 13.1787 7.01187 13.0626 6.98294L12.2915 6.79083L11.8883 5.81794L12.2975 5.13716C12.3591 5.03469 12.343 4.90341 12.2585 4.81888L11.1795 3.73987C11.0949 3.65531 10.9636 3.63922 10.8612 3.70081L10.1804 4.11003L9.20745 3.70685L9.01534 2.9357C8.98644 2.81966 8.88222 2.73823 8.76264 2.73823H8.26032V1.59245C8.26032 1.44862 8.14373 1.33203 7.9999 1.33203C7.85607 1.33203 7.73949 1.44862 7.73949 1.59245V2.73823H7.23709C7.11751 2.73823 7.01331 2.81966 6.98438 2.9357L6.79227 3.70685L5.81938 4.11003L5.1386 3.70081C5.03607 3.63919 4.90485 3.65529 4.82032 3.73987L3.74131 4.81888C3.65675 4.90344 3.64066 5.03471 3.70225 5.13716L4.11146 5.81794L3.70829 6.79083L2.93714 6.98294C2.8211 7.01185 2.73967 7.11607 2.73967 7.23565V7.73805H1.59391C1.45008 7.73805 1.3335 7.85463 1.3335 7.99846C1.3335 8.14226 1.45008 8.25888 1.59391 8.25888H2.73969V8.76128C2.73969 8.88086 2.82113 8.98508 2.93717 9.01396L3.70831 9.20609L4.11149 10.179L3.70225 10.8598C3.64063 10.9623 3.65675 11.0935 3.74131 11.1781L4.82032 12.2571C4.90488 12.3416 5.03615 12.3577 5.13865 12.2961L5.81941 11.8869L6.79232 12.2901L6.98443 13.0612C7.01334 13.1773 7.11756 13.2587 7.23714 13.2587H7.73951V14.4045C7.73951 14.5483 7.8561 14.6649 7.99993 14.6649C8.14376 14.6649 8.26034 14.5483 8.26034 14.4045V13.2587H8.76274C8.88232 13.2587 8.98652 13.1773 9.01545 13.0612L9.20756 12.2901L10.1805 11.8869L10.8612 12.2961C10.9637 12.3577 11.095 12.3416 11.1796 12.2571L12.2586 11.1781C12.3431 11.0935 12.3592 10.9622 12.2976 10.8598L11.8884 10.179L12.2916 9.20609L13.0627 9.01396C13.1788 8.98508 13.2602 8.88086 13.2602 8.76128V8.25888H14.406C14.5498 8.25888 14.6664 8.14226 14.6664 7.99846C14.6663 7.85463 14.5497 7.73805 14.4059 7.73805ZM12.7393 8.55779L12.0382 8.73247C11.9581 8.75245 11.8922 8.80919 11.8606 8.88547L11.3569 10.1009C11.3253 10.1772 11.3318 10.264 11.3743 10.3348L11.7463 10.9537L10.9551 11.7449L10.3362 11.3729C10.2654 11.3303 10.1786 11.3239 10.1023 11.3555L8.88686 11.8592C8.81058 11.8909 8.75383 11.9567 8.73386 12.0369L8.5592 12.7379H7.44055L7.26589 12.0369C7.24592 11.9567 7.18917 11.8909 7.1129 11.8592L5.89743 11.3555C5.82113 11.3239 5.73435 11.3303 5.66355 11.3729L5.04464 11.7449L4.25342 10.9537L4.62545 10.3348C4.668 10.264 4.67443 10.1772 4.64282 10.1009L4.13912 8.88547C4.10751 8.80919 4.04159 8.75245 3.96149 8.73247L3.26045 8.55779V7.43914L3.96152 7.26448C4.04162 7.2445 4.10753 7.18776 4.13915 7.11148L4.64284 5.89602C4.67446 5.81971 4.668 5.73294 4.62548 5.66216L4.25344 5.04325L5.04467 4.25203L5.66357 4.62406C5.73435 4.66661 5.82113 4.67307 5.89743 4.64143L7.1129 4.13773C7.18917 4.10612 7.24592 4.04021 7.26589 3.9601L7.44055 3.25904H8.5592L8.73386 3.9601C8.75383 4.04021 8.81058 4.10612 8.88686 4.13773L10.1023 4.64143C10.1787 4.67305 10.2654 4.66659 10.3362 4.62406L10.9551 4.25203L11.7463 5.04325L11.3743 5.66216C11.3317 5.73294 11.3253 5.81971 11.3569 5.89602L11.8606 7.11148C11.8922 7.18776 11.9581 7.2445 12.0382 7.26448L12.7393 7.43914V8.55779Z",
7424
+ fill: "currentColor"
7425
+ }),
7426
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
7427
+ d: "M9.14809 4.86755C9.01309 4.81807 8.86346 4.88729 8.8139 5.02229C8.76434 5.15731 8.83364 5.30692 8.96864 5.35648C10.0712 5.76114 10.8121 6.82252 10.8121 7.99757C10.8121 9.54835 9.55041 10.81 7.99965 10.81C6.4489 10.81 5.18729 9.54833 5.18729 7.99755C5.18729 6.88567 5.84426 5.87593 6.86098 5.42515C6.99247 5.36687 7.05179 5.21302 6.99348 5.08156C6.9352 4.9501 6.78132 4.89075 6.64989 4.94906C5.44505 5.48325 4.6665 6.67987 4.6665 7.99755C4.6665 9.83546 6.16176 11.3308 7.99971 11.3308C9.83765 11.3308 11.3329 9.83546 11.3329 7.99755C11.3329 6.605 10.4549 5.34713 9.14809 4.86755Z",
7428
+ fill: "currentColor"
7429
+ }),
7430
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
7431
+ d: "M8.01348 4.66409L7.99967 4.66406C7.85585 4.66406 7.73926 4.78065 7.73926 4.92448C7.73926 5.06831 7.85585 5.1849 7.99967 5.1849L8.01194 5.18492C8.0122 5.18492 8.01246 5.18492 8.01272 5.18492C8.15618 5.18492 8.2727 5.06883 8.27314 4.92526C8.27355 4.78143 8.1573 4.6645 8.01348 4.66409Z",
7432
+ fill: "currentColor"
7433
+ }),
7434
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
7435
+ d: "M9.81413 6.96094C9.6703 6.96094 9.55371 7.07753 9.55371 7.22135V8.73919C9.55371 8.883 9.6703 8.99961 9.81413 8.99961C9.95796 8.99961 10.0745 8.883 10.0745 8.73919V7.22133C10.0745 7.0775 9.95796 6.96094 9.81413 6.96094Z",
7436
+ fill: "currentColor"
7437
+ }),
7438
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
7439
+ d: "M8.55132 6.96094H8.01481C7.87098 6.96094 7.75439 7.07753 7.75439 7.22135V7.74057V8.09581V8.73917C7.75439 8.88297 7.87098 8.99958 8.01481 8.99958C8.15864 8.99958 8.27523 8.88297 8.27523 8.73917V8.35622H8.55135C8.91463 8.35622 9.2102 8.06063 9.2102 7.69737V7.61979C9.21018 7.25648 8.91463 6.96094 8.55132 6.96094ZM8.68937 7.69734C8.68937 7.77346 8.62744 7.83539 8.55132 7.83539H8.2752V7.74055V7.48172H8.55132C8.62744 7.48172 8.68937 7.54365 8.68937 7.61977V7.69734Z",
7440
+ fill: "currentColor"
7441
+ }),
7442
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
7443
+ d: "M7.47523 8.67635L6.80685 7.1187C6.76581 7.02297 6.67169 6.96094 6.56755 6.96094C6.46341 6.96094 6.3693 7.02297 6.32823 7.11867L5.65984 8.67633C5.60312 8.80849 5.6643 8.96161 5.79648 9.01831C5.92867 9.075 6.08177 9.01385 6.13849 8.88169L6.56755 7.88172L6.99664 8.88169C7.03898 8.98039 7.13508 9.0395 7.23607 9.0395C7.27031 9.0395 7.30515 9.03268 7.33862 9.01833C7.47078 8.96164 7.53195 8.80852 7.47523 8.67635Z",
7444
+ fill: "currentColor"
7445
+ }),
7446
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
7447
+ d: "M13.7813 1.33203C13.2931 1.33203 12.896 1.72919 12.896 2.21742C12.896 2.3668 12.9333 2.50755 12.9989 2.63107L12.0025 3.62737C11.9008 3.72906 11.9008 3.89396 12.0025 3.99565C12.0534 4.04648 12.1201 4.0719 12.1867 4.0719C12.2533 4.0719 12.32 4.04648 12.3708 3.99562L13.367 2.99951C13.4907 3.06531 13.6317 3.10279 13.7813 3.10279C14.2695 3.10279 14.6667 2.70562 14.6667 2.2174C14.6667 1.72917 14.2696 1.33203 13.7813 1.33203Z",
7448
+ fill: "currentColor"
7449
+ }),
7450
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
7451
+ d: "M3.99712 12.002C3.89542 11.9004 3.73053 11.9004 3.62886 12.002L2.6329 12.998C2.50925 12.9323 2.36837 12.8949 2.21889 12.8949C1.73066 12.8949 1.3335 13.2921 1.3335 13.7803C1.3335 14.2685 1.73066 14.6657 2.21889 14.6657C2.70712 14.6657 3.10428 14.2685 3.10428 13.7803C3.10428 13.6308 3.06688 13.4899 3.00118 13.3663L3.99714 12.3703C4.09881 12.2686 4.09881 12.1037 3.99712 12.002Z",
7452
+ fill: "currentColor"
7453
+ }),
7454
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
7455
+ d: "M12.3711 12.0021C12.3224 11.9536 12.2552 11.9258 12.1867 11.9258C12.1182 11.9258 12.051 11.9536 12.0026 12.0021C11.9541 12.0505 11.9263 12.1177 11.9263 12.1862C11.9263 12.2547 11.9541 12.3219 12.0026 12.3703C12.051 12.4187 12.1182 12.4466 12.1867 12.4466C12.2554 12.4466 12.3224 12.4187 12.3711 12.3703C12.4195 12.3219 12.4471 12.2549 12.4471 12.1862C12.4471 12.1177 12.4195 12.0505 12.3711 12.0021Z",
7456
+ fill: "currentColor"
7457
+ }),
7458
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
7459
+ d: "M13.7813 12.8934C13.6316 12.8934 13.4906 12.9308 13.3669 12.9967L12.927 12.5567C12.8253 12.4551 12.6604 12.455 12.5587 12.5567C12.457 12.6584 12.457 12.8233 12.5587 12.925L12.9988 13.3651C12.9332 13.4887 12.8959 13.6294 12.8959 13.7788C12.8959 14.267 13.2931 14.6642 13.7813 14.6642C14.2695 14.6642 14.6666 14.267 14.6666 13.7788C14.6666 13.2905 14.2695 12.8934 13.7813 12.8934Z",
7460
+ fill: "currentColor"
7461
+ }),
7462
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
7463
+ d: "M3.99712 3.62737L3.00118 2.63143C3.06688 2.50779 3.10428 2.3669 3.10428 2.21742C3.10428 1.72922 2.70712 1.33203 2.21889 1.33203C1.73066 1.33203 1.3335 1.72919 1.3335 2.21742C1.3335 2.70565 1.73066 3.10281 2.21889 3.10281C2.36839 3.10281 2.50928 3.06542 2.6329 2.99971L3.62886 3.99565C3.67972 4.04651 3.74636 4.07193 3.813 4.07193C3.87964 4.07193 3.94631 4.04651 3.99714 3.99565C4.09881 3.89396 4.09881 3.72906 3.99712 3.62737Z",
7464
+ fill: "currentColor"
7465
+ })
7466
+ ]
7467
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("clipPath", {
7468
+ id: "restapi-clip",
7469
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
7470
+ width: "13.3333",
7471
+ height: "13.3333",
7472
+ fill: "white",
7473
+ transform: "translate(1.3335 1.33203)"
7474
+ })
7475
+ }) })]
7476
+ });
7477
+ //#endregion
7478
+ //#region src/view/components/EditModeSidebar/index.tsx
7479
+ const EditModeSidebar = ({ selectedItem, onSelectItem, endpoints, hasGeneralError, hasSaveErrors }) => {
7480
+ const { wrapSSR, cx, token } = useStyle("EditModeSidebar", (token, scope) => ({
7481
+ [scope("root")]: {
7482
+ display: "flex",
7483
+ flexDirection: "column",
7484
+ gap: token.marginXS,
7485
+ padding: token.padding,
7486
+ backgroundColor: token.colorBgContainer,
7487
+ borderRadius: token.borderRadius,
7488
+ width: 320,
7489
+ minWidth: 320,
7490
+ flexShrink: 0,
7491
+ overflowY: "auto"
7492
+ },
7493
+ [scope("spec-icon")]: {
7494
+ fontSize: 16,
7495
+ color: token.colorTextSecondary,
7496
+ flexShrink: 0,
7497
+ display: "flex",
7498
+ alignItems: "center"
7499
+ },
7500
+ [scope("spec-label")]: {
7501
+ fontSize: token.fontSize,
7502
+ fontWeight: 400,
7503
+ color: token.colorText,
7504
+ lineHeight: "22px"
7505
+ },
7506
+ [scope("badge")]: {
7507
+ minWidth: "3.75rem",
7508
+ textAlign: "center",
7509
+ border: "none"
7510
+ },
7511
+ [scope("path")]: {
7512
+ fontSize: token.fontSize,
7513
+ fontWeight: 400,
7514
+ lineHeight: "22px",
7515
+ whiteSpace: "nowrap",
7516
+ overflow: "hidden",
7517
+ textOverflow: "ellipsis",
7518
+ flex: 1
7519
+ },
7520
+ [`${scope("root")} .ant-menu`]: {
7521
+ background: "transparent",
7522
+ border: "none",
7523
+ paddingInline: 0
7524
+ },
7525
+ [`${scope("root")} .ant-menu-item`]: {
7526
+ padding: `${token.paddingXS}px ${token.paddingLG}px`,
7527
+ borderRadius: token.borderRadius,
7528
+ height: "auto",
7529
+ lineHeight: "22px",
7530
+ display: "flex",
7531
+ alignItems: "center",
7532
+ gap: 12,
7533
+ marginInline: 0,
7534
+ marginBlock: 0,
7535
+ width: "100%",
7536
+ transition: "background-color 0.15s"
7537
+ },
7538
+ [`${scope("root")} .ant-menu-item:not(.ant-menu-item-selected):hover`]: { backgroundColor: token.colorFillTertiary },
7539
+ [`${scope("root")} .ant-menu-item-selected`]: { backgroundColor: token.colorPrimaryBg },
7540
+ [`${scope("root")} .ant-menu-item.error-active.ant-menu-item-selected`]: { backgroundColor: token.colorErrorBg },
7541
+ [`${scope("root")} .ant-menu-item-group-title`]: {
7542
+ fontSize: token.fontSize,
7543
+ fontWeight: 400,
7544
+ color: token.colorTextTertiary,
7545
+ lineHeight: "22px",
7546
+ paddingInline: 0,
7547
+ paddingTop: 0,
7548
+ paddingBottom: token.marginXXS,
7549
+ userSelect: "none"
7550
+ },
7551
+ [`${scope("root")} .ant-menu-item-group + .ant-menu-item-group`]: { marginTop: token.marginXS },
7552
+ [`${scope("spec-item")}:not(:last-child)`]: { marginBottom: token.marginXS },
7553
+ [`${scope("root")} .ant-menu-title-content`]: {
7554
+ overflow: "hidden",
7555
+ display: "flex",
7556
+ flex: 1,
7557
+ alignItems: "center",
7558
+ minWidth: 0,
7559
+ gap: 12
7560
+ },
7561
+ [`${scope("root")} .ant-menu-item-selected ${scope("spec-label")}`]: { color: token.colorPrimary }
7562
+ }));
7563
+ const selectedKeys = selectedItem.type === "endpoint" ? [selectedItem.key] : [selectedItem.type];
7564
+ const items = [{
7565
+ type: "group",
7566
+ label: "Specifications",
7567
+ children: [
7568
+ hasSaveErrors && {
7569
+ key: "errors",
7570
+ className: `${cx("spec-item")} error-active`,
7571
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7572
+ className: cx("spec-icon"),
7573
+ style: { color: token.colorError },
7574
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.ExclamationCircleOutlined, {})
7575
+ }),
7576
+ label: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7577
+ className: cx("spec-label"),
7578
+ style: { color: token.colorError },
7579
+ children: "Errors"
7580
+ })
7581
+ },
7582
+ {
7583
+ key: "general",
7584
+ className: cx("spec-item"),
7585
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7586
+ className: cx("spec-icon"),
7587
+ style: hasGeneralError ? { color: token.colorError } : void 0,
7588
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RestApiIcon, {})
7589
+ }),
7590
+ label: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7591
+ className: cx("spec-label"),
7592
+ style: hasGeneralError ? { color: token.colorError } : void 0,
7593
+ children: "General"
7594
+ })
7595
+ },
7596
+ {
7597
+ key: "tags",
7598
+ className: cx("spec-item"),
7599
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7600
+ className: cx("spec-icon"),
7601
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.TagOutlined, {})
7602
+ }),
7603
+ label: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7604
+ className: cx("spec-label"),
7605
+ children: "Tags"
7606
+ })
7607
+ }
7608
+ ].filter(Boolean)
7609
+ }, {
7610
+ type: "group",
7611
+ label: "Endpoints",
7612
+ children: endpoints.map((ep) => {
7613
+ const colors = methodColors$1[ep.method];
7614
+ return {
7615
+ key: ep.id,
7616
+ label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tag, {
7617
+ className: cx("badge"),
7618
+ style: {
7619
+ backgroundColor: colors?.bg,
7620
+ color: colors?.color,
7621
+ border: "none"
7622
+ },
7623
+ children: ep.method
7624
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7625
+ className: cx("path"),
7626
+ style: { color: selectedItem.type === "endpoint" && selectedItem.key === ep.id ? token.colorPrimary : token.colorText },
7627
+ children: ep.path
7628
+ })] })
7629
+ };
7630
+ })
7631
+ }];
7632
+ const handleMenuClick = ({ key }) => {
7633
+ if (key === "errors") onSelectItem({ type: "errors" });
7634
+ else if (key === "general") onSelectItem({ type: "general" });
7635
+ else if (key === "tags") onSelectItem({ type: "tags" });
7636
+ else onSelectItem({
7637
+ type: "endpoint",
7638
+ key
7639
+ });
7640
+ };
7641
+ return wrapSSR(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7642
+ className: cx("root"),
7643
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Menu, {
7644
+ mode: "inline",
7645
+ selectedKeys,
7646
+ items,
7647
+ onClick: handleMenuClick,
7648
+ style: {
7649
+ background: "transparent",
7650
+ border: "none"
7651
+ }
7652
+ })
7653
+ }));
7654
+ };
5912
7655
  token.colorPrimary, token.colorSuccess, token.colorError, token.colorWarning, token["volcano.5"], token["geekblue.6"], token["purple.5"], token["volcano.4"];
5913
7656
  const darkerMethodColors = {
5914
7657
  GET: {
@@ -6350,10 +8093,7 @@ const Sidebar = ({ searchValue, setSearchValue, onNodeSelect }) => {
6350
8093
  });
6351
8094
  if (isMobile) return wrapSSR(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("aside", {
6352
8095
  className: cx("sider"),
6353
- style: {
6354
- width: "100%",
6355
- height: "100%"
6356
- },
8096
+ style: { height: "100%" },
6357
8097
  children: inner
6358
8098
  }));
6359
8099
  return wrapSSR(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(re_resizable.Resizable, {
@@ -6380,7 +8120,48 @@ const Sidebar = ({ searchValue, setSearchValue, onNodeSelect }) => {
6380
8120
  };
6381
8121
  //#endregion
6382
8122
  //#region src/view/console/EndpointPage/EndpointPage.tsx
6383
- const { Title: Title$1, Paragraph } = antd.Typography;
8123
+ const { Title: Title$2, Paragraph } = antd.Typography;
8124
+ const MAX_VISIBLE_ENUMS = 2;
8125
+ const renderEnumTags = (enums, token) => {
8126
+ const tagStyle = {
8127
+ background: token.colorFillAlter,
8128
+ border: `1px solid ${token.colorBorder}`,
8129
+ borderRadius: token.borderRadiusSM
8130
+ };
8131
+ if (enums.length <= MAX_VISIBLE_ENUMS) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8132
+ style: {
8133
+ display: "flex",
8134
+ flexWrap: "wrap",
8135
+ gap: token.marginXXS
8136
+ },
8137
+ children: enums.map((e) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tag, {
8138
+ style: tagStyle,
8139
+ children: e
8140
+ }, e))
8141
+ });
8142
+ const visible = enums.slice(0, MAX_VISIBLE_ENUMS);
8143
+ const hidden = enums.slice(MAX_VISIBLE_ENUMS);
8144
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
8145
+ style: {
8146
+ display: "flex",
8147
+ flexWrap: "wrap",
8148
+ gap: token.marginXXS
8149
+ },
8150
+ children: [visible.map((e) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tag, {
8151
+ style: tagStyle,
8152
+ children: e
8153
+ }, e)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
8154
+ title: hidden.join(", "),
8155
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(antd.Tag, {
8156
+ style: {
8157
+ ...tagStyle,
8158
+ cursor: "pointer"
8159
+ },
8160
+ children: ["+", hidden.length]
8161
+ })
8162
+ })]
8163
+ });
8164
+ };
6384
8165
  const requestColumns = [
6385
8166
  {
6386
8167
  title: "Parameter",
@@ -6423,7 +8204,7 @@ const buildRequestData = (params, token) => [...params].sort((a, b) => a.require
6423
8204
  })
6424
8205
  ] }),
6425
8206
  desc: p.description || "--",
6426
- enum: p.schema?.enum ? p.schema.enum.map((e) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tag, { children: e }, e)) : "--"
8207
+ enum: p.schema?.enum ? renderEnumTags(p.schema.enum, token) : "--"
6427
8208
  };
6428
8209
  });
6429
8210
  const buildHeaderData = (headers, token) => {
@@ -6452,7 +8233,7 @@ const buildHeaderData = (headers, token) => {
6452
8233
  })
6453
8234
  ] }, idx),
6454
8235
  desc: header.description || "--",
6455
- enum: header.schema?.enum ? header.schema.enum.map((e) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tag, { children: e }, e)) : "--"
8236
+ enum: header.schema?.enum ? renderEnumTags(header.schema.enum, token) : "--"
6456
8237
  };
6457
8238
  });
6458
8239
  };
@@ -6484,7 +8265,7 @@ const buildRequestBodyData = (requestBody, token) => {
6484
8265
  })
6485
8266
  ] }),
6486
8267
  desc: prop.description || "--",
6487
- enum: prop.enum ? prop.enum.map((e) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tag, { children: e }, e)) : "--"
8268
+ enum: prop.enum ? renderEnumTags(prop.enum, token) : "--"
6488
8269
  }));
6489
8270
  };
6490
8271
  const EndpointPage = () => {
@@ -6526,8 +8307,7 @@ const EndpointPage = () => {
6526
8307
  ".ant-tabs-tab": { paddingTop: "0" }
6527
8308
  },
6528
8309
  "& .ant-table": { backgroundColor: `${token.colorBgBase} !important` },
6529
- "& .ant-table-thead > tr > th": { backgroundColor: `${token.colorBgBase} !important` },
6530
- "& .ant-table-tbody > tr > td": { backgroundColor: `${token.colorBgBase} !important` }
8310
+ "& .ant-table-thead > tr > th": { backgroundColor: `${token.colorBgBase} !important` }
6531
8311
  },
6532
8312
  [scope("row-odd")]: { "& > td": { background: `${token.colorBgElevated} !important` } },
6533
8313
  [scope("row-even")]: { "& > td": { background: `${token.colorBgLayout} !important` } }
@@ -6654,7 +8434,7 @@ const EndpointPage = () => {
6654
8434
  }) }
6655
8435
  ] })]
6656
8436
  }),
6657
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Title$1, {
8437
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Title$2, {
6658
8438
  level: 3,
6659
8439
  style: {
6660
8440
  display: "flex",
@@ -6739,10 +8519,7 @@ const MainContent = ({ searchEnabled, handleResetSearch, handleVisitLandingPage
6739
8519
  const { focusedContent, transformedData } = useStore(({ view }) => view);
6740
8520
  const { wrapSSR, cx, token } = useStyle("MainContent", (token, scope) => ({
6741
8521
  [scope("inner-doc-container")]: {
6742
- flex: 1,
6743
8522
  minWidth: 0,
6744
- height: "100%",
6745
- overflow: "auto",
6746
8523
  borderRadius: token.borderRadius,
6747
8524
  padding: token.paddingXL
6748
8525
  },
@@ -6848,13 +8625,7 @@ const Codebox$1 = ({ code, language, wrapLongLines }) => {
6848
8625
  const [appTheme] = (0, react$1.useState)("DARK");
6849
8626
  const { token, theme: themeConfig } = antd.theme.useToken();
6850
8627
  const bodyBg = themeConfig.id == 1 ? token.colorBgContainer : "#1d2856";
6851
- const { cx } = useStyle("codeBox", (token, scope) => ({ [scope("codebox")]: {
6852
- borderRadius: token.borderRadius,
6853
- height: "100%",
6854
- maxHeight: "100%",
6855
- overflow: "auto",
6856
- pre: { height: "100%" }
6857
- } }));
8628
+ const { cx } = useStyle("codeBox", (token, scope) => ({ [scope("codebox")]: { borderRadius: token.borderRadius } }));
6858
8629
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6859
8630
  className: cx("codebox"),
6860
8631
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_syntax_highlighter.Light, {
@@ -6866,7 +8637,6 @@ const Codebox$1 = ({ code, language, wrapLongLines }) => {
6866
8637
  customStyle: {
6867
8638
  margin: 0,
6868
8639
  minHeight: "3rem",
6869
- overflowY: "auto",
6870
8640
  padding: "0.75rem 1rem 0.75rem 1.5rem",
6871
8641
  backgroundColor: bodyBg,
6872
8642
  fontSize: "0.75rem"
@@ -6879,7 +8649,7 @@ const Codebox$1 = ({ code, language, wrapLongLines }) => {
6879
8649
  //#endregion
6880
8650
  //#region src/view/console/CodeboxSidebar.tsx
6881
8651
  function CodeboxSidebar$1() {
6882
- const { selectedEndpoint, selectedApi, activeRequestTab, selectedStatusCode, statusCodeOptions, setSelectedStatusCode } = useStore(({ view }) => view);
8652
+ const { selectedEndpoint, selectedApi, selectedStatusCode, statusCodeOptions, setSelectedStatusCode } = useStore(({ view }) => view);
6883
8653
  const httpStatusOptions = (0, react$1.useMemo)(() => statusCodeOptions.map((code) => ({
6884
8654
  value: code,
6885
8655
  label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
@@ -6912,7 +8682,7 @@ function CodeboxSidebar$1() {
6912
8682
  const queryParams = params.filter((p) => p.in === "query");
6913
8683
  return [`curl --location '${serverUrl}${resolvedPath}${queryParams.length > 0 ? "?" + queryParams.map((p) => `${p.name}=sample-value`).join("&") : ""}'`, ...params.filter((p) => p.in === "header").map((p) => `--header '${p.name}: sample-value'`)];
6914
8684
  })();
6915
- const hasActiveTabParams = (selectedEndpoint?.parameters ?? []).some((p) => p.in === activeRequestTab);
8685
+ const hasAnyParams = (selectedEndpoint?.parameters ?? []).some((p) => p.in === "header" || p.in === "path" || p.in === "query");
6916
8686
  const { token: antdToken, theme: themeConfig } = antd.theme.useToken();
6917
8687
  const isDark = themeConfig.id == 1;
6918
8688
  const headerBg = isDark ? antdToken.colorBgElevated : "#1d2856";
@@ -7034,7 +8804,7 @@ function CodeboxSidebar$1() {
7034
8804
  }));
7035
8805
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7036
8806
  className: cx("container"),
7037
- children: [hasActiveTabParams && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8807
+ children: [hasAnyParams && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7038
8808
  className: cx("rightCard", "rightCardRequest"),
7039
8809
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7040
8810
  className: cx("rightCardHeader"),
@@ -7134,6 +8904,18 @@ const transformOpenApiToDocs = (api) => {
7134
8904
  content: resolvedContent
7135
8905
  };
7136
8906
  }
8907
+ if (entry.responses) {
8908
+ const resolvedResponses = {};
8909
+ for (const [code, responseValue] of Object.entries(entry.responses)) if (responseValue.content) {
8910
+ const resolvedContent = {};
8911
+ for (const [contentType, contentValue] of Object.entries(responseValue.content)) resolvedContent[contentType] = { schema: resolveSchema(contentValue.schema, api.components) ?? contentValue.schema };
8912
+ resolvedResponses[code] = {
8913
+ ...responseValue,
8914
+ content: resolvedContent
8915
+ };
8916
+ } else resolvedResponses[code] = responseValue;
8917
+ entry.responses = resolvedResponses;
8918
+ }
7137
8919
  const matchedTags = (methodData.tags ?? []).filter((tag) => validTags.has(tag));
7138
8920
  if (matchedTags.length > 0) matchedTags.forEach((tag) => {
7139
8921
  if (!groupedPathsByTags[tag]) groupedPathsByTags[tag] = [];
@@ -7176,20 +8958,31 @@ const transformOpenApiToDocs = (api) => {
7176
8958
  const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPage, onSave }) => {
7177
8959
  const [searchValue, setSearchValue] = (0, react$1.useState)("");
7178
8960
  const [mode, setMode] = (0, react$1.useState)("edit");
7179
- const [hasChanges, setHasChanges] = (0, react$1.useState)(false);
7180
8961
  const [bannerVisible, setBannerVisible] = (0, react$1.useState)(false);
7181
8962
  const [resetKey, setResetKey] = (0, react$1.useState)(0);
7182
- const [generalCollapsed, setGeneralCollapsed] = (0, react$1.useState)(false);
7183
- const [tagsCollapsed, setTagsCollapsed] = (0, react$1.useState)(false);
8963
+ const [generalCollapsed, setGeneralCollapsed] = (0, react$1.useState)(true);
8964
+ const [tagsCollapsed, setTagsCollapsed] = (0, react$1.useState)(true);
7184
8965
  const [endpointsCollapsed, setEndpointsCollapsed] = (0, react$1.useState)(false);
8966
+ const [saveConfirmModal, setSaveConfirmModal] = (0, react$1.useState)(false);
8967
+ const [resetConfirmModal, setResetConfirmModal] = (0, react$1.useState)(false);
8968
+ const [selectedEditItem, setSelectedEditItem] = (0, react$1.useState)({ type: "general" });
8969
+ const [errorBoxExpanded, setErrorBoxExpanded] = (0, react$1.useState)(false);
7185
8970
  const [localApiName, setLocalApiName] = (0, react$1.useState)("");
8971
+ const [apiNameTouched, setApiNameTouched] = (0, react$1.useState)(false);
7186
8972
  const [localDescription, setLocalDescription] = (0, react$1.useState)("");
8973
+ const [descriptionTouched, setDescriptionTouched] = (0, react$1.useState)(false);
8974
+ const hasApiNameError = apiNameTouched && (!localApiName.trim() || !/^[A-Za-z0-9_\s-]+$/.test(localApiName.trim()));
8975
+ const hasDescriptionError = descriptionTouched && !localDescription.trim();
8976
+ const hasGeneralError = hasApiNameError || hasDescriptionError;
8977
+ const [saveErrors, setSaveErrors] = (0, react$1.useState)([]);
7187
8978
  const [selectedUrl, setSelectedUrl] = (0, react$1.useState)("");
7188
8979
  const [endpointNames, setEndpointNames] = (0, react$1.useState)({});
7189
8980
  const [endpointDescs, setEndpointDescs] = (0, react$1.useState)({});
7190
8981
  const [endpointTags, setEndpointTags] = (0, react$1.useState)({});
7191
8982
  const [endpointParams, setEndpointParams] = (0, react$1.useState)({});
7192
8983
  const [endpointResponseParams, setEndpointResponseParams] = (0, react$1.useState)({});
8984
+ const [endpointRequestBody, setEndpointRequestBody] = (0, react$1.useState)({});
8985
+ const [endpointResponseBody, setEndpointResponseBody] = (0, react$1.useState)({});
7193
8986
  const [tagDrawerState, setTagDrawerState] = (0, react$1.useState)({
7194
8987
  open: false,
7195
8988
  mode: "add"
@@ -7200,11 +8993,12 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7200
8993
  });
7201
8994
  const [localTags, setLocalTags] = (0, react$1.useState)([]);
7202
8995
  const [messageApi, contextHolder] = antd.message.useMessage();
7203
- const { focusedContent, selectedNodeKey, selectedApi, originalData, builtTreeData, selectedEndpoint, setOriginalData, setTransformedData, setBuiltTreeData, setFocusedContent, setExpandedKeys, setSelectedEndpoint } = useStore(({ view }) => view);
8996
+ const { focusedContent, selectedNodeKey, selectedApi, originalData, transformedData, builtTreeData, selectedEndpoint, setOriginalData, setTransformedData, setBuiltTreeData, setSelectedApi, setFocusedContent, setExpandedKeys, setSelectedEndpoint } = useStore(({ view }) => view);
7204
8997
  const { selectFirstApi, selectPreSelectedApi, clearSelection } = useNodeSelection();
7205
8998
  const hasInitializedRef = (0, react$1.useRef)(false);
7206
8999
  const { useBreakpoint } = antd.Grid;
7207
9000
  const isMobile = !useBreakpoint().md;
9001
+ const allEndpoints = (0, react$1.useMemo)(() => selectedApi ? Object.values(selectedApi.tags ?? {}).flat() : [], [selectedApi]);
7208
9002
  (0, react$1.useEffect)(() => {
7209
9003
  return () => {
7210
9004
  resetStore();
@@ -7264,6 +9058,14 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7264
9058
  gap: token.marginLG,
7265
9059
  width: "100%"
7266
9060
  },
9061
+ [scope("content-scroll-area")]: {
9062
+ display: "grid",
9063
+ gridTemplateColumns: "minmax(0, 1fr) auto",
9064
+ flex: 1,
9065
+ gap: token.marginLG,
9066
+ overflow: "auto",
9067
+ minWidth: 0
9068
+ },
7267
9069
  [".delete-tag-confirm-modal .ant-modal-container"]: {
7268
9070
  "--ant-modal-content-padding": "0px !important",
7269
9071
  padding: "0 !important"
@@ -7342,15 +9144,18 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7342
9144
  }, [selectedApi]);
7343
9145
  const tagMetadata = (0, react$1.useMemo)(() => {
7344
9146
  if (!originalData || !selectedApi) return [];
7345
- const rawFile = originalData.find((f) => Object.keys(f.paths)[0] === selectedApi.contextPath);
7346
- if (!rawFile?.tags) return [];
7347
- return rawFile.tags.map((t) => ({
9147
+ const mapped = originalData.find((f) => Object.keys(f.paths)[0] === selectedApi.contextPath)?.tags?.map((t) => ({
7348
9148
  name: t.name,
7349
9149
  description: t.description,
7350
9150
  externalDocsUrl: t.externalDocs?.url,
7351
9151
  externalDocsDescription: t.externalDocs?.description,
7352
9152
  isDefault: t.name.toLowerCase() === "default"
7353
- }));
9153
+ })) ?? [];
9154
+ if (!mapped.some((t) => t.isDefault) && selectedApi.tags["default"]) mapped.push({
9155
+ name: "default",
9156
+ isDefault: true
9157
+ });
9158
+ return mapped;
7354
9159
  }, [originalData, selectedApi]);
7355
9160
  const initialEndpointResponseParams = (0, react$1.useMemo)(() => {
7356
9161
  if (!originalData || !selectedApi) return {};
@@ -7412,11 +9217,89 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7412
9217
  });
7413
9218
  return result;
7414
9219
  }, [originalData, selectedApi]);
9220
+ const initialEndpointRequestBody = (0, react$1.useMemo)(() => {
9221
+ if (!originalData || !selectedApi) return {};
9222
+ const rawFile = originalData.find((f) => Object.keys(f.paths)[0] === selectedApi.contextPath);
9223
+ if (!rawFile) return {};
9224
+ const pathMethodToId = {};
9225
+ Object.values(selectedApi.tags).flat().forEach((ep) => {
9226
+ pathMethodToId[`${ep.path}||${ep.method.toLowerCase()}`] = ep.id;
9227
+ });
9228
+ const result = {};
9229
+ Object.entries(rawFile.paths).forEach(([path, methods]) => {
9230
+ Object.entries(methods).forEach(([method, operation]) => {
9231
+ const schema = operation.requestBody?.content?.["application/json"]?.schema;
9232
+ const epId = pathMethodToId[`${path}||${method}`];
9233
+ if (epId && schema) result[epId] = schema;
9234
+ });
9235
+ });
9236
+ return result;
9237
+ }, [originalData, selectedApi]);
9238
+ const initialEndpointResponseBody = (0, react$1.useMemo)(() => {
9239
+ if (!originalData || !selectedApi) return {};
9240
+ const rawFile = originalData.find((f) => Object.keys(f.paths)[0] === selectedApi.contextPath);
9241
+ if (!rawFile) return {};
9242
+ const pathMethodToId = {};
9243
+ Object.values(selectedApi.tags).flat().forEach((ep) => {
9244
+ pathMethodToId[`${ep.path}||${ep.method.toLowerCase()}`] = ep.id;
9245
+ });
9246
+ const result = {};
9247
+ Object.entries(rawFile.paths).forEach(([path, methods]) => {
9248
+ Object.entries(methods).forEach(([method, operation]) => {
9249
+ const responses = operation.responses;
9250
+ if (!responses) return;
9251
+ const schema = responses["200" in responses ? "200" : Object.keys(responses)[0]]?.content?.["application/json"]?.schema;
9252
+ const epId = pathMethodToId[`${path}||${method}`];
9253
+ if (epId && schema) result[epId] = schema;
9254
+ });
9255
+ });
9256
+ return result;
9257
+ }, [originalData, selectedApi]);
9258
+ (0, react$1.useEffect)(() => {
9259
+ setLocalTags(tagMetadata);
9260
+ setEndpointParams(initialEndpointParams);
9261
+ setEndpointResponseParams(initialEndpointResponseParams);
9262
+ setEndpointRequestBody(initialEndpointRequestBody);
9263
+ setEndpointResponseBody(initialEndpointResponseBody);
9264
+ }, [selectedApi]);
9265
+ const hasChanges = (0, react$1.useMemo)(() => {
9266
+ if (!selectedApi) return false;
9267
+ if (localApiName !== (selectedApi.title || "")) return true;
9268
+ if (localDescription !== (selectedApi.description || "")) return true;
9269
+ if (JSON.stringify(localTags) !== JSON.stringify(tagMetadata)) return true;
9270
+ for (const [id, name] of Object.entries(endpointNames)) {
9271
+ const ep = allEndpoints.find((e) => e.id === id);
9272
+ if (ep && name !== (ep.summary ?? "")) return true;
9273
+ }
9274
+ for (const [id, desc] of Object.entries(endpointDescs)) {
9275
+ const ep = allEndpoints.find((e) => e.id === id);
9276
+ if (ep && desc !== (ep.description ?? "")) return true;
9277
+ }
9278
+ for (const [id, tags] of Object.entries(endpointTags)) {
9279
+ const ep = allEndpoints.find((e) => e.id === id);
9280
+ if (ep && JSON.stringify(tags) !== JSON.stringify(ep.tags ?? [])) return true;
9281
+ }
9282
+ if (JSON.stringify(endpointParams) !== JSON.stringify(initialEndpointParams)) return true;
9283
+ if (JSON.stringify(endpointResponseParams) !== JSON.stringify(initialEndpointResponseParams)) return true;
9284
+ return false;
9285
+ }, [
9286
+ selectedApi,
9287
+ localApiName,
9288
+ localDescription,
9289
+ localTags,
9290
+ tagMetadata,
9291
+ allEndpoints,
9292
+ endpointNames,
9293
+ endpointDescs,
9294
+ endpointTags,
9295
+ endpointParams,
9296
+ endpointResponseParams,
9297
+ initialEndpointParams,
9298
+ initialEndpointResponseParams
9299
+ ]);
7415
9300
  (0, react$1.useEffect)(() => {
7416
- setLocalTags(tagMetadata);
7417
- setEndpointParams(initialEndpointParams);
7418
- setEndpointResponseParams(initialEndpointResponseParams);
7419
- }, [selectedApi]);
9301
+ setBannerVisible(hasChanges);
9302
+ }, [hasChanges]);
7420
9303
  (0, react$1.useEffect)(() => {
7421
9304
  if (mode !== "view" || !selectedEndpoint) return;
7422
9305
  const epId = selectedEndpoint.id;
@@ -7467,7 +9350,6 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7467
9350
  isDefault: false
7468
9351
  };
7469
9352
  setLocalTags((prev) => [...prev, newTag]);
7470
- setHasChanges(true);
7471
9353
  setBannerVisible(true);
7472
9354
  };
7473
9355
  const handleUpdateTag = (updatedTag) => {
@@ -7479,7 +9361,6 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7479
9361
  externalDocsUrl: updatedTag.externalDocsLink,
7480
9362
  externalDocsDescription: updatedTag.externalDocsDescription
7481
9363
  } : t));
7482
- setHasChanges(true);
7483
9364
  setBannerVisible(true);
7484
9365
  };
7485
9366
  const handleDeleteTagConfirm = () => {
@@ -7489,7 +9370,6 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7489
9370
  open: false,
7490
9371
  tagName: ""
7491
9372
  });
7492
- setHasChanges(true);
7493
9373
  setBannerVisible(true);
7494
9374
  };
7495
9375
  const getEndpointsByTag = () => {
@@ -7509,8 +9389,10 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7509
9389
  return filtered;
7510
9390
  };
7511
9391
  const handleReset = () => {
7512
- setHasChanges(false);
7513
9392
  setBannerVisible(false);
9393
+ setApiNameTouched(false);
9394
+ setDescriptionTouched(false);
9395
+ setSaveErrors([]);
7514
9396
  setLocalApiName(selectedApi?.title ?? "");
7515
9397
  setLocalDescription(selectedApi?.description ?? "");
7516
9398
  setEndpointNames({});
@@ -7519,6 +9401,7 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7519
9401
  setEndpointParams(initialEndpointParams);
7520
9402
  setEndpointResponseParams(initialEndpointResponseParams);
7521
9403
  setResetKey((prev) => prev + 1);
9404
+ messageApi.success("Changes have been reset successfully.");
7522
9405
  };
7523
9406
  const handleSave = async () => {
7524
9407
  if (!selectedApi || !originalData) return;
@@ -7592,9 +9475,55 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7592
9475
  else delete methodObj["x-response-params"];
7593
9476
  }
7594
9477
  });
7595
- await onSave?.(cloned);
7596
- setHasChanges(false);
7597
- setBannerVisible(false);
9478
+ Object.entries(endpointRequestBody).forEach(([id, schema]) => {
9479
+ const loc = idToPathMethod[id];
9480
+ if (!loc) return;
9481
+ const pathEntry = cloned.paths[loc.path];
9482
+ if (!pathEntry) return;
9483
+ const methodObj = pathEntry[loc.method];
9484
+ if (!methodObj) return;
9485
+ const methodObjAny = methodObj;
9486
+ if (!methodObjAny.requestBody) methodObjAny.requestBody = {};
9487
+ const rb = methodObjAny.requestBody;
9488
+ if (!rb.content) rb.content = {};
9489
+ rb.content["application/json"] = { schema };
9490
+ });
9491
+ Object.entries(endpointResponseBody).forEach(([id, schema]) => {
9492
+ const loc = idToPathMethod[id];
9493
+ if (!loc) return;
9494
+ const pathEntry = cloned.paths[loc.path];
9495
+ if (!pathEntry) return;
9496
+ const methodObj = pathEntry[loc.method];
9497
+ if (!methodObj) return;
9498
+ const methodObjAny = methodObj;
9499
+ if (!methodObjAny.responses) return;
9500
+ const responses = methodObjAny.responses;
9501
+ const statusCode = "200" in responses ? "200" : Object.keys(responses)[0];
9502
+ if (!responses[statusCode]) return;
9503
+ if (!responses[statusCode].content) responses[statusCode].content = {};
9504
+ responses[statusCode].content["application/json"] = { schema };
9505
+ });
9506
+ try {
9507
+ await onSave?.(cloned);
9508
+ setBannerVisible(false);
9509
+ setSaveErrors([]);
9510
+ messageApi.success("Changes have been saved and published successfully.");
9511
+ setOriginalData(originalData.map((f) => Object.keys(f.paths)[0] === selectedApi.contextPath ? cloned : f));
9512
+ const newTransformed = [cloned].map(transformOpenApiToDocs)[0];
9513
+ const newTransformedData = (transformedData ?? []).map((t) => t.contextPath === selectedApi.contextPath ? newTransformed : t);
9514
+ setTransformedData(newTransformedData);
9515
+ setBuiltTreeData(buildTreeDataStructure(newTransformedData) ?? []);
9516
+ setSelectedApi(newTransformed);
9517
+ } catch (err) {
9518
+ let messages = [];
9519
+ if (err && typeof err === "object" && "errors" in err) {
9520
+ const e = err;
9521
+ messages = Array.isArray(e.errors) ? e.errors : [e.errors];
9522
+ } else if (err instanceof Error) messages = err.message.split("\n").filter(Boolean);
9523
+ else messages = [String(err)];
9524
+ setSaveErrors(messages);
9525
+ setSelectedEditItem({ type: "errors" });
9526
+ }
7598
9527
  };
7599
9528
  const handleResetSearch = () => {
7600
9529
  setSearchValue("");
@@ -7606,6 +9535,102 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7606
9535
  }
7607
9536
  window.location.pathname = "/";
7608
9537
  };
9538
+ (0, react$1.useEffect)(() => {
9539
+ setErrorBoxExpanded(false);
9540
+ }, [selectedEditItem]);
9541
+ const errorBox = saveErrors.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9542
+ style: {
9543
+ background: token.colorErrorBg,
9544
+ borderRadius: token.borderRadiusLG,
9545
+ padding: `${token.marginLG}px ${token.marginLG}px 48px`,
9546
+ width: "100%"
9547
+ },
9548
+ children: [
9549
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9550
+ style: {
9551
+ display: "flex",
9552
+ alignItems: "center",
9553
+ gap: token.marginXS
9554
+ },
9555
+ children: [selectedEditItem.type !== "errors" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9556
+ onClick: () => setErrorBoxExpanded((prev) => !prev),
9557
+ style: {
9558
+ display: "flex",
9559
+ alignItems: "center",
9560
+ background: "transparent",
9561
+ border: "none",
9562
+ cursor: "pointer",
9563
+ padding: 0,
9564
+ lineHeight: 1
9565
+ },
9566
+ "aria-label": "Collapse",
9567
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.RightOutlined, { style: {
9568
+ fontSize: 14,
9569
+ color: token.colorError,
9570
+ transform: errorBoxExpanded ? "rotate(90deg)" : "none",
9571
+ transition: "transform 0.2s"
9572
+ } })
9573
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd_es_typography_Title_js.default, {
9574
+ level: 3,
9575
+ style: {
9576
+ margin: 0,
9577
+ color: token.colorError
9578
+ },
9579
+ children: "Errors"
9580
+ })]
9581
+ }),
9582
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9583
+ style: {
9584
+ color: token.colorError,
9585
+ fontSize: 16,
9586
+ lineHeight: "24px",
9587
+ marginTop: token.marginXS,
9588
+ marginBottom: token.marginSM
9589
+ },
9590
+ children: "Failed to update the OpenAPI documentation. Please resolve the following issues:"
9591
+ }),
9592
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Divider, { style: { margin: `${token.marginSM}px 0` } }),
9593
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ol", {
9594
+ style: {
9595
+ paddingLeft: token.marginLG,
9596
+ margin: 0
9597
+ },
9598
+ children: saveErrors.map((msg, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
9599
+ style: {
9600
+ color: token.colorText,
9601
+ marginBottom: token.marginXS
9602
+ },
9603
+ children: msg
9604
+ }, i))
9605
+ })
9606
+ ]
9607
+ }) : null;
9608
+ const errorBoxCollapsed = saveErrors.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
9609
+ onClick: () => setErrorBoxExpanded(true),
9610
+ style: {
9611
+ display: "flex",
9612
+ alignItems: "center",
9613
+ gap: token.marginXS,
9614
+ padding: `${token.paddingXS}px ${token.paddingLG}px`,
9615
+ background: token.colorErrorBg,
9616
+ borderRadius: token.borderRadiusLG,
9617
+ border: "none",
9618
+ cursor: "pointer",
9619
+ width: "100%",
9620
+ textAlign: "left"
9621
+ },
9622
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.RightOutlined, { style: {
9623
+ fontSize: 14,
9624
+ color: token.colorError
9625
+ } }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9626
+ style: {
9627
+ color: token.colorError,
9628
+ fontSize: token.fontSizeLG,
9629
+ fontWeight: 600
9630
+ },
9631
+ children: "Errors"
9632
+ })]
9633
+ }) : null;
7609
9634
  const switcherNode = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7610
9635
  style: {
7611
9636
  display: "flex",
@@ -7664,158 +9689,365 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7664
9689
  apiName: selectedApi?.title || "API",
7665
9690
  mode,
7666
9691
  onModeChange: setMode,
7667
- onReset: handleReset,
7668
- onSave: handleSave,
9692
+ onReset: () => setResetConfirmModal(true),
9693
+ onSave: () => setSaveConfirmModal(true),
7669
9694
  hasChanges,
9695
+ hasErrors: hasGeneralError,
7670
9696
  switcherNode: isMobile ? switcherNode : void 0
7671
9697
  })
7672
9698
  }),
7673
9699
  bannerVisible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnsavedChangesBanner, { onClose: () => setBannerVisible(false) }),
7674
- mode === "edit" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
7675
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7676
- className: cx("section"),
7677
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GeneralSection, {
7678
- apiName: localApiName,
7679
- authType: selectedApi?.authType || "",
7680
- version: selectedApi?.relatedVersions?.find((v) => v.apiId === selectedApi?.currentVersion)?.version || "",
7681
- description: localDescription,
7682
- onApiNameChange: setLocalApiName,
7683
- onDescriptionChange: setLocalDescription,
7684
- collapsed: generalCollapsed,
7685
- onToggleCollapse: () => setGeneralCollapsed((c) => !c),
7686
- onChangeDetected: () => {
7687
- setHasChanges(true);
7688
- setBannerVisible(true);
7689
- }
7690
- })
7691
- }),
7692
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7693
- className: cx("section"),
7694
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TagsSection, {
7695
- tags: localTags,
7696
- collapsed: tagsCollapsed,
7697
- onToggleCollapse: () => setTagsCollapsed((prev) => !prev),
7698
- onAddTag: () => setTagDrawerState({
7699
- open: true,
7700
- mode: "add"
9700
+ mode === "edit" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9701
+ style: {
9702
+ display: "flex",
9703
+ gap: token.marginLG,
9704
+ flex: 1,
9705
+ minHeight: 0
9706
+ },
9707
+ children: [!isMobile && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditModeSidebar, {
9708
+ selectedItem: selectedEditItem,
9709
+ onSelectItem: setSelectedEditItem,
9710
+ endpoints: allEndpoints,
9711
+ hasGeneralError,
9712
+ hasSaveErrors: saveErrors.length > 0
9713
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9714
+ style: {
9715
+ display: "flex",
9716
+ flexDirection: "column",
9717
+ gap: token.marginLG,
9718
+ flex: 1,
9719
+ overflow: "auto"
9720
+ },
9721
+ children: isMobile ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
9722
+ errorBox && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9723
+ className: cx("section"),
9724
+ children: errorBox
7701
9725
  }),
7702
- onEditTag: (tag) => setTagDrawerState({
7703
- open: true,
7704
- mode: "edit",
7705
- initialValues: {
7706
- name: tag.name,
7707
- description: tag.description,
7708
- externalDocsDescription: tag.externalDocsDescription,
7709
- externalDocsLink: tag.externalDocsUrl
7710
- }
9726
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9727
+ className: cx("section"),
9728
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GeneralSection, {
9729
+ apiName: localApiName,
9730
+ authType: selectedApi?.authType || "",
9731
+ version: selectedApi?.relatedVersions?.find((v) => v.apiId === selectedApi?.currentVersion)?.version || "",
9732
+ description: localDescription,
9733
+ onApiNameChange: (val) => {
9734
+ setApiNameTouched(true);
9735
+ setLocalApiName(val);
9736
+ },
9737
+ apiNameError: hasApiNameError,
9738
+ onDescriptionChange: (val) => {
9739
+ setDescriptionTouched(true);
9740
+ setLocalDescription(val);
9741
+ },
9742
+ descriptionError: hasDescriptionError,
9743
+ collapsed: generalCollapsed,
9744
+ onToggleCollapse: () => setGeneralCollapsed((c) => !c),
9745
+ onChangeDetected: () => {
9746
+ setBannerVisible(true);
9747
+ }
9748
+ })
9749
+ }),
9750
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9751
+ className: cx("section"),
9752
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TagsSection, {
9753
+ tags: localTags,
9754
+ collapsed: tagsCollapsed,
9755
+ onToggleCollapse: () => setTagsCollapsed((prev) => !prev),
9756
+ onAddTag: () => setTagDrawerState({
9757
+ open: true,
9758
+ mode: "add"
9759
+ }),
9760
+ onEditTag: (tag) => setTagDrawerState({
9761
+ open: true,
9762
+ mode: "edit",
9763
+ initialValues: {
9764
+ name: tag.name,
9765
+ description: tag.description,
9766
+ externalDocsDescription: tag.externalDocsDescription,
9767
+ externalDocsLink: tag.externalDocsUrl
9768
+ }
9769
+ }),
9770
+ onDeleteTag: (tagName) => setDeleteTagModal({
9771
+ open: true,
9772
+ tagName
9773
+ })
9774
+ })
7711
9775
  }),
7712
- onDeleteTag: (tagName) => setDeleteTagModal({
7713
- open: true,
7714
- tagName
9776
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9777
+ className: cx("section"),
9778
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EndpointsSection, {
9779
+ mode,
9780
+ endpointsByTag: getEndpointsByTag(),
9781
+ collapsed: endpointsCollapsed,
9782
+ onToggleCollapse: () => setEndpointsCollapsed((c) => !c),
9783
+ endpointNames,
9784
+ endpointDescs,
9785
+ endpointTags,
9786
+ availableTags: localTags.map((t) => t.name),
9787
+ onEndpointNameChange: (id, val) => {
9788
+ setEndpointNames((prev) => ({
9789
+ ...prev,
9790
+ [id]: val
9791
+ }));
9792
+ setBannerVisible(true);
9793
+ },
9794
+ onEndpointDescChange: (id, val) => {
9795
+ setEndpointDescs((prev) => ({
9796
+ ...prev,
9797
+ [id]: val
9798
+ }));
9799
+ setBannerVisible(true);
9800
+ },
9801
+ onEndpointTagsChange: (id, val) => {
9802
+ setEndpointTags((prev) => ({
9803
+ ...prev,
9804
+ [id]: val
9805
+ }));
9806
+ setBannerVisible(true);
9807
+ },
9808
+ endpointParams,
9809
+ onAddParameter: (endpointId, param) => {
9810
+ setEndpointParams((prev) => ({
9811
+ ...prev,
9812
+ [endpointId]: [...prev[endpointId] ?? [], param]
9813
+ }));
9814
+ setBannerVisible(true);
9815
+ },
9816
+ onEditParameter: (endpointId, idx, param) => {
9817
+ setEndpointParams((prev) => ({
9818
+ ...prev,
9819
+ [endpointId]: prev[endpointId]?.map((p, i) => i === idx ? param : p) ?? []
9820
+ }));
9821
+ setBannerVisible(true);
9822
+ },
9823
+ onDeleteParameter: (endpointId, idx) => {
9824
+ setEndpointParams((prev) => ({
9825
+ ...prev,
9826
+ [endpointId]: prev[endpointId]?.filter((_, i) => i !== idx) ?? []
9827
+ }));
9828
+ setBannerVisible(true);
9829
+ },
9830
+ endpointResponseParams,
9831
+ onAddResponseParameter: (endpointId, param) => {
9832
+ setEndpointResponseParams((prev) => ({
9833
+ ...prev,
9834
+ [endpointId]: [...prev[endpointId] ?? [], param]
9835
+ }));
9836
+ setBannerVisible(true);
9837
+ },
9838
+ onEditResponseParameter: (endpointId, idx, param) => {
9839
+ setEndpointResponseParams((prev) => ({
9840
+ ...prev,
9841
+ [endpointId]: prev[endpointId]?.map((p, i) => i === idx ? param : p) ?? []
9842
+ }));
9843
+ setBannerVisible(true);
9844
+ },
9845
+ onDeleteResponseParameter: (endpointId, idx) => {
9846
+ setEndpointResponseParams((prev) => ({
9847
+ ...prev,
9848
+ [endpointId]: prev[endpointId]?.filter((_, i) => i !== idx) ?? []
9849
+ }));
9850
+ setBannerVisible(true);
9851
+ },
9852
+ onRequestContentChange: (endpointId, jsonString) => {
9853
+ try {
9854
+ const schema = JSON.parse(jsonString);
9855
+ setEndpointRequestBody((prev) => ({
9856
+ ...prev,
9857
+ [endpointId]: schema
9858
+ }));
9859
+ setBannerVisible(true);
9860
+ } catch {}
9861
+ },
9862
+ onResponseContentChange: (endpointId, jsonString) => {
9863
+ try {
9864
+ const schema = JSON.parse(jsonString);
9865
+ setEndpointResponseBody((prev) => ({
9866
+ ...prev,
9867
+ [endpointId]: schema
9868
+ }));
9869
+ setBannerVisible(true);
9870
+ } catch {}
9871
+ },
9872
+ requestBodySchemas: endpointRequestBody,
9873
+ responseBodySchemas: endpointResponseBody
9874
+ }, resetKey)
7715
9875
  })
7716
- })
7717
- }),
7718
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7719
- className: cx("section"),
7720
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EndpointsSection, {
7721
- mode,
7722
- endpointsByTag: getEndpointsByTag(),
7723
- collapsed: endpointsCollapsed,
7724
- onToggleCollapse: () => setEndpointsCollapsed((c) => !c),
7725
- endpointNames,
7726
- endpointDescs,
7727
- endpointTags,
7728
- availableTags: localTags.map((t) => t.name),
7729
- onEndpointNameChange: (id, val) => {
7730
- setEndpointNames((prev) => ({
7731
- ...prev,
7732
- [id]: val
7733
- }));
7734
- setHasChanges(true);
7735
- setBannerVisible(true);
7736
- },
7737
- onEndpointDescChange: (id, val) => {
7738
- setEndpointDescs((prev) => ({
7739
- ...prev,
7740
- [id]: val
7741
- }));
7742
- setHasChanges(true);
7743
- setBannerVisible(true);
7744
- },
7745
- onEndpointTagsChange: (id, val) => {
7746
- setEndpointTags((prev) => ({
7747
- ...prev,
7748
- [id]: val
7749
- }));
7750
- setHasChanges(true);
7751
- setBannerVisible(true);
7752
- },
7753
- endpointParams,
7754
- onAddParameter: (endpointId, param) => {
7755
- setEndpointParams((prev) => ({
7756
- ...prev,
7757
- [endpointId]: [...prev[endpointId] ?? [], param]
7758
- }));
7759
- setHasChanges(true);
7760
- setBannerVisible(true);
7761
- },
7762
- onEditParameter: (endpointId, idx, param) => {
7763
- setEndpointParams((prev) => ({
7764
- ...prev,
7765
- [endpointId]: prev[endpointId]?.map((p, i) => i === idx ? param : p) ?? []
7766
- }));
7767
- setHasChanges(true);
7768
- setBannerVisible(true);
7769
- },
7770
- onDeleteParameter: (endpointId, idx) => {
7771
- setEndpointParams((prev) => ({
7772
- ...prev,
7773
- [endpointId]: prev[endpointId]?.filter((_, i) => i !== idx) ?? []
7774
- }));
7775
- setHasChanges(true);
7776
- setBannerVisible(true);
7777
- },
7778
- endpointResponseParams,
7779
- onAddResponseParameter: (endpointId, param) => {
7780
- setEndpointResponseParams((prev) => ({
7781
- ...prev,
7782
- [endpointId]: [...prev[endpointId] ?? [], param]
7783
- }));
7784
- setHasChanges(true);
7785
- setBannerVisible(true);
7786
- },
7787
- onEditResponseParameter: (endpointId, idx, param) => {
7788
- setEndpointResponseParams((prev) => ({
7789
- ...prev,
7790
- [endpointId]: prev[endpointId]?.map((p, i) => i === idx ? param : p) ?? []
7791
- }));
7792
- setHasChanges(true);
7793
- setBannerVisible(true);
7794
- },
7795
- onDeleteResponseParameter: (endpointId, idx) => {
7796
- setEndpointResponseParams((prev) => ({
7797
- ...prev,
7798
- [endpointId]: prev[endpointId]?.filter((_, i) => i !== idx) ?? []
7799
- }));
7800
- setHasChanges(true);
7801
- setBannerVisible(true);
7802
- }
7803
- }, resetKey)
7804
- })
7805
- ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9876
+ ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
9877
+ selectedEditItem.type === "errors" && errorBox && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9878
+ className: cx("section"),
9879
+ children: errorBox
9880
+ }),
9881
+ selectedEditItem.type !== "errors" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: errorBoxExpanded && errorBox ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9882
+ className: cx("section"),
9883
+ children: errorBox
9884
+ }) : errorBoxCollapsed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9885
+ className: cx("section"),
9886
+ children: errorBoxCollapsed
9887
+ }) }),
9888
+ selectedEditItem.type === "general" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9889
+ className: cx("section"),
9890
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GeneralSection, {
9891
+ apiName: localApiName,
9892
+ authType: selectedApi?.authType || "",
9893
+ version: selectedApi?.relatedVersions?.find((v) => v.apiId === selectedApi?.currentVersion)?.version || "",
9894
+ description: localDescription,
9895
+ onApiNameChange: (val) => {
9896
+ setApiNameTouched(true);
9897
+ setLocalApiName(val);
9898
+ },
9899
+ apiNameError: hasApiNameError,
9900
+ onDescriptionChange: (val) => {
9901
+ setDescriptionTouched(true);
9902
+ setLocalDescription(val);
9903
+ },
9904
+ descriptionError: hasDescriptionError,
9905
+ collapsed: generalCollapsed,
9906
+ onToggleCollapse: () => setGeneralCollapsed((c) => !c),
9907
+ onChangeDetected: () => {
9908
+ setBannerVisible(true);
9909
+ }
9910
+ })
9911
+ }),
9912
+ selectedEditItem.type === "tags" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9913
+ className: cx("section"),
9914
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TagsSection, {
9915
+ tags: localTags,
9916
+ collapsed: tagsCollapsed,
9917
+ onToggleCollapse: () => setTagsCollapsed((prev) => !prev),
9918
+ onAddTag: () => setTagDrawerState({
9919
+ open: true,
9920
+ mode: "add"
9921
+ }),
9922
+ onEditTag: (tag) => setTagDrawerState({
9923
+ open: true,
9924
+ mode: "edit",
9925
+ initialValues: {
9926
+ name: tag.name,
9927
+ description: tag.description,
9928
+ externalDocsDescription: tag.externalDocsDescription,
9929
+ externalDocsLink: tag.externalDocsUrl
9930
+ }
9931
+ }),
9932
+ onDeleteTag: (tagName) => setDeleteTagModal({
9933
+ open: true,
9934
+ tagName
9935
+ })
9936
+ })
9937
+ }),
9938
+ selectedEditItem.type === "endpoint" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EndpointsSection, {
9939
+ mode,
9940
+ endpointsByTag: getEndpointsByTag(),
9941
+ selectedEndpointKey: selectedEditItem.key,
9942
+ collapsed: endpointsCollapsed,
9943
+ onToggleCollapse: () => setEndpointsCollapsed((c) => !c),
9944
+ endpointNames,
9945
+ endpointDescs,
9946
+ endpointTags,
9947
+ availableTags: localTags.map((t) => t.name),
9948
+ onEndpointNameChange: (id, val) => {
9949
+ setEndpointNames((prev) => ({
9950
+ ...prev,
9951
+ [id]: val
9952
+ }));
9953
+ setBannerVisible(true);
9954
+ },
9955
+ onEndpointDescChange: (id, val) => {
9956
+ setEndpointDescs((prev) => ({
9957
+ ...prev,
9958
+ [id]: val
9959
+ }));
9960
+ setBannerVisible(true);
9961
+ },
9962
+ onEndpointTagsChange: (id, val) => {
9963
+ setEndpointTags((prev) => ({
9964
+ ...prev,
9965
+ [id]: val
9966
+ }));
9967
+ setBannerVisible(true);
9968
+ },
9969
+ endpointParams,
9970
+ onAddParameter: (endpointId, param) => {
9971
+ setEndpointParams((prev) => ({
9972
+ ...prev,
9973
+ [endpointId]: [...prev[endpointId] ?? [], param]
9974
+ }));
9975
+ setBannerVisible(true);
9976
+ },
9977
+ onEditParameter: (endpointId, idx, param) => {
9978
+ setEndpointParams((prev) => ({
9979
+ ...prev,
9980
+ [endpointId]: prev[endpointId]?.map((p, i) => i === idx ? param : p) ?? []
9981
+ }));
9982
+ setBannerVisible(true);
9983
+ },
9984
+ onDeleteParameter: (endpointId, idx) => {
9985
+ setEndpointParams((prev) => ({
9986
+ ...prev,
9987
+ [endpointId]: prev[endpointId]?.filter((_, i) => i !== idx) ?? []
9988
+ }));
9989
+ setBannerVisible(true);
9990
+ },
9991
+ endpointResponseParams,
9992
+ onAddResponseParameter: (endpointId, param) => {
9993
+ setEndpointResponseParams((prev) => ({
9994
+ ...prev,
9995
+ [endpointId]: [...prev[endpointId] ?? [], param]
9996
+ }));
9997
+ setBannerVisible(true);
9998
+ },
9999
+ onEditResponseParameter: (endpointId, idx, param) => {
10000
+ setEndpointResponseParams((prev) => ({
10001
+ ...prev,
10002
+ [endpointId]: prev[endpointId]?.map((p, i) => i === idx ? param : p) ?? []
10003
+ }));
10004
+ setBannerVisible(true);
10005
+ },
10006
+ onDeleteResponseParameter: (endpointId, idx) => {
10007
+ setEndpointResponseParams((prev) => ({
10008
+ ...prev,
10009
+ [endpointId]: prev[endpointId]?.filter((_, i) => i !== idx) ?? []
10010
+ }));
10011
+ setBannerVisible(true);
10012
+ },
10013
+ onRequestContentChange: (endpointId, jsonString) => {
10014
+ try {
10015
+ const schema = JSON.parse(jsonString);
10016
+ setEndpointRequestBody((prev) => ({
10017
+ ...prev,
10018
+ [endpointId]: schema
10019
+ }));
10020
+ setBannerVisible(true);
10021
+ } catch {}
10022
+ },
10023
+ onResponseContentChange: (endpointId, jsonString) => {
10024
+ try {
10025
+ const schema = JSON.parse(jsonString);
10026
+ setEndpointResponseBody((prev) => ({
10027
+ ...prev,
10028
+ [endpointId]: schema
10029
+ }));
10030
+ setBannerVisible(true);
10031
+ } catch {}
10032
+ },
10033
+ requestBodySchemas: endpointRequestBody,
10034
+ responseBodySchemas: endpointResponseBody
10035
+ }, resetKey)
10036
+ ] })
10037
+ })]
10038
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7806
10039
  className: cx("docs-layout"),
7807
- children: [
7808
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Sidebar, {
7809
- searchValue,
7810
- setSearchValue
7811
- }),
7812
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MainContent, {
10040
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Sidebar, {
10041
+ searchValue,
10042
+ setSearchValue
10043
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10044
+ className: cx("content-scroll-area"),
10045
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MainContent, {
7813
10046
  handleVisitLandingPage: _handleVisitLandingPage,
7814
10047
  handleResetSearch,
7815
10048
  searchEnabled: !!searchValue
7816
- }),
7817
- !isMobile && focusedContent === "ENDPOINT" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeboxSidebar$1, {})
7818
- ]
10049
+ }), !isMobile && focusedContent === "ENDPOINT" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeboxSidebar$1, {})]
10050
+ })]
7819
10051
  }),
7820
10052
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AddTagDrawer, {
7821
10053
  open: tagDrawerState.open,
@@ -7828,6 +10060,144 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
7828
10060
  onAddTag: handleAddTag,
7829
10061
  onEditTag: handleUpdateTag
7830
10062
  }),
10063
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(antd.Modal, {
10064
+ open: saveConfirmModal,
10065
+ onCancel: () => setSaveConfirmModal(false),
10066
+ centered: true,
10067
+ title: null,
10068
+ footer: null,
10069
+ closable: false,
10070
+ width: 520,
10071
+ className: "delete-tag-confirm-modal",
10072
+ styles: {
10073
+ content: {
10074
+ padding: 0,
10075
+ borderRadius: 8,
10076
+ overflow: "hidden"
10077
+ },
10078
+ body: {
10079
+ padding: 0,
10080
+ margin: 0
10081
+ }
10082
+ },
10083
+ children: [
10084
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10085
+ className: cx("deleteModalHead"),
10086
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10087
+ className: cx("deleteModalTitle"),
10088
+ children: "Save & Publish Changes"
10089
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
10090
+ className: cx("deleteModalCloseBtn"),
10091
+ onClick: () => setSaveConfirmModal(false),
10092
+ "aria-label": "Close",
10093
+ children: "×"
10094
+ })]
10095
+ }),
10096
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10097
+ className: cx("deleteModalContent"),
10098
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10099
+ className: cx("deleteModalContentText"),
10100
+ children: "Are you sure you want to Save & Publish Changes?"
10101
+ })
10102
+ }),
10103
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10104
+ className: cx("deleteModalFooter"),
10105
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
10106
+ size: "middle",
10107
+ onClick: () => setSaveConfirmModal(false),
10108
+ style: {
10109
+ borderRadius: 8,
10110
+ height: 32,
10111
+ paddingInline: 15
10112
+ },
10113
+ children: "Cancel"
10114
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
10115
+ type: "primary",
10116
+ size: "middle",
10117
+ onClick: () => {
10118
+ setSaveConfirmModal(false);
10119
+ handleSave();
10120
+ },
10121
+ style: {
10122
+ borderRadius: 8,
10123
+ height: 32,
10124
+ paddingInline: 16
10125
+ },
10126
+ children: "Yes, Save & Publish"
10127
+ })]
10128
+ })
10129
+ ]
10130
+ }),
10131
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(antd.Modal, {
10132
+ open: resetConfirmModal,
10133
+ onCancel: () => setResetConfirmModal(false),
10134
+ centered: true,
10135
+ title: null,
10136
+ footer: null,
10137
+ closable: false,
10138
+ width: 520,
10139
+ className: "delete-tag-confirm-modal",
10140
+ styles: {
10141
+ content: {
10142
+ padding: 0,
10143
+ borderRadius: 8,
10144
+ overflow: "hidden"
10145
+ },
10146
+ body: {
10147
+ padding: 0,
10148
+ margin: 0
10149
+ }
10150
+ },
10151
+ children: [
10152
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10153
+ className: cx("deleteModalHead"),
10154
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10155
+ className: cx("deleteModalTitle"),
10156
+ children: "Reset changes?"
10157
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
10158
+ className: cx("deleteModalCloseBtn"),
10159
+ onClick: () => setResetConfirmModal(false),
10160
+ "aria-label": "Close",
10161
+ children: "×"
10162
+ })]
10163
+ }),
10164
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10165
+ className: cx("deleteModalContent"),
10166
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10167
+ className: cx("deleteModalContentText"),
10168
+ children: "This will discard your unsaved changes."
10169
+ })
10170
+ }),
10171
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10172
+ className: cx("deleteModalFooter"),
10173
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
10174
+ size: "middle",
10175
+ onClick: () => setResetConfirmModal(false),
10176
+ style: {
10177
+ borderRadius: 8,
10178
+ height: 32,
10179
+ paddingInline: 15
10180
+ },
10181
+ children: "Cancel"
10182
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
10183
+ size: "middle",
10184
+ onClick: () => {
10185
+ setResetConfirmModal(false);
10186
+ handleReset();
10187
+ },
10188
+ style: {
10189
+ borderRadius: 8,
10190
+ height: 32,
10191
+ paddingInline: 16,
10192
+ backgroundColor: "#faad14",
10193
+ borderColor: "#faad14",
10194
+ color: "#fff"
10195
+ },
10196
+ children: "Yes, Reset"
10197
+ })]
10198
+ })
10199
+ ]
10200
+ }),
7831
10201
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(antd.Modal, {
7832
10202
  open: deleteTagModal.open,
7833
10203
  onCancel: () => setDeleteTagModal({