Keep project actions inline on mobile

Update the Projects modal card layout so edit/delete and activation controls stay beside the project title on narrow viewports. Add truncation for long project titles and paths, collapse activate/deactivate labels on phones, and preserve desktop spacing while preventing horizontal overflow.

Alessandro committed Jun 23, 2026 at 12:40 UTC 2f847f525e30bb7be689727bd87a36898662f24a
1 file changed +92 -31
webui/components/projects/project-list.html
+92 -31
@@ -37,34 +37,36 @@
37
38 <template :key="project.name" x-for="project in $store.projects.projectList">
39 <div class="projects-project-card" :class="{ 'projects-active': project.name === $store.chats.selectedContext?.project?.name }">
40 - <div class="projects-project-card-header" style="display: flex; align-items: start; justify-content: space-between; gap: 1em;">
41 - <div>
42 - <div class="projects-project-card-title">
43 - <span class="project-color-ball" :style="project.color ? { backgroundColor: project.color } : { border: '1px solid var(--color-border)' }"></span>
44 - <span x-text="project.title"></span>
45 - </div>
46 - <div class="projects-project-card-name">/<span x-text="project.name"></span></div>
47 - </div>
48 - <div class="projects-project-card-actions" style="display: flex; gap: 0.5em;">
49 - <template x-if="$store.chats.selectedContext && project.name === $store.chats.selectedContext?.project?.name">
50 - <button type="button" class="button cancel" title="Deactivate" style="width:9em" @click="$store.projects.deactivateProject()">
51 - <span class="icon material-symbols-outlined">close</span> Deactivate
52 - </button>
53 - </template>
54 - <template x-if="$store.chats.selectedContext && project.name !== $store.chats.selectedContext?.project?.name">
55 - <button type="button" class="button confirm" title="Activate" style="width:9em" @click="$store.projects.activateProject(project.name)">
56 - <span class="icon material-symbols-outlined">play_arrow</span> Activate
57 - </button>
58 - </template>
59 - <button type="button" class="button icon-button" title="Edit" @click="$store.projects.openEditModal(project.name)">
60 - <span class="icon material-symbols-outlined">edit</span>
61 - </button>
62 - <button type="button" class="button cancel icon-button" title="Delete" @click="$confirmClick($event, () => $store.projects.deleteProject(project.name))">
63 - <span class="icon material-symbols-outlined">delete</span>
64 - </button>
65 - </div>
66 -</div>
67 -<!-- <div class="projects-project-card-description"><span x-text="project.description"></span></div> -->
40 + <div class="projects-project-card-header">
41 + <div class="projects-project-card-info">
42 + <div class="projects-project-card-title">
43 + <span class="project-color-ball" :style="project.color ? { backgroundColor: project.color } : { border: '1px solid var(--color-border)' }"></span>
44 + <span class="projects-project-card-title-text" x-text="project.title"></span>
45 + </div>
46 + <div class="projects-project-card-name">/<span x-text="project.name"></span></div>
47 + </div>
48 + <div class="projects-project-card-actions">
49 + <template x-if="$store.chats.selectedContext && project.name === $store.chats.selectedContext?.project?.name">
50 + <button type="button" class="button cancel projects-project-card-state-action" title="Deactivate" @click="$store.projects.deactivateProject()">
51 + <span class="icon material-symbols-outlined">close</span>
52 + <span class="projects-project-card-action-text">Deactivate</span>
53 + </button>
54 + </template>
55 + <template x-if="$store.chats.selectedContext && project.name !== $store.chats.selectedContext?.project?.name">
56 + <button type="button" class="button confirm projects-project-card-state-action" title="Activate" @click="$store.projects.activateProject(project.name)">
57 + <span class="icon material-symbols-outlined">play_arrow</span>
58 + <span class="projects-project-card-action-text">Activate</span>
59 + </button>
60 + </template>
61 + <button type="button" class="button icon-button" title="Edit" @click="$store.projects.openEditModal(project.name)">
62 + <span class="icon material-symbols-outlined">edit</span>
63 + </button>
64 + <button type="button" class="button cancel icon-button" title="Delete" @click="$confirmClick($event, () => $store.projects.deleteProject(project.name))">
65 + <span class="icon material-symbols-outlined">delete</span>
66 + </button>
67 + </div>
68 + </div>
69 + <!-- <div class="projects-project-card-description"><span x-text="project.description"></span></div> -->
70 </div>
71 </template>
72
@@ -94,14 +96,52 @@
96 border-color: var(--color-highlight);
97 }
98
99 + .projects-project-card-header {
100 + display: flex;
101 + align-items: flex-start;
102 + justify-content: space-between;
103 + gap: 1em;
104 + }
105 +
106 + .projects-project-card-info {
107 + min-width: 0;
108 + flex: 1 1 auto;
109 + }
110 +
111 .projects-project-card-title {
112 font-weight: bold;
113 font-size: 1.2em;
114 display: flex;
115 align-items: center;
116 + min-width: 0;
117 + line-height: 1.25;
118 }
119 +
120 + .projects-project-card-title-text {
121 + min-width: 0;
122 + overflow: hidden;
123 + text-overflow: ellipsis;
124 + white-space: nowrap;
125 + }
126 +
127 .projects-project-card-name {
128 margin-top: var(--spacing-xs);
129 + min-width: 0;
130 + overflow: hidden;
131 + text-overflow: ellipsis;
132 + white-space: nowrap;
133 + }
134 +
135 + .projects-project-card-actions {
136 + display: flex;
137 + align-items: center;
138 + gap: 0.5em;
139 + flex: 0 0 auto;
140 + }
141 +
142 + .projects-project-card-state-action {
143 + gap: 0.35em;
144 + min-width: 9em;
145 }
146
147 .project-color-ball {
@@ -162,14 +202,35 @@
202 flex-wrap: wrap;
203 gap: 1em;
204 }
205 +
206 .projects-project-card-header {
166 - flex-direction: column;
167 - gap: 1em;
207 + flex-direction: row;
208 + gap: 0.75em;
209 + }
210 +
211 + .projects-project-card-title {
212 + font-size: 1.1em;
213 }
214 +
215 + .projects-project-card-actions {
216 + gap: 0.4em;
217 + padding-top: 0.08em;
218 + }
219 +
220 + .projects-project-card-state-action {
221 + min-width: 2.75rem;
222 + padding-left: 0.75rem;
223 + padding-right: 0.75rem;
224 + }
225 +
226 + .projects-project-card-action-text {
227 + display: none;
228 + }
229 +
230 .active-project-display {
231 width: 100%;
232 justify-content: space-between;
233 }
234 }
235 </style>
175 -</html>
\ No newline at end of file
236 +</html>