@devtron-labs/devtron-fe-common-lib 0.0.7-beta-47 → 0.0.7-beta-40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Common/CustomTagSelector/ValidationRules.d.ts +1 -1
- package/dist/Common/Helper.d.ts +0 -22
- package/dist/Common/Types.d.ts +0 -1
- package/dist/Common/index.d.ts +0 -1
- package/dist/index.js +49 -231
- package/package.json +1 -1
- package/src/Common/CustomTagSelector/TagDetails.tsx +2 -2
- package/src/Common/CustomTagSelector/TagLabelSelect.tsx +5 -1
- package/src/Common/CustomTagSelector/TagLabelValueSelector.tsx +2 -2
- package/src/Common/CustomTagSelector/ValidationRules.ts +21 -17
- package/src/Common/Helper.tsx +36 -199
- package/src/Common/Types.ts +0 -1
- package/src/Common/index.ts +0 -1
- package/dist/Common/DeleteComponentModal/DeleteComponent.d.ts +0 -4
- package/dist/Common/DeleteComponentModal/types.d.ts +0 -15
- package/src/Assets/Icon/ic-info-filled.svg +0 -7
- package/src/Assets/Icon/ic-warning.svg +0 -7
- package/src/Common/DeleteComponentModal/DeleteComponent.tsx +0 -95
- package/src/Common/DeleteComponentModal/types.ts +0 -15
package/dist/Common/Helper.d.ts
CHANGED
|
@@ -17,26 +17,4 @@ export declare function not(e: any): boolean;
|
|
|
17
17
|
export declare function useEffectAfterMount(cb: any, dependencies: any): void;
|
|
18
18
|
export declare function getCookie(sKey: any): string;
|
|
19
19
|
export declare function getLoginInfo(): any;
|
|
20
|
-
export declare function useForm(stateSchema: any, validationSchema: {}, callback: any): {
|
|
21
|
-
state: any;
|
|
22
|
-
disable: boolean;
|
|
23
|
-
handleOnChange: (event: any) => void;
|
|
24
|
-
handleOnSubmit: (event: any) => void;
|
|
25
|
-
};
|
|
26
|
-
export declare function CustomInput({ name, value, error, onChange, onBlur, onFocus, label, type, disabled, autoComplete, labelClassName, placeholder, tabIndex, dataTestid, }: {
|
|
27
|
-
name: any;
|
|
28
|
-
value: any;
|
|
29
|
-
error: any;
|
|
30
|
-
onChange: any;
|
|
31
|
-
onBlur?: (e: any) => void;
|
|
32
|
-
onFocus?: (e: any) => void;
|
|
33
|
-
label: any;
|
|
34
|
-
type?: string;
|
|
35
|
-
disabled?: boolean;
|
|
36
|
-
autoComplete?: string;
|
|
37
|
-
labelClassName?: string;
|
|
38
|
-
placeholder?: string;
|
|
39
|
-
tabIndex?: number;
|
|
40
|
-
dataTestid?: string;
|
|
41
|
-
}): JSX.Element;
|
|
42
20
|
export {};
|
package/dist/Common/Types.d.ts
CHANGED
package/dist/Common/index.d.ts
CHANGED
|
@@ -29,4 +29,3 @@ export { default as GenericEmptyState } from './EmptyState/GenericEmptyState';
|
|
|
29
29
|
export { default as Toggle } from './Toggle/Toggle';
|
|
30
30
|
export { default as ScanVulnerabilitiesTable } from './Security/ScanVulnerabilitiesTable';
|
|
31
31
|
export { default as StyledRadioGroup } from './RadioGroup/RadioGroup';
|
|
32
|
-
export { default as DeleteComponent } from './DeleteComponentModal/DeleteComponent';
|
package/dist/index.js
CHANGED
|
@@ -503,15 +503,15 @@ function styleInject(css, ref) {
|
|
|
503
503
|
var css_248z$6 = ".empty-state {\n height: 100%;\n}\n.empty-state img {\n height: 40%;\n max-height: 200px;\n width: auto;\n max-width: 250px;\n}\n.empty-state svg {\n height: 40%;\n max-height: 200px;\n width: auto;\n}\n.empty-state h1,\n.empty-state h2,\n.empty-state h3,\n.empty-state h4,\n.empty-state h5,\n.empty-state h6 {\n color: var(--N900);\n}\n.empty-state .subtitle {\n font-size: 13px;\n width: 300px;\n font-weight: 400;\n text-align: center;\n line-height: 1.5;\n margin-bottom: 20px;\n}\n.empty-state .cta {\n height: 36px;\n}\n.empty-state p {\n width: 300px;\n text-align: center;\n font-size: 13px;\n color: var(--N700);\n}\n.empty-state strong {\n font-size: 16px;\n margin-bottom: 4px;\n color: var(--N900);\n font-weight: normal;\n}\n.empty-state .select-popup {\n height: min-content;\n max-height: 250px;\n overflow: auto;\n padding: 8px 0;\n}\n.empty-state .empty-state__loader {\n width: 34px;\n height: 34px;\n margin-bottom: 16px;\n}\n.empty-state .empty-state__loading-text {\n font-size: 12px;\n width: 200px;\n font-weight: normal;\n font-stretch: normal;\n font-style: normal;\n line-height: 1.5;\n letter-spacing: normal;\n text-align: center;\n color: var(--N900);\n}\n.empty-state .button__icon {\n width: 16px;\n height: 16px;\n margin-left: 8px;\n}";
|
|
504
504
|
styleInject(css_248z$6);
|
|
505
505
|
|
|
506
|
-
var _g$
|
|
507
|
-
function _extends$
|
|
506
|
+
var _g$2;
|
|
507
|
+
function _extends$a() { _extends$a = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$a.apply(this, arguments); }
|
|
508
508
|
var SvgIcProgressing = function SvgIcProgressing(props) {
|
|
509
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$
|
|
509
|
+
return /*#__PURE__*/React__namespace.createElement("svg", _extends$a({
|
|
510
510
|
xmlns: "http://www.w3.org/2000/svg",
|
|
511
511
|
viewBox: "0 0 24 24",
|
|
512
512
|
width: "1em",
|
|
513
513
|
height: "1em"
|
|
514
|
-
}, props), _g$
|
|
514
|
+
}, props), _g$2 || (_g$2 = /*#__PURE__*/React__namespace.createElement("g", {
|
|
515
515
|
fill: "none"
|
|
516
516
|
}, /*#__PURE__*/React__namespace.createElement("animateTransform", {
|
|
517
517
|
attributeName: "transform",
|
|
@@ -558,8 +558,8 @@ EmptyState.Loading = Loading;
|
|
|
558
558
|
|
|
559
559
|
function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);else for(t in e)e[t]&&(n&&(n+=" "),n+=t);return n}function clsx(){for(var e,t,f=0,n="";f<arguments.length;)(e=arguments[f++])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
|
|
560
560
|
|
|
561
|
-
function _extends$
|
|
562
|
-
_extends$
|
|
561
|
+
function _extends$9() {
|
|
562
|
+
_extends$9 = Object.assign || function (target) {
|
|
563
563
|
for (var i = 1; i < arguments.length; i++) {
|
|
564
564
|
var source = arguments[i];
|
|
565
565
|
|
|
@@ -573,7 +573,7 @@ function _extends$a() {
|
|
|
573
573
|
return target;
|
|
574
574
|
};
|
|
575
575
|
|
|
576
|
-
return _extends$
|
|
576
|
+
return _extends$9.apply(this, arguments);
|
|
577
577
|
}
|
|
578
578
|
|
|
579
579
|
function _objectWithoutPropertiesLoose$2(source, excluded) {
|
|
@@ -1299,7 +1299,7 @@ function ProgressBar(_ref) {
|
|
|
1299
1299
|
isIn = _ref.isIn,
|
|
1300
1300
|
theme = _ref.theme;
|
|
1301
1301
|
|
|
1302
|
-
var style = _extends$
|
|
1302
|
+
var style = _extends$9({}, userStyle, {
|
|
1303
1303
|
animationDuration: delay + "ms",
|
|
1304
1304
|
animationPlayState: isRunning ? 'running' : 'paused',
|
|
1305
1305
|
opacity: hide ? 0 : 1
|
|
@@ -1576,9 +1576,9 @@ var ToastContainer = function ToastContainer(props) {
|
|
|
1576
1576
|
,
|
|
1577
1577
|
id: containerId
|
|
1578
1578
|
}, getToastToRender(function (position, toastList) {
|
|
1579
|
-
var containerStyle = !toastList.length ? _extends$
|
|
1579
|
+
var containerStyle = !toastList.length ? _extends$9({}, style, {
|
|
1580
1580
|
pointerEvents: 'none'
|
|
1581
|
-
}) : _extends$
|
|
1581
|
+
}) : _extends$9({}, style);
|
|
1582
1582
|
return React.createElement("div", {
|
|
1583
1583
|
className: getClassName(position),
|
|
1584
1584
|
style: containerStyle,
|
|
@@ -1685,7 +1685,7 @@ function dispatchToast(content, options) {
|
|
|
1685
1685
|
|
|
1686
1686
|
|
|
1687
1687
|
function mergeOptions(type, options) {
|
|
1688
|
-
return _extends$
|
|
1688
|
+
return _extends$9({}, options, {
|
|
1689
1689
|
type: options && options.type || type,
|
|
1690
1690
|
toastId: getToastId(options)
|
|
1691
1691
|
});
|
|
@@ -1702,7 +1702,7 @@ function toast(content, options) {
|
|
|
1702
1702
|
}
|
|
1703
1703
|
|
|
1704
1704
|
toast.loading = function (content, options) {
|
|
1705
|
-
return dispatchToast(content, mergeOptions(TYPE.DEFAULT, _extends$
|
|
1705
|
+
return dispatchToast(content, mergeOptions(TYPE.DEFAULT, _extends$9({
|
|
1706
1706
|
isLoading: true,
|
|
1707
1707
|
autoClose: false,
|
|
1708
1708
|
closeOnClick: false,
|
|
@@ -1718,7 +1718,7 @@ function handlePromise(promise, _ref2, options) {
|
|
|
1718
1718
|
var id;
|
|
1719
1719
|
|
|
1720
1720
|
if (pending) {
|
|
1721
|
-
id = isStr(pending) ? toast.loading(pending, options) : toast.loading(pending.render, _extends$
|
|
1721
|
+
id = isStr(pending) ? toast.loading(pending, options) : toast.loading(pending.render, _extends$9({}, options, pending));
|
|
1722
1722
|
}
|
|
1723
1723
|
|
|
1724
1724
|
var resetParams = {
|
|
@@ -1737,7 +1737,7 @@ function handlePromise(promise, _ref2, options) {
|
|
|
1737
1737
|
return;
|
|
1738
1738
|
}
|
|
1739
1739
|
|
|
1740
|
-
var baseParams = _extends$
|
|
1740
|
+
var baseParams = _extends$9({
|
|
1741
1741
|
type: type
|
|
1742
1742
|
}, resetParams, options, {
|
|
1743
1743
|
data: result
|
|
@@ -1748,10 +1748,10 @@ function handlePromise(promise, _ref2, options) {
|
|
|
1748
1748
|
} : input; // if the id is set we know that it's an update
|
|
1749
1749
|
|
|
1750
1750
|
if (id) {
|
|
1751
|
-
toast.update(id, _extends$
|
|
1751
|
+
toast.update(id, _extends$9({}, baseParams, params));
|
|
1752
1752
|
} else {
|
|
1753
1753
|
// using toast.promise without loading
|
|
1754
|
-
toast(params.render, _extends$
|
|
1754
|
+
toast(params.render, _extends$9({}, baseParams, params));
|
|
1755
1755
|
}
|
|
1756
1756
|
|
|
1757
1757
|
return result;
|
|
@@ -1775,7 +1775,7 @@ toast.warning = /*#__PURE__*/createToastByType(TYPE.WARNING);
|
|
|
1775
1775
|
toast.warn = toast.warning;
|
|
1776
1776
|
|
|
1777
1777
|
toast.dark = function (content, options) {
|
|
1778
|
-
return dispatchToast(content, mergeOptions(TYPE.DEFAULT, _extends$
|
|
1778
|
+
return dispatchToast(content, mergeOptions(TYPE.DEFAULT, _extends$9({
|
|
1779
1779
|
theme: 'dark'
|
|
1780
1780
|
}, options)));
|
|
1781
1781
|
};
|
|
@@ -1832,7 +1832,7 @@ toast.update = function (toastId, options) {
|
|
|
1832
1832
|
var oldOptions = toast.props,
|
|
1833
1833
|
oldContent = toast.content;
|
|
1834
1834
|
|
|
1835
|
-
var nextOptions = _extends$
|
|
1835
|
+
var nextOptions = _extends$9({}, oldOptions, options, {
|
|
1836
1836
|
toastId: options.toastId || toastId,
|
|
1837
1837
|
updateId: generateToastId()
|
|
1838
1838
|
});
|
|
@@ -3927,28 +3927,6 @@ function captureException(exception, captureContext) {
|
|
|
3927
3927
|
return getCurrentHub().captureException(exception, { captureContext });
|
|
3928
3928
|
}
|
|
3929
3929
|
|
|
3930
|
-
var _g$2;
|
|
3931
|
-
function _extends$9() { _extends$9 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$9.apply(this, arguments); }
|
|
3932
|
-
var SvgIcWarning = function SvgIcWarning(props) {
|
|
3933
|
-
return /*#__PURE__*/React__namespace.createElement("svg", _extends$9({
|
|
3934
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3935
|
-
width: "1em",
|
|
3936
|
-
height: "1em",
|
|
3937
|
-
viewBox: "0 0 32 32"
|
|
3938
|
-
}, props), _g$2 || (_g$2 = /*#__PURE__*/React__namespace.createElement("g", {
|
|
3939
|
-
fill: "none",
|
|
3940
|
-
fillRule: "evenodd"
|
|
3941
|
-
}, /*#__PURE__*/React__namespace.createElement("path", {
|
|
3942
|
-
d: "M0 0h32v32H0z"
|
|
3943
|
-
}), /*#__PURE__*/React__namespace.createElement("path", {
|
|
3944
|
-
fill: "#FFCB5D",
|
|
3945
|
-
d: "M18.315 5.052 29.72 25.01A2.667 2.667 0 0 1 27.405 29H4.595a2.667 2.667 0 0 1-2.315-3.99L13.685 5.052a2.667 2.667 0 0 1 4.63 0z"
|
|
3946
|
-
}), /*#__PURE__*/React__namespace.createElement("path", {
|
|
3947
|
-
fill: "#FFF",
|
|
3948
|
-
d: "M16 22.667a1.333 1.333 0 1 1 0 2.666 1.333 1.333 0 0 1 0-2.666zM16 12c.736 0 1.333.597 1.333 1.333v6.334a1.333 1.333 0 1 1-2.666 0v-6.334c0-.736.597-1.333 1.333-1.333z"
|
|
3949
|
-
}))));
|
|
3950
|
-
};
|
|
3951
|
-
|
|
3952
3930
|
toast.configure({
|
|
3953
3931
|
autoClose: 3000,
|
|
3954
3932
|
hideProgressBar: true,
|
|
@@ -4087,110 +4065,6 @@ function getLoginInfo() {
|
|
|
4087
4065
|
return null;
|
|
4088
4066
|
}
|
|
4089
4067
|
}
|
|
4090
|
-
}
|
|
4091
|
-
function useForm(stateSchema, validationSchema, callback) {
|
|
4092
|
-
if (validationSchema === void 0) { validationSchema = {}; }
|
|
4093
|
-
var _a = __read(React.useState(stateSchema), 2), state = _a[0], setState = _a[1];
|
|
4094
|
-
var _b = __read(React.useState(true), 2), disable = _b[0], setDisable = _b[1];
|
|
4095
|
-
var _c = __read(React.useState(false), 2), isDirty = _c[0], setIsDirty = _c[1];
|
|
4096
|
-
// Disable button in initial render.
|
|
4097
|
-
React.useEffect(function () {
|
|
4098
|
-
setDisable(true);
|
|
4099
|
-
}, []);
|
|
4100
|
-
// For every changed in our state this will be fired
|
|
4101
|
-
// To be able to disable the button
|
|
4102
|
-
React.useEffect(function () {
|
|
4103
|
-
if (isDirty) {
|
|
4104
|
-
setDisable(validateState(state));
|
|
4105
|
-
}
|
|
4106
|
-
}, [state, isDirty]);
|
|
4107
|
-
// Used to disable submit button if there's an error in state
|
|
4108
|
-
// or the required field in state has no value.
|
|
4109
|
-
// Wrapped in useCallback to cached the function to avoid intensive memory leaked
|
|
4110
|
-
// in every re-render in component
|
|
4111
|
-
var validateState = React.useCallback(function (state) {
|
|
4112
|
-
//check errors in all fields
|
|
4113
|
-
var hasErrorInState = Object.keys(validationSchema).some(function (key) {
|
|
4114
|
-
var isInputFieldRequired = validationSchema[key].required;
|
|
4115
|
-
var stateValue = state[key].value; // state value
|
|
4116
|
-
var stateError = state[key].error; // state error
|
|
4117
|
-
return (isInputFieldRequired && !stateValue) || stateError;
|
|
4118
|
-
});
|
|
4119
|
-
return hasErrorInState;
|
|
4120
|
-
}, [state, validationSchema]);
|
|
4121
|
-
function validateField(name, value) {
|
|
4122
|
-
if (validationSchema[name].required) {
|
|
4123
|
-
if (!value) {
|
|
4124
|
-
return 'This is a required field.';
|
|
4125
|
-
}
|
|
4126
|
-
}
|
|
4127
|
-
function _validateSingleValidator(validator, value) {
|
|
4128
|
-
if (value && !validator.regex.test(value)) {
|
|
4129
|
-
return false;
|
|
4130
|
-
}
|
|
4131
|
-
return true;
|
|
4132
|
-
}
|
|
4133
|
-
// single validator
|
|
4134
|
-
var _validator = validationSchema[name].validator;
|
|
4135
|
-
if (_validator && typeof _validator === 'object') {
|
|
4136
|
-
if (!_validateSingleValidator(_validator, value)) {
|
|
4137
|
-
return _validator.error;
|
|
4138
|
-
}
|
|
4139
|
-
}
|
|
4140
|
-
// multiple validators
|
|
4141
|
-
var _validators = validationSchema[name].validators;
|
|
4142
|
-
if (_validators && typeof _validators === 'object' && Array.isArray(_validators)) {
|
|
4143
|
-
var errors_1 = [];
|
|
4144
|
-
_validators.forEach(function (_validator) {
|
|
4145
|
-
if (!_validateSingleValidator(_validator, value)) {
|
|
4146
|
-
errors_1.push(_validator.error);
|
|
4147
|
-
}
|
|
4148
|
-
});
|
|
4149
|
-
if (errors_1.length > 0) {
|
|
4150
|
-
return errors_1;
|
|
4151
|
-
}
|
|
4152
|
-
}
|
|
4153
|
-
return '';
|
|
4154
|
-
}
|
|
4155
|
-
var handleOnChange = React.useCallback(function (event) {
|
|
4156
|
-
setIsDirty(true);
|
|
4157
|
-
var _a = event.target, name = _a.name, value = _a.value;
|
|
4158
|
-
var error = validateField(name, value);
|
|
4159
|
-
setState(function (prevState) {
|
|
4160
|
-
var _a;
|
|
4161
|
-
return (__assign(__assign({}, prevState), (_a = {}, _a[name] = { value: value, error: error }, _a)));
|
|
4162
|
-
});
|
|
4163
|
-
}, [validationSchema]);
|
|
4164
|
-
var handleOnSubmit = function (event) {
|
|
4165
|
-
event.preventDefault();
|
|
4166
|
-
var newState = Object.keys(validationSchema).reduce(function (agg, curr) {
|
|
4167
|
-
agg[curr] = __assign(__assign({}, state[curr]), { error: validateField(curr, state[curr].value) });
|
|
4168
|
-
return agg;
|
|
4169
|
-
}, state);
|
|
4170
|
-
if (!validateState(newState)) {
|
|
4171
|
-
callback(state);
|
|
4172
|
-
}
|
|
4173
|
-
else {
|
|
4174
|
-
setState(__assign({}, newState));
|
|
4175
|
-
}
|
|
4176
|
-
};
|
|
4177
|
-
return { state: state, disable: disable, handleOnChange: handleOnChange, handleOnSubmit: handleOnSubmit };
|
|
4178
|
-
}
|
|
4179
|
-
function handleError(error) {
|
|
4180
|
-
if (!error) {
|
|
4181
|
-
return [];
|
|
4182
|
-
}
|
|
4183
|
-
if (!Array.isArray(error)) {
|
|
4184
|
-
return [error];
|
|
4185
|
-
}
|
|
4186
|
-
return error;
|
|
4187
|
-
}
|
|
4188
|
-
function CustomInput(_a) {
|
|
4189
|
-
var name = _a.name, value = _a.value, error = _a.error, onChange = _a.onChange, _b = _a.onBlur, onBlur = _b === void 0 ? function (e) { } : _b, _c = _a.onFocus, onFocus = _c === void 0 ? function (e) { } : _c, label = _a.label, _d = _a.type, type = _d === void 0 ? 'text' : _d, _e = _a.disabled, disabled = _e === void 0 ? false : _e; _a.autoComplete; var _g = _a.labelClassName, labelClassName = _g === void 0 ? '' : _g, _h = _a.placeholder, placeholder = _h === void 0 ? '' : _h, _j = _a.tabIndex, tabIndex = _j === void 0 ? 1 : _j, _k = _a.dataTestid, dataTestid = _k === void 0 ? '' : _k;
|
|
4190
|
-
return (jsxRuntime.jsxs("div", __assign({ className: "flex column left top" }, { children: [jsxRuntime.jsx("label", __assign({ className: "form__label ".concat(labelClassName) }, { children: label })), jsxRuntime.jsx("input", { "data-testid": dataTestid, type: type, name: name, autoComplete: "off", className: "form__input", onChange: function (e) {
|
|
4191
|
-
e.persist();
|
|
4192
|
-
onChange(e);
|
|
4193
|
-
}, onBlur: onBlur, onFocus: onFocus, placeholder: placeholder, value: value, disabled: disabled, tabIndex: tabIndex }), handleError(error).map(function (err) { return (jsxRuntime.jsxs("div", __assign({ className: "form__error" }, { children: [jsxRuntime.jsx(SvgIcWarning, { className: "form__icon form__icon--error" }), err] }))); })] })));
|
|
4194
4068
|
}
|
|
4195
4069
|
|
|
4196
4070
|
function Progressing(_a) {
|
|
@@ -8795,35 +8669,39 @@ var ValidationRules = /** @class */ (function () {
|
|
|
8795
8669
|
errorList.push('Key is required');
|
|
8796
8670
|
}
|
|
8797
8671
|
else {
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
|
|
8803
|
-
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8672
|
+
if (!key.startsWith("devtron.ai/")) {
|
|
8673
|
+
var re = new RegExp('/', 'g');
|
|
8674
|
+
var noOfSlashInKey = (_a = key.match(re)) === null || _a === void 0 ? void 0 : _a.length;
|
|
8675
|
+
if (noOfSlashInKey > 1) {
|
|
8676
|
+
errorList.push('Key: Max 1 ( / ) allowed');
|
|
8677
|
+
}
|
|
8678
|
+
else if (noOfSlashInKey === 1) {
|
|
8679
|
+
var _b = __read(key.split('/'), 2), prefix = _b[0], name_1 = _b[1];
|
|
8680
|
+
errorList.push.apply(errorList, __spreadArray([], __read(validateTagValue(name_1).map(function (error) { return "Name: ".concat(error); })), false));
|
|
8681
|
+
if (prefix.length > 253) {
|
|
8682
|
+
errorList.push('Prefix: Can be max 253 characters');
|
|
8683
|
+
}
|
|
8684
|
+
var validPrefix = PATTERNS.KUBERNETES_KEY_PREFIX.test(prefix);
|
|
8685
|
+
if (!validPrefix) {
|
|
8686
|
+
errorList.push('Prefix: Must be a DNS subdomain (a series of DNS labels separated by dots (.)');
|
|
8687
|
+
}
|
|
8808
8688
|
}
|
|
8809
|
-
|
|
8810
|
-
|
|
8811
|
-
errorList.push('Prefix: Must be a DNS subdomain (a series of DNS labels separated by dots (.)');
|
|
8689
|
+
else {
|
|
8690
|
+
errorList.push.apply(errorList, __spreadArray([], __read(validateTagValue(key).map(function (error) { return "Name: ".concat(error); })), false));
|
|
8812
8691
|
}
|
|
8813
8692
|
}
|
|
8814
|
-
else {
|
|
8815
|
-
errorList.push.apply(errorList, __spreadArray([], __read(validateTagValue(key).map(function (error) { return "Name: ".concat(error); })), false));
|
|
8816
|
-
}
|
|
8817
8693
|
}
|
|
8818
8694
|
return { isValid: errorList.length === 0, messages: errorList };
|
|
8819
8695
|
};
|
|
8820
|
-
this.propagateTagValue = function (value) {
|
|
8696
|
+
this.propagateTagValue = function (value, key) {
|
|
8821
8697
|
var errorList = [];
|
|
8822
8698
|
if (!value) {
|
|
8823
8699
|
errorList.push('Value is required');
|
|
8824
8700
|
}
|
|
8825
8701
|
else {
|
|
8826
|
-
|
|
8702
|
+
if (!key.startsWith("devtron.ai/")) {
|
|
8703
|
+
errorList.push.apply(errorList, __spreadArray([], __read(validateTagValue(value)), false));
|
|
8704
|
+
}
|
|
8827
8705
|
}
|
|
8828
8706
|
return { isValid: errorList.length === 0, messages: errorList };
|
|
8829
8707
|
};
|
|
@@ -8858,7 +8736,7 @@ var TagLabelValueSelector = function (_a) {
|
|
|
8858
8736
|
: _tagData.value !== '';
|
|
8859
8737
|
}
|
|
8860
8738
|
else if (selectedValue || isRequired || _tagData.propagate) {
|
|
8861
|
-
_tagData.isInvalidValue = !validationRules.propagateTagValue(selectedValue).isValid;
|
|
8739
|
+
_tagData.isInvalidValue = !validationRules.propagateTagValue(selectedValue, _tagData.key).isValid;
|
|
8862
8740
|
_tagData.isInvalidKey = !_tagData.key || _tagData.isInvalidKey;
|
|
8863
8741
|
}
|
|
8864
8742
|
else {
|
|
@@ -8887,7 +8765,7 @@ var TagLabelValueSelector = function (_a) {
|
|
|
8887
8765
|
}
|
|
8888
8766
|
}
|
|
8889
8767
|
else if (isRequired || selectedValue || tagData.propagate) {
|
|
8890
|
-
field = validationRules.propagateTagValue(selectedValue);
|
|
8768
|
+
field = validationRules.propagateTagValue(selectedValue, tagData.key);
|
|
8891
8769
|
}
|
|
8892
8770
|
if (!field.isValid) {
|
|
8893
8771
|
return (jsxRuntime.jsxs("div", __assign({ className: "p-4", onClick: stopPropagation, "data-testid": "tag-label-cross-stop-propagation" }, { children: [field.messages.map(function (error) { return (jsxRuntime.jsxs("div", __assign({ className: "flexbox pr-4 pl-4" }, { children: [jsxRuntime.jsx("span", { children: jsxRuntime.jsx(SvgIcCross, { className: "icon-dim-14 scr-5 mt-3 mr-4" }) }), jsxRuntime.jsx("span", { children: error })] }), error)); }), tagInputType === exports.KEY_VALUE.KEY && (jsxRuntime.jsxs("div", __assign({ className: "flexbox pr-4 pl-4" }, { children: [jsxRuntime.jsx("span", { children: jsxRuntime.jsx(SvgIcInfoOutlined, { className: "icon-dim-14 mt-3 mr-4" }) }), jsxRuntime.jsx("span", __assign({ className: "dc__italic-font-style" }, { children: "Key format: prefix/name or name" }))] })))] })));
|
|
@@ -8939,12 +8817,12 @@ var TagDetails = function (_a) {
|
|
|
8939
8817
|
_tagData.isInvalidKey =
|
|
8940
8818
|
_tagData.key || _tagData.value ? !validationRules.propagateTagKey(_tagData.key).isValid : false;
|
|
8941
8819
|
_tagData.isInvalidValue = _tagData.value
|
|
8942
|
-
? !validationRules.propagateTagValue(_tagData.value).isValid
|
|
8820
|
+
? !validationRules.propagateTagValue(_tagData.value, _tagData.key).isValid
|
|
8943
8821
|
: false;
|
|
8944
8822
|
}
|
|
8945
8823
|
setTagData(index, _tagData);
|
|
8946
8824
|
};
|
|
8947
|
-
return (jsxRuntime.jsxs("div", __assign({ className: "flexbox mb-8" }, { children: [jsxRuntime.jsx("div", __assign({ className: "dc__border h-30 pl-4 pr-4 br-4 mr-8 pointer ".concat(tagData.propagate ? 'bcn-7' : ''), onClick: propagateTagToResource, "data-testid": "propagate-tag-".concat(index) }, { children: jsxRuntime.jsx(SvgInjectTag, { className: "icon-dim-20 mt-4 ".concat(tagData.propagate ? 'scn-0' : '') }) })), jsxRuntime.jsx(TagLabelValueSelector, { selectedTagIndex: index, tagData: tagData, setTagData: setTagData, tagInputType: exports.KEY_VALUE.KEY, placeholder: "Enter key", tabIndex: tabIndex - 1, refVar: keyRef, dependentRef: valueRef, tagOptions: suggestedTagsOptions }), jsxRuntime.jsx(TagLabelValueSelector, { selectedTagIndex: index, tagData: tagData, setTagData: setTagData, tagInputType: exports.KEY_VALUE.VALUE, placeholder: "Enter value", tabIndex: tabIndex, refVar: valueRef, dependentRef: keyRef }), jsxRuntime.jsx("div", __assign({ className: "dc__border pl-4 pr-4 dc__right-radius-4 pointer flex top", onClick: deleteTag, "data-testid": "delete-tag-".concat(index) }, { children: jsxRuntime.jsx(SvgIcCross, { className: "icon-dim-20 mt-4" }) }))] })));
|
|
8825
|
+
return (jsxRuntime.jsxs("div", __assign({ className: "flexbox mb-8" }, { children: [jsxRuntime.jsx("div", __assign({ className: "dc__border h-30 pl-4 pr-4 br-4 mr-8 pointer ".concat(tagData.propagate ? 'bcn-7' : '', " ").concat(tagData.key.startsWith("devtron.ai/") ? 'cursor-not-allowed bcn-1' : ''), onClick: propagateTagToResource, "data-testid": "propagate-tag-".concat(index) }, { children: jsxRuntime.jsx(SvgInjectTag, { className: "icon-dim-20 mt-4 ".concat(tagData.propagate ? 'scn-0' : '') }) })), jsxRuntime.jsx(TagLabelValueSelector, { selectedTagIndex: index, tagData: tagData, setTagData: setTagData, tagInputType: exports.KEY_VALUE.KEY, placeholder: "Enter key", tabIndex: tabIndex - 1, refVar: keyRef, dependentRef: valueRef, tagOptions: suggestedTagsOptions }), jsxRuntime.jsx(TagLabelValueSelector, { selectedTagIndex: index, tagData: tagData, setTagData: setTagData, tagInputType: exports.KEY_VALUE.VALUE, placeholder: "Enter value", tabIndex: tabIndex, refVar: valueRef, dependentRef: keyRef }), jsxRuntime.jsx("div", __assign({ className: "dc__border pl-4 pr-4 dc__right-radius-4 pointer flex top", onClick: deleteTag, "data-testid": "delete-tag-".concat(index) }, { children: jsxRuntime.jsx(SvgIcCross, { className: "icon-dim-20 mt-4" }) }))] })));
|
|
8948
8826
|
};
|
|
8949
8827
|
|
|
8950
8828
|
var _path$1;
|
|
@@ -8966,7 +8844,11 @@ var TagLabelSelect = function (_a) {
|
|
|
8966
8844
|
var isCreateApp = _a.isCreateApp, labelTags = _a.labelTags, setLabelTags = _a.setLabelTags, _b = _a.tabIndex, tabIndex = _b === void 0 ? 0 : _b;
|
|
8967
8845
|
var setTagData = function (index, tagValue) {
|
|
8968
8846
|
var _tags = __spreadArray([], __read(labelTags), false);
|
|
8969
|
-
|
|
8847
|
+
var _tagValue = tagValue;
|
|
8848
|
+
if (_tagValue.key.startsWith("devtron.ai/")) {
|
|
8849
|
+
_tagValue.propagate = false;
|
|
8850
|
+
}
|
|
8851
|
+
_tags[index] = _tagValue;
|
|
8970
8852
|
setLabelTags(_tags);
|
|
8971
8853
|
};
|
|
8972
8854
|
var addNewTag = function () {
|
|
@@ -16704,67 +16586,6 @@ function Radio(_a) {
|
|
|
16704
16586
|
}
|
|
16705
16587
|
RadioGroup.Radio = Radio;
|
|
16706
16588
|
|
|
16707
|
-
var info = "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2220%22%20height%3D%2220%22%20viewBox%3D%220%200%2032%2032%22%3E%20%20%20%20%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%20%20%20%20%20%20%20%20%3Cpath%20d%3D%22M0%200h32v32H0z%22%2F%3E%20%20%20%20%20%20%20%20%3Cpath%20fill%3D%22%2306C%22%20d%3D%22M16%202.667C8.64%202.667%202.667%208.64%202.667%2016S8.64%2029.333%2016%2029.333%2029.333%2023.36%2029.333%2016%2023.36%202.667%2016%202.667z%22%2F%3E%20%20%20%20%20%20%20%20%3Cpath%20fill%3D%22%23FFF%22%20d%3D%22M16%2014.667c.736%200%201.333.597%201.333%201.333v5.333a1.333%201.333%200%201%201-2.666%200V16c0-.736.597-1.333%201.333-1.333zm0-5.334A1.333%201.333%200%201%201%2016%2012a1.333%201.333%200%200%201%200-2.667z%22%2F%3E%20%20%20%20%3C%2Fg%3E%3C%2Fsvg%3E";
|
|
16708
|
-
|
|
16709
|
-
function DeleteComponent(_a) {
|
|
16710
|
-
var setDeleting = _a.setDeleting, toggleConfirmation = _a.toggleConfirmation, deleteComponent = _a.deleteComponent, title = _a.title, component = _a.component, payload = _a.payload, _b = _a.confirmationDialogDescription, confirmationDialogDescription = _b === void 0 ? '' : _b, _c = _a.redirectTo, redirectTo = _c === void 0 ? false : _c, _d = _a.url, url = _d === void 0 ? '' : _d, reload = _a.reload, _e = _a.configuration, configuration = _e === void 0 ? '' : _e, closeCustomComponent = _a.closeCustomComponent;
|
|
16711
|
-
var _f = __read(React.useState(false), 2), showCannotDeleteDialogModal = _f[0], setCannotDeleteDialogModal = _f[1];
|
|
16712
|
-
var push = reactRouterDom.useHistory().push;
|
|
16713
|
-
function handleDelete() {
|
|
16714
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
16715
|
-
var serverError_1;
|
|
16716
|
-
return __generator(this, function (_a) {
|
|
16717
|
-
switch (_a.label) {
|
|
16718
|
-
case 0:
|
|
16719
|
-
setDeleting(true);
|
|
16720
|
-
_a.label = 1;
|
|
16721
|
-
case 1:
|
|
16722
|
-
_a.trys.push([1, 3, 4, 5]);
|
|
16723
|
-
return [4 /*yield*/, deleteComponent(payload)];
|
|
16724
|
-
case 2:
|
|
16725
|
-
_a.sent();
|
|
16726
|
-
toast.success('Successfully deleted');
|
|
16727
|
-
toggleConfirmation(false);
|
|
16728
|
-
if (redirectTo) {
|
|
16729
|
-
push(url);
|
|
16730
|
-
}
|
|
16731
|
-
else {
|
|
16732
|
-
reload();
|
|
16733
|
-
}
|
|
16734
|
-
if (typeof closeCustomComponent === 'function') {
|
|
16735
|
-
closeCustomComponent();
|
|
16736
|
-
}
|
|
16737
|
-
return [3 /*break*/, 5];
|
|
16738
|
-
case 3:
|
|
16739
|
-
serverError_1 = _a.sent();
|
|
16740
|
-
if (serverError_1 instanceof ServerErrors && serverError_1.code === 500) {
|
|
16741
|
-
setCannotDeleteDialogModal(true);
|
|
16742
|
-
}
|
|
16743
|
-
return [3 /*break*/, 5];
|
|
16744
|
-
case 4:
|
|
16745
|
-
setDeleting(false);
|
|
16746
|
-
return [7 /*endfinally*/];
|
|
16747
|
-
case 5: return [2 /*return*/];
|
|
16748
|
-
}
|
|
16749
|
-
});
|
|
16750
|
-
});
|
|
16751
|
-
}
|
|
16752
|
-
var handleConfirmation = function () {
|
|
16753
|
-
setCannotDeleteDialogModal(false);
|
|
16754
|
-
toggleConfirmation(false);
|
|
16755
|
-
if (typeof closeCustomComponent === 'function') {
|
|
16756
|
-
closeCustomComponent();
|
|
16757
|
-
}
|
|
16758
|
-
};
|
|
16759
|
-
var renderCannotDeleteDialogModal = function () {
|
|
16760
|
-
return (jsxRuntime.jsxs(ConfirmationDialog, __assign({ className: "confirmation-dialog__body--w-360" }, { children: [jsxRuntime.jsx(ConfirmationDialog.Icon, { src: info }), jsxRuntime.jsx(ConfirmationDialog.Body, { title: "Cannot delete ".concat(component, " '").concat(title, "'") }), jsxRuntime.jsx("p", __assign({ className: "fs-13 cn-7 " }, { children: confirmationDialogDescription })), jsxRuntime.jsx(ConfirmationDialog.ButtonGroup, { children: jsxRuntime.jsx("button", __assign({ type: "button", className: "cta", onClick: handleConfirmation }, { children: "Okay" })) })] })));
|
|
16761
|
-
};
|
|
16762
|
-
var renderDeleteDialog = function () {
|
|
16763
|
-
return (jsxRuntime.jsx(DeleteDialog, __assign({ title: "Delete ".concat(component, " '").concat(title, "'"), delete: handleDelete, closeDelete: function () { return toggleConfirmation(false); }, dataTestId: "delete-dialog" }, { children: jsxRuntime.jsx(DeleteDialog.Description, { children: jsxRuntime.jsxs("p", { children: ["Are you sure you want to delete this ", configuration ? configuration : component, "? "] }) }) })));
|
|
16764
|
-
};
|
|
16765
|
-
return (jsxRuntime.jsxs("div", { children: [!showCannotDeleteDialogModal && renderDeleteDialog(), showCannotDeleteDialogModal && renderCannotDeleteDialogModal()] }));
|
|
16766
|
-
}
|
|
16767
|
-
|
|
16768
16589
|
exports.BreadCrumb = BreadCrumb;
|
|
16769
16590
|
exports.BreadcrumbStore = Store;
|
|
16770
16591
|
exports.CDModalTab = CDModalTab;
|
|
@@ -16772,12 +16593,10 @@ exports.Checkbox = Checkbox;
|
|
|
16772
16593
|
exports.ClearIndicator = ClearIndicator;
|
|
16773
16594
|
exports.ConditionalWrap = ConditionalWrap;
|
|
16774
16595
|
exports.ConfirmationDialog = ConfirmationDialog;
|
|
16775
|
-
exports.CustomInput = CustomInput;
|
|
16776
16596
|
exports.CustomSelect = CustomSelect;
|
|
16777
16597
|
exports.DEFAULT_TAG_DATA = DEFAULT_TAG_DATA;
|
|
16778
16598
|
exports.DOCUMENTATION = DOCUMENTATION;
|
|
16779
16599
|
exports.DOCUMENTATION_HOME_PAGE = DOCUMENTATION_HOME_PAGE;
|
|
16780
|
-
exports.DeleteComponent = DeleteComponent;
|
|
16781
16600
|
exports.DeleteDialog = DeleteDialog;
|
|
16782
16601
|
exports.DetailsProgressing = DetailsProgressing;
|
|
16783
16602
|
exports.DialogForm = DialogForm;
|
|
@@ -16845,5 +16664,4 @@ exports.toastAccessDenied = toastAccessDenied;
|
|
|
16845
16664
|
exports.trash = trash;
|
|
16846
16665
|
exports.useBreadcrumb = useBreadcrumb;
|
|
16847
16666
|
exports.useEffectAfterMount = useEffectAfterMount;
|
|
16848
|
-
exports.useForm = useForm;
|
|
16849
16667
|
exports.useThrottledEffect = useThrottledEffect;
|
package/package.json
CHANGED
|
@@ -33,7 +33,7 @@ export const TagDetails = ({
|
|
|
33
33
|
_tagData.isInvalidKey =
|
|
34
34
|
_tagData.key || _tagData.value ? !validationRules.propagateTagKey(_tagData.key).isValid : false
|
|
35
35
|
_tagData.isInvalidValue = _tagData.value
|
|
36
|
-
? !validationRules.propagateTagValue(_tagData.value).isValid
|
|
36
|
+
? !validationRules.propagateTagValue(_tagData.value, _tagData.key).isValid
|
|
37
37
|
: false
|
|
38
38
|
}
|
|
39
39
|
setTagData(index, _tagData)
|
|
@@ -41,7 +41,7 @@ export const TagDetails = ({
|
|
|
41
41
|
return (
|
|
42
42
|
<div className="flexbox mb-8">
|
|
43
43
|
<div
|
|
44
|
-
className={`dc__border h-30 pl-4 pr-4 br-4 mr-8 pointer ${tagData.propagate ? 'bcn-7' : ''}`}
|
|
44
|
+
className={`dc__border h-30 pl-4 pr-4 br-4 mr-8 pointer ${tagData.propagate ? 'bcn-7' : ''} ${tagData.key.startsWith("devtron.ai/") ? 'cursor-not-allowed bcn-1' : ''}`}
|
|
45
45
|
onClick={propagateTagToResource}
|
|
46
46
|
data-testid={`propagate-tag-${index}`}
|
|
47
47
|
>
|
|
@@ -13,7 +13,11 @@ export const TagLabelSelect = ({
|
|
|
13
13
|
}: TagLabelSelectType) => {
|
|
14
14
|
const setTagData = (index, tagValue): void => {
|
|
15
15
|
const _tags = [...labelTags]
|
|
16
|
-
|
|
16
|
+
const _tagValue = tagValue
|
|
17
|
+
if(_tagValue.key.startsWith("devtron.ai/")){
|
|
18
|
+
_tagValue.propagate = false
|
|
19
|
+
}
|
|
20
|
+
_tags[index] = _tagValue
|
|
17
21
|
setLabelTags(_tags)
|
|
18
22
|
}
|
|
19
23
|
|
|
@@ -50,7 +50,7 @@ export const TagLabelValueSelector = ({
|
|
|
50
50
|
? !validationRules.propagateTagKey(selectedValue).isValid
|
|
51
51
|
: _tagData.value !== ''
|
|
52
52
|
} else if (selectedValue || isRequired || _tagData.propagate) {
|
|
53
|
-
_tagData.isInvalidValue = !validationRules.propagateTagValue(selectedValue).isValid
|
|
53
|
+
_tagData.isInvalidValue = !validationRules.propagateTagValue(selectedValue, _tagData.key).isValid
|
|
54
54
|
_tagData.isInvalidKey = !_tagData.key || _tagData.isInvalidKey
|
|
55
55
|
} else {
|
|
56
56
|
_tagData.isInvalidValue = false
|
|
@@ -80,7 +80,7 @@ export const TagLabelValueSelector = ({
|
|
|
80
80
|
field = validationRules.propagateTagKey(selectedValue)
|
|
81
81
|
}
|
|
82
82
|
} else if (isRequired || selectedValue || tagData.propagate) {
|
|
83
|
-
field = validationRules.propagateTagValue(selectedValue)
|
|
83
|
+
field = validationRules.propagateTagValue(selectedValue, tagData.key)
|
|
84
84
|
}
|
|
85
85
|
if (!field.isValid) {
|
|
86
86
|
return (
|
|
@@ -21,33 +21,37 @@ export class ValidationRules {
|
|
|
21
21
|
if (!key) {
|
|
22
22
|
errorList.push('Key is required')
|
|
23
23
|
} else {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
if(!key.startsWith("devtron.ai/")){
|
|
25
|
+
const re = new RegExp('/', 'g')
|
|
26
|
+
const noOfSlashInKey = key.match(re)?.length
|
|
27
|
+
if (noOfSlashInKey > 1) {
|
|
28
|
+
errorList.push('Key: Max 1 ( / ) allowed')
|
|
29
|
+
} else if (noOfSlashInKey === 1) {
|
|
30
|
+
const [prefix, name] = key.split('/')
|
|
31
|
+
errorList.push(...validateTagValue(name).map((error) => `Name: ${error}`))
|
|
32
|
+
if (prefix.length > 253) {
|
|
33
|
+
errorList.push('Prefix: Can be max 253 characters')
|
|
34
|
+
}
|
|
35
|
+
const validPrefix = PATTERNS.KUBERNETES_KEY_PREFIX.test(prefix)
|
|
36
|
+
if (!validPrefix) {
|
|
37
|
+
errorList.push('Prefix: Must be a DNS subdomain (a series of DNS labels separated by dots (.)')
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
errorList.push(...validateTagValue(key).map((error) => `Name: ${error}`))
|
|
33
41
|
}
|
|
34
|
-
const validPrefix = PATTERNS.KUBERNETES_KEY_PREFIX.test(prefix)
|
|
35
|
-
if (!validPrefix) {
|
|
36
|
-
errorList.push('Prefix: Must be a DNS subdomain (a series of DNS labels separated by dots (.)')
|
|
37
|
-
}
|
|
38
|
-
} else {
|
|
39
|
-
errorList.push(...validateTagValue(key).map((error) => `Name: ${error}`))
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
return { isValid: errorList.length === 0, messages: errorList }
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
propagateTagValue = (value: string): { isValid: boolean; messages: string[] } => {
|
|
47
|
+
propagateTagValue = (value: string, key: string): { isValid: boolean; messages: string[] } => {
|
|
46
48
|
const errorList = []
|
|
47
49
|
if (!value) {
|
|
48
50
|
errorList.push('Value is required')
|
|
49
51
|
} else {
|
|
50
|
-
|
|
52
|
+
if(!key.startsWith("devtron.ai/")){
|
|
53
|
+
errorList.push(...validateTagValue(value))
|
|
54
|
+
}
|
|
51
55
|
}
|
|
52
56
|
return { isValid: errorList.length === 0, messages: errorList }
|
|
53
57
|
}
|
package/src/Common/Helper.tsx
CHANGED
|
@@ -1,49 +1,48 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useEffect, useRef } from 'react'
|
|
2
2
|
import { ServerErrors } from './ServerError'
|
|
3
3
|
import { toast } from 'react-toastify'
|
|
4
4
|
import * as Sentry from '@sentry/browser'
|
|
5
5
|
import { toastAccessDenied } from './ToastBody'
|
|
6
6
|
import { ERROR_EMPTY_SCREEN, TOKEN_COOKIE_NAME } from './Constants'
|
|
7
|
-
import { ReactComponent as FormError } from '../Assets/Icon/ic-warning.svg'
|
|
8
7
|
|
|
9
8
|
toast.configure({
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
autoClose: 3000,
|
|
10
|
+
hideProgressBar: true,
|
|
11
|
+
pauseOnHover: true,
|
|
12
|
+
pauseOnFocusLoss: true,
|
|
13
|
+
closeOnClick: false,
|
|
14
|
+
newestOnTop: true,
|
|
15
|
+
toastClassName: 'devtron-toast',
|
|
16
|
+
bodyClassName: 'devtron-toast__body',
|
|
18
17
|
})
|
|
19
18
|
|
|
20
19
|
export function showError(serverError, showToastOnUnknownError = true, hideAccessError = false) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
20
|
+
if (serverError instanceof ServerErrors && Array.isArray(serverError.errors)) {
|
|
21
|
+
serverError.errors.map(({ userMessage, internalMessage }) => {
|
|
22
|
+
if (
|
|
23
|
+
serverError.code === 403 &&
|
|
24
|
+
(userMessage === ERROR_EMPTY_SCREEN.UNAUTHORIZED || userMessage === ERROR_EMPTY_SCREEN.FORBIDDEN)
|
|
25
|
+
) {
|
|
26
|
+
if (!hideAccessError) {
|
|
27
|
+
toastAccessDenied()
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
toast.error(userMessage || internalMessage)
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
} else {
|
|
34
|
+
if (serverError.code !== 403 && serverError.code !== 408) {
|
|
35
|
+
Sentry.captureException(serverError)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (showToastOnUnknownError) {
|
|
39
|
+
if (serverError.message) {
|
|
40
|
+
toast.error(serverError.message)
|
|
41
|
+
} else {
|
|
42
|
+
toast.error('Some Error Occurred')
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
interface ConditionalWrapper<T> {
|
|
@@ -168,166 +167,4 @@ export function getLoginInfo() {
|
|
|
168
167
|
return null
|
|
169
168
|
}
|
|
170
169
|
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export function useForm(stateSchema, validationSchema = {}, callback) {
|
|
174
|
-
const [state, setState] = useState(stateSchema)
|
|
175
|
-
const [disable, setDisable] = useState(true)
|
|
176
|
-
const [isDirty, setIsDirty] = useState(false)
|
|
177
|
-
|
|
178
|
-
// Disable button in initial render.
|
|
179
|
-
useEffect(() => {
|
|
180
|
-
setDisable(true)
|
|
181
|
-
}, [])
|
|
182
|
-
|
|
183
|
-
// For every changed in our state this will be fired
|
|
184
|
-
// To be able to disable the button
|
|
185
|
-
useEffect(() => {
|
|
186
|
-
if (isDirty) {
|
|
187
|
-
setDisable(validateState(state))
|
|
188
|
-
}
|
|
189
|
-
}, [state, isDirty])
|
|
190
|
-
|
|
191
|
-
// Used to disable submit button if there's an error in state
|
|
192
|
-
// or the required field in state has no value.
|
|
193
|
-
// Wrapped in useCallback to cached the function to avoid intensive memory leaked
|
|
194
|
-
// in every re-render in component
|
|
195
|
-
const validateState = useCallback(
|
|
196
|
-
(state) => {
|
|
197
|
-
//check errors in all fields
|
|
198
|
-
const hasErrorInState = Object.keys(validationSchema).some((key) => {
|
|
199
|
-
const isInputFieldRequired = validationSchema[key].required
|
|
200
|
-
const stateValue = state[key].value // state value
|
|
201
|
-
const stateError = state[key].error // state error
|
|
202
|
-
return (isInputFieldRequired && !stateValue) || stateError
|
|
203
|
-
})
|
|
204
|
-
return hasErrorInState
|
|
205
|
-
},
|
|
206
|
-
[state, validationSchema],
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
function validateField(name, value): string | string[] {
|
|
210
|
-
if (validationSchema[name].required) {
|
|
211
|
-
if (!value) {
|
|
212
|
-
return 'This is a required field.'
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
function _validateSingleValidator(validator, value) {
|
|
217
|
-
if (value && !validator.regex.test(value)) {
|
|
218
|
-
return false
|
|
219
|
-
}
|
|
220
|
-
return true
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// single validator
|
|
224
|
-
let _validator = validationSchema[name].validator
|
|
225
|
-
if (_validator && typeof _validator === 'object') {
|
|
226
|
-
if (!_validateSingleValidator(_validator, value)) {
|
|
227
|
-
return _validator.error
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// multiple validators
|
|
232
|
-
let _validators = validationSchema[name].validators
|
|
233
|
-
if (_validators && typeof _validators === 'object' && Array.isArray(_validators)) {
|
|
234
|
-
let errors = []
|
|
235
|
-
_validators.forEach((_validator) => {
|
|
236
|
-
if (!_validateSingleValidator(_validator, value)) {
|
|
237
|
-
errors.push(_validator.error)
|
|
238
|
-
}
|
|
239
|
-
})
|
|
240
|
-
if (errors.length > 0) {
|
|
241
|
-
return errors
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return ''
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const handleOnChange = useCallback(
|
|
249
|
-
(event) => {
|
|
250
|
-
setIsDirty(true)
|
|
251
|
-
|
|
252
|
-
const { name, value } = event.target
|
|
253
|
-
let error = validateField(name, value)
|
|
254
|
-
setState((prevState) => ({
|
|
255
|
-
...prevState,
|
|
256
|
-
[name]: { value, error },
|
|
257
|
-
}))
|
|
258
|
-
},
|
|
259
|
-
[validationSchema],
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
const handleOnSubmit = (event) => {
|
|
263
|
-
event.preventDefault()
|
|
264
|
-
const newState = Object.keys(validationSchema).reduce((agg, curr) => {
|
|
265
|
-
agg[curr] = { ...state[curr], error: validateField(curr, state[curr].value) }
|
|
266
|
-
return agg
|
|
267
|
-
}, state)
|
|
268
|
-
if (!validateState(newState)) {
|
|
269
|
-
callback(state)
|
|
270
|
-
} else {
|
|
271
|
-
setState({ ...newState })
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
return { state, disable, handleOnChange, handleOnSubmit }
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
function handleError(error: any): any[] {
|
|
278
|
-
if (!error) {
|
|
279
|
-
return []
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (!Array.isArray(error)) {
|
|
283
|
-
return [error]
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return error
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
export function CustomInput({
|
|
290
|
-
name,
|
|
291
|
-
value,
|
|
292
|
-
error,
|
|
293
|
-
onChange,
|
|
294
|
-
onBlur = (e) => {},
|
|
295
|
-
onFocus = (e) => {},
|
|
296
|
-
label,
|
|
297
|
-
type = 'text',
|
|
298
|
-
disabled = false,
|
|
299
|
-
autoComplete = 'off',
|
|
300
|
-
labelClassName = '',
|
|
301
|
-
placeholder = '',
|
|
302
|
-
tabIndex = 1,
|
|
303
|
-
dataTestid = '',
|
|
304
|
-
}) {
|
|
305
|
-
return (
|
|
306
|
-
<div className="flex column left top">
|
|
307
|
-
<label className={`form__label ${labelClassName}`}>{label}</label>
|
|
308
|
-
<input
|
|
309
|
-
data-testid={dataTestid}
|
|
310
|
-
type={type}
|
|
311
|
-
name={name}
|
|
312
|
-
autoComplete="off"
|
|
313
|
-
className="form__input"
|
|
314
|
-
onChange={(e) => {
|
|
315
|
-
e.persist()
|
|
316
|
-
onChange(e)
|
|
317
|
-
}}
|
|
318
|
-
onBlur={onBlur}
|
|
319
|
-
onFocus={onFocus}
|
|
320
|
-
placeholder={placeholder}
|
|
321
|
-
value={value}
|
|
322
|
-
disabled={disabled}
|
|
323
|
-
tabIndex={tabIndex}
|
|
324
|
-
/>
|
|
325
|
-
{handleError(error).map((err) => (
|
|
326
|
-
<div className="form__error">
|
|
327
|
-
<FormError className="form__icon form__icon--error" />
|
|
328
|
-
{err}
|
|
329
|
-
</div>
|
|
330
|
-
))}
|
|
331
|
-
</div>
|
|
332
|
-
)
|
|
333
|
-
}
|
|
170
|
+
}
|
package/src/Common/Types.ts
CHANGED
package/src/Common/index.ts
CHANGED
|
@@ -29,4 +29,3 @@ export { default as GenericEmptyState } from './EmptyState/GenericEmptyState'
|
|
|
29
29
|
export { default as Toggle } from './Toggle/Toggle'
|
|
30
30
|
export { default as ScanVulnerabilitiesTable } from './Security/ScanVulnerabilitiesTable'
|
|
31
31
|
export { default as StyledRadioGroup } from './RadioGroup/RadioGroup'
|
|
32
|
-
export { default as DeleteComponent } from './DeleteComponentModal/DeleteComponent'
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
import { DeleteComponentProps } from './types';
|
|
3
|
-
declare function DeleteComponent({ setDeleting, toggleConfirmation, deleteComponent, title, component, payload, confirmationDialogDescription, redirectTo, url, reload, configuration, closeCustomComponent, }: DeleteComponentProps): JSX.Element;
|
|
4
|
-
export default DeleteComponent;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface DeleteComponentProps {
|
|
2
|
-
setDeleting: (boolean: any) => void;
|
|
3
|
-
toggleConfirmation: any;
|
|
4
|
-
deleteComponent: (any: any) => Promise<any>;
|
|
5
|
-
title: string;
|
|
6
|
-
component: string;
|
|
7
|
-
payload: any;
|
|
8
|
-
confirmationDialogDescription?: string;
|
|
9
|
-
redirectTo?: boolean;
|
|
10
|
-
url?: string;
|
|
11
|
-
reload?: () => void;
|
|
12
|
-
configuration?: string;
|
|
13
|
-
dataTestid?: string;
|
|
14
|
-
closeCustomComponent?: () => void;
|
|
15
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 32 32">
|
|
2
|
-
<g fill="none" fill-rule="evenodd">
|
|
3
|
-
<path d="M0 0h32v32H0z"/>
|
|
4
|
-
<path fill="#06C" d="M16 2.667C8.64 2.667 2.667 8.64 2.667 16S8.64 29.333 16 29.333 29.333 23.36 29.333 16 23.36 2.667 16 2.667z"/>
|
|
5
|
-
<path fill="#FFF" d="M16 14.667c.736 0 1.333.597 1.333 1.333v5.333a1.333 1.333 0 1 1-2.666 0V16c0-.736.597-1.333 1.333-1.333zm0-5.334A1.333 1.333 0 1 1 16 12a1.333 1.333 0 0 1 0-2.667z"/>
|
|
6
|
-
</g>
|
|
7
|
-
</svg>
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
2
|
-
<g fill="none" fill-rule="evenodd">
|
|
3
|
-
<path d="M0 0h32v32H0z"/>
|
|
4
|
-
<path fill="#FFCB5D" d="M18.315 5.052L29.72 25.01A2.667 2.667 0 0 1 27.405 29H4.595a2.667 2.667 0 0 1-2.315-3.99L13.685 5.052a2.667 2.667 0 0 1 4.63 0z"/>
|
|
5
|
-
<path fill="#FFF" d="M16 22.667a1.333 1.333 0 1 1 0 2.666 1.333 1.333 0 0 1 0-2.666zM16 12c.736 0 1.333.597 1.333 1.333v6.334a1.333 1.333 0 1 1-2.666 0v-6.334c0-.736.597-1.333 1.333-1.333z"/>
|
|
6
|
-
</g>
|
|
7
|
-
</svg>
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
2
|
-
import { useHistory } from 'react-router-dom'
|
|
3
|
-
import { toast } from 'react-toastify'
|
|
4
|
-
import info from '../../Assets/Icon/ic-info-filled.svg'
|
|
5
|
-
import { ConfirmationDialog, DeleteDialog } from '../Dialogs'
|
|
6
|
-
import { ServerErrors } from '../ServerError'
|
|
7
|
-
import { DeleteComponentProps } from './types'
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
function DeleteComponent({
|
|
11
|
-
setDeleting,
|
|
12
|
-
toggleConfirmation,
|
|
13
|
-
deleteComponent,
|
|
14
|
-
title,
|
|
15
|
-
component,
|
|
16
|
-
payload,
|
|
17
|
-
confirmationDialogDescription = '',
|
|
18
|
-
redirectTo = false,
|
|
19
|
-
url = '',
|
|
20
|
-
reload,
|
|
21
|
-
configuration = '',
|
|
22
|
-
closeCustomComponent,
|
|
23
|
-
}: DeleteComponentProps) {
|
|
24
|
-
const [showCannotDeleteDialogModal, setCannotDeleteDialogModal] = useState(false)
|
|
25
|
-
const { push } = useHistory()
|
|
26
|
-
|
|
27
|
-
async function handleDelete() {
|
|
28
|
-
setDeleting(true)
|
|
29
|
-
try {
|
|
30
|
-
await deleteComponent(payload)
|
|
31
|
-
toast.success('Successfully deleted')
|
|
32
|
-
toggleConfirmation(false)
|
|
33
|
-
if (redirectTo) {
|
|
34
|
-
push(url)
|
|
35
|
-
} else {
|
|
36
|
-
reload()
|
|
37
|
-
}
|
|
38
|
-
if (typeof closeCustomComponent === 'function') {
|
|
39
|
-
closeCustomComponent()
|
|
40
|
-
}
|
|
41
|
-
} catch (serverError) {
|
|
42
|
-
if (serverError instanceof ServerErrors && serverError.code === 500) {
|
|
43
|
-
setCannotDeleteDialogModal(true)
|
|
44
|
-
}
|
|
45
|
-
} finally {
|
|
46
|
-
setDeleting(false)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const handleConfirmation = () => {
|
|
51
|
-
setCannotDeleteDialogModal(false)
|
|
52
|
-
toggleConfirmation(false)
|
|
53
|
-
if (typeof closeCustomComponent === 'function') {
|
|
54
|
-
closeCustomComponent()
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const renderCannotDeleteDialogModal = () => {
|
|
59
|
-
return (
|
|
60
|
-
<ConfirmationDialog className="confirmation-dialog__body--w-360">
|
|
61
|
-
<ConfirmationDialog.Icon src={info} />
|
|
62
|
-
<ConfirmationDialog.Body title={`Cannot delete ${component} '${title}'`} />
|
|
63
|
-
<p className="fs-13 cn-7 ">{confirmationDialogDescription}</p>
|
|
64
|
-
<ConfirmationDialog.ButtonGroup>
|
|
65
|
-
<button type="button" className="cta" onClick={handleConfirmation}>
|
|
66
|
-
Okay
|
|
67
|
-
</button>
|
|
68
|
-
</ConfirmationDialog.ButtonGroup>
|
|
69
|
-
</ConfirmationDialog>
|
|
70
|
-
)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const renderDeleteDialog = () => {
|
|
74
|
-
return (
|
|
75
|
-
<DeleteDialog
|
|
76
|
-
title={`Delete ${component} '${title}'`}
|
|
77
|
-
delete={handleDelete}
|
|
78
|
-
closeDelete={() => toggleConfirmation(false)}
|
|
79
|
-
dataTestId="delete-dialog"
|
|
80
|
-
>
|
|
81
|
-
<DeleteDialog.Description>
|
|
82
|
-
<p>Are you sure you want to delete this {configuration ? configuration : component}? </p>
|
|
83
|
-
</DeleteDialog.Description>
|
|
84
|
-
</DeleteDialog>
|
|
85
|
-
)
|
|
86
|
-
}
|
|
87
|
-
return (
|
|
88
|
-
<div>
|
|
89
|
-
{!showCannotDeleteDialogModal && renderDeleteDialog()}
|
|
90
|
-
{showCannotDeleteDialogModal && renderCannotDeleteDialogModal()}
|
|
91
|
-
</div>
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export default DeleteComponent
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface DeleteComponentProps {
|
|
2
|
-
setDeleting: (boolean) => void
|
|
3
|
-
toggleConfirmation: any
|
|
4
|
-
deleteComponent: (any) => Promise<any>
|
|
5
|
-
title: string
|
|
6
|
-
component: string
|
|
7
|
-
payload: any
|
|
8
|
-
confirmationDialogDescription?: string
|
|
9
|
-
redirectTo?: boolean
|
|
10
|
-
url?: string
|
|
11
|
-
reload?: () => void
|
|
12
|
-
configuration?: string
|
|
13
|
-
dataTestid?: string
|
|
14
|
-
closeCustomComponent?: () => void
|
|
15
|
-
}
|