diff --git a/app/src/pages/tracing/SpanFilterConditionField.tsx b/app/src/pages/tracing/SpanFilterConditionField.tsx index 711b54a9cd..d4c9962579 100644 --- a/app/src/pages/tracing/SpanFilterConditionField.tsx +++ b/app/src/pages/tracing/SpanFilterConditionField.tsx @@ -1,5 +1,6 @@ import React, { startTransition, + useCallback, useDeferredValue, useEffect, useState, @@ -14,13 +15,18 @@ import { css } from "@emotion/react"; import { AddonBefore, + Button, + Field, Flex, + Form, HelpTooltip, Icon, Icons, + PopoverTrigger, Text, TooltipTrigger, TriggerWrap, + View, } from "@arizeai/components"; import { useTheme } from "@phoenix/contexts"; @@ -51,7 +57,7 @@ const fieldCSS = css` border-radius: var(--ac-global-rounding-small); background-color: var(--ac-global-input-field-background-color); transition: all 0.2s ease-in-out; - overflow: hidden; + overflow-x: hidden; &:hover, &[data-is-focused="true"] { border-color: var(--ac-global-input-field-border-color-active); @@ -60,6 +66,7 @@ const fieldCSS = css` &[data-is-invalid="true"] { border-color: var(--ac-global-color-danger); } + box-sizing: border-box; `; function filterConditionCompletions(context: CompletionContext) { @@ -229,6 +236,16 @@ export function SpanFilterConditionField(props: SpanFilterConditionFieldProps) { const deferredFilterCondition = useDeferredValue(filterCondition); const { theme } = useTheme(); const codeMirrorTheme = theme === "dark" ? nord : undefined; + const onAddFilterConditionSnippet = useCallback( + (additionalCondition: string) => { + if (filterCondition.length > 0) { + setFilterCondition(`${filterCondition} and ${additionalCondition}`); + } else { + setFilterCondition(additionalCondition); + } + }, + [filterCondition, setFilterCondition] + ); useEffect(() => { isConditionValid(deferredFilterCondition).then((result) => { @@ -288,6 +305,25 @@ export function SpanFilterConditionField(props: SpanFilterConditionFieldProps) { > } /> + + + + + + @@ -304,3 +340,103 @@ export function SpanFilterConditionField(props: SpanFilterConditionFieldProps) { ); } + +/** + * Component to build up a filter condition via snippets of conditions + * E.x. filter by kind, filter by token count, etc. + */ +function FilterConditionBuilder(props: { + onAddFilterConditionSnippet: (condition: string) => void; +}) { + const { onAddFilterConditionSnippet } = props; + return ( + +
+ + + + + +
+ ); +} + +/** + * A snippet of filter condition that can be added to the filter condition field + */ +function FilterConditionSnippet(props: { + label: string; + initialSnippet: string; + onAddFilterConditionSnippet: (condition: string) => void; +}) { + const { initialSnippet, onAddFilterConditionSnippet } = props; + const [snippet, setSnippet] = useState(initialSnippet); + const { theme } = useTheme(); + const codeMirrorTheme = theme === "light" ? undefined : nord; + return ( + + +
+ +
+