@prorobotech/openapi-k8s-toolkit 1.3.0-alpha.9 → 1.4.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/{index-C7wXx2NH.mjs → index-85og70S2.mjs} +5 -37
  2. package/dist/index-85og70S2.mjs.map +1 -0
  3. package/dist/{index-CqVGo048.mjs → index-BwCZPalv.mjs} +2380 -631
  4. package/dist/index-BwCZPalv.mjs.map +1 -0
  5. package/dist/openapi-k8s-toolkit.es.js +1 -1
  6. package/dist/openapi-k8s-toolkit.umd.js +2344 -626
  7. package/dist/openapi-k8s-toolkit.umd.js.map +1 -1
  8. package/dist/types/api/forms.d.ts +4 -0
  9. package/dist/types/api/permissions.d.ts +3 -1
  10. package/dist/types/components/atoms/ConfirmModal/ConfirmModal.d.ts +13 -0
  11. package/dist/types/components/atoms/ConfirmModal/index.d.ts +2 -0
  12. package/dist/types/components/atoms/index.d.ts +2 -0
  13. package/dist/types/components/molecules/BlackholeForm/molecules/helpers/validation.d.ts +6 -0
  14. package/dist/types/components/molecules/BlackholeForm/molecules/helpers/validation.test.d.ts +1 -0
  15. package/dist/types/components/molecules/BlackholeForm/organisms/BlackholeFormProvider/BlackholeFormProvider.d.ts +7 -0
  16. package/dist/types/components/molecules/ManageableBreadcrumbs/organisms/ManageableBreadcrumbsProvider/ManageableBreadcrumbsProvider.d.ts +1 -0
  17. package/dist/types/components/molecules/ManageableBreadcrumbs/organisms/ManageableBreadcrumbsProvider/utils.d.ts +2 -1
  18. package/dist/types/components/molecules/ManageableSidebar/organisms/ManageableSidebarProvider/ManageableSidebarProvider.d.ts +2 -0
  19. package/dist/types/components/molecules/ManageableSidebar/organisms/ManageableSidebarProvider/types.d.ts +10 -0
  20. package/dist/types/components/molecules/ManageableSidebar/organisms/ManageableSidebarProvider/utils.d.ts +24 -1
  21. package/dist/types/components/molecules/MarketPlace/MarketPlace.d.ts +1 -1
  22. package/dist/types/components/molecules/YamlEditorSingleton/YamlEditorSingleton.d.ts +1 -0
  23. package/dist/types/components/molecules/YamlEditorSingleton/utils.d.ts +3 -0
  24. package/dist/types/components/molecules/YamlEditorSingleton/utils.test.d.ts +1 -0
  25. package/dist/types/components/organisms/DynamicComponents/atoms/modals/AnnotationsEditModal/AnnotationsEditModal.d.ts +1 -0
  26. package/dist/types/components/organisms/DynamicComponents/atoms/modals/LabelsEditModal/LabelsEditModal.d.ts +1 -0
  27. package/dist/types/components/organisms/DynamicComponents/atoms/modals/TaintsEditModal/TaintsEditModal.d.ts +1 -0
  28. package/dist/types/components/organisms/DynamicComponents/atoms/modals/TolerationsEditModal/TolerationsEditModal.d.ts +1 -0
  29. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/ActionsDropdown.d.ts +2 -2
  30. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/index.d.ts +2 -0
  31. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers.d.ts +77 -0
  32. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers.test.d.ts +1 -0
  33. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers.utils.test.d.ts +1 -0
  34. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownPermissions.d.ts +10 -0
  35. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownPermissions.test.d.ts +1 -0
  36. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/modals/OpenKubeletConfigModal.d.ts +9 -0
  37. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/modals/ScaleModal.d.ts +10 -0
  38. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/permissionsMap.d.ts +7 -0
  39. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/renderActionModal.d.ts +8 -0
  40. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/styled.d.ts +860 -0
  41. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/utils.d.ts +17 -9
  42. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/utils.test.d.ts +1 -0
  43. package/dist/types/components/organisms/DynamicComponents/molecules/AggregatedCounterCard/molecules/AnnotationsModal/AnnotationsModal.d.ts +1 -0
  44. package/dist/types/components/organisms/DynamicComponents/molecules/AggregatedCounterCard/molecules/LabelsModal/LabelsModal.d.ts +1 -0
  45. package/dist/types/components/organisms/DynamicComponents/molecules/AggregatedCounterCard/molecules/TaintsModal/TaintsModal.d.ts +1 -0
  46. package/dist/types/components/organisms/DynamicComponents/molecules/AggregatedCounterCard/molecules/TolerationsModal/TolerationsModal.d.ts +1 -0
  47. package/dist/types/components/organisms/DynamicComponents/molecules/AggregatedCounterCard/utils.d.ts +1 -0
  48. package/dist/types/components/organisms/DynamicComponents/molecules/AntdLink/utils.d.ts +1 -0
  49. package/dist/types/components/organisms/DynamicComponents/molecules/AntdLink/utils.test.d.ts +1 -0
  50. package/dist/types/components/organisms/DynamicComponents/molecules/EnrichedTable/utils.d.ts +1 -0
  51. package/dist/types/components/organisms/DynamicComponents/molecules/EnrichedTable/utils.test.d.ts +1 -0
  52. package/dist/types/components/organisms/DynamicComponents/molecules/LabelsToSearchParams/utils.d.ts +6 -0
  53. package/dist/types/components/organisms/DynamicComponents/molecules/SecretBase64Plain/styled.d.ts +1 -0
  54. package/dist/types/components/organisms/DynamicComponents/molecules/SecretBase64Plain/utils.d.ts +2 -0
  55. package/dist/types/components/organisms/DynamicComponents/molecules/SecretBase64Plain/utils.test.d.ts +1 -0
  56. package/dist/types/components/organisms/DynamicComponents/molecules/StatusText/utils.d.ts +2 -2
  57. package/dist/types/components/organisms/DynamicComponents/types/ActionsDropdown.d.ts +122 -1
  58. package/dist/types/components/organisms/DynamicComponents/types/Annotations.d.ts +14 -0
  59. package/dist/types/components/organisms/DynamicComponents/types/Labels.d.ts +13 -0
  60. package/dist/types/components/organisms/DynamicComponents/types/LabelsToSearchParams.d.ts +2 -0
  61. package/dist/types/components/organisms/DynamicComponents/types/MarketplaceCard.d.ts +1 -1
  62. package/dist/types/components/organisms/DynamicComponents/types/SecretBase64Plain.d.ts +10 -0
  63. package/dist/types/components/organisms/DynamicComponents/types/StatusText.d.ts +1 -1
  64. package/dist/types/components/organisms/DynamicComponents/types/Taints.d.ts +14 -0
  65. package/dist/types/components/organisms/DynamicComponents/types/Tolerations.d.ts +14 -0
  66. package/dist/types/components/organisms/DynamicComponents/types/YamlEditorSingleton.d.ts +13 -0
  67. package/dist/types/hooks/usePermissions.d.ts +4 -2
  68. package/dist/types/localTypes/bff/form.d.ts +2 -0
  69. package/dist/types/localTypes/bff/table.d.ts +1 -0
  70. package/dist/types/localTypes/permissions.d.ts +1 -0
  71. package/package.json +5 -5
  72. package/dist/index-C7wXx2NH.mjs.map +0 -1
  73. package/dist/index-CqVGo048.mjs.map +0 -1
@@ -1,9 +1,9 @@
1
- import styled, { createGlobalStyle } from 'styled-components';
1
+ import styled, { css, createGlobalStyle } from 'styled-components';
2
2
  import * as React$1 from 'react';
3
3
  import React__default, { useState, useRef, useLayoutEffect, useReducer, useEffect, useCallback, useMemo, Fragment, createContext, useContext, memo, createElement, isValidElement, cloneElement, useInsertionEffect, useSyncExternalStore, forwardRef, useImperativeHandle, PureComponent, Children, Component, lazy, Suspense } from 'react';
4
- import { Input, Tree, Modal, Alert, theme, Select, Tag, Flex, Typography, Breadcrumb, Spin, Menu, Tooltip as Tooltip$1, Space, Button, Card as Card$2, Row, Col, Tabs, notification, Form, Popover, Switch, Segmented, Table, Progress, Statistic, message, Dropdown, Slider, InputNumber, Result, DatePicker, Radio, Checkbox, Empty } from 'antd';
4
+ import { Input, Tree, Modal, Alert, theme, Select, Tag, Flex, Typography, Breadcrumb, Spin, Menu, Tooltip as Tooltip$1, Space, Button, Card as Card$2, Row, Col, Tabs, notification, Form, Popover, Switch, Segmented, Table, Progress, Statistic, message, InputNumber, Dropdown, Slider, Result, DatePicker, Radio, Checkbox, Empty } from 'antd';
5
5
  import * as AntIcons from '@ant-design/icons';
6
- import { LoadingOutlined, ExclamationCircleFilled, CloseCircleFilled, CheckCircleFilled, PlusOutlined, ClearOutlined, MinusOutlined, CaretDownOutlined, CaretRightOutlined, InfoCircleOutlined, EyeOutlined, EyeInvisibleOutlined, CopyOutlined, DownOutlined, SearchOutlined, MoreOutlined, CheckOutlined, CloseOutlined, BugOutlined, EllipsisOutlined, PoweroffOutlined, FullscreenExitOutlined, FullscreenOutlined, SettingOutlined, ReloadOutlined } from '@ant-design/icons';
6
+ import { LoadingOutlined, ExclamationCircleFilled, CloseCircleFilled, CheckCircleFilled, PlusOutlined, ClearOutlined, MinusOutlined, CaretDownOutlined, CaretRightOutlined, InfoCircleOutlined, SearchOutlined, EyeOutlined, EyeInvisibleOutlined, CopyOutlined, WarningOutlined, MoreOutlined, DownOutlined, CheckOutlined, CloseOutlined, QuestionCircleOutlined, BugOutlined, EllipsisOutlined, PoweroffOutlined, FullscreenExitOutlined, FullscreenOutlined, SettingOutlined, ReloadOutlined } from '@ant-design/icons';
7
7
  import { useNavigate, useSearchParams, Link, useLocation, useParams } from 'react-router-dom';
8
8
  import { useQuery, useQueries, useQueryClient } from '@tanstack/react-query';
9
9
  import RFB from 'novnc-next';
@@ -1578,7 +1578,7 @@ const CustomTreeProvider = styled.div`
1578
1578
  justify-content: center;
1579
1579
  }
1580
1580
  `;
1581
- const Styled$H = {
1581
+ const Styled$I = {
1582
1582
  CustomTreeProvider
1583
1583
  };
1584
1584
 
@@ -1643,7 +1643,7 @@ const TreeWithSearch = ({ treeData, onSelect }) => {
1643
1643
  });
1644
1644
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1645
1645
  /* @__PURE__ */ jsxRuntimeExports.jsx(Search$1, { style: { marginBottom: 8 }, placeholder: "Search", onChange }),
1646
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$H.CustomTreeProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1646
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$I.CustomTreeProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1647
1647
  Tree,
1648
1648
  {
1649
1649
  treeData: loop(treeData),
@@ -7917,6 +7917,17 @@ const patchEntryWithReplaceOp = async ({
7917
7917
  }
7918
7918
  return axios.patch(endpoint, replaceOp, config);
7919
7919
  };
7920
+ const patchEntryWithMergePatch = async ({
7921
+ endpoint,
7922
+ body
7923
+ }) => {
7924
+ return axios.patch(endpoint, JSON.stringify(body), {
7925
+ method: "PATCH",
7926
+ headers: {
7927
+ "Content-Type": "application/merge-patch+json"
7928
+ }
7929
+ });
7930
+ };
7920
7931
  const patchEntryWithDeleteOp = async ({
7921
7932
  endpoint,
7922
7933
  pathToValue
@@ -7965,6 +7976,7 @@ const DeleteModal = ({ name, onClose, endpoint }) => {
7965
7976
  confirmLoading: isLoading,
7966
7977
  okButtonProps: { danger: true },
7967
7978
  width: 400,
7979
+ centered: true,
7968
7980
  children: error && /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { type: "error", message: "Error while delete", description: error?.response?.data?.message })
7969
7981
  }
7970
7982
  );
@@ -8001,11 +8013,41 @@ const DeleteModalMany = ({ data, onClose }) => {
8001
8013
  confirmLoading: isLoading,
8002
8014
  okButtonProps: { danger: true },
8003
8015
  width: 400,
8016
+ centered: true,
8004
8017
  children: error && /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { type: "error", message: "Error while delete", description: error?.response?.data?.message })
8005
8018
  }
8006
8019
  );
8007
8020
  };
8008
8021
 
8022
+ const ConfirmModal = ({
8023
+ title,
8024
+ onConfirm,
8025
+ onClose,
8026
+ confirmText = "Confirm",
8027
+ cancelText = "Cancel",
8028
+ confirmLoading = false,
8029
+ danger = false,
8030
+ width = 400,
8031
+ children
8032
+ }) => {
8033
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
8034
+ Modal,
8035
+ {
8036
+ title,
8037
+ open: true,
8038
+ onOk: () => onConfirm(),
8039
+ onCancel: () => onClose(),
8040
+ okText: confirmText,
8041
+ cancelText,
8042
+ confirmLoading,
8043
+ okButtonProps: { danger },
8044
+ width,
8045
+ centered: true,
8046
+ children
8047
+ }
8048
+ );
8049
+ };
8050
+
8009
8051
  const DeleteIcon = ({ width, height }) => {
8010
8052
  const { token } = theme.useToken();
8011
8053
  return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { width: width ?? 18, height: height ?? 19, viewBox: "0 0 18 19", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -8201,14 +8243,14 @@ const ContentContainer = styled.div`
8201
8243
  display: ${({ $displayFlex }) => $displayFlex ? "flex" : "block"};
8202
8244
  flex-flow: ${({ $flexFlow }) => $flexFlow};
8203
8245
  `;
8204
- const Styled$G = {
8246
+ const Styled$H = {
8205
8247
  ContentContainer
8206
8248
  };
8207
8249
 
8208
8250
  const ContentCard$1 = ({ children, flexGrow, displayFlex, flexFlow, maxHeight }) => {
8209
8251
  const { token } = theme.useToken();
8210
8252
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
8211
- Styled$G.ContentContainer,
8253
+ Styled$H.ContentContainer,
8212
8254
  {
8213
8255
  $flexGrow: flexGrow,
8214
8256
  $bgColor: token.colorBgContainer,
@@ -8269,13 +8311,13 @@ const UncontrolledSelect$1 = styled(Select)`
8269
8311
  padding-inline: 8px;
8270
8312
  }
8271
8313
  `;
8272
- const Styled$F = {
8314
+ const Styled$G = {
8273
8315
  UncontrolledSelect: UncontrolledSelect$1
8274
8316
  };
8275
8317
 
8276
8318
  const UncontrolledSelect = (props) => {
8277
8319
  const { isCursorPointer } = props;
8278
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$F.UncontrolledSelect, { ...props, $isCursorPointer: isCursorPointer });
8320
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$G.UncontrolledSelect, { ...props, $isCursorPointer: isCursorPointer });
8279
8321
  };
8280
8322
 
8281
8323
  const CustomSelect$5 = styled(Select)`
@@ -8323,13 +8365,13 @@ const CustomSelect$5 = styled(Select)`
8323
8365
  margin-block: 0 !important;
8324
8366
  }
8325
8367
  `;
8326
- const Styled$E = {
8368
+ const Styled$F = {
8327
8369
  CustomSelect: CustomSelect$5
8328
8370
  };
8329
8371
 
8330
8372
  const CustomSelect$4 = (props) => {
8331
8373
  const { paddingContainerEnd, ...rest } = props;
8332
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$E.CustomSelect, { $paddingContainerEnd: paddingContainerEnd, ...rest });
8374
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$F.CustomSelect, { $paddingContainerEnd: paddingContainerEnd, ...rest });
8333
8375
  };
8334
8376
 
8335
8377
  const CursorPointerTag = styled(Tag)`
@@ -8476,7 +8518,7 @@ const Abbr$2 = styled.span`
8476
8518
  height: min-content;
8477
8519
  margin-right: 4px;
8478
8520
  `;
8479
- const Styled$D = {
8521
+ const Styled$E = {
8480
8522
  Abbr: Abbr$2
8481
8523
  };
8482
8524
 
@@ -8516,7 +8558,7 @@ const ResourceLink = ({
8516
8558
  baseFactoriesMapping
8517
8559
  });
8518
8560
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { align: "center", gap: 8, children: [
8519
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$D.Abbr, { $bgColor: bgColor, children: abbr }),
8561
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$E.Abbr, { $bgColor: bgColor, children: abbr }),
8520
8562
  resourceLink ? /* @__PURE__ */ jsxRuntimeExports.jsx(
8521
8563
  Typography.Link,
8522
8564
  {
@@ -8555,7 +8597,7 @@ const NoWrapContainer = styled.div`
8555
8597
  flex-wrap: nowrap !important;
8556
8598
  }
8557
8599
  `;
8558
- const Styled$C = {
8600
+ const Styled$D = {
8559
8601
  PositionRelativeContainer,
8560
8602
  FullWidthContainer,
8561
8603
  NoWrapContainer
@@ -8598,9 +8640,9 @@ const CollapsibleBreadcrumb = ({ items }) => {
8598
8640
  };
8599
8641
  return [firstItem, ellipsisItem, lastItem];
8600
8642
  };
8601
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$C.PositionRelativeContainer, { children: [
8602
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$C.FullWidthContainer, { ref: containerRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Breadcrumb, { separator: ">", items: renderItems() }) }),
8603
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$C.NoWrapContainer, { ref: breadcrumbRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Breadcrumb, { separator: ">", items, style: { display: "flex", flexWrap: "nowrap" } }) })
8643
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$D.PositionRelativeContainer, { children: [
8644
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$D.FullWidthContainer, { ref: containerRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Breadcrumb, { separator: ">", items: renderItems() }) }),
8645
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$D.NoWrapContainer, { ref: breadcrumbRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Breadcrumb, { separator: ">", items, style: { display: "flex", flexWrap: "nowrap" } }) })
8604
8646
  ] });
8605
8647
  };
8606
8648
 
@@ -8608,12 +8650,12 @@ const HeightDiv$1 = styled.div`
8608
8650
  min-height: 22px;
8609
8651
  width: 100%;
8610
8652
  `;
8611
- const Styled$B = {
8653
+ const Styled$C = {
8612
8654
  HeightDiv: HeightDiv$1
8613
8655
  };
8614
8656
 
8615
8657
  const ManageableBreadcrumbs = ({ data }) => {
8616
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$B.HeightDiv, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleBreadcrumb, { items: data.breadcrumbItems }) });
8658
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$C.HeightDiv, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleBreadcrumb, { items: data.breadcrumbItems }) });
8617
8659
  };
8618
8660
 
8619
8661
  const kindByGvr = (entries) => (gvr) => {
@@ -9580,9 +9622,10 @@ const mapLinksFromRaw$1 = ({
9580
9622
  const prepareDataForManageableBreadcrumbs = ({
9581
9623
  data,
9582
9624
  replaceValues,
9583
- idToCompare
9625
+ idToCompare,
9626
+ fallbackIdToCompare
9584
9627
  }) => {
9585
- const foundData = data.find((el) => el?.id === idToCompare);
9628
+ const foundData = data.find((el) => el?.id === idToCompare) || (fallbackIdToCompare ? data.find((el) => el?.id === fallbackIdToCompare) : void 0);
9586
9629
  if (!foundData) {
9587
9630
  return void 0;
9588
9631
  }
@@ -9599,7 +9642,7 @@ const HeightDiv = styled.div`
9599
9642
  min-height: 22px;
9600
9643
  width: 100%;
9601
9644
  `;
9602
- const Styled$A = {
9645
+ const Styled$B = {
9603
9646
  HeightDiv
9604
9647
  };
9605
9648
 
@@ -9611,7 +9654,8 @@ const ManageableBreadcrumbsProvider = ({
9611
9654
  isEnabled,
9612
9655
  replaceValues,
9613
9656
  pathname,
9614
- idToCompare
9657
+ idToCompare,
9658
+ fallbackIdToCompare
9615
9659
  }) => {
9616
9660
  const {
9617
9661
  data: rawData,
@@ -9628,7 +9672,7 @@ const ManageableBreadcrumbsProvider = ({
9628
9672
  return null;
9629
9673
  }
9630
9674
  if (rawDataLoading) {
9631
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$A.HeightDiv, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Spin, {}) });
9675
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$B.HeightDiv, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Spin, {}) });
9632
9676
  }
9633
9677
  if (!rawData) {
9634
9678
  return null;
@@ -9640,10 +9684,11 @@ const ManageableBreadcrumbsProvider = ({
9640
9684
  const result = prepareDataForManageableBreadcrumbs({
9641
9685
  data: parsedData,
9642
9686
  replaceValues,
9643
- idToCompare
9687
+ idToCompare,
9688
+ fallbackIdToCompare
9644
9689
  });
9645
9690
  if (!result) {
9646
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$A.HeightDiv, {});
9691
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$B.HeightDiv, {});
9647
9692
  }
9648
9693
  return /* @__PURE__ */ jsxRuntimeExports.jsx(ManageableBreadcrumbs, { data: result }, JSON.stringify(idToCompare));
9649
9694
  };
@@ -9671,7 +9716,7 @@ const CustomMenu = styled(Menu)`
9671
9716
  margin: 0 !important;
9672
9717
  }
9673
9718
  `;
9674
- const Styled$z = {
9719
+ const Styled$A = {
9675
9720
  CustomMenu
9676
9721
  };
9677
9722
 
@@ -9698,7 +9743,7 @@ const ManageableSidebar = ({ data, noMarginTop }) => {
9698
9743
  setSelectedKeys(data.selectedKeys);
9699
9744
  }, [data.selectedKeys]);
9700
9745
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
9701
- Styled$z.CustomMenu,
9746
+ Styled$A.CustomMenu,
9702
9747
  {
9703
9748
  selectedKeys,
9704
9749
  onSelect: () => {
@@ -9715,156 +9760,6 @@ const ManageableSidebar = ({ data, noMarginTop }) => {
9715
9760
  );
9716
9761
  };
9717
9762
 
9718
- const getLabel$1 = ({
9719
- preparedLink,
9720
- label,
9721
- key,
9722
- externalKeys,
9723
- replaceValues
9724
- }) => {
9725
- const preparedLabel = prepareTemplate({ template: label, replaceValues });
9726
- if (preparedLink) {
9727
- if (externalKeys && externalKeys.includes(key)) {
9728
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
9729
- "a",
9730
- {
9731
- onClick: (e) => {
9732
- e.preventDefault();
9733
- e.stopPropagation();
9734
- const url = preparedLink.startsWith("/") ? `${window.location.origin}${preparedLink}` : preparedLink;
9735
- window.open(url);
9736
- },
9737
- children: preparedLabel
9738
- }
9739
- );
9740
- }
9741
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: preparedLink, children: preparedLabel });
9742
- }
9743
- return preparedLabel;
9744
- };
9745
- const mapLinksFromRaw = ({
9746
- rawLinks,
9747
- replaceValues,
9748
- externalKeys
9749
- }) => {
9750
- return rawLinks.map(({ key, label, link, children }) => {
9751
- const preparedLink = link ? prepareTemplate({ template: link, replaceValues }) : void 0;
9752
- return {
9753
- key,
9754
- label: getLabel$1({ preparedLink, label, key, externalKeys, replaceValues }),
9755
- internalMetaLink: preparedLink,
9756
- children: children ? mapLinksFromRaw({
9757
- rawLinks: children,
9758
- replaceValues,
9759
- externalKeys
9760
- }) : void 0
9761
- };
9762
- });
9763
- };
9764
- const findMatchingItems = ({
9765
- items,
9766
- pathname,
9767
- tags
9768
- }) => {
9769
- const traverse = (nodes, parents) => nodes.flatMap((node) => {
9770
- const currentPath = [...parents, node.key ? node.key : String(node.key)];
9771
- const cleanNodeInternalMetaLink = node.internalMetaLink?.startsWith("/") ? node.internalMetaLink.slice(1) : node.internalMetaLink;
9772
- const cleanPathname = pathname.startsWith("/") ? pathname.slice(1) : pathname;
9773
- const matched = cleanNodeInternalMetaLink === cleanPathname ? currentPath : [];
9774
- const tagsToMatch = tags && tags.keysAndTags && node.key ? tags.keysAndTags[typeof node.key === "string" ? node.key : String(node.key)] : void 0;
9775
- const matchedByTags = tags && tags.currentTags && tagsToMatch && tagsToMatch.some((tag) => tags.currentTags?.includes(tag)) ? currentPath : [];
9776
- let childrenResults = [];
9777
- if ("children" in node && node.children) {
9778
- childrenResults = traverse(node.children, currentPath);
9779
- }
9780
- return [...matched, ...matchedByTags, ...childrenResults];
9781
- });
9782
- return traverse(items, []);
9783
- };
9784
- const prepareDataForManageableSidebar = ({
9785
- data,
9786
- replaceValues,
9787
- pathname,
9788
- idToCompare,
9789
- fallbackIdToCompare,
9790
- currentTags
9791
- }) => {
9792
- const foundData = data.find((el) => el.id === idToCompare) || (fallbackIdToCompare ? data.find((el) => el.id === fallbackIdToCompare) : void 0);
9793
- if (!foundData) {
9794
- return void 0;
9795
- }
9796
- const preparedCurrentTags = currentTags && currentTags.length > 0 ? currentTags.map((el) => prepareTemplate({ template: el, replaceValues })) : void 0;
9797
- const result = {
9798
- menuItems: mapLinksFromRaw({
9799
- rawLinks: foundData.menuItems,
9800
- replaceValues,
9801
- externalKeys: foundData.externalKeys
9802
- })
9803
- };
9804
- const openedKeys = result?.menuItems ? findMatchingItems({
9805
- items: result?.menuItems,
9806
- pathname,
9807
- tags: { keysAndTags: foundData.keysAndTags, currentTags: preparedCurrentTags }
9808
- }) : [];
9809
- const stringedOpenedKeys = openedKeys.map((el) => typeof el === "string" ? el : String(el));
9810
- return { ...result, selectedKeys: stringedOpenedKeys };
9811
- };
9812
-
9813
- const ManageableSidebarProvider = ({
9814
- cluster,
9815
- apiGroup,
9816
- apiVersion,
9817
- plural,
9818
- isEnabled,
9819
- replaceValues,
9820
- pathname,
9821
- idToCompare,
9822
- fallbackIdToCompare,
9823
- currentTags,
9824
- hidden,
9825
- noMarginTop
9826
- }) => {
9827
- const {
9828
- data: rawData,
9829
- isError: rawDataError,
9830
- isLoading: rawDataLoading
9831
- } = useK8sSmartResource({
9832
- cluster,
9833
- apiGroup,
9834
- apiVersion,
9835
- plural,
9836
- isEnabled
9837
- });
9838
- if (rawDataError) {
9839
- return null;
9840
- }
9841
- if (rawDataLoading) {
9842
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Spin, {});
9843
- }
9844
- if (!rawData) {
9845
- return null;
9846
- }
9847
- if (hidden) {
9848
- return null;
9849
- }
9850
- const parsedData = rawData?.items.map(({ spec }) => spec);
9851
- if (!parsedData) {
9852
- return null;
9853
- }
9854
- const result = prepareDataForManageableSidebar({
9855
- data: parsedData,
9856
- replaceValues,
9857
- pathname,
9858
- idToCompare,
9859
- fallbackIdToCompare,
9860
- currentTags
9861
- });
9862
- if (!result) {
9863
- return null;
9864
- }
9865
- return /* @__PURE__ */ jsxRuntimeExports.jsx(ManageableSidebar, { data: result, noMarginTop });
9866
- };
9867
-
9868
9763
  function commonjsRequire(path) {
9869
9764
  throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
9870
9765
  }
@@ -33880,13 +33775,516 @@ lodash.exports;
33880
33775
  var lodashExports = lodash.exports;
33881
33776
  const _$1 = /*@__PURE__*/getDefaultExportFromCjs(lodashExports);
33882
33777
 
