Spaces:
Running
Running
Add horizontal scrolling to AgentTable with frozen columns and better layout
Browse files
src/components/AgentTable.vue
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
<template>
|
| 2 |
-
<DataTable :value="rows" :rows="10" :rowsPerPageOptions="[10,25,50]" paginator scrollable scrollHeight="flex" :loading="loading" :sortMode="'multiple'" :multiSortMeta="multiSortMeta" v-model:expandedRows="expandedRows" :dataKey="'key'" @sort="onSort" @rowToggle="onRowToggle" @rowExpand="onRowExpand" :selection="selection" @update:selection="onSelectionUpdate">
|
| 3 |
-
<Column v-if="selectable" selectionMode="multiple" style="width:
|
| 4 |
-
<Column expander style="width:
|
| 5 |
-
<Column field="agent_name" header="Agent & Model
|
| 6 |
<template #body="{ data }">
|
| 7 |
<div>
|
| 8 |
<div style="display: flex; align-items: center; gap: 0.5rem;">
|
|
@@ -15,7 +15,7 @@
|
|
| 15 |
</template>
|
| 16 |
</Column>
|
| 17 |
<!-- <Column field="asset" header="Asset"/> -->
|
| 18 |
-
<Column field="ret_with_fees" header="Return" sortable>
|
| 19 |
<template #body="{ data }">
|
| 20 |
<div>
|
| 21 |
<div :style="pctStyle(data.ret_with_fees)">{{ fmtSignedPct(data.ret_with_fees) }}</div>
|
|
@@ -24,19 +24,19 @@
|
|
| 24 |
</template>
|
| 25 |
</Column>
|
| 26 |
|
| 27 |
-
<Column field="vs_bh_with_fees" header="Vs Buy & Hold" sortable>
|
| 28 |
<template #body="{ data }">
|
| 29 |
<span :style="pctStyle(data.vs_bh_with_fees)">{{ fmtSignedPct(data.vs_bh_with_fees) }}</span>
|
| 30 |
</template>
|
| 31 |
</Column>
|
| 32 |
|
| 33 |
-
<Column field="sharpe" header="Sharpe Ratio" sortable>
|
| 34 |
<template #body="{ data }">
|
| 35 |
{{ fmtNum(data.sharpe) }}
|
| 36 |
</template>
|
| 37 |
</Column>
|
| 38 |
|
| 39 |
-
<Column field="win_rate" header="Win Rate" sortable>
|
| 40 |
<template #body="{ data }">
|
| 41 |
{{ fmtPctNeutral(data.win_rate) }}
|
| 42 |
</template>
|
|
@@ -151,6 +151,43 @@ export default {
|
|
| 151 |
</script>
|
| 152 |
|
| 153 |
<style scoped>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
</style>
|
| 155 |
|
| 156 |
|
|
|
|
| 1 |
<template>
|
| 2 |
+
<DataTable :value="rows" :rows="10" :rowsPerPageOptions="[10,25,50]" paginator scrollable scrollHeight="flex" :loading="loading" :sortMode="'multiple'" :multiSortMeta="multiSortMeta" v-model:expandedRows="expandedRows" :dataKey="'key'" @sort="onSort" @rowToggle="onRowToggle" @rowExpand="onRowExpand" :selection="selection" @update:selection="onSelectionUpdate" class="agent-table-scroll">
|
| 3 |
+
<Column v-if="selectable" selectionMode="multiple" :style="{ width: '50px', minWidth: '50px' }" frozen />
|
| 4 |
+
<Column expander :style="{ width: '50px', minWidth: '50px' }" frozen />
|
| 5 |
+
<Column field="agent_name" header="Agent & Model" :style="{ minWidth: '200px' }" frozen>
|
| 6 |
<template #body="{ data }">
|
| 7 |
<div>
|
| 8 |
<div style="display: flex; align-items: center; gap: 0.5rem;">
|
|
|
|
| 15 |
</template>
|
| 16 |
</Column>
|
| 17 |
<!-- <Column field="asset" header="Asset"/> -->
|
| 18 |
+
<Column field="ret_with_fees" header="Return" sortable :style="{ minWidth: '180px' }">
|
| 19 |
<template #body="{ data }">
|
| 20 |
<div>
|
| 21 |
<div :style="pctStyle(data.ret_with_fees)">{{ fmtSignedPct(data.ret_with_fees) }}</div>
|
|
|
|
| 24 |
</template>
|
| 25 |
</Column>
|
| 26 |
|
| 27 |
+
<Column field="vs_bh_with_fees" header="Vs Buy & Hold" sortable :style="{ minWidth: '140px' }">
|
| 28 |
<template #body="{ data }">
|
| 29 |
<span :style="pctStyle(data.vs_bh_with_fees)">{{ fmtSignedPct(data.vs_bh_with_fees) }}</span>
|
| 30 |
</template>
|
| 31 |
</Column>
|
| 32 |
|
| 33 |
+
<Column field="sharpe" header="Sharpe Ratio" sortable :style="{ minWidth: '120px' }">
|
| 34 |
<template #body="{ data }">
|
| 35 |
{{ fmtNum(data.sharpe) }}
|
| 36 |
</template>
|
| 37 |
</Column>
|
| 38 |
|
| 39 |
+
<Column field="win_rate" header="Win Rate" sortable :style="{ minWidth: '110px' }">
|
| 40 |
<template #body="{ data }">
|
| 41 |
{{ fmtPctNeutral(data.win_rate) }}
|
| 42 |
</template>
|
|
|
|
| 151 |
</script>
|
| 152 |
|
| 153 |
<style scoped>
|
| 154 |
+
/* Enable horizontal scrolling */
|
| 155 |
+
:deep(.agent-table-scroll .p-datatable-wrapper) {
|
| 156 |
+
overflow-x: auto;
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
:deep(.agent-table-scroll .p-datatable-table) {
|
| 160 |
+
min-width: 800px;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
/* Frozen column styles */
|
| 164 |
+
:deep(.agent-table-scroll .p-frozen-column) {
|
| 165 |
+
background: #ffffff;
|
| 166 |
+
z-index: 1;
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
:deep(.agent-table-scroll .p-datatable-thead > tr > th.p-frozen-column) {
|
| 170 |
+
background: #F6F8FB;
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
/* Better scrollbar */
|
| 174 |
+
:deep(.agent-table-scroll .p-datatable-wrapper)::-webkit-scrollbar {
|
| 175 |
+
height: 8px;
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
:deep(.agent-table-scroll .p-datatable-wrapper)::-webkit-scrollbar-track {
|
| 179 |
+
background: #f1f1f1;
|
| 180 |
+
border-radius: 4px;
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
:deep(.agent-table-scroll .p-datatable-wrapper)::-webkit-scrollbar-thumb {
|
| 184 |
+
background: #cbd5e1;
|
| 185 |
+
border-radius: 4px;
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
:deep(.agent-table-scroll .p-datatable-wrapper)::-webkit-scrollbar-thumb:hover {
|
| 189 |
+
background: #94a3b8;
|
| 190 |
+
}
|
| 191 |
</style>
|
| 192 |
|
| 193 |
|