@prorobotech/openapi-k8s-toolkit 1.3.0-alpha.13 → 1.3.0-alpha.14

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.
@@ -9767,13 +9767,31 @@ const mapLinksFromRaw = ({
9767
9767
  const findMatchingItems = ({
9768
9768
  items,
9769
9769
  pathname,
9770
+ searchParams,
9770
9771
  tags
9771
9772
  }) => {
9773
+ const normalizePath = (value) => {
9774
+ if (!value) {
9775
+ return void 0;
9776
+ }
9777
+ return value.startsWith("/") ? value.slice(1) : value;
9778
+ };
9772
9779
  const traverse = (nodes, parents) => nodes.flatMap((node) => {
9773
9780
  const currentPath = [...parents, node.key ? node.key : String(node.key)];
9774
- const cleanNodeInternalMetaLink = node.internalMetaLink?.startsWith("/") ? node.internalMetaLink.slice(1) : node.internalMetaLink;
9775
- const cleanPathname = pathname.startsWith("/") ? pathname.slice(1) : pathname;
9776
- const matched = cleanNodeInternalMetaLink === cleanPathname ? currentPath : [];
9781
+ const cleanNodeInternalMetaLink = normalizePath(node.internalMetaLink);
9782
+ const cleanPathname = normalizePath(pathname.split("?")[0]);
9783
+ let searchSuffix;
9784
+ if (searchParams && searchParams.length > 0) {
9785
+ searchSuffix = searchParams.startsWith("?") ? searchParams : `?${searchParams}`;
9786
+ }
9787
+ let pathnameWithSearch;
9788
+ if (searchSuffix) {
9789
+ pathnameWithSearch = `${pathname}${searchSuffix}`;
9790
+ } else if (pathname.includes("?")) {
9791
+ pathnameWithSearch = pathname;
9792
+ }
9793
+ const cleanPathnameWithSearch = normalizePath(pathnameWithSearch);
9794
+ const matched = cleanNodeInternalMetaLink === cleanPathname || cleanPathnameWithSearch && cleanNodeInternalMetaLink === cleanPathnameWithSearch ? currentPath : [];
9777
9795
  const tagsToMatch = tags && tags.keysAndTags && node.key ? tags.keysAndTags[typeof node.key === "string" ? node.key : String(node.key)] : void 0;
9778
9796
  const matchedByTags = tags && tags.currentTags && tagsToMatch && tagsToMatch.some((tag) => tags.currentTags?.includes(tag)) ? currentPath : [];
9779
9797
  let childrenResults = [];
@@ -9788,6 +9806,7 @@ const prepareDataForManageableSidebar = ({
9788
9806
  data,
9789
9807
  replaceValues,
9790
9808
  pathname,
9809
+ searchParams,
9791
9810
  idToCompare,
9792
9811
  fallbackIdToCompare,
9793
9812
  currentTags
@@ -9807,6 +9826,7 @@ const prepareDataForManageableSidebar = ({
9807
9826
  const openedKeys = result?.menuItems ? findMatchingItems({
9808
9827
  items: result?.menuItems,
9809
9828
  pathname,
9829
+ searchParams,
9810
9830
  tags: { keysAndTags: foundData.keysAndTags, currentTags: preparedCurrentTags }
9811
9831
  }) : [];
9812
9832
  const stringedOpenedKeys = openedKeys.map((el) => typeof el === "string" ? el : String(el));
@@ -9821,6 +9841,7 @@ const ManageableSidebarProvider = ({
9821
9841
  isEnabled,
9822
9842
  replaceValues,
9823
9843
  pathname,
9844
+ searchParams,
9824
9845
  idToCompare,
9825
9846
  fallbackIdToCompare,
9826
9847
  currentTags,
@@ -9858,6 +9879,7 @@ const ManageableSidebarProvider = ({
9858
9879
  data: parsedData,
9859
9880
  replaceValues,
9860
9881
  pathname,
9882
+ searchParams,
9861
9883
  idToCompare,
9862
9884
  fallbackIdToCompare,
9863
9885
  currentTags
@@ -43142,7 +43164,8 @@ const YamlEditorSingleton$1 = ({
43142
43164
  designNewLayout,
43143
43165
  designNewLayoutHeight,
43144
43166
  openNotification,
43145
- readOnly = false
43167
+ readOnly = false,
43168
+ canEdit
43146
43169
  }) => {
43147
43170
  const { token } = theme.useToken();
43148
43171
  const navigate = useNavigate();
@@ -43266,7 +43289,7 @@ const YamlEditorSingleton$1 = ({
43266
43289
  }
43267
43290
  ) }),
43268
43291
  !readOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$y.ControlsRowContainer, { $bgColor: token.colorPrimaryBg, $designNewLayout: designNewLayout, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { gap: designNewLayout ? 10 : 16, align: "center", children: [
43269
- /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "primary", onClick: onSubmit, loading: isLoading, children: "Submit" }),
43292
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "primary", onClick: onSubmit, loading: isLoading, disabled: canEdit === false, children: "Submit" }),
43270
43293
  backlink && /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: () => navigate(backlink), children: "Cancel" }),
43271
43294
  /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: handleReload, children: "Reload" })
43272
43295
  ] }) }),
@@ -43337,6 +43360,8 @@ const YamlEditorSingleton = ({
43337
43360
  prefillValuesRequestIndex,
43338
43361
  pathToData,
43339
43362
  substractHeight,
43363
+ permissions,
43364
+ permissionContext,
43340
43365
  ...props
43341
43366
  } = data;
43342
43367
  const [height, setHeight] = useState(0);
@@ -43357,6 +43382,26 @@ const YamlEditorSingleton = ({
43357
43382
  acc[index.toString()] = value;
43358
43383
  return acc;
43359
43384
  }, {});
43385
+ const safeMultiQueryData = multiQueryData || {};
43386
+ const permissionContextPrepared = permissionContext ? {
43387
+ cluster: parseAll({ text: permissionContext.cluster, replaceValues, multiQueryData: safeMultiQueryData }),
43388
+ namespace: permissionContext.namespace ? parseAll({ text: permissionContext.namespace, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
43389
+ apiGroup: permissionContext.apiGroup ? parseAll({ text: permissionContext.apiGroup, replaceValues, multiQueryData: safeMultiQueryData }) : void 0,
43390
+ plural: parseAll({ text: permissionContext.plural, replaceValues, multiQueryData: safeMultiQueryData })
43391
+ } : void 0;
43392
+ const isPermissionContextValid = !!permissionContextPrepared && !isMultiqueryLoading && !!permissionContextPrepared.cluster && permissionContextPrepared.cluster !== "-" && !!permissionContextPrepared.plural && permissionContextPrepared.plural !== "-";
43393
+ const updatePermission = usePermissions({
43394
+ cluster: permissionContextPrepared?.cluster || "",
43395
+ namespace: permissionContextPrepared?.namespace,
43396
+ apiGroup: permissionContextPrepared?.apiGroup,
43397
+ plural: permissionContextPrepared?.plural || "",
43398
+ verb: "update",
43399
+ refetchInterval: false,
43400
+ enabler: isPermissionContextValid
43401
+ });
43402
+ const canUpdate = permissions?.canUpdate ?? updatePermission.data?.status.allowed;
43403
+ const shouldGateEdit = Boolean(permissions || permissionContext);
43404
+ const canEdit = !shouldGateEdit || canUpdate === true;
43360
43405
  const clusterPrepared = parseAll({ text: cluster, replaceValues, multiQueryData });
43361
43406
  const apiGroupPrepared = apiGroup ? parseAll({ text: apiGroup, replaceValues, multiQueryData }) : "no-api-group";
43362
43407
  const apiVersionPrepared = apiVersion ? parseAll({ text: apiVersion, replaceValues, multiQueryData }) : "no-api-version";
@@ -43382,6 +43427,7 @@ const YamlEditorSingleton = ({
43382
43427
  designNewLayout: true,
43383
43428
  designNewLayoutHeight: height,
43384
43429
  openNotification: true,
43430
+ canEdit,
43385
43431
  ...props
43386
43432
  }
43387
43433
  ),
@@ -77754,7 +77800,7 @@ const TolerationsModal = ({
77754
77800
  };
77755
77801
 
77756
77802
  const LazyEnrichedTableModal = lazy(
77757
- () => import('./index-Cw_DSYZi.mjs').then((mod) => ({ default: mod.EnrichedTableModal }))
77803
+ () => import('./index-TsZ_uyy3.mjs').then((mod) => ({ default: mod.EnrichedTableModal }))
77758
77804
  );
77759
77805
  const renderActiveType = (activeType, extraProps) => {
77760
77806
  if (!activeType) return null;
@@ -83643,14 +83689,6 @@ const BlackholeForm = ({
83643
83689
  message: "Only the data from the form will be sent. Empty fields will be removed recursively."
83644
83690
  }
83645
83691
  )
83646
- ] }),
83647
- isCreate && createPermission.data?.status.allowed === false && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
83648
- /* @__PURE__ */ jsxRuntimeExports.jsx(Spacer$1, { $space: 10, $samespace: true }),
83649
- /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { type: "warning", message: "Insufficient rights to create" })
83650
- ] }),
83651
- !isCreate && updatePermission.data?.status.allowed === false && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
83652
- /* @__PURE__ */ jsxRuntimeExports.jsx(Spacer$1, { $space: 10, $samespace: true }),
83653
- /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { type: "warning", message: "Insufficient rights to edit" })
83654
83692
  ] })
