@devtron-labs/devtron-fe-common-lib 0.0.48-beta-3 → 0.0.48-beta-5

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.
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { AddCDButtonProps } from './types';
3
+ export default function AddCDButton({ position, addCDButtons, endNode, startNode, handleAddCD, tooltipContent, }: Readonly<AddCDButtonProps>): JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { default as AddCDButton } from './AddCDButton';
2
+ export { handleAddCD } from './utils';
@@ -0,0 +1,26 @@
1
+ import { AddCDPositions, AddPipelineType, EdgeEndNodeType, EdgeNodeType, Point } from '../Types';
2
+ export interface AddCDButtonProps {
3
+ position: AddCDPositions;
4
+ addCDButtons: AddCDPositions[];
5
+ endNode: Point & EdgeEndNodeType;
6
+ startNode: Point & EdgeNodeType;
7
+ handleAddCD: (position: AddCDPositions) => void;
8
+ tooltipContent?: string;
9
+ }
10
+ export interface HandleAddCD {
11
+ position: AddCDPositions;
12
+ handleCDSelect: (workflowId: number | string, ciPipelineId: number | string, parentPipelineType: string, parentPipelineId: number | string, isWebhookCD?: boolean, childPipelineId?: number | string, addType?: AddPipelineType) => void;
13
+ startNode: EdgeNodeType;
14
+ endNode: EdgeEndNodeType;
15
+ workflowId: number | string;
16
+ ciPipelineId: number | string;
17
+ isWebhookCD: boolean;
18
+ isParallelEdge: boolean;
19
+ }
20
+ export interface GetPipelineType {
21
+ isWebhookCD: boolean;
22
+ startNode: EdgeNodeType;
23
+ }
24
+ export interface TooltipContentProps {
25
+ tooltipContent?: string;
26
+ }
@@ -0,0 +1,2 @@
1
+ import { HandleAddCD } from './types';
2
+ export declare const handleAddCD: ({ position, handleCDSelect, startNode, endNode, workflowId, ciPipelineId, isWebhookCD, isParallelEdge, }: HandleAddCD) => void;
@@ -16,5 +16,4 @@ export declare function setImageTags(request: any, pipelineId: number, artifactI
16
16
  export declare const genericCDMaterialsService: (serviceType: CDMaterialServiceEnum, cdMaterialID: number, stage: DeploymentNodeType, signal: AbortSignal, queryParams?: CDMaterialServiceQueryParams) => Promise<CDMaterialResponseType>;
17
17
  export declare function extractImage(image: string): string;
18
18
  export declare function createGitCommitUrl(url: string, revision: string): string;
19
- export declare function fetchChartTemplateVersions(): Promise<ResponseType>;
20
19
  export {};
@@ -20,7 +20,6 @@ export declare const ROUTES: {
20
20
  USER_CHECK_ROLE: string;
21
21
  IMAGE_TAGGING: string;
22
22
  CD_MATERIAL_GET: string;
23
- DEPLOYMENT_TEMPLATE_LIST: string;
24
23
  };
25
24
  export declare enum KEY_VALUE {
26
25
  KEY = "key",
@@ -10,6 +10,7 @@ export interface DeleteDialogProps {
10
10
  dataTestId?: string;
11
11
  buttonPrimaryText?: string;
12
12
  shouldStopPropagation?: boolean;
13
+ disabled?: boolean;
13
14
  }
14
15
  export interface ForceDeleteDialogType {
15
16
  onClickDelete: () => void;
@@ -48,13 +48,6 @@ export declare const getUrlWithSearchParams: (url: string, params: Record<string
48
48
  * Custom exception logger function for logging errors to sentry
49
49
  */
50
50
  export declare const logExceptionToSentry: typeof Sentry.captureException;
51
- export declare const customStyles: {
52
- control: (base: any, state: any) => any;
53
- indicatorSeparator: (base: any, state: any) => any;
54
- valueContainer: (base: any, state: any) => any;
55
- dropdownIndicator: (base: any, state: any) => any;
56
- };
57
- export declare const getFilteredChartVersions: (charts: any, selectedChartType: any) => any;
58
51
  export declare function getUnlockedJSON(json: any, jsonPathArray: any): any;
59
52
  export declare function getLockedJSON(json: any, jsonPathArray: string[]): any;
60
53
  export {};
@@ -261,6 +261,10 @@ export interface CDMaterialServiceQueryParams {
261
261
  resource?: CDMaterialResourceQuery;
262
262
  filter?: CDMaterialFilterQuery;
263
263
  }
264
+ export interface DownstreamNodesEnvironmentsType {
265
+ environmentId: number;
266
+ environmentName: string;
267
+ }
264
268
  export interface CommonNodeAttr {
265
269
  connectingCiPipelineId?: number;
266
270
  parents: string | number[] | string[];
@@ -322,6 +326,9 @@ export interface CommonNodeAttr {
322
326
  };
323
327
  appReleaseTagNames?: string[];
324
328
  tagsEditable?: boolean;
329
+ deploymentAppCreated?: boolean;
330
+ isLast?: boolean;
331
+ downstreamEnvironments?: DownstreamNodesEnvironmentsType[];
325
332
  }
326
333
  export declare enum DeploymentAppTypes {
327
334
  HELM = "helm",
@@ -563,15 +570,6 @@ export interface CiPipeline {
563
570
  isOffendingMandatoryPlugin?: boolean;
564
571
  pipelineType?: string;
565
572
  }
566
- export interface DeploymentChartVersionType {
567
- chartRefId: number;
568
- chartVersion: string;
569
- chartType: string;
570
- type: number;
571
- }
572
- export interface ChartVersionAndTypeSelectorProps {
573
- setSelectedChartRefId: React.Dispatch<React.SetStateAction<number>>;
574
- }
575
573
  export interface InformationBarProps {
576
574
  text: string;
577
575
  className?: string;
@@ -586,7 +584,7 @@ export interface CodeEditorInterface {
586
584
  onFocus?: () => void;
587
585
  children?: any;
588
586
  defaultValue?: string;
589
- mode?: 'json' | 'yaml' | 'shell' | 'dockerfile' | 'plaintext';
587
+ mode?: 'json' | 'yaml' | 'shell' | 'dockerfile';
590
588
  tabSize?: number;
591
589
  readOnly?: boolean;
592
590
  noParsing?: boolean;
@@ -627,4 +625,44 @@ export interface CodeEditorHeaderInterface {
627
625
  className?: string;
628
626
  hideDefaultSplitHeader?: boolean;
629
627
  }
628
+ export declare enum PipelineType {
629
+ CI_PIPELINE = "CI_PIPELINE",
630
+ CD_PIPELINE = "CD_PIPELINE",
631
+ WEBHOOK = "WEBHOOK",
632
+ LINKED_CD = "LINKED_CD"
633
+ }
634
+ export declare enum WorkflowNodeType {
635
+ GIT = "GIT",
636
+ CI = "CI",
637
+ WEBHOOK = "WEBHOOK",
638
+ PRE_CD = "PRECD",
639
+ CD = "CD",
640
+ POST_CD = "POSTCD"
641
+ }
642
+ export declare enum AddCDPositions {
643
+ LEFT = "left",
644
+ RIGHT = "right"
645
+ }
646
+ export interface SelectedNode {
647
+ nodeType: WorkflowNodeType;
648
+ id: string;
649
+ }
650
+ export declare enum AddPipelineType {
651
+ SEQUENTIAL = "SEQUENTIAL",
652
+ PARALLEL = "PARALLEL"
653
+ }
654
+ export interface Point {
655
+ x: number;
656
+ y: number;
657
+ }
658
+ export interface EdgeNodeType {
659
+ height: number;
660
+ width: number;
661
+ userApprovalConfig?: UserApprovalConfigType;
662
+ type?: any;
663
+ id?: number | string;
664
+ }
665
+ export interface EdgeEndNodeType extends EdgeNodeType {
666
+ userApprovalConfig?: UserApprovalConfigType;
667
+ }
630
668
  export {};
@@ -42,5 +42,5 @@ export * from './Hooks';
42
42
  export { AppStatus } from './AppStatus';
43
43
  export * from './RJSF';
44
44
  export * from './DevtronProgressing';
45
- export { default as ChartVersionAndTypeSelector } from './ChartVersionAndTypeSelector';
45
+ export * from './AddCDButton';
46
46
  export * from './CustomInput';
package/dist/index.js CHANGED
@@ -48,8 +48,7 @@ var ROUTES = {
48
48
  PROJECT_LIST_MIN: 'team/autocomplete',
49
49
  USER_CHECK_ROLE: 'user/check/roles',
50
50
  IMAGE_TAGGING: 'app/image-tagging',
51
- CD_MATERIAL_GET: 'app/cd-pipeline',
52
- DEPLOYMENT_TEMPLATE_LIST: 'app/template/list'
51
+ CD_MATERIAL_GET: 'app/cd-pipeline'
53
52
  };
54
53
  exports.KEY_VALUE = void 0;
55
54
  (function (KEY_VALUE) {
@@ -465,7 +464,33 @@ exports.FilterConditionType = void 0;
465
464
  (function (FilterConditionType) {
466
465
  FilterConditionType[FilterConditionType["PASS"] = 1] = "PASS";
467
466
  FilterConditionType[FilterConditionType["FAIL"] = 0] = "FAIL";
468
- })(exports.FilterConditionType || (exports.FilterConditionType = {}));
467
+ })(exports.FilterConditionType || (exports.FilterConditionType = {}));
468
+ exports.PipelineType = void 0;
469
+ (function (PipelineType) {
470
+ PipelineType["CI_PIPELINE"] = "CI_PIPELINE";
471
+ PipelineType["CD_PIPELINE"] = "CD_PIPELINE";
472
+ PipelineType["WEBHOOK"] = "WEBHOOK";
473
+ PipelineType["LINKED_CD"] = "LINKED_CD";
474
+ })(exports.PipelineType || (exports.PipelineType = {}));
475
+ exports.WorkflowNodeType = void 0;
476
+ (function (WorkflowNodeType) {
477
+ WorkflowNodeType["GIT"] = "GIT";
478
+ WorkflowNodeType["CI"] = "CI";
479
+ WorkflowNodeType["WEBHOOK"] = "WEBHOOK";
480
+ WorkflowNodeType["PRE_CD"] = "PRECD";
481
+ WorkflowNodeType["CD"] = "CD";
482
+ WorkflowNodeType["POST_CD"] = "POSTCD";
483
+ })(exports.WorkflowNodeType || (exports.WorkflowNodeType = {}));
484
+ exports.AddCDPositions = void 0;
485
+ (function (AddCDPositions) {
486
+ AddCDPositions["LEFT"] = "left";
487
+ AddCDPositions["RIGHT"] = "right";
488
+ })(exports.AddCDPositions || (exports.AddCDPositions = {}));
489
+ exports.AddPipelineType = void 0;
490
+ (function (AddPipelineType) {
491
+ AddPipelineType["SEQUENTIAL"] = "SEQUENTIAL";
492
+ AddPipelineType["PARALLEL"] = "PARALLEL";
493
+ })(exports.AddPipelineType || (exports.AddPipelineType = {}));
469
494
 
470
495
  var responseMessages = {
471
496
  100: 'Continue',
@@ -11736,26 +11761,12 @@ var getUrlWithSearchParams = function (url, params) {
11736
11761
  * Custom exception logger function for logging errors to sentry
11737
11762
  */
11738
11763
  var logExceptionToSentry = captureException.bind(window);
11739
- var customStyles = {
11740
- control: function (base, state) { return (__assign(__assign({}, base), { minHeight: '32px', boxShadow: 'none', border: 'none', cursor: 'pointer', background: 'transparent' })); },
11741
- indicatorSeparator: function (base, state) { return (__assign(__assign({}, base), { width: 0 })); },
11742
- valueContainer: function (base, state) { return (__assign(__assign({}, base), { padding: '0', fontSize: '13px', fontWeight: '600' })); },
11743
- dropdownIndicator: function (base, state) { return (__assign(__assign({}, base), { color: 'var(--N400)', padding: '0 8px', transition: 'all .2s ease', transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : 'rotate(0deg)' })); },
11744
- };
11745
- var getFilteredChartVersions = function (charts, selectedChartType) {
11746
- // Filter chart versions based on selected chart type
11747
- return charts
11748
- .filter(function (item) { return (item === null || item === void 0 ? void 0 : item.chartType) === selectedChartType.value; })
11749
- .map(function (item) { return ({
11750
- value: item === null || item === void 0 ? void 0 : item.chartVersion,
11751
- label: item === null || item === void 0 ? void 0 : item.chartVersion,
11752
- chartRefId: item.chartRefId,
11753
- }); });
11754
- };
11755
11764
  function removeEmptyObjectKeysAndNullValues(obj) {
11756
11765
  // It recursively removes empty object keys and array values that are null
11757
11766
  for (var key in obj) {
11758
11767
  if (Array.isArray(obj[key])) {
11768
+ if (obj[key].length === 0)
11769
+ continue;
11759
11770
  obj[key] = obj[key].filter(function (item) { return item !== null; });
11760
11771
  // Check if the array is empty
11761
11772
  if (obj[key].length === 0) {
@@ -11767,7 +11778,7 @@ function removeEmptyObjectKeysAndNullValues(obj) {
11767
11778
  delete obj[key];
11768
11779
  }
11769
11780
  }
11770
- else if (obj[key] === null || obj[key] === undefined) {
11781
+ else if (obj[key] === undefined) {
11771
11782
  delete obj[key];
11772
11783
  }
11773
11784
  }
@@ -16671,7 +16682,7 @@ var DeleteDialog = function (props) {
16671
16682
  }
16672
16683
  props.closeDelete();
16673
16684
  };
16674
- return (jsxRuntime.jsxs(ConfirmationDialog, __assign({ className: "confirmation-dialog__body--w-400" }, { children: [jsxRuntime.jsx(ConfirmationDialog.Icon, { src: warn }), jsxRuntime.jsx(ConfirmationDialog.Body, __assign({ title: props.title }, { children: jsxRuntime.jsxs("div", __assign({ className: "fs-13 cn-7 lh-1-54 w-100" }, { children: [props.description ? props.description : null, props.children] })) })), jsxRuntime.jsx(ConfirmationDialog.ButtonGroup, { children: jsxRuntime.jsxs("div", __assign({ className: "flex right" }, { children: [jsxRuntime.jsx("button", __assign({ type: "button", className: "cta cancel cta-cd-delete-modal ml-16", onClick: handleModalClose, disabled: props.apiCallInProgress, "data-testid": "dialog-cancel" }, { children: "Cancel" })), jsxRuntime.jsx("button", __assign({ type: "button", className: "cta delete cta-cd-delete-modal ml-16", onClick: handleDelete, disabled: props.apiCallInProgress, "data-testid": "dialog-delete" }, { children: props.apiCallInProgress ? (jsxRuntime.jsx(Progressing, {})) : ("".concat(props.deletePrefix || '').concat(props.buttonPrimaryText ? props.buttonPrimaryText : 'Delete').concat(props.deletePostfix || '')) }))] })) })] })));
16685
+ return (jsxRuntime.jsxs(ConfirmationDialog, __assign({ className: "confirmation-dialog__body--w-400" }, { children: [jsxRuntime.jsx(ConfirmationDialog.Icon, { src: warn }), jsxRuntime.jsx(ConfirmationDialog.Body, __assign({ title: props.title }, { children: jsxRuntime.jsxs("div", __assign({ className: "fs-13 cn-7 lh-1-54 w-100" }, { children: [props.description ? props.description : null, props.children] })) })), jsxRuntime.jsx(ConfirmationDialog.ButtonGroup, { children: jsxRuntime.jsxs("div", __assign({ className: "flex right" }, { children: [jsxRuntime.jsx("button", __assign({ type: "button", className: "cta cancel cta-cd-delete-modal ml-16", onClick: handleModalClose, disabled: props.apiCallInProgress, "data-testid": "dialog-cancel" }, { children: "Cancel" })), jsxRuntime.jsx("button", __assign({ type: "button", className: "cta delete cta-cd-delete-modal ml-16", onClick: handleDelete, disabled: props.apiCallInProgress || props.disabled, "data-testid": "dialog-delete" }, { children: props.apiCallInProgress ? (jsxRuntime.jsx(Progressing, {})) : ("".concat(props.deletePrefix || '').concat(props.buttonPrimaryText ? props.buttonPrimaryText : 'Delete').concat(props.deletePostfix || '')) }))] })) })] })));
16675
16686
  };
16676
16687
  function DeleteDialogDescription(props) {
16677
16688
  return jsxRuntime.jsx(jsxRuntime.Fragment, { children: props.children });
@@ -24484,9 +24495,6 @@ function createGitCommitUrl(url, revision) {
24484
24495
  }
24485
24496
  }
24486
24497
  return "NA";
24487
- }
24488
- function fetchChartTemplateVersions() {
24489
- return get("".concat(ROUTES.DEPLOYMENT_TEMPLATE_LIST, "?appId=-1&envId=-1"));
24490
24498
  }
24491
24499
 
24492
24500
  /*
@@ -28201,51 +28209,46 @@ function DevtronProgressing(_a) {
28201
28209
  return (jsxRuntime.jsx("div", __assign({ className: parentClasses ? parentClasses : '' }, { children: jsxRuntime.jsx(SvgIcRotateDevtron, { className: classes ? classes : '' }) })));
28202
28210
  }
28203
28211
 
28204
- // @TODO: Generalize this component to be used in CodeEditor as Chart selector toolbar
28205
- // when the Code Editor is moved to the fe-common-lib
28206
- var ChartVersionAndTypeSelector = function (_a) {
28207
- var setSelectedChartRefId = _a.setSelectedChartRefId;
28208
- var _b = __read(React.useState([]), 2), charts = _b[0], setCharts = _b[1];
28209
- var _c = __read(React.useState(null), 2), selectedChartType = _c[0], setSelectedChartType = _c[1];
28210
- var _d = __read(React.useState([]), 2), chartVersionOptions = _d[0], setChartVersionOptions = _d[1];
28211
- var _e = __read(React.useState([]), 2), chartTypeOptions = _e[0], setChartTypeOptions = _e[1];
28212
- var _f = __read(React.useState(null), 2), selectedChartVersion = _f[0], setSelectedChartVersion = _f[1];
28213
- React.useEffect(function () {
28214
- fetchChartTemplateVersions()
28215
- .then(function (res) {
28216
- var charts = (res === null || res === void 0 ? void 0 : res.result) || [];
28217
- setCharts(charts);
28218
- // Extract unique chart types from the data
28219
- var chartTypeOptions = __spreadArray([], __read(new Set(charts.map(function (item) { return item.chartType; }))), false).map(function (type) { return ({
28220
- value: type,
28221
- label: type,
28222
- }); });
28223
- setChartTypeOptions(chartTypeOptions);
28224
- var filteredVersions = getFilteredChartVersions(charts, chartTypeOptions[0]);
28225
- selectFirstChartVersion(filteredVersions);
28226
- })
28227
- .catch(function (err) {
28228
- showError(err);
28229
- });
28230
- }, []);
28231
- var selectFirstChartVersion = function (filteredVersions) {
28232
- var _a;
28233
- setChartVersionOptions(filteredVersions);
28234
- setSelectedChartVersion(filteredVersions[0]); // Select the first chart version by default
28235
- setSelectedChartRefId((_a = filteredVersions[0]) === null || _a === void 0 ? void 0 : _a.chartRefId);
28236
- };
28237
- // Function to update chart version options based on selected chart type
28238
- var handleChartTypeChange = function (selectedOption) {
28239
- setSelectedChartType(selectedOption);
28240
- var filteredVersions = getFilteredChartVersions(charts, selectedOption);
28241
- selectFirstChartVersion(filteredVersions);
28242
- };
28243
- // Function to handle the change of the selected chart version
28244
- var handleChartVersionChange = function (selectedOption) {
28245
- setSelectedChartVersion(selectedOption);
28246
- setSelectedChartRefId(selectedOption.chartRefId);
28212
+ function TooltipContent(_a) {
28213
+ var tooltipContent = _a.tooltipContent;
28214
+ if (tooltipContent) {
28215
+ return (jsxRuntime.jsxs("div", __assign({ className: "dc__white-space-pre-wrap" }, { children: [jsxRuntime.jsx("p", __assign({ className: "m-0 cn-0 fs-12 fw-6 lh-18" }, { children: "Click to add" })), tooltipContent] })));
28216
+ }
28217
+ return jsxRuntime.jsx("div", __assign({ className: "dc__white-space-pre-wrap" }, { children: "Click to add here" }));
28218
+ }
28219
+ function AddCDButton(_a) {
28220
+ var position = _a.position, addCDButtons = _a.addCDButtons, endNode = _a.endNode, startNode = _a.startNode, handleAddCD = _a.handleAddCD, tooltipContent = _a.tooltipContent;
28221
+ var referenceNode = position === exports.AddCDPositions.RIGHT ? endNode : startNode;
28222
+ var handleAddCDClick = function () {
28223
+ handleAddCD(position);
28247
28224
  };
28248
- return (jsxRuntime.jsxs("div", __assign({ className: "flex" }, { children: [jsxRuntime.jsxs("div", __assign({ className: "chart-type-options flex", "data-testid": "chart-type-options" }, { children: [jsxRuntime.jsx("span", __assign({ className: "chart-type-options-label mr-4" }, { children: "Chart Type" })), jsxRuntime.jsx(ReactSelect, { value: selectedChartType !== null && selectedChartType !== void 0 ? selectedChartType : chartTypeOptions[0], options: chartTypeOptions, onChange: handleChartTypeChange, styles: customStyles })] })), jsxRuntime.jsxs("div", __assign({ className: "chart-version-options flex", "data-testid": "chart-version-options" }, { children: [jsxRuntime.jsx("span", __assign({ className: "chart-version-options-label mr-4" }, { children: "Chart Version" })), jsxRuntime.jsx(ReactSelect, { value: selectedChartVersion !== null && selectedChartVersion !== void 0 ? selectedChartVersion : chartVersionOptions[0], options: chartVersionOptions, onChange: handleChartVersionChange, styles: customStyles })] }))] })));
28225
+ if (addCDButtons === null || addCDButtons === void 0 ? void 0 : addCDButtons.includes(position)) {
28226
+ return (jsxRuntime.jsx(Tippy, __assign({ placement: "top", content: jsxRuntime.jsx(TooltipContent, { tooltipContent: tooltipContent }), className: "default-tt", arrow: false }, { children: jsxRuntime.jsxs("svg", __assign({ x: referenceNode.x + (position === exports.AddCDPositions.RIGHT ? -20 - 5 : referenceNode.width + 5),
28227
+ // Here 10 is the height of the button / 2
28228
+ y: referenceNode.y + referenceNode.height / 2 - 10, width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", "data-testid": "add-cd-to-".concat(position), onClick: handleAddCDClick, className: "dc__outline-none-imp" }, { children: [jsxRuntime.jsx("rect", { width: "20", height: "20", rx: "10", fill: "#664BEE", className: "add-cd-edge-btn" }), jsxRuntime.jsx("path", { d: "M6.5 10H13.5M10 6.5V13.5", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] })) })));
28229
+ }
28230
+ return null;
28231
+ }
28232
+
28233
+ var getPipelineType = function (_a) {
28234
+ var isWebhookCD = _a.isWebhookCD, startNode = _a.startNode;
28235
+ if (isWebhookCD) {
28236
+ return exports.PipelineType.WEBHOOK;
28237
+ }
28238
+ if (startNode.type === exports.WorkflowNodeType.CI) {
28239
+ return exports.PipelineType.CI_PIPELINE;
28240
+ }
28241
+ return exports.PipelineType.CD_PIPELINE;
28242
+ };
28243
+ var handleAddCD = function (_a) {
28244
+ var position = _a.position, handleCDSelect = _a.handleCDSelect, startNode = _a.startNode, endNode = _a.endNode, workflowId = _a.workflowId, ciPipelineId = _a.ciPipelineId, isWebhookCD = _a.isWebhookCD, isParallelEdge = _a.isParallelEdge;
28245
+ if (!handleCDSelect) {
28246
+ return;
28247
+ }
28248
+ var pipelineType = getPipelineType({ isWebhookCD: isWebhookCD, startNode: startNode });
28249
+ var addPipelineType = isParallelEdge && position === exports.AddCDPositions.RIGHT ? exports.AddPipelineType.PARALLEL : exports.AddPipelineType.SEQUENTIAL;
28250
+ var endNodeId = !isParallelEdge && position === exports.AddCDPositions.RIGHT ? endNode.id : null;
28251
+ handleCDSelect(workflowId, ciPipelineId, pipelineType, startNode.id, isWebhookCD, endNodeId, addPipelineType);
28249
28252
  };
28250
28253
 
28251
28254
  function CustomInput(_a) {
@@ -28304,12 +28307,12 @@ function CustomInput(_a) {
28304
28307
  }, onBlur: onBlur, onFocus: onFocus, placeholder: placeholder, value: value, disabled: disabled, tabIndex: tabIndex, autoFocus: autoFocus, readOnly: readOnly, ref: ref, onKeyPress: onKeyPress, defaultValue: defaultValue, onKeyDown: onKeyDown, required: required }), getInputError(), helperText && (jsxRuntime.jsxs("div", __assign({ className: "form__text-field-info" }, { children: [jsxRuntime.jsx(SvgIcInfoFilled, { className: "form__icon form__icon--info" }), jsxRuntime.jsx("p", __assign({ className: "sentence-case" }, { children: helperText }))] })))] })));
28305
28308
  }
28306
28309
 
28310
+ exports.AddCDButton = AddCDButton;
28307
28311
  exports.AppStatus = AppStatus;
28308
28312
  exports.BreadCrumb = BreadCrumb;
28309
28313
  exports.BreadcrumbStore = Store;
28310
28314
  exports.BuildStageVariable = BuildStageVariable;
28311
28315
  exports.CDModalTab = CDModalTab;
28312
- exports.ChartVersionAndTypeSelector = ChartVersionAndTypeSelector;
28313
28316
  exports.Checkbox = Checkbox$1;
28314
28317
  exports.ClearIndicator = ClearIndicator;
28315
28318
  exports.ClipboardButton = ClipboardButton;
@@ -28382,15 +28385,12 @@ exports.VisibleModal2 = VisibleModal2;
28382
28385
  exports.closeOnEscKeyPressed = closeOnEscKeyPressed;
28383
28386
  exports.copyToClipboard = copyToClipboard;
28384
28387
  exports.createGitCommitUrl = createGitCommitUrl;
28385
- exports.customStyles = customStyles;
28386
28388
  exports.extractImage = extractImage;
28387
- exports.fetchChartTemplateVersions = fetchChartTemplateVersions;
28388
28389
  exports.genericCDMaterialsService = genericCDMaterialsService;
28389
28390
  exports.get = get;
28390
28391
  exports.getAlphabetIcon = getAlphabetIcon;
28391
28392
  exports.getCookie = getCookie;
28392
28393
  exports.getEmptyArrayOfLength = getEmptyArrayOfLength;
28393
- exports.getFilteredChartVersions = getFilteredChartVersions;
28394
28394
  exports.getInferredTypeFromValueType = getInferredTypeFromValueType;
28395
28395
  exports.getLockedJSON = getLockedJSON;
28396
28396
  exports.getLoginInfo = getLoginInfo;
@@ -28400,6 +28400,7 @@ exports.getTeamListMin = getTeamListMin;
28400
28400
  exports.getUnlockedJSON = getUnlockedJSON;
28401
28401
  exports.getUrlWithSearchParams = getUrlWithSearchParams;
28402
28402
  exports.getUserRole = getUserRole;
28403
+ exports.handleAddCD = handleAddCD;
28403
28404
  exports.handleUTCTime = handleUTCTime;
28404
28405
  exports.logExceptionToSentry = logExceptionToSentry;
28405
28406
  exports.multiSelectStyles = multiSelectStyles;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devtron-labs/devtron-fe-common-lib",
3
- "version": "0.0.48-beta-3",
3
+ "version": "0.0.48-beta-5",
4
4
  "description": "Supporting common component library",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -0,0 +1,68 @@
1
+ import React from 'react'
2
+ import Tippy from '@tippyjs/react'
3
+ import { AddCDButtonProps, TooltipContentProps } from './types'
4
+ import { AddCDPositions } from '../Types'
5
+
6
+ function TooltipContent({ tooltipContent }: TooltipContentProps) {
7
+ if (tooltipContent) {
8
+ return (
9
+ <div className="dc__white-space-pre-wrap">
10
+ <p className="m-0 cn-0 fs-12 fw-6 lh-18">Click to add</p>
11
+
12
+ {tooltipContent}
13
+ </div>
14
+ )
15
+ }
16
+
17
+ return <div className="dc__white-space-pre-wrap">Click to add here</div>
18
+ }
19
+
20
+ export default function AddCDButton({
21
+ position,
22
+ addCDButtons,
23
+ endNode,
24
+ startNode,
25
+ handleAddCD,
26
+ tooltipContent,
27
+ }: Readonly<AddCDButtonProps>) {
28
+ const referenceNode = position === AddCDPositions.RIGHT ? endNode : startNode
29
+ const handleAddCDClick = () => {
30
+ handleAddCD(position)
31
+ }
32
+
33
+ if (addCDButtons?.includes(position)) {
34
+ return (
35
+ <Tippy
36
+ placement="top"
37
+ content={<TooltipContent tooltipContent={tooltipContent} />}
38
+ className="default-tt"
39
+ arrow={false}
40
+ >
41
+ <svg
42
+ x={referenceNode.x + (position === AddCDPositions.RIGHT ? -20 - 5 : referenceNode.width + 5)}
43
+ // Here 10 is the height of the button / 2
44
+ y={referenceNode.y + referenceNode.height / 2 - 10}
45
+ width="20"
46
+ height="20"
47
+ viewBox="0 0 20 20"
48
+ fill="none"
49
+ xmlns="http://www.w3.org/2000/svg"
50
+ data-testid={`add-cd-to-${position}`}
51
+ onClick={handleAddCDClick}
52
+ className="dc__outline-none-imp"
53
+ >
54
+ <rect width="20" height="20" rx="10" fill="#664BEE" className="add-cd-edge-btn" />
55
+ <path
56
+ d="M6.5 10H13.5M10 6.5V13.5"
57
+ stroke="white"
58
+ strokeWidth="1.5"
59
+ strokeLinecap="round"
60
+ strokeLinejoin="round"
61
+ />
62
+ </svg>
63
+ </Tippy>
64
+ )
65
+ }
66
+
67
+ return null
68
+ }
@@ -0,0 +1,2 @@
1
+ export { default as AddCDButton } from './AddCDButton'
2
+ export { handleAddCD } from './utils'
@@ -0,0 +1,38 @@
1
+ import { AddCDPositions, AddPipelineType, EdgeEndNodeType, EdgeNodeType, Point } from '../Types'
2
+
3
+ export interface AddCDButtonProps {
4
+ position: AddCDPositions
5
+ addCDButtons: AddCDPositions[]
6
+ endNode: Point & EdgeEndNodeType
7
+ startNode: Point & EdgeNodeType
8
+ handleAddCD: (position: AddCDPositions) => void
9
+ tooltipContent?: string
10
+ }
11
+
12
+ export interface HandleAddCD {
13
+ position: AddCDPositions
14
+ handleCDSelect: (
15
+ workflowId: number | string,
16
+ ciPipelineId: number | string,
17
+ parentPipelineType: string,
18
+ parentPipelineId: number | string,
19
+ isWebhookCD?: boolean,
20
+ childPipelineId?: number | string,
21
+ addType?: AddPipelineType,
22
+ ) => void
23
+ startNode: EdgeNodeType
24
+ endNode: EdgeEndNodeType
25
+ workflowId: number | string
26
+ ciPipelineId: number | string
27
+ isWebhookCD: boolean
28
+ isParallelEdge: boolean
29
+ }
30
+
31
+ export interface GetPipelineType {
32
+ isWebhookCD: boolean
33
+ startNode: EdgeNodeType
34
+ }
35
+
36
+ export interface TooltipContentProps {
37
+ tooltipContent?: string
38
+ }
@@ -0,0 +1,35 @@
1
+ import { AddCDPositions, AddPipelineType, PipelineType, WorkflowNodeType } from '../Types'
2
+ import { HandleAddCD, GetPipelineType } from './types'
3
+
4
+ const getPipelineType = ({ isWebhookCD, startNode }: GetPipelineType) => {
5
+ if (isWebhookCD) {
6
+ return PipelineType.WEBHOOK
7
+ }
8
+
9
+ if (startNode.type === WorkflowNodeType.CI) {
10
+ return PipelineType.CI_PIPELINE
11
+ }
12
+
13
+ return PipelineType.CD_PIPELINE
14
+ }
15
+
16
+ export const handleAddCD = ({
17
+ position,
18
+ handleCDSelect,
19
+ startNode,
20
+ endNode,
21
+ workflowId,
22
+ ciPipelineId,
23
+ isWebhookCD,
24
+ isParallelEdge,
25
+ }: HandleAddCD) => {
26
+ if (!handleCDSelect) {
27
+ return
28
+ }
29
+ const pipelineType = getPipelineType({ isWebhookCD, startNode })
30
+ const addPipelineType =
31
+ isParallelEdge && position === AddCDPositions.RIGHT ? AddPipelineType.PARALLEL : AddPipelineType.SEQUENTIAL
32
+ const endNodeId = !isParallelEdge && position === AddCDPositions.RIGHT ? endNode.id : null
33
+
34
+ handleCDSelect(workflowId, ciPipelineId, pipelineType, startNode.id, isWebhookCD, endNodeId, addPipelineType)
35
+ }
@@ -309,7 +309,3 @@ export function createGitCommitUrl(url: string, revision: string): string {
309
309
  }
310
310
  return "NA"
311
311
  }
312
-
313
- export function fetchChartTemplateVersions() {
314
- return get(`${ROUTES.DEPLOYMENT_TEMPLATE_LIST}?appId=-1&envId=-1`)
315
- }
@@ -24,8 +24,7 @@ export const ROUTES = {
24
24
  PROJECT_LIST_MIN: 'team/autocomplete',
25
25
  USER_CHECK_ROLE: 'user/check/roles',
26
26
  IMAGE_TAGGING:'app/image-tagging',
27
- CD_MATERIAL_GET: 'app/cd-pipeline',
28
- DEPLOYMENT_TEMPLATE_LIST: 'app/template/list'
27
+ CD_MATERIAL_GET: 'app/cd-pipeline'
29
28
  }
30
29
 
31
30
  export enum KEY_VALUE {
@@ -45,7 +45,7 @@ export const DeleteDialog: React.FC<DeleteDialogProps> & { Description?: React.F
45
45
  type="button"
46
46
  className="cta delete cta-cd-delete-modal ml-16"
47
47
  onClick={handleDelete}
48
- disabled={props.apiCallInProgress}
48
+ disabled={props.apiCallInProgress || props.disabled}
49
49
  data-testid="dialog-delete"
50
50
  >
51
51
  {props.apiCallInProgress ? (
@@ -11,6 +11,7 @@ export interface DeleteDialogProps {
11
11
  dataTestId?: string
12
12
  buttonPrimaryText?: string
13
13
  shouldStopPropagation?: boolean
14
+ disabled?: boolean
14
15
  }
15
16
 
16
17
  export interface ForceDeleteDialogType {
@@ -461,48 +461,11 @@ export const getUrlWithSearchParams = (url: string, params: Record<string | numb
461
461
  */
462
462
  export const logExceptionToSentry = Sentry.captureException.bind(window)
463
463
 
464
- export const customStyles = {
465
- control: (base, state) => ({
466
- ...base,
467
- minHeight: '32px',
468
- boxShadow: 'none',
469
- border: 'none',
470
- cursor: 'pointer',
471
- background: 'transparent',
472
- }),
473
- indicatorSeparator: (base, state) => ({
474
- ...base,
475
- width: 0,
476
- }),
477
- valueContainer: (base, state) => ({
478
- ...base,
479
- padding: '0',
480
- fontSize: '13px',
481
- fontWeight: '600',
482
- }),
483
- dropdownIndicator: (base, state) => ({
484
- ...base,
485
- color: 'var(--N400)',
486
- padding: '0 8px',
487
- transition: 'all .2s ease',
488
- transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : 'rotate(0deg)',
489
- }),
490
- }
491
-
492
- export const getFilteredChartVersions = (charts, selectedChartType) => {
493
- // Filter chart versions based on selected chart type
494
- return charts
495
- .filter((item) => item?.chartType === selectedChartType.value)
496
- .map((item) => ({
497
- value: item?.chartVersion,
498
- label: item?.chartVersion,
499
- chartRefId: item.chartRefId,
500
- }))
501
- }
502
464
  function removeEmptyObjectKeysAndNullValues(obj) {
503
465
  // It recursively removes empty object keys and array values that are null
504
466
  for (let key in obj) {
505
467
  if (Array.isArray(obj[key])) {
468
+ if (obj[key].length === 0) continue
506
469
  obj[key] = obj[key].filter((item) => item !== null)
507
470
  // Check if the array is empty
508
471
  if (obj[key].length === 0) {
@@ -512,7 +475,7 @@ function removeEmptyObjectKeysAndNullValues(obj) {
512
475
  if (removeEmptyObjectKeysAndNullValues(obj[key])) {
513
476
  delete obj[key]
514
477
  }
515
- } else if (obj[key] === null || obj[key] === undefined) {
478
+ } else if (obj[key] === undefined) {
516
479
  delete obj[key]
517
480
  }
518
481
  }
@@ -293,6 +293,11 @@ export interface CDMaterialServiceQueryParams {
293
293
  filter?: CDMaterialFilterQuery
294
294
  }
295
295
 
296
+ export interface DownstreamNodesEnvironmentsType {
297
+ environmentId: number
298
+ environmentName: string
299
+ }
300
+
296
301
  export interface CommonNodeAttr {
297
302
  connectingCiPipelineId?: number
298
303
  parents: string | number[] | string[]
@@ -354,6 +359,9 @@ export interface CommonNodeAttr {
354
359
  }
355
360
  appReleaseTagNames?: string[]
356
361
  tagsEditable?: boolean
362
+ deploymentAppCreated?: boolean
363
+ isLast?: boolean
364
+ downstreamEnvironments?: DownstreamNodesEnvironmentsType[]
357
365
  }
358
366
 
359
367
  export enum DeploymentAppTypes {
@@ -623,18 +631,6 @@ export interface CiPipeline {
623
631
  isOffendingMandatoryPlugin?: boolean
624
632
  pipelineType?: string
625
633
  }
626
-
627
- export interface DeploymentChartVersionType {
628
- chartRefId: number
629
- chartVersion: string
630
- chartType: string
631
- type: number
632
- }
633
-
634
- export interface ChartVersionAndTypeSelectorProps {
635
- setSelectedChartRefId: React.Dispatch<React.SetStateAction<number>>
636
- }
637
-
638
634
  export interface InformationBarProps {
639
635
  text: string
640
636
  className?: string
@@ -650,7 +646,7 @@ export interface CodeEditorInterface {
650
646
  onFocus?: () => void
651
647
  children?: any
652
648
  defaultValue?: string
653
- mode?: 'json' | 'yaml' | 'shell' | 'dockerfile' | 'plaintext'
649
+ mode?: 'json' | 'yaml' | 'shell' | 'dockerfile'
654
650
  tabSize?: number
655
651
  readOnly?: boolean
656
652
  noParsing?: boolean
@@ -692,4 +688,52 @@ export interface CodeEditorHeaderInterface {
692
688
  children?: any;
693
689
  className?: string
694
690
  hideDefaultSplitHeader?: boolean;
695
- }
691
+ }
692
+
693
+ export enum PipelineType {
694
+ CI_PIPELINE = 'CI_PIPELINE',
695
+ CD_PIPELINE = 'CD_PIPELINE',
696
+ WEBHOOK = 'WEBHOOK',
697
+ LINKED_CD = 'LINKED_CD',
698
+ }
699
+
700
+ export enum WorkflowNodeType {
701
+ GIT = 'GIT',
702
+ CI = 'CI',
703
+ WEBHOOK = 'WEBHOOK',
704
+ PRE_CD = 'PRECD',
705
+ CD = 'CD',
706
+ POST_CD = 'POSTCD',
707
+ }
708
+
709
+ export enum AddCDPositions {
710
+ LEFT = 'left',
711
+ RIGHT = 'right',
712
+ }
713
+
714
+ export interface SelectedNode {
715
+ nodeType: WorkflowNodeType
716
+ id: string
717
+ }
718
+
719
+ export enum AddPipelineType {
720
+ SEQUENTIAL = 'SEQUENTIAL',
721
+ PARALLEL = 'PARALLEL',
722
+ }
723
+
724
+ export interface Point {
725
+ x: number
726
+ y: number
727
+ }
728
+
729
+ export interface EdgeNodeType {
730
+ height: number
731
+ width: number
732
+ userApprovalConfig?: UserApprovalConfigType
733
+ type?: any
734
+ id?: number | string
735
+ }
736
+
737
+ export interface EdgeEndNodeType extends EdgeNodeType {
738
+ userApprovalConfig?: UserApprovalConfigType
739
+ }
@@ -42,5 +42,5 @@ export * from './Hooks'
42
42
  export { AppStatus } from './AppStatus'
43
43
  export * from './RJSF'
44
44
  export * from './DevtronProgressing'
45
- export { default as ChartVersionAndTypeSelector } from './ChartVersionAndTypeSelector'
45
+ export * from './AddCDButton'
46
46
  export * from './CustomInput'
@@ -1,4 +0,0 @@
1
- /// <reference types="react" />
2
- import { ChartVersionAndTypeSelectorProps } from './Types';
3
- declare const ChartVersionAndTypeSelector: ({ setSelectedChartRefId }: ChartVersionAndTypeSelectorProps) => JSX.Element;
4
- export default ChartVersionAndTypeSelector;
@@ -1,78 +0,0 @@
1
- import React, { useEffect, useState } from 'react'
2
- import { fetchChartTemplateVersions } from './Common.service'
3
- import { ChartVersionAndTypeSelectorProps, DeploymentChartVersionType } from './Types'
4
- import ReactSelect from 'react-select'
5
- import { customStyles, getFilteredChartVersions, showError } from './Helper'
6
-
7
- // @TODO: Generalize this component to be used in CodeEditor as Chart selector toolbar
8
- // when the Code Editor is moved to the fe-common-lib
9
- const ChartVersionAndTypeSelector = ({ setSelectedChartRefId }: ChartVersionAndTypeSelectorProps) => {
10
- const [charts, setCharts] = useState<DeploymentChartVersionType[]>([])
11
- const [selectedChartType, setSelectedChartType] = useState(null)
12
- const [chartVersionOptions, setChartVersionOptions] = useState([])
13
- const [chartTypeOptions, setChartTypeOptions] = useState([])
14
- const [selectedChartVersion, setSelectedChartVersion] = useState(null)
15
-
16
- useEffect(() => {
17
- fetchChartTemplateVersions()
18
- .then((res) => {
19
- const charts = res?.result || []
20
- setCharts(charts)
21
- // Extract unique chart types from the data
22
- const chartTypeOptions = [...new Set(charts.map((item) => item.chartType))].map((type) => ({
23
- value: type,
24
- label: type,
25
- }))
26
- setChartTypeOptions(chartTypeOptions)
27
- const filteredVersions = getFilteredChartVersions(charts, chartTypeOptions[0])
28
- selectFirstChartVersion(filteredVersions)
29
- })
30
- .catch((err) => {
31
- showError(err)
32
- })
33
- }, [])
34
-
35
- const selectFirstChartVersion = (filteredVersions) => {
36
- setChartVersionOptions(filteredVersions)
37
- setSelectedChartVersion(filteredVersions[0]) // Select the first chart version by default
38
- setSelectedChartRefId(filteredVersions[0]?.chartRefId)
39
- }
40
-
41
- // Function to update chart version options based on selected chart type
42
- const handleChartTypeChange = (selectedOption) => {
43
- setSelectedChartType(selectedOption)
44
- const filteredVersions = getFilteredChartVersions(charts, selectedOption)
45
- selectFirstChartVersion(filteredVersions)
46
- }
47
-
48
- // Function to handle the change of the selected chart version
49
- const handleChartVersionChange = (selectedOption) => {
50
- setSelectedChartVersion(selectedOption)
51
- setSelectedChartRefId(selectedOption.chartRefId)
52
- }
53
-
54
- return (
55
- <div className="flex">
56
- <div className="chart-type-options flex" data-testid="chart-type-options">
57
- <span className="chart-type-options-label mr-4">Chart Type</span>
58
- <ReactSelect
59
- value={selectedChartType ?? chartTypeOptions[0]}
60
- options={chartTypeOptions}
61
- onChange={handleChartTypeChange}
62
- styles={customStyles}
63
- />
64
- </div>
65
- <div className="chart-version-options flex" data-testid="chart-version-options">
66
- <span className="chart-version-options-label mr-4">Chart Version</span>
67
- <ReactSelect
68
- value={selectedChartVersion ?? chartVersionOptions[0]}
69
- options={chartVersionOptions}
70
- onChange={handleChartVersionChange}
71
- styles={customStyles}
72
- />
73
- </div>
74
- </div>
75
- )
76
- }
77
-
78
- export default ChartVersionAndTypeSelector