@@ -71,94 +71,108 @@ function toggleDurationSortType() {
7171 </script >
7272
7373<template >
74- <table w-full border-separate border-spacing-0 >
75- <thead border =" b base" >
76- <tr px2 class =" [& _th]:(sticky top-0 z10 border-b border-base)" >
77- <th v-if =" selectedFields.includes('hookName')" bg-base w32 ws-nowrap p1 text-center font-600 >
78- Hook name
79- </th >
80- <th v-if =" selectedFields.includes('module')" bg-base min-w100 ws-nowrap p1 text-left font-600 >
81- <button flex =" ~ row gap1 items-center" w-full >
82- Module
83- <VMenu >
84- <span w-6 h-6 rounded-full cursor-pointer hover =" bg-active" flex =" ~ items-center justify-center" >
85- <i text-xs class =" i-carbon-filter" :class =" filterModuleTypes.length !== searchFilterTypes.length ? 'text-primary op100' : 'op50'" />
86- </span >
87- <template #popper >
88- <div class =" p2" flex =" ~ col gap2" >
89- <label
90- v-for =" rule of searchFilterTypes"
91- :key =" rule.name"
92- border =" ~ base rounded-md" px2 py1
93- flex =" ~ items-center gap-1"
94- select-none
95- :title =" rule.description"
96- class =" cursor-pointer module-type-filter"
97- >
98- <input
99- type =" checkbox"
100- mr1
101- :checked =" filterModuleTypes?.includes(rule.name)"
102- @change =" toggleModuleType(rule)"
103- >
104- <div :class =" rule.icon" icon-catppuccin />
105- <div text-sm >{{ rule.description || rule.name }}</div >
106- </label >
107- </div >
108- </template >
109- </VMenu >
110- </button >
111- </th >
112- <th v-if =" selectedFields.includes('startTime')" rounded-tr-2 bg-base ws-nowrap p1 text-center font-600 >
113- Start Time
114- </th >
115- <th v-if =" selectedFields.includes('endTime')" rounded-tr-2 bg-base ws-nowrap p1 text-center font-600 >
116- End Time
117- </th >
118- <th v-if =" selectedFields.includes('duration')" rounded-tr-2 bg-base ws-nowrap p1 text-center font-600 >
119- <button flex =" ~ row gap1 items-center justify-center" w-full @click =" toggleDurationSortType" >
120- Duration
74+ <div role =" table" w-full >
75+ <div role =" row" class =" sticky top-0 z10 border-b border-base" flex =" ~ row" >
76+ <div v-if =" selectedFields.includes('hookName')" role =" columnheader" bg-base flex-none w32 ws-nowrap p1 text-center font-600 >
77+ Hook name
78+ </div >
79+ <div v-if =" selectedFields.includes('module')" role =" columnheader" bg-base flex-1 min-w100 ws-nowrap p1 text-left font-600 >
80+ <button flex =" ~ row gap1 items-center" w-full >
81+ Module
82+ <VMenu >
12183 <span w-6 h-6 rounded-full cursor-pointer hover =" bg-active" flex =" ~ items-center justify-center" >
122- <i text-xs : class =" [durationSortType !== 'asc' ? ' i-carbon-arrow-down' : 'i-carbon-arrow-up', durationSortType ? 'op100 text-primary' : 'op50'] " />
84+ <i text-xs class =" i-carbon-filter " :class = " filterModuleTypes.length !== searchFilterTypes.length ? 'text-primary op100 ' : 'op50'" />
12385 </span >
124- </button >
125- </th >
126- </tr >
127- </thead >
128- <tbody v-if =" filtered.length" >
129- <tr v-for =" (item, index) in filtered" :key =" item.id" class =" [& _td]:(border-base border-b-1 border-dashed)" :class =" [index === filtered.length - 1 ? '[& _td]:(border-b-0)' : '']" >
130- <td v-if =" selectedFields.includes('hookName')" w32 ws-nowrap text-center text-sm op80 >
131- {{ HOOK_NAME_MAP[item.type] }}
132- </td >
133- <td v-if =" selectedFields.includes('module')" min-w100 text-left text-ellipsis line-clamp-2 >
134- <DisplayModuleId
135- :id =" item.module"
136- w-full border-none
137- :session =" session"
138- :link =" `/session/${session.id}/graph?module=${item.module}`"
139- hover =" bg-active"
140- border =" ~ base rounded" block px2 py1
141- />
142- </td >
143- <td v-if =" selectedFields.includes('startTime')" text-center font-mono text-sm min-w52 op80 >
144- <time v-if =" item.timestamp_start" :datetime =" new Date(item.timestamp_start).toISOString()" >{{ normalizeTimestamp(item.timestamp_start) }}</time >
145- </td >
146- <td v-if =" selectedFields.includes('endTime')" text-center font-mono text-sm min-w52 op80 >
147- <time v-if =" item.timestamp_end" :datetime =" new Date(item.timestamp_end).toISOString()" >{{ normalizeTimestamp(item.timestamp_end) }}</time >
148- </td >
149- <td v-if =" selectedFields.includes('duration')" text-center text-sm >
150- <DisplayDuration :duration =" item.duration" />
151- </td >
152- </tr >
153- </tbody >
154- <tbody v-else >
155- <tr >
156- <td :colspan =" selectedFields.length" p4 >
157- <div w-full h-48 flex =" ~ items-center justify-center" op50 italic >
158- No data
86+ <template #popper >
87+ <div class =" p2" flex =" ~ col gap2" >
88+ <label
89+ v-for =" rule of searchFilterTypes"
90+ :key =" rule.name"
91+ border =" ~ base rounded-md" px2 py1
92+ flex =" ~ items-center gap-1"
93+ select-none
94+ :title =" rule.description"
95+ class =" cursor-pointer module-type-filter"
96+ >
97+ <input
98+ type =" checkbox"
99+ mr1
100+ :checked =" filterModuleTypes?.includes(rule.name)"
101+ @change =" toggleModuleType(rule)"
102+ >
103+ <div :class =" rule.icon" icon-catppuccin />
104+ <div text-sm >{{ rule.description || rule.name }}</div >
105+ </label >
106+ </div >
107+ </template >
108+ </VMenu >
109+ </button >
110+ </div >
111+ <div v-if =" selectedFields.includes('startTime')" role =" columnheader" rounded-tr-2 bg-base flex-none min-w52 ws-nowrap p1 text-center font-600 >
112+ Start Time
113+ </div >
114+ <div v-if =" selectedFields.includes('endTime')" role =" columnheader" rounded-tr-2 bg-base flex-none min-w52 ws-nowrap p1 text-center font-600 >
115+ End Time
116+ </div >
117+ <div v-if =" selectedFields.includes('duration')" role =" columnheader" rounded-tr-2 bg-base flex-none ws-nowrap p1 text-center font-600 w-27 >
118+ <button flex =" ~ row gap1 items-center justify-center" w-full @click =" toggleDurationSortType" >
119+ Duration
120+ <span w-6 h-6 rounded-full cursor-pointer hover =" bg-active" flex =" ~ items-center justify-center" >
121+ <i text-xs :class =" [durationSortType !== 'asc' ? 'i-carbon-arrow-down' : 'i-carbon-arrow-up', durationSortType ? 'op100 text-primary' : 'op50']" />
122+ </span >
123+ </button >
124+ </div >
125+ </div >
126+
127+ <DataVirtualList
128+ v-if =" filtered.length && selectedFields.length"
129+ role =" rowgroup"
130+ :items =" filtered"
131+ key-prop =" id"
132+ >
133+ <template #default =" { item , index } " >
134+ <div
135+ role =" row"
136+ flex =" ~ row"
137+ class =" border-base border-b-1 border-dashed"
138+ :class =" [index === filtered.length - 1 ? 'border-b-0' : '']"
139+ >
140+ <div v-if =" selectedFields.includes('hookName')" role =" cell" flex =" ~ items-center justify-center" flex-none w32 ws-nowrap text-sm op80 >
141+ {{ HOOK_NAME_MAP[item.type] }}
142+ </div >
143+ <div v-if =" selectedFields.includes('module')" role =" cell" flex-1 min-w100 text-left text-ellipsis line-clamp-2 >
144+ <DisplayModuleId
145+ :id =" item.module"
146+ w-full border-none
147+ :session =" session"
148+ :link =" `/session/${session.id}/graph?module=${item.module}`"
149+ hover =" bg-active"
150+ border =" ~ base rounded" block px2 py1
151+ />
159152 </div >
160- </td >
161- </tr >
162- </tbody >
163- </table >
153+ <div v-if =" selectedFields.includes('startTime')" role =" cell" flex =" ~ items-center justify-center" flex-none text-center font-mono text-sm min-w52 op80 >
154+ <time v-if =" item.timestamp_start" :datetime =" new Date(item.timestamp_start).toISOString()" >{{ normalizeTimestamp(item.timestamp_start) }}</time >
155+ </div >
156+ <div v-if =" selectedFields.includes('endTime')" role =" cell" flex =" ~ items-center justify-center" flex-none text-center font-mono text-sm min-w52 op80 >
157+ <time v-if =" item.timestamp_end" :datetime =" new Date(item.timestamp_end).toISOString()" >{{ normalizeTimestamp(item.timestamp_end) }}</time >
158+ </div >
159+ <div v-if =" selectedFields.includes('duration')" role =" cell" flex =" ~ items-center justify-center" flex-none text-center text-sm w-27 >
160+ <DisplayDuration :duration =" item.duration" />
161+ </div >
162+ </div >
163+ </template >
164+ </DataVirtualList >
165+ <div v-else >
166+ <div p4 >
167+ <div w-full h-48 flex =" ~ items-center justify-center" op50 italic >
168+ <p v-if =" !selectedFields.length" >
169+ No columns selected
170+ </p >
171+ <p v-else >
172+ No data
173+ </p >
174+ </div >
175+ </div >
176+ </div >
177+ </div >
164178</template >
0 commit comments