@devtron-labs/devtron-fe-common-lib 0.0.6-beta-15 → 0.0.6-beta-17
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/TagDetails.d.ts +2 -7
- package/dist/Common/CustomTagSelector/TagLabelSelect.d.ts +2 -5
- package/dist/Common/CustomTagSelector/TagLabelValueSelector.d.ts +2 -9
- package/dist/Common/Types.d.ts +18 -0
- package/dist/index.js +26 -31
- package/package.json +2 -1
- package/src/Common/BreadCrumb/BreadCrumb.tsx +77 -57
- package/src/Common/CustomTagSelector/TagDetails.tsx +3 -8
- package/src/Common/CustomTagSelector/TagLabelSelect.tsx +2 -8
- package/src/Common/CustomTagSelector/TagLabelValueSelector.tsx +13 -25
- package/src/Common/CustomTagSelector/ValidationRules.ts +3 -3
- package/src/Common/Types.ts +31 -8
|
@@ -1,8 +1,3 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
3
|
-
export default function TagDetails({ index, tagData, setTagData, removeTag, }:
|
|
4
|
-
index: number;
|
|
5
|
-
tagData: TagType;
|
|
6
|
-
setTagData: (index: number, tagData: TagType) => void;
|
|
7
|
-
removeTag: (index: number) => void;
|
|
8
|
-
}): JSX.Element;
|
|
2
|
+
import { TagDetailType } from '../Types';
|
|
3
|
+
export default function TagDetails({ index, tagData, setTagData, removeTag, }: TagDetailType): JSX.Element;
|
|
@@ -1,6 +1,3 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
3
|
-
export declare const TagLabelSelect: ({ labelTags, setLabelTags
|
|
4
|
-
labelTags: TagType[];
|
|
5
|
-
setLabelTags: (tagList: TagType[]) => void;
|
|
6
|
-
}) => JSX.Element;
|
|
2
|
+
import { TagLabelSelectType } from '../Types';
|
|
3
|
+
export declare const TagLabelSelect: ({ labelTags, setLabelTags }: TagLabelSelectType) => JSX.Element;
|
|
@@ -1,10 +1,3 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
3
|
-
export
|
|
4
|
-
selectedTagIndex: number;
|
|
5
|
-
tagData: TagType;
|
|
6
|
-
setTagData: (index: number, tagData: TagType) => void;
|
|
7
|
-
tagOptions?: OptionType[];
|
|
8
|
-
isRequired?: boolean;
|
|
9
|
-
type?: string;
|
|
10
|
-
}): JSX.Element;
|
|
2
|
+
import { TagLabelValueSelectorType } from '../Types';
|
|
3
|
+
export declare const TagLabelValueSelector: ({ selectedTagIndex, tagData, setTagData, tagOptions, isRequired, type, }: TagLabelValueSelectorType) => JSX.Element;
|
package/dist/Common/Types.d.ts
CHANGED
|
@@ -25,3 +25,21 @@ export declare enum TippyTheme {
|
|
|
25
25
|
black = "black",
|
|
26
26
|
white = "white"
|
|
27
27
|
}
|
|
28
|
+
export interface TagLabelSelectType {
|
|
29
|
+
labelTags: TagType[];
|
|
30
|
+
setLabelTags: (tagList: TagType[]) => void;
|
|
31
|
+
}
|
|
32
|
+
export interface TagDetailType {
|
|
33
|
+
index: number;
|
|
34
|
+
tagData: TagType;
|
|
35
|
+
setTagData: (index: number, tagData: TagType) => void;
|
|
36
|
+
removeTag: (index: number) => void;
|
|
37
|
+
}
|
|
38
|
+
export interface TagLabelValueSelectorType {
|
|
39
|
+
selectedTagIndex: number;
|
|
40
|
+
tagData: TagType;
|
|
41
|
+
setTagData: (index: number, tagData: TagType) => void;
|
|
42
|
+
tagOptions?: OptionType[];
|
|
43
|
+
isRequired?: boolean;
|
|
44
|
+
type?: string;
|
|
45
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -4049,7 +4049,7 @@ function useBreadcrumbContext() {
|
|
|
4049
4049
|
|
|
4050
4050
|
React__default.createContext(null);
|
|
4051
4051
|
function useBreadcrumb(props, deps) {
|
|
4052
|
-
var sep = (props === null || props === void 0 ? void 0 : props.sep) ||
|
|
4052
|
+
var sep = (props === null || props === void 0 ? void 0 : props.sep) || '/';
|
|
4053
4053
|
deps = deps || [];
|
|
4054
4054
|
var _a = useRouteMatch(), url = _a.url, path = _a.path;
|
|
4055
4055
|
var params = useParams();
|
|
@@ -4071,12 +4071,12 @@ function useBreadcrumb(props, deps) {
|
|
|
4071
4071
|
setState(function (state) { return (__assign(__assign({}, state), { alias: tempAlias })); });
|
|
4072
4072
|
}
|
|
4073
4073
|
var levels = useMemo(function () {
|
|
4074
|
-
var paths = path.split(
|
|
4075
|
-
var urls = url.split(
|
|
4074
|
+
var paths = path.split('/').filter(Boolean);
|
|
4075
|
+
var urls = url.split('/').filter(Boolean);
|
|
4076
4076
|
return paths.map(function (path, idx) {
|
|
4077
4077
|
var crumb = { to: urls[idx], name: path };
|
|
4078
|
-
if (path.startsWith(
|
|
4079
|
-
crumb.className =
|
|
4078
|
+
if (path.startsWith(':') && params[path.replace(':', '')]) {
|
|
4079
|
+
crumb.className = 'param';
|
|
4080
4080
|
}
|
|
4081
4081
|
return crumb;
|
|
4082
4082
|
});
|
|
@@ -4091,22 +4091,22 @@ function useBreadcrumb(props, deps) {
|
|
|
4091
4091
|
? "".concat(prefix).concat(to)
|
|
4092
4092
|
: null,
|
|
4093
4093
|
name: typeof state.alias[name] === 'object'
|
|
4094
|
-
? !!((_d = state.alias[name]) === null || _d === void 0 ? void 0 : _d.component)
|
|
4094
|
+
? !!((_d = state.alias[name]) === null || _d === void 0 ? void 0 : _d.component)
|
|
4095
|
+
? state.alias[name].component
|
|
4096
|
+
: null
|
|
4095
4097
|
: state.alias[name] || name,
|
|
4096
4098
|
className: curr.className || '',
|
|
4097
4099
|
});
|
|
4098
4100
|
return { res: res, prefix: "".concat(prefix).concat(curr.to).concat(sep) };
|
|
4099
|
-
}, { res: [], prefix:
|
|
4101
|
+
}, { res: [], prefix: '/' });
|
|
4100
4102
|
}, [levels, state]).res;
|
|
4101
4103
|
return { breadcrumbs: breadcrumbs, setCrumb: setCrumb, resetCrumb: resetCrumb };
|
|
4102
4104
|
}
|
|
4103
4105
|
var BreadCrumb = function (_a) {
|
|
4104
|
-
var breadcrumbs = _a.breadcrumbs, _b = _a.sep, sep = _b === void 0 ?
|
|
4106
|
+
var breadcrumbs = _a.breadcrumbs, _b = _a.sep, sep = _b === void 0 ? '/' : _b, _c = _a.className, className = _c === void 0 ? 'dc__devtron-breadcrumb__item' : _c;
|
|
4105
4107
|
var url = useRouteMatch().url;
|
|
4106
4108
|
var filteredCrumbs = breadcrumbs.filter(function (crumb) { return !!crumb.name; });
|
|
4107
|
-
return jsx(React__default.Fragment, { children: filteredCrumbs.map(function (breadcrumb, idx) {
|
|
4108
|
-
return jsxs(React__default.Fragment, { children: [jsx(ConditionalWrap, __assign({ condition: !!breadcrumb.to, wrap: function (children) { return jsx(Link, __assign({ className: "".concat(url === breadcrumb.to ? 'active' : '', " ").concat(className, " ").concat(breadcrumb.className || ""), to: breadcrumb.to }, { children: children })); } }, { children: breadcrumb.name })), idx + 1 !== filteredCrumbs.length && breadcrumb.name && jsx("span", __assign({ className: "".concat(className, "__separator cn-5") }, { children: sep }))] }, idx);
|
|
4109
|
-
}) });
|
|
4109
|
+
return (jsx(React__default.Fragment, { children: filteredCrumbs.map(function (breadcrumb, idx) { return (jsxs(React__default.Fragment, { children: [jsx(ConditionalWrap, __assign({ condition: !!breadcrumb.to, wrap: function (children) { return (jsx(Link, __assign({ className: "".concat(url === breadcrumb.to ? 'active' : '', " ").concat(className, " ").concat(breadcrumb.className || ''), to: breadcrumb.to }, { children: children }))); } }, { children: breadcrumb.name })), idx + 1 !== filteredCrumbs.length && breadcrumb.name && (jsx("span", __assign({ className: "".concat(className, "__separator cn-5") }, { children: sep })))] }, idx)); }) }));
|
|
4110
4110
|
};
|
|
4111
4111
|
|
|
4112
4112
|
var RadioGroupContext = createContext({ name: '', value: '', disabled: false, onChange: function (event) { } });
|
|
@@ -8423,19 +8423,18 @@ var SvgIcInfoOutlined = function SvgIcInfoOutlined(props) {
|
|
|
8423
8423
|
})));
|
|
8424
8424
|
};
|
|
8425
8425
|
|
|
8426
|
-
function
|
|
8426
|
+
var TagLabelValueSelector = function (_a) {
|
|
8427
8427
|
var selectedTagIndex = _a.selectedTagIndex, tagData = _a.tagData, setTagData = _a.setTagData, tagOptions = _a.tagOptions, isRequired = _a.isRequired, type = _a.type;
|
|
8428
8428
|
var _b = __read(useState(''), 2), selectedValue = _b[0], setSelectedValue = _b[1];
|
|
8429
8429
|
var _c = __read(useState(false), 2), isPopupOpen = _c[0], togglePopup = _c[1];
|
|
8430
8430
|
var validationRules = new ValidationRules();
|
|
8431
8431
|
useEffect(function () {
|
|
8432
|
-
|
|
8433
|
-
setSelectedValue(_tagData[type]);
|
|
8432
|
+
setSelectedValue((tagData === null || tagData === void 0 ? void 0 : tagData[type]) || '');
|
|
8434
8433
|
}, [selectedTagIndex, tagData, type]);
|
|
8435
8434
|
var handleOnBlur = function (e) {
|
|
8436
8435
|
if (!e.relatedTarget ||
|
|
8437
8436
|
!e.relatedTarget.classList.value ||
|
|
8438
|
-
e.relatedTarget.classList.value.
|
|
8437
|
+
!e.relatedTarget.classList.value.includes("tag-".concat(selectedTagIndex, "-class"))) {
|
|
8439
8438
|
var _tagData = __assign({}, tagData);
|
|
8440
8439
|
_tagData[type] = selectedValue;
|
|
8441
8440
|
if (type === 'key') {
|
|
@@ -8443,15 +8442,13 @@ function TagLabelValueSelector(_a) {
|
|
|
8443
8442
|
? !validationRules.propagateTagKey(selectedValue).isValid
|
|
8444
8443
|
: _tagData.value !== '';
|
|
8445
8444
|
}
|
|
8445
|
+
else if (selectedValue) {
|
|
8446
|
+
_tagData.isInvalidValue = !validationRules.propagateTagValue(selectedValue).isValid;
|
|
8447
|
+
_tagData.isInvalidKey = !_tagData.key || _tagData.isInvalidKey;
|
|
8448
|
+
}
|
|
8446
8449
|
else {
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
_tagData.isInvalidKey = !_tagData.key || _tagData.isInvalidKey;
|
|
8450
|
-
}
|
|
8451
|
-
else {
|
|
8452
|
-
_tagData.isInvalidValue = false;
|
|
8453
|
-
_tagData.isInvalidKey = !_tagData.key ? false : _tagData.isInvalidKey;
|
|
8454
|
-
}
|
|
8450
|
+
_tagData.isInvalidValue = false;
|
|
8451
|
+
_tagData.isInvalidKey = !_tagData.key ? false : _tagData.isInvalidKey;
|
|
8455
8452
|
}
|
|
8456
8453
|
setTagData(selectedTagIndex, _tagData);
|
|
8457
8454
|
}
|
|
@@ -8466,14 +8463,12 @@ function TagLabelValueSelector(_a) {
|
|
|
8466
8463
|
};
|
|
8467
8464
|
var renderValidationsSuggestions = function () {
|
|
8468
8465
|
var field = { isValid: true, messages: [] };
|
|
8469
|
-
if (type === '
|
|
8470
|
-
if (isRequired || selectedValue) {
|
|
8471
|
-
field = validationRules.propagateTagValue(selectedValue);
|
|
8472
|
-
}
|
|
8473
|
-
}
|
|
8474
|
-
else {
|
|
8466
|
+
if (type === 'key') {
|
|
8475
8467
|
field = validationRules.propagateTagKey(selectedValue);
|
|
8476
8468
|
}
|
|
8469
|
+
else if (isRequired || selectedValue) {
|
|
8470
|
+
field = validationRules.propagateTagValue(selectedValue);
|
|
8471
|
+
}
|
|
8477
8472
|
if (!field.isValid) {
|
|
8478
8473
|
return (jsxs("div", __assign({ className: "p-4" }, { children: [field.messages.map(function (error) { return (jsxs("div", __assign({ className: "flexbox p-4" }, { children: [jsx("span", { children: jsx(SvgIcClose, { className: "icon-dim-14 scr-5 mt-3 mr-4" }) }), jsx("span", { children: error })] }), error)); }), type === 'key' && (jsxs("div", __assign({ className: "flexbox p-4" }, { children: [jsx("span", { children: jsx(SvgIcInfoOutlined, { className: "icon-dim-14 mt-3 mr-4" }) }), jsx("span", __assign({ className: "dc__italic-font-style" }, { children: "Key format: prefix/name or name" }))] })))] })));
|
|
8479
8474
|
}
|
|
@@ -8493,7 +8488,7 @@ function TagLabelValueSelector(_a) {
|
|
|
8493
8488
|
return (jsxs(PopupMenu, __assign({ onToggleCallback: function (isOpen) { return togglePopup(isOpen); }, autoClose: true }, { children: [jsx(PopupMenu.Button, __assign({ rootClassName: "".concat(type === 'key'
|
|
8494
8489
|
? "dc__no-right-radius"
|
|
8495
8490
|
: "dc__no-border-radius dc__no-right-border dc__no-left-border", " ").concat(tagData[type === 'key' ? 'isInvalidKey' : 'isInvalidValue'] ? 'er-5 bw-1' : '') }, { children: jsx("input", { type: "text", className: "form__input pt-4-imp pb-4-imp dc__no-border", value: selectedValue, onChange: handleInputChange, onBlur: handleOnBlur }) })), jsx(PopupMenu.Body, __assign({ rootClassName: "tag-".concat(selectedTagIndex, "-class"), autoWidth: true }, { children: isPopupOpen && renderSuggestions() }))] })));
|
|
8496
|
-
}
|
|
8491
|
+
};
|
|
8497
8492
|
|
|
8498
8493
|
function TagDetails(_a) {
|
|
8499
8494
|
var index = _a.index, tagData = _a.tagData, setTagData = _a.setTagData, removeTag = _a.removeTag;
|
|
@@ -8615,4 +8610,4 @@ function ForceDeleteDialog(_a) {
|
|
|
8615
8610
|
return (jsx("div", { children: jsx(DeleteDialog, __assign({ title: forceDeleteDialogTitle, delete: onClickDelete, closeDelete: closeDeleteModal, deletePrefix: "Force " }, { children: jsxs(DeleteDialog.Description, { children: [jsxs("p", __assign({ className: "mt-12 mb-12 p-8 dc__break-word dc__window-bg" }, { children: ["Error: ", forceDeleteDialogMessage] })), jsx("p", { children: "Do you want to force delete?" })] }) })) }));
|
|
8616
8611
|
}
|
|
8617
8612
|
|
|
8618
|
-
export { BreadCrumb, Store as BreadcrumbStore, ConditionalWrap, ConfirmationDialog, DeleteDialog, DetailsProgressing, DialogForm, DialogFormSubmit, Drawer, ErrorScreenManager, ErrorScreenNotAuthorized, ForceDeleteDialog, Host, Modal, OpaqueModal, PATTERNS, PopupMenu, Progressing, RadioGroup, RadioGroupItem, RequestTimeout, ServerError, ServerErrors, TagLabelSelect, TippyCustomized, TippyTheme, ToastBody, ToastBody3, ToastBodyWithButton, VisibleModal, VisibleModal2, get, post, put, showError, toastAccessDenied, trash, useBreadcrumb };
|
|
8613
|
+
export { BreadCrumb, Store as BreadcrumbStore, ConditionalWrap, ConfirmationDialog, DeleteDialog, DetailsProgressing, DialogForm, DialogFormSubmit, Drawer, ErrorScreenManager, ErrorScreenNotAuthorized, ForceDeleteDialog, Host, Modal, OpaqueModal, PATTERNS, PopupMenu, Progressing, RadioGroup, RadioGroupItem, RequestTimeout, ServerError, ServerErrors, TagLabelSelect, TagLabelValueSelector, TippyCustomized, TippyTheme, ToastBody, ToastBody3, ToastBodyWithButton, VisibleModal, VisibleModal2, get, post, put, showError, toastAccessDenied, trash, useBreadcrumb };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devtron-labs/devtron-fe-common-lib",
|
|
3
|
-
"version": "0.0.6-beta-
|
|
3
|
+
"version": "0.0.6-beta-17",
|
|
4
4
|
"description": "Supporting common component library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"react": "^17.0.2",
|
|
42
42
|
"react-dom": "^17.0.2",
|
|
43
|
+
"react-router": "^5.3.0",
|
|
43
44
|
"react-router-dom": "^5.3.0"
|
|
44
45
|
},
|
|
45
46
|
"dependencies": {
|
|
@@ -1,36 +1,35 @@
|
|
|
1
1
|
import React, { useMemo, useEffect } from 'react'
|
|
2
|
-
import { Link, useRouteMatch, useParams } from 'react-router-dom'
|
|
2
|
+
import { Link, useRouteMatch, useParams } from 'react-router-dom'
|
|
3
3
|
import { useBreadcrumbContext } from './BreadcrumbStore'
|
|
4
|
-
import { ConditionalWrap } from '../Helper'
|
|
4
|
+
import { ConditionalWrap } from '../Helper'
|
|
5
5
|
export const BreadcrumbContext = React.createContext(null)
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
interface Breadcrumb {
|
|
9
|
-
to: string
|
|
10
|
-
name: string
|
|
11
|
-
className?: string
|
|
8
|
+
to: string
|
|
9
|
+
name: string
|
|
10
|
+
className?: string
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
interface UseBreadcrumbState {
|
|
15
|
-
breadcrumbs: Breadcrumb[]
|
|
16
|
-
setCrumb: (props: { [key: string]: any
|
|
17
|
-
resetCrumb: (props: string[]) => void
|
|
14
|
+
breadcrumbs: Breadcrumb[]
|
|
15
|
+
setCrumb: (props: { [key: string]: any }) => void
|
|
16
|
+
resetCrumb: (props: string[]) => void
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
interface AdvancedAlias {
|
|
21
|
-
component: any
|
|
22
|
-
linked: boolean
|
|
20
|
+
component: any
|
|
21
|
+
linked: boolean
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
interface UseBreadcrumbProps {
|
|
26
|
-
sep?: string
|
|
27
|
-
alias?: { [key: string]: AdvancedAlias | any
|
|
25
|
+
sep?: string
|
|
26
|
+
alias?: { [key: string]: AdvancedAlias | any }
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
type UseBreadcrumbOptionalProps = UseBreadcrumbProps | null
|
|
31
30
|
|
|
32
31
|
export function useBreadcrumb(props?: UseBreadcrumbOptionalProps, deps?: any[]): UseBreadcrumbState {
|
|
33
|
-
let sep = props?.sep ||
|
|
32
|
+
let sep = props?.sep || '/'
|
|
34
33
|
deps = deps || []
|
|
35
34
|
const { url, path } = useRouteMatch()
|
|
36
35
|
const params = useParams()
|
|
@@ -38,12 +37,12 @@ export function useBreadcrumb(props?: UseBreadcrumbOptionalProps, deps?: any[]):
|
|
|
38
37
|
|
|
39
38
|
useEffect(() => {
|
|
40
39
|
if (!props || !props.alias) return
|
|
41
|
-
setState(state => ({ ...state, alias: { ...state.alias, ...props.alias } }))
|
|
40
|
+
setState((state) => ({ ...state, alias: { ...state.alias, ...props.alias } }))
|
|
42
41
|
return () => resetCrumb(Object.keys(props.alias))
|
|
43
42
|
}, deps)
|
|
44
43
|
|
|
45
44
|
function setCrumb(props) {
|
|
46
|
-
setState(state => ({ ...state, alias: { ...state.alias, ...props } }))
|
|
45
|
+
setState((state) => ({ ...state, alias: { ...state.alias, ...props } }))
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
function resetCrumb(props: string[]) {
|
|
@@ -51,36 +50,42 @@ export function useBreadcrumb(props?: UseBreadcrumbOptionalProps, deps?: any[]):
|
|
|
51
50
|
delete agg[curr]
|
|
52
51
|
return agg
|
|
53
52
|
}, state.alias)
|
|
54
|
-
setState(state => ({ ...state, alias: tempAlias }))
|
|
53
|
+
setState((state) => ({ ...state, alias: tempAlias }))
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
let levels: Breadcrumb[] = useMemo(() => {
|
|
58
|
-
const paths = path.split(
|
|
59
|
-
const urls = url.split(
|
|
57
|
+
const paths = path.split('/').filter(Boolean)
|
|
58
|
+
const urls = url.split('/').filter(Boolean)
|
|
60
59
|
return paths.map((path, idx) => {
|
|
61
60
|
const crumb: Breadcrumb = { to: urls[idx], name: path }
|
|
62
|
-
if (path.startsWith(
|
|
63
|
-
crumb.className =
|
|
61
|
+
if (path.startsWith(':') && params[path.replace(':', '')]) {
|
|
62
|
+
crumb.className = 'param'
|
|
64
63
|
}
|
|
65
64
|
return crumb
|
|
66
65
|
})
|
|
67
66
|
}, [path, url])
|
|
68
67
|
const { res: breadcrumbs } = useMemo(() => {
|
|
69
|
-
return levels.reduce(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
68
|
+
return levels.reduce(
|
|
69
|
+
(agg, curr, idx) => {
|
|
70
|
+
const { res, prefix } = agg
|
|
71
|
+
const { to, name } = curr
|
|
72
|
+
res.push({
|
|
73
|
+
to:
|
|
74
|
+
!state.alias[name]?.component || (state.alias[name]?.component && state.alias[name]?.linked)
|
|
75
|
+
? `${prefix}${to}`
|
|
76
|
+
: null,
|
|
77
|
+
name:
|
|
78
|
+
typeof state.alias[name] === 'object'
|
|
79
|
+
? !!state.alias[name]?.component
|
|
80
|
+
? state.alias[name].component
|
|
81
|
+
: null
|
|
82
|
+
: state.alias[name] || name,
|
|
83
|
+
className: curr.className || '',
|
|
84
|
+
})
|
|
85
|
+
return { res, prefix: `${prefix}${curr.to}${sep}` }
|
|
86
|
+
},
|
|
87
|
+
{ res: [], prefix: '/' },
|
|
88
|
+
)
|
|
84
89
|
}, [levels, state])
|
|
85
90
|
|
|
86
91
|
return { breadcrumbs, setCrumb, resetCrumb }
|
|
@@ -88,27 +93,42 @@ export function useBreadcrumb(props?: UseBreadcrumbOptionalProps, deps?: any[]):
|
|
|
88
93
|
|
|
89
94
|
interface Breadcrumbs {
|
|
90
95
|
breadcrumbs: Breadcrumb[]
|
|
91
|
-
sep?: string
|
|
92
|
-
className?: string
|
|
93
|
-
}
|
|
96
|
+
sep?: string
|
|
97
|
+
className?: string
|
|
98
|
+
}
|
|
94
99
|
|
|
95
|
-
export const BreadCrumb: React.FC<Breadcrumbs> = ({
|
|
100
|
+
export const BreadCrumb: React.FC<Breadcrumbs> = ({
|
|
101
|
+
breadcrumbs,
|
|
102
|
+
sep = '/',
|
|
103
|
+
className = 'dc__devtron-breadcrumb__item',
|
|
104
|
+
}) => {
|
|
96
105
|
const { url } = useRouteMatch()
|
|
97
|
-
const filteredCrumbs = breadcrumbs.filter(crumb => !!crumb.name)
|
|
98
|
-
return
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
{children
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
const filteredCrumbs = breadcrumbs.filter((crumb) => !!crumb.name)
|
|
107
|
+
return (
|
|
108
|
+
<React.Fragment>
|
|
109
|
+
{filteredCrumbs.map((breadcrumb, idx) => (
|
|
110
|
+
<React.Fragment key={idx}>
|
|
111
|
+
<ConditionalWrap
|
|
112
|
+
condition={!!breadcrumb.to}
|
|
113
|
+
wrap={(children) => (
|
|
114
|
+
<Link
|
|
115
|
+
className={`${url === breadcrumb.to ? 'active' : ''} ${className} ${
|
|
116
|
+
breadcrumb.className || ''
|
|
117
|
+
}`}
|
|
118
|
+
to={breadcrumb.to}
|
|
119
|
+
>
|
|
120
|
+
{children}
|
|
121
|
+
</Link>
|
|
122
|
+
)}
|
|
123
|
+
>
|
|
124
|
+
{breadcrumb.name}
|
|
125
|
+
</ConditionalWrap>
|
|
109
126
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
127
|
+
{idx + 1 !== filteredCrumbs.length && breadcrumb.name && (
|
|
128
|
+
<span className={`${className}__separator cn-5`}>{sep}</span>
|
|
129
|
+
)}
|
|
130
|
+
</React.Fragment>
|
|
131
|
+
))}
|
|
132
|
+
</React.Fragment>
|
|
133
|
+
)
|
|
134
|
+
}
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { ReactComponent as DeleteCross } from '../../Assets/Icon/ic-close.svg'
|
|
3
3
|
import { ReactComponent as InjectTag } from '../../Assets/Icon/inject-tag.svg'
|
|
4
|
-
import {
|
|
5
|
-
import TagLabelValueSelector from './TagLabelValueSelector'
|
|
4
|
+
import { TagDetailType } from '../Types'
|
|
5
|
+
import { TagLabelValueSelector } from './TagLabelValueSelector'
|
|
6
6
|
|
|
7
7
|
export default function TagDetails({
|
|
8
8
|
index,
|
|
9
9
|
tagData,
|
|
10
10
|
setTagData,
|
|
11
11
|
removeTag,
|
|
12
|
-
}: {
|
|
13
|
-
index: number
|
|
14
|
-
tagData: TagType
|
|
15
|
-
setTagData: (index: number, tagData: TagType) => void
|
|
16
|
-
removeTag: (index: number) => void
|
|
17
|
-
}) {
|
|
12
|
+
}: TagDetailType) {
|
|
18
13
|
const deleteTag = (): void => {
|
|
19
14
|
removeTag(index)
|
|
20
15
|
}
|
|
@@ -2,15 +2,9 @@ import React from 'react'
|
|
|
2
2
|
import PropagateTagInfo from './PropagateTagInfo'
|
|
3
3
|
import { ReactComponent as Add } from '../../Assets/Icon/ic-add.svg'
|
|
4
4
|
import TagDetails from './TagDetails'
|
|
5
|
-
import {
|
|
5
|
+
import { TagLabelSelectType } from '../Types'
|
|
6
6
|
|
|
7
|
-
export const TagLabelSelect = ({
|
|
8
|
-
labelTags,
|
|
9
|
-
setLabelTags,
|
|
10
|
-
}: {
|
|
11
|
-
labelTags: TagType[]
|
|
12
|
-
setLabelTags: (tagList: TagType[]) => void
|
|
13
|
-
}) => {
|
|
7
|
+
export const TagLabelSelect = ({ labelTags, setLabelTags }: TagLabelSelectType) => {
|
|
14
8
|
const setTagData = (index, tagValue): void => {
|
|
15
9
|
const _tags = [...labelTags]
|
|
16
10
|
_tags[index] = tagValue
|
|
@@ -1,40 +1,32 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import { TagLabelValueSelectorType } from '../Types'
|
|
3
3
|
import PopupMenu from '../PopupMenu'
|
|
4
4
|
import { ValidationRules } from './ValidationRules'
|
|
5
5
|
import { ReactComponent as ErrorCross } from '../../Assets/Icon/ic-close.svg'
|
|
6
6
|
import { ReactComponent as Info } from '../../Assets/Icon/ic-info-outlined.svg'
|
|
7
7
|
|
|
8
|
-
export
|
|
8
|
+
export const TagLabelValueSelector = ({
|
|
9
9
|
selectedTagIndex,
|
|
10
10
|
tagData,
|
|
11
11
|
setTagData,
|
|
12
12
|
tagOptions,
|
|
13
13
|
isRequired,
|
|
14
14
|
type,
|
|
15
|
-
}: {
|
|
16
|
-
selectedTagIndex: number
|
|
17
|
-
tagData: TagType
|
|
18
|
-
setTagData: (index: number, tagData: TagType) => void
|
|
19
|
-
tagOptions?: OptionType[]
|
|
20
|
-
isRequired?: boolean
|
|
21
|
-
type?: string
|
|
22
|
-
}) {
|
|
15
|
+
}: TagLabelValueSelectorType) => {
|
|
23
16
|
const [selectedValue, setSelectedValue] = useState<string>('')
|
|
24
17
|
const [isPopupOpen, togglePopup] = useState<boolean>(false)
|
|
25
18
|
|
|
26
19
|
const validationRules = new ValidationRules()
|
|
27
20
|
|
|
28
21
|
useEffect(() => {
|
|
29
|
-
|
|
30
|
-
setSelectedValue(_tagData[type])
|
|
22
|
+
setSelectedValue(tagData?.[type] || '')
|
|
31
23
|
}, [selectedTagIndex, tagData, type])
|
|
32
24
|
|
|
33
25
|
const handleOnBlur = (e) => {
|
|
34
26
|
if (
|
|
35
27
|
!e.relatedTarget ||
|
|
36
28
|
!e.relatedTarget.classList.value ||
|
|
37
|
-
e.relatedTarget.classList.value.
|
|
29
|
+
!e.relatedTarget.classList.value.includes(`tag-${selectedTagIndex}-class`)
|
|
38
30
|
) {
|
|
39
31
|
const _tagData = { ...tagData }
|
|
40
32
|
_tagData[type] = selectedValue
|
|
@@ -42,14 +34,12 @@ export default function TagLabelValueSelector({
|
|
|
42
34
|
_tagData.isInvalidKey = selectedValue
|
|
43
35
|
? !validationRules.propagateTagKey(selectedValue).isValid
|
|
44
36
|
: _tagData.value !== ''
|
|
37
|
+
} else if (selectedValue) {
|
|
38
|
+
_tagData.isInvalidValue = !validationRules.propagateTagValue(selectedValue).isValid
|
|
39
|
+
_tagData.isInvalidKey = !_tagData.key || _tagData.isInvalidKey
|
|
45
40
|
} else {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
_tagData.isInvalidKey = !_tagData.key || _tagData.isInvalidKey
|
|
49
|
-
} else {
|
|
50
|
-
_tagData.isInvalidValue = false
|
|
51
|
-
_tagData.isInvalidKey = !_tagData.key ? false : _tagData.isInvalidKey
|
|
52
|
-
}
|
|
41
|
+
_tagData.isInvalidValue = false
|
|
42
|
+
_tagData.isInvalidKey = !_tagData.key ? false : _tagData.isInvalidKey
|
|
53
43
|
}
|
|
54
44
|
setTagData(selectedTagIndex, _tagData)
|
|
55
45
|
}
|
|
@@ -67,12 +57,10 @@ export default function TagLabelValueSelector({
|
|
|
67
57
|
|
|
68
58
|
const renderValidationsSuggestions = (): JSX.Element => {
|
|
69
59
|
let field = { isValid: true, messages: [] }
|
|
70
|
-
if (type === '
|
|
71
|
-
if (isRequired || selectedValue) {
|
|
72
|
-
field = validationRules.propagateTagValue(selectedValue)
|
|
73
|
-
}
|
|
74
|
-
} else {
|
|
60
|
+
if (type === 'key') {
|
|
75
61
|
field = validationRules.propagateTagKey(selectedValue)
|
|
62
|
+
} else if (isRequired || selectedValue) {
|
|
63
|
+
field = validationRules.propagateTagValue(selectedValue)
|
|
76
64
|
}
|
|
77
65
|
if (!field.isValid) {
|
|
78
66
|
return (
|
|
@@ -5,11 +5,11 @@ const validateTagValue = (value: string): string[] => {
|
|
|
5
5
|
if (value.length > 63) {
|
|
6
6
|
errorList.push('Can be max 63 characters')
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
const firstLastAlphanumeric = PATTERNS.START_END_ALPHANUMERIC.test(value)
|
|
9
9
|
if (!firstLastAlphanumeric) {
|
|
10
10
|
errorList.push('Must start and end with an alphanumeric character')
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
const validValue = PATTERNS.ALPHANUMERIC_WITH_SPECIAL_CHAR.test(value)
|
|
13
13
|
if (!validValue) {
|
|
14
14
|
errorList.push('Can only contain alphanumeric chars and (-), (_), (.)')
|
|
15
15
|
}
|
|
@@ -32,7 +32,7 @@ export class ValidationRules {
|
|
|
32
32
|
if (prefix.length > 253) {
|
|
33
33
|
errorList.push('Prefix: Can be max 253 characters')
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
const validPrefix = PATTERNS.KUBERNETES_KEY_PREFIX.test(prefix)
|
|
36
36
|
if (!validPrefix) {
|
|
37
37
|
errorList.push('Prefix: Must be a DNS subdomain (a series of DNS labels separated by dots (.)')
|
|
38
38
|
}
|
package/src/Common/Types.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { TagLabelSelect } from './CustomTagSelector'
|
|
2
|
+
|
|
1
3
|
export interface ResponseType {
|
|
2
4
|
code: number
|
|
3
5
|
status: string
|
|
@@ -12,20 +14,41 @@ export interface APIOptions {
|
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export interface TagType {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
key: string
|
|
18
|
+
value?: string
|
|
19
|
+
description?: string
|
|
20
|
+
propagate: boolean
|
|
21
|
+
isInvalidKey?: boolean
|
|
22
|
+
isInvalidValue?: boolean
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export interface OptionType {
|
|
24
|
-
label: string
|
|
25
|
-
value: string
|
|
26
|
+
label: string
|
|
27
|
+
value: string
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
export enum TippyTheme {
|
|
29
31
|
black = 'black',
|
|
30
32
|
white = 'white',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface TagLabelSelectType {
|
|
36
|
+
labelTags: TagType[]
|
|
37
|
+
setLabelTags: (tagList: TagType[]) => void
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface TagDetailType {
|
|
41
|
+
index: number
|
|
42
|
+
tagData: TagType
|
|
43
|
+
setTagData: (index: number, tagData: TagType) => void
|
|
44
|
+
removeTag: (index: number) => void
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface TagLabelValueSelectorType {
|
|
48
|
+
selectedTagIndex: number
|
|
49
|
+
tagData: TagType
|
|
50
|
+
setTagData: (index: number, tagData: TagType) => void
|
|
51
|
+
tagOptions?: OptionType[]
|
|
52
|
+
isRequired?: boolean
|
|
53
|
+
type?: string
|
|
31
54
|
}
|