33778
+ const parsePartsOfUrl = ({
33779
+ template,
33780
+ replaceValues
33781
+ }) => {
33782
+ return prepareTemplate({ template, replaceValues });
33783
+ };
33784
+ const parseMutliqueryText = ({
33785
+ text,
33786
+ multiQueryData,
33787
+ customFallback
33788
+ }) => {
33789
+ if (!text) {
33790
+ return "";
33791
+ }
33792
+ return text.replace(
33793
+ /\{reqs\[(\d+)\]\[((?:\s*['"][^'"]+['"]\s*,?)+)\](?:\[\s*['"]([^'"]+)['"]\s*\])?\}/g,
33794
+ (_match, reqIndexStr, rawPath, fallback) => {
33795
+ try {
33796
+ const reqIndex = parseInt(reqIndexStr, 10);
33797
+ const path = Array.from(rawPath.matchAll(/['"]([^'"]+)['"]/g)).map(
33798
+ (m) => m[1]
33799
+ );
33800
+ const value = _$1.get(multiQueryData[`req${reqIndex}`] || {}, path, fallback !== void 0 ? fallback : void 0);
33801
+ if (value == null && !customFallback) {
33802
+ return fallback ?? "Undefined with no fallback";
33803
+ }
33804
+ if (customFallback && (value === void 0 || value === null)) {
33805
+ return customFallback;
33806
+ }
33807
+ return String(value);
33808
+ } catch {
33809
+ return _match;
33810
+ }
33811
+ }
33812
+ );
33813
+ };
33814
+ const parseJsonPathTemplate = ({
33815
+ text,
33816
+ multiQueryData,
33817
+ customFallback,
33818
+ replaceValues
33819
+ }) => {
33820
+ if (!text) return "";
33821
+ const placeholderRegex = /\{reqsJsonPath\[(\d+)\]\s*\[\s*(['"])([\s\S]*?)\2\s*\](?:\s*\[\s*(['"])([\s\S]*?)\4\s*\])?\}/g;
33822
+ const resolve = (input) => input.replace(
33823
+ placeholderRegex,
33824
+ (match, reqIndexStr, _quote, rawJsonPathExpr, _fallbackQuote, inlineFallback = "Undefined with no fallback") => {
33825
+ try {
33826
+ const reqIndex = Number(reqIndexStr);
33827
+ const jsonRoot = multiQueryData[`req${reqIndex}`];
33828
+ let jsonPathExpr = rawJsonPathExpr;
33829
+ let previous2 = null;
33830
+ let loopGuard = 0;
33831
+ while (previous2 !== jsonPathExpr && loopGuard < 10) {
33832
+ previous2 = jsonPathExpr;
33833
+ jsonPathExpr = resolve(jsonPathExpr);
33834
+ loopGuard++;
33835
+ }
33836
+ if (replaceValues) {
33837
+ jsonPathExpr = prepareTemplate({
33838
+ template: jsonPathExpr,
33839
+ replaceValues
33840
+ });
33841
+ }
33842
+ if (jsonRoot === void 0 && customFallback) return customFallback;
33843
+ if (jsonRoot === void 0) return inlineFallback;
33844
+ const results = jp.query(jsonRoot, `$${jsonPathExpr}`);
33845
+ const value = results?.[0];
33846
+ if (value == null) {
33847
+ return customFallback ?? inlineFallback;
33848
+ }
33849
+ return String(value);
33850
+ } catch {
33851
+ return match;
33852
+ }
33853
+ }
33854
+ );
33855
+ let result = text;
33856
+ let previous = null;
33857
+ let iterations = 0;
33858
+ while (result !== previous && iterations < 10) {
33859
+ previous = result;
33860
+ result = resolve(result);
33861
+ iterations++;
33862
+ }
33863
+ return result;
33864
+ };
33865
+ const parseWithoutPartsOfUrl = ({
33866
+ text,
33867
+ multiQueryData,
33868
+ customFallback
33869
+ }) => {
33870
+ return parseJsonPathTemplate({
33871
+ text: parseMutliqueryText({
33872
+ text,
33873
+ multiQueryData,
33874
+ customFallback
33875
+ }),
33876
+ multiQueryData,
33877
+ customFallback
33878
+ });
33879
+ };
33880
+ const parseAll = ({
33881
+ text,
33882
+ replaceValues,
33883
+ multiQueryData
33884
+ }) => {
33885
+ return parsePartsOfUrl({
33886
+ template: parseJsonPathTemplate({
33887
+ text: parseMutliqueryText({
33888
+ text,
33889
+ multiQueryData
33890
+ }),
33891
+ multiQueryData,
33892
+ replaceValues
33893
+ }),
33894
+ replaceValues
33895
+ });
33896
+ };
33897
+ const parsePromTemplate = ({
33898
+ text,
33899
+ replaceValues,
33900
+ multiQueryData
33901
+ }) => {
33902
+ const parsed = parseJsonPathTemplate({
33903
+ text: parseMutliqueryText({
33904
+ text,
33905
+ multiQueryData
33906
+ }),
33907
+ multiQueryData,
33908
+ replaceValues
33909
+ });
33910
+ return parsed.replace(/\{(\d+)\}/g, (_2, key) => replaceValues[key] || "");
33911
+ };
33912
+
33913
+ const collectLinksWithResourcesList = ({
33914
+ items,
33915
+ parentPath = "",
33916
+ replaceValues,
33917
+ multiQueryData,
33918
+ isEnabled
33919
+ }) => items.flatMap((item) => {
33920
+ const nodePath = parentPath ? `${parentPath}/${item.key}` : item.key;
33921
+ const self = item.resourcesList ? (() => {
33922
+ const clusterPrepared = parseAll({
33923
+ text: item.resourcesList.cluster,
33924
+ replaceValues,
33925
+ multiQueryData
33926
+ });
33927
+ const apiGroupPrepared = item.resourcesList.apiGroup ? parseAll({
33928
+ text: item.resourcesList.apiGroup,
33929
+ replaceValues,
33930
+ multiQueryData
33931
+ }) : void 0;
33932
+ const apiVersionPrepared = parseAll({
33933
+ text: item.resourcesList.apiVersion,
33934
+ replaceValues,
33935
+ multiQueryData
33936
+ });
33937
+ const pluralPrepared = parseAll({
33938
+ text: item.resourcesList.plural,
33939
+ replaceValues,
33940
+ multiQueryData
33941
+ });
33942
+ const namespacePrepared = item.resourcesList.namespace ? parseAll({
33943
+ text: item.resourcesList.namespace,
33944
+ replaceValues,
33945
+ multiQueryData
33946
+ }) : void 0;
33947
+ return [
33948
+ {
33949
+ nodePath,
33950
+ k8sParams: {
33951
+ cluster: clusterPrepared,
33952
+ apiGroup: apiGroupPrepared,
33953
+ apiVersion: apiVersionPrepared,
33954
+ plural: pluralPrepared,
33955
+ namespace: namespacePrepared,
33956
+ isEnabled: Boolean(clusterPrepared && apiVersionPrepared && pluralPrepared && isEnabled !== false)
33957
+ }
33958
+ }
33959
+ ];
33960
+ })() : [];
33961
+ const nested = item.children ? collectLinksWithResourcesList({
33962
+ items: item.children,
33963
+ parentPath: nodePath,
33964
+ replaceValues,
33965
+ multiQueryData,
33966
+ isEnabled
33967
+ }) : [];
33968
+ return [...self, ...nested];
33969
+ });
33970
+ const getLabel$1 = ({
33971
+ preparedLink,
33972
+ label,
33973
+ key,
33974
+ externalKeys,
33975
+ replaceValues,
33976
+ multiQueryData
33977
+ }) => {
33978
+ const preparedLabel = parseAll({ text: label, replaceValues, multiQueryData });
33979
+ if (preparedLink) {
33980
+ if (externalKeys && externalKeys.includes(key)) {
33981
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
33982
+ "a",
33983
+ {
33984
+ onClick: (e) => {
33985
+ e.preventDefault();
33986
+ e.stopPropagation();
33987
+ const url = preparedLink.startsWith("/") ? `${window.location.origin}${preparedLink}` : preparedLink;
33988
+ window.open(url);
33989
+ },
33990
+ children: preparedLabel
33991
+ }
33992
+ );
33993
+ }
33994
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Link, { to: preparedLink, children: preparedLabel });
33995
+ }
33996
+ return preparedLabel;
33997
+ };
33998
+ const mapLinksFromRaw = ({
33999
+ rawLinks,
34000
+ replaceValues,
34001
+ multiQueryData,
34002
+ externalKeys,
34003
+ resourcesListData,
34004
+ parentPath = ""
34005
+ }) => {
34006
+ return rawLinks.map(({ key, label, link, children, resourcesList }) => {
34007
+ const nodePath = parentPath ? `${parentPath}/${key}` : key;
34008
+ const preparedLink = link ? parseAll({ text: link, replaceValues, multiQueryData }) : void 0;
34009
+ const staticChildren = children ? mapLinksFromRaw({
34010
+ rawLinks: children,
34011
+ replaceValues,
34012
+ multiQueryData,
34013
+ externalKeys,
34014
+ resourcesListData,
34015
+ parentPath: nodePath
34016
+ }) : [];
34017
+ const dynamicChildrenRaw = resourcesList ? (resourcesListData?.[nodePath]?.items || []).map((item, index) => {
34018
+ const resourceName = (() => {
34019
+ try {
34020
+ const value = jp.query(item, `$${resourcesList.jsonPathToName}`)[0];
34021
+ return value !== void 0 && value !== null ? String(value) : void 0;
34022
+ } catch {
34023
+ return void 0;
34024
+ }
34025
+ })();
34026
+ if (!resourceName) {
34027
+ return void 0;
34028
+ }
34029
+ const childLink = parseAll({
34030
+ text: resourcesList.linkToResource,
34031
+ replaceValues: { ...replaceValues, resourceName },
34032
+ multiQueryData
34033
+ });
34034
+ const childKey = `${key}-${resourceName}-${index}`;
34035
+ return {
34036
+ key: childKey,
34037
+ label: getLabel$1({
34038
+ preparedLink: childLink,
34039
+ label: resourceName,
34040
+ key: childKey,
34041
+ externalKeys,
34042
+ replaceValues,
34043
+ multiQueryData
34044
+ }),
34045
+ internalMetaLink: childLink
34046
+ };
34047
+ }).filter(Boolean) : [];
34048
+ const dynamicChildren = dynamicChildrenRaw;
34049
+ const mergedChildren = [...staticChildren, ...dynamicChildren];
34050
+ return {
34051
+ key,
34052
+ label: getLabel$1({ preparedLink, label, key, externalKeys, replaceValues, multiQueryData }),
34053
+ internalMetaLink: preparedLink,
34054
+ children: mergedChildren.length > 0 ? mergedChildren : void 0
34055
+ };
34056
+ });
34057
+ };
34058
+ const findMatchingItems = ({
34059
+ items,
34060
+ pathname,
34061
+ searchParams,
34062
+ tags
34063
+ }) => {
34064
+ const normalizePath = (value) => {
34065
+ if (!value) {
34066
+ return void 0;
34067
+ }
34068
+ return value.startsWith("/") ? value.slice(1) : value;
34069
+ };
34070
+ const traverse = (nodes, parents) => nodes.flatMap((node) => {
34071
+ const currentPath = [...parents, node.key ? node.key : String(node.key)];
34072
+ const cleanNodeInternalMetaLink = normalizePath(node.internalMetaLink);
34073
+ const cleanPathname = normalizePath(pathname.split("?")[0]);
34074
+ let searchSuffix;
34075
+ if (searchParams && searchParams.length > 0) {
34076
+ searchSuffix = searchParams.startsWith("?") ? searchParams : `?${searchParams}`;
34077
+ }
34078
+ let pathnameWithSearch;
34079
+ if (searchSuffix) {
34080
+ pathnameWithSearch = `${pathname}${searchSuffix}`;
34081
+ } else if (pathname.includes("?")) {
34082
+ pathnameWithSearch = pathname;
34083
+ }
34084
+ const cleanPathnameWithSearch = normalizePath(pathnameWithSearch);
34085
+ const matched = cleanNodeInternalMetaLink === cleanPathname || cleanPathnameWithSearch && cleanNodeInternalMetaLink === cleanPathnameWithSearch ? currentPath : [];
34086
+ const tagsToMatch = tags && tags.keysAndTags && node.key ? tags.keysAndTags[typeof node.key === "string" ? node.key : String(node.key)] : void 0;
34087
+ const matchedByTags = tags && tags.currentTags && tagsToMatch && tagsToMatch.some((tag) => tags.currentTags?.includes(tag)) ? currentPath : [];
34088
+ let childrenResults = [];
34089
+ if ("children" in node && node.children) {
34090
+ childrenResults = traverse(node.children, currentPath);
34091
+ }
34092
+ return [...matched, ...matchedByTags, ...childrenResults];
34093
+ });
34094
+ return traverse(items, []);
34095
+ };
34096
+ const stripInternalMetaFromItems = (items) => items.map((item) => {
34097
+ if (!item) {
34098
+ return item;
34099
+ }
34100
+ const rest = { ...item };
34101
+ delete rest.internalMetaLink;
34102
+ if ("children" in rest && Array.isArray(rest.children)) {
34103
+ return {
34104
+ ...rest,
34105
+ children: stripInternalMetaFromItems(rest.children)
34106
+ };
34107
+ }
34108
+ return rest;
34109
+ });
34110
+ const prepareDataForManageableSidebar = ({
34111
+ data,
34112
+ replaceValues,
34113
+ multiQueryData = {},
34114
+ pathname,
34115
+ searchParams,
34116
+ idToCompare,
34117
+ fallbackIdToCompare,
34118
+ currentTags,
34119
+ resourcesListData
34120
+ }) => {
34121
+ const foundData = data.find((el) => el.id === idToCompare) || (fallbackIdToCompare ? data.find((el) => el.id === fallbackIdToCompare) : void 0);
34122
+ if (!foundData) {
34123
+ return void 0;
34124
+ }
34125
+ const preparedCurrentTags = currentTags && currentTags.length > 0 ? currentTags.map((el) => parseAll({ text: el, replaceValues, multiQueryData })) : void 0;
34126
+ const result = {
34127
+ menuItems: mapLinksFromRaw({
34128
+ rawLinks: foundData.menuItems,
34129
+ replaceValues,
34130
+ multiQueryData,
34131
+ externalKeys: foundData.externalKeys,
34132
+ resourcesListData
34133
+ })
34134
+ };
34135
+ const openedKeys = result?.menuItems ? findMatchingItems({
34136
+ items: result?.menuItems,
34137
+ pathname,
34138
+ searchParams,
34139
+ tags: { keysAndTags: foundData.keysAndTags, currentTags: preparedCurrentTags }
34140
+ }) : [];
34141
+ const stringedOpenedKeys = openedKeys.map((el) => typeof el === "string" ? el : String(el));
34142
+ return { menuItems: stripInternalMetaFromItems(result.menuItems), selectedKeys: stringedOpenedKeys };
34143
+ };
34144
+
34145
+ const ResourcesListFetcher = ({ nodePath, params, onUpdate }) => {
34146
+ const { data, isLoading } = useK8sSmartResource(params);
34147
+ useEffect(() => {
34148
+ const maybeItems = data?.items;
34149
+ const preparedItems = Array.isArray(maybeItems) ? maybeItems : [];
34150
+ onUpdate({
34151
+ nodePath,
34152
+ entry: {
34153
+ items: preparedItems,
34154
+ isLoading
34155
+ }
34156
+ });
34157
+ }, [nodePath, data?.items, isLoading, onUpdate]);
34158
+ return null;
34159
+ };
34160
+ const ManageableSidebarProvider = ({
34161
+ cluster,
34162
+ apiGroup,
34163
+ apiVersion,
34164
+ plural,
34165
+ isEnabled,
34166
+ replaceValues,
34167
+ multiQueryData,
34168
+ pathname,
34169
+ searchParams,
34170
+ idToCompare,
34171
+ fallbackIdToCompare,
34172
+ currentTags,
34173
+ hidden,
34174
+ noMarginTop
34175
+ }) => {
34176
+ const safeMultiQueryData = useMemo(() => multiQueryData || {}, [multiQueryData]);
34177
+ const {
34178
+ data: rawData,
34179
+ isError: rawDataError,
34180
+ isLoading: rawDataLoading
34181
+ } = useK8sSmartResource({
34182
+ cluster,
34183
+ apiGroup,
34184
+ apiVersion,
34185
+ plural,
34186
+ isEnabled
34187
+ });
34188
+ const parsedData = rawData?.items.map(({ spec }) => spec) || [];
34189
+ const foundData = parsedData.find((el) => el.id === idToCompare) || (fallbackIdToCompare ? parsedData.find((el) => el.id === fallbackIdToCompare) : void 0);
34190
+ const linksWithResourcesList = useMemo(
34191
+ () => collectLinksWithResourcesList({
34192
+ items: foundData?.menuItems || [],
34193
+ replaceValues,
34194
+ multiQueryData: safeMultiQueryData,
34195
+ isEnabled
34196
+ }),
34197
+ [foundData?.menuItems, replaceValues, safeMultiQueryData, isEnabled]
34198
+ );
34199
+ const [resourcesByPath, setResourcesByPath] = useState({});
34200
+ useEffect(() => {
34201
+ setResourcesByPath((prev) => {
34202
+ const next = linksWithResourcesList.reduce(
34203
+ (acc, { nodePath, k8sParams }) => {
34204
+ acc[nodePath] = prev[nodePath] || { items: [], isLoading: Boolean(k8sParams.isEnabled) };
34205
+ return acc;
34206
+ },
34207
+ {}
34208
+ );
34209
+ return next;
34210
+ });
34211
+ }, [linksWithResourcesList]);
34212
+ const handleResourceUpdate = useCallback(({ nodePath, entry }) => {
34213
+ setResourcesByPath((prev) => {
34214
+ const previous = prev[nodePath];
34215
+ if (previous && previous.items === entry.items && previous.isLoading === entry.isLoading) {
34216
+ return prev;
34217
+ }
34218
+ return { ...prev, [nodePath]: entry };
34219
+ });
34220
+ }, []);
34221
+ const isResourcesLoading = linksWithResourcesList.some(({ nodePath, k8sParams }) => {
34222
+ if (!k8sParams.isEnabled) {
34223
+ return false;
34224
+ }
34225
+ return resourcesByPath[nodePath]?.isLoading !== false;
34226
+ });
34227
+ if (isResourcesLoading) {
34228
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
34229
+ linksWithResourcesList.map(({ nodePath, k8sParams }) => /* @__PURE__ */ jsxRuntimeExports.jsx(ResourcesListFetcher, { nodePath, params: k8sParams, onUpdate: handleResourceUpdate }, nodePath)),
34230
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Spin, {})
34231
+ ] });
34232
+ }
34233
+ if (rawDataError) {
34234
+ return null;
34235
+ }
34236
+ if (rawDataLoading) {
34237
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Spin, {});
34238
+ }
34239
+ if (!rawData) {
34240
+ return null;
34241
+ }
34242
+ if (hidden) {
34243
+ return null;
34244
+ }
34245
+ if (!parsedData || parsedData.length === 0) {
34246
+ return null;
34247
+ }
34248
+ if (!foundData) {
34249
+ return null;
34250
+ }
34251
+ const resourcesListData = linksWithResourcesList.reduce(
34252
+ (acc, { nodePath }) => {
34253
+ const result2 = resourcesByPath[nodePath];
34254
+ acc[nodePath] = {
34255
+ items: Array.isArray(result2?.items) ? result2.items : []
34256
+ };
34257
+ return acc;
34258
+ },
34259
+ {}
34260
+ );
34261
+ const result = prepareDataForManageableSidebar({
34262
+ data: parsedData,
34263
+ replaceValues,
34264
+ multiQueryData: safeMultiQueryData,
34265
+ pathname,
34266
+ searchParams,
34267
+ idToCompare,
34268
+ fallbackIdToCompare,
34269
+ currentTags,
34270
+ resourcesListData
34271
+ });
34272
+ if (!result) {
34273
+ return null;
34274
+ }
34275
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
34276
+ linksWithResourcesList.map(({ nodePath, k8sParams }) => /* @__PURE__ */ jsxRuntimeExports.jsx(ResourcesListFetcher, { nodePath, params: k8sParams, onUpdate: handleResourceUpdate }, nodePath)),
34277
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ManageableSidebar, { data: result, noMarginTop })
34278
+ ] });
34279
+ };
34280
+
33883
34281
  const ShortenedText = styled.div`
33884
34282
  max-width: ${({ $maxWidth }) => $maxWidth}px;
33885
34283
  overflow: hidden;
33886
34284
  white-space: nowrap;
33887
34285
  text-overflow: ellipsis;
33888
34286
  `;
33889
- const Styled$y = {
34287
+ const Styled$z = {
33890
34288
  ShortenedText
33891
34289
  };
33892
34290
 
@@ -33895,7 +34293,7 @@ const ShortenedTextWithTooltip = ({ text, trimLength, maxWidth = 200 }) => {
33895
34293
  const trimmedText = text.substring(0, trimLength);
33896
34294
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip$1, { title: text, placement: "top", children: trimmedText });
33897
34295
  }
33898
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip$1, { title: text, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$y.ShortenedText, { $maxWidth: maxWidth, children: text }) });
34296
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip$1, { title: text, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$z.ShortenedText, { $maxWidth: maxWidth, children: text }) });
33899
34297
  };
33900
34298
 
