@prorobotech/openapi-k8s-toolkit 1.4.0-alpha.13 → 1.4.0-alpha.15

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 (27) hide show
  1. package/dist/{index-D_swkE1M.mjs → index-_-34pI9_.mjs} +2 -2
  2. package/dist/{index-D_swkE1M.mjs.map → index-_-34pI9_.mjs.map} +1 -1
  3. package/dist/{index-C5QXAXXJ.mjs → index-mwV-HNIP.mjs} +695 -168
  4. package/dist/index-mwV-HNIP.mjs.map +1 -0
  5. package/dist/openapi-k8s-toolkit.es.js +1 -1
  6. package/dist/openapi-k8s-toolkit.umd.js +691 -164
  7. package/dist/openapi-k8s-toolkit.umd.js.map +1 -1
  8. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/actionHandlers.d.ts +23 -0
  9. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/handlers/index.d.ts +6 -0
  10. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/handlers/useCreateFromFilesHandlers.d.ts +11 -0
  11. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/handlers/useDrainHandlers.d.ts +12 -0
  12. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/handlers/useEvictHandlers.d.ts +9 -0
  13. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/handlers/useRerunHandlers.d.ts +11 -0
  14. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/handlers/useRollbackHandlers.d.ts +11 -0
  15. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/handlers/useScaleHandlers.d.ts +11 -0
  16. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/helpers.d.ts +25 -0
  17. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/index.d.ts +3 -0
  18. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/types.d.ts +65 -0
  19. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers/useActionsDropdownHandlers.d.ts +38 -0
  20. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/modals/CreateFromFilesModal.d.ts +12 -0
  21. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/modals/CreateFromFilesModal.test.d.ts +1 -0
  22. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/modals/DownloadAsFilesModal.d.ts +11 -0
  23. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/modals/DownloadAsFilesModal.test.d.ts +1 -0
  24. package/dist/types/components/organisms/DynamicComponents/types/ActionsDropdown.d.ts +22 -2
  25. package/package.json +1 -1
  26. package/dist/index-C5QXAXXJ.mjs.map +0 -1
  27. package/dist/types/components/organisms/DynamicComponents/molecules/ActionsDropdown/hooks/useActionsDropdownHandlers.d.ts +0 -103
@@ -7992,6 +7992,11 @@
7992
7992
  okButtonProps: { danger: true },
7993
7993
  width: 400,
7994
7994
  centered: true,
7995
+ styles: {
7996
+ header: {
7997
+ paddingRight: "30px"
7998
+ }
7999
+ },
7995
8000
  children: error && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Alert, { type: "error", message: "Error while delete", description: error?.response?.data?.message })
7996
8001
  }
7997
8002
  );
@@ -8029,6 +8034,11 @@
8029
8034
  okButtonProps: { danger: true },
8030
8035
  width: 400,
8031
8036
  centered: true,
8037
+ styles: {
8038
+ header: {
8039
+ paddingRight: "30px"
8040
+ }
8041
+ },
8032
8042
  children: error && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Alert, { type: "error", message: "Error while delete", description: error?.response?.data?.message })
8033
8043
  }
8034
8044
  );
@@ -8058,6 +8068,11 @@
8058
8068
  okButtonProps: { danger },
8059
8069
  width,
8060
8070
  centered: true,
8071
+ styles: {
8072
+ header: {
8073
+ paddingRight: "30px"
8074
+ }
8075
+ },
8061
8076
  children
8062
8077
  }
8063
8078
  );
@@ -43826,6 +43841,11 @@
43826
43841
  title: /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Typography.Text, { type: "danger", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$z.BigText, { children: "Error!" }) }),
43827
43842
  cancelButtonProps: { style: { display: "none" } },
43828
43843
  centered: true,
43844
+ styles: {
43845
+ header: {
43846
+ paddingRight: "30px"
43847
+ }
43848
+ },
43829
43849
  children: [
43830
43850
  "An error has occurred: ",
43831
43851
  error?.response?.data?.message
@@ -44475,6 +44495,11 @@
44475
44495
  width: editModalWidth || 520,
44476
44496
  destroyOnHidden: true,
44477
44497
  centered: true,
44498
+ styles: {
44499
+ header: {
44500
+ paddingRight: "30px"
44501
+ }
44502
+ },
44478
44503
  children: [
44479
44504
  error && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Alert, { type: "error", message: "Error while submitting", description: error?.response?.data?.message }),
44480
44505
  modalDescriptionText && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
@@ -44607,6 +44632,11 @@
44607
44632
  width: editModalWidth || 520,
44608
44633
  destroyOnHidden: true,
44609
44634
  centered: true,
44635
+ styles: {
44636
+ header: {
44637
+ paddingRight: "30px"
44638
+ }
44639
+ },
44610
44640
  children: [
44611
44641
  error && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Alert, { type: "error", message: "Error while submitting", description: error?.response?.data?.message }),
44612
44642
  modalDescriptionText && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
@@ -44756,6 +44786,11 @@
44756
44786
  width: editModalWidth || 520,
44757
44787
  destroyOnHidden: true,
44758
44788
  centered: true,
44789
+ styles: {
44790
+ header: {
44791
+ paddingRight: "30px"
44792
+ }
44793
+ },
44759
44794
  children: [
44760
44795
  error && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Alert, { type: "error", message: "Error while submitting", description: error?.response?.data?.message }),
44761
44796
  modalDescriptionText && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
@@ -44950,6 +44985,11 @@
44950
44985
  width: editModalWidth || 520,
44951
44986
  destroyOnHidden: true,
44952
44987
  centered: true,
44988
+ styles: {
44989
+ header: {
44990
+ paddingRight: "30px"
44991
+ }
44992
+ },
44953
44993
  children: [
44954
44994
  error && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Alert, { type: "error", message: "Error while submitting", description: error?.response?.data?.message }),
44955
44995
  modalDescriptionText && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
@@ -45009,6 +45049,11 @@
45009
45049
  width: editModalWidth || 520,
45010
45050
  destroyOnHidden: true,
45011
45051
  centered: true,
45052
+ styles: {
45053
+ header: {
45054
+ paddingRight: "30px"
45055
+ }
45056
+ },
45012
45057
  children: [
45013
45058
  modalDescriptionText && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
45014
45059
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: modalDescriptionTextStyle, children: modalDescriptionText }),
@@ -79612,7 +79657,9 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
79612
79657
  deleteChildren: { verb: "delete" },
79613
79658
  rerunLast: { verb: "create" },
79614
79659
  drain: { verb: "patch" },
79615
- rollback: { verb: "patch" }
79660
+ rollback: { verb: "patch" },
79661
+ downloadAsFiles: { verb: "get" },
79662
+ createFromFiles: { verb: "create" }
79616
79663
  };
79617
79664
 
