feat(dashboard): Add cross filter from context menu (#23141)

This commit is contained in:
Kamil Gabryjelski
2023-02-23 17:05:41 +01:00
committed by GitHub
parent 95eb8d79d0
commit ee1952e488
26 changed files with 896 additions and 753 deletions

View File

@@ -39,74 +39,95 @@ export default function EchartsTreemap({
selectedValues,
width,
}: TreemapTransformedProps) {
const handleChange = useCallback(
(values: string[]) => {
if (!emitCrossFilters) {
return;
const getCrossFilterDataMask = useCallback(
(data, treePathInfo) => {
if (data?.children) {
return undefined;
}
const { treePath } = extractTreePathInfo(treePathInfo);
const name = treePath.join(',');
const selected = Object.values(selectedValues);
let values: string[];
if (selected.includes(name)) {
values = selected.filter(v => v !== name);
} else {
values = [name];
}
const groupbyValues = values.map(value => labelMap[value]);
setDataMask({
extraFormData: {
filters:
values.length === 0
? []
: groupby.map((col, idx) => {
const val: DataRecordValue[] = groupbyValues.map(v => v[idx]);
if (val === null || val === undefined)
return {
dataMask: {
extraFormData: {
filters:
values.length === 0
? []
: groupby.map((col, idx) => {
const val: DataRecordValue[] = groupbyValues.map(
v => v[idx],
);
if (val === null || val === undefined)
return {
col,
op: 'IS NULL' as const,
};
return {
col,
op: 'IS NULL',
op: 'IN' as const,
val: val as (string | number | boolean)[],
};
return {
col,
op: 'IN',
val: val as (string | number | boolean)[],
};
}),
}),
},
filterState: {
value: groupbyValues.length ? groupbyValues : null,
selectedValues: values.length ? values : null,
},
},
filterState: {
value: groupbyValues.length ? groupbyValues : null,
selectedValues: values.length ? values : null,
},
});
isCurrentValueSelected: selected.includes(name),
};
},
[groupby, labelMap, setDataMask, selectedValues],
[groupby, labelMap, selectedValues],
);
const handleChange = useCallback(
(data, treePathInfo) => {
if (!emitCrossFilters) {
return;
}
const dataMask = getCrossFilterDataMask(data, treePathInfo)?.dataMask;
if (dataMask) {
setDataMask(dataMask);
}
},
[emitCrossFilters, getCrossFilterDataMask, setDataMask],
);
const eventHandlers: EventHandlers = {
click: props => {
const { data, treePathInfo } = props;
// do nothing when clicking on the parent node
if (data?.children) {
return;
}
const { treePath } = extractTreePathInfo(treePathInfo);
const name = treePath.join(',');
const values = Object.values(selectedValues);
if (values.includes(name)) {
handleChange(values.filter(v => v !== name));
} else {
handleChange([name]);
}
handleChange(data, treePathInfo);
},
contextmenu: eventParams => {
if (onContextMenu) {
eventParams.event.stop();
const { treePath } = extractTreePathInfo(eventParams.treePathInfo);
const { data, treePathInfo } = eventParams;
const { treePath } = extractTreePathInfo(treePathInfo);
if (treePath.length > 0) {
const pointerEvent = eventParams.event.event;
const filters: BinaryQueryObjectFilterClause[] = [];
const drillToDetailFilters: BinaryQueryObjectFilterClause[] = [];
treePath.forEach((path, i) =>
filters.push({
drillToDetailFilters.push({
col: groupby[i],
op: '==',
val: path === 'null' ? NULL_STRING : path,
formattedVal: path,
}),
);
onContextMenu(pointerEvent.clientX, pointerEvent.clientY, filters);
onContextMenu(pointerEvent.clientX, pointerEvent.clientY, {
drillToDetail: drillToDetailFilters,
crossFilter: getCrossFilterDataMask(data, treePathInfo),
});
}
}
},