Skip to content

Commit

Permalink
feat(annotations): refetch annootations on annotation changes (#3980)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeldking authored Jul 24, 2024
1 parent 5c7747e commit 9ba7cb9
Show file tree
Hide file tree
Showing 12 changed files with 821 additions and 194 deletions.
2 changes: 2 additions & 0 deletions app/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,7 @@ type SpanAnnotation implements Node & Annotation {

type SpanAnnotationMutationPayload {
spanAnnotations: [SpanAnnotation!]!
query: Query!
}

type SpanAsExampleRevision implements ExampleRevision {
Expand Down Expand Up @@ -1339,6 +1340,7 @@ type TraceAnnotation implements Node {

type TraceAnnotationMutationPayload {
traceAnnotations: [TraceAnnotation!]!
query: Query!
}

type TraceEvaluation implements Annotation {
Expand Down
6 changes: 5 additions & 1 deletion app/src/pages/project/DatasetSelectorPopoverContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from "@arizeai/components";

import { DatasetSelectorPopoverContent_datasets$key } from "./__generated__/DatasetSelectorPopoverContent_datasets.graphql";
import { DatasetSelectorPopoverContentDatasetsQuery } from "./__generated__/DatasetSelectorPopoverContentDatasetsQuery.graphql";
import { DatasetSelectorPopoverContentQuery } from "./__generated__/DatasetSelectorPopoverContentQuery.graphql";

export type DatasetSelectorPopoverContentProps = {
Expand Down Expand Up @@ -83,7 +84,10 @@ function DatasetsListBox(props: {
onDatasetSelected: (datasetId: string) => void;
}) {
const { search, onDatasetSelected } = props;
const [data] = useRefetchableFragment(
const [data] = useRefetchableFragment<
DatasetSelectorPopoverContentDatasetsQuery,
DatasetSelectorPopoverContent_datasets$key
>(
graphql`
fragment DatasetSelectorPopoverContent_datasets on Query
@refetchable(queryName: "DatasetSelectorPopoverContentDatasetsQuery") {
Expand Down
83 changes: 52 additions & 31 deletions app/src/pages/trace/EditSpanAnnotationsDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Suspense, useMemo, useState } from "react";
import { graphql, useLazyLoadQuery } from "react-relay";
import { graphql, useLazyLoadQuery, useRefetchableFragment } from "react-relay";
import { css } from "@emotion/react";

import {
Expand All @@ -22,12 +22,14 @@ import { Empty } from "@phoenix/components/Empty";
import { useNotifySuccess } from "@phoenix/contexts";
import { formatFloat } from "@phoenix/utils/numberFormatUtils";

import { EditSpanAnnotationsDialogNewAnnotationQuery } from "./__generated__/EditSpanAnnotationsDialogNewAnnotationQuery.graphql";
import {
AnnotatorKind,
EditSpanAnnotationsDialogQuery,
EditSpanAnnotationsDialogQuery$data,
} from "./__generated__/EditSpanAnnotationsDialogQuery.graphql";
EditSpanAnnotationsDialog_spanAnnotations$data,
EditSpanAnnotationsDialog_spanAnnotations$key,
} from "./__generated__/EditSpanAnnotationsDialog_spanAnnotations.graphql";
import { EditSpanAnnotationsDialogNewAnnotationQuery } from "./__generated__/EditSpanAnnotationsDialogNewAnnotationQuery.graphql";
import { EditSpanAnnotationsDialogQuery } from "./__generated__/EditSpanAnnotationsDialogQuery.graphql";
import { EditSpanAnnotationsDialogSpanAnnotationsQuery } from "./__generated__/EditSpanAnnotationsDialogSpanAnnotationsQuery.graphql";
import { NewSpanAnnotationForm } from "./NewSpanAnnotationForm";
import { SpanAnnotationActionMenu } from "./SpanAnnotationActionMenu";
import { SpanAnnotationForm } from "./SpanAnnotationForm";
Expand All @@ -43,7 +45,6 @@ export function EditSpanAnnotationsDialog(
const [newAnnotationName, setNewAnnotationName] = useState<string | null>(
null
);
const [fetchKey, setFetchKey] = useState(0);
const notifySuccess = useNotifySuccess();
return (
<Dialog
Expand Down Expand Up @@ -76,7 +77,6 @@ export function EditSpanAnnotationsDialog(
}}
onCreated={() => {
setNewAnnotationName(null);
setFetchKey((key) => key + 1);
notifySuccess({
title: `New Span Annotation`,
message: `Annotation ${newAnnotationName} has been created.`,
Expand All @@ -86,7 +86,7 @@ export function EditSpanAnnotationsDialog(
</View>
)}
<Suspense>
<EditSpanAnnotations {...props} fetchKey={fetchKey} />
<EditSpanAnnotations {...props} />
</Suspense>
</div>
</Dialog>
Expand Down Expand Up @@ -166,36 +166,52 @@ function NewAnnotationPopover(props: NewAnnotationPopoverProps) {
</Card>
);
}
type EditSpanAnnotationsProps = EditSpanAnnotationsDialogProps & {
/**
* Key used to force a refetch of the annotations
*/
fetchKey: number;
};
type EditSpanAnnotationsProps = EditSpanAnnotationsDialogProps;

function EditSpanAnnotations(props: EditSpanAnnotationsProps) {
const { fetchKey } = props;
const data = useLazyLoadQuery<EditSpanAnnotationsDialogQuery>(
graphql`
query EditSpanAnnotationsDialogQuery($spanId: GlobalID!) {
span: node(id: $spanId) {
id
... on Span {
spanAnnotations {
id
name
annotatorKind
score
label
explanation
}
...EditSpanAnnotationsDialog_spanAnnotations
}
}
}
`,
{ spanId: props.spanNodeId },
{ fetchKey, fetchPolicy: "store-and-network" }
{ fetchPolicy: "store-and-network" }
);
return <SpanAnnotationsList span={data.span} />;
}

function SpanAnnotationsList(props: {
span: EditSpanAnnotationsDialog_spanAnnotations$key;
}) {
const { span } = props;
const [data] = useRefetchableFragment<
EditSpanAnnotationsDialogSpanAnnotationsQuery,
EditSpanAnnotationsDialog_spanAnnotations$key
>(
graphql`
fragment EditSpanAnnotationsDialog_spanAnnotations on Span
@refetchable(queryName: "EditSpanAnnotationsDialogSpanAnnotationsQuery") {
id
spanAnnotations {
id
name
annotatorKind
score
label
explanation
}
}
`,
span
);
const annotations = data.span.spanAnnotations || [];

const annotations = data.spanAnnotations || [];
const hasAnnotations = annotations.length > 0;
return (
<div>
Expand All @@ -211,7 +227,7 @@ function EditSpanAnnotations(props: EditSpanAnnotationsProps) {
>
{annotations.map((annotation, idx) => (
<li key={idx}>
<SpanAnnotationCard annotation={annotation} />
<SpanAnnotationCard annotation={annotation} spanNodeId={data.id} />
</li>
))}
</ul>
Expand Down Expand Up @@ -263,11 +279,14 @@ function NewSpanAnnotationCard(props: {
}

type Annotation = NonNullable<
EditSpanAnnotationsDialogQuery$data["span"]["spanAnnotations"]
EditSpanAnnotationsDialog_spanAnnotations$data["spanAnnotations"]
>[number];

function SpanAnnotationCard(props: { annotation: Annotation }) {
const { annotation } = props;
function SpanAnnotationCard(props: {
annotation: Annotation;
spanNodeId: string;
}) {
const { annotation, spanNodeId } = props;
const [error, setError] = useState<Error | null>(null);
const notifySuccess = useNotifySuccess();
return (
Expand All @@ -287,6 +306,7 @@ function SpanAnnotationCard(props: { annotation: Annotation }) {
<AnnotatorKindLabel kind={annotation.annotatorKind} />
<SpanAnnotationActionMenu
annotationId={annotation.id}
spanNodeId={spanNodeId}
annotationName={annotation.name}
onSpanAnnotationDelete={() => {
notifySuccess({
Expand Down Expand Up @@ -412,8 +432,9 @@ function NewAnnotationPopoverContent(props: {
if (keys === "all" || keys.size === 0) {
return;
}
const name = keys.entries().next().value[0];
setNewName(name);
const nameKey = keys.values().next().value;
const name = nameKey as string;
setNewName(name || "");
}}
disabledKeys={existingAnnotationNames}
>
Expand Down
11 changes: 8 additions & 3 deletions app/src/pages/trace/NewSpanAnnotationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ export function NewSpanAnnotationForm(props: NewSpanAnnotationFormProps) {
graphql`
mutation NewSpanAnnotationFormMutation(
$input: CreateSpanAnnotationInput!
$spanId: GlobalID!
) {
createSpanAnnotations(input: [$input]) {
spanAnnotations {
id
name
query {
node(id: $spanId) {
... on Span {
...EditSpanAnnotationsDialog_spanAnnotations
}
}
}
}
}
Expand All @@ -37,6 +41,7 @@ export function NewSpanAnnotationForm(props: NewSpanAnnotationFormProps) {
annotatorKind: "HUMAN",
...data,
},
spanId: spanNodeId,
},
onCompleted: () => {
onCreated();
Expand Down
13 changes: 12 additions & 1 deletion app/src/pages/trace/SpanAnnotationActionMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { AnnotationActionMenu } from "./AnnotationActionMenu";

type SpanAnnotationActionMenuProps = {
annotationId: string;
spanNodeId: string;
annotationName: string;
onSpanAnnotationDelete: () => void;
onSpanAnnotationDeleteError: (error: Error) => void;
Expand All @@ -28,6 +29,7 @@ type SpanAnnotationActionMenuProps = {
export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) {
const {
annotationId,
spanNodeId,
annotationName,
onSpanAnnotationDelete,
onSpanAnnotationDeleteError,
Expand All @@ -37,9 +39,16 @@ export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) {
useMutation<SpanAnnotationActionMenuDeleteMutation>(graphql`
mutation SpanAnnotationActionMenuDeleteMutation(
$annotationId: GlobalID!
$spanId: GlobalID!
) {
deleteSpanAnnotations(input: { annotationIds: [$annotationId] }) {
__typename
query {
node(id: $spanId) {
... on Span {
...EditSpanAnnotationsDialog_spanAnnotations
}
}
}
}
}
`);
Expand All @@ -49,6 +58,7 @@ export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) {
commitDelete({
variables: {
annotationId,
spanId: spanNodeId,
},
onCompleted: () => {
onSpanAnnotationDelete();
Expand All @@ -61,6 +71,7 @@ export function SpanAnnotationActionMenu(props: SpanAnnotationActionMenuProps) {
}, [
commitDelete,
annotationId,
spanNodeId,
onSpanAnnotationDelete,
onSpanAnnotationDeleteError,
]);
Expand Down
Loading

0 comments on commit 9ba7cb9

Please sign in to comment.