79618
79665
  const IconWrapper = styled.span`
@@ -79710,15 +79757,26 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
79710
79757
  }
79711
79758
  return value;
79712
79759
  };
79713
- const resolveObjectFromTemplate = (template, multiQueryData) => {
79714
- const match = template.match(/^\{reqs\[(\d+)\]\[((?:\s*['"][^'"]+['"]\s*,?)+)\]\}$/);
79715
- if (match) {
79716
- const reqIndex = parseInt(match[1], 10);
79717
- const pathKeys = Array.from(match[2].matchAll(/['"]([^'"]+)['"]/g)).map((m) => m[1]);
79718
- const reqData = multiQueryData[`req${reqIndex}`];
79719
- if (reqData != null) {
79720
- return _$1.get(reqData, pathKeys);
79760
+ const resolveObjectByReqIndexAndJsonPath = ({
79761
+ reqIndex,
79762
+ jsonPathToObj,
79763
+ multiQueryData
79764
+ }) => {
79765
+ const reqIndexNumber = Number(reqIndex);
79766
+ if (!Number.isInteger(reqIndexNumber) || reqIndexNumber < 0) {
79767
+ return void 0;
79768
+ }
79769
+ const jsonRoot = multiQueryData[`req${reqIndexNumber}`];
79770
+ if (jsonRoot === void 0) {
79771
+ return void 0;
79772
+ }
79773
+ try {
79774
+ const value = jp.query(jsonRoot, `$${jsonPathToObj}`)?.[0];
79775
+ if (value && typeof value === "object" && !Array.isArray(value)) {
79776
+ return value;
79721
79777
  }
79778
+ } catch {
79779
+ return void 0;
79722
79780
  }
79723
79781
  return void 0;
79724
79782
  };
@@ -79783,6 +79841,74 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
79783
79841
  childResourceName: childResourceNamePrepared
79784
79842
  };
79785
79843
  };
79844
+ const generateDnsCompliantName = (prefix, maxLength = 63) => {
79845
+ const timestamp = Date.now();
79846
+ const randomHex = Math.random().toString(16).substring(2, 6);
79847
+ const suffix = `-${timestamp}-${randomHex}`;
79848
+ const truncatedPrefix = prefix.substring(0, maxLength - suffix.length);
79849
+ return `${truncatedPrefix}${suffix}`.toLowerCase().replace(/[^a-z0-9-]/g, "-");
79850
+ };
79851
+ const JOB_MANAGED_LABEL_KEYS = [
79852
+ "controller-uid",
79853
+ "job-name",
79854
+ "batch.kubernetes.io/controller-uid",
79855
+ "batch.kubernetes.io/job-name"
79856
+ ];
79857
+ const stripManagedJobLabels = (labels) => {
79858
+ if (!labels || typeof labels !== "object" || Array.isArray(labels)) {
79859
+ return void 0;
79860
+ }
79861
+ const cleaned = { ...labels };
79862
+ JOB_MANAGED_LABEL_KEYS.forEach((key) => delete cleaned[key]);
79863
+ return Object.keys(cleaned).length > 0 ? cleaned : void 0;
79864
+ };
79865
+ const stripMetadataForRerun = (sourceObj, sourceJobName) => {
79866
+ let normalizedSourceObj = sourceObj;
79867
+ if (_$1.isPlainObject(_$1.get(sourceObj, "spec"))) {
79868
+ normalizedSourceObj = sourceObj;
79869
+ } else if (_$1.isPlainObject(sourceObj) && _$1.isPlainObject(_$1.get(sourceObj, "template"))) {
79870
+ normalizedSourceObj = { spec: sourceObj };
79871
+ }
79872
+ const copy = JSON.parse(JSON.stringify(normalizedSourceObj));
79873
+ const oldMeta = copy.metadata ?? {};
79874
+ const cleanedMetadataLabels = stripManagedJobLabels(oldMeta.labels);
79875
+ copy.metadata = {
79876
+ ...oldMeta.namespace ? { namespace: oldMeta.namespace } : {},
79877
+ ...cleanedMetadataLabels ? { labels: cleanedMetadataLabels } : {},
79878
+ ...oldMeta.annotations ? { annotations: oldMeta.annotations } : {},
79879
+ generateName: `${sourceJobName}-rerun-`
79880
+ };
79881
+ const spec = _$1.get(copy, "spec");
79882
+ if (_$1.isPlainObject(spec)) {
79883
+ const specObj = spec;
79884
+ delete specObj.selector;
79885
+ delete specObj.manualSelector;
79886
+ }
79887
+ const templateLabels = _$1.get(copy, "spec.template.metadata.labels");
79888
+ if (_$1.isPlainObject(templateLabels)) {
79889
+ const cleanedTemplateLabels = stripManagedJobLabels(templateLabels);
79890
+ if (cleanedTemplateLabels) {
79891
+ _$1.set(copy, "spec.template.metadata.labels", cleanedTemplateLabels);
79892
+ } else {
79893
+ _$1.unset(copy, "spec.template.metadata.labels");
79894
+ }
79895
+ }
79896
+ delete copy.status;
79897
+ return copy;
79898
+ };
79899
+ const MAX_FAILED_PODS_SHOWN = 5;
79900
+ const buildDrainFailureDescription = ({ drained, failed, skipped }) => {
79901
+ const lines = [`Evicted ${drained}, skipped ${skipped}, failed ${failed.length}`];
79902
+ const shown = failed.slice(0, MAX_FAILED_PODS_SHOWN);
79903
+ shown.forEach((pod) => {
79904
+ lines.push(React$1.createElement("br", null), `${pod.namespace}/${pod.name}: ${pod.error}`);
79905
+ });
79906
+ if (failed.length > MAX_FAILED_PODS_SHOWN) {
79907
+ lines.push(React$1.createElement("br", null), `+${failed.length - MAX_FAILED_PODS_SHOWN} more`);
79908
+ }
79909
+ return React$1.createElement(React$1.Fragment, null, ...lines);
79910
+ };
79911
+
79786
79912
  const handleEditAction = (action, ctx, fullPath, navigate) => {
79787
79913
  const clusterPrepared = parseAll({ text: action.props.cluster, ...ctx });
79788
79914
  const namespacePrepared = action.props.namespace ? parseAll({ text: action.props.namespace, ...ctx }) : void 0;
@@ -79868,56 +79994,51 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
79868
79994
  });
79869
79995
  setModalOpen(true);
79870
79996
  };
79871
- const generateDnsCompliantName = (prefix, maxLength = 63) => {
79872
- const timestamp = Date.now();
79873
- const randomHex = Math.random().toString(16).substring(2, 6);
79874
- const suffix = `-${timestamp}-${randomHex}`;
79875
- const truncatedPrefix = prefix.substring(0, maxLength - suffix.length);
79876
- return `${truncatedPrefix}${suffix}`.toLowerCase().replace(/[^a-z0-9-]/g, "-");
79877
- };
79878
- const JOB_MANAGED_LABEL_KEYS = [
79879
- "controller-uid",
79880
- "job-name",
79881
- "batch.kubernetes.io/controller-uid",
79882
- "batch.kubernetes.io/job-name"
79883
- ];
79884
- const stripManagedJobLabels = (labels) => {
79885
- if (!labels || typeof labels !== "object" || Array.isArray(labels)) {
79886
- return void 0;
79997
+ const fireTriggerRunAction = (action, ctx, multiQueryData, { showSuccess, showError }) => {
79998
+ const createEndpointPrepared = parseAll({ text: action.props.createEndpoint, ...ctx });
79999
+ const cronJobNamePrepared = parseAll({ text: action.props.cronJobName, ...ctx });
80000
+ const jobTemplateObj = resolveObjectByReqIndexAndJsonPath({
80001
+ reqIndex: action.props.reqIndex,
80002
+ jsonPathToObj: action.props.jsonPathToObj,
80003
+ multiQueryData
80004
+ });
80005
+ if (!jobTemplateObj) {
80006
+ showError("Trigger run", new Error("Could not resolve job template from resource data"));
80007
+ return;
79887
80008
  }
79888
- const cleaned = { ...labels };
79889
- JOB_MANAGED_LABEL_KEYS.forEach((key) => delete cleaned[key]);
79890
- return Object.keys(cleaned).length > 0 ? cleaned : void 0;
79891
- };
79892
- const stripMetadataForRerun = (sourceObj, sourceJobName) => {
79893
- const normalizedSourceObj = _$1.isPlainObject(_$1.get(sourceObj, "spec")) ? sourceObj : _$1.isPlainObject(sourceObj) && _$1.isPlainObject(_$1.get(sourceObj, "template")) ? { spec: sourceObj } : sourceObj;
79894
- const copy = JSON.parse(JSON.stringify(normalizedSourceObj));
79895
- const oldMeta = copy.metadata ?? {};
79896
- const cleanedMetadataLabels = stripManagedJobLabels(oldMeta.labels);
79897
- copy.metadata = {
79898
- ...oldMeta.namespace ? { namespace: oldMeta.namespace } : {},
79899
- ...cleanedMetadataLabels ? { labels: cleanedMetadataLabels } : {},
79900
- ...oldMeta.annotations ? { annotations: oldMeta.annotations } : {},
79901
- generateName: `${sourceJobName}-rerun-`
80009
+ const jobName = generateDnsCompliantName(`${cronJobNamePrepared}-manual`);
80010
+ const namespaceParsed = cronJobNamePrepared ? _$1.get(jobTemplateObj, ["metadata", "namespace"]) : void 0;
80011
+ const body = {
80012
+ apiVersion: "batch/v1",
80013
+ kind: "Job",
80014
+ metadata: {
80015
+ name: jobName,
80016
+ ...namespaceParsed ? { namespace: namespaceParsed } : {},
80017
+ annotations: {
80018
+ "cronjob.kubernetes.io/instantiate": "manual"
80019
+ }
80020
+ },
80021
+ spec: jobTemplateObj.spec
79902
80022
  };
79903
- const spec = _$1.get(copy, "spec");
79904
- if (_$1.isPlainObject(spec)) {
79905
- const specObj = spec;
79906
- delete specObj.selector;
79907
- delete specObj.manualSelector;
79908
- }
79909
- const templateLabels = _$1.get(copy, "spec.template.metadata.labels");
79910
- if (_$1.isPlainObject(templateLabels)) {
79911
- const cleanedTemplateLabels = stripManagedJobLabels(templateLabels);
79912
- if (cleanedTemplateLabels) {
79913
- _$1.set(copy, "spec.template.metadata.labels", cleanedTemplateLabels);
79914
- } else {
79915
- _$1.unset(copy, "spec.template.metadata.labels");
80023
+ const triggerLabel = `Trigger run for ${cronJobNamePrepared}`;
80024
+ createNewEntry({ endpoint: createEndpointPrepared, body }).then(() => showSuccess(triggerLabel)).catch((error) => {
80025
+ showError(triggerLabel, error);
80026
+ });
80027
+ };
80028
+ const handleDownloadAsFilesAction = (action, ctx, setActiveAction, setModalOpen) => {
80029
+ const endpointPrepared = parseAll({ text: action.props.endpoint, ...ctx });
80030
+ const namePrepared = parseAll({ text: action.props.name, ...ctx });
80031
+ setActiveAction({
80032
+ ...action,
80033
+ props: {
80034
+ ...action.props,
80035
+ endpoint: endpointPrepared,
80036
+ name: namePrepared
79916
80037
  }
79917
- }
79918
- delete copy.status;
79919
- return copy;
80038
+ });
80039
+ setModalOpen(true);
79920
80040
  };
80041
+
79921
80042
  const useScaleHandlers = (ctx, { showSuccess, showError }) => {
79922
80043
  const [scaleModalData, setScaleModalData] = React$1.useState(null);
79923
80044
  const [isScaleLoading, setIsScaleLoading] = React$1.useState(false);
@@ -79962,6 +80083,7 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
79962
80083
  };
79963
80084
  return { scaleModalData, isScaleLoading, handleScaleAction, handleScaleConfirm, handleScaleCancel };
79964
80085
  };
80086
+
79965
80087
  const useEvictHandlers = ({ showSuccess, showError }) => {
79966
80088
  const [evictModalData, setEvictModalData] = React$1.useState(null);
79967
80089
  const [isEvictLoading, setIsEvictLoading] = React$1.useState(false);
@@ -79983,13 +80105,18 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
79983
80105
  };
79984
80106
  return { evictModalData, isEvictLoading, setEvictModalData, handleEvictConfirm, handleEvictCancel };
79985
80107
  };
80108
+
79986
80109
  const useRerunHandlers = (ctx, multiQueryData, { showSuccess, showError }) => {
79987
80110
  const [rerunModalData, setRerunModalData] = React$1.useState(null);
79988
80111
  const [isRerunLoading, setIsRerunLoading] = React$1.useState(false);
79989
80112
  const handleRerunLastAction = (action) => {
79990
80113
  const createEndpointPrepared = parseAll({ text: action.props.createEndpoint, ...ctx });
79991
80114
  const sourceJobNamePrepared = parseAll({ text: action.props.sourceJobName, ...ctx });
79992
- const sourceJobObj = resolveObjectFromTemplate(action.props.sourceJobSpec, multiQueryData);
80115
+ const sourceJobObj = resolveObjectByReqIndexAndJsonPath({
80116
+ reqIndex: action.props.reqIndex,
80117
+ jsonPathToObj: action.props.jsonPathToObj,
80118
+ multiQueryData
80119
+ });
79993
80120
  if (!sourceJobObj) {
79994
80121
  showError("Rerun job", new Error("Could not resolve source job spec from resource data"));
79995
80122
  return;
@@ -80018,18 +80145,7 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80018
80145
  };
80019
80146
  return { rerunModalData, isRerunLoading, handleRerunLastAction, handleRerunConfirm, handleRerunCancel };
80020
80147
  };
80021
- const MAX_FAILED_PODS_SHOWN = 5;
80022
- const buildDrainFailureDescription = ({ drained, failed, skipped }) => {
80023
- const lines = [`Evicted ${drained}, skipped ${skipped}, failed ${failed.length}`];
80024
- const shown = failed.slice(0, MAX_FAILED_PODS_SHOWN);
80025
- shown.forEach((pod) => {
80026
- lines.push(React$1.createElement("br", null), `${pod.namespace}/${pod.name}: ${pod.error}`);
80027
- });
80028
- if (failed.length > MAX_FAILED_PODS_SHOWN) {
80029
- lines.push(React$1.createElement("br", null), `+${failed.length - MAX_FAILED_PODS_SHOWN} more`);
80030
- }
80031
- return React$1.createElement(React$1.Fragment, null, ...lines);
80032
- };
80148
+
80033
80149
  const useDrainHandlers = (ctx, { showError }, notificationApi, invalidateMultiQuery) => {
80034
80150
  const [drainModalData, setDrainModalData] = React$1.useState(null);
80035
80151
  const [isDrainLoading, setIsDrainLoading] = React$1.useState(false);
@@ -80075,6 +80191,7 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80075
80191
  };
80076
80192
  return { drainModalData, isDrainLoading, handleDrainAction, handleDrainConfirm, handleDrainCancel };
80077
80193
  };
80194
+
80078
80195
  const useRollbackHandlers = (ctx, { showSuccess, showError }) => {
80079
80196
  const [rollbackModalData, setRollbackModalData] = React$1.useState(null);
80080
80197
  const [isRollbackLoading, setIsRollbackLoading] = React$1.useState(false);
@@ -80108,33 +80225,57 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80108
80225
  };
80109
80226
  return { rollbackModalData, isRollbackLoading, handleRollbackAction, handleRollbackConfirm, handleRollbackCancel };
80110
80227
  };
80111
- const fireTriggerRunAction = (action, ctx, multiQueryData, { showSuccess, showError }) => {
80112
- const createEndpointPrepared = parseAll({ text: action.props.createEndpoint, ...ctx });
80113
- const cronJobNamePrepared = parseAll({ text: action.props.cronJobName, ...ctx });
80114
- const jobTemplateObj = resolveObjectFromTemplate(action.props.jobTemplate, multiQueryData);
80115
- if (!jobTemplateObj) {
80116
- showError("Trigger run", new Error("Could not resolve job template from resource data"));
80117
- return;
80118
- }
80119
- const jobName = generateDnsCompliantName(`${cronJobNamePrepared}-manual`);
80120
- const namespaceParsed = cronJobNamePrepared ? _$1.get(jobTemplateObj, ["metadata", "namespace"]) : void 0;
80121
- const body = {
80122
- apiVersion: "batch/v1",
80123
- kind: "Job",
80124
- metadata: {
80125
- name: jobName,
80126
- ...namespaceParsed ? { namespace: namespaceParsed } : {},
80127
- annotations: {
80128
- "cronjob.kubernetes.io/instantiate": "manual"
80129
- }
80130
- },
80131
- spec: jobTemplateObj.spec
80228
+
80229
+ const useCreateFromFilesHandlers = (ctx, { showSuccess, showError }) => {
80230
+ const [createFromFilesModalData, setCreateFromFilesModalData] = React$1.useState(null);
80231
+ const [isCreateFromFilesLoading, setIsCreateFromFilesLoading] = React$1.useState(false);
80232
+ const handleCreateFromFilesAction = (action) => {
80233
+ const createEndpointPrepared = parseAll({ text: action.props.createEndpoint, ...ctx });
80234
+ const namespacePrepared = parseAll({ text: action.props.namespace, ...ctx });
80235
+ const apiVersionPrepared = action.props.apiVersion ? parseAll({ text: action.props.apiVersion, ...ctx }) : "v1";
80236
+ setCreateFromFilesModalData({
80237
+ createEndpoint: createEndpointPrepared,
80238
+ namespace: namespacePrepared,
80239
+ resourceKind: action.props.resourceKind,
80240
+ apiVersion: apiVersionPrepared
80241
+ });
80242
+ };
80243
+ const handleCreateFromFilesConfirm = (name, data, binaryData) => {
80244
+ if (!createFromFilesModalData) return;
80245
+ setIsCreateFromFilesLoading(true);
80246
+ const { createEndpoint, namespace, resourceKind, apiVersion } = createFromFilesModalData;
80247
+ const createLabel = `Create ${resourceKind} ${name}`;
80248
+ const body = {
80249
+ apiVersion,
80250
+ kind: resourceKind,
80251
+ metadata: { name, namespace }
80252
+ };
80253
+ if (Object.keys(data).length > 0) {
80254
+ body.data = data;
80255
+ }
80256
+ if (Object.keys(binaryData).length > 0) {
80257
+ body.binaryData = binaryData;
80258
+ }
80259
+ createNewEntry({ endpoint: createEndpoint, body }).then(() => showSuccess(createLabel)).catch((error) => {
80260
+ showError(createLabel, error);
80261
+ }).finally(() => {
80262
+ setIsCreateFromFilesLoading(false);
80263
+ setCreateFromFilesModalData(null);
80264
+ });
80265
+ };
80266
+ const handleCreateFromFilesCancel = () => {
80267
+ setCreateFromFilesModalData(null);
80268
+ setIsCreateFromFilesLoading(false);
80269
+ };
80270
+ return {
80271
+ createFromFilesModalData,
80272
+ isCreateFromFilesLoading,
80273
+ handleCreateFromFilesAction,
80274
+ handleCreateFromFilesConfirm,
80275
+ handleCreateFromFilesCancel
80132
80276
  };
80133
- const triggerLabel = `Trigger run for ${cronJobNamePrepared}`;
80134
- createNewEntry({ endpoint: createEndpointPrepared, body }).then(() => showSuccess(triggerLabel)).catch((error) => {
80135
- showError(triggerLabel, error);
80136
- });
80137
80277
  };
80278
+
80138
80279
  const useActionsDropdownHandlers = ({ replaceValues, multiQueryData }) => {
80139
80280
  const navigate = reactRouterDom.useNavigate();
80140
80281
  const location = reactRouterDom.useLocation();
@@ -80187,6 +80328,13 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80187
80328
  invalidateMultiQuery
80188
80329
  );
80189
80330
  const { rollbackModalData, isRollbackLoading, handleRollbackAction, handleRollbackConfirm, handleRollbackCancel } = useRollbackHandlers(ctx, notificationCallbacks);
80331
+ const {
80332
+ createFromFilesModalData,
80333
+ isCreateFromFilesLoading,
80334
+ handleCreateFromFilesAction,
80335
+ handleCreateFromFilesConfirm,
80336
+ handleCreateFromFilesCancel
80337
+ } = useCreateFromFilesHandlers(ctx, notificationCallbacks);
80190
80338
  const handleDeleteChildrenAction = (action) => {
80191
80339
  try {
80192
80340
  const data = buildDeleteChildrenData(action, ctx);
@@ -80201,57 +80349,59 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80201
80349
  invalidateMultiQuery();
80202
80350
  };
80203
80351
  const handleActionClick = (action) => {
80204
- if (action.type === "edit") {
80205
- handleEditAction(action, ctx, fullPath, navigate);
80206
- return;
80207
- }
80208
- if (action.type === "delete") {
80209
- handleDeleteAction(action, ctx, setDeleteModalData);
80210
- return;
80211
- }
80212
- if (action.type === "cordon" || action.type === "uncordon" || action.type === "suspend" || action.type === "resume") {
80213
- handlePatchActions(action, ctx, showSuccess, showError);
80214
- return;
80215
- }
80216
- if (action.type === "rolloutRestart") {
80217
- handleRolloutRestartAction(action, ctx, showSuccess, showError);
80218
- return;
80219
- }
80220
- if (action.type === "evict") {
80221
- const evictData = buildEvictModalData(action.props, ctx);
80222
- setEvictModalData(evictData);
80223
- return;
80224
- }
80225
- if (action.type === "openKubeletConfig") {
80226
- handleOpenKubeletConfigAction(action, ctx, setActiveAction, setModalOpen);
80227
- return;
80228
- }
80229
- if (action.type === "scale") {
80230
- handleScaleAction(action);
80231
- return;
80232
- }
80233
- if (action.type === "triggerRun") {
80234
- fireTriggerRunAction(action, ctx, multiQueryData, notificationCallbacks);
80235
- return;
80236
- }
80237
- if (action.type === "deleteChildren") {
80238
- handleDeleteChildrenAction(action);
80239
- return;
80240
- }
80241
- if (action.type === "rerunLast") {
80242
- handleRerunLastAction(action);
80243
- return;
80244
- }
80245
- if (action.type === "drain") {
80246
- handleDrainAction(action);
80247
- return;
80248
- }
80249
- if (action.type === "rollback") {
80250
- handleRollbackAction(action);
80251
- return;
80352
+ switch (action.type) {
80353
+ case "edit":
80354
+ handleEditAction(action, ctx, fullPath, navigate);
80355
+ return;
80356
+ case "delete":
80357
+ handleDeleteAction(action, ctx, setDeleteModalData);
80358
+ return;
80359
+ case "cordon":
80360
+ case "uncordon":
80361
+ case "suspend":
80362
+ case "resume":
80363
+ handlePatchActions(action, ctx, showSuccess, showError);
80364
+ return;
80365
+ case "rolloutRestart":
80366
+ handleRolloutRestartAction(action, ctx, showSuccess, showError);
80367
+ return;
80368
+ case "evict": {
80369
+ const evictData = buildEvictModalData(action.props, ctx);
80370
+ setEvictModalData(evictData);
80371
+ return;
80372
+ }
80373
+ case "openKubeletConfig":
80374
+ handleOpenKubeletConfigAction(action, ctx, setActiveAction, setModalOpen);
80375
+ return;
80376
+ case "scale":
80377
+ handleScaleAction(action);
80378
+ return;
80379
+ case "triggerRun":
80380
+ fireTriggerRunAction(action, ctx, multiQueryData, notificationCallbacks);
80381
+ return;
80382
+ case "deleteChildren":
80383
+ handleDeleteChildrenAction(action);
80384
+ return;
80385
+ case "rerunLast":
80386
+ handleRerunLastAction(action);
80387
+ return;
80388
+ case "drain":
80389
+ handleDrainAction(action);
80390
+ return;
80391
+ case "rollback":
80392
+ handleRollbackAction(action);
80393
+ return;
80394
+ case "downloadAsFiles":
80395
+ handleDownloadAsFilesAction(action, ctx, setActiveAction, setModalOpen);
80396
+ return;
80397
+ case "createFromFiles":
80398
+ handleCreateFromFilesAction(action);
80399
+ return;
80400
+ default: {
80401
+ setActiveAction(action);
80402
+ setModalOpen(true);
80403
+ }
80252
80404
  }
80253
- setActiveAction(action);
80254
- setModalOpen(true);
80255
80405
  };
80256
80406
  const handleCloseModal = () => {
80257
80407
  setModalOpen(false);
@@ -80296,7 +80446,11 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80296
80446
  handleDrainConfirm,
80297
80447
  handleDrainCancel,
80298
80448
  handleRollbackConfirm,
80299
- handleRollbackCancel
80449
+ handleRollbackCancel,
80450
+ createFromFilesModalData,
80451
+ isCreateFromFilesLoading,
80452
+ handleCreateFromFilesConfirm,
80453
+ handleCreateFromFilesCancel
80300
80454
  };
80301
80455
  };
80302
80456
 
@@ -80460,6 +80614,151 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80460
80614
  );
80461
80615
  };
80462
80616
 
80617
+ const getDataEntries = (resource) => {
80618
+ const entries = [];
80619
+ const data = resource.data;
80620
+ const binaryData = resource.binaryData;
80621
+ if (data) {
80622
+ Object.keys(data).forEach((key) => {
80623
+ entries.push({ key, isBinary: false });
80624
+ });
80625
+ }
80626
+ if (binaryData) {
80627
+ Object.keys(binaryData).forEach((key) => {
80628
+ entries.push({ key, isBinary: true });
80629
+ });
80630
+ }
80631
+ return entries;
80632
+ };
80633
+ const decodeBase64 = (value) => {
80634
+ const binaryString = atob(value);
80635
+ const bytes = new Uint8Array(binaryString.length);
80636
+ for (let i = 0; i < binaryString.length; i += 1) {
80637
+ bytes[i] = binaryString.charCodeAt(i);
80638
+ }
80639
+ return bytes;
80640
+ };
80641
+ const triggerFileDownload = (filename, content) => {
80642
+ const blob = typeof content === "string" ? new Blob([content], { type: "text/plain" }) : new Blob([Uint8Array.from(content)]);
80643
+ const url = URL.createObjectURL(blob);
80644
+ const a = document.createElement("a");
80645
+ a.href = url;
80646
+ a.download = filename;
80647
+ document.body.appendChild(a);
80648
+ a.click();
80649
+ document.body.removeChild(a);
80650
+ URL.revokeObjectURL(url);
80651
+ };
80652
+ const DownloadAsFilesModal = ({
80653
+ open,
80654
+ onClose,
80655
+ endpoint,
80656
+ resourceKind,
80657
+ name
80658
+ }) => {
80659
+ const [selectedKeys, setSelectedKeys] = React$1.useState([]);
80660
+ const { data, isLoading, isError, error } = useDirectUnknownResource({
80661
+ uri: endpoint,
80662
+ queryKey: ["download-as-files", endpoint],
80663
+ refetchInterval: false,
80664
+ isEnabled: open && !!endpoint && endpoint !== "-"
80665
+ });
80666
+ const entries = React$1.useMemo(() => data ? getDataEntries(data) : [], [data]);
80667
+ const allKeys = React$1.useMemo(() => entries.map((e) => e.key), [entries]);
80668
+ const handleSelectAll = (checked) => {
80669
+ setSelectedKeys(checked ? allKeys : []);
80670
+ };
80671
+ const handleToggleKey = (key, checked) => {
80672
+ setSelectedKeys((prev) => checked ? [...prev, key] : prev.filter((k) => k !== key));
80673
+ };
80674
+ const handleDownload = () => {
80675
+ if (!data) return;
80676
+ const dataMap = data.data ?? {};
80677
+ const binaryDataMap = data.binaryData ?? {};
80678
+ const isSecret = resourceKind === "Secret";
80679
+ selectedKeys.forEach((key) => {
80680
+ if (binaryDataMap[key] !== void 0) {
80681
+ triggerFileDownload(key, decodeBase64(binaryDataMap[key]));
80682
+ } else if (dataMap[key] !== void 0) {
80683
+ const content = isSecret ? decodeBase64(dataMap[key]) : dataMap[key];
80684
+ triggerFileDownload(key, content);
80685
+ }
80686
+ });
80687
+ onClose();
80688
+ };
80689
+ const isAllSelected = allKeys.length > 0 && selectedKeys.length === allKeys.length;
80690
+ const isIndeterminate = selectedKeys.length > 0 && selectedKeys.length < allKeys.length;
80691
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
80692
+ antd.Modal,
80693
+ {
80694
+ title: `Download files from «${name}»`,
80695
+ open,
80696
+ onOk: handleDownload,
80697
+ onCancel: onClose,
80698
+ okText: "Download",
80699
+ okButtonProps: { disabled: selectedKeys.length === 0 },
80700
+ width: 520,
80701
+ styles: {
80702
+ header: {
80703
+ paddingRight: "30px"
80704
+ }
80705
+ },
80706
+ children: [
80707
+ isLoading && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Spin, {}),
80708
+ isError && /* @__PURE__ */ jsxRuntimeExports.jsx(
80709
+ antd.Alert,
80710
+ {
80711
+ type: "error",
80712
+ showIcon: true,
80713
+ message: "Failed to load resource",
80714
+ description: error instanceof Error ? error.message : "Unknown error"
80715
+ }
80716
+ ),
80717
+ !isLoading && !isError && entries.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(antd.Typography.Text, { type: "secondary", children: [
80718
+ "No data entries found in this ",
80719
+ resourceKind,
80720
+ "."
80721
+ ] }),
80722
+ !isLoading && !isError && entries.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
80723
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { marginBottom: 8 }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
80724
+ antd.Checkbox,
80725
+ {
80726
+ checked: isAllSelected,
80727
+ indeterminate: isIndeterminate,
80728
+ onChange: (e) => handleSelectAll(e.target.checked),
80729
+ children: [
80730
+ "Select all (",
80731
+ entries.length,
80732
+ ")"
80733
+ ]
80734
+ }
80735
+ ) }),
80736
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
80737
+ antd.List,
80738
+ {
80739
+ size: "small",
80740
+ bordered: true,
80741
+ dataSource: entries,
80742
+ style: { maxHeight: 400, overflow: "auto" },
80743
+ renderItem: (entry) => /* @__PURE__ */ jsxRuntimeExports.jsx(antd.List.Item, { style: { padding: "4px 12px" }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
80744
+ antd.Checkbox,
80745
+ {
80746
+ checked: selectedKeys.includes(entry.key),
80747
+ onChange: (e) => handleToggleKey(entry.key, e.target.checked),
80748
+ children: [
80749
+ entry.key,
80750
+ entry.isBinary && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Typography.Text, { type: "secondary", style: { marginLeft: 8 }, children: "(binary)" })
80751
+ ]
80752
+ }
80753
+ ) })
80754
+ }
80755
+ )
80756
+ ] })
80757
+ ]
80758
+ }
80759
+ );
80760
+ };
80761
+
80463
80762
  const renderActionModal = (action, extraProps) => {
80464
80763
  switch (action.type) {
80465
80764
  case "edit":
@@ -80489,7 +80788,18 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80489
80788
  case "rerunLast":
80490
80789
  case "drain":
80491
80790
  case "rollback":
80791
+ case "createFromFiles":
80492
80792
  return null;
80793
+ case "downloadAsFiles":
80794
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
80795
+ DownloadAsFilesModal,
80796
+ {
80797
+ ...extraProps,
80798
+ endpoint: action.props.endpoint,
80799
+ resourceKind: action.props.resourceKind,
80800
+ name: action.props.name
80801
+ }
80802
+ );
80493
80803
  default: {
80494
80804
  const _exhaustive = action;
80495
80805
  return _exhaustive;
@@ -80520,6 +80830,11 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80520
80830
  confirmLoading: isLoading,
80521
80831
  okButtonProps: { disabled: !isValidReplicas },
80522
80832
  width: 400,
80833
+ styles: {
80834
+ header: {
80835
+ paddingRight: "30px"
80836
+ }
80837
+ },
80523
80838
  children: [
80524
80839
  /* @__PURE__ */ jsxRuntimeExports.jsxs(antd.Typography.Paragraph, { children: [
80525
80840
  "Current replicas: ",
@@ -80544,6 +80859,174 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80544
80859
  );
80545
80860
  };
80546
80861
 
80862
+ const isValidUtf8Text = (bytes) => {
80863
+ try {
80864
+ const decoded = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
80865
+ return !decoded.includes("\0");
80866
+ } catch {
80867
+ return false;
80868
+ }
80869
+ };
80870
+ const arrayBufferToBase64 = (buffer) => {
80871
+ const bytes = new Uint8Array(buffer);
80872
+ let binary = "";
80873
+ for (let i = 0; i < bytes.length; i += 1) {
80874
+ binary += String.fromCharCode(bytes[i]);
80875
+ }
80876
+ return btoa(binary);
80877
+ };
80878
+ const CreateFromFilesModal = ({
80879
+ open,
80880
+ onClose,
80881
+ onConfirm,
80882
+ resourceKind,
80883
+ namespace,
80884
+ isLoading
80885
+ }) => {
80886
+ const [resourceName, setResourceName] = React$1.useState("");
80887
+ const [fileEntries, setFileEntries] = React$1.useState([]);
80888
+ const handleBeforeUpload = (file) => {
80889
+ const reader = new FileReader();
80890
+ reader.onload = () => {
80891
+ const buffer = reader.result;
80892
+ const bytes = new Uint8Array(buffer);
80893
+ const isBinary = !isValidUtf8Text(bytes);
80894
+ let content;
80895
+ if (resourceKind === "Secret") {
80896
+ content = arrayBufferToBase64(buffer);
80897
+ } else if (isBinary) {
80898
+ content = arrayBufferToBase64(buffer);
80899
+ } else {
80900
+ content = new TextDecoder("utf-8").decode(bytes);
80901
+ }
80902
+ setFileEntries((prev) => [
80903
+ ...prev,
80904
+ {
80905
+ uid: file.uid,
80906
+ originalName: file.name,
80907
+ keyName: file.name,
80908
+ content,
80909
+ isBinary: resourceKind === "Secret" ? false : isBinary
80910
+ }
80911
+ ]);
80912
+ };
80913
+ reader.readAsArrayBuffer(file);
80914
+ return false;
80915
+ };
80916
+ const handleRemoveFile = (uid) => {
80917
+ setFileEntries((prev) => prev.filter((e) => e.uid !== uid));
80918
+ };
80919
+ const handleKeyNameChange = (uid, newKeyName) => {
80920
+ setFileEntries((prev) => prev.map((e) => e.uid === uid ? { ...e, keyName: newKeyName } : e));
80921
+ };
80922
+ const handleConfirm = () => {
80923
+ const trimmedResourceName = resourceName.trim();
80924
+ const data = {};
80925
+ const binaryData = {};
80926
+ fileEntries.forEach((entry) => {
80927
+ const keyName = entry.keyName.trim();
80928
+ if (entry.isBinary) {
80929
+ binaryData[keyName] = entry.content;
80930
+ } else {
80931
+ data[keyName] = entry.content;
80932
+ }
80933
+ });
80934
+ onConfirm(trimmedResourceName, data, binaryData);
80935
+ };
80936
+ const handleClose = () => {
80937
+ setResourceName("");
80938
+ setFileEntries([]);
80939
+ onClose();
80940
+ };
80941
+ const hasEmptyKeyNames = fileEntries.some((e) => !e.keyName.trim());
80942
+ const hasDuplicateKeyNames = new Set(fileEntries.map((e) => e.keyName.trim())).size !== fileEntries.length;
80943
+ const isValid = resourceName.trim() && fileEntries.length > 0 && !hasEmptyKeyNames && !hasDuplicateKeyNames;
80944
+ const columns = [
80945
+ {
80946
+ title: "File",
80947
+ dataIndex: "originalName",
80948
+ key: "originalName",
80949
+ width: "35%",
80950
+ render: (text, record) => /* @__PURE__ */ jsxRuntimeExports.jsxs(antd.Space, { children: [
80951
+ /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Typography.Text, { ellipsis: true, style: { maxWidth: 150 }, children: text }),
80952
+ record.isBinary && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Typography.Text, { type: "secondary", children: "(binary)" })
80953
+ ] })
80954
+ },
80955
+ {
80956
+ title: "Key name",
80957
+ dataIndex: "keyName",
80958
+ key: "keyName",
80959
+ render: (_, record) => /* @__PURE__ */ jsxRuntimeExports.jsx(
80960
+ antd.Input,
80961
+ {
80962
+ size: "small",
80963
+ value: record.keyName,
80964
+ onChange: (e) => handleKeyNameChange(record.uid, e.target.value),
80965
+ status: !record.keyName.trim() ? "error" : void 0
80966
+ }
80967
+ )
80968
+ },
80969
+ {
80970
+ title: "",
80971
+ key: "actions",
80972
+ width: 40,
80973
+ render: (_, record) => /* @__PURE__ */ jsxRuntimeExports.jsx(AntIcons.DeleteOutlined, { style: { color: "#ff4d4f", cursor: "pointer" }, onClick: () => handleRemoveFile(record.uid) })
80974
+ }
80975
+ ];
80976
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
80977
+ antd.Modal,
80978
+ {
80979
+ title: `Create ${resourceKind} from files`,
80980
+ open,
80981
+ onOk: handleConfirm,
80982
+ onCancel: handleClose,
80983
+ okText: "Create",
80984
+ confirmLoading: isLoading,
80985
+ okButtonProps: { disabled: !isValid },
80986
+ width: 600,
80987
+ styles: {
80988
+ header: {
80989
+ paddingRight: "30px"
80990
+ }
80991
+ },
80992
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(antd.Space, { direction: "vertical", style: { width: "100%" }, size: "middle", children: [
80993
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
80994
+ /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Typography.Text, { strong: true, children: "Name" }),
80995
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
80996
+ antd.Input,
80997
+ {
80998
+ placeholder: `${resourceKind.toLowerCase()}-name`,
80999
+ value: resourceName,
81000
+ onChange: (e) => setResourceName(e.target.value),
81001
+ style: { marginTop: 4 }
81002
+ }
81003
+ )
81004
+ ] }),
81005
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
81006
+ /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Typography.Text, { strong: true, children: "Namespace" }),
81007
+ /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Input, { value: namespace, disabled: true, style: { marginTop: 4 } })
81008
+ ] }),
81009
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(antd.Upload.Dragger, { multiple: true, beforeUpload: handleBeforeUpload, showUploadList: false, children: [
81010
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ant-upload-drag-icon", children: /* @__PURE__ */ jsxRuntimeExports.jsx(AntIcons.InboxOutlined, {}) }),
81011
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ant-upload-text", children: "Click or drag files to add" })
81012
+ ] }),
81013
+ fileEntries.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
81014
+ antd.Table,
81015
+ {
81016
+ dataSource: fileEntries,
81017
+ columns,
81018
+ rowKey: "uid",
81019
+ size: "small",
81020
+ pagination: false,
81021
+ scroll: { y: 300 }
81022
+ }
81023
+ ),
81024
+ hasDuplicateKeyNames && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Typography.Text, { type: "danger", children: "Key names must be unique." })
81025
+ ] })
81026
+ }
81027
+ );
81028
+ };
81029
+
80547
81030
  const ActionsDropdown = ({ data, children }) => {
80548
81031
  const { buttonText = "Actions", buttonVariant = "default", containerStyle, actions, permissions } = data;
80549
81032
  const { data: multiQueryData, isLoading: isMultiQueryLoading, isError: isMultiQueryError, errors } = useMultiQuery();
@@ -80593,7 +81076,11 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80593
81076
  handleDrainConfirm,
80594
81077
  handleDrainCancel,
80595
81078
  handleRollbackConfirm,
80596
- handleRollbackCancel
81079
+ handleRollbackCancel,
81080
+ createFromFilesModalData,
81081
+ isCreateFromFilesLoading,
81082
+ handleCreateFromFilesConfirm,
81083
+ handleCreateFromFilesCancel
80597
81084
  } = useActionsDropdownHandlers({
80598
81085
  replaceValues,
80599
81086
  multiQueryData: safeMultiQueryData
@@ -80690,6 +81177,17 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
80690
81177
  children: "This will revert the resource to its previous revision."
80691
81178
  }
80692
81179
  ),
81180
+ createFromFilesModalData && /* @__PURE__ */ jsxRuntimeExports.jsx(
81181
+ CreateFromFilesModal,
81182
+ {
81183
+ open: true,
81184
+ onClose: handleCreateFromFilesCancel,
81185
+ onConfirm: handleCreateFromFilesConfirm,
81186
+ resourceKind: createFromFilesModalData.resourceKind,
81187
+ namespace: createFromFilesModalData.namespace,
81188
+ isLoading: isCreateFromFilesLoading
81189
+ }
81190
+ ),
80693
81191
  children
80694
81192
  ] });
80695
81193
  };
@@ -82656,15 +83154,16 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
82656
83154
  /* @__PURE__ */ jsxRuntimeExports.jsx(PersistedCheckbox, { formName: persistName || name, persistedControls, type: "arr" })
82657
83155
  ] })
82658
83156
  ] }),
82659
- /* @__PURE__ */ jsxRuntimeExports.jsx(
82660
- ResetedFormItem$1,
82661
- {
82662
- name: arrName || fixedName,
82663
- rules: [getRequiredRule(forceNonRequired === false && !!required?.includes(getStringByName(name)), name)],
82664
- validateTrigger: "onBlur",
82665
- hasFeedback: designNewLayout ? { icons: feedbackIcons } : true,
82666
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs(antd.Flex, { gap: 8, align: "center", children: [
82667
- /* @__PURE__ */ jsxRuntimeExports.jsx(
83157
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(antd.Flex, { gap: 8, align: "center", children: [
83158
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
83159
+ ResetedFormItem$1,
83160
+ {
83161
+ name: arrName || fixedName,
83162
+ rules: [getRequiredRule(forceNonRequired === false && !!required?.includes(getStringByName(name)), name)],
83163
+ validateTrigger: "onBlur",
83164
+ hasFeedback: designNewLayout ? { icons: feedbackIcons } : true,
83165
+ style: { flex: 1 },
83166
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
82668
83167
  antd.Select,
82669
83168
  {
82670
83169
  mode: customProps.mode,
@@ -82676,12 +83175,12 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
82676
83175
  showSearch: true,
82677
83176
  style: { width: "100%" }
82678
83177
  }
82679
- ),
82680
- relatedValueTooltip && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Tooltip, { title: relatedValueTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(AntIcons.QuestionCircleOutlined, {}) })
82681
- ] })
82682
- },
82683
- arrKey !== void 0 ? arrKey : Array.isArray(name) ? name.slice(-1)[0] : name
82684
- )
83178
+ )
83179
+ },
83180
+ arrKey !== void 0 ? arrKey : Array.isArray(name) ? name.slice(-1)[0] : name
83181
+ ),
83182
+ relatedValueTooltip && /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Tooltip, { title: relatedValueTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(AntIcons.QuestionCircleOutlined, {}) })
83183
+ ] })
82685
83184
  ] });
82686
83185
  };
82687
83186
 
@@ -84782,6 +85281,19 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
84782
85281
  const [form] = antd.Form.useForm();
84783
85282
  const allValues = antd.Form.useWatch([], form);
84784
85283
  const namespaceFromFormData = antd.Form.useWatch(["metadata", "namespace"], form);
85284
+ const resolvedBacklink = React$1.useMemo(() => {
85285
+ if (!backlink || !namespaceFromFormData) return backlink;
85286
+ const tablePattern = /(\/api-table\/|\/builtin-table\/)/;
85287
+ const match = backlink.match(tablePattern);
85288
+ if (!match || match.index == null) return backlink;
85289
+ const beforeTable = backlink.substring(0, match.index);
85290
+ const tableAndAfter = backlink.substring(match.index);
85291
+ const segments = beforeTable.split("/").filter(Boolean);
85292
+ if (segments.length <= 2) {
85293
+ return `${beforeTable}/${namespaceFromFormData}${tableAndAfter}`;
85294
+ }
85295
+ return backlink;
85296
+ }, [backlink, namespaceFromFormData]);
84785
85297
  const [properties, setProperties] = React$1.useState(staticProperties);
84786
85298
  const [yamlValues, setYamlValues] = React$1.useState();
84787
85299
  const debouncedSetYamlValues = useDebounceCallback(setYamlValues, 500);
@@ -84873,8 +85385,8 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
84873
85385
  if (isCreate) {
84874
85386
  createNewEntry({ endpoint, body }).then((res) => {
84875
85387
  console.log(res);
84876
- if (backlink) {
84877
- navigate(backlink);
85388
+ if (resolvedBacklink) {
85389
+ navigate(resolvedBacklink);
84878
85390
  }
84879
85391
  }).catch((error2) => {
84880
85392
  console.log("Form submit error", error2);
@@ -84888,8 +85400,8 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
84888
85400
  } else {
84889
85401
  updateEntry({ endpoint, body }).then((res) => {
84890
85402
  console.log(res);
84891
- if (backlink) {
84892
- navigate(backlink);
85403
+ if (resolvedBacklink) {
85404
+ navigate(resolvedBacklink);
84893
85405
  }
84894
85406
  }).catch((error2) => {
84895
85407
  console.log("Form submit error", error2);
@@ -85539,6 +86051,11 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
85539
86051
  title: /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Typography.Text, { type: "danger", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$i.BigText, { children: "Error!" }) }),
85540
86052
  cancelButtonProps: { style: { display: "none" } },
85541
86053
  centered: true,
86054
+ styles: {
86055
+ header: {
86056
+ paddingRight: "30px"
86057
+ }
86058
+ },
85542
86059
  children: [
85543
86060
  "An error has occurred: ",
85544
86061
  error?.response?.data?.message
@@ -85554,6 +86071,11 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
85554
86071
  title: "Debug for properties",
85555
86072
  width: "90vw",
85556
86073
  centered: true,
86074
+ styles: {
86075
+ header: {
86076
+ paddingRight: "30px"
86077
+ }
86078
+ },
85557
86079
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$i.DebugContainer, { $designNewLayoutHeight: designNewLayoutHeight, children: /* @__PURE__ */ jsxRuntimeExports.jsx(React$1.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
85558
86080
  Editor,
85559
86081
  {
@@ -85913,6 +86435,11 @@ Take a look at the reducer(s) handling this action type: ${action.type}.
85913
86435
  onCancel: () => setIsOpen(false),
85914
86436
  onOk: () => submit(),
85915
86437
  centered: true,
86438
+ styles: {
86439
+ header: {
86440
+ paddingRight: "30px"
86441
+ }
86442
+ },
85916
86443
  children: /* @__PURE__ */ jsxRuntimeExports.jsxs(antd.Form, { form, name: "control-hooks", initialValues: { ...defaultValues }, children: [
85917
86444
  /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Form.Item, { label: "Name", name: "name", children: /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Input, { required: true }) }),
85918
86445
  /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Form.Item, { label: "Description", name: "description", children: /* @__PURE__ */ jsxRuntimeExports.jsx(antd.Input, { required: true }) }),