11import React , { useState } from "react" ;
2- import { Trace , Span } from "@/types/traces" ;
2+ import { Trace , Span , Thread } from "@/types/traces" ;
33import { TRACE_DATA_TYPE } from "@/hooks/useTracesOrSpansList" ;
44import {
55 Dialog ,
@@ -11,16 +11,23 @@ import {
1111import { Button } from "@/components/ui/button" ;
1212import { Input } from "@/components/ui/input" ;
1313import { useToast } from "@/components/ui/use-toast" ;
14- import useTraceUpdateMutation from "@/api/traces/useTraceUpdateMutation" ;
15- import useSpanUpdateMutation from "@/api/traces/useSpanUpdateMutation" ;
14+ import useTraceBatchUpdateMutation from "@/api/traces/useTraceBatchUpdateMutation" ;
15+ import useSpanBatchUpdateMutation from "@/api/traces/useSpanBatchUpdateMutation" ;
16+ import useThreadBatchUpdateMutation from "@/api/traces/useThreadBatchUpdateMutation" ;
1617import useAppStore from "@/store/AppStore" ;
1718
19+ export enum TAG_ENTITY_TYPE {
20+ traces = "traces" ,
21+ spans = "spans" ,
22+ threads = "threads" ,
23+ }
24+
1825type AddTagDialogProps = {
19- rows : Array < Trace | Span > ;
26+ rows : Array < Trace | Span | Thread > ;
2027 open : boolean | number ;
2128 setOpen : ( open : boolean | number ) => void ;
2229 projectId : string ;
23- type : TRACE_DATA_TYPE ;
30+ type : TRACE_DATA_TYPE | TAG_ENTITY_TYPE . threads ;
2431 onSuccess ?: ( ) => void ;
2532} ;
2633
@@ -35,9 +42,9 @@ const AddTagDialog: React.FunctionComponent<AddTagDialogProps> = ({
3542 const { toast } = useToast ( ) ;
3643 const workspaceName = useAppStore ( ( state ) => state . activeWorkspaceName ) ;
3744 const [ newTag , setNewTag ] = useState < string > ( "" ) ;
38- const traceUpdateMutation = useTraceUpdateMutation ( ) ;
39- const spanUpdateMutation = useSpanUpdateMutation ( ) ;
40- const MAX_ENTITIES = 10 ;
45+ const traceBatchUpdateMutation = useTraceBatchUpdateMutation ( ) ;
46+ const spanBatchUpdateMutation = useSpanBatchUpdateMutation ( ) ;
47+ const threadBatchUpdateMutation = useThreadBatchUpdateMutation ( ) ;
4148
4249 const handleClose = ( ) => {
4350 setOpen ( false ) ;
@@ -47,54 +54,55 @@ const AddTagDialog: React.FunctionComponent<AddTagDialogProps> = ({
4754 const handleAddTag = ( ) => {
4855 if ( ! newTag ) return ;
4956
50- const promises : Promise < unknown > [ ] = [ ] ;
51-
52- rows . forEach ( ( row ) => {
53- const currentTags = row . tags || [ ] ;
54-
55- if ( currentTags . includes ( newTag ) ) return ;
56-
57- const newTags = [ ...currentTags , newTag ] ;
58-
59- if ( type === TRACE_DATA_TYPE . traces ) {
60- promises . push (
61- traceUpdateMutation . mutateAsync ( {
62- projectId,
63- traceId : row . id ,
64- trace : {
65- workspace_name : workspaceName ,
66- project_id : projectId ,
67- tags : newTags ,
68- } ,
69- } ) ,
70- ) ;
71- } else {
72- const span = row as Span ;
73- const parentId = span . parent_span_id ;
57+ let mutationPromise ;
58+ let entityName ;
7459
75- promises . push (
76- spanUpdateMutation . mutateAsync ( {
77- projectId,
78- spanId : span . id ,
79- span : {
80- workspace_name : workspaceName ,
81- project_id : projectId ,
82- ...( parentId && { parent_span_id : parentId } ) ,
83- trace_id : span . trace_id ,
84- tags : newTags ,
85- } ,
86- } ) ,
87- ) ;
88- }
89- } ) ;
60+ if ( type === TRACE_DATA_TYPE . traces ) {
61+ const ids = rows . map ( ( row ) => row . id ) ;
62+ mutationPromise = traceBatchUpdateMutation . mutateAsync ( {
63+ projectId,
64+ traceIds : ids ,
65+ trace : {
66+ workspace_name : workspaceName ,
67+ project_id : projectId ,
68+ tags : [ newTag ] ,
69+ } ,
70+ mergeTags : true ,
71+ } ) ;
72+ entityName = "traces" ;
73+ } else if ( type === TRACE_DATA_TYPE . spans ) {
74+ const ids = rows . map ( ( row ) => row . id ) ;
75+ mutationPromise = spanBatchUpdateMutation . mutateAsync ( {
76+ projectId,
77+ spanIds : ids ,
78+ span : {
79+ workspace_name : workspaceName ,
80+ project_id : projectId ,
81+ trace_id : ( rows [ 0 ] as Span ) . trace_id ,
82+ tags : [ newTag ] ,
83+ } ,
84+ mergeTags : true ,
85+ } ) ;
86+ entityName = "spans" ;
87+ } else {
88+ // threads - use thread_model_id instead of id
89+ const threadModelIds = rows . map ( ( row ) => ( row as Thread ) . thread_model_id ) ;
90+ mutationPromise = threadBatchUpdateMutation . mutateAsync ( {
91+ projectId,
92+ threadIds : threadModelIds ,
93+ thread : {
94+ tags : [ newTag ] ,
95+ } ,
96+ mergeTags : true ,
97+ } ) ;
98+ entityName = "threads" ;
99+ }
90100
91- Promise . all ( promises )
101+ mutationPromise
92102 . then ( ( ) => {
93103 toast ( {
94104 title : "Success" ,
95- description : `Tag "${ newTag } " added to ${ rows . length } selected ${
96- type === TRACE_DATA_TYPE . traces ? "traces" : "spans"
97- } `,
105+ description : `Tag "${ newTag } " added to ${ rows . length } selected ${ entityName } ` ,
98106 } ) ;
99107
100108 if ( onSuccess ) {
@@ -104,7 +112,7 @@ const AddTagDialog: React.FunctionComponent<AddTagDialogProps> = ({
104112 handleClose ( ) ;
105113 } )
106114 . catch ( ( ) => {
107- // Error handling is already done by the mutation hooks,this just ensures we don't close the dialog on error
115+ // Error handling is already done by the mutation hooks
108116 } ) ;
109117 } ;
110118
@@ -114,34 +122,28 @@ const AddTagDialog: React.FunctionComponent<AddTagDialogProps> = ({
114122 < DialogHeader >
115123 < DialogTitle >
116124 Add tag to { rows . length } { " " }
117- { type === TRACE_DATA_TYPE . traces ? "traces" : "spans" }
125+ { type === TRACE_DATA_TYPE . traces
126+ ? "traces"
127+ : type === TRACE_DATA_TYPE . spans
128+ ? "spans"
129+ : "threads" }
118130 </ DialogTitle >
119131 </ DialogHeader >
120- { rows . length > MAX_ENTITIES && (
121- < div className = "mb-2 text-sm text-destructive" >
122- You can only add tags to up to { MAX_ENTITIES } entities at a time.
123- Please select fewer entities.
124- </ div >
125- ) }
126132 < div className = "grid gap-4 py-4" >
127133 < div className = "flex items-center gap-4" >
128134 < Input
129135 placeholder = "New tag"
130136 value = { newTag }
131137 onChange = { ( event ) => setNewTag ( event . target . value ) }
132138 className = "col-span-3"
133- disabled = { rows . length > MAX_ENTITIES }
134139 />
135140 </ div >
136141 </ div >
137142 < DialogFooter >
138143 < Button variant = "outline" onClick = { handleClose } >
139144 Cancel
140145 </ Button >
141- < Button
142- onClick = { handleAddTag }
143- disabled = { ! newTag || rows . length > MAX_ENTITIES }
144- >
146+ < Button onClick = { handleAddTag } disabled = { ! newTag } >
145147 Add tag
146148 </ Button >
147149 </ DialogFooter >
0 commit comments