@genspectrum/dashboard-components 0.4.1 → 0.4.2
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/custom-elements.json +2 -2
- package/dist/dashboard-components.js +10 -6
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +4 -4
- package/package.json +1 -1
- package/src/preact/locationFilter/location-filter.tsx +9 -2
- package/src/preact/textInput/text-input.tsx +2 -2
- package/src/web-components/input/gs-location-filter.stories.ts +9 -0
- package/src/web-components/input/gs-text-input.stories.ts +6 -0
|
@@ -767,20 +767,20 @@ declare global {
|
|
|
767
767
|
|
|
768
768
|
declare global {
|
|
769
769
|
interface HTMLElementTagNameMap {
|
|
770
|
-
'gs-
|
|
770
|
+
'gs-location-filter': LocationFilterComponent;
|
|
771
771
|
}
|
|
772
772
|
interface HTMLElementEventMap {
|
|
773
|
-
'gs-
|
|
773
|
+
'gs-location-changed': CustomEvent<Record<string, string>>;
|
|
774
774
|
}
|
|
775
775
|
}
|
|
776
776
|
|
|
777
777
|
|
|
778
778
|
declare global {
|
|
779
779
|
interface HTMLElementTagNameMap {
|
|
780
|
-
'gs-
|
|
780
|
+
'gs-text-input': TextInputComponent;
|
|
781
781
|
}
|
|
782
782
|
interface HTMLElementEventMap {
|
|
783
|
-
'gs-
|
|
783
|
+
'gs-text-input-changed': CustomEvent<Record<string, string>>;
|
|
784
784
|
}
|
|
785
785
|
}
|
|
786
786
|
|
package/package.json
CHANGED
|
@@ -51,11 +51,11 @@ export const LocationFilterInner = ({ initialValue, fields }: LocationFilterInne
|
|
|
51
51
|
const onInput = (event: JSXInternal.TargetedInputEvent<HTMLInputElement>) => {
|
|
52
52
|
const inputValue = event.currentTarget.value;
|
|
53
53
|
setValue(inputValue);
|
|
54
|
-
if (inputValue.trim() === value.trim()) {
|
|
54
|
+
if (inputValue.trim() === value.trim() && inputValue !== '') {
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
const eventDetail = parseLocation(inputValue, fields);
|
|
58
|
-
if (hasMatchingEntry(data, eventDetail)) {
|
|
58
|
+
if (hasAllUndefined(eventDetail) || hasMatchingEntry(data, eventDetail)) {
|
|
59
59
|
divRef.current?.dispatchEvent(
|
|
60
60
|
new CustomEvent('gs-location-changed', {
|
|
61
61
|
detail: eventDetail,
|
|
@@ -92,10 +92,17 @@ export const LocationFilterInner = ({ initialValue, fields }: LocationFilterInne
|
|
|
92
92
|
};
|
|
93
93
|
|
|
94
94
|
const parseLocation = (location: string, fields: string[]) => {
|
|
95
|
+
if (location === '') {
|
|
96
|
+
return fields.reduce((acc, field) => ({ ...acc, [field]: undefined }), {});
|
|
97
|
+
}
|
|
95
98
|
const fieldValues = location.split('/').map((part) => part.trim());
|
|
99
|
+
|
|
96
100
|
return fields.reduce((acc, field, i) => ({ ...acc, [field]: fieldValues[i] }), {});
|
|
97
101
|
};
|
|
98
102
|
|
|
103
|
+
const hasAllUndefined = (obj: Record<string, string | undefined>) =>
|
|
104
|
+
Object.values(obj).every((value) => value === undefined);
|
|
105
|
+
|
|
99
106
|
const hasMatchingEntry = (data: Record<string, string>[] | null, eventDetail: Record<string, string>) => {
|
|
100
107
|
if (data === null) {
|
|
101
108
|
return false;
|
|
@@ -56,7 +56,7 @@ export const TextInputInner: FunctionComponent<TextInputInnerProps> = ({
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
const onInput = () => {
|
|
59
|
-
const value = inputRef.current?.value;
|
|
59
|
+
const value = inputRef.current?.value === '' ? undefined : inputRef.current?.value;
|
|
60
60
|
|
|
61
61
|
if (isValidValue(value)) {
|
|
62
62
|
inputRef.current?.dispatchEvent(
|
|
@@ -71,7 +71,7 @@ export const TextInputInner: FunctionComponent<TextInputInnerProps> = ({
|
|
|
71
71
|
|
|
72
72
|
const isValidValue = (value: string | undefined) => {
|
|
73
73
|
if (value === undefined) {
|
|
74
|
-
return
|
|
74
|
+
return true;
|
|
75
75
|
}
|
|
76
76
|
return data.includes(value);
|
|
77
77
|
};
|
|
@@ -185,7 +185,16 @@ export const FiresEvent: StoryObj<LocationFilterProps> = {
|
|
|
185
185
|
await step('Input invalid location', async () => {
|
|
186
186
|
await userEvent.type(inputField(), 'Not / A / Location');
|
|
187
187
|
await expect(listenerMock).not.toHaveBeenCalled();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
await step('Empty input', async () => {
|
|
188
191
|
await userEvent.type(inputField(), '{backspace>18/}');
|
|
192
|
+
await expect(listenerMock.mock.calls.at(-1)[0].detail).toStrictEqual({
|
|
193
|
+
region: undefined,
|
|
194
|
+
country: undefined,
|
|
195
|
+
division: undefined,
|
|
196
|
+
location: undefined,
|
|
197
|
+
});
|
|
189
198
|
});
|
|
190
199
|
|
|
191
200
|
await step('Select Asia', async () => {
|
|
@@ -118,7 +118,13 @@ export const FiresEvent: StoryObj<Required<TextInputProps>> = {
|
|
|
118
118
|
await step('Enters an invalid host name', async () => {
|
|
119
119
|
await userEvent.type(inputField(), 'notInList');
|
|
120
120
|
await expect(listenerMock).not.toHaveBeenCalled();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
await step('Empty input', async () => {
|
|
121
124
|
await userEvent.type(inputField(), '{backspace>9/}');
|
|
125
|
+
await expect(listenerMock.mock.calls.at(-1)[0].detail).toStrictEqual({
|
|
126
|
+
host: undefined,
|
|
127
|
+
});
|
|
122
128
|
});
|
|
123
129
|
|
|
124
130
|
await step('Enter a valid host name', async () => {
|