forked from syndesisio/syndesis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
IntegrationEditorLabels.tsx
113 lines (102 loc) · 3.09 KB
/
IntegrationEditorLabels.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import {
FormGroup,
Select,
SelectOption,
SelectVariant,
} from '@patternfly/react-core';
import * as React from 'react';
export interface IIntegrationEditorLabelsProps {
initialLabels: string[];
onSelectLabels: (labels: string[]) => void;
}
/**
* Valid format: alphanumeric=alphanumeric
* e.g. Rachel=pizza, lex=hotdogs123
* @param input
*/
const validateLabel = (input: string): boolean => {
const regexIncludeEqual = /(^\w+)(=)(\w+$)/g;
return regexIncludeEqual.test(input);
};
export const IntegrationEditorLabels: React.FunctionComponent<IIntegrationEditorLabelsProps> =
({ initialLabels, onSelectLabels }) => {
const [labels, setLabels] = React.useState(initialLabels);
const [isOpen, setIsOpen] = React.useState(false);
const labelRef = React.useRef(labels);
const isValid = React.useRef(true);
React.useEffect(() => {
if (labelRef.current === labels) {
return;
} else {
labelRef.current = labels;
onSelectLabels(labelRef.current);
}
}, [labels]);
const onCreateOption = (newValue: string) => {
// don't create if it's invalid
if (!validateLabel(newValue)) {
isValid.current = false;
return;
}
};
const onToggle = (isOpenNew: boolean) => {
setIsOpen(isOpenNew);
};
const onSelect = (
event: React.MouseEvent | React.ChangeEvent,
value: any
) => {
if (labels.includes(value)) {
setLabels(labels.filter((item) => item !== value));
} else if (validateLabel(value)) {
setLabels([...labels, value]);
}
setIsOpen(false);
};
const clearSelection = () => {
setLabels([]);
setIsOpen(false);
};
const titleId = 'integration-editor-select';
const placeholderText = 'Specify a label in this format: key=value';
return (
<FormGroup
fieldId={'integration-label-select'}
label={'Labels'}
data-testid={'integration-label-select'}
>
<div>
<span id={titleId} hidden={true}>
{placeholderText}
</span>
<Select
aria-labelledby={titleId}
isCreatable={true}
isOpen={isOpen}
id={'integration-label-select'}
name={'integration-label-select'}
onClear={clearSelection}
onCreateOption={onCreateOption}
onSelect={onSelect}
onToggle={onToggle}
placeholderText={placeholderText}
selections={labels}
typeAheadAriaLabel={placeholderText}
validated={isValid.current ? 'default' : 'error'}
variant={SelectVariant.typeaheadMulti}
>
{initialLabels &&
initialLabels.map((option, index) => (
<SelectOption
key={index}
value={option}
label={option}
data-testid={'label-option-' + option}
/>
))}
</Select>
{!isValid && <p>Please use the following format: key=value</p>}
</div>
</FormGroup>
);
};