@spectric/ui 0.0.20 → 0.0.22
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/components/Banner.d.ts +1 -1
- package/dist/components/dialog/dialog.d.ts +2 -1
- package/dist/components/pagination/pagination.d.ts +1 -1
- package/dist/components/query_bar/QueryBar.d.ts +31 -11
- package/dist/components/query_bar/dateTimePopup.d.ts +2 -0
- package/dist/components/query_bar/geojsonPopup.d.ts +2 -0
- package/dist/components/query_bar/querylanguage/kuery/functions/geospatial.d.ts +19 -0
- package/dist/components/query_bar/querylanguage/outputTypes/toCQL.d.ts +2 -1
- package/dist/components/query_bar/querylanguage/outputTypes/toMongo.d.ts +6 -1
- package/dist/components/symbols.d.ts +6 -0
- package/dist/components/table/cell.d.ts +2 -2
- package/dist/components/table/header.d.ts +2 -1
- package/dist/components/table/table.d.ts +14 -7
- package/dist/custom-elements.json +8 -8
- package/dist/index.d.ts +4 -0
- package/dist/index.es.js +4556 -2834
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +424 -248
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +6 -1
- package/src/components/Banner.ts +46 -31
- package/src/components/dialog/dialog.css.ts +29 -29
- package/src/components/dialog/dialog.ts +165 -135
- package/src/components/input.ts +49 -39
- package/src/components/pagination/pagination.ts +167 -113
- package/src/components/query_bar/QueryBar.ts +441 -185
- package/src/components/query_bar/dateTimePopup.ts +54 -0
- package/src/components/query_bar/geojsonPopup.ts +44 -0
- package/src/components/query_bar/querylanguage/kuery/ast/_generated_/kuery.js +1836 -2745
- package/src/components/query_bar/querylanguage/kuery/ast/ast.ts +15 -13
- package/src/components/query_bar/querylanguage/kuery/ast/kuery.peg +92 -126
- package/src/components/query_bar/querylanguage/kuery/functions/geospatial.ts +25 -0
- package/src/components/query_bar/querylanguage/kuery/functions/index.ts +9 -7
- package/src/components/query_bar/querylanguage/outputTypes/toCQL.ts +56 -34
- package/src/components/query_bar/querylanguage/outputTypes/toMongo.ts +46 -34
- package/src/components/symbols.ts +6 -0
- package/src/components/table/__tests__/table.spec.ts +143 -55
- package/src/components/table/cell.ts +188 -145
- package/src/components/table/header.ts +163 -152
- package/src/components/table/table.css +4 -2
- package/src/components/table/table.ts +415 -262
- package/src/components/table/virtualBody.ts +170 -115
- package/src/components/tooltip/popover.ts +263 -225
- package/src/stories/Dialog.stories.ts +59 -0
- package/src/stories/QueryBar.stories.ts +46 -37
- package/src/stories/fixtures/data.ts +195 -36
- package/src/stories/table.stories.ts +70 -22
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
/* eslint-disable @kbn/eslint/require-license-header */
|
|
2
|
-
import { FieldTypes, KueryNode } from
|
|
3
|
-
import { wildcardSymbol } from
|
|
2
|
+
import { FieldTypes, KueryNode } from "../..";
|
|
3
|
+
import { wildcardSymbol } from "../kuery/node_types/wildcard";
|
|
4
|
+
import { wktToGeoJSON } from "@terraformer/wkt";
|
|
4
5
|
|
|
5
6
|
export const KQL_WILDCARD_SYMBOL = wildcardSymbol;
|
|
6
|
-
export const KQL_NODE_TYPE_WILDCARD =
|
|
7
|
-
export type FunctionName =
|
|
7
|
+
export const KQL_NODE_TYPE_WILDCARD = "wildcard";
|
|
8
|
+
export type FunctionName =
|
|
9
|
+
| "is"
|
|
10
|
+
| "and"
|
|
11
|
+
| "or"
|
|
12
|
+
| "not"
|
|
13
|
+
| "range"
|
|
14
|
+
| "exists"
|
|
15
|
+
| "nested";
|
|
8
16
|
const and = (node: KueryNode) => {
|
|
9
17
|
const children = node.arguments || [];
|
|
10
|
-
let query: any = {
|
|
18
|
+
let query: any = { $and: children.map((c: KueryNode) => toMongo(c)) };
|
|
11
19
|
|
|
12
20
|
return query;
|
|
13
21
|
};
|
|
@@ -17,62 +25,65 @@ const is = (node: KueryNode) => {
|
|
|
17
25
|
} = node;
|
|
18
26
|
|
|
19
27
|
let value = toMongo(valueArg);
|
|
20
|
-
const isExistsQuery =
|
|
28
|
+
const isExistsQuery =
|
|
29
|
+
valueArg.type === "wildcard" &&
|
|
30
|
+
(valueArg.value as any) === "@kuery-wildcard@";
|
|
21
31
|
if (isExistsQuery) {
|
|
22
|
-
return exists(node)
|
|
32
|
+
return exists(node);
|
|
23
33
|
}
|
|
24
|
-
let query: any = {}
|
|
25
|
-
query[toMongo(fieldNameArg)] = {
|
|
34
|
+
let query: any = {};
|
|
35
|
+
query[toMongo(fieldNameArg)] = { $eq: value };
|
|
26
36
|
return query;
|
|
27
37
|
};
|
|
28
38
|
|
|
29
39
|
const or = (node: KueryNode) => {
|
|
30
40
|
const children = node.arguments || [];
|
|
31
41
|
return {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
42
|
+
$or: children.map((child: KueryNode) => {
|
|
43
|
+
return toMongo(child);
|
|
44
|
+
}),
|
|
45
|
+
};
|
|
38
46
|
};
|
|
39
47
|
const not = (node: KueryNode) => {
|
|
40
48
|
const [fieldNameArg] = node.arguments;
|
|
41
49
|
let query: any = {};
|
|
42
|
-
query = {
|
|
50
|
+
query = { $ne: toMongo(fieldNameArg) };
|
|
43
51
|
return query;
|
|
44
52
|
};
|
|
45
53
|
|
|
46
54
|
const AST_TO_CQL = {
|
|
47
|
-
gt:
|
|
48
|
-
lt:
|
|
49
|
-
gte:
|
|
50
|
-
lte:
|
|
55
|
+
gt: "$gt",
|
|
56
|
+
lt: "$lt",
|
|
57
|
+
gte: "$gte",
|
|
58
|
+
lte: "$lte",
|
|
51
59
|
};
|
|
52
60
|
const range = (node: KueryNode) => {
|
|
53
61
|
const [fieldNameArg, operator] = node.arguments;
|
|
54
|
-
let valueArg = operator.value
|
|
62
|
+
let valueArg = operator.value;
|
|
55
63
|
// @ts-ignore
|
|
56
64
|
const opsign = AST_TO_CQL[operator.name];
|
|
57
65
|
let value = toMongo(valueArg);
|
|
58
66
|
|
|
59
|
-
let query: any = {}
|
|
60
|
-
query[fieldNameArg.value] = {}
|
|
61
|
-
query[fieldNameArg.value][opsign] = value
|
|
62
|
-
return query
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
let query: any = {};
|
|
68
|
+
query[fieldNameArg.value] = {};
|
|
69
|
+
query[fieldNameArg.value][opsign] = value;
|
|
70
|
+
return query;
|
|
65
71
|
};
|
|
66
72
|
const exists = (node: KueryNode) => {
|
|
67
73
|
const [fieldNameArg] = node.arguments;
|
|
68
|
-
return { [toMongo(fieldNameArg)]: { $ne: null } }
|
|
74
|
+
return { [toMongo(fieldNameArg)]: { $ne: null } };
|
|
69
75
|
};
|
|
70
76
|
|
|
71
77
|
const nested = (node: KueryNode) => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
console.warn("TODO Implement nested search", node);
|
|
79
|
+
return "";
|
|
80
|
+
};
|
|
81
|
+
const geospatial = (node: KueryNode) => {
|
|
82
|
+
const [fieldName, operator, value] = node.arguments;
|
|
83
|
+
if (operator == "within") {
|
|
84
|
+
return { [fieldName.value]: { $geoWithin: wktToGeoJSON(value.value) } };
|
|
85
|
+
}
|
|
86
|
+
};
|
|
76
87
|
export const functions = {
|
|
77
88
|
is,
|
|
78
89
|
and,
|
|
@@ -80,7 +91,8 @@ export const functions = {
|
|
|
80
91
|
not,
|
|
81
92
|
range,
|
|
82
93
|
exists,
|
|
83
|
-
nested
|
|
94
|
+
nested,
|
|
95
|
+
geospatial,
|
|
84
96
|
};
|
|
85
97
|
const nodeTypes = {
|
|
86
98
|
function: (node: KueryNode) => {
|
|
@@ -92,7 +104,7 @@ const nodeTypes = {
|
|
|
92
104
|
},
|
|
93
105
|
wildcard: (node: KueryNode) => {
|
|
94
106
|
const { value } = node;
|
|
95
|
-
return `/${value.split(KQL_WILDCARD_SYMBOL).join(
|
|
107
|
+
return `/${value.split(KQL_WILDCARD_SYMBOL).join(".*")}/`;
|
|
96
108
|
},
|
|
97
109
|
};
|
|
98
110
|
|
|
@@ -1,91 +1,179 @@
|
|
|
1
|
-
import { test, expect } from
|
|
2
|
-
import type { SpectricTableElement, TableEvents } from
|
|
3
|
-
import type SpectricModule from "../../../index.ts"
|
|
1
|
+
import { test, expect } from "@playwright/test";
|
|
2
|
+
import type { SpectricTableElement, TableEvents } from "../index";
|
|
3
|
+
import type SpectricModule from "../../../index.ts";
|
|
4
|
+
import { SpectricInput } from "../../../index.ts";
|
|
4
5
|
test.beforeEach(async ({ page }) => {
|
|
5
|
-
page.on(
|
|
6
|
+
page.on("console", (msg) => {
|
|
7
|
+
console.log(`Page[${msg.type()}]:` + msg.text());
|
|
8
|
+
});
|
|
6
9
|
await page.addInitScript(() => {
|
|
7
10
|
//@ts-ignore
|
|
8
11
|
window.awaitEvent = function awaitEvent(target, event, trigger) {
|
|
9
12
|
return new Promise((resolve, reject) => {
|
|
13
|
+
let timeout = setTimeout(reject, 400);
|
|
10
14
|
const handleEvent = (...args) => {
|
|
15
|
+
clearTimeout(timeout);
|
|
11
16
|
//@ts-ignore
|
|
12
|
-
target.removeEventListener(event, this)
|
|
13
|
-
resolve(args)
|
|
14
|
-
}
|
|
17
|
+
target.removeEventListener(event, this);
|
|
18
|
+
resolve(args);
|
|
19
|
+
};
|
|
15
20
|
//@ts-ignore
|
|
16
|
-
target.addEventListener(event, handleEvent)
|
|
17
|
-
trigger()
|
|
18
|
-
})
|
|
19
|
-
}
|
|
20
|
-
})
|
|
21
|
-
await page.goto('http://localhost:6006/iframe.html?globals=&args=&id=spectric-ui-components-ui-table--milti-select&viewMode=story');
|
|
21
|
+
target.addEventListener(event, handleEvent);
|
|
22
|
+
trigger();
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
});
|
|
22
26
|
});
|
|
23
|
-
test.describe("Spectric Table Tests", () => {
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
test.describe("Spectric Table Tests", () => {
|
|
29
|
+
test("MultiSelect Table Select All/Deselect All ", async ({ page }) => {
|
|
30
|
+
await page.goto(
|
|
31
|
+
"http://localhost:6006/iframe.html?globals=&args=&id=spectric-ui-components-ui-table--multi-select&viewMode=story"
|
|
32
|
+
);
|
|
33
|
+
let tableLocator = page.locator("spectric-table");
|
|
34
|
+
tableLocator.waitFor();
|
|
28
35
|
var selected = await tableLocator.evaluate<number, SpectricTableElement>(
|
|
29
36
|
async (table) => {
|
|
30
|
-
let selectAll = table.querySelectorAll<HTMLElement>(
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
let selectAll = table.querySelectorAll<HTMLElement>(
|
|
38
|
+
"spectric-table-header spectric-input[variant='checkbox'] spectric-button"
|
|
39
|
+
)[0];
|
|
40
|
+
let [event] = (await window.awaitEvent<TableEvents>(
|
|
41
|
+
table,
|
|
42
|
+
"selected",
|
|
43
|
+
() => selectAll.click()
|
|
44
|
+
)) as Parameters<TableEvents["selected"]>;
|
|
45
|
+
return event.detail.length;
|
|
33
46
|
}
|
|
34
|
-
)
|
|
35
|
-
await expect(selected, "All Selected").toBeGreaterThan(0)
|
|
47
|
+
);
|
|
48
|
+
await expect(selected, "All Selected").toBeGreaterThan(0);
|
|
36
49
|
|
|
37
50
|
selected = await tableLocator.evaluate<number, SpectricTableElement>(
|
|
38
51
|
async (table) => {
|
|
39
|
-
let selectAll = table.querySelectorAll<HTMLElement>(
|
|
40
|
-
|
|
41
|
-
|
|
52
|
+
let selectAll = table.querySelectorAll<HTMLElement>(
|
|
53
|
+
"spectric-table-header spectric-input[variant='checkbox'] spectric-button"
|
|
54
|
+
)[0];
|
|
55
|
+
let [event] = (await window.awaitEvent<TableEvents>(
|
|
56
|
+
table,
|
|
57
|
+
"selected",
|
|
58
|
+
() => selectAll.click()
|
|
59
|
+
)) as Parameters<TableEvents["selected"]>;
|
|
60
|
+
return event.detail.length;
|
|
42
61
|
}
|
|
43
|
-
)
|
|
44
|
-
await expect(selected, "None Selected").toBe(0)
|
|
62
|
+
);
|
|
63
|
+
await expect(selected, "None Selected").toBe(0);
|
|
45
64
|
|
|
46
65
|
selected = await tableLocator.evaluate<number, SpectricTableElement>(
|
|
47
66
|
async (table) => {
|
|
48
|
-
let selectAll = table.querySelectorAll<HTMLElement>(
|
|
49
|
-
|
|
50
|
-
|
|
67
|
+
let selectAll = table.querySelectorAll<HTMLElement>(
|
|
68
|
+
"spectric-table-virtual-body spectric-input[variant='checkbox'] spectric-button"
|
|
69
|
+
)[2];
|
|
70
|
+
let [event] = (await window.awaitEvent<TableEvents>(
|
|
71
|
+
table,
|
|
72
|
+
"selected",
|
|
73
|
+
() => selectAll.click()
|
|
74
|
+
)) as Parameters<TableEvents["selected"]>;
|
|
75
|
+
return event.detail.length;
|
|
51
76
|
}
|
|
52
|
-
)
|
|
53
|
-
await expect(selected, "One Selected").toBe(1)
|
|
77
|
+
);
|
|
78
|
+
await expect(selected, "One Selected").toBe(1);
|
|
54
79
|
|
|
55
80
|
selected = await tableLocator.evaluate<number, SpectricTableElement>(
|
|
56
81
|
async (table) => {
|
|
57
|
-
let selectAll = table.querySelectorAll<HTMLElement>(
|
|
58
|
-
|
|
59
|
-
|
|
82
|
+
let selectAll = table.querySelectorAll<HTMLElement>(
|
|
83
|
+
"spectric-table-virtual-body spectric-input[variant='checkbox'] spectric-button"
|
|
84
|
+
)[2];
|
|
85
|
+
let [event] = (await window.awaitEvent<TableEvents>(
|
|
86
|
+
table,
|
|
87
|
+
"selected",
|
|
88
|
+
() => selectAll.click()
|
|
89
|
+
)) as Parameters<TableEvents["selected"]>;
|
|
90
|
+
return event.detail.length;
|
|
60
91
|
}
|
|
61
|
-
)
|
|
62
|
-
await expect(selected, "One DeSelected").toBe(0)
|
|
92
|
+
);
|
|
93
|
+
await expect(selected, "One DeSelected").toBe(0);
|
|
63
94
|
});
|
|
64
95
|
|
|
96
|
+
test("SingleSelect Table ensure only one is selected", async ({ page }) => {
|
|
97
|
+
await page.goto(
|
|
98
|
+
"http://localhost:6006/iframe.html?globals=&args=&id=spectric-ui-components-ui-table--single-select&viewMode=story"
|
|
99
|
+
);
|
|
100
|
+
let tableLocator = page.locator("spectric-table");
|
|
101
|
+
tableLocator.waitFor();
|
|
102
|
+
var selected = await tableLocator.evaluate<number, SpectricTableElement>(
|
|
103
|
+
async (table) => {
|
|
104
|
+
let select = table.querySelectorAll<HTMLElement>(
|
|
105
|
+
"spectric-input[variant='checkbox'].table-checkbox-single spectric-button"
|
|
106
|
+
)[0];
|
|
107
|
+
let [event] = (await window.awaitEvent<TableEvents>(
|
|
108
|
+
table,
|
|
109
|
+
"selected",
|
|
110
|
+
() => select.click()
|
|
111
|
+
)) as Parameters<TableEvents["selected"]>;
|
|
112
|
+
return event.detail.length;
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
await expect(selected, "One Selected").toBe(1);
|
|
116
|
+
|
|
117
|
+
selected = await tableLocator.evaluate<number, SpectricTableElement>(
|
|
118
|
+
async (table) => {
|
|
119
|
+
let select = table.querySelectorAll<HTMLElement>(
|
|
120
|
+
"spectric-input[variant='checkbox'].table-checkbox-single spectric-button"
|
|
121
|
+
)[1];
|
|
122
|
+
let [event] = (await window.awaitEvent<TableEvents>(
|
|
123
|
+
table,
|
|
124
|
+
"selected",
|
|
125
|
+
() => select.click()
|
|
126
|
+
)) as Parameters<TableEvents["selected"]>;
|
|
127
|
+
return event.detail.length;
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
await expect(selected, "One Selected").toBe(1);
|
|
131
|
+
|
|
132
|
+
let checked = await tableLocator.evaluate<number, SpectricTableElement>(
|
|
133
|
+
async (table) => {
|
|
134
|
+
let selectAll = table.querySelectorAll<HTMLElement>(
|
|
135
|
+
"spectric-input[variant='checkbox'].table-checkbox-single"
|
|
136
|
+
)[2];
|
|
137
|
+
let checked = Array.from(
|
|
138
|
+
table.querySelectorAll<SpectricInput>(
|
|
139
|
+
"spectric-input[variant='checkbox'].table-checkbox-single"
|
|
140
|
+
)
|
|
141
|
+
).filter((node) => node.checked);
|
|
142
|
+
return checked.length;
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
await expect(checked, "One checked").toBe(1);
|
|
146
|
+
});
|
|
65
147
|
|
|
66
|
-
test(
|
|
67
|
-
|
|
68
|
-
|
|
148
|
+
test("Ensure all event listeners are cleaned up and not leaked", async ({
|
|
149
|
+
page,
|
|
150
|
+
}) => {
|
|
151
|
+
await page.goto(
|
|
152
|
+
"http://localhost:6006/iframe.html?globals=&args=&id=spectric-ui-components-ui-table--multi-select&viewMode=story"
|
|
153
|
+
);
|
|
154
|
+
let tableLocator = page.locator("spectric-table");
|
|
155
|
+
await tableLocator.waitFor();
|
|
69
156
|
let listenerCount = await page.evaluate(async () => {
|
|
70
|
-
const module = await import("./src/index.ts") as typeof SpectricModule
|
|
71
|
-
return module.getListeners()
|
|
72
|
-
})
|
|
73
|
-
await expect(listenerCount).toBeGreaterThan(0)
|
|
157
|
+
const module = (await import("./src/index.ts")) as typeof SpectricModule;
|
|
158
|
+
return module.getListeners();
|
|
159
|
+
});
|
|
160
|
+
await expect(listenerCount).toBeGreaterThan(0);
|
|
74
161
|
//Delete all content and expect everything to get cleaned up
|
|
75
162
|
listenerCount = await page.evaluate(async () => {
|
|
76
|
-
const module = await import("./src/index.ts") as typeof SpectricModule
|
|
77
|
-
document.body.innerHTML = ""
|
|
78
|
-
return module.getListeners()
|
|
79
|
-
})
|
|
80
|
-
await expect(listenerCount).toBe(0)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
|
|
163
|
+
const module = (await import("./src/index.ts")) as typeof SpectricModule;
|
|
164
|
+
document.body.innerHTML = "";
|
|
165
|
+
return module.getListeners();
|
|
166
|
+
});
|
|
167
|
+
await expect(listenerCount).toBe(0);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
86
170
|
|
|
87
171
|
declare global {
|
|
88
172
|
interface Window {
|
|
89
|
-
awaitEvent: <EventMap extends Record<string, any>, K = keyof EventMap>(
|
|
173
|
+
awaitEvent: <EventMap extends Record<string, any>, K = keyof EventMap>(
|
|
174
|
+
target: HTMLElement,
|
|
175
|
+
event: K,
|
|
176
|
+
trigger: () => void
|
|
177
|
+
) => Parameters<EventMap[keyof EventMap]>;
|
|
90
178
|
}
|
|
91
179
|
}
|