33901
34299
  const FilterDropdown = ({
@@ -34526,139 +34924,22 @@ const partsOfUrlContext = createContextFactory();
34526
34924
  const PartsOfUrlProvider = partsOfUrlContext.Provider;
34527
34925
  const usePartsOfUrl = partsOfUrlContext.useTypedContext;
34528
34926
 
34529
- const parsePartsOfUrl = ({
34530
- template,
34531
- replaceValues
34532
- }) => {
34533
- return prepareTemplate({ template, replaceValues });
34534
- };
34535
- const parseMutliqueryText = ({
34536
- text,
34537
- multiQueryData,
34538
- customFallback
34539
- }) => {
34540
- if (!text) {
34541
- return "";
34927
+ const isExternalHref = (href) => {
34928
+ if (!href) {
34929
+ return false;
34542
34930
  }
34543
- return text.replace(
34544
- /\{reqs\[(\d+)\]\[((?:\s*['"][^'"]+['"]\s*,?)+)\](?:\[\s*['"]([^'"]+)['"]\s*\])?\}/g,
34545
- (_match, reqIndexStr, rawPath, fallback) => {
34546
- try {
34547
- const reqIndex = parseInt(reqIndexStr, 10);
34548
- const path = Array.from(rawPath.matchAll(/['"]([^'"]+)['"]/g)).map(
34549
- (m) => m[1]
34550
- );
34551
- const value = _$1.get(multiQueryData[`req${reqIndex}`] || {}, path, fallback !== void 0 ? fallback : void 0);
34552
- if (value == null && !customFallback) {
34553
- return fallback ?? "Undefined with no fallback";
34554
- }
34555
- if (customFallback && (value === void 0 || value === null)) {
34556
- return customFallback;
34557
- }
34558
- return String(value);
34559
- } catch {
34560
- return _match;
34561
- }
34562
- }
34563
- );
34564
- };
34565
- const parseJsonPathTemplate = ({
34566
- text,
34567
- multiQueryData,
34568
- customFallback,
34569
- replaceValues
34570
- }) => {
34571
- if (!text) return "";
34572
- const placeholderRegex = /\{reqsJsonPath\[(\d+)\]\s*\[\s*(['"])([\s\S]*?)\2\s*\](?:\s*\[\s*(['"])([\s\S]*?)\4\s*\])?\}/g;
34573
- const resolve = (input) => input.replace(
34574
- placeholderRegex,
34575
- (match, reqIndexStr, _quote, rawJsonPathExpr, _fallbackQuote, inlineFallback = "Undefined with no fallback") => {
34576
- try {
34577
- const reqIndex = Number(reqIndexStr);
34578
- const jsonRoot = multiQueryData[`req${reqIndex}`];
34579
- let jsonPathExpr = rawJsonPathExpr;
34580
- let previous2 = null;
34581
- let loopGuard = 0;
34582
- while (previous2 !== jsonPathExpr && loopGuard < 10) {
34583
- previous2 = jsonPathExpr;
34584
- jsonPathExpr = resolve(jsonPathExpr);
34585
- loopGuard++;
34586
- }
34587
- if (replaceValues) {
34588
- jsonPathExpr = prepareTemplate({
34589
- template: jsonPathExpr,
34590
- replaceValues
34591
- });
34592
- }
34593
- if (jsonRoot === void 0 && customFallback) return customFallback;
34594
- if (jsonRoot === void 0) return inlineFallback;
34595
- const results = jp.query(jsonRoot, `$${jsonPathExpr}`);
34596
- const value = results?.[0];
34597
- if (value == null) {
34598
- return customFallback ?? inlineFallback;
34599
- }
34600
- return String(value);
34601
- } catch {
34602
- return match;
34603
- }
34604
- }
34605
- );
34606
- let result = text;
34607
- let previous = null;
34608
- let iterations = 0;
34609
- while (result !== previous && iterations < 10) {
34610
- previous = result;
34611
- result = resolve(result);
34612
- iterations++;
34931
+ if (/^(mailto:|tel:|sms:)/i.test(href)) {
34932
+ return true;
34933
+ }
34934
+ if (href.startsWith("//")) {
34935
+ return true;
34936
+ }
34937
+ try {
34938
+ const parsed = new URL(href, window.location.origin);
34939
+ return parsed.origin !== window.location.origin;
34940
+ } catch {
34941
+ return false;
34613
34942
  }
34614
- return result;
34615
- };
34616
- const parseWithoutPartsOfUrl = ({
34617
- text,
34618
- multiQueryData,
34619
- customFallback
34620
- }) => {
34621
- return parseJsonPathTemplate({
34622
- text: parseMutliqueryText({
34623
- text,
34624
- multiQueryData,
34625
- customFallback
34626
- }),
34627
- multiQueryData,
34628
- customFallback
34629
- });
34630
- };
34631
- const parseAll = ({
34632
- text,
34633
- replaceValues,
34634
- multiQueryData
34635
- }) => {
34636
- return parsePartsOfUrl({
34637
- template: parseJsonPathTemplate({
34638
- text: parseMutliqueryText({
34639
- text,
34640
- multiQueryData
34641
- }),
34642
- multiQueryData,
34643
- replaceValues
34644
- }),
34645
- replaceValues
34646
- });
34647
- };
34648
- const parsePromTemplate = ({
34649
- text,
34650
- replaceValues,
34651
- multiQueryData
34652
- }) => {
34653
- const parsed = parseJsonPathTemplate({
34654
- text: parseMutliqueryText({
34655
- text,
34656
- multiQueryData
34657
- }),
34658
- multiQueryData,
34659
- replaceValues
34660
- });
34661
- return parsed.replace(/\{(\d+)\}/g, (_2, key) => replaceValues[key] || "");
34662
34943
  };
34663
34944
 
34664
34945
  const AntdLink = ({
@@ -34675,6 +34956,7 @@ const AntdLink = ({
34675
34956
  }, {});
34676
34957
  const textPrepared = parseAll({ text, replaceValues, multiQueryData });
34677
34958
  const hrefPrepared = parseAll({ text: href, replaceValues, multiQueryData });
34959
+ const isExternal = isExternalHref(hrefPrepared);
34678
34960
  if (isMultiqueryLoading) {
34679
34961
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading multiquery" });
34680
34962
  }
@@ -34683,6 +34965,9 @@ const AntdLink = ({
34683
34965
  {
34684
34966
  href: hrefPrepared,
34685
34967
  onClick: (e) => {
34968
+ if (isExternal) {
34969
+ return;
34970
+ }
34686
34971
  e.preventDefault();
34687
34972
  navigate(hrefPrepared);
34688
34973
  },
@@ -34922,7 +35207,7 @@ const getResult = ({
34922
35207
  valuesPrepared,
34923
35208
  criteriaSuccess,
34924
35209
  criteriaError,
34925
- stategySuccess,
35210
+ strategySuccess,
34926
35211
  strategyError,
34927
35212
  valueToCompareSuccess,
34928
35213
  valueToCompareError,
@@ -34931,7 +35216,7 @@ const getResult = ({
34931
35216
  fallbackText
34932
35217
  }) => {
34933
35218
  let success = false;
34934
- if (stategySuccess === "some") {
35219
+ if (strategySuccess === "some") {
34935
35220
  success = criteriaSuccess === "equals" ? valuesPrepared.some((v) => valueToCompareSuccess.includes(v)) : valuesPrepared.some((v) => !valueToCompareSuccess.includes(v));
34936
35221
  } else {
34937
35222
  success = criteriaSuccess === "equals" ? valuesPrepared.every((v) => valueToCompareSuccess.includes(v)) : valuesPrepared.every((v) => !valueToCompareSuccess.includes(v));
@@ -34961,7 +35246,7 @@ const StatusText$1 = ({
34961
35246
  values,
34962
35247
  criteriaSuccess,
34963
35248
  criteriaError,
34964
- stategySuccess,
35249
+ strategySuccess,
34965
35250
  strategyError,
34966
35251
  valueToCompareSuccess,
34967
35252
  valueToCompareError,
@@ -34993,7 +35278,7 @@ const StatusText$1 = ({
34993
35278
  valuesPrepared,
34994
35279
  criteriaSuccess,
34995
35280
  criteriaError,
34996
- stategySuccess,
35281
+ strategySuccess,
34997
35282
  strategyError,
34998
35283
  valueToCompareSuccess,
34999
35284
  valueToCompareError,
@@ -35032,6 +35317,7 @@ const checkPermission = async ({
35032
35317
  resourceAttributes: {
35033
35318
  ...body.apiGroup ? { group: body.apiGroup } : {},
35034
35319
  resource: body.plural,
35320
+ ...body.subresource ? { subresource: body.subresource } : {},
35035
35321
  verb: body.verb,
35036
35322
  ...body.namespace ? { namespace: body.namespace } : {},
35037
35323
  ...body.name ? { name: body.name } : {}
@@ -35051,24 +35337,26 @@ const usePermissions = ({
35051
35337
  namespace,
35052
35338
  apiGroup,
35053
35339
  plural,
35340
+ subresource,
35054
35341
  verb,
35055
35342
  name,
35056
35343
  refetchInterval,
35057
35344
  enabler
35058
35345
  }) => {
35059
35346
  return useQuery({
35060
- queryKey: ["usePermissions", cluster, namespace, apiGroup, plural, verb, name],
35347
+ queryKey: ["usePermissions", cluster, namespace, apiGroup, plural, subresource, verb, name],
35061
35348
  queryFn: async () => (await checkPermission({
35062
35349
  cluster,
35063
35350
  body: {
35064
35351
  namespace,
35065
35352
  apiGroup,
35066
35353
  plural,
35354
+ subresource,
35067
35355
  verb
35068
35356
  }
35069
35357
  })).data,
35070
35358
  refetchInterval: refetchInterval !== void 0 ? refetchInterval : 5e3,
35071
- enabled: enabler || true
35359
+ enabled: enabler ?? true
35072
35360
  });
35073
35361
  };
35074
35362
 
@@ -35133,6 +35421,15 @@ const serializeLabelsWithNoEncoding$1 = (input) => {
35133
35421
  return entries.map(([k, v]) => `${k}=${v}`).join(",");
35134
35422
  };
35135
35423
 
35424
+ const isValidLabelSelectorObject = (input) => {
35425
+ if (typeof input !== "object" || input === null || Array.isArray(input) || Object.getPrototypeOf(input) !== Object.prototype) {
35426
+ return false;
35427
+ }
35428
+ const entries = Object.entries(input);
35429
+ if (entries.length === 0) return false;
35430
+ return entries.every(([, value]) => typeof value === "string" || typeof value === "number");
35431
+ };
35432
+
35136
35433
  const EnrichedTable$1 = ({
35137
35434
  data,
35138
35435
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -35193,7 +35490,8 @@ const EnrichedTable$1 = ({
35193
35490
  namespace: namespacePrepared,
35194
35491
  cluster: clusterPrepared,
35195
35492
  verb: "create",
35196
- refetchInterval: false
35493
+ refetchInterval: false,
35494
+ enabler: Boolean(dataForControlsPrepared && clusterPrepared && !isMultiqueryLoading)
35197
35495
  });
35198
35496
  const fetchUrlPrepared = fetchUrl ? parseAll({ text: fetchUrl, replaceValues, multiQueryData }) : void 0;
35199
35497
  const k8sResourceToFetchPrepared = k8sResourceToFetch ? {
@@ -35215,8 +35513,10 @@ const EnrichedTable$1 = ({
35215
35513
  if (labelSelectorFull) {
35216
35514
  const root = multiQueryData[`req${labelSelectorFull.reqIndex}`];
35217
35515
  const value = Array.isArray(labelSelectorFull.pathToLabels) ? _$1.get(root || {}, labelSelectorFull.pathToLabels) : jp.query(root || {}, `$${labelSelectorFull.pathToLabels}`)[0];
35218
- const serializedLabels = serializeLabelsWithNoEncoding$1(value);
35219
- if (serializedLabels.length > 0) sParams.set("labelSelector", serializedLabels);
35516
+ if (isValidLabelSelectorObject(value)) {
35517
+ const serializedLabels = serializeLabelsWithNoEncoding$1(value);
35518
+ if (serializedLabels.length > 0) sParams.set("labelSelector", serializedLabels);
35519
+ }
35220
35520
  }
35221
35521
  if (fieldSelector) {
35222
35522
  const parsedObject = Object.fromEntries(
@@ -43118,12 +43418,42 @@ const BigText$1 = styled.div`
43118
43418
  font-size: 16px;
43119
43419
  line-height: 24px;
43120
43420
  `;
43121
- const Styled$x = {
43421
+ const Styled$y = {
43122
43422
  BorderRadiusContainer: BorderRadiusContainer$1,
43123
43423
  ControlsRowContainer: ControlsRowContainer$1,
43124
43424
  BigText: BigText$1
43125
43425
  };
43126
43426
 
43427
+ const findManagedFieldsLine = (model) => {
43428
+ let inMetadata = false;
43429
+ let metadataIndent = -1;
43430
+ for (let lineNumber = 1; lineNumber <= model.getLineCount(); lineNumber++) {
43431
+ const line = model.getLineContent(lineNumber);
43432
+ const trimmed = line.trim();
43433
+ const indent = line.match(/^\s*/)?.[0].length ?? 0;
43434
+ if (!inMetadata && /^metadata\s*:\s*$/.test(trimmed)) {
43435
+ inMetadata = true;
43436
+ metadataIndent = indent;
43437
+ } else if (inMetadata) {
43438
+ if (trimmed && indent <= metadataIndent) {
43439
+ inMetadata = false;
43440
+ } else if (/^managedFields\s*:\s*$/.test(trimmed)) {
43441
+ return lineNumber;
43442
+ }
43443
+ }
43444
+ }
43445
+ return null;
43446
+ };
43447
+ const collapseManagedFieldsInEditor = (editor) => {
43448
+ const model = editor.getModel();
43449
+ if (!model) return;
43450
+ const managedFieldsLine = findManagedFieldsLine(model);
43451
+ if (managedFieldsLine === null) return;
43452
+ if (managedFieldsLine >= model.getLineCount()) return;
43453
+ editor.setPosition({ lineNumber: managedFieldsLine, column: 1 });
43454
+ editor.trigger("managed-fields-collapse", "editor.fold", null);
43455
+ };
43456
+
43127
43457
  const NOTIFICATION_KEY = "yaml-data-changed";
43128
43458
  const YamlEditorSingleton$1 = ({
43129
43459
  theme: theme$1,
@@ -43138,7 +43468,8 @@ const YamlEditorSingleton$1 = ({
43138
43468
  designNewLayout,
43139
43469
  designNewLayoutHeight,
43140
43470
  openNotification,
43141
- readOnly = false
43471
+ readOnly = false,
43472
+ canEdit
43142
43473
  }) => {
43143
43474
  const { token } = theme.useToken();
43144
43475
  const navigate = useNavigate();
@@ -43149,6 +43480,12 @@ const YamlEditorSingleton$1 = ({
43149
43480
  const initialPrefillYamlRef = useRef(null);
43150
43481
  const latestPrefillYamlRef = useRef(null);
43151
43482
  const firstLoadRef = useRef(true);
43483
+ const editorRef = useRef(null);
43484
+ const collapseManagedFieldsIfNeeded = useCallback(() => {
43485
+ const editor = editorRef.current;
43486
+ if (!editor) return;
43487
+ collapseManagedFieldsInEditor(editor);
43488
+ }, []);
43152
43489
  const handleReload = useCallback(() => {
43153
43490
  api.destroy(NOTIFICATION_KEY);
43154
43491
  const nextYaml = latestPrefillYamlRef.current ?? initialPrefillYamlRef.current;
@@ -43192,6 +43529,12 @@ const YamlEditorSingleton$1 = ({
43192
43529
  }
43193
43530
  latestPrefillYamlRef.current = nextYaml;
43194
43531
  }, [prefillValuesSchema, openNotificationYamlChanged]);
43532
+ useEffect(() => {
43533
+ const id = setTimeout(() => {
43534
+ collapseManagedFieldsIfNeeded();
43535
+ }, 0);
43536
+ return () => clearTimeout(id);
43537
+ }, [yamlData, collapseManagedFieldsIfNeeded]);
43195
43538
  const onSubmit = () => {
43196
43539
  setIsLoading(true);
43197
43540
  setError(void 0);
@@ -43242,13 +43585,19 @@ const YamlEditorSingleton$1 = ({
43242
43585
  };
43243
43586
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
43244
43587
  contextHolder,
43245
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$x.BorderRadiusContainer, { $designNewLayoutHeight: designNewLayoutHeight, $colorBorder: token.colorBorder, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
43588
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$y.BorderRadiusContainer, { $designNewLayoutHeight: designNewLayoutHeight, $colorBorder: token.colorBorder, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
43246
43589
  Ft$1,
43247
43590
  {
43248
43591
  defaultLanguage: "yaml",
43249
43592
  width: "100%",
43250
43593
  height: designNewLayoutHeight || "75vh",
43251
43594
  value: yamlData,
43595
+ onMount: (editor) => {
43596
+ editorRef.current = editor;
43597
+ setTimeout(() => {
43598
+ collapseManagedFieldsIfNeeded();
43599
+ }, 0);
43600
+ },
43252
43601
  onChange: (value) => {
43253
43602
  if (!readOnly) {
43254
43603
  setYamlData(value || "");
@@ -43261,8 +43610,8 @@ const YamlEditorSingleton$1 = ({
43261
43610
  }
43262
43611
  }
43263
43612
  ) }),
43264
- !readOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$x.ControlsRowContainer, { $bgColor: token.colorPrimaryBg, $designNewLayout: designNewLayout, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { gap: designNewLayout ? 10 : 16, align: "center", children: [
43265
- /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "primary", onClick: onSubmit, loading: isLoading, children: "Submit" }),
43613
+ !readOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$y.ControlsRowContainer, { $bgColor: token.colorPrimaryBg, $designNewLayout: designNewLayout, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { gap: designNewLayout ? 10 : 16, align: "center", children: [
43614
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "primary", onClick: onSubmit, loading: isLoading, disabled: canEdit === false, children: "Submit" }),
43266
43615
  backlink && /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: () => navigate(backlink), children: "Cancel" }),
43267
43616
  /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: handleReload, children: "Reload" })
43268
43617
  ] }) }),
@@ -43272,8 +43621,9 @@ const YamlEditorSingleton$1 = ({
43272
43621
  open: !!error,
43273
43622
  onOk: () => setError(void 0),
43274
43623
  onCancel: () => setError(void 0),
43275
- title: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography.Text, { type: "danger", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$x.BigText, { children: "Error!" }) }),
43624
+ title: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography.Text, { type: "danger", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$y.BigText, { children: "Error!" }) }),
43276
43625
  cancelButtonProps: { style: { display: "none" } },
43626
+ centered: true,
43277
43627
  children: [
43278
43628
  "An error has occurred: ",
43279
43629
  error?.response?.data?.message
@@ -43295,23 +43645,35 @@ const getPrefillValuesWithForces = ({
43295
43645
  apiGroup,
43296
43646
  apiVersion
43297
43647
  }) => {
43298
- if (!forcedKind) {
43648
+ if (typeof prefillValues !== "object" || prefillValues === null) {
43299
43649
  return prefillValues;
43300
43650
  }
43301
43651
  const newValues = { ...prefillValues };
43302
- if (typeof newValues === "object" && newValues !== null) {
43652
+ if (forcedKind) {
43303
43653
  if ("kind" in newValues) {
43304
43654
  delete newValues.kind;
43305
43655
  }
43306
43656
  if ("apiVersion" in newValues) {
43307
43657
  delete newValues.apiVersion;
43308
43658
  }
43659
+ newValues.kind = forcedKind;
43660
+ if (apiVersion) {
43661
+ newValues.apiVersion = `${apiGroup ? `${apiGroup}/` : ""}${apiVersion}`;
43662
+ }
43309
43663
  }
43310
- return {
43311
- kind: forcedKind,
43312
- apiVersion: `${apiGroup ? `${apiGroup}/` : ""}${apiVersion}`,
43313
- ...newValues
43314
- };
43664
+ const orderedValues = {};
43665
+ if ("kind" in newValues) {
43666
+ orderedValues.kind = newValues.kind;
43667
+ }
43668
+ if ("apiVersion" in newValues) {
43669
+ orderedValues.apiVersion = newValues.apiVersion;
43670
+ }
43671
+ Object.keys(newValues).forEach((key) => {
43672
+ if (key !== "kind" && key !== "apiVersion") {
43673
+ orderedValues[key] = newValues[key];
43674
+ }
43675
+ });
43676
+ return orderedValues;
43315
43677
  };
43316
43678
 
43317
43679
  const YamlEditorSingleton = ({
@@ -43333,6 +43695,8 @@ const YamlEditorSingleton = ({
43333
43695
  prefillValuesRequestIndex,
43334
43696
  pathToData,
43335
43697
  substractHeight,
43698
+ permissions,
43699
+ permissionContext,
43336
43700
  ...props
43337
43701
  } = data;
43338
43702
  const [height, setHeight] = useState(0);
@@ -43353,6 +43717,26 @@ const YamlEditorSingleton = ({
43353
43717
  acc[index.toString()] = value;
43354
43718
  return acc;
43355
43719
  }, {});
43720
+ const safeMultiQueryData = multiQueryData || {};
43721
+ const permissionContextPrepared = permissionContext ? {
43722
+ cluster: parseAll({ text: permissionContext.cluster, replaceValues, multiQueryData: safeMultiQueryData }),
43723
+ namespace: permissionContext.namespace ? parseAll({ text: permissionContext.namespace, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
43724
+ apiGroup: permissionContext.apiGroup ? parseAll({ text: permissionContext.apiGroup, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
43725
+ plural: parseAll({ text: permissionContext.plural, replaceValues, multiQueryData: safeMultiQueryData })
43726
+ } : void 0;
43727
+ const isPermissionContextValid = !!permissionContextPrepared && !isMultiqueryLoading && !!permissionContextPrepared.cluster && permissionContextPrepared.cluster !== "-" && !!permissionContextPrepared.plural && permissionContextPrepared.plural !== "-";
43728
+ const updatePermission = usePermissions({
43729
+ cluster: permissionContextPrepared?.cluster || "",
43730
+ namespace: permissionContextPrepared?.namespace,
43731
+ apiGroup: permissionContextPrepared?.apiGroup,
43732
+ plural: permissionContextPrepared?.plural || "",
43733
+ verb: "update",
43734
+ refetchInterval: false,
43735
+ enabler: isPermissionContextValid
43736
+ });
43737
+ const canUpdate = permissions?.canUpdate ?? updatePermission.data?.status.allowed;
43738
+ const shouldGateEdit = Boolean(permissions || permissionContext);
43739
+ const canEdit = !shouldGateEdit || canUpdate === true;
43356
43740
  const clusterPrepared = parseAll({ text: cluster, replaceValues, multiQueryData });
43357
43741
  const apiGroupPrepared = apiGroup ? parseAll({ text: apiGroup, replaceValues, multiQueryData }) : "no-api-group";
43358
43742
  const apiVersionPrepared = apiVersion ? parseAll({ text: apiVersion, replaceValues, multiQueryData }) : "no-api-version";
@@ -43378,6 +43762,7 @@ const YamlEditorSingleton = ({
43378
43762
  designNewLayout: true,
43379
43763
  designNewLayoutHeight: height,
43380
43764
  openNotification: true,
43765
+ canEdit,
43381
43766
  ...props
43382
43767
  }
43383
43768
  ),
@@ -43388,7 +43773,7 @@ const YamlEditorSingleton = ({
43388
43773
  const VisibilityContainer$1 = styled.div`
43389
43774
  display: ${({ $hidden }) => $hidden ? "none" : "block"};
43390
43775
  `;
43391
- const Styled$w = {
43776
+ const Styled$x = {
43392
43777
  VisibilityContainer: VisibilityContainer$1
43393
43778
  };
43394
43779
 
@@ -43434,7 +43819,7 @@ const VisibilityContainer = ({
43434
43819
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading multiquery" });
43435
43820
  }
43436
43821
  const shouldAutoHide = !criteria && (!valuePrepared || valuePrepared === "~undefined-value~");
43437
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$w.VisibilityContainer, { $hidden: shouldAutoHide || shouldHideByCriteria, children });
43822
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$x.VisibilityContainer, { $hidden: shouldAutoHide || shouldHideByCriteria, children });
43438
43823
  };
43439
43824
 
43440
43825
  const unknownToString = (value) => {
@@ -43699,7 +44084,7 @@ const Content$1 = styled.div`
43699
44084
  display: ${({ $isOpen }) => $isOpen ? "block" : "none"};
43700
44085
  padding: ${({ $designNewLayout }) => $designNewLayout ? "0 0 0 6px" : "4px"};
43701
44086
  `;
43702
- const Styled$v = {
44087
+ const Styled$w = {
43703
44088
  Container: Container$3,
43704
44089
  TitleBar,
43705
44090
  Content: Content$1
@@ -43726,14 +44111,14 @@ const CustomCollapse = ({
43726
44111
  }
43727
44112
  };
43728
44113
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
43729
- Styled$v.Container,
44114
+ Styled$w.Container,
43730
44115
  {
43731
44116
  $designNewLayout: designNewLayout,
43732
44117
  $borderColor: token.colorBorder,
43733
44118
  $bgColor: token.colorBgContainer,
43734
44119
  children: [
43735
44120
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { justify: "space-between", children: [
43736
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$v.TitleBar, { onClick: () => toggleCollapse(), children: [
44121
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$w.TitleBar, { onClick: () => toggleCollapse(), children: [
43737
44122
  !designNewLayout && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: isOpen ? /* @__PURE__ */ jsxRuntimeExports.jsx(CaretDownOutlined, { size: 14 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(CaretRightOutlined, { size: 14 }) }),
43738
44123
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: title }),
43739
44124
  designNewLayout && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: isOpen ? /* @__PURE__ */ jsxRuntimeExports.jsx(DownIcon, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(UpIcon, {}) })
@@ -43744,7 +44129,7 @@ const CustomCollapse = ({
43744
44129
  persistedCheckbox
43745
44130
  ] })
43746
44131
  ] }),
43747
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$v.Content, { $isOpen: isOpen, $designNewLayout: designNewLayout, children })
44132
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$w.Content, { $isOpen: isOpen, $designNewLayout: designNewLayout, children })
43748
44133
  ]
43749
44134
  }
43750
44135
  );
@@ -43778,13 +44163,13 @@ const CustomSizeTitle = styled.div`
43778
44163
  const Content = styled.div`
43779
44164
  padding: ${({ $designNewLayout }) => $designNewLayout ? "0 0 0 6px" : "4px"};
43780
44165
  `;
43781
- const Styled$u = {
44166
+ const Styled$v = {
43782
44167
  Content
43783
44168
  };
43784
44169
 
43785
44170
  const ArrayInsideContainer = ({ children }) => {
43786
44171
  const designNewLayout = useDesignNewLayout();
43787
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$u.Content, { $designNewLayout: designNewLayout, children });
44172
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$v.Content, { $designNewLayout: designNewLayout, children });
43788
44173
  };
43789
44174
 
43790
44175
  const includesPath = (haystack, needle) => haystack.some((h) => h.length === needle.length && h.every((seg, i) => seg === String(needle[i])));
@@ -43820,6 +44205,7 @@ const LabelsEditModal = ({
43820
44205
  close,
43821
44206
  values,
43822
44207
  openNotificationSuccess,
44208
+ disableSubmit,
43823
44209
  modalTitle,
43824
44210
  modalDescriptionText,
43825
44211
  inputLabel,
@@ -43881,6 +44267,7 @@ const LabelsEditModal = ({
43881
44267
  setError(void 0);
43882
44268
  },
43883
44269
  okText: "Save",
44270
+ okButtonProps: { disabled: disableSubmit },
43884
44271
  confirmLoading: isLoading,
43885
44272
  maskClosable: false,
43886
44273
  width: editModalWidth || 520,
@@ -43947,7 +44334,7 @@ const LabelsEditModal = ({
43947
44334
  const ResetedFormList$3 = styled(Form.List)`
43948
44335
  margin-bottom: 8px;
43949
44336
  `;
43950
- const Styled$t = {
44337
+ const Styled$u = {
43951
44338
  ResetedFormList: ResetedFormList$3
43952
44339
  };
43953
44340
 
@@ -43956,6 +44343,7 @@ const TaintsEditModal = ({
43956
44343
  close,
43957
44344
  values,
43958
44345
  openNotificationSuccess,
44346
+ disableSubmit,
43959
44347
  modalTitle,
43960
44348
  modalDescriptionText,
43961
44349
  inputLabel,
@@ -44011,6 +44399,7 @@ const TaintsEditModal = ({
44011
44399
  setError(void 0);
44012
44400
  },
44013
44401
  okText: "Save",
44402
+ okButtonProps: { disabled: disableSubmit },
44014
44403
  confirmLoading: isLoading,
44015
44404
  maskClosable: false,
44016
44405
  width: editModalWidth || 520,
@@ -44032,7 +44421,7 @@ const TaintsEditModal = ({
44032
44421
  /* @__PURE__ */ jsxRuntimeExports.jsx(Col, { span: cols[3], children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", {}) })
44033
44422
  ] }),
44034
44423
  /* @__PURE__ */ jsxRuntimeExports.jsx(Spacer$1, { $space: 10, $samespace: true }),
44035
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$t.ResetedFormList, { name: "taints", children: (fields, { add, remove }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
44424
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$u.ResetedFormList, { name: "taints", children: (fields, { add, remove }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
44036
44425
  fields.map(({ key, name, ...restField }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(Row, { gutter: [16, 16], children: [
44037
44426
  /* @__PURE__ */ jsxRuntimeExports.jsx(Col, { span: cols[0], children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44038
44427
  ResetedFormItem$1,
@@ -44093,7 +44482,7 @@ const TaintsEditModal = ({
44093
44482
  const ResetedFormList$2 = styled(Form.List)`
44094
44483
  margin-bottom: 8px;
44095
44484
  `;
44096
- const Styled$s = {
44485
+ const Styled$t = {
44097
44486
  ResetedFormList: ResetedFormList$2
44098
44487
  };
44099
44488
 
@@ -44102,6 +44491,7 @@ const TolerationsEditModal = ({
44102
44491
  close,
44103
44492
  values,
44104
44493
  openNotificationSuccess,
44494
+ disableSubmit,
44105
44495
  modalTitle,
44106
44496
  modalDescriptionText,
44107
44497
  inputLabel,
@@ -44158,6 +44548,7 @@ const TolerationsEditModal = ({
44158
44548
  setError(void 0);
44159
44549
  },
44160
44550
  okText: "Save",
44551
+ okButtonProps: { disabled: disableSubmit },
44161
44552
  confirmLoading: isLoading,
44162
44553
  maskClosable: false,
44163
44554
  width: editModalWidth || 520,
@@ -44188,7 +44579,7 @@ const TolerationsEditModal = ({
44188
44579
  /* @__PURE__ */ jsxRuntimeExports.jsx(Col, { span: cols[4], children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", {}) })
44189
44580
  ] }),
44190
44581
  /* @__PURE__ */ jsxRuntimeExports.jsx(Spacer$1, { $space: 10, $samespace: true }),
44191
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$s.ResetedFormList, { name: "tolerations", children: (fields, { add, remove }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
44582
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$t.ResetedFormList, { name: "tolerations", children: (fields, { add, remove }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
44192
44583
  fields.map(({ key, name, ...restField }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(Row, { gutter: [16, 16], children: [
44193
44584
  /* @__PURE__ */ jsxRuntimeExports.jsx(Col, { span: cols[0], children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44194
44585
  ResetedFormItem$1,
@@ -44280,7 +44671,7 @@ const TolerationsEditModal = ({
44280
44671
  const ResetedFormList$1 = styled(Form.List)`
44281
44672
  margin-bottom: 8px;
44282
44673
  `;
44283
- const Styled$r = {
44674
+ const Styled$s = {
44284
44675
  ResetedFormList: ResetedFormList$1
44285
44676
  };
44286
44677
 
@@ -44289,6 +44680,7 @@ const AnnotationsEditModal = ({
44289
44680
  close,
44290
44681
  values,
44291
44682
  openNotificationSuccess,
44683
+ disableSubmit,
44292
44684
  modalTitle,
44293
44685
  modalDescriptionText,
44294
44686
  inputLabel,
@@ -44350,6 +44742,7 @@ const AnnotationsEditModal = ({
44350
44742
  setError(void 0);
44351
44743
  },
44352
44744
  okText: "Save",
44745
+ okButtonProps: { disabled: disableSubmit },
44353
44746
  confirmLoading: isLoading,
44354
44747
  maskClosable: false,
44355
44748
  width: editModalWidth || 520,
@@ -44370,7 +44763,7 @@ const AnnotationsEditModal = ({
44370
44763
  /* @__PURE__ */ jsxRuntimeExports.jsx(Col, { span: cols[2], children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", {}) })
44371
44764
  ] }),
44372
44765
  /* @__PURE__ */ jsxRuntimeExports.jsx(Spacer$1, { $space: 10, $samespace: true }),
44373
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$r.ResetedFormList, { name: "annotations", children: (fields, { add, remove }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
44766
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$s.ResetedFormList, { name: "annotations", children: (fields, { add, remove }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
44374
44767
  fields.map(({ key, name, ...restField }) => /* @__PURE__ */ jsxRuntimeExports.jsxs(Row, { gutter: [16, 16], children: [
44375
44768
  /* @__PURE__ */ jsxRuntimeExports.jsx(Col, { span: cols[0], children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44376
44769
  ResetedFormItem$1,
@@ -44392,6 +44785,39 @@ const AnnotationsEditModal = ({
44392
44785
  );
44393
44786
  };
44394
44787
 
44788
+ const ReadOnlyModal = ({
44789
+ open,
44790
+ close,
44791
+ modalTitle,
44792
+ modalDescriptionText,
44793
+ modalDescriptionTextStyle,
44794
+ editModalWidth,
44795
+ children
44796
+ }) => {
44797
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
44798
+ Modal,
44799
+ {
44800
+ title: modalTitle,
44801
+ open,
44802
+ okButtonProps: { style: { display: "none" } },
44803
+ onCancel: () => {
44804
+ close();
44805
+ },
44806
+ maskClosable: false,
44807
+ width: editModalWidth || 520,
44808
+ destroyOnHidden: true,
44809
+ centered: true,
44810
+ children: [
44811
+ modalDescriptionText && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
44812
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: modalDescriptionTextStyle, children: modalDescriptionText }),
44813
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Spacer$1, { $space: 10, $samespace: true })
44814
+ ] }),
44815
+ children
44816
+ ]
44817
+ }
44818
+ );
44819
+ };
44820
+
44395
44821
  const isRecordStringNumber = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.entries(value).every(([k, v]) => typeof k === "string" && (typeof v === "string" || typeof v === "number"));
44396
44822
  const parseLabelsArrayOfAny = (value) => {
44397
44823
  if (!Array.isArray(value)) {
@@ -44431,7 +44857,9 @@ const Labels = ({ data, children }) => {
44431
44857
  endpoint,
44432
44858
  pathToValue,
44433
44859
  editModalWidth,
44434
- paddingContainerEnd
44860
+ paddingContainerEnd,
44861
+ permissions,
44862
+ permissionContext
44435
44863
  } = data;
44436
44864
  const [api, contextHolder] = notification.useNotification();
44437
44865
  const navigate = useNavigate();
@@ -44439,6 +44867,31 @@ const Labels = ({ data, children }) => {
44439
44867
  const { maxTagTextLength, ...restSelectProps } = selectProps || { maxTagTextLength: void 0 };
44440
44868
  const { data: multiQueryData, isLoading: isMultiQueryLoading, isError: isMultiQueryErrors, errors } = useMultiQuery();
44441
44869
  const partsOfUrl = usePartsOfUrl();
44870
+ const safeMultiQueryData = multiQueryData || {};
44871
+ const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
44872
+ acc[index.toString()] = value;
44873
+ return acc;
44874
+ }, {});
44875
+ const permissionContextPrepared = permissionContext ? {
44876
+ cluster: parseAll({ text: permissionContext.cluster, replaceValues, multiQueryData: safeMultiQueryData }),
44877
+ namespace: permissionContext.namespace ? parseAll({ text: permissionContext.namespace, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
44878
+ apiGroup: permissionContext.apiGroup ? parseAll({ text: permissionContext.apiGroup, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
44879
+ plural: parseAll({ text: permissionContext.plural, replaceValues, multiQueryData: safeMultiQueryData })
44880
+ } : void 0;
44881
+ const isPermissionContextValid = !!permissionContextPrepared && !isMultiQueryLoading && !!permissionContextPrepared.cluster && permissionContextPrepared.cluster !== "-" && !!permissionContextPrepared.plural && permissionContextPrepared.plural !== "-";
44882
+ const patchPermission = usePermissions({
44883
+ cluster: permissionContextPrepared?.cluster || "",
44884
+ namespace: permissionContextPrepared?.namespace,
44885
+ apiGroup: permissionContextPrepared?.apiGroup,
44886
+ plural: permissionContextPrepared?.plural || "",
44887
+ verb: "patch",
44888
+ refetchInterval: false,
44889
+ enabler: isPermissionContextValid
44890
+ });
44891
+ const canPatch = permissions?.canPatch ?? patchPermission.data?.status.allowed;
44892
+ const shouldGateEdit = Boolean(permissions || permissionContext);
44893
+ const canOpenEdit = !readOnly;
44894
+ const canSubmitEdit = !readOnly && (!shouldGateEdit || canPatch === true);
44442
44895
  if (isMultiQueryLoading) {
44443
44896
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." });
44444
44897
  }
@@ -44448,10 +44901,6 @@ const Labels = ({ data, children }) => {
44448
44901
  /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { children: errors.map((e, i) => e && /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: typeof e === "string" ? e : e.message }, i)) })
44449
44902
  ] });
44450
44903
  }
44451
- const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
44452
- acc[index.toString()] = value;
44453
- return acc;
44454
- }, {});
44455
44904
  const jsonRoot = multiQueryData[`req${reqIndex}`];
44456
44905
  if (jsonRoot === void 0) {
44457
44906
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "No root for json path" });
@@ -44482,7 +44931,7 @@ const Labels = ({ data, children }) => {
44482
44931
  });
44483
44932
  };
44484
44933
  const EmptySelect = /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: containerStyle, children: [
44485
- !readOnly && !verticalViewList && /* @__PURE__ */ jsxRuntimeExports.jsx(Flex, { justify: "flex-end", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44934
+ canOpenEdit && !verticalViewList && /* @__PURE__ */ jsxRuntimeExports.jsx(Flex, { justify: "flex-end", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44486
44935
  Button,
44487
44936
  {
44488
44937
  type: "text",
@@ -44510,7 +44959,7 @@ const Labels = ({ data, children }) => {
44510
44959
  isCursorPointer: true
44511
44960
  }
44512
44961
  ),
44513
- !readOnly && verticalViewList && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
44962
+ canOpenEdit && verticalViewList && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
44514
44963
  /* @__PURE__ */ jsxRuntimeExports.jsx(Spacer$1, { $space: 8, $samespace: true }),
44515
44964
  /* @__PURE__ */ jsxRuntimeExports.jsx(Flex, { justify: "flex-start", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44516
44965
  Button,
@@ -44529,12 +44978,13 @@ const Labels = ({ data, children }) => {
44529
44978
  ] }),
44530
44979
  children,
44531
44980
  contextHolder,
44532
- /* @__PURE__ */ jsxRuntimeExports.jsx(
44981
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
44533
44982
  LabelsEditModal,
44534
44983
  {
44535
44984
  open,
44536
44985
  close: () => setOpen(false),
44537
44986
  openNotificationSuccess,
44987
+ disableSubmit: !canSubmitEdit,
44538
44988
  modalTitle: modalTitlePrepared,
44539
44989
  modalDescriptionText: modalDescriptionTextPrepared,
44540
44990
  modalDescriptionTextStyle,
@@ -44557,7 +45007,7 @@ const Labels = ({ data, children }) => {
44557
45007
  }
44558
45008
  const labels = Object.entries(labelsRaw).map(([key, value]) => `${key}=${value}`);
44559
45009
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: containerStyle, children: [
44560
- !readOnly && !verticalViewList && /* @__PURE__ */ jsxRuntimeExports.jsx(Flex, { justify: "flex-end", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
45010
+ canOpenEdit && !verticalViewList && /* @__PURE__ */ jsxRuntimeExports.jsx(Flex, { justify: "flex-end", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44561
45011
  Button,
44562
45012
  {
44563
45013
  type: "text",
@@ -44641,7 +45091,7 @@ const Labels = ({ data, children }) => {
44641
45091
  }
44642
45092
  }
44643
45093
  ),
44644
- !readOnly && verticalViewList && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
45094
+ canOpenEdit && verticalViewList && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
44645
45095
  /* @__PURE__ */ jsxRuntimeExports.jsx(Spacer$1, { $space: 8, $samespace: true }),
44646
45096
  /* @__PURE__ */ jsxRuntimeExports.jsx(Flex, { justify: "flex-start", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44647
45097
  Button,
@@ -44660,13 +45110,14 @@ const Labels = ({ data, children }) => {
44660
45110
  ] }),
44661
45111
  children,
44662
45112
  contextHolder,
44663
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45113
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
44664
45114
  LabelsEditModal,
44665
45115
  {
44666
45116
  open,
44667
45117
  close: () => setOpen(false),
44668
45118
  values: labelsRaw,
44669
45119
  openNotificationSuccess,
45120
+ disableSubmit: !canSubmitEdit,
44670
45121
  modalTitle: modalTitlePrepared,
44671
45122
  modalDescriptionText: modalDescriptionTextPrepared,
44672
45123
  modalDescriptionTextStyle,
@@ -44683,7 +45134,24 @@ const Labels = ({ data, children }) => {
44683
45134
  ] });
44684
45135
  };
44685
45136
 
45137
+ const handleLabelsToSearchParamsLinkClick = ({
45138
+ e,
45139
+ hrefPrepared,
45140
+ navigate
45141
+ }) => {
45142
+ const isExternal = isExternalHref(hrefPrepared);
45143
+ if (isExternal) {
45144
+ return;
45145
+ }
45146
+ e.preventDefault();
45147
+ navigate(hrefPrepared);
45148
+ };
45149
+
44686
45150
  const LabelsToSearchParams = ({ data, children }) => {
45151
+ const renderWithSearchIcon = (content) => /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { align: "flex-start", gap: 8, children: [
45152
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SearchOutlined, { style: { marginTop: 4 } }),
45153
+ content
45154
+ ] });
44687
45155
  const {
44688
45156
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
44689
45157
  id,
@@ -44692,9 +45160,12 @@ const LabelsToSearchParams = ({ data, children }) => {
44692
45160
  linkPrefix,
44693
45161
  textLink,
44694
45162
  errorText,
45163
+ errorMode = "errorText",
44695
45164
  maxTextLength,
45165
+ renderLabelsAsRows,
44696
45166
  ...linkProps
44697
45167
  } = data;
45168
+ const navigate = useNavigate();
44698
45169
  const { data: multiQueryData, isLoading: isMultiQueryLoading, isError: isMultiQueryErrors, errors } = useMultiQuery();
44699
45170
  const partsOfUrl = usePartsOfUrl();
44700
45171
  if (isMultiQueryLoading) {
@@ -44717,33 +45188,66 @@ const LabelsToSearchParams = ({ data, children }) => {
44717
45188
  const anythingForNow = jp.query(jsonRoot || {}, `$${jsonPathToLabels}`);
44718
45189
  const { data: labelsRaw, error: errorArrayOfObjects } = parseLabelsArrayOfAny(anythingForNow);
44719
45190
  const linkPrefixPrepared = parseAll({ text: linkPrefix, replaceValues, multiQueryData });
45191
+ const labelsPrefixPrepared = linkPrefixPrepared.includes("?") ? `${linkPrefixPrepared}${linkPrefixPrepared.endsWith("?") || linkPrefixPrepared.endsWith("&") ? "" : "&"}labels=` : `${linkPrefixPrepared}?labels=`;
45192
+ const renderErrorFallback = () => {
45193
+ if (errorMode === "default") {
45194
+ const fallbackText = textLink || errorText;
45195
+ const handleDefaultFallbackLinkClick = (e) => handleLabelsToSearchParamsLinkClick({
45196
+ e,
45197
+ hrefPrepared: linkPrefixPrepared,
45198
+ navigate
45199
+ });
45200
+ return renderWithSearchIcon(
45201
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography.Link, { href: linkPrefixPrepared, onClick: handleDefaultFallbackLinkClick, ...linkProps, children: [
45202
+ fallbackText,
45203
+ children
45204
+ ] })
45205
+ );
45206
+ }
45207
+ return renderWithSearchIcon(
45208
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography.Text, { children: [
45209
+ errorText,
45210
+ children
45211
+ ] })
45212
+ );
45213
+ };
44720
45214
  if (!labelsRaw) {
44721
45215
  if (errorArrayOfObjects) {
44722
45216
  console.log(errorArrayOfObjects);
44723
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography.Link, { href: linkPrefixPrepared, ...linkProps, children: [
44724
- errorText,
44725
- children
44726
- ] });
45217
+ return renderErrorFallback();
44727
45218
  }
44728
45219
  console.log("Not a valid data structure");
44729
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography.Link, { href: linkPrefixPrepared, ...linkProps, children: [
44730
- errorText,
44731
- children
44732
- ] });
45220
+ return renderErrorFallback();
44733
45221
  }
44734
45222
  const labels = Object.entries(labelsRaw).map(([key, value]) => `${key}=${value}`).join(",");
45223
+ const labelsRows = Object.entries(labelsRaw).map(([key, value]) => `${key}=${value}`);
44735
45224
  const labelsEncoded = encodeURIComponent(labels);
44736
- const hrefPrepared = `${linkPrefixPrepared}${labelsEncoded}`;
45225
+ const hrefPrepared = `${labelsPrefixPrepared}${labelsEncoded}`;
45226
+ const handleLinkClick = (e) => handleLabelsToSearchParamsLinkClick({
45227
+ e,
45228
+ hrefPrepared,
45229
+ navigate
45230
+ });
45231
+ if (renderLabelsAsRows) {
45232
+ return renderWithSearchIcon(
45233
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { vertical: true, children: [
45234
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography.Link, { href: hrefPrepared, onClick: handleLinkClick, ...linkProps, children: labelsRows.map((row, index) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { display: "block" }, children: index < labelsRows.length - 1 ? `${row},` : row }, `${row}-${index}`)) }),
45235
+ children
45236
+ ] })
45237
+ );
45238
+ }
44737
45239
  if (maxTextLength && !textLink) {
44738
45240
  const truncatedLabels = maxTextLength ? truncate$1(labels, maxTextLength) : labels;
44739
45241
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
44740
45242
  Popover,
44741
45243
  {
44742
45244
  content: /* @__PURE__ */ jsxRuntimeExports.jsx(Flex, { vertical: true, gap: 8, children: Object.entries(labelsRaw).map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: `${key}=${value}` }, key)) }),
44743
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography.Link, { href: hrefPrepared, ...linkProps, children: [
44744
- truncatedLabels,
44745
- children
44746
- ] })
45245
+ children: renderWithSearchIcon(
45246
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography.Link, { href: hrefPrepared, onClick: handleLinkClick, ...linkProps, children: [
45247
+ truncatedLabels,
45248
+ children
45249
+ ] })
45250
+ )
44747
45251
  }
44748
45252
  );
44749
45253
  }
@@ -44753,17 +45257,21 @@ const LabelsToSearchParams = ({ data, children }) => {
44753
45257
  Popover,
44754
45258
  {
44755
45259
  content: /* @__PURE__ */ jsxRuntimeExports.jsx(Flex, { vertical: true, gap: 8, children: Object.entries(labelsRaw).map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: `${key}=${value}` }, key)) }),
44756
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography.Link, { href: hrefPrepared, ...linkProps, children: [
44757
- truncatedTextLink,
44758
- children
44759
- ] })
45260
+ children: renderWithSearchIcon(
45261
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography.Link, { href: hrefPrepared, onClick: handleLinkClick, ...linkProps, children: [
45262
+ truncatedTextLink,
45263
+ children
45264
+ ] })
45265
+ )
44760
45266
  }
44761
45267
  );
44762
45268
  }
44763
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography.Link, { href: hrefPrepared, ...linkProps, children: [
44764
- textLink || labels,
44765
- children
44766
- ] });
45269
+ return renderWithSearchIcon(
45270
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography.Link, { href: hrefPrepared, onClick: handleLinkClick, ...linkProps, children: [
45271
+ textLink || labels,
45272
+ children
45273
+ ] })
45274
+ );
44767
45275
  };
44768
45276
 
44769
45277
  const flattenOnce$1 = (arr) => arr.reduce((acc, row) => [...acc, ...row], []);
@@ -44814,12 +45322,40 @@ const Taints = ({ data, children }) => {
44814
45322
  endpoint,
44815
45323
  pathToValue,
44816
45324
  editModalWidth,
44817
- cols
45325
+ cols,
45326
+ readOnly,
45327
+ permissions,
45328
+ permissionContext
44818
45329
  } = data;
44819
45330
  const [api, contextHolder] = notification.useNotification();
44820
45331
  const [open, setOpen] = useState(false);
44821
45332
  const { data: multiQueryData, isLoading: isMultiQueryLoading, isError: isMultiQueryErrors, errors } = useMultiQuery();
44822
45333
  const partsOfUrl = usePartsOfUrl();
45334
+ const safeMultiQueryData = multiQueryData || {};
45335
+ const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
45336
+ acc[index.toString()] = value;
45337
+ return acc;
45338
+ }, {});
45339
+ const permissionContextPrepared = permissionContext ? {
45340
+ cluster: parseAll({ text: permissionContext.cluster, replaceValues, multiQueryData: safeMultiQueryData }),
45341
+ namespace: permissionContext.namespace ? parseAll({ text: permissionContext.namespace, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
45342
+ apiGroup: permissionContext.apiGroup ? parseAll({ text: permissionContext.apiGroup, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
45343
+ plural: parseAll({ text: permissionContext.plural, replaceValues, multiQueryData: safeMultiQueryData })
45344
+ } : void 0;
45345
+ const isPermissionContextValid = !!permissionContextPrepared && !isMultiQueryLoading && !!permissionContextPrepared.cluster && permissionContextPrepared.cluster !== "-" && !!permissionContextPrepared.plural && permissionContextPrepared.plural !== "-";
45346
+ const patchPermission = usePermissions({
45347
+ cluster: permissionContextPrepared?.cluster || "",
45348
+ namespace: permissionContextPrepared?.namespace,
45349
+ apiGroup: permissionContextPrepared?.apiGroup,
45350
+ plural: permissionContextPrepared?.plural || "",
45351
+ verb: "patch",
45352
+ refetchInterval: false,
45353
+ enabler: isPermissionContextValid
45354
+ });
45355
+ const canPatch = permissions?.canPatch ?? patchPermission.data?.status.allowed;
45356
+ const shouldGateEdit = Boolean(permissions || permissionContext);
45357
+ const canOpenEdit = !readOnly;
45358
+ const canSubmitEdit = !readOnly && (!shouldGateEdit || canPatch === true);
44823
45359
  if (isMultiQueryLoading) {
44824
45360
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." });
44825
45361
  }
@@ -44829,10 +45365,6 @@ const Taints = ({ data, children }) => {
44829
45365
  /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { children: errors.map((e, i) => e && /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: typeof e === "string" ? e : e.message }, i)) })
44830
45366
  ] });
44831
45367
  }
44832
- const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
44833
- acc[index.toString()] = value;
44834
- return acc;
44835
- }, {});
44836
45368
  const jsonRoot = multiQueryData[`req${reqIndex}`];
44837
45369
  if (jsonRoot === void 0) {
44838
45370
  console.log(`Item Counter: ${id}: No root for json path`);
@@ -44868,7 +45400,7 @@ const Taints = ({ data, children }) => {
44868
45400
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: containerStyle, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { align: "center", gap: 8, children: [
44869
45401
  errorText,
44870
45402
  " ",
44871
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45403
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
44872
45404
  Button,
44873
45405
  {
44874
45406
  type: "text",
@@ -44882,13 +45414,14 @@ const Taints = ({ data, children }) => {
44882
45414
  )
44883
45415
  ] }) }),
44884
45416
  contextHolder,
44885
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45417
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
44886
45418
  TaintsEditModal,
44887
45419
  {
44888
45420
  open,
44889
45421
  close: () => setOpen(false),
44890
45422
  values: taints,
44891
45423
  openNotificationSuccess,
45424
+ disableSubmit: !canSubmitEdit,
44892
45425
  modalTitle: modalTitlePrepared,
44893
45426
  modalDescriptionText: modalDescriptionTextPrepared,
44894
45427
  modalDescriptionTextStyle,
@@ -44908,7 +45441,7 @@ const Taints = ({ data, children }) => {
44908
45441
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: containerStyle, children: [
44909
45442
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { align: "center", gap: 8, children: [
44910
45443
  parsedTextWithCounter,
44911
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45444
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
44912
45445
  Button,
44913
45446
  {
44914
45447
  type: "text",
@@ -44924,13 +45457,14 @@ const Taints = ({ data, children }) => {
44924
45457
  children
44925
45458
  ] }),
44926
45459
  contextHolder,
44927
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45460
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
44928
45461
  TaintsEditModal,
44929
45462
  {
44930
45463
  open,
44931
45464
  close: () => setOpen(false),
44932
45465
  values: taints,
44933
45466
  openNotificationSuccess,
45467
+ disableSubmit: !canSubmitEdit,
44934
45468
  modalTitle: modalTitlePrepared,
44935
45469
  modalDescriptionText: modalDescriptionTextPrepared,
44936
45470
  inputLabel: inputLabelPrepared,
@@ -45001,16 +45535,44 @@ const Tolerations = ({
45001
45535
  modalDescriptionTextStyle,
45002
45536
  inputLabel,
45003
45537
  inputLabelStyle,
45538
+ readOnly,
45004
45539
  containerStyle,
45005
45540
  endpoint,
45006
45541
  pathToValue,
45007
45542
  editModalWidth,
45008
- cols
45543
+ cols,
45544
+ permissions,
45545
+ permissionContext
45009
45546
  } = data;
45010
45547
  const [api, contextHolder] = notification.useNotification();
45011
45548
  const [open, setOpen] = useState(false);
45012
45549
  const { data: multiQueryData, isLoading: isMultiQueryLoading, isError: isMultiQueryErrors, errors } = useMultiQuery();
45013
45550
  const partsOfUrl = usePartsOfUrl();
45551
+ const safeMultiQueryData = multiQueryData || {};
45552
+ const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
45553
+ acc[index.toString()] = value;
45554
+ return acc;
45555
+ }, {});
45556
+ const permissionContextPrepared = permissionContext ? {
45557
+ cluster: parseAll({ text: permissionContext.cluster, replaceValues, multiQueryData: safeMultiQueryData }),
45558
+ namespace: permissionContext.namespace ? parseAll({ text: permissionContext.namespace, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
45559
+ apiGroup: permissionContext.apiGroup ? parseAll({ text: permissionContext.apiGroup, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
45560
+ plural: parseAll({ text: permissionContext.plural, replaceValues, multiQueryData: safeMultiQueryData })
45561
+ } : void 0;
45562
+ const isPermissionContextValid = !!permissionContextPrepared && !isMultiQueryLoading && !!permissionContextPrepared.cluster && permissionContextPrepared.cluster !== "-" && !!permissionContextPrepared.plural && permissionContextPrepared.plural !== "-";
45563
+ const patchPermission = usePermissions({
45564
+ cluster: permissionContextPrepared?.cluster || "",
45565
+ namespace: permissionContextPrepared?.namespace,
45566
+ apiGroup: permissionContextPrepared?.apiGroup,
45567
+ plural: permissionContextPrepared?.plural || "",
45568
+ verb: "patch",
45569
+ refetchInterval: false,
45570
+ enabler: isPermissionContextValid
45571
+ });
45572
+ const canPatch = permissions?.canPatch ?? patchPermission.data?.status.allowed;
45573
+ const shouldGateEdit = Boolean(permissions || permissionContext);
45574
+ const canOpenEdit = !readOnly;
45575
+ const canSubmitEdit = !readOnly && (!shouldGateEdit || canPatch === true);
45014
45576
  if (isMultiQueryLoading) {
45015
45577
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." });
45016
45578
  }
@@ -45020,10 +45582,6 @@ const Tolerations = ({
45020
45582
  /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { children: errors.map((e, i) => e && /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: typeof e === "string" ? e : e.message }, i)) })
45021
45583
  ] });
45022
45584
  }
45023
- const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
45024
- acc[index.toString()] = value;
45025
- return acc;
45026
- }, {});
45027
45585
  const jsonRoot = multiQueryData[`req${reqIndex}`];
45028
45586
  if (jsonRoot === void 0) {
45029
45587
  console.log(`Item Counter: ${id}: No root for json path`);
@@ -45058,7 +45616,7 @@ const Tolerations = ({
45058
45616
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
45059
45617
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: containerStyle, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { align: "center", gap: 8, children: [
45060
45618
  errorText,
45061
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45619
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
45062
45620
  Button,
45063
45621
  {
45064
45622
  type: "text",
@@ -45072,13 +45630,14 @@ const Tolerations = ({
45072
45630
  )
45073
45631
  ] }) }),
45074
45632
  contextHolder,
45075
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45633
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
45076
45634
  TolerationsEditModal,
45077
45635
  {
45078
45636
  open,
45079
45637
  close: () => setOpen(false),
45080
45638
  values: tolerations,
45081
45639
  openNotificationSuccess,
45640
+ disableSubmit: !canSubmitEdit,
45082
45641
  modalTitle: modalTitlePrepared,
45083
45642
  modalDescriptionText: modalDescriptionTextPrepared,
45084
45643
  modalDescriptionTextStyle,
@@ -45098,7 +45657,7 @@ const Tolerations = ({
45098
45657
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: containerStyle, children: [
45099
45658
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { align: "center", gap: 8, children: [
45100
45659
  parsedTextWithCounter,
45101
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45660
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
45102
45661
  Button,
45103
45662
  {
45104
45663
  type: "text",
@@ -45114,13 +45673,14 @@ const Tolerations = ({
45114
45673
  children
45115
45674
  ] }),
45116
45675
  contextHolder,
45117
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45676
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
45118
45677
  TolerationsEditModal,
45119
45678
  {
45120
45679
  open,
45121
45680
  close: () => setOpen(false),
45122
45681
  values: tolerations,
45123
45682
  openNotificationSuccess,
45683
+ disableSubmit: !canSubmitEdit,
45124
45684
  modalTitle: modalTitlePrepared,
45125
45685
  modalDescriptionText: modalDescriptionTextPrepared,
45126
45686
  modalDescriptionTextStyle,
@@ -45167,16 +45727,44 @@ const Annotations = ({
45167
45727
  modalDescriptionTextStyle,
45168
45728
  inputLabel,
45169
45729
  inputLabelStyle,
45730
+ readOnly,
45170
45731
  containerStyle,
45171
45732
  endpoint,
45172
45733
  pathToValue,
45173
45734
  editModalWidth,
45174
- cols
45735
+ cols,
45736
+ permissions,
45737
+ permissionContext
45175
45738
  } = data;
45176
45739
  const [api, contextHolder] = notification.useNotification();
45177
45740
  const [open, setOpen] = useState(false);
45178
45741
  const { data: multiQueryData, isLoading: isMultiQueryLoading, isError: isMultiQueryErrors, errors } = useMultiQuery();
45179
45742
  const partsOfUrl = usePartsOfUrl();
45743
+ const safeMultiQueryData = multiQueryData || {};
45744
+ const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
45745
+ acc[index.toString()] = value;
45746
+ return acc;
45747
+ }, {});
45748
+ const permissionContextPrepared = permissionContext ? {
45749
+ cluster: parseAll({ text: permissionContext.cluster, replaceValues, multiQueryData: safeMultiQueryData }),
45750
+ namespace: permissionContext.namespace ? parseAll({ text: permissionContext.namespace, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
45751
+ apiGroup: permissionContext.apiGroup ? parseAll({ text: permissionContext.apiGroup, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
45752
+ plural: parseAll({ text: permissionContext.plural, replaceValues, multiQueryData: safeMultiQueryData })
45753
+ } : void 0;
45754
+ const isPermissionContextValid = !!permissionContextPrepared && !isMultiQueryLoading && !!permissionContextPrepared.cluster && permissionContextPrepared.cluster !== "-" && !!permissionContextPrepared.plural && permissionContextPrepared.plural !== "-";
45755
+ const patchPermission = usePermissions({
45756
+ cluster: permissionContextPrepared?.cluster || "",
45757
+ namespace: permissionContextPrepared?.namespace,
45758
+ apiGroup: permissionContextPrepared?.apiGroup,
45759
+ plural: permissionContextPrepared?.plural || "",
45760
+ verb: "patch",
45761
+ refetchInterval: false,
45762
+ enabler: isPermissionContextValid
45763
+ });
45764
+ const canPatch = permissions?.canPatch ?? patchPermission.data?.status.allowed;
45765
+ const shouldGateEdit = Boolean(permissions || permissionContext);
45766
+ const canOpenEdit = !readOnly;
45767
+ const canSubmitEdit = !readOnly && (!shouldGateEdit || canPatch === true);
45180
45768
  if (isMultiQueryLoading) {
45181
45769
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." });
45182
45770
  }
@@ -45186,10 +45774,6 @@ const Annotations = ({
45186
45774
  /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { children: errors.map((e, i) => e && /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: typeof e === "string" ? e : e.message }, i)) })
45187
45775
  ] });
45188
45776
  }
45189
- const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
45190
- acc[index.toString()] = value;
45191
- return acc;
45192
- }, {});
45193
45777
  const jsonRoot = multiQueryData[`req${reqIndex}`];
45194
45778
  if (jsonRoot === void 0) {
45195
45779
  console.log(`Item Counter: ${id}: No root for json path`);
@@ -45224,7 +45808,7 @@ const Annotations = ({
45224
45808
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
45225
45809
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: containerStyle, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { align: "center", gap: 8, children: [
45226
45810
  errorText,
45227
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45811
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
45228
45812
  Button,
45229
45813
  {
45230
45814
  type: "text",
@@ -45238,13 +45822,14 @@ const Annotations = ({
45238
45822
  )
45239
45823
  ] }) }),
45240
45824
  contextHolder,
45241
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45825
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
45242
45826
  AnnotationsEditModal,
45243
45827
  {
45244
45828
  open,
45245
45829
  close: () => setOpen(false),
45246
45830
  values: annotations,
45247
45831
  openNotificationSuccess,
45832
+ disableSubmit: !canSubmitEdit,
45248
45833
  modalTitle: modalTitlePrepared,
45249
45834
  modalDescriptionText: modalDescriptionTextPrepared,
45250
45835
  modalDescriptionTextStyle,
@@ -45264,7 +45849,7 @@ const Annotations = ({
45264
45849
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: containerStyle, children: [
45265
45850
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { align: "center", gap: 8, children: [
45266
45851
  parsedTextWithCounter,
45267
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45852
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
45268
45853
  Button,
45269
45854
  {
45270
45855
  type: "text",
@@ -45280,13 +45865,14 @@ const Annotations = ({
45280
45865
  children
45281
45866
  ] }),
45282
45867
  contextHolder,
45283
- /* @__PURE__ */ jsxRuntimeExports.jsx(
45868
+ canOpenEdit && /* @__PURE__ */ jsxRuntimeExports.jsx(
45284
45869
  AnnotationsEditModal,
45285
45870
  {
45286
45871
  open,
45287
45872
  close: () => setOpen(false),
45288
45873
  values: annotations,
45289
45874
  openNotificationSuccess,
45875
+ disableSubmit: !canSubmitEdit,
45290
45876
  modalTitle: modalTitlePrepared,
45291
45877
  modalDescriptionText: modalDescriptionTextPrepared,
45292
45878
  modalDescriptionTextStyle,
@@ -46259,27 +46845,63 @@ const NoSelect = styled.div`
46259
46845
  user-select: none;
46260
46846
  }
46261
46847
  `;
46262
- const DisabledInput = styled(Input)`
46848
+ const hiddenCursor = css`
46263
46849
  /* stylelint-disable declaration-no-important */
46264
46850
  cursor: ${({ $hidden }) => $hidden ? "default" : "pointer"} !important;
46265
46851
  `;
46852
+ const DisabledInput = styled(Input)`
46853
+ ${hiddenCursor}
46854
+ `;
46855
+ const DisabledTextArea = styled(Input.TextArea)`
46856
+ ${hiddenCursor}
46857
+ `;
46266
46858
  const NotificationOverrides = createGlobalStyle`
46267
46859
  .no-message-notif .ant-notification-notice-message {
46268
46860
  margin-bottom: 0 !important;
46269
46861
  }
46270
46862
  `;
46271
- const Styled$q = {
46863
+ const Styled$r = {
46272
46864
  NoSelect,
46273
46865
  DisabledInput,
46866
+ DisabledTextArea,
46274
46867
  NotificationOverrides
46275
46868
  };
46276
46869
 
46870
+ const decodeIfBase64 = (value, shouldDecode) => {
46871
+ if (!shouldDecode) {
46872
+ return value;
46873
+ }
46874
+ try {
46875
+ return atob(value);
46876
+ } catch (error) {
46877
+ console.error(error);
46878
+ return value;
46879
+ }
46880
+ };
46881
+ const resolveMultilineRows = (value, multilineRows) => {
46882
+ const computedRows = Math.min(12, Math.max(3, value.split(/\r\n|\r|\n/).length));
46883
+ if (typeof multilineRows === "number" && Number.isFinite(multilineRows)) {
46884
+ return Math.min(30, Math.max(1, Math.floor(multilineRows)));
46885
+ }
46886
+ return computedRows;
46887
+ };
46888
+
46277
46889
  const SecretBase64Plain = ({ data }) => {
46278
46890
  const {
46279
46891
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
46280
46892
  id,
46893
+ type,
46894
+ value,
46895
+ reqIndex,
46896
+ jsonPathToSecrets,
46281
46897
  base64Value,
46282
46898
  plainTextValue,
46899
+ multiline,
46900
+ multilineRows,
46901
+ shownByDefault,
46902
+ hideEye,
46903
+ textStyle,
46904
+ emptyText,
46283
46905
  containerStyle,
46284
46906
  inputContainerStyle,
46285
46907
  flexProps,
@@ -46287,8 +46909,9 @@ const SecretBase64Plain = ({ data }) => {
46287
46909
  notificationText,
46288
46910
  notificationWidth
46289
46911
  } = data;
46290
- const [hidden, setHidden] = useState(true);
46291
- const inputRef = useRef(null);
46912
+ const hiddenDefault = !shownByDefault;
46913
+ const [hidden, setHidden] = useState(hiddenDefault);
46914
+ const [hiddenByKey, setHiddenByKey] = useState({});
46292
46915
  const [notificationApi, contextHolder] = notification.useNotification();
46293
46916
  const { data: multiQueryData, isLoading, isError, errors } = useMultiQuery();
46294
46917
  const partsOfUrl = usePartsOfUrl();
@@ -46302,20 +46925,26 @@ const SecretBase64Plain = ({ data }) => {
46302
46925
  /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { children: errors.map((e, i) => e && /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: typeof e === "string" ? e : e.message }, i)) })
46303
46926
  ] });
46304
46927
  }
46305
- const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
46306
- acc[index.toString()] = value;
46928
+ const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value2, index) => {
46929
+ acc[index.toString()] = value2;
46307
46930
  return acc;
46308
46931
  }, {});
46309
46932
  const parsedText = parseAll({
46310
- text: base64Value || plainTextValue || "Oneof required",
46933
+ text: value ?? base64Value ?? plainTextValue ?? "Value required",
46311
46934
  replaceValues,
46312
46935
  multiQueryData
46313
46936
  });
46314
- const decodedText = base64Value ? atob(parsedText) : parsedText;
46315
- const copyToClipboard = async () => {
46937
+ const emptyTextPrepared = typeof emptyText === "string" && emptyText.length > 0 ? parseAll({
46938
+ text: emptyText,
46939
+ replaceValues,
46940
+ multiQueryData
46941
+ }) : void 0;
46942
+ const shouldDecodeSingle = type === "base64" ? true : type === "plain" ? false : base64Value !== void 0;
46943
+ const decodedText = decodeIfBase64(parsedText, shouldDecodeSingle);
46944
+ const copyToClipboard = async (valueToCopy) => {
46316
46945
  try {
46317
- if (decodedText !== null && decodedText !== void 0) {
46318
- await navigator.clipboard.writeText(decodedText);
46946
+ if (valueToCopy !== null && valueToCopy !== void 0) {
46947
+ await navigator.clipboard.writeText(valueToCopy);
46319
46948
  notificationApi.info({
46320
46949
  // message: `Copied: ${decodedText.substring(0, 5)}...`,
46321
46950
  message: notificationText || "Text copied to clipboard",
@@ -46333,42 +46962,103 @@ const SecretBase64Plain = ({ data }) => {
46333
46962
  console.error(error);
46334
46963
  }
46335
46964
  };
46336
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: containerStyle, children: [
46337
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$q.NotificationOverrides, {}),
46338
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { gap: 8, ...flexProps, children: [
46339
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$q.NoSelect, { style: inputContainerStyle, children: niceLooking ? /* @__PURE__ */ jsxRuntimeExports.jsx(te, { theme, hidden, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
46340
- Styled$q.DisabledInput,
46965
+ const handleInputClick = async (e, isHidden, valueToCopy) => {
46966
+ if (isHidden) {
46967
+ return;
46968
+ }
46969
+ e.currentTarget.focus();
46970
+ e.currentTarget.select();
46971
+ await copyToClipboard(valueToCopy);
46972
+ };
46973
+ const useNiceLooking = !!niceLooking && !multiline;
46974
+ const renderSecretField = ({
46975
+ value: value2,
46976
+ isHidden,
46977
+ onToggle
46978
+ }) => {
46979
+ const effectiveHidden = hideEye ? false : isHidden;
46980
+ const shownValue = useNiceLooking ? value2 : effectiveHidden ? "" : value2;
46981
+ const resolvedMultilineRows = resolveMultilineRows(value2, multilineRows);
46982
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { gap: 8, ...flexProps, children: [
46983
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$r.NoSelect, { style: inputContainerStyle, children: useNiceLooking ? /* @__PURE__ */ jsxRuntimeExports.jsx(te, { theme, hidden: effectiveHidden, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
46984
+ Styled$r.DisabledInput,
46341
46985
  {
46342
- $hidden: hidden,
46343
- ref: inputRef,
46344
- onClick: () => {
46345
- if (!hidden) {
46346
- inputRef.current?.focus({
46347
- cursor: "all"
46348
- });
46349
- copyToClipboard();
46350
- }
46351
- },
46352
- value: decodedText
46986
+ $hidden: effectiveHidden,
46987
+ onClick: (e) => handleInputClick(e, effectiveHidden, value2),
46988
+ value: shownValue,
46989
+ readOnly: true
46353
46990
  }
46354
- ) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
46355
- Styled$q.DisabledInput,
46991
+ ) }) : multiline ? /* @__PURE__ */ jsxRuntimeExports.jsx(
46992
+ Styled$r.DisabledTextArea,
46356
46993
  {
46357
- $hidden: hidden,
46358
- ref: inputRef,
46359
- onClick: () => {
46360
- if (!hidden) {
46361
- inputRef.current?.focus({
46362
- cursor: "all"
46363
- });
46364
- copyToClipboard();
46365
- }
46366
- },
46367
- value: hidden ? "" : decodedText
46994
+ $hidden: effectiveHidden,
46995
+ onClick: (e) => handleInputClick(e, effectiveHidden, value2),
46996
+ value: shownValue,
46997
+ rows: resolvedMultilineRows,
46998
+ readOnly: true
46999
+ }
47000
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
47001
+ Styled$r.DisabledInput,
47002
+ {
47003
+ $hidden: effectiveHidden,
47004
+ onClick: (e) => handleInputClick(e, effectiveHidden, value2),
47005
+ value: shownValue,
47006
+ readOnly: true
46368
47007
  }
46369
47008
  ) }),
46370
- /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "text", onClick: () => setHidden(!hidden), children: hidden ? /* @__PURE__ */ jsxRuntimeExports.jsx(EyeOutlined, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(EyeInvisibleOutlined, {}) })
46371
- ] }),
47009
+ !hideEye && /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "text", onClick: onToggle, children: isHidden ? /* @__PURE__ */ jsxRuntimeExports.jsx(EyeOutlined, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(EyeInvisibleOutlined, {}) })
47010
+ ] });
47011
+ };
47012
+ if (reqIndex && jsonPathToSecrets) {
47013
+ const reqIndexPrepared = parseAll({ text: reqIndex, replaceValues, multiQueryData });
47014
+ const jsonPathToSecretsPrepared = parseAll({ text: jsonPathToSecrets, replaceValues, multiQueryData });
47015
+ const jsonRoot = multiQueryData[`req${reqIndexPrepared}`];
47016
+ if (jsonRoot === void 0) {
47017
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "No root for json path" });
47018
+ }
47019
+ const pathResults = jp.query(jsonRoot || {}, `$${jsonPathToSecretsPrepared}`);
47020
+ const objectToRender = pathResults.find((item) => item !== null && typeof item === "object" && !Array.isArray(item)) || null;
47021
+ const secretsEntries = objectToRender ? Object.entries(objectToRender) : [];
47022
+ if (secretsEntries.length === 0) {
47023
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: containerStyle, children: [
47024
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$r.NotificationOverrides, {}),
47025
+ emptyTextPrepared && /* @__PURE__ */ jsxRuntimeExports.jsx(Typography.Text, { style: textStyle, children: emptyTextPrepared }),
47026
+ contextHolder
47027
+ ] });
47028
+ }
47029
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: containerStyle, children: [
47030
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$r.NotificationOverrides, {}),
47031
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Flex, { vertical: true, gap: 8, children: secretsEntries.map(([key, rawValue]) => {
47032
+ const parsedValue = parseAll({
47033
+ text: typeof rawValue === "string" ? rawValue : String(rawValue),
47034
+ replaceValues,
47035
+ multiQueryData
47036
+ });
47037
+ const shouldDecodeObject = type !== "plain";
47038
+ const secretValue = decodeIfBase64(parsedValue, shouldDecodeObject);
47039
+ const hiddenForKey = hiddenByKey[key] ?? hiddenDefault;
47040
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
47041
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography.Text, { strong: true, style: textStyle, children: key }),
47042
+ renderSecretField({
47043
+ value: secretValue,
47044
+ isHidden: hiddenForKey,
47045
+ onToggle: () => setHiddenByKey((prevState) => ({
47046
+ ...prevState,
47047
+ [key]: !(prevState[key] ?? hiddenDefault)
47048
+ }))
47049
+ })
47050
+ ] }, key);
47051
+ }) }),
47052
+ contextHolder
47053
+ ] });
47054
+ }
47055
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: containerStyle, children: [
47056
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$r.NotificationOverrides, {}),
47057
+ renderSecretField({
47058
+ value: decodedText,
47059
+ isHidden: hidden,
47060
+ onToggle: () => setHidden(!hidden)
47061
+ }),
46372
47062
  contextHolder
46373
47063
  ] });
46374
47064
  };
@@ -46386,7 +47076,7 @@ const RoundSpan = styled.span`
46386
47076
  letter-spacing: 0.02em;
46387
47077
  box-sizing: content-box;
46388
47078
  `;
46389
- const Styled$p = {
47079
+ const Styled$q = {
46390
47080
  RoundSpan
46391
47081
  };
46392
47082
 
@@ -46425,7 +47115,7 @@ const ResourceBadge = ({ data }) => {
46425
47115
  multiQueryData
46426
47116
  }) : getUppercase(parsedValue);
46427
47117
  const bgColor = hslFromString(parsedValue, theme);
46428
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$p.RoundSpan, { $bgColor: bgColor, style, children: parsedAbbreviation });
47118
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$q.RoundSpan, { $bgColor: bgColor, style, children: parsedAbbreviation });
46429
47119
  };
46430
47120
 
46431
47121
  const serializeLabelsWithNoEncoding = (input) => {
@@ -77068,7 +77758,7 @@ const TitleSelect = styled(Select)`
77068
77758
  }
77069
77759
  }
77070
77760
  `;
77071
- const Styled$o = {
77761
+ const Styled$p = {
77072
77762
  TitleSelect
77073
77763
  };
77074
77764
 
@@ -77149,7 +77839,7 @@ const DropdownRedirect = ({
77149
77839
  }
77150
77840
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
77151
77841
  /* @__PURE__ */ jsxRuntimeExports.jsx(
77152
- Styled$o.TitleSelect,
77842
+ Styled$p.TitleSelect,
77153
77843
  {
77154
77844
  value: currentValuePrepared,
77155
77845
  onChange: handleChange,
@@ -77222,6 +77912,7 @@ const CopyButton = ({
77222
77912
  const LabelsModal = ({
77223
77913
  open,
77224
77914
  onClose,
77915
+ disableSubmit,
77225
77916
  reqIndex,
77226
77917
  jsonPathToLabels,
77227
77918
  notificationSuccessMessage,
@@ -77290,6 +77981,7 @@ const LabelsModal = ({
77290
77981
  open,
77291
77982
  close: onClose,
77292
77983
  openNotificationSuccess,
77984
+ disableSubmit,
77293
77985
  modalTitle: modalTitlePrepared,
77294
77986
  modalDescriptionText: modalDescriptionTextPrepared,
77295
77987
  modalDescriptionTextStyle,
@@ -77319,6 +78011,7 @@ const LabelsModal = ({
77319
78011
  close: onClose,
77320
78012
  values: labelsRaw,
77321
78013
  openNotificationSuccess,
78014
+ disableSubmit,
77322
78015
  modalTitle: modalTitlePrepared,
77323
78016
  modalDescriptionText: modalDescriptionTextPrepared,
77324
78017
  modalDescriptionTextStyle,
@@ -77338,6 +78031,7 @@ const LabelsModal = ({
77338
78031
  const AnnotationsModal = ({
77339
78032
  open,
77340
78033
  onClose,
78034
+ disableSubmit,
77341
78035
  reqIndex,
77342
78036
  jsonPathToObj,
77343
78037
  notificationSuccessMessage,
@@ -77408,6 +78102,7 @@ const AnnotationsModal = ({
77408
78102
  close: onClose,
77409
78103
  values: annotations,
77410
78104
  openNotificationSuccess,
78105
+ disableSubmit,
77411
78106
  modalTitle: modalTitlePrepared,
77412
78107
  modalDescriptionText: errorArrayOfObjects,
77413
78108
  modalDescriptionTextStyle,
@@ -77430,6 +78125,7 @@ const AnnotationsModal = ({
77430
78125
  close: onClose,
77431
78126
  values: annotations,
77432
78127
  openNotificationSuccess,
78128
+ disableSubmit,
77433
78129
  modalTitle: modalTitlePrepared,
77434
78130
  modalDescriptionText: modalDescriptionTextPrepared,
77435
78131
  modalDescriptionTextStyle,
@@ -77447,6 +78143,7 @@ const AnnotationsModal = ({
77447
78143
  const TaintsModal = ({
77448
78144
  open,
77449
78145
  onClose,
78146
+ disableSubmit,
77450
78147
  reqIndex,
77451
78148
  jsonPathToArray,
77452
78149
  notificationSuccessMessage,
@@ -77516,6 +78213,7 @@ const TaintsModal = ({
77516
78213
  close: onClose,
77517
78214
  values: taints,
77518
78215
  openNotificationSuccess,
78216
+ disableSubmit,
77519
78217
  modalTitle: modalTitlePrepared,
77520
78218
  modalDescriptionText: errorArrayOfObjects,
77521
78219
  modalDescriptionTextStyle,
@@ -77538,6 +78236,7 @@ const TaintsModal = ({
77538
78236
  close: onClose,
77539
78237
  values: taints,
77540
78238
  openNotificationSuccess,
78239
+ disableSubmit,
77541
78240
  modalTitle: modalTitlePrepared,
77542
78241
  modalDescriptionText: modalDescriptionTextPrepared,
77543
78242
  inputLabel: inputLabelPrepared,
@@ -77555,6 +78254,7 @@ const TaintsModal = ({
77555
78254
  const TolerationsModal = ({
77556
78255
  open,
77557
78256
  onClose,
78257
+ disableSubmit,
77558
78258
  reqIndex,
77559
78259
  jsonPathToArray,
77560
78260
  notificationSuccessMessage,
@@ -77625,6 +78325,7 @@ const TolerationsModal = ({
77625
78325
  close: onClose,
77626
78326
  values: tolerations,
77627
78327
  openNotificationSuccess,
78328
+ disableSubmit,
77628
78329
  modalTitle: modalTitlePrepared,
77629
78330
  modalDescriptionText: errorArrayOfObjects,
77630
78331
  modalDescriptionTextStyle,
@@ -77647,6 +78348,7 @@ const TolerationsModal = ({
77647
78348
  close: onClose,
77648
78349
  values: tolerations,
77649
78350
  openNotificationSuccess,
78351
+ disableSubmit,
77650
78352
  modalTitle: modalTitlePrepared,
77651
78353
  modalDescriptionText: modalDescriptionTextPrepared,
77652
78354
  modalDescriptionTextStyle,
@@ -77662,21 +78364,22 @@ const TolerationsModal = ({
77662
78364
  };
77663
78365
 
77664
78366
  const LazyEnrichedTableModal = lazy(
77665
- () => import('./index-C7wXx2NH.mjs').then((mod) => ({ default: mod.EnrichedTableModal }))
78367
+ () => import('./index-85og70S2.mjs').then((mod) => ({ default: mod.EnrichedTableModal }))
77666
78368
  );
77667
78369
  const renderActiveType = (activeType, extraProps) => {
77668
78370
  if (!activeType) return null;
78371
+ const { open, onClose, disableSubmit } = extraProps;
77669
78372
  switch (activeType.type) {
77670
78373
  case "labels":
77671
- return /* @__PURE__ */ jsxRuntimeExports.jsx(LabelsModal, { ...activeType.props, ...extraProps });
78374
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(LabelsModal, { ...activeType.props, open, onClose, disableSubmit });
77672
78375
  case "annotations":
77673
- return /* @__PURE__ */ jsxRuntimeExports.jsx(AnnotationsModal, { ...activeType.props, ...extraProps });
78376
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(AnnotationsModal, { ...activeType.props, open, onClose, disableSubmit });
77674
78377
  case "taints":
77675
- return /* @__PURE__ */ jsxRuntimeExports.jsx(TaintsModal, { ...activeType.props, ...extraProps });
78378
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(TaintsModal, { ...activeType.props, open, onClose, disableSubmit });
77676
78379
  case "tolerations":
77677
- return /* @__PURE__ */ jsxRuntimeExports.jsx(TolerationsModal, { ...activeType.props, ...extraProps });
78380
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(TolerationsModal, { ...activeType.props, open, onClose, disableSubmit });
77678
78381
  case "table":
77679
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyEnrichedTableModal, { ...activeType.props, ...extraProps }) });
78382
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(LazyEnrichedTableModal, { ...activeType.props, open, onClose }) });
77680
78383
  default: {
77681
78384
  const _exhaustive = activeType;
77682
78385
  return _exhaustive;
@@ -77735,7 +78438,7 @@ const CardIcon = styled.div`
77735
78438
  const HiddenContainer = styled.div`
77736
78439
  display: ${({ $isHidden }) => $isHidden ? "none" : "auto"};
77737
78440
  `;
77738
- const Styled$n = {
78441
+ const Styled$o = {
77739
78442
  Card: Card$1,
77740
78443
  CardTitle,
77741
78444
  CardNumber,
@@ -77743,6 +78446,7 @@ const Styled$n = {
77743
78446
  HiddenContainer
77744
78447
  };
77745
78448
 
78449
+ const isPatchActiveType = (value) => value?.type === "labels" || value?.type === "annotations" || value?.type === "taints" || value?.type === "tolerations";
77746
78450
  const AggregatedCounterCard = ({ data, children }) => {
77747
78451
  const {
77748
78452
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -77756,6 +78460,53 @@ const AggregatedCounterCard = ({ data, children }) => {
77756
78460
  const [open, setOpen] = useState(false);
77757
78461
  const { data: multiQueryData, isLoading: isMultiQueryLoading, isError: isMultiQueryErrors, errors } = useMultiQuery();
77758
78462
  const partsOfUrl = usePartsOfUrl();
78463
+ const safeMultiQueryData = multiQueryData || {};
78464
+ const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
78465
+ acc[index.toString()] = value;
78466
+ return acc;
78467
+ }, {});
78468
+ const patchActiveType = isPatchActiveType(activeType) ? activeType : void 0;
78469
+ const permissionContextPrepared = patchActiveType?.props.permissionContext ? {
78470
+ cluster: parseAll({
78471
+ text: patchActiveType.props.permissionContext.cluster,
78472
+ replaceValues,
78473
+ multiQueryData: safeMultiQueryData
78474
+ }),
78475
+ namespace: patchActiveType.props.permissionContext.namespace ? parseAll({
78476
+ text: patchActiveType.props.permissionContext.namespace,
78477
+ replaceValues,
78478
+ multiQueryData: safeMultiQueryData
78479
+ }) : void 0,
78480
+ apiGroup: patchActiveType.props.permissionContext.apiGroup ? parseAll({
78481
+ text: patchActiveType.props.permissionContext.apiGroup,
78482
+ replaceValues,
78483
+ multiQueryData: safeMultiQueryData
78484
+ }) : void 0,
78485
+ plural: parseAll({
78486
+ text: patchActiveType.props.permissionContext.plural,
78487
+ replaceValues,
78488
+ multiQueryData: safeMultiQueryData
78489
+ })
78490
+ } : void 0;
78491
+ const isPermissionContextValid = !!permissionContextPrepared && !isMultiQueryLoading && !!permissionContextPrepared.cluster && permissionContextPrepared.cluster !== "-" && !!permissionContextPrepared.plural && permissionContextPrepared.plural !== "-";
78492
+ const patchPermission = usePermissions({
78493
+ cluster: permissionContextPrepared?.cluster || "",
78494
+ namespace: permissionContextPrepared?.namespace,
78495
+ apiGroup: permissionContextPrepared?.apiGroup,
78496
+ plural: permissionContextPrepared?.plural || "",
78497
+ verb: "patch",
78498
+ refetchInterval: false,
78499
+ enabler: isPermissionContextValid
78500
+ });
78501
+ const canPatch = patchActiveType?.props.permissions?.canPatch ?? patchPermission.data?.status.allowed;
78502
+ const shouldGateEdit = Boolean(patchActiveType?.props.permissions || patchActiveType?.props.permissionContext);
78503
+ const canOpenActiveType = !!activeType;
78504
+ const canSubmitActiveType = !patchActiveType || !shouldGateEdit || canPatch === true;
78505
+ useEffect(() => {
78506
+ if (open && !canOpenActiveType) {
78507
+ setOpen(false);
78508
+ }
78509
+ }, [open, canOpenActiveType]);
77759
78510
  if (isMultiQueryLoading) {
77760
78511
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." });
77761
78512
  }
@@ -77765,22 +78516,18 @@ const AggregatedCounterCard = ({ data, children }) => {
77765
78516
  /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { children: errors.map((e, i) => e && /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: typeof e === "string" ? e : e.message }, i)) })
77766
78517
  ] });
77767
78518
  }
77768
- const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
77769
- acc[index.toString()] = value;
77770
- return acc;
77771
- }, {});
77772
78519
  const jsonRoot = multiQueryData[`req${counter.props.reqIndex}`];
77773
78520
  if (jsonRoot === void 0) {
77774
78521
  console.log(`Counter: ${id}: No root for json path`);
77775
78522
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
77776
- Styled$n.Card,
78523
+ Styled$o.Card,
77777
78524
  {
77778
78525
  $colorBorder: token.colorBorder,
77779
78526
  $colorBgContainer: token.colorBgContainer,
77780
78527
  $colorPrimary: token.colorPrimary,
77781
- $cursorPointer: !!activeType,
78528
+ $cursorPointer: canOpenActiveType,
77782
78529
  onClick: () => {
77783
- if (activeType) {
78530
+ if (canOpenActiveType) {
77784
78531
  setOpen(true);
77785
78532
  }
77786
78533
  return void 0;
@@ -77788,15 +78535,15 @@ const AggregatedCounterCard = ({ data, children }) => {
77788
78535
  children: [
77789
78536
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { gap: 4, vertical: true, children: [
77790
78537
  /* @__PURE__ */ jsxRuntimeExports.jsx(
77791
- Styled$n.CardTitle,
78538
+ Styled$o.CardTitle,
77792
78539
  {
77793
78540
  $colorTextDescription: token.colorTextDescription,
77794
78541
  children: `Counter: ${id}: No root for json path`
77795
78542
  }
77796
78543
  ),
77797
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.CardNumber, { $colorText: token.colorText, children: "-" })
78544
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$o.CardNumber, { $colorText: token.colorText, children: "-" })
77798
78545
  ] }),
77799
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.CardIcon, { $colorInfo: token.colorInfo, children: iconBase64Encoded && renderIcon$1(iconBase64Encoded, token.colorInfo) })
78546
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$o.CardIcon, { $colorInfo: token.colorInfo, children: iconBase64Encoded && renderIcon$1(iconBase64Encoded, token.colorInfo) })
77800
78547
  ]
77801
78548
  }
77802
78549
  );
@@ -77807,24 +78554,24 @@ const AggregatedCounterCard = ({ data, children }) => {
77807
78554
  if (errorParsingCounter) {
77808
78555
  console.log(`Counter: ${id}: ${errorParsingCounter}`);
77809
78556
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
77810
- Styled$n.Card,
78557
+ Styled$o.Card,
77811
78558
  {
77812
78559
  $colorBorder: token.colorBorder,
77813
78560
  $colorBgContainer: token.colorBgContainer,
77814
78561
  $colorPrimary: token.colorPrimary,
77815
- $cursorPointer: !!activeType,
78562
+ $cursorPointer: canOpenActiveType,
77816
78563
  onClick: () => {
77817
- if (activeType) {
78564
+ if (canOpenActiveType) {
77818
78565
  setOpen(true);
77819
78566
  }
77820
78567
  return void 0;
77821
78568
  },
77822
78569
  children: [
77823
78570
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { gap: 4, vertical: true, children: [
77824
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.CardTitle, { $colorTextDescription: token.colorTextDescription, children: errorParsingCounter }),
77825
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.CardNumber, { $colorText: token.colorText, children: "-" })
78571
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$o.CardTitle, { $colorTextDescription: token.colorTextDescription, children: errorParsingCounter }),
78572
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$o.CardNumber, { $colorText: token.colorText, children: "-" })
77826
78573
  ] }),
77827
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.CardIcon, { $colorInfo: token.colorInfo, children: iconBase64Encoded && renderIcon$1(iconBase64Encoded, token.colorInfo) })
78574
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$o.CardIcon, { $colorInfo: token.colorInfo, children: iconBase64Encoded && renderIcon$1(iconBase64Encoded, token.colorInfo) })
77828
78575
  ]
77829
78576
  }
77830
78577
  );
@@ -77832,28 +78579,32 @@ const AggregatedCounterCard = ({ data, children }) => {
77832
78579
  const parsedText = parseAll({ text, replaceValues, multiQueryData });
77833
78580
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
77834
78581
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
77835
- Styled$n.Card,
78582
+ Styled$o.Card,
77836
78583
  {
77837
78584
  $colorBorder: token.colorBorder,
77838
78585
  $colorBgContainer: token.colorBgContainer,
77839
78586
  $colorPrimary: token.colorPrimary,
77840
- $cursorPointer: !!activeType,
78587
+ $cursorPointer: canOpenActiveType,
77841
78588
  onClick: () => {
77842
- if (activeType) {
78589
+ if (canOpenActiveType) {
77843
78590
  setOpen(true);
77844
78591
  }
77845
78592
  return void 0;
77846
78593
  },
77847
78594
  children: [
77848
78595
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { gap: 4, vertical: true, children: [
77849
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.CardTitle, { $colorTextDescription: token.colorTextDescription, children: parsedText }),
77850
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.CardNumber, { $colorText: token.colorText, children: counterToDisplay })
78596
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$o.CardTitle, { $colorTextDescription: token.colorTextDescription, children: parsedText }),
78597
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$o.CardNumber, { $colorText: token.colorText, children: counterToDisplay })
77851
78598
  ] }),
77852
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.CardIcon, { $colorInfo: token.colorInfo, children: iconBase64Encoded && renderIcon$1(iconBase64Encoded, token.colorInfo) })
78599
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$o.CardIcon, { $colorInfo: token.colorInfo, children: iconBase64Encoded && renderIcon$1(iconBase64Encoded, token.colorInfo) })
77853
78600
  ]
77854
78601
  }
77855
78602
  ),
77856
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.HiddenContainer, { $isHidden: !open, children: renderActiveType(activeType, { open, onClose: () => setOpen(false) }) }),
78603
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$o.HiddenContainer, { $isHidden: !open, children: canOpenActiveType && renderActiveType(activeType, {
78604
+ open,
78605
+ onClose: () => setOpen(false),
78606
+ disableSubmit: !canSubmitActiveType
78607
+ }) }),
77857
78608
  children
77858
78609
  ] });
77859
78610
  };
@@ -78278,7 +79029,7 @@ const UsedBadge = styled.div`
78278
79029
  white-space: nowrap;
78279
79030
  z-index: 3;
78280
79031
  `;
78281
- const Styled$m = {
79032
+ const Styled$n = {
78282
79033
  TooltipContent,
78283
79034
  TooltipRow,
78284
79035
  TooltipDot,
@@ -78427,17 +79178,17 @@ const UsageGraphCard = ({
78427
79178
  const usedPercent = clampPercent(resolvedUsed ?? NaN, resolvedLimit ?? NaN);
78428
79179
  const limitPercent = 100;
78429
79180
  const gradientMidStop = `${requestedPercent.toFixed(2)}%`;
78430
- const tooltipTitle = /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$m.TooltipContent, { $colorInfoBgHover: token.colorInfoBgHover, children: [
78431
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$m.TooltipRow, { $colorText: token.colorText, children: [
78432
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.TooltipDot, { $color: "#5EDBBD" }),
79181
+ const tooltipTitle = /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$n.TooltipContent, { $colorInfoBgHover: token.colorInfoBgHover, children: [
79182
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$n.TooltipRow, { $colorText: token.colorText, children: [
79183
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.TooltipDot, { $color: "#5EDBBD" }),
78433
79184
  "Requested"
78434
79185
  ] }),
78435
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$m.TooltipRow, { $colorText: token.colorText, children: [
78436
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.TooltipDot, { $color: "#FF1C1C" }),
79186
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$n.TooltipRow, { $colorText: token.colorText, children: [
79187
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.TooltipDot, { $color: "#FF1C1C" }),
78437
79188
  "Used"
78438
79189
  ] }),
78439
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$m.TooltipRow, { $colorText: token.colorText, children: [
78440
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.TooltipDot, { $color: "#FD9125" }),
79190
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$n.TooltipRow, { $colorText: token.colorText, children: [
79191
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.TooltipDot, { $color: "#FD9125" }),
78441
79192
  "Limit"
78442
79193
  ] })
78443
79194
  ] });
@@ -78515,10 +79266,10 @@ const UsageGraphCard = ({
78515
79266
  observer.disconnect();
78516
79267
  };
78517
79268
  }, [updateUsedBadgeClamp, updateRequestedLabelClamp]);
78518
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$m.Wrapper, { style: containerStyle, $colorBgContainer: token.colorBgContainer, $colorBorder: token.colorBorder, children: [
78519
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.Header, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.Title, { $colorText: token.colorText, children: title }) }),
78520
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$m.ChartContainer, { children: [
78521
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.ChartWrapper, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.ChartInner, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(ComposedChart, { data: chartData, margin: { top: 8, right: 12, left: 12, bottom: 0 }, children: [
79269
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$n.Wrapper, { style: containerStyle, $colorBgContainer: token.colorBgContainer, $colorBorder: token.colorBorder, children: [
79270
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.Header, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.Title, { $colorText: token.colorText, children: title }) }),
79271
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$n.ChartContainer, { children: [
79272
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.ChartWrapper, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.ChartInner, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(ResponsiveContainer, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(ComposedChart, { data: chartData, margin: { top: 8, right: 12, left: 12, bottom: 0 }, children: [
78522
79273
  /* @__PURE__ */ jsxRuntimeExports.jsx(XAxis, { dataKey: "index", hide: true }),
78523
79274
  /* @__PURE__ */ jsxRuntimeExports.jsx(YAxis, { hide: true, domain: yDomain, padding: { top: 6, bottom: 24 } }),
78524
79275
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -78542,9 +79293,9 @@ const UsageGraphCard = ({
78542
79293
  }
78543
79294
  )
78544
79295
  ] }) }) }) }),
78545
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.ChartOverlay, { $isDark: isDark })
79296
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.ChartOverlay, { $isDark: isDark })
78546
79297
  ] }),
78547
- /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.GradientBarWrapper, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$m.GradientBarContainer, { children: [
79298
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.GradientBarWrapper, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$n.GradientBarContainer, { children: [
78548
79299
  /* @__PURE__ */ jsxRuntimeExports.jsx(
78549
79300
  Tooltip$1,
78550
79301
  {
@@ -78556,7 +79307,7 @@ const UsageGraphCard = ({
78556
79307
  body: { padding: 0, borderRadius: 6 }
78557
79308
  },
78558
79309
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(
78559
- Styled$m.GradientBar,
79310
+ Styled$n.GradientBar,
78560
79311
  {
78561
79312
  $minColor: minColor,
78562
79313
  $midColor: midColor,
@@ -78566,12 +79317,12 @@ const UsageGraphCard = ({
78566
79317
  )
78567
79318
  }
78568
79319
  ),
78569
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$m.BadgesContainer, { ref: badgesContainerRef, children: [
78570
- resolvedRequested !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.BarMarker, { $left: requestedPercent, $edgeAlign: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(RequestedMarkerSvg, {}) }),
78571
- resolvedUsed !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.BarMarker, { $left: usedPercent, $flipX: true, $paddingTop: 10, children: /* @__PURE__ */ jsxRuntimeExports.jsx(UsedMarkerSvg, {}) }),
78572
- resolvedLimit !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.BarMarker, { $left: limitPercent, children: /* @__PURE__ */ jsxRuntimeExports.jsx(LimitMarkerSvg, {}) }),
79320
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Styled$n.BadgesContainer, { ref: badgesContainerRef, children: [
79321
+ resolvedRequested !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.BarMarker, { $left: requestedPercent, $edgeAlign: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(RequestedMarkerSvg, {}) }),
79322
+ resolvedUsed !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.BarMarker, { $left: usedPercent, $flipX: true, $paddingTop: 10, children: /* @__PURE__ */ jsxRuntimeExports.jsx(UsedMarkerSvg, {}) }),
79323
+ resolvedLimit !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$n.BarMarker, { $left: limitPercent, children: /* @__PURE__ */ jsxRuntimeExports.jsx(LimitMarkerSvg, {}) }),
78573
79324
  resolvedUsed !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
78574
- Styled$m.UsedBadge,
79325
+ Styled$n.UsedBadge,
78575
79326
  {
78576
79327
  ref: usedBadgeRef,
78577
79328
  $left: clampedUsedPercent ?? usedPercent,
@@ -78593,7 +79344,7 @@ const UsageGraphCard = ({
78593
79344
  }
78594
79345
  ),
78595
79346
  resolvedRequested !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
78596
- Styled$m.MarkerLabel,
79347
+ Styled$n.MarkerLabel,
78597
79348
  {
78598
79349
  ref: requestedLabelRef,
78599
79350
  $left: clampedRequestedPercent ?? requestedPercent,
@@ -78614,7 +79365,7 @@ const UsageGraphCard = ({
78614
79365
  }
78615
79366
  ),
78616
79367
  resolvedLimit !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
78617
- Styled$m.MarkerLabel,
79368
+ Styled$n.MarkerLabel,
78618
79369
  {
78619
79370
  ref: limitLabelRef,
78620
79371
  $left: limitPercent,
@@ -78640,6 +79391,77 @@ const UsageGraphCard = ({
78640
79391
  ] });
78641
79392
  };
78642
79393
 
79394
+ const ACTION_REQUIRED_PERMISSIONS = {
79395
+ edit: { verb: "update" },
79396
+ editLabels: { verb: "patch" },
79397
+ editAnnotations: { verb: "patch" },
79398
+ editTaints: { verb: "patch" },
79399
+ editTolerations: { verb: "patch" },
79400
+ delete: { verb: "delete" },
79401
+ cordon: { verb: "patch" },
79402
+ uncordon: { verb: "patch" },
79403
+ suspend: { verb: "patch" },
79404
+ resume: { verb: "patch" },
79405
+ rolloutRestart: { verb: "patch" },
79406
+ evict: { verb: "create", subresource: "eviction" },
79407
+ openKubeletConfig: { verb: "get", subresource: "proxy" },
79408
+ scale: { verb: "update", subresource: "scale" },
79409
+ triggerRun: { verb: "create" },
79410
+ deleteChildren: { verb: "delete" },
79411
+ rerunLast: { verb: "create" },
79412
+ drain: { verb: "patch" },
79413
+ rollback: { verb: "patch" }
79414
+ };
79415
+
79416
+ const IconWrapper = styled.span`
79417
+ display: inline-flex;
79418
+ width: 14px;
79419
+ height: 14px;
79420
+ align-items: center;
79421
+ justify-content: center;
79422
+ `;
79423
+ const IconScaler = styled.span`
79424
+ display: inline-flex;
79425
+ transform: scale(0.58);
79426
+ `;
79427
+ const IconButton = styled(Button)`
79428
+ height: 24px;
79429
+
79430
+ .anticon {
79431
+ font-size: 16px;
79432
+ }
79433
+ `;
79434
+ const Styled$m = {
79435
+ IconWrapper,
79436
+ IconScaler,
79437
+ IconButton
79438
+ };
79439
+
79440
+ const UNDEFINED_FALLBACK = "Undefined with no fallback";
79441
+ const isMeaningfulValue = (value) => value.length > 0 && value !== "-" && value !== UNDEFINED_FALLBACK;
79442
+ const getVisibleActions = (actions, { replaceValues, multiQueryData }) => {
79443
+ return actions.flatMap((action, index) => {
79444
+ const condition = action.props.visibleWhen;
79445
+ if (!condition) {
79446
+ return [{ action, actionKey: `${action.type}-${index}` }];
79447
+ }
79448
+ const currentValue = parseAll({ text: condition.value, replaceValues, multiQueryData });
79449
+ const hasValue = isMeaningfulValue(currentValue);
79450
+ if (condition.criteria === "exists") {
79451
+ return hasValue ? [{ action, actionKey: `${action.type}-${index}` }] : [];
79452
+ }
79453
+ if (condition.criteria === "notExists") {
79454
+ return !hasValue ? [{ action, actionKey: `${action.type}-${index}` }] : [];
79455
+ }
79456
+ if (condition.valueToCompare === void 0) {
79457
+ return [{ action, actionKey: `${action.type}-${index}` }];
79458
+ }
79459
+ const expectedValues = (Array.isArray(condition.valueToCompare) ? condition.valueToCompare : [condition.valueToCompare]).map((value) => parseAll({ text: value, replaceValues, multiQueryData }));
79460
+ const matches = expectedValues.includes(currentValue);
79461
+ const isVisible = condition.criteria === "equals" ? matches : !matches;
79462
+ return isVisible ? [{ action, actionKey: `${action.type}-${index}` }] : [];
79463
+ });
79464
+ };
78643
79465
  const buildEditUrl = (props, fullPath) => {
78644
79466
  const { cluster, namespace, syntheticProject, apiGroup, apiVersion, plural, name, baseprefix = "" } = props;
78645
79467
  const pathPrefix = !apiGroup || apiGroup.length === 0 ? "forms/builtin" : "forms/apis";
@@ -78657,6 +79479,673 @@ const buildEditUrl = (props, fullPath) => {
78657
79479
  ].filter(Boolean);
78658
79480
  return `/${parts.join("/")}?backlink=${backlink}`;
78659
79481
  };
79482
+ const getActionIcon = (action) => {
79483
+ if (action.props.iconBase64Encoded) {
79484
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.IconWrapper, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$m.IconScaler, { children: renderIcon$1(action.props.iconBase64Encoded, "currentColor") }) });
79485
+ }
79486
+ if (action.props.icon) {
79487
+ return renderAntIcon(action.props.icon);
79488
+ }
79489
+ return void 0;
79490
+ };
79491
+ const isActionDisabledByPermission = (actionKey, permissions) => {
79492
+ return permissions[actionKey] !== true;
79493
+ };
79494
+ const getMenuItems = (visibleActions, onActionClick, permissions) => visibleActions.map(({ action, actionKey }) => ({
79495
+ key: actionKey,
79496
+ label: action.props.tooltip ? /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip$1, { title: action.props.tooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: action.props.text }) }) : action.props.text,
79497
+ icon: getActionIcon(action),
79498
+ disabled: action.props.disabled || isActionDisabledByPermission(actionKey, permissions),
79499
+ danger: action.props.danger,
79500
+ onClick: () => onActionClick(action)
79501
+ }));
79502
+
79503
+ const parseValueIfString = (value, ctx) => {
79504
+ if (typeof value === "string") {
79505
+ return parseAll({ text: value, ...ctx });
79506
+ }
79507
+ return value;
79508
+ };
79509
+ const resolveObjectFromTemplate = (template, multiQueryData) => {
79510
+ const match = template.match(/^\{reqs\[(\d+)\]\[((?:\s*['"][^'"]+['"]\s*,?)+)\]\}$/);
79511
+ if (match) {
79512
+ const reqIndex = parseInt(match[1], 10);
79513
+ const pathKeys = Array.from(match[2].matchAll(/['"]([^'"]+)['"]/g)).map((m) => m[1]);
79514
+ const reqData = multiQueryData[`req${reqIndex}`];
79515
+ if (reqData != null) {
79516
+ return _$1.get(reqData, pathKeys);
79517
+ }
79518
+ }
79519
+ return void 0;
79520
+ };
79521
+ const buildEvictModalData = (props, ctx) => {
79522
+ const endpointPrepared = parseAll({ text: props.endpoint, ...ctx });
79523
+ const namePrepared = parseAll({ text: props.name, ...ctx });
79524
+ const namespacePrepared = props.namespace ? parseAll({ text: props.namespace, ...ctx }) : void 0;
79525
+ const apiVersionPrepared = props.apiVersion ? parseAll({ text: props.apiVersion, ...ctx }) : "policy/v1";
79526
+ return {
79527
+ endpoint: endpointPrepared,
79528
+ name: namePrepared,
79529
+ namespace: namespacePrepared,
79530
+ apiVersion: apiVersionPrepared,
79531
+ gracePeriodSeconds: props.gracePeriodSeconds,
79532
+ dryRun: props.dryRun
79533
+ };
79534
+ };
79535
+ const buildEvictBody = (data) => {
79536
+ const deleteOptions = {};
79537
+ if (data.gracePeriodSeconds !== void 0) {
79538
+ deleteOptions.gracePeriodSeconds = data.gracePeriodSeconds;
79539
+ }
79540
+ if (data.dryRun && data.dryRun.length > 0) {
79541
+ deleteOptions.dryRun = data.dryRun;
79542
+ }
79543
+ return {
79544
+ apiVersion: data.apiVersion,
79545
+ kind: "Eviction",
79546
+ metadata: {
79547
+ name: data.name,
79548
+ ...data.namespace ? { namespace: data.namespace } : {}
79549
+ },
79550
+ ...Object.keys(deleteOptions).length > 0 ? { deleteOptions } : {}
79551
+ };
79552
+ };
79553
+ const buildDeleteChildrenData = (action, ctx) => {
79554
+ const childResourceNamePrepared = parseAll({ text: action.props.childResourceName, ...ctx });
79555
+ const childrenTemplatePrepared = parseWithoutPartsOfUrl({
79556
+ text: action.props.children,
79557
+ multiQueryData: ctx.multiQueryData
79558
+ });
79559
+ let parsedChildren;
79560
+ try {
79561
+ parsedChildren = JSON.parse(childrenTemplatePrepared);
79562
+ } catch {
79563
+ throw new Error("Could not parse children data");
79564
+ }
79565
+ if (!Array.isArray(parsedChildren)) {
79566
+ throw new Error("No children found to delete");
79567
+ }
79568
+ const children = parsedChildren.filter(
79569
+ (el) => typeof el === "object" && el !== null && typeof el.name === "string" && typeof el.endpoint === "string"
79570
+ ).map((el) => ({
79571
+ name: parsePartsOfUrl({ template: el.name, replaceValues: ctx.replaceValues }),
79572
+ endpoint: parsePartsOfUrl({ template: el.endpoint, replaceValues: ctx.replaceValues })
79573
+ }));
79574
+ if (children.length === 0) {
79575
+ throw new Error("No children found to delete");
79576
+ }
79577
+ return {
79578
+ children,
79579
+ childResourceName: childResourceNamePrepared
79580
+ };
79581
+ };
79582
+ const handleEditAction = (action, ctx, fullPath, navigate) => {
79583
+ const clusterPrepared = parseAll({ text: action.props.cluster, ...ctx });
79584
+ const namespacePrepared = action.props.namespace ? parseAll({ text: action.props.namespace, ...ctx }) : void 0;
79585
+ const syntheticProjectPrepared = action.props.syntheticProject ? parseAll({ text: action.props.syntheticProject, ...ctx }) : void 0;
79586
+ const apiGroupPrepared = action.props.apiGroup ? parseAll({ text: action.props.apiGroup, ...ctx }) : void 0;
79587
+ const apiVersionPrepared = parseAll({ text: action.props.apiVersion, ...ctx });
79588
+ const pluralPrepared = parseAll({ text: action.props.plural, ...ctx });
79589
+ const namePrepared = parseAll({ text: action.props.name, ...ctx });
79590
+ const baseprefixPrepared = action.props.baseprefix ? parseAll({ text: action.props.baseprefix, ...ctx }) : void 0;
79591
+ const url = buildEditUrl(
79592
+ {
79593
+ ...action.props,
79594
+ cluster: clusterPrepared,
79595
+ namespace: namespacePrepared,
79596
+ syntheticProject: syntheticProjectPrepared,
79597
+ apiGroup: apiGroupPrepared,
79598
+ apiVersion: apiVersionPrepared,
79599
+ plural: pluralPrepared,
79600
+ name: namePrepared,
79601
+ baseprefix: baseprefixPrepared
79602
+ },
79603
+ fullPath
79604
+ );
79605
+ navigate(url);
79606
+ };
79607
+ const handleDeleteAction = (action, ctx, setDeleteModalData) => {
79608
+ const endpointPrepared = parseAll({ text: action.props.endpoint, ...ctx });
79609
+ const namePrepared = parseAll({ text: action.props.name, ...ctx });
79610
+ const redirectToPrepared = action.props.redirectTo ? parseAll({ text: action.props.redirectTo, ...ctx }) : void 0;
79611
+ setDeleteModalData({
79612
+ name: namePrepared,
79613
+ endpoint: endpointPrepared,
79614
+ redirectTo: redirectToPrepared
79615
+ });
79616
+ };
79617
+ const handlePatchActions = (action, ctx, onSuccess, onError) => {
79618
+ const actionLabel = action.props.text || action.type;
79619
+ const endpointPrepared = parseAll({ text: action.props.endpoint, ...ctx });
79620
+ const pathToValuePrepared = parseAll({ text: action.props.pathToValue, ...ctx });
79621
+ const valuePrepared = parseValueIfString(action.props.value, ctx);
79622
+ patchEntryWithReplaceOp({
79623
+ endpoint: endpointPrepared,
79624
+ pathToValue: pathToValuePrepared,
79625
+ body: valuePrepared
79626
+ }).then(() => onSuccess(actionLabel)).catch((error) => {
79627
+ onError(actionLabel, error);
79628
+ });
79629
+ };
79630
+ const handleRolloutRestartAction = (action, ctx, onSuccess, onError) => {
79631
+ const actionLabel = action.props.text || "Rollout restart";
79632
+ const endpointPrepared = parseAll({ text: action.props.endpoint, ...ctx });
79633
+ const annotationKeyPrepared = action.props.annotationKey ? parseAll({ text: action.props.annotationKey, ...ctx }) : "kubectl.kubernetes.io/restartedAt";
79634
+ const timestampPrepared = action.props.timestamp ? parseAll({ text: action.props.timestamp, ...ctx }) : (/* @__PURE__ */ new Date()).toISOString();
79635
+ patchEntryWithMergePatch({
79636
+ endpoint: endpointPrepared,
79637
+ body: {
79638
+ spec: {
79639
+ template: {
79640
+ metadata: {
79641
+ annotations: {
79642
+ [annotationKeyPrepared]: timestampPrepared
79643
+ }
79644
+ }
79645
+ }
79646
+ }
79647
+ }
79648
+ }).then(() => onSuccess(actionLabel)).catch((error) => {
79649
+ onError(actionLabel, error);
79650
+ });
79651
+ };
79652
+ const handleOpenKubeletConfigAction = (action, ctx, setActiveAction, setModalOpen) => {
79653
+ const urlPrepared = parseAll({ text: action.props.url, ...ctx });
79654
+ const modalTitlePrepared = action.props.modalTitle ? parseAll({ text: action.props.modalTitle, ...ctx }) : void 0;
79655
+ const modalDescriptionTextPrepared = action.props.modalDescriptionText ? parseAll({ text: action.props.modalDescriptionText, ...ctx }) : void 0;
79656
+ setActiveAction({
79657
+ ...action,
79658
+ props: {
79659
+ ...action.props,
79660
+ url: urlPrepared,
79661
+ modalTitle: modalTitlePrepared,
79662
+ modalDescriptionText: modalDescriptionTextPrepared
79663
+ }
79664
+ });
79665
+ setModalOpen(true);
79666
+ };
79667
+ const generateDnsCompliantName = (prefix, maxLength = 63) => {
79668
+ const timestamp = Date.now();
79669
+ const randomHex = Math.random().toString(16).substring(2, 6);
79670
+ const suffix = `-${timestamp}-${randomHex}`;
79671
+ const truncatedPrefix = prefix.substring(0, maxLength - suffix.length);
79672
+ return `${truncatedPrefix}${suffix}`.toLowerCase().replace(/[^a-z0-9-]/g, "-");
79673
+ };
79674
+ const JOB_MANAGED_LABEL_KEYS = [
79675
+ "controller-uid",
79676
+ "job-name",
79677
+ "batch.kubernetes.io/controller-uid",
79678
+ "batch.kubernetes.io/job-name"
79679
+ ];
79680
+ const stripManagedJobLabels = (labels) => {
79681
+ if (!labels || typeof labels !== "object" || Array.isArray(labels)) {
79682
+ return void 0;
79683
+ }
79684
+ const cleaned = { ...labels };
79685
+ JOB_MANAGED_LABEL_KEYS.forEach((key) => delete cleaned[key]);
79686
+ return Object.keys(cleaned).length > 0 ? cleaned : void 0;
79687
+ };
79688
+ const stripMetadataForRerun = (sourceObj, sourceJobName) => {
79689
+ const normalizedSourceObj = _$1.isPlainObject(_$1.get(sourceObj, "spec")) ? sourceObj : _$1.isPlainObject(sourceObj) && _$1.isPlainObject(_$1.get(sourceObj, "template")) ? { spec: sourceObj } : sourceObj;
79690
+ const copy = JSON.parse(JSON.stringify(normalizedSourceObj));
79691
+ const oldMeta = copy.metadata ?? {};
79692
+ const cleanedMetadataLabels = stripManagedJobLabels(oldMeta.labels);
79693
+ copy.metadata = {
79694
+ ...oldMeta.namespace ? { namespace: oldMeta.namespace } : {},
79695
+ ...cleanedMetadataLabels ? { labels: cleanedMetadataLabels } : {},
79696
+ ...oldMeta.annotations ? { annotations: oldMeta.annotations } : {},
79697
+ generateName: `${sourceJobName}-rerun-`
79698
+ };
79699
+ const spec = _$1.get(copy, "spec");
79700
+ if (_$1.isPlainObject(spec)) {
79701
+ const specObj = spec;
79702
+ delete specObj.selector;
79703
+ delete specObj.manualSelector;
79704
+ }
79705
+ const templateLabels = _$1.get(copy, "spec.template.metadata.labels");
79706
+ if (_$1.isPlainObject(templateLabels)) {
79707
+ const cleanedTemplateLabels = stripManagedJobLabels(templateLabels);
79708
+ if (cleanedTemplateLabels) {
79709
+ _$1.set(copy, "spec.template.metadata.labels", cleanedTemplateLabels);
79710
+ } else {
79711
+ _$1.unset(copy, "spec.template.metadata.labels");
79712
+ }
79713
+ }
79714
+ delete copy.status;
79715
+ return copy;
79716
+ };
79717
+ const useScaleHandlers = (ctx, { showSuccess, showError }) => {
79718
+ const [scaleModalData, setScaleModalData] = useState(null);
79719
+ const [isScaleLoading, setIsScaleLoading] = useState(false);
79720
+ const handleScaleAction = (action) => {
79721
+ const endpointPrepared = parseAll({ text: action.props.endpoint, ...ctx });
79722
+ const namePrepared = parseAll({ text: action.props.name, ...ctx });
79723
+ const namespacePrepared = action.props.namespace ? parseAll({ text: action.props.namespace, ...ctx }) : void 0;
79724
+ const apiVersionPrepared = action.props.apiVersion ? parseAll({ text: action.props.apiVersion, ...ctx }) : "autoscaling/v1";
79725
+ const currentReplicasStr = parseAll({ text: action.props.currentReplicas, ...ctx });
79726
+ const currentReplicas = parseInt(currentReplicasStr, 10) || 0;
79727
+ setScaleModalData({
79728
+ endpoint: endpointPrepared,
79729
+ currentReplicas,
79730
+ name: namePrepared,
79731
+ namespace: namespacePrepared,
79732
+ apiVersion: apiVersionPrepared
79733
+ });
79734
+ };
79735
+ const handleScaleConfirm = (newReplicas) => {
79736
+ if (!scaleModalData) return;
79737
+ setIsScaleLoading(true);
79738
+ const body = {
79739
+ apiVersion: scaleModalData.apiVersion,
79740
+ kind: "Scale",
79741
+ metadata: {
79742
+ name: scaleModalData.name,
79743
+ ...scaleModalData.namespace ? { namespace: scaleModalData.namespace } : {}
79744
+ },
79745
+ spec: { replicas: newReplicas }
79746
+ };
79747
+ const scaleLabel = `Scale ${scaleModalData.name}`;
79748
+ updateEntry({ endpoint: scaleModalData.endpoint, body }).then(() => showSuccess(scaleLabel)).catch((error) => {
79749
+ showError(scaleLabel, error);
79750
+ }).finally(() => {
79751
+ setIsScaleLoading(false);
79752
+ setScaleModalData(null);
79753
+ });
79754
+ };
79755
+ const handleScaleCancel = () => {
79756
+ setScaleModalData(null);
79757
+ setIsScaleLoading(false);
79758
+ };
79759
+ return { scaleModalData, isScaleLoading, handleScaleAction, handleScaleConfirm, handleScaleCancel };
79760
+ };
79761
+ const useEvictHandlers = ({ showSuccess, showError }) => {
79762
+ const [evictModalData, setEvictModalData] = useState(null);
79763
+ const [isEvictLoading, setIsEvictLoading] = useState(false);
79764
+ const handleEvictConfirm = () => {
79765
+ if (!evictModalData) return;
79766
+ setIsEvictLoading(true);
79767
+ const body = buildEvictBody(evictModalData);
79768
+ const evictLabel = `Evict ${evictModalData.name}`;
79769
+ createNewEntry({ endpoint: evictModalData.endpoint, body }).then(() => showSuccess(evictLabel)).catch((error) => {
79770
+ showError(evictLabel, error);
79771
+ }).finally(() => {
79772
+ setIsEvictLoading(false);
79773
+ setEvictModalData(null);
79774
+ });
79775
+ };
79776
+ const handleEvictCancel = () => {
79777
+ setEvictModalData(null);
79778
+ setIsEvictLoading(false);
79779
+ };
79780
+ return { evictModalData, isEvictLoading, setEvictModalData, handleEvictConfirm, handleEvictCancel };
79781
+ };
79782
+ const useRerunHandlers = (ctx, multiQueryData, { showSuccess, showError }) => {
79783
+ const [rerunModalData, setRerunModalData] = useState(null);
79784
+ const [isRerunLoading, setIsRerunLoading] = useState(false);
79785
+ const handleRerunLastAction = (action) => {
79786
+ const createEndpointPrepared = parseAll({ text: action.props.createEndpoint, ...ctx });
79787
+ const sourceJobNamePrepared = parseAll({ text: action.props.sourceJobName, ...ctx });
79788
+ const sourceJobObj = resolveObjectFromTemplate(action.props.sourceJobSpec, multiQueryData);
79789
+ if (!sourceJobObj) {
79790
+ showError("Rerun job", new Error("Could not resolve source job spec from resource data"));
79791
+ return;
79792
+ }
79793
+ setRerunModalData({
79794
+ createEndpoint: createEndpointPrepared,
79795
+ sourceName: sourceJobNamePrepared,
79796
+ sourceSpec: sourceJobObj
79797
+ });
79798
+ };
79799
+ const handleRerunConfirm = () => {
79800
+ if (!rerunModalData) return;
79801
+ setIsRerunLoading(true);
79802
+ const body = stripMetadataForRerun(rerunModalData.sourceSpec, rerunModalData.sourceName);
79803
+ const rerunLabel = `Rerun ${rerunModalData.sourceName}`;
79804
+ createNewEntry({ endpoint: rerunModalData.createEndpoint, body }).then(() => showSuccess(rerunLabel)).catch((error) => {
79805
+ showError(rerunLabel, error);
79806
+ }).finally(() => {
79807
+ setIsRerunLoading(false);
79808
+ setRerunModalData(null);
79809
+ });
79810
+ };
79811
+ const handleRerunCancel = () => {
79812
+ setRerunModalData(null);
79813
+ setIsRerunLoading(false);
79814
+ };
79815
+ return { rerunModalData, isRerunLoading, handleRerunLastAction, handleRerunConfirm, handleRerunCancel };
79816
+ };
79817
+ const fireTriggerRunAction = (action, ctx, multiQueryData, { showSuccess, showError }) => {
79818
+ const createEndpointPrepared = parseAll({ text: action.props.createEndpoint, ...ctx });
79819
+ const cronJobNamePrepared = parseAll({ text: action.props.cronJobName, ...ctx });
79820
+ const jobTemplateObj = resolveObjectFromTemplate(action.props.jobTemplate, multiQueryData);
79821
+ if (!jobTemplateObj) {
79822
+ showError("Trigger run", new Error("Could not resolve job template from resource data"));
79823
+ return;
79824
+ }
79825
+ const jobName = generateDnsCompliantName(`${cronJobNamePrepared}-manual`);
79826
+ const namespaceParsed = cronJobNamePrepared ? _$1.get(jobTemplateObj, ["metadata", "namespace"]) : void 0;
79827
+ const body = {
79828
+ apiVersion: "batch/v1",
79829
+ kind: "Job",
79830
+ metadata: {
79831
+ name: jobName,
79832
+ ...namespaceParsed ? { namespace: namespaceParsed } : {},
79833
+ annotations: {
79834
+ "cronjob.kubernetes.io/instantiate": "manual"
79835
+ }
79836
+ },
79837
+ spec: jobTemplateObj.spec
79838
+ };
79839
+ const triggerLabel = `Trigger run for ${cronJobNamePrepared}`;
79840
+ createNewEntry({ endpoint: createEndpointPrepared, body }).then(() => showSuccess(triggerLabel)).catch((error) => {
79841
+ showError(triggerLabel, error);
79842
+ });
79843
+ };
79844
+ const useActionsDropdownHandlers = ({ replaceValues, multiQueryData }) => {
79845
+ const navigate = useNavigate();
79846
+ const location = useLocation();
79847
+ const [searchParams] = useSearchParams();
79848
+ const queryClient = useQueryClient();
79849
+ const [notificationApi, notificationContextHolder] = notification.useNotification();
79850
+ const fullPath = location.pathname + location.search;
79851
+ const [activeAction, setActiveAction] = useState(null);
79852
+ const [modalOpen, setModalOpen] = useState(false);
79853
+ const [deleteModalData, setDeleteModalData] = useState(null);
79854
+ const [deleteChildrenModalData, setDeleteChildrenModalData] = useState(null);
79855
+ const invalidateMultiQuery = () => {
79856
+ queryClient.invalidateQueries({ queryKey: ["multi"] });
79857
+ };
79858
+ const showSuccess = (actionLabel) => {
79859
+ invalidateMultiQuery();
79860
+ notificationApi.success({
79861
+ message: `${actionLabel} successful`,
79862
+ placement: "bottomRight"
79863
+ });
79864
+ };
79865
+ const getErrorDescription = (error) => {
79866
+ if (error instanceof AxiosError) {
79867
+ return error.response?.data?.message || error.message;
79868
+ }
79869
+ if (error instanceof Error) {
79870
+ return error.message;
79871
+ }
79872
+ return "Unknown error";
79873
+ };
79874
+ const showError = (actionLabel, error) => {
79875
+ notificationApi.error({
79876
+ message: `${actionLabel} failed`,
79877
+ description: getErrorDescription(error),
79878
+ placement: "bottomRight"
79879
+ });
79880
+ };
79881
+ const ctx = { replaceValues, multiQueryData };
79882
+ const notificationCallbacks = { showSuccess, showError };
79883
+ const { scaleModalData, isScaleLoading, handleScaleAction, handleScaleConfirm, handleScaleCancel } = useScaleHandlers(
79884
+ ctx,
79885
+ notificationCallbacks
79886
+ );
79887
+ const { evictModalData, isEvictLoading, setEvictModalData, handleEvictConfirm, handleEvictCancel } = useEvictHandlers(notificationCallbacks);
79888
+ const { rerunModalData, isRerunLoading, handleRerunLastAction, handleRerunConfirm, handleRerunCancel } = useRerunHandlers(ctx, multiQueryData, notificationCallbacks);
79889
+ const handleDeleteChildrenAction = (action) => {
79890
+ try {
79891
+ const data = buildDeleteChildrenData(action, ctx);
79892
+ setDeleteChildrenModalData(data);
79893
+ } catch (error) {
79894
+ const childResourceNamePrepared = parseAll({ text: action.props.childResourceName, ...ctx });
79895
+ showError(`Delete ${childResourceNamePrepared}`, error);
79896
+ }
79897
+ };
79898
+ const handleDeleteChildrenClose = () => {
79899
+ setDeleteChildrenModalData(null);
79900
+ invalidateMultiQuery();
79901
+ };
79902
+ const handleActionClick = (action) => {
79903
+ if (action.type === "edit") {
79904
+ handleEditAction(action, ctx, fullPath, navigate);
79905
+ return;
79906
+ }
79907
+ if (action.type === "delete") {
79908
+ handleDeleteAction(action, ctx, setDeleteModalData);
79909
+ return;
79910
+ }
79911
+ if (action.type === "cordon" || action.type === "uncordon" || action.type === "suspend" || action.type === "resume") {
79912
+ handlePatchActions(action, ctx, showSuccess, showError);
79913
+ return;
79914
+ }
79915
+ if (action.type === "rolloutRestart") {
79916
+ handleRolloutRestartAction(action, ctx, showSuccess, showError);
79917
+ return;
79918
+ }
79919
+ if (action.type === "evict") {
79920
+ const evictData = buildEvictModalData(action.props, ctx);
79921
+ setEvictModalData(evictData);
79922
+ return;
79923
+ }
79924
+ if (action.type === "openKubeletConfig") {
79925
+ handleOpenKubeletConfigAction(action, ctx, setActiveAction, setModalOpen);
79926
+ return;
79927
+ }
79928
+ if (action.type === "scale") {
79929
+ handleScaleAction(action);
79930
+ return;
79931
+ }
79932
+ if (action.type === "triggerRun") {
79933
+ fireTriggerRunAction(action, ctx, multiQueryData, notificationCallbacks);
79934
+ return;
79935
+ }
79936
+ if (action.type === "deleteChildren") {
79937
+ handleDeleteChildrenAction(action);
79938
+ return;
79939
+ }
79940
+ if (action.type === "rerunLast") {
79941
+ handleRerunLastAction(action);
79942
+ return;
79943
+ }
79944
+ if (action.type === "drain" || action.type === "rollback") {
79945
+ return;
79946
+ }
79947
+ setActiveAction(action);
79948
+ setModalOpen(true);
79949
+ };
79950
+ const handleCloseModal = () => {
79951
+ setModalOpen(false);
79952
+ setActiveAction(null);
79953
+ };
79954
+ const handleDeleteModalClose = () => {
79955
+ const redirectTo = deleteModalData?.redirectTo;
79956
+ const backlink = searchParams.get("backlink");
79957
+ setDeleteModalData(null);
79958
+ if (redirectTo) {
79959
+ navigate(redirectTo);
79960
+ } else if (backlink) {
79961
+ navigate(decodeURIComponent(backlink));
79962
+ }
79963
+ };
79964
+ return {
79965
+ notificationContextHolder,
79966
+ activeAction,
79967
+ modalOpen,
79968
+ deleteModalData,
79969
+ evictModalData,
79970
+ isEvictLoading,
79971
+ scaleModalData,
79972
+ isScaleLoading,
79973
+ deleteChildrenModalData,
79974
+ rerunModalData,
79975
+ isRerunLoading,
79976
+ handleActionClick,
79977
+ handleCloseModal,
79978
+ handleDeleteModalClose,
79979
+ handleEvictConfirm,
79980
+ handleEvictCancel,
79981
+ handleScaleConfirm,
79982
+ handleScaleCancel,
79983
+ handleDeleteChildrenClose,
79984
+ handleRerunConfirm,
79985
+ handleRerunCancel
79986
+ };
79987
+ };
79988
+
79989
+ const buildCacheKey = (slot) => `${slot.cluster}|${slot.namespace ?? ""}|${slot.apiGroup ?? ""}|${slot.plural}|${slot.subresource ?? ""}|${slot.verb}`;
79990
+ const parsePermissionContext = (ctx, parseCtx) => ({
79991
+ cluster: parseAll({ text: ctx.cluster, ...parseCtx }),
79992
+ namespace: ctx.namespace ? parseAll({ text: ctx.namespace, ...parseCtx }) : void 0,
79993
+ apiGroup: ctx.apiGroup ? parseAll({ text: ctx.apiGroup, ...parseCtx }) : void 0,
79994
+ plural: parseAll({ text: ctx.plural, ...parseCtx }),
79995
+ subresource: ctx.subresource ? parseAll({ text: ctx.subresource, ...parseCtx }) : void 0
79996
+ });
79997
+ const isValidContext = (parsed) => !!parsed.cluster && parsed.cluster !== "-" && !!parsed.plural && parsed.plural !== "-";
79998
+ const useManyPermissions = (slots, enabled) => {
79999
+ return useQueries({
80000
+ queries: slots.map((slot) => ({
80001
+ queryKey: [
80002
+ "usePermissions",
80003
+ slot.cluster,
80004
+ slot.namespace,
80005
+ slot.apiGroup,
80006
+ slot.plural,
80007
+ slot.subresource,
80008
+ slot.verb,
80009
+ void 0
80010
+ ],
80011
+ queryFn: async () => (await checkPermission({
80012
+ cluster: slot.cluster,
80013
+ body: {
80014
+ namespace: slot.namespace,
80015
+ apiGroup: slot.apiGroup,
80016
+ plural: slot.plural,
80017
+ subresource: slot.subresource,
80018
+ verb: slot.verb
80019
+ }
80020
+ })).data,
80021
+ refetchInterval: false,
80022
+ enabled
80023
+ }))
80024
+ });
80025
+ };
80026
+ const useActionsDropdownPermissions = ({
80027
+ actions,
80028
+ permissions,
80029
+ replaceValues,
80030
+ multiQueryData,
80031
+ isMultiQueryLoading
80032
+ }) => {
80033
+ const shouldCheckPermissions = !permissions;
80034
+ const { slots, mappings } = useMemo(() => {
80035
+ if (!shouldCheckPermissions || isMultiQueryLoading) {
80036
+ return {
80037
+ slots: [],
80038
+ mappings: []
80039
+ };
80040
+ }
80041
+ const parseCtx = { replaceValues, multiQueryData };
80042
+ const uniqueSlots = [];
80043
+ const cacheKeyToIndex = /* @__PURE__ */ new Map();
80044
+ const actionMappings = [];
80045
+ actions.forEach((action, index) => {
80046
+ const actionKey = `${action.type}-${index}`;
80047
+ const permCtx = action.props.permissionContext;
80048
+ if (!permCtx) {
80049
+ return;
80050
+ }
80051
+ const parsed = parsePermissionContext(permCtx, parseCtx);
80052
+ if (!isValidContext(parsed)) {
80053
+ return;
80054
+ }
80055
+ const requiredPerm = ACTION_REQUIRED_PERMISSIONS[action.type];
80056
+ const subresource = requiredPerm.subresource ?? parsed.subresource;
80057
+ const slotData = {
80058
+ cluster: parsed.cluster,
80059
+ namespace: parsed.namespace,
80060
+ apiGroup: parsed.apiGroup,
80061
+ plural: parsed.plural,
80062
+ subresource,
80063
+ verb: requiredPerm.verb
80064
+ };
80065
+ const cacheKey = buildCacheKey(slotData);
80066
+ let slotIndex = cacheKeyToIndex.get(cacheKey);
80067
+ if (slotIndex === void 0) {
80068
+ slotIndex = uniqueSlots.length;
80069
+ uniqueSlots.push({ ...slotData, cacheKey });
80070
+ cacheKeyToIndex.set(cacheKey, slotIndex);
80071
+ }
80072
+ actionMappings.push({ actionKey, slotIndex });
80073
+ });
80074
+ return { slots: uniqueSlots, mappings: actionMappings };
80075
+ }, [shouldCheckPermissions, isMultiQueryLoading, actions, replaceValues, multiQueryData]);
80076
+ const enabled = shouldCheckPermissions && !isMultiQueryLoading;
80077
+ const slotResults = useManyPermissions(slots, enabled);
80078
+ if (permissions) {
80079
+ return permissions;
80080
+ }
80081
+ const computed = {};
80082
+ mappings.forEach((mapping) => {
80083
+ const result = slotResults[mapping.slotIndex];
80084
+ computed[mapping.actionKey] = result?.data?.status?.allowed;
80085
+ });
80086
+ return computed;
80087
+ };
80088
+
80089
+ const toYamlString = (value) => {
80090
+ if (value === void 0) return "";
80091
+ if (typeof value === "string") {
80092
+ try {
80093
+ return stringify(JSON.parse(value));
80094
+ } catch {
80095
+ return value;
80096
+ }
80097
+ }
80098
+ return stringify(value);
80099
+ };
80100
+ const OpenKubeletConfigModal = ({ open, onClose, props }) => {
80101
+ const theme = useTheme();
80102
+ const { data, isLoading, isError, error } = useDirectUnknownResource({
80103
+ uri: props.url,
80104
+ queryKey: ["open-kubelet-config", props.url],
80105
+ refetchInterval: false,
80106
+ isEnabled: open && !!props.url && props.url !== "-"
80107
+ });
80108
+ const yamlData = useMemo(() => toYamlString(data), [data]);
80109
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
80110
+ ReadOnlyModal,
80111
+ {
80112
+ open,
80113
+ close: onClose,
80114
+ modalTitle: props.modalTitle || props.text,
80115
+ modalDescriptionText: props.modalDescriptionText,
80116
+ editModalWidth: props.editModalWidth || 920,
80117
+ children: [
80118
+ isLoading && /* @__PURE__ */ jsxRuntimeExports.jsx(Spin, {}),
80119
+ isError && /* @__PURE__ */ jsxRuntimeExports.jsx(
80120
+ Alert,
80121
+ {
80122
+ type: "error",
80123
+ showIcon: true,
80124
+ message: "Failed to load kubelet config",
80125
+ description: error instanceof Error ? error.message : "Unknown error"
80126
+ }
80127
+ ),
80128
+ !isLoading && !isError && /* @__PURE__ */ jsxRuntimeExports.jsx(
80129
+ Ft$1,
80130
+ {
80131
+ defaultLanguage: "yaml",
80132
+ width: "100%",
80133
+ height: "60vh",
80134
+ value: yamlData,
80135
+ theme: theme === "dark" ? "vs-dark" : "vs",
80136
+ options: {
80137
+ readOnly: true,
80138
+ minimap: { enabled: false },
80139
+ wordWrap: "on",
80140
+ lineNumbers: "on"
80141
+ }
80142
+ }
80143
+ )
80144
+ ]
80145
+ }
80146
+ );
80147
+ };
80148
+
78660
80149
  const renderActionModal = (action, extraProps) => {
78661
80150
  switch (action.type) {
78662
80151
  case "edit":
@@ -78669,84 +80158,192 @@ const renderActionModal = (action, extraProps) => {
78669
80158
  return /* @__PURE__ */ jsxRuntimeExports.jsx(TaintsModal, { ...action.props, ...extraProps });
78670
80159
  case "editTolerations":
78671
80160
  return /* @__PURE__ */ jsxRuntimeExports.jsx(TolerationsModal, { ...action.props, ...extraProps });
80161
+ case "delete":
80162
+ return null;
80163
+ case "cordon":
80164
+ case "uncordon":
80165
+ case "suspend":
80166
+ case "resume":
80167
+ case "rolloutRestart":
80168
+ case "evict":
80169
+ return null;
80170
+ case "openKubeletConfig":
80171
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(OpenKubeletConfigModal, { ...extraProps, props: action.props });
80172
+ case "scale":
80173
+ case "triggerRun":
80174
+ case "deleteChildren":
80175
+ case "rerunLast":
80176
+ case "drain":
80177
+ case "rollback":
80178
+ return null;
78672
80179
  default: {
78673
80180
  const _exhaustive = action;
78674
80181
  return _exhaustive;
78675
80182
  }
78676
80183
  }
78677
80184
  };
78678
- const getMenuItems = (actions, onActionClick) => actions.map((action, index) => ({
78679
- key: `${action.type}-${index}`,
78680
- label: action.props.text,
78681
- icon: action.props.icon ? renderAntIcon(action.props.icon) : void 0,
78682
- disabled: action.props.disabled,
78683
- danger: action.props.danger,
78684
- onClick: () => onActionClick(action)
78685
- }));
80185
+
80186
+ const ScaleModal = ({ open, onClose, onConfirm, currentReplicas, name, isLoading }) => {
80187
+ const [replicas, setReplicas] = useState(currentReplicas);
80188
+ useEffect(() => {
80189
+ if (open) {
80190
+ setReplicas(currentReplicas);
80191
+ }
80192
+ }, [open, currentReplicas]);
80193
+ const isValidReplicas = Number.isInteger(replicas) && (replicas ?? -1) >= 0;
80194
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
80195
+ Modal,
80196
+ {
80197
+ title: `Scale «${name}»`,
80198
+ open,
80199
+ onOk: () => {
80200
+ if (isValidReplicas) {
80201
+ onConfirm(replicas);
80202
+ }
80203
+ },
80204
+ onCancel: onClose,
80205
+ okText: "Scale",
80206
+ confirmLoading: isLoading,
80207
+ okButtonProps: { disabled: !isValidReplicas },
80208
+ width: 400,
80209
+ children: [
80210
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography.Paragraph, { children: [
80211
+ "Current replicas: ",
80212
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: currentReplicas })
80213
+ ] }),
80214
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography.Paragraph, { children: "New replicas:" }),
80215
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
80216
+ InputNumber,
80217
+ {
80218
+ min: 0,
80219
+ precision: 0,
80220
+ step: 1,
80221
+ value: replicas,
80222
+ parser: (value) => Number(value ? value.replace(/[^\d]/g, "") : 0),
80223
+ onChange: (value) => setReplicas(typeof value === "number" ? value : null),
80224
+ style: { width: "100%" },
80225
+ autoFocus: true
80226
+ }
80227
+ )
80228
+ ]
80229
+ }
80230
+ );
80231
+ };
78686
80232
 
78687
80233
  const ActionsDropdown = ({ data, children }) => {
78688
- const { buttonText = "Actions", containerStyle, actions } = data;
78689
- const navigate = useNavigate();
78690
- const location = useLocation();
78691
- const fullPath = location.pathname + location.search;
78692
- const [activeAction, setActiveAction] = useState(null);
78693
- const [modalOpen, setModalOpen] = useState(false);
78694
- const { data: multiQueryData, isLoading: isMultiQueryLoading, isError: isMultiQueryErrors, errors } = useMultiQuery();
80234
+ const { buttonText = "Actions", buttonVariant = "default", containerStyle, actions, permissions } = data;
80235
+ const { data: multiQueryData, isLoading: isMultiQueryLoading, isError: isMultiQueryError, errors } = useMultiQuery();
78695
80236
  const partsOfUrl = usePartsOfUrl();
78696
- if (isMultiQueryLoading) {
78697
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." });
78698
- }
78699
- if (isMultiQueryErrors) {
78700
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
78701
- /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { children: "Errors:" }),
78702
- /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { children: errors.map((e, i) => e && /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: typeof e === "string" ? e : e.message }, i)) })
78703
- ] });
78704
- }
78705
80237
  const replaceValues = partsOfUrl.partsOfUrl.reduce((acc, value, index) => {
78706
80238
  acc[index.toString()] = value;
78707
80239
  return acc;
78708
80240
  }, {});
78709
- const handleActionClick = (action) => {
78710
- if (action.type === "edit") {
78711
- const clusterPrepared = parseAll({ text: action.props.cluster, replaceValues, multiQueryData });
78712
- const namespacePrepared = action.props.namespace ? parseAll({ text: action.props.namespace, replaceValues, multiQueryData }) : void 0;
78713
- const syntheticProjectPrepared = action.props.syntheticProject ? parseAll({ text: action.props.syntheticProject, replaceValues, multiQueryData }) : void 0;
78714
- const apiGroupPrepared = action.props.apiGroup ? parseAll({ text: action.props.apiGroup, replaceValues, multiQueryData }) : void 0;
78715
- const apiVersionPrepared = parseAll({ text: action.props.apiVersion, replaceValues, multiQueryData });
78716
- const pluralPrepared = parseAll({ text: action.props.plural, replaceValues, multiQueryData });
78717
- const namePrepared = parseAll({ text: action.props.name, replaceValues, multiQueryData });
78718
- const baseprefixPrepared = action.props.baseprefix ? parseAll({ text: action.props.baseprefix, replaceValues, multiQueryData }) : void 0;
78719
- const url = buildEditUrl(
80241
+ const safeMultiQueryData = multiQueryData ?? {};
80242
+ const effectivePermissions = useActionsDropdownPermissions({
80243
+ actions,
80244
+ permissions,
80245
+ replaceValues,
80246
+ multiQueryData: safeMultiQueryData,
80247
+ isMultiQueryLoading
80248
+ });
80249
+ const visibleActions = getVisibleActions(actions, {
80250
+ replaceValues,
80251
+ multiQueryData: safeMultiQueryData
80252
+ });
80253
+ const {
80254
+ notificationContextHolder,
80255
+ activeAction,
80256
+ modalOpen,
80257
+ deleteModalData,
80258
+ evictModalData,
80259
+ isEvictLoading,
80260
+ scaleModalData,
80261
+ isScaleLoading,
80262
+ deleteChildrenModalData,
80263
+ rerunModalData,
80264
+ isRerunLoading,
80265
+ handleActionClick,
80266
+ handleCloseModal,
80267
+ handleDeleteModalClose,
80268
+ handleEvictConfirm,
80269
+ handleEvictCancel,
80270
+ handleScaleConfirm,
80271
+ handleScaleCancel,
80272
+ handleDeleteChildrenClose,
80273
+ handleRerunConfirm,
80274
+ handleRerunCancel
80275
+ } = useActionsDropdownHandlers({
80276
+ replaceValues,
80277
+ multiQueryData: safeMultiQueryData
80278
+ });
80279
+ if (isMultiQueryLoading) {
80280
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Spin, { size: "small" });
80281
+ }
80282
+ if (isMultiQueryError) {
80283
+ const errorMessage = errors.filter((e) => e !== null).map((e) => typeof e === "string" ? e : e.message).join("; ");
80284
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip$1, { title: errorMessage || "Failed to load data", children: /* @__PURE__ */ jsxRuntimeExports.jsx(WarningOutlined, { style: { color: "red" } }) });
80285
+ }
80286
+ const menuItems = getMenuItems(visibleActions, handleActionClick, effectivePermissions);
80287
+ const renderButton = () => {
80288
+ if (buttonVariant === "icon") {
80289
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
80290
+ Styled$m.IconButton,
78720
80291
  {
78721
- ...action.props,
78722
- cluster: clusterPrepared,
78723
- namespace: namespacePrepared,
78724
- syntheticProject: syntheticProjectPrepared,
78725
- apiGroup: apiGroupPrepared,
78726
- apiVersion: apiVersionPrepared,
78727
- plural: pluralPrepared,
78728
- name: namePrepared,
78729
- baseprefix: baseprefixPrepared
78730
- },
78731
- fullPath
80292
+ type: "text",
80293
+ size: "small",
80294
+ onClick: (e) => {
80295
+ e.stopPropagation();
80296
+ e.preventDefault();
80297
+ },
80298
+ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(MoreOutlined, {})
80299
+ }
78732
80300
  );
78733
- navigate(url);
78734
- return;
78735
80301
  }
78736
- setActiveAction(action);
78737
- setModalOpen(true);
78738
- };
78739
- const handleCloseModal = () => {
78740
- setModalOpen(false);
78741
- setActiveAction(null);
78742
- };
78743
- const menuItems = getMenuItems(actions, handleActionClick);
78744
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: containerStyle, children: [
78745
- /* @__PURE__ */ jsxRuntimeExports.jsx(Dropdown, { menu: { items: menuItems }, trigger: ["click"], children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { children: [
80302
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { children: [
78746
80303
  buttonText,
78747
80304
  /* @__PURE__ */ jsxRuntimeExports.jsx(DownOutlined, {})
78748
- ] }) }),
80305
+ ] });
80306
+ };
80307
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: containerStyle, children: [
80308
+ notificationContextHolder,
80309
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Dropdown, { menu: { items: menuItems }, trigger: ["click"], children: renderButton() }),
78749
80310
  activeAction && renderActionModal(activeAction, { open: modalOpen, onClose: handleCloseModal }),
80311
+ deleteModalData && /* @__PURE__ */ jsxRuntimeExports.jsx(DeleteModal, { name: deleteModalData.name, endpoint: deleteModalData.endpoint, onClose: handleDeleteModalClose }),
80312
+ evictModalData && /* @__PURE__ */ jsxRuntimeExports.jsx(
80313
+ ConfirmModal,
80314
+ {
80315
+ title: `Evict «${evictModalData.name}?»`,
80316
+ onConfirm: handleEvictConfirm,
80317
+ onClose: handleEvictCancel,
80318
+ confirmText: "Evict",
80319
+ confirmLoading: isEvictLoading,
80320
+ danger: true,
80321
+ children: "This will evict the pod. It may be blocked by PodDisruptionBudget."
80322
+ }
80323
+ ),
80324
+ scaleModalData && /* @__PURE__ */ jsxRuntimeExports.jsx(
80325
+ ScaleModal,
80326
+ {
80327
+ open: true,
80328
+ currentReplicas: scaleModalData.currentReplicas,
80329
+ name: scaleModalData.name,
80330
+ onConfirm: handleScaleConfirm,
80331
+ onClose: handleScaleCancel,
80332
+ isLoading: isScaleLoading
80333
+ }
80334
+ ),
80335
+ deleteChildrenModalData && /* @__PURE__ */ jsxRuntimeExports.jsx(DeleteModalMany, { data: deleteChildrenModalData.children, onClose: handleDeleteChildrenClose }),
80336
+ rerunModalData && /* @__PURE__ */ jsxRuntimeExports.jsx(
80337
+ ConfirmModal,
80338
+ {
80339
+ title: `Rerun job "${rerunModalData.sourceName}"?`,
80340
+ onConfirm: handleRerunConfirm,
80341
+ onClose: handleRerunCancel,
80342
+ confirmText: "Rerun",
80343
+ confirmLoading: isRerunLoading,
80344
+ children: "This will create a new Job with the same spec."
80345
+ }
80346
+ ),
78750
80347
  children
78751
80348
  ] });
78752
80349
  };
@@ -79196,13 +80793,13 @@ const getEnrichedColumnsWithControls = ({
79196
80793
  label: "Edit",
79197
80794
  key: "edit",
79198
80795
  // icon: editIcon || <EditOutlined size={12} />,
79199
- disabled: value?.permissions && value.permissions.canUpdate ? !value.permissions?.canUpdate : false
80796
+ disabled: value?.permissions ? !value.permissions.canUpdate : true
79200
80797
  },
79201
80798
  {
79202
80799
  label: "Delete",
79203
80800
  key: "delete",
79204
80801
  // icon: deleteIcon || <DeleteOutlined size={12} />,
79205
- disabled: value?.permissions && value.permissions.canDelete ? !value.permissions?.canDelete : false
80802
+ disabled: value?.permissions ? !value.permissions.canDelete : true
79206
80803
  }
79207
80804
  ],
79208
80805
  onClick: ({ key, domEvent }) => {
@@ -79446,19 +81043,6 @@ const prepare = ({
79446
81043
  }
79447
81044
  return {};
79448
81045
  });
79449
- if (customFields.length > 0) {
79450
- dataSource = dataSource.map((el) => {
79451
- const newFieldsForComplexJsonPath = {};
79452
- customFields.forEach(({ dataIndex, jsonPath }) => {
79453
- const jpQueryResult = jp.query(el || {}, `$${jsonPath}`);
79454
- newFieldsForComplexJsonPath[dataIndex] = Array.isArray(jpQueryResult) && jpQueryResult.length === 1 ? jpQueryResult[0] : jpQueryResult;
79455
- });
79456
- if (typeof el === "object") {
79457
- return { ...el, ...newFieldsForComplexJsonPath };
79458
- }
79459
- return { ...newFieldsForComplexJsonPath };
79460
- });
79461
- }
79462
81046
  if (flatMapColumns.length > 0 && dataSource) {
79463
81047
  let currentDataSource = dataSource;
79464
81048
  flatMapColumns.forEach((flatMapColumn) => {
@@ -79502,6 +81086,56 @@ const prepare = ({
79502
81086
  });
79503
81087
  dataSource = currentDataSource;
79504
81088
  }
81089
+ if (customFields.length > 0) {
81090
+ dataSource = dataSource.map((el) => {
81091
+ const newFieldsForComplexJsonPath = {};
81092
+ customFields.forEach(({ dataIndex, jsonPath }) => {
81093
+ let fieldValue = null;
81094
+ let handled = false;
81095
+ const flatMapMatch = jsonPath.match(/^(.*)\[(_flatMap[^]]+_Key)](.*)$/);
81096
+ if (flatMapMatch && el && typeof el === "object" && !Array.isArray(el)) {
81097
+ const basePath = flatMapMatch[1];
81098
+ const keyField = flatMapMatch[2];
81099
+ const tailPath = flatMapMatch[3];
81100
+ const keyValue = el[keyField];
81101
+ if (keyValue !== null && keyValue !== void 0) {
81102
+ const baseResult = jp.query(el, `$${basePath}`)[0];
81103
+ if (baseResult && typeof baseResult === "object" && !Array.isArray(baseResult)) {
81104
+ const baseValue = baseResult[String(keyValue)];
81105
+ if (tailPath) {
81106
+ const normalizedTailPath = tailPath.startsWith(".") || tailPath.startsWith("[") ? tailPath : `.${tailPath}`;
81107
+ const tailResult = jp.query(baseValue, `$${normalizedTailPath}`);
81108
+ fieldValue = Array.isArray(tailResult) && tailResult.length === 1 ? tailResult[0] : tailResult;
81109
+ } else {
81110
+ fieldValue = baseValue;
81111
+ }
81112
+ handled = true;
81113
+ }
81114
+ }
81115
+ }
81116
+ if (!handled) {
81117
+ let resolvedJsonPath = jsonPath;
81118
+ if (el && typeof el === "object" && !Array.isArray(el)) {
81119
+ resolvedJsonPath = jsonPath.replace(/\[(_flatMap[^]]+_Key)]/g, (match, keyField) => {
81120
+ const keyValue = el[keyField];
81121
+ if (keyValue === null || keyValue === void 0) {
81122
+ return match;
81123
+ }
81124
+ const escaped = String(keyValue).replace(/'/g, "\\'");
81125
+ return `['${escaped}']`;
81126
+ });
81127
+ }
81128
+ const jpQueryResult = jp.query(el, `$${resolvedJsonPath}`);
81129
+ fieldValue = Array.isArray(jpQueryResult) && jpQueryResult.length === 1 ? jpQueryResult[0] : jpQueryResult;
81130
+ }
81131
+ newFieldsForComplexJsonPath[dataIndex] = fieldValue;
81132
+ });
81133
+ if (typeof el === "object") {
81134
+ return { ...el, ...newFieldsForComplexJsonPath };
81135
+ }
81136
+ return { ...newFieldsForComplexJsonPath };
81137
+ });
81138
+ }
79505
81139
  } else {
79506
81140
  dataSource = dataItems.map((el) => {
79507
81141
  if (typeof el === "object" && el !== null && !Array.isArray(el) && el.spec && typeof el.spec === "object") {
@@ -79565,7 +81199,8 @@ const EnrichedTableProvider = ({
79565
81199
  namespace,
79566
81200
  cluster,
79567
81201
  verb: "update",
79568
- refetchInterval: false
81202
+ refetchInterval: false,
81203
+ enabler: Boolean(dataForControls && dataForControls.plural && cluster)
79569
81204
  });
79570
81205
  const deletePermission = usePermissions({
79571
81206
  apiGroup: dataForControls?.apiGroup,
@@ -79573,7 +81208,8 @@ const EnrichedTableProvider = ({
79573
81208
  namespace,
79574
81209
  cluster,
79575
81210
  verb: "delete",
79576
- refetchInterval: false
81211
+ refetchInterval: false,
81212
+ enabler: Boolean(dataForControls && dataForControls.plural && cluster)
79577
81213
  });
79578
81214
  useEffect(() => {
79579
81215
  setIsError(void 0);
@@ -79653,7 +81289,7 @@ const EnrichedTableProvider = ({
79653
81289
  additionalPrinterColumnsCustomSortersAndFilters: preparedProps.additionalPrinterColumnsCustomSortersAndFilters,
79654
81290
  selectData,
79655
81291
  tableProps,
79656
- withoutControls
81292
+ withoutControls: preparedProps.withoutControls ?? withoutControls
79657
81293
  }
79658
81294
  );
79659
81295
  };
@@ -80388,6 +82024,16 @@ const resolveFormPath = (pathInput, basePathForRelative) => {
80388
82024
  };
80389
82025
  const normalizeNameToPath = (name) => Array.isArray(name) ? name : [name];
80390
82026
 
82027
+ const prettyFieldPath = (name) => {
82028
+ return Array.isArray(name) ? name.map((segment) => String(segment)).join(".") : String(name);
82029
+ };
82030
+ const getRequiredRule = (isRequired, name) => {
82031
+ return {
82032
+ required: isRequired,
82033
+ message: `Please enter ${prettyFieldPath(name)}`
82034
+ };
82035
+ };
82036
+
80391
82037
  const FormListInput = ({
80392
82038
  name,
80393
82039
  arrKey,
@@ -80417,6 +82063,9 @@ const FormListInput = ({
80417
82063
  const rawRelatedFieldValue = Form.useWatch(relatedPath, form);
80418
82064
  const relatedFieldValue = relatedPath ? rawRelatedFieldValue : void 0;
80419
82065
  const relatedTouched = relatedPath ? form.isFieldTouched(relatedPath) : "~";
82066
+ const isWaitingForRelatedValue = Boolean(relatedPath && !rawRelatedFieldValue);
82067
+ const relatedPathLabel = relatedPath?.join(".");
82068
+ const relatedValueTooltip = relatedPathLabel ? isWaitingForRelatedValue ? `Please select ${relatedPathLabel} first` : `Depends on ${relatedPathLabel}` : void 0;
80420
82069
  const hasFiredRef = useRef(false);
80421
82070
  const relatedFieldValuePrev = useRef("unset");
80422
82071
  const hasSeededRef = useRef(false);
@@ -80533,21 +82182,25 @@ const FormListInput = ({
80533
82182
  ResetedFormItem$1,
80534
82183
  {
80535
82184
  name: arrName || fixedName,
80536
- rules: [{ required: forceNonRequired === false && required?.includes(getStringByName(name)) }],
82185
+ rules: [getRequiredRule(forceNonRequired === false && !!required?.includes(getStringByName(name)), name)],
80537
82186
  validateTrigger: "onBlur",
80538
82187
  hasFeedback: designNewLayout ? { icons: feedbackIcons } : true,
80539
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(
80540
- Select,
80541
- {
80542
- mode: customProps.mode,
80543
- placeholder: "Select",
80544
- options: uniqueOptions,
80545
- filterOption: filterSelectOptions,
80546
- disabled: relatedPath && !rawRelatedFieldValue,
80547
- allowClear: true,
80548
- showSearch: true
80549
- }
80550
- )
82188
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { gap: 8, align: "center", children: [
82189
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
82190
+ Select,
82191
+ {
82192
+ mode: customProps.mode,
82193
+ placeholder: "Select",
82194
+ options: uniqueOptions,
82195
+ filterOption: filterSelectOptions,
82196
+ disabled: isWaitingForRelatedValue,
82197
+ allowClear: true,
82198
+ showSearch: true,
82199
+ style: { width: "100%" }
82200
+ }
82201
+ ),
82202
+ relatedValueTooltip && /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip$1, { title: relatedValueTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(QuestionCircleOutlined, {}) })
82203
+ ] })
80551
82204
  },
80552
82205
  arrKey !== void 0 ? arrKey : Array.isArray(name) ? name.slice(-1)[0] : name
80553
82206
  )
@@ -80717,7 +82370,7 @@ const RangeInput = ({
80717
82370
  ResetedFormItem$1,
80718
82371
  {
80719
82372
  name: arrName || name,
80720
- rules: [{ required: forceNonRequired === false && required?.includes(getStringByName(name)) }],
82373
+ rules: [getRequiredRule(forceNonRequired === false && !!required?.includes(getStringByName(name)), name)],
80721
82374
  validateTrigger: "onBlur",
80722
82375
  hasFeedback: designNewLayout ? { icons: feedbackIcons } : true,
80723
82376
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(Slider, { min, max, step, ...props })
@@ -80733,7 +82386,7 @@ const RangeInput = ({
80733
82386
  ResetedFormItem$1,
80734
82387
  {
80735
82388
  name: arrName || name,
80736
- rules: [{ required: forceNonRequired === false && required?.includes(getStringByName(name)) }],
82389
+ rules: [getRequiredRule(forceNonRequired === false && !!required?.includes(getStringByName(name)), name)],
80737
82390
  validateTrigger: "onBlur",
80738
82391
  hasFeedback: designNewLayout ? { icons: feedbackIcons } : true,
80739
82392
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(InputNumber, { min, max, step, value, disabled: props.disabled })
@@ -80962,7 +82615,7 @@ const FormNamespaceInput = ({
80962
82615
  ResetedFormItem$1,
80963
82616
  {
80964
82617
  name,
80965
- rules: [{ required: true }],
82618
+ rules: [getRequiredRule(true, name)],
80966
82619
  validateTrigger: "onBlur",
80967
82620
  hasFeedback: designNewLayout ? { icons: feedbackIcons } : true,
80968
82621
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -81013,7 +82666,7 @@ const FormStringInput = ({
81013
82666
  ResetedFormItem$1,
81014
82667
  {
81015
82668
  name: arrName || fixedName,
81016
- rules: [{ required: forceNonRequired === false && required?.includes(getStringByName(name)) }],
82669
+ rules: [getRequiredRule(forceNonRequired === false && !!required?.includes(getStringByName(name)), name)],
81017
82670
  validateTrigger: "onBlur",
81018
82671
  hasFeedback: designNewLayout ? { icons: feedbackIcons } : true,
81019
82672
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { placeholder: getStringByName(name) })
@@ -81094,7 +82747,7 @@ const FormStringMultilineInput = ({
81094
82747
  ResetedFormItem$1,
81095
82748
  {
81096
82749
  name: arrName || fixedName,
81097
- rules: [{ required: forceNonRequired === false && required?.includes(getStringByName(name)) }],
82750
+ rules: [getRequiredRule(forceNonRequired === false && !!required?.includes(getStringByName(name)), name)],
81098
82751
  validateTrigger: "onBlur",
81099
82752
  hasFeedback: designNewLayout ? { icons: feedbackIcons } : true,
81100
82753
  style: {
@@ -81220,7 +82873,7 @@ const FormEnumStringInput = ({
81220
82873
  ResetedFormItem$1,
81221
82874
  {
81222
82875
  name: arrName || fixedName,
81223
- rules: [{ required: forceNonRequired === false && required?.includes(getStringByName(name)) }],
82876
+ rules: [getRequiredRule(forceNonRequired === false && !!required?.includes(getStringByName(name)), name)],
81224
82877
  validateTrigger: "onBlur",
81225
82878
  hasFeedback: designNewLayout ? { icons: feedbackIcons } : true,
81226
82879
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(Select, { options: options.map((el) => ({ value: el, label: el })), placeholder: getStringByName(name) })
@@ -81262,7 +82915,7 @@ const FormNumberInput = ({
81262
82915
  ResetedFormItem$1,
81263
82916
  {
81264
82917
  name: arrName || name,
81265
- rules: [{ required: forceNonRequired === false && required?.includes(getStringByName(name)) }],
82918
+ rules: [getRequiredRule(forceNonRequired === false && !!required?.includes(getStringByName(name)), name)],
81266
82919
  validateTrigger: "onBlur",
81267
82920
  hasFeedback: designNewLayout ? { icons: feedbackIcons } : true,
81268
82921
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(InputNumber, { placeholder: getStringByName(name), step: isNumber ? 0.1 : 1 })
@@ -81882,7 +83535,7 @@ const getArrayFormItemFromSwagger = ({
81882
83535
  {
81883
83536
  validator: async (_, value) => {
81884
83537
  if (!value || value.length < 1) {
81885
- return Promise.reject(new Error("Field is required"));
83538
+ return Promise.reject(new Error(`Please enter ${prettyFieldPath(name)}`));
81886
83539
  }
81887
83540
  }
81888
83541
  }
@@ -82669,6 +84322,7 @@ const BlackholeForm = ({
82669
84322
  const [persistedKeys, setPersistedKeys] = useState(persistedPaths || []);
82670
84323
  const [resolvedHiddenPaths, setResolvedHiddenPaths] = useState([]);
82671
84324
  const blockedPathsRef = useRef(/* @__PURE__ */ new Set());
84325
+ const manualBlockedPathsRef = useRef(/* @__PURE__ */ new Set());
82672
84326
  const overflowRef = useRef(null);
82673
84327
  const valuesToYamlReqId = useRef(0);
82674
84328
  const yamlToValuesReqId = useRef(0);
@@ -82992,6 +84646,10 @@ const BlackholeForm = ({
82992
84646
  const path = JSON.parse(bk);
82993
84647
  if (isPrefix(path, removedPrefix)) blockedPathsRef.current.delete(bk);
82994
84648
  }
84649
+ for (const bk of [...manualBlockedPathsRef.current]) {
84650
+ const path = JSON.parse(bk);
84651
+ if (isPrefix(path, removedPrefix)) manualBlockedPathsRef.current.delete(bk);
84652
+ }
82995
84653
  }
82996
84654
  }
82997
84655
  }
@@ -83090,6 +84748,7 @@ const BlackholeForm = ({
83090
84748
  form.setFieldsValue(data);
83091
84749
  const dataPathSet = new Set(getAllPathsFromObj(data).map((p) => pathKey$1(p)));
83092
84750
  blockedPathsRef.current.forEach((k) => {
84751
+ if (manualBlockedPathsRef.current.has(k)) return;
83093
84752
  if (dataPathSet.has(k)) blockedPathsRef.current.delete(k);
83094
84753
  });
83095
84754
  setExpandedKeys(expandedKeysRef.current);
@@ -83248,6 +84907,9 @@ const BlackholeForm = ({
83248
84907
  const newProperties = deepMerge(oldProperties, newObject);
83249
84908
  setProperties(newProperties);
83250
84909
  const fullPath = [...arrPath, name];
84910
+ const fullPathKey = pathKey$1(fullPath);
84911
+ blockedPathsRef.current.delete(fullPathKey);
84912
+ manualBlockedPathsRef.current.delete(fullPathKey);
83251
84913
  const currentValue = form.getFieldValue(fullPath);
83252
84914
  if (currentValue === void 0) {
83253
84915
  if (type2 === "string" || type2 === "multilineString" || type2 === "multilineStringBase64") {
@@ -83274,10 +84936,22 @@ const BlackholeForm = ({
83274
84936
  };
83275
84937
  const removeField = ({ path }) => {
83276
84938
  const arrPath = Array.isArray(path) ? path : [path];
83277
- const modifiedProperties = _$1.cloneDeep(properties);
83278
84939
  blockedPathsRef.current.add(pathKey$1(arrPath));
84940
+ manualBlockedPathsRef.current.add(pathKey$1(arrPath));
83279
84941
  form.setFieldValue(arrPath, void 0);
83280
- setProperties(modifiedProperties);
84942
+ setExpandedKeys(
84943
+ (prev) => prev.filter((p) => {
84944
+ const full = Array.isArray(p) ? p : [p];
84945
+ return !isPrefix(full, arrPath);
84946
+ })
84947
+ );
84948
+ setPersistedKeys(
84949
+ (prev) => prev.filter((p) => {
84950
+ const full = Array.isArray(p) ? p : [p];
84951
+ return !isPrefix(full, arrPath);
84952
+ })
84953
+ );
84954
+ setProperties((prevProps) => pruneAdditionalForValues(prevProps, form.getFieldsValue(true), blockedPathsRef));
83281
84955
  onValuesChangeCallback();
83282
84956
  };
83283
84957
  const onExpandOpen = (value) => {
@@ -83347,14 +85021,6 @@ const BlackholeForm = ({
83347
85021
  message: "Only the data from the form will be sent. Empty fields will be removed recursively."
83348
85022
  }
83349
85023
  )
83350
- ] }),
83351
- isCreate && createPermission.data?.status.allowed === false && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
83352
- /* @__PURE__ */ jsxRuntimeExports.jsx(Spacer$1, { $space: 10, $samespace: true }),
83353
- /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { type: "warning", message: "Insufficient rights to create" })
83354
- ] }),
83355
- !isCreate && updatePermission.data?.status.allowed === false && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
83356
- /* @__PURE__ */ jsxRuntimeExports.jsx(Spacer$1, { $space: 10, $samespace: true }),
83357
- /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { type: "warning", message: "Insufficient rights to edit" })
83358
85024
  ] })
83359
85025
  ]
83360
85026
  }
@@ -83372,7 +85038,16 @@ const BlackholeForm = ({
83372
85038
  ] }),
83373
85039
  /* @__PURE__ */ jsxRuntimeExports.jsx(FlexGrow, {}),
83374
85040
  /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$h.ControlsRowContainer, { $bgColor: token.colorPrimaryBg, $designNewLayout: designNewLayout, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { gap: designNewLayout ? 10 : 16, align: "center", children: [
83375
- /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "primary", onClick: onSubmit, loading: isLoading, children: "Submit" }),
85041
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
85042
+ Button,
85043
+ {
85044
+ type: "primary",
85045
+ onClick: onSubmit,
85046
+ loading: isLoading,
85047
+ disabled: isCreate && createPermission.data?.status.allowed !== true || !isCreate && updatePermission.data?.status.allowed !== true,
85048
+ children: "Submit"
85049
+ }
85050
+ ),
83376
85051
  backlink && /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: () => navigate(backlink), children: "Cancel" }),
83377
85052
  /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: () => setIsDebugModalOpen(true), icon: /* @__PURE__ */ jsxRuntimeExports.jsx(BugOutlined, {}) }),
83378
85053
  designNewLayout && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography.Text, { children: "Only the data from the form will be sent. Empty fields will be removed recursively." }) })
@@ -83385,6 +85060,7 @@ const BlackholeForm = ({
83385
85060
  onCancel: () => setError(void 0),
83386
85061
  title: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography.Text, { type: "danger", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$h.BigText, { children: "Error!" }) }),
83387
85062
  cancelButtonProps: { style: { display: "none" } },
85063
+ centered: true,
83388
85064
  children: [
83389
85065
  "An error has occurred: ",
83390
85066
  error?.response?.data?.message
@@ -83399,6 +85075,7 @@ const BlackholeForm = ({
83399
85075
  onCancel: () => setIsDebugModalOpen(false),
83400
85076
  title: "Debug for properties",
83401
85077
  width: "90vw",
85078
+ centered: true,
83402
85079
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$h.DebugContainer, { $designNewLayoutHeight: designNewLayoutHeight, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
83403
85080
  Editor,
83404
85081
  {
@@ -83425,6 +85102,7 @@ const BlackholeFormProvider = ({
83425
85102
  urlParamsForPermissions,
83426
85103
  data,
83427
85104
  customizationId,
85105
+ forcingCustomization,
83428
85106
  isCreate,
83429
85107
  backlink,
83430
85108
  modeData,
@@ -83432,21 +85110,66 @@ const BlackholeFormProvider = ({
83432
85110
  designNewLayoutHeight
83433
85111
  }) => {
83434
85112
  const [preparedData, setPreparedData] = useState();
83435
- const [isLoading, setIsLoading] = useState(false);
85113
+ const [isLoading, setIsLoading] = useState(true);
83436
85114
  const [isNamespaced, setIsNamespaced] = useState(false);
83437
85115
  const [isError, setIsError] = useState(false);
85116
+ const hasAppliedBackendModeRef = useRef(false);
85117
+ const { data: overridesData, isLoading: overridesLoading } = useK8sSmartResource({
85118
+ cluster,
85119
+ apiGroup: forcingCustomization.baseApiGroup,
85120
+ apiVersion: forcingCustomization.baseApiVersion,
85121
+ plural: "customformsoverrides",
85122
+ isEnabled: Boolean(cluster && forcingCustomization.baseApiGroup && forcingCustomization.baseApiVersion)
85123
+ });
85124
+ const { data: mappingData, isLoading: mappingLoading } = useK8sSmartResource({
85125
+ cluster,
85126
+ apiGroup: forcingCustomization.baseApiGroup,
85127
+ apiVersion: forcingCustomization.baseApiVersion,
85128
+ plural: forcingCustomization.cfoMappingPlural,
85129
+ fieldSelector: `metadata.name=${forcingCustomization.cfoMappinResourceName}`,
85130
+ isEnabled: Boolean(
85131
+ cluster && forcingCustomization.baseApiGroup && forcingCustomization.baseApiVersion && forcingCustomization.cfoMappingPlural && forcingCustomization.cfoMappinResourceName
85132
+ )
85133
+ });
83438
85134
  const fallbackToManualMode = useCallback(() => {
83439
- if (modeData) {
83440
- modeData.onChange("Manual");
83441
- modeData.onDisabled();
83442
- }
85135
+ if (!modeData || hasAppliedBackendModeRef.current) return;
85136
+ modeData.onChange("Manual");
85137
+ hasAppliedBackendModeRef.current = true;
83443
85138
  }, [modeData]);
85139
+ const applyForceViewMode = useCallback(
85140
+ (forceViewMode) => {
85141
+ if (!modeData || !forceViewMode || hasAppliedBackendModeRef.current) return;
85142
+ if (forceViewMode === "Manual") {
85143
+ modeData.onChange("Manual");
85144
+ hasAppliedBackendModeRef.current = true;
85145
+ return;
85146
+ }
85147
+ modeData.onChange("OpenAPI");
85148
+ hasAppliedBackendModeRef.current = true;
85149
+ },
85150
+ [modeData]
85151
+ );
85152
+ const forcedCustomizationId = customizationId ? mappingData?.items?.[0]?.spec?.mappings?.[customizationId] : void 0;
85153
+ const hasMatchingOverride = Boolean(
85154
+ customizationId && overridesData?.items?.some((item) => item?.spec?.customizationId === customizationId)
85155
+ );
85156
+ const hasForcedMatchingOverride = Boolean(
85157
+ forcedCustomizationId && overridesData?.items?.some((item) => item?.spec?.customizationId === forcedCustomizationId)
85158
+ );
85159
+ const isResolutionReady = !customizationId || !overridesLoading && !mappingLoading;
85160
+ const resolvedCustomizationId = isResolutionReady ? hasMatchingOverride ? customizationId : hasForcedMatchingOverride ? forcedCustomizationId : forcingCustomization.fallbackId : void 0;
83444
85161
  useEffect(() => {
85162
+ if (!cluster) {
85163
+ setIsLoading(false);
85164
+ return;
85165
+ }
85166
+ if (!isResolutionReady) return;
85167
+ if (customizationId && !resolvedCustomizationId) return;
83445
85168
  setIsLoading(true);
83446
85169
  const payload = {
83447
85170
  data,
83448
85171
  cluster,
83449
- customizationId
85172
+ customizationId: resolvedCustomizationId
83450
85173
  };
83451
85174
  axios.post(`/api/clusters/${cluster}/openapi-bff/forms/formPrepare/prepareFormProps`, payload).then(({ data: data2 }) => {
83452
85175
  if (data2.isNamespaced) {
@@ -83455,8 +85178,13 @@ const BlackholeFormProvider = ({
83455
85178
  if (data2.result === "error") {
83456
85179
  setIsError(data2.error);
83457
85180
  console.warn(data2.error);
83458
- fallbackToManualMode();
85181
+ if (data2.forceViewMode) {
85182
+ applyForceViewMode(data2.forceViewMode);
85183
+ } else {
85184
+ fallbackToManualMode();
85185
+ }
83459
85186
  } else {
85187
+ applyForceViewMode(data2.forceViewMode);
83460
85188
  setPreparedData({
83461
85189
  properties: data2.properties,
83462
85190
  required: data2.required || [],
@@ -83475,7 +85203,15 @@ const BlackholeFormProvider = ({
83475
85203
  }).finally(() => {
83476
85204
  setIsLoading(false);
83477
85205
  });
83478
- }, [cluster, data, customizationId, fallbackToManualMode]);
85206
+ }, [
85207
+ cluster,
85208
+ data,
85209
+ customizationId,
85210
+ resolvedCustomizationId,
85211
+ isResolutionReady,
85212
+ fallbackToManualMode,
85213
+ applyForceViewMode
85214
+ ]);
83479
85215
  if (isLoading) {
83480
85216
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Spin, {});
83481
85217
  }
@@ -83698,6 +85434,7 @@ const AddEditFormModal = ({
83698
85434
  open: isOpen !== false,
83699
85435
  onCancel: () => setIsOpen(false),
83700
85436
  onOk: () => submit(),
85437
+ centered: true,
83701
85438
  children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Form, { form, name: "control-hooks", initialValues: { ...defaultValues }, children: [
83702
85439
  /* @__PURE__ */ jsxRuntimeExports.jsx(Form.Item, { label: "Name", name: "name", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { required: true }) }),
83703
85440
  /* @__PURE__ */ jsxRuntimeExports.jsx(Form.Item, { label: "Description", name: "description", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { required: true }) }),
@@ -83879,7 +85616,7 @@ const MarketplaceCard = ({
83879
85616
  onEditClick,
83880
85617
  addedMode,
83881
85618
  standalone,
83882
- showZeroResources
85619
+ showZeroResources = false
83883
85620
  }) => {
83884
85621
  const { useToken } = theme;
83885
85622
  const { token } = useToken();
@@ -83914,10 +85651,16 @@ const MarketplaceCard = ({
83914
85651
  namespace,
83915
85652
  apiGroup,
83916
85653
  apiVersion: apiVersion || "",
83917
- plural: type,
83918
- isEnabled: Boolean(apiVersion && addedMode && type !== "direct")
85654
+ plural: plural || "",
85655
+ isEnabled: Boolean(apiVersion && plural && addedMode && type !== "direct")
83919
85656
  });
83920
- if (addedMode && (k8sListError || type === "direct") && !showZeroResources) {
85657
+ const isAddedMode = Boolean(addedMode);
85658
+ const isDirectType = type === "direct";
85659
+ const hasK8sListError = Boolean(k8sListError);
85660
+ const isUncountable = isAddedMode && (hasK8sListError || isDirectType);
85661
+ const itemsCount = k8sList?.items?.length ?? 0;
85662
+ const isCountableZero = isAddedMode && !isUncountable && itemsCount === 0;
85663
+ if (showZeroResources === false && (isUncountable || isCountableZero)) {
83921
85664
  return null;
83922
85665
  }
83923
85666
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -83955,7 +85698,7 @@ const MarketplaceCard = ({
83955
85698
  " ",
83956
85699
  addedMode && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
83957
85700
  "x",
83958
- k8sList?.items?.length
85701
+ itemsCount
83959
85702
  ] })
83960
85703
  ] }),
83961
85704
  /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$f.TagsContainer, { children: tags.map((tag) => /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$f.CustomTag, { children: tag }, tag)) }),
@@ -84032,7 +85775,7 @@ const MarketPlace = ({
84032
85775
  marketplaceKind,
84033
85776
  baseprefix,
84034
85777
  standalone,
84035
- forceAddedMode,
85778
+ addedMode,
84036
85779
  showZeroResources
84037
85780
  }) => {
84038
85781
  const [api, contextHolder] = notification.useNotification();
@@ -84185,7 +85928,7 @@ const MarketPlace = ({
84185
85928
  setIsAddEditOpen(marketplacePanels.items.find(({ spec }) => spec.name === name) || false);
84186
85929
  },
84187
85930
  standalone,
84188
- addedMode: forceAddedMode,
85931
+ addedMode,
84189
85932
  showZeroResources
84190
85933
  },
84191
85934
  name
@@ -88027,9 +89770,15 @@ const usePluginManifest = ({
88027
89770
  queryKey: ["usePluginManifest", cluster],
88028
89771
  queryFn: () => getPlugins({ cluster }),
88029
89772
  refetchInterval: refetchInterval !== void 0 ? refetchInterval : 6e4,
88030
- enabled: isEnabled
89773
+ enabled: isEnabled,
89774
+ // 🔴 Disable ALL auto refetching
89775
+ refetchOnWindowFocus: false,
89776
+ refetchOnReconnect: false,
89777
+ refetchOnMount: false,
89778
+ // 🟢 Optional: Make data never go stale
89779
+ staleTime: Infinity
88031
89780
  });
88032
89781
  };
88033
89782
 
88034
- export { useInfiniteSentinel as $, getBuiltinResourceTypes as A, getCrdData as B, getDirectUnknownResource as C, DeleteIcon as D, EnrichedTableProvider as E, checkPermission as F, getSwagger as G, filterIfApiInstanceNamespaceScoped as H, filterIfBuiltInInstanceNamespaceScoped as I, checkIfApiInstanceNamespaceScoped as J, checkIfBuiltInInstanceNamespaceScoped as K, getKinds as L, useClusterList as M, useApiResources as N, useApiResourceSingle as O, PaddingContainer as P, useBuiltinResources as Q, useBuiltinResourceSingle as R, Spacer$1 as S, useCrdResources as T, useCrdResourceSingle as U, useApisResourceTypes as V, useApiResourceTypesByGroup as W, useBuiltinResourceTypes as X, useCrdData as Y, useListWatch as Z, _$1 as _, useTheme as a, getAllPathsFromObj as a$, useK8sVerbs as a0, useManyK8sSmartResource as a1, useSmartResourceParams as a2, useResourceScope as a3, useKinds as a4, usePluginManifest as a5, TreeWithSearch as a6, UpIcon as a7, DownIcon as a8, BackToDefaultIcon as a9, getEnrichedColumnsWithControls as aA, YamlEditorSingleton$1 as aB, BlackholeFormProvider as aC, BlackholeForm as aD, getObjectFormItemsDraft as aE, MarketPlace as aF, MarketplaceCard as aG, ProjectInfoCard as aH, PodTerminal as aI, NodeTerminal as aJ, PodLogs as aK, PodLogsMonaco as aL, VMVNC as aM, Search as aN, Events as aO, DynamicRenderer as aP, DynamicComponents as aQ, DynamicRendererWithProviders as aR, prepareTemplate as aS, isFlatObject as aT, filterSelectOptions as aU, getStringByName as aV, floorToDecimal as aW, parseQuotaValue as aX, parseQuotaValueCpu as aY, parseQuotaValueMemoryAndStorage as aZ, normalizeValuesForQuotasToNumber as a_, SuccessIcon as aa, feedbackIcons as ab, PlusIcon as ac, MinusIcon as ad, LockedIcon as ae, UnlockedIcon as af, PauseCircleIcon as ag, ResumeCircleIcon as ah, LookingGlassIcon as ai, EarthIcon as aj, ContentCard$1 as ak, FlexGrow as al, UncontrolledSelect as am, CustomSelect$4 as an, CursorPointerTag as ao, CursorPointerTagMinContent as ap, CursorDefaultDiv as aq, ResourceLink as ar, ManageableBreadcrumbsProvider as as, prepareDataForManageableBreadcrumbs as at, ManageableBreadcrumbs as au, ManageableSidebarProvider as av, prepareDataForManageableSidebar as aw, ManageableSidebar as ax, EnrichedTable as ay, getEnrichedColumns as az, usePartsOfUrl as b, getPrefixSubarrays as b0, groupsToTreeData as b1, getBuiltinTreeData as b2, getGroupsByCategory as b3, createContextFactory as b4, prepareUrlsToFetchForDynamicRenderer as b5, deepMerge as b6, getSortedKinds as b7, getSortedKindsAll as b8, hslFromString as b9, getUppercase as ba, kindByGvr as bb, pluralByKind as bc, namespacedByGvr as bd, getLinkToBuiltinForm as be, getLinkToApiForm as bf, isMultilineString as bg, isMultilineFromYaml as bh, includesArray as bi, getResourceLink as bj, getNamespaceLink as bk, convertBytes as bl, formatBytesAuto as bm, toBytes as bn, convertStorage as bo, parseValueWithUnit as bp, convertCores as bq, formatCoresAuto as br, toCores as bs, convertCompute as bt, parseCoresWithUnit as bu, formatDateAuto as bv, isValidRFC3339 as bw, usePermissions as c, jp as d, useDirectUnknownResource as e, useK8sSmartResource as f, EditIcon as g, getLinkToForm as h, DeleteModal as i, jsxRuntimeExports as j, DeleteModalMany as k, getClusterList as l, createNewEntry as m, updateEntry as n, deleteEntry as o, parseAll as p, getApiResources as q, getApiResourceSingle as r, serializeLabelsWithNoEncoding$1 as s, getBuiltinResources as t, useMultiQuery as u, getBuiltinResourceSingle as v, getCrdResources as w, getCrdResourceSingle as x, getApiResourceTypes as y, getApiResourceTypesByApiGroup as z };
88035
- //# sourceMappingURL=index-CqVGo048.mjs.map
89783
+ export { useInfiniteSentinel as $, getBuiltinResourceTypes as A, getCrdData as B, getDirectUnknownResource as C, DeleteIcon as D, EnrichedTableProvider as E, checkPermission as F, getSwagger as G, filterIfApiInstanceNamespaceScoped as H, filterIfBuiltInInstanceNamespaceScoped as I, checkIfApiInstanceNamespaceScoped as J, checkIfBuiltInInstanceNamespaceScoped as K, getKinds as L, useClusterList as M, useApiResources as N, useApiResourceSingle as O, PaddingContainer as P, useBuiltinResources as Q, ReadOnlyModal as R, useBuiltinResourceSingle as S, useCrdResources as T, useCrdResourceSingle as U, useApisResourceTypes as V, useApiResourceTypesByGroup as W, useBuiltinResourceTypes as X, useCrdData as Y, useListWatch as Z, _$1 as _, useTheme as a, parseQuotaValueMemoryAndStorage as a$, useK8sVerbs as a0, useManyK8sSmartResource as a1, useSmartResourceParams as a2, useResourceScope as a3, useKinds as a4, usePluginManifest as a5, Spacer$1 as a6, TreeWithSearch as a7, ConfirmModal as a8, UpIcon as a9, EnrichedTable as aA, getEnrichedColumns as aB, getEnrichedColumnsWithControls as aC, YamlEditorSingleton$1 as aD, BlackholeFormProvider as aE, BlackholeForm as aF, getObjectFormItemsDraft as aG, MarketPlace as aH, MarketplaceCard as aI, ProjectInfoCard as aJ, PodTerminal as aK, NodeTerminal as aL, PodLogs as aM, PodLogsMonaco as aN, VMVNC as aO, Search as aP, Events as aQ, DynamicRenderer as aR, DynamicComponents as aS, DynamicRendererWithProviders as aT, prepareTemplate as aU, isFlatObject as aV, filterSelectOptions as aW, getStringByName as aX, floorToDecimal as aY, parseQuotaValue as aZ, parseQuotaValueCpu as a_, DownIcon as aa, BackToDefaultIcon as ab, SuccessIcon as ac, feedbackIcons as ad, PlusIcon as ae, MinusIcon as af, LockedIcon as ag, UnlockedIcon as ah, PauseCircleIcon as ai, ResumeCircleIcon as aj, LookingGlassIcon as ak, EarthIcon as al, ContentCard$1 as am, FlexGrow as an, UncontrolledSelect as ao, CustomSelect$4 as ap, CursorPointerTag as aq, CursorPointerTagMinContent as ar, CursorDefaultDiv as as, ResourceLink as at, ManageableBreadcrumbsProvider as au, prepareDataForManageableBreadcrumbs as av, ManageableBreadcrumbs as aw, ManageableSidebarProvider as ax, prepareDataForManageableSidebar as ay, ManageableSidebar as az, usePartsOfUrl as b, normalizeValuesForQuotasToNumber as b0, getAllPathsFromObj as b1, getPrefixSubarrays as b2, groupsToTreeData as b3, getBuiltinTreeData as b4, getGroupsByCategory as b5, createContextFactory as b6, prepareUrlsToFetchForDynamicRenderer as b7, deepMerge as b8, getSortedKinds as b9, getSortedKindsAll as ba, hslFromString as bb, getUppercase as bc, kindByGvr as bd, pluralByKind as be, namespacedByGvr as bf, getLinkToBuiltinForm as bg, getLinkToApiForm as bh, isMultilineString as bi, isMultilineFromYaml as bj, includesArray as bk, getResourceLink as bl, getNamespaceLink as bm, convertBytes as bn, formatBytesAuto as bo, toBytes as bp, convertStorage as bq, parseValueWithUnit as br, convertCores as bs, formatCoresAuto as bt, toCores as bu, convertCompute as bv, parseCoresWithUnit as bw, formatDateAuto as bx, isValidRFC3339 as by, usePermissions as c, useDirectUnknownResource as d, useK8sSmartResource as e, jsxRuntimeExports as f, EditIcon as g, getLinkToForm as h, DeleteModal as i, jp as j, DeleteModalMany as k, getClusterList as l, createNewEntry as m, updateEntry as n, deleteEntry as o, parseAll as p, getApiResources as q, getApiResourceSingle as r, serializeLabelsWithNoEncoding$1 as s, getBuiltinResources as t, useMultiQuery as u, getBuiltinResourceSingle as v, getCrdResources as w, getCrdResourceSingle as x, getApiResourceTypes as y, getApiResourceTypesByApiGroup as z };
89784
+ //# sourceMappingURL=index-BwCZPalv.mjs.map