83655
83693
  ]
83656
83694
  }
@@ -83668,7 +83706,16 @@ const BlackholeForm = ({
83668
83706
  ] }),
83669
83707
  /* @__PURE__ */ jsxRuntimeExports.jsx(FlexGrow, {}),
83670
83708
  /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$h.ControlsRowContainer, { $bgColor: token.colorPrimaryBg, $designNewLayout: designNewLayout, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Flex, { gap: designNewLayout ? 10 : 16, align: "center", children: [
83671
- /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "primary", onClick: onSubmit, loading: isLoading, children: "Submit" }),
83709
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
83710
+ Button,
83711
+ {
83712
+ type: "primary",
83713
+ onClick: onSubmit,
83714
+ loading: isLoading,
83715
+ disabled: isCreate && createPermission.data?.status.allowed !== true || !isCreate && updatePermission.data?.status.allowed !== true,
83716
+ children: "Submit"
83717
+ }
83718
+ ),
83672
83719
  backlink && /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: () => navigate(backlink), children: "Cancel" }),
83673
83720
  /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: () => setIsDebugModalOpen(true), icon: /* @__PURE__ */ jsxRuntimeExports.jsx(BugOutlined, {}) }),
83674
83721
  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." }) })
@@ -83721,6 +83768,7 @@ const BlackholeFormProvider = ({
83721
83768
  urlParamsForPermissions,
83722
83769
  data,
83723
83770
  customizationId,
83771
+ forcingCustomization,
83724
83772
  isCreate,
83725
83773
  backlink,
83726
83774
  modeData,
@@ -83728,21 +83776,49 @@ const BlackholeFormProvider = ({
83728
83776
  designNewLayoutHeight
83729
83777
  }) => {
83730
83778
  const [preparedData, setPreparedData] = useState();
83731
- const [isLoading, setIsLoading] = useState(false);
83779
+ const [isLoading, setIsLoading] = useState(true);
83732
83780
  const [isNamespaced, setIsNamespaced] = useState(false);
83733
83781
  const [isError, setIsError] = useState(false);
83782
+ const { data: overridesData, isLoading: overridesLoading } = useK8sSmartResource({
83783
+ cluster,
83784
+ apiGroup: forcingCustomization.baseApiGroup,
83785
+ apiVersion: forcingCustomization.baseApiVersion,
83786
+ plural: "customformsoverrides",
83787
+ isEnabled: Boolean(cluster && forcingCustomization.baseApiGroup && forcingCustomization.baseApiVersion)
83788
+ });
83789
+ const { data: mappingData, isLoading: mappingLoading } = useK8sSmartResource({
83790
+ cluster,
83791
+ apiGroup: forcingCustomization.baseApiGroup,
83792
+ apiVersion: forcingCustomization.baseApiVersion,
83793
+ plural: forcingCustomization.cfoMappingPlural,
83794
+ fieldSelector: `metadata.name=${forcingCustomization.cfoMappinResourceName}`,
83795
+ isEnabled: Boolean(
83796
+ cluster && forcingCustomization.baseApiGroup && forcingCustomization.baseApiVersion && forcingCustomization.cfoMappingPlural && forcingCustomization.cfoMappinResourceName
83797
+ )
83798
+ });
83734
83799
  const fallbackToManualMode = useCallback(() => {
83735
83800
  if (modeData) {
83736
83801
  modeData.onChange("Manual");
83737
83802
  modeData.onDisabled();
83738
83803
  }
83739
83804
  }, [modeData]);
83805
+ const forcedCustomizationId = customizationId ? mappingData?.items?.[0]?.spec?.mappings?.[customizationId] : void 0;
83806
+ const hasMatchingOverride = Boolean(
83807
+ customizationId && overridesData?.items?.some((item) => item?.spec?.customizationId === customizationId)
83808
+ );
83809
+ const hasForcedMatchingOverride = Boolean(
83810
+ forcedCustomizationId && overridesData?.items?.some((item) => item?.spec?.customizationId === forcedCustomizationId)
83811
+ );
83812
+ const isResolutionReady = !customizationId || !overridesLoading && !mappingLoading;
83813
+ const resolvedCustomizationId = isResolutionReady ? hasMatchingOverride ? customizationId : hasForcedMatchingOverride ? forcedCustomizationId : forcingCustomization.fallbackId : void 0;
83740
83814
  useEffect(() => {
83815
+ if (!isResolutionReady) return;
83816
+ if (customizationId && !resolvedCustomizationId) return;
83741
83817
  setIsLoading(true);
83742
83818
  const payload = {
83743
83819
  data,
83744
83820
  cluster,
83745
- customizationId
83821
+ customizationId: resolvedCustomizationId
83746
83822
  };
83747
83823
  axios.post(`/api/clusters/${cluster}/openapi-bff/forms/formPrepare/prepareFormProps`, payload).then(({ data: data2 }) => {
83748
83824
  if (data2.isNamespaced) {
@@ -83771,7 +83847,7 @@ const BlackholeFormProvider = ({
83771
83847
  }).finally(() => {
83772
83848
  setIsLoading(false);
83773
83849
  });
83774
- }, [cluster, data, customizationId, fallbackToManualMode]);
83850
+ }, [cluster, data, customizationId, resolvedCustomizationId, isResolutionReady, fallbackToManualMode]);
83775
83851
  if (isLoading) {
83776
83852
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Spin, {});
83777
83853
  }
@@ -88328,4 +88404,4 @@ const usePluginManifest = ({
88328
88404
  };
88329
88405
 
88330
88406
  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 };
88331
- //# sourceMappingURL=index-BA00s3b1.mjs.map
88407
+ //# sourceMappingURL=index-BmH40O5l.mjs.map