chats and tasks lists polishing
frdel committed
Nov 4, 2025 at 14:15 UTC
d96d13d24e63b407dad2c8b9a672f55c6b49581f
3 files changed
+66
-26
webui/components/sidebar/chats/chats-list.html
+13
-17
@@ -14,10 +14,9 @@
14
<ul class="config-list chats-config-list" x-show="$store.chats.contexts.length > 0">
15
<template x-for="context in $store.chats.contexts" :key="context.id">
16
<li>
17
- <div :class="{'chat-container': true, 'chat-selected': context.id === $store.chats.selected}">
18
- <div class="chat-stripe" :style="'background-color: ' + (context.project?.color || 'transparent')">
19
- </div>
20
- <div class="chat-list-button" @click="$store.chats.selectChat(context.id)">
17
+ <div :class="{'chat-container': true, 'chat-selected': context.id === $store.chats.selected}" @click="$store.chats.selectChat(context.id)">
18
+ <div class="chat-list-button">
19
+ <span class="project-color-ball" :style="context.project?.color ? { backgroundColor: context.project.color } : { border: '1px solid var(--color-border)' }"></span>
20
<span class="chat-name" :title="context.name ? context.name : 'Chat #' + context.no"
21
x-text="context.name ? context.name : 'Chat #' + context.no"></span>
22
</div>
@@ -69,7 +68,6 @@
68
69
.chat-container {
70
position: relative;
72
- /* Anchor for the stripe */
71
display: flex;
72
align-items: center;
73
justify-content: space-between;
@@ -78,7 +76,7 @@
76
border-radius: 4px;
77
transition: background-color 0.2s ease-in-out;
78
overflow: hidden;
81
- /* Important for containing the stripe's corners */
79
+ cursor: pointer;
80
}
81
82
.chat-container:hover {
@@ -89,20 +87,18 @@
87
display: flex;
88
align-items: center;
89
flex-grow: 1;
92
- cursor: pointer;
93
- padding: 8px 8px 8px 10px;
94
- /* Top/Right/Bottom/Left - Left padding for stripe */
90
+ padding: 8px;
91
overflow: hidden;
92
+ gap: 0.5em;
93
}
94
98
- .chat-stripe {
99
- position: absolute;
100
- left: 0;
101
- top: 0;
102
- width: 5px;
103
- height: 100%;
104
- border-radius: 0;
105
- /* No rounded corners */
95
+ .project-color-ball {
96
+ width: 0.6em;
97
+ height: 0.6em;
98
+ border-radius: 50%;
99
+ display: inline-block;
100
+ box-sizing: border-box;
101
+ flex-shrink: 0;
102
}
103
104
.chat-name {
webui/components/sidebar/chats/chats-store.js
+3
@@ -11,6 +11,7 @@ import {
11
getConnectionStatus,
12
} from "/index.js";
13
import { store as notificationStore } from "/components/notifications/notification-store.js";
14
+import { store as tasksStore } from "/components/sidebar/tasks/tasks-store.js";
15
16
const model = {
17
contexts: [],
@@ -272,6 +273,8 @@ const model = {
273
setSelected(contextId) {
274
this.selected = contextId;
275
this.selectedContext = this.contexts.find((ctx) => ctx.id === contextId);
276
+ // if not found in contexts, try to find in tasks < not nice, will need refactor later
277
+ if(!this.selectedContext) this.selectedContext = tasksStore.tasks.find((ctx) => ctx.id === contextId);
278
localStorage.setItem("lastSelectedChat", contextId);
279
},
280
webui/components/sidebar/tasks/tasks-list.html
+50
-9
@@ -24,13 +24,16 @@
24
<ul class="config-list tasks-config-list" x-show="$store.tasks.tasks.length > 0">
25
<template x-for="task in $store.tasks.tasks" :key="task.id">
26
<li>
27
- <div :class="{'chat-list-button': true, 'font-bold': task.id === $store.tasks.selected, 'has-task-container': true}"
28
- @click="$store.tasks.selectTask(task.id)">
29
- <div class="task-container task-container-vertical">
30
- <span class="task-name"
31
- :title="(task.task_name || `Task #${task.no}`) + ' (' + (task.name || `Chat #${task.no}`) + ')'"
32
- x-text="(task.task_name || `Task #${task.no}`) + ' (' + (task.name || `Chat #${task.no}`) + ')'"
27
+ <div class="task-container" :class="{'task-selected': task.id === $store.tasks.selected}">
28
+ <div class="chat-list-button" @click="$store.tasks.selectTask(task.id)">
29
+ <div class="task-container-vertical">
30
+ <div class="task-title-line">
31
+ <span class="project-color-ball" :style="task.project?.color ? { backgroundColor: task.project.color } : { border: '1px solid var(--color-border)' }"></span>
32
+ <span class="task-name"
33
+ :title="(task.task_name || `Task #${task.no}`)"
34
+ x-text="(task.task_name || `Task #${task.no}`)"
35
:data-task-id="task.id"></span>
36
+ </div>
37
<div class="task-info-line">
38
<span class="scheduler-status-badge scheduler-status-badge-small"
39
:class="task.state ? `scheduler-status-${task.state}` : 'scheduler-status-idle'"
@@ -50,6 +53,7 @@
53
</button>
54
<button class="edit-button" title="Delete task" @click.stop="$store.tasks.deleteTask(task.id)">X</button>
55
</div>
56
+ </div>
57
</div>
58
</div>
59
</li>
@@ -115,13 +119,50 @@
119
height: 0;
120
}
121
118
- .task-name { display: block; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 3px 0; margin-left: 10px; cursor: pointer; border-radius: 4px; transition: background-color 0.2s; font-size: var(--font-size-small); margin-bottom: 2px; }
119
- .task-name:hover { background-color: rgba(255,255,255,0.1); text-decoration: none; }
122
+ .task-title-line {
123
+ display: flex;
124
+ align-items: center;
125
+ gap: 0.5em;
126
+ }
127
+
128
+ .project-color-ball {
129
+ width: 0.6em;
130
+ height: 0.6em;
131
+ border-radius: 50%;
132
+ display: inline-block;
133
+ box-sizing: border-box;
134
+ flex-shrink: 0;
135
+ }
136
+
137
+ .task-name { display: block; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 3px 0; cursor: pointer; border-radius: 4px; transition: background-color 0.2s; font-size: var(--font-size-small); margin-bottom: 2px; }
138
.light-mode .task-name:hover { background-color: rgba(0,0,0,0.05); }
139
122
- .task-info-line { display: flex; justify-content: space-between; align-items: center; width: 100%; margin-top: 2px; margin-left: 5px; }
140
+ .task-info-line { display: flex; justify-content: space-between; align-items: center; width: 100%; margin-top: 2px; }
141
142
+ .task-container {
143
+ width: 100%;
144
+ display: flex;
145
+ align-items: stretch;
146
+ position: relative;
147
+ border-radius: 4px;
148
+ overflow: hidden;
149
+ }
150
+
151
+ .task-container:hover {
152
+ background-color: rgba(255, 255, 255, 0.03);
153
+ }
154
+
155
+
156
.task-container-vertical { display: flex; flex-direction: column; width: 100%; gap: 6px; }
157
+
158
+ /* Selected task accent */
159
+ .task-selected {
160
+ background-color: rgba(var(--color-border-rgb, 50, 50, 50), 0.5);
161
+ }
162
+
163
+ .task-selected .task-name {
164
+ font-weight: bold;
165
+ }
166
167
/* Scheduler badges (subset used in sidebar) */
168
.scheduler-status-badge { display: inline-block; padding: 4px 8px; border-radius: 4px; font-size: 12px; font-weight: 500; text-transform: capitalize; white-space: nowrap; }