@@ -82,108 +82,119 @@ function toggleDurationSortType() {
8282 </script >
8383
8484<template >
85- <div role =" table" min-w-max >
86- <div role =" row" class =" sticky top-0 z10 border-b border-base" flex =" ~ row" >
87- <div v-if =" selectedFields.includes('hookName')" role =" columnheader" bg-base flex-none w32 ws-nowrap p1 text-center font-600 >
88- Hook name
89- </div >
90- <div v-if =" selectedFields.includes('module')" role =" columnheader" bg-base flex-1 min-w100 ws-nowrap p1 text-left font-600 >
91- <button flex =" ~ row gap1 items-center" w-full >
92- Module
93- <VMenu >
85+ <DataVirtualList
86+ v-if =" filtered.length && selectedFields.length"
87+ class =" plugin-details-table"
88+ role =" table"
89+ min-w-max h-full min-h-0
90+ :items =" filtered"
91+ key-prop =" id"
92+ :page-mode =" false"
93+ >
94+ <template #before >
95+ <div role =" row" class =" border-b border-base bg-base" flex =" ~ row" >
96+ <div v-if =" selectedFields.includes('hookName')" role =" columnheader" bg-base flex-none w32 ws-nowrap p1 text-center font-600 >
97+ Hook name
98+ </div >
99+ <div v-if =" selectedFields.includes('module')" role =" columnheader" bg-base flex-1 min-w100 ws-nowrap p1 text-left font-600 >
100+ <button flex =" ~ row gap1 items-center" w-full >
101+ Module
102+ <VMenu >
103+ <span w-6 h-6 rounded-full cursor-pointer hover =" bg-active" flex =" ~ items-center justify-center" >
104+ <i text-xs class =" i-ph-funnel-duotone" :class =" filterModuleTypes.length !== searchFilterTypes.length ? 'text-primary op100' : 'op50'" />
105+ </span >
106+ <template #popper >
107+ <div class =" p2" flex =" ~ col gap2" >
108+ <label
109+ v-for =" rule of searchFilterTypes"
110+ :key =" rule.name"
111+ border =" ~ base rounded-md" px2 py1
112+ flex =" ~ items-center gap-1"
113+ select-none
114+ :title =" rule.description"
115+ class =" cursor-pointer module-type-filter"
116+ >
117+ <input
118+ type =" checkbox"
119+ mr1
120+ :checked =" filterModuleTypes?.includes(rule.name)"
121+ @change =" toggleModuleType(rule)"
122+ >
123+ <div :class =" rule.icon" icon-catppuccin />
124+ <div text-sm >{{ rule.description || rule.name }}</div >
125+ </label >
126+ </div >
127+ </template >
128+ </VMenu >
129+ </button >
130+ </div >
131+ <div v-if =" selectedFields.includes('duration')" role =" columnheader" rounded-tr-2 bg-base flex-none ws-nowrap p1 text-center font-600 w-27 >
132+ <button flex =" ~ row gap1 items-center justify-center" w-full @click =" toggleDurationSortType" >
133+ Duration
94134 <span w-6 h-6 rounded-full cursor-pointer hover =" bg-active" flex =" ~ items-center justify-center" >
95- <i text-xs class =" i-ph-funnel- duotone" :class = " filterModuleTypes.length !== searchFilterTypes.length ? 'text-primary op100 ' : 'op50'" />
135+ <i text-xs : class =" [durationSortType !== 'asc' ? ' i-ph-arrow-down- duotone' : 'i-ph-arrow-up-duotone', durationSortType ? 'op100 text-primary' : 'op50'] " />
96136 </span >
97- <template #popper >
98- <div class =" p2" flex =" ~ col gap2" >
99- <label
100- v-for =" rule of searchFilterTypes"
101- :key =" rule.name"
102- border =" ~ base rounded-md" px2 py1
103- flex =" ~ items-center gap-1"
104- select-none
105- :title =" rule.description"
106- class =" cursor-pointer module-type-filter"
107- >
108- <input
109- type =" checkbox"
110- mr1
111- :checked =" filterModuleTypes?.includes(rule.name)"
112- @change =" toggleModuleType(rule)"
113- >
114- <div :class =" rule.icon" icon-catppuccin />
115- <div text-sm >{{ rule.description || rule.name }}</div >
116- </label >
117- </div >
118- </template >
119- </VMenu >
120- </button >
121- </div >
122- <div v-if =" selectedFields.includes('duration')" role =" columnheader" rounded-tr-2 bg-base flex-none ws-nowrap p1 text-center font-600 w-27 >
123- <button flex =" ~ row gap1 items-center justify-center" w-full @click =" toggleDurationSortType" >
124- Duration
125- <span w-6 h-6 rounded-full cursor-pointer hover =" bg-active" flex =" ~ items-center justify-center" >
126- <i text-xs :class =" [durationSortType !== 'asc' ? 'i-ph-arrow-down-duotone' : 'i-ph-arrow-up-duotone', durationSortType ? 'op100 text-primary' : 'op50']" />
127- </span >
128- </button >
129- </div >
130- <div v-if =" selectedFields.includes('startTime')" role =" columnheader" rounded-tr-2 bg-base flex-none min-w52 ws-nowrap p1 text-center font-600 >
131- Start Time
132- </div >
133- <div v-if =" selectedFields.includes('endTime')" role =" columnheader" rounded-tr-2 bg-base flex-none min-w52 ws-nowrap p1 text-center font-600 >
134- End Time
137+ </button >
138+ </div >
139+ <div v-if =" selectedFields.includes('startTime')" role =" columnheader" rounded-tr-2 bg-base flex-none min-w52 ws-nowrap p1 text-center font-600 >
140+ Start Time
141+ </div >
142+ <div v-if =" selectedFields.includes('endTime')" role =" columnheader" rounded-tr-2 bg-base flex-none min-w52 ws-nowrap p1 text-center font-600 >
143+ End Time
144+ </div >
135145 </div >
136- </div >
146+ </template >
137147
138- <DataVirtualList
139- v-if =" filtered.length && selectedFields.length"
140- role =" rowgroup"
141- :items =" filtered"
142- key-prop =" id"
143- >
144- <template #default =" { item , index } " >
145- <div
146- role =" row"
147- flex =" ~ row"
148- class =" border-base border-b border-dashed"
149- :class =" [index === filtered.length - 1 ? 'border-b-0' : '']"
150- >
151- <div v-if =" selectedFields.includes('hookName')" role =" cell" flex =" ~ items-center justify-center" flex-none w32 ws-nowrap op80 >
152- <DisplayBadge :text =" HOOK_NAME_MAP[item.type]" />
153- </div >
154- <div v-if =" selectedFields.includes('module')" role =" cell" flex-1 min-w100 text-left text-ellipsis line-clamp-2 >
155- <DisplayModuleId
156- :id =" item.module"
157- w-full border-none ws-nowrap
158- :session =" session"
159- :link =" `/session/${session.id}/graph?module=${item.module}`"
160- hover =" bg-active"
161- border =" ~ base rounded" block px2 py1
162- />
163- </div >
164- <div v-if =" selectedFields.includes('duration')" role =" cell" flex =" ~ items-center justify-center" flex-none text-center text-sm w-27 >
165- <DisplayDuration :duration =" item.duration" />
166- </div >
167- <div v-if =" selectedFields.includes('startTime')" role =" cell" flex =" ~ items-center justify-center" flex-none text-center font-mono text-sm min-w52 op80 >
168- {{ normalizeTimestamp(item.timestamp_start) }}
169- </div >
170- <div v-if =" selectedFields.includes('endTime')" role =" cell" flex =" ~ items-center justify-center" flex-none text-center font-mono text-sm min-w52 op80 >
171- {{ normalizeTimestamp(item.timestamp_end) }}
172- </div >
148+ <template #default =" { item , index } " >
149+ <div
150+ role =" row"
151+ flex =" ~ row"
152+ class =" border-base border-b border-dashed"
153+ :class =" [index === filtered.length - 1 ? 'border-b-0' : '']"
154+ >
155+ <div v-if =" selectedFields.includes('hookName')" role =" cell" flex =" ~ items-center justify-center" flex-none w32 ws-nowrap op80 >
156+ <DisplayBadge :text =" HOOK_NAME_MAP[item.type]" />
157+ </div >
158+ <div v-if =" selectedFields.includes('module')" role =" cell" flex-1 min-w100 text-left text-ellipsis line-clamp-2 >
159+ <DisplayModuleId
160+ :id =" item.module"
161+ w-full border-none ws-nowrap
162+ :session =" session"
163+ :link =" `/session/${session.id}/graph?module=${item.module}`"
164+ hover =" bg-active"
165+ border =" ~ base rounded" block px2 py1
166+ />
167+ </div >
168+ <div v-if =" selectedFields.includes('duration')" role =" cell" flex =" ~ items-center justify-center" flex-none text-center text-sm w-27 >
169+ <DisplayDuration :duration =" item.duration" />
173170 </div >
174- </template >
175- </DataVirtualList >
176- <div v-else >
177- <div p4 >
178- <div w-full h-48 flex =" ~ items-center justify-center" op50 italic >
179- <p v-if =" !selectedFields.length" >
180- No columns selected
181- </p >
182- <p v-else >
183- No data
184- </p >
171+ <div v-if =" selectedFields.includes('startTime')" role =" cell" flex =" ~ items-center justify-center" flex-none text-center font-mono text-sm min-w52 op80 >
172+ {{ normalizeTimestamp(item.timestamp_start) }}
185173 </div >
174+ <div v-if =" selectedFields.includes('endTime')" role =" cell" flex =" ~ items-center justify-center" flex-none text-center font-mono text-sm min-w52 op80 >
175+ {{ normalizeTimestamp(item.timestamp_end) }}
176+ </div >
177+ </div >
178+ </template >
179+ </DataVirtualList >
180+ <div v-else role =" table" min-w-max h-full >
181+ <div p4 >
182+ <div w-full h-48 flex =" ~ items-center justify-center" op50 italic >
183+ <p v-if =" !selectedFields.length" >
184+ No columns selected
185+ </p >
186+ <p v-else >
187+ No data
188+ </p >
186189 </div >
187190 </div >
188191 </div >
189192</template >
193+
194+ <style scoped>
195+ .plugin-details-table :deep(.vue-recycle-scroller__slot ) {
196+ position : sticky ;
197+ top : 0 ;
198+ z-index : 10 ;
199+ }
200+ </style >
0 commit comments