-
Notifications
You must be signed in to change notification settings - Fork 285
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(traces): span table column visibility controls (#1687)
* WIP * feat(traces): span table column visibility controls * fix package lock * Switch ignore pattern
- Loading branch information
1 parent
b796cb4
commit 559852f
Showing
7 changed files
with
2,776 additions
and
2,950 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import React, { ChangeEvent, useCallback, useMemo } from "react"; | ||
import { Column, VisibilityState } from "@tanstack/react-table"; | ||
import { css } from "@emotion/react"; | ||
|
||
import { Dropdown, Flex, Icon, Icons, View } from "@arizeai/components"; | ||
|
||
const UN_HIDABLE_COLUMN_IDS = ["spanKind", "name"]; | ||
|
||
type SpanColumnSelectorProps = { | ||
/** | ||
* The columns that can be displayed in the span table | ||
* This could be made more generic to support other tables | ||
* but for now working on the span tables to figure out the right interface | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
columns: Column<any>[]; | ||
/** | ||
* Map of the column id to the visibility state | ||
*/ | ||
columnVisibility: VisibilityState; | ||
/* | ||
* Callback to set the visibility state of a column | ||
*/ | ||
onColumnVisibilityChange: (visibilityState: VisibilityState) => void; | ||
}; | ||
|
||
export function SpanColumnSelector(props: SpanColumnSelectorProps) { | ||
return ( | ||
<Dropdown | ||
menu={<ColumnSelectorMenu {...props} />} | ||
triggerProps={{ | ||
placement: "bottom end", | ||
}} | ||
> | ||
<Flex direction="row" alignItems="center" gap="size-100"> | ||
<Icon svg={<Icons.Column />} /> | ||
Columns | ||
</Flex> | ||
</Dropdown> | ||
); | ||
} | ||
|
||
const columCheckboxItemCSS = css` | ||
padding: var(--ac-global-dimension-static-size-50) | ||
var(--ac-global-dimension-static-size-100); | ||
label { | ||
display: flex; | ||
align-items: center; | ||
gap: var(--ac-global-dimension-static-size-100); | ||
} | ||
`; | ||
|
||
function ColumnSelectorMenu(props: SpanColumnSelectorProps) { | ||
const { | ||
columns: propsColumns, | ||
columnVisibility, | ||
onColumnVisibilityChange, | ||
} = props; | ||
|
||
const columns = useMemo(() => { | ||
return propsColumns.filter((column) => { | ||
return !UN_HIDABLE_COLUMN_IDS.includes(column.id); | ||
}); | ||
}, [propsColumns]); | ||
|
||
const allVisible = useMemo(() => { | ||
return columns.every((column) => { | ||
const stateValue = columnVisibility[column.id]; | ||
const isVisible = stateValue == null ? true : stateValue; | ||
return isVisible; | ||
}); | ||
}, [columns, columnVisibility]); | ||
|
||
const onCheckboxChange = useCallback( | ||
(event: ChangeEvent<HTMLInputElement>) => { | ||
const { name, checked } = event.target; | ||
onColumnVisibilityChange({ ...columnVisibility, [name]: checked }); | ||
}, | ||
[columnVisibility, onColumnVisibilityChange] | ||
); | ||
|
||
const onToggleAll = useCallback( | ||
(event: ChangeEvent<HTMLInputElement>) => { | ||
const { checked } = event.target; | ||
const newVisibilityState = columns.reduce((acc, column) => { | ||
return { ...acc, [column.id]: checked }; | ||
}, {}); | ||
onColumnVisibilityChange(newVisibilityState); | ||
}, | ||
[columns, onColumnVisibilityChange] | ||
); | ||
|
||
return ( | ||
<View paddingTop="size-50" paddingBottom="size-50"> | ||
<View | ||
borderBottomColor="dark" | ||
borderBottomWidth="thin" | ||
paddingBottom="size-50" | ||
> | ||
<div css={columCheckboxItemCSS}> | ||
<label> | ||
<input | ||
type="checkbox" | ||
name={"toggle-all"} | ||
checked={allVisible} | ||
onChange={onToggleAll} | ||
/> | ||
toggle all | ||
</label> | ||
</div> | ||
</View> | ||
|
||
<ul> | ||
{columns.map((column) => { | ||
const stateValue = columnVisibility[column.id]; | ||
const isVisible = stateValue == null ? true : stateValue; | ||
const name = | ||
typeof column.columnDef.header == "string" | ||
? column.columnDef.header | ||
: column.id; | ||
return ( | ||
<li key={column.id} css={columCheckboxItemCSS}> | ||
<label> | ||
<input | ||
type="checkbox" | ||
name={column.id} | ||
checked={isVisible} | ||
onChange={onCheckboxChange} | ||
/> | ||
{name} | ||
</label> | ||
</li> | ||
); | ||
})} | ||
</ul> | ||
</View> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { css } from "@emotion/react"; | ||
|
||
export const spansTableCSS = css` | ||
display: flex; | ||
flex-direction: column; | ||
flex: 1 1 auto; | ||
overflow: hidden; | ||
.span-filter-condition-field { | ||
flex: 1 1 auto; | ||
} | ||
// Style the column selector | ||
.ac-dropdown-button { | ||
min-width: var(--ac-global-dimension-static-size-300); | ||
} | ||
`; |