fix for scheduler and memory dashboard style

3clyp50 committed Jan 2, 2026 at 10:59 UTC 98fe3e8be6db76ea3ac5d1bf540ba5a0cd713bfd
12 files changed +716 -760
webui/components/chat/input/bottom-actions.html
+15
@@ -4,6 +4,7 @@
4 import { store } from "/components/chat/input/input-store.js";
5 import { store as historyStore } from "/components/modals/history/history-store.js";
6 import { store as contextStore } from "/components/modals/context/context-store.js";
7 + import { store as chatsStore } from "/components/sidebar/chats/chats-store.js";
8 </script>
9 </head>
10 <body>
@@ -24,6 +25,20 @@
25 <span x-text="$store.chatInput.paused ? 'Resume Agent' : 'Pause Agent'"></span>
26 </button>
27
28 + <button class="text-button" @click="$store.chats.resetChat()">
29 + <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" width="14" height="14">
30 + <path d="M19.36 2.72l1.42 1.42-5.72 5.71c1.07 1.54 1.22 3.39.32 4.59L9.06 8.12c1.2-.9 3.05-.75 4.59.32l5.71-5.72M5.93 17.57c-2.01-2.01-3.24-4.41-3.58-6.65l4.88-2.09 7.44 7.44-2.09 4.88c-2.24-.34-4.64-1.57-6.65-3.58z"/>
31 + </svg>
32 + <p>Clear Chat</p>
33 + </button>
34 +
35 + <button class="text-button" @click="$store.chats.saveChat()">
36 + <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" width="14" height="14">
37 + <path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/>
38 + </svg>
39 + <p>Save Chat</p>
40 + </button>
41 +
42 <button class="text-button" @click="$store.chatInput.loadKnowledge()">
43 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
44 <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5m-13.5-9L12 3m0 0 4.5 4.5M12 3v13.5"></path>
webui/components/modals/memory/memory-dashboard.html
+9 -4
@@ -474,6 +474,11 @@
474 white-space: normal;
475 word-wrap: break-word;
476 }
477 + .preview-cell {
478 + overflow: visible;
479 + white-space: normal;
480 + word-wrap: break-word;
481 + }
482 .metadata-info {
483 display: flex;
484 flex-direction: column;
@@ -631,20 +636,20 @@
636 order: 5;
637 flex: auto;
638 width: 100%;
634 - height: 42px;
639 + min-height: 42px;
640 }
641 .btn-clear {
642 order: 6;
643 flex: 40%;
644 min-width: 80px;
645 padding: 0;
641 - height: 42px;
646 + min-height: 42px;
647 justify-content: center;
648 }
649 .btn-search {
650 order: 7;
651 flex: 40%;
647 - height: 42px;
652 + min-height: 42px;
653 padding: 0 1rem;
654 min-width: 80px;
655 }
@@ -654,7 +659,7 @@
659 }
660 .memory-filters-header .filter-group-inline select,
661 .memory-filters-header .filter-group-inline input {
657 - height: 42px;
662 + min-height: 42px;
663 font-size: 1rem;
664 }
665 .memory-filters-header .filter-group-inline.filter-limit {
webui/components/modals/scheduler/scheduler-modal.html
+29 -1
@@ -16,6 +16,26 @@
16 </div>
17 </div>
18 </template>
19 +
20 + <!-- Modal Footer (exists immediately so modals.js can move it) -->
21 + <template x-if="$store.schedulerStore">
22 + <div class="modal-footer scheduler-modal-footer" data-modal-footer
23 + x-show="$store.schedulerStore.isCreating || $store.schedulerStore.isEditing">
24 + <div class="buttons-container scheduler-modal-footer-actions">
25 + <div class="buttons-left">
26 + <button type="button" class="button cancel"
27 + x-show="$store.schedulerStore.isEditing"
28 + @click="$store.schedulerStore.deleteTask($store.schedulerStore.editingTask.uuid)">Delete</button>
29 + </div>
30 + <div class="buttons-right">
31 + <button type="button" class="button cancel"
32 + @click="$store.schedulerStore.cancelEdit()">Cancel</button>
33 + <button type="button" class="button confirm"
34 + @click="$store.schedulerStore.saveTask()">Save</button>
35 + </div>
36 + </div>
37 + </div>
38 + </template>
39 </div>
40
41 <style>
@@ -29,7 +49,15 @@
49 padding: 0;
50 }
51 .scheduler-dashboard-description {
32 - padding: 1rem 1rem;
52 + padding: 1rem 0;
53 + }
54 +
55 + .scheduler-modal-footer {
56 + padding: 0.6rem 1rem;
57 + }
58 +
59 + .scheduler-modal-footer-actions {
60 + width: 100%;
61 }
62 </style>
63 </body>
webui/components/modals/scheduler/scheduler-store.js
+9
@@ -904,6 +904,15 @@ const schedulerStoreModel = {
904 } ${task.schedule.month || "*"} ${task.schedule.weekday || "*"}`;
905 },
906
907 + formatTaskType(type) {
908 + const typeMap = {
909 + scheduled: "Scheduled",
910 + adhoc: "Ad-hoc",
911 + planned: "Planned",
912 + };
913 + return typeMap[type] || type;
914 + },
915 +
916 getStateBadgeClass(state) {
917 switch (state) {
918 case "idle":
webui/components/modals/scheduler/scheduler-task-detail.html
+41 -20
@@ -18,23 +18,18 @@
18 :class="$store.schedulerStore.selectedTaskForDetail ? $store.schedulerStore.getStateBadgeClass($store.schedulerStore.selectedTaskForDetail.state) : ''"
19 x-text="$store.schedulerStore.selectedTaskForDetail ? $store.schedulerStore.selectedTaskForDetail.state : ''"></div>
20 </div>
21 - <div class="scheduler-detail-header-actions">
22 - <button class="btn btn-action-header"
23 - @click="$store.schedulerStore.runTask($store.schedulerStore.selectedTaskForDetail.uuid)"
24 - title="Run Task">
25 - <span class="material-symbols-outlined">play_arrow</span>
26 - </button>
27 - <button class="btn btn-action-header"
28 - @click="$store.schedulerStore.editFromDetail()"
29 - title="Edit Task">
30 - <span class="material-symbols-outlined">edit</span>
31 - </button>
32 - <button class="btn btn-action-header danger"
33 - @click="$store.schedulerStore.deleteFromDetail()"
34 - title="Delete Task">
35 - <span class="material-symbols-outlined">delete</span>
36 - </button>
37 - <button class="btn btn-cancel" @click="$store.schedulerStore.closeTaskDetail()">Close</button>
21 + <div class="buttons-container scheduler-detail-actions">
22 + <div class="buttons-left">
23 + <button type="button" class="button cancel"
24 + @click="$store.schedulerStore.deleteFromDetail()">Delete</button>
25 + </div>
26 + <div class="buttons-right">
27 + <button type="button" class="button confirm"
28 + @click="$store.schedulerStore.editFromDetail()">Edit</button>
29 + <button type="button" class="button"
30 + @click="$store.schedulerStore.runTask($store.schedulerStore.selectedTaskForDetail.uuid)">Run</button>
31 +
32 + </div>
33 </div>
34 </div>
35
@@ -42,7 +37,7 @@
37 <div class="scheduler-details-grid">
38 <div class="scheduler-details-label">Type:</div>
39 <div class="scheduler-details-value"
45 - x-text="$store.schedulerStore.selectedTaskForDetail ? $store.schedulerStore.selectedTaskForDetail.type : ''"></div>
40 + x-text="$store.schedulerStore.selectedTaskForDetail ? $store.schedulerStore.formatTaskType($store.schedulerStore.selectedTaskForDetail.type) : ''"></div>
41
42 <div class="scheduler-details-label">Project:</div>
43 <div class="scheduler-details-value">
@@ -143,11 +138,37 @@
138 </div>
139 </div>
140 </template>
141 +
142 + <!-- Modal Footer (exists immediately so modals.js can move it) -->
143 + <template x-if="$store.schedulerStore">
144 + <div class="modal-footer scheduler-detail-footer" data-modal-footer>
145 + <div class="buttons-container scheduler-detail-footer-actions">
146 + <div class="buttons-left">
147 + <button type="button" class="button cancel"
148 + @click="$store.schedulerStore.deleteFromDetail()">Delete</button>
149 + </div>
150 + <div class="buttons-right">
151 + <button type="button" class="button confirm"
152 + @click="$store.schedulerStore.editFromDetail()">Edit</button>
153 + <button type="button" class="button"
154 + @click="$store.schedulerStore.runTask($store.schedulerStore.selectedTaskForDetail.uuid)">Run</button>
155 + </div>
156 + </div>
157 + </div>
158 + </template>
159 </div>
160
161 <style>
149 - .scheduler-detail-header-actions .btn-cancel {
150 - margin-left: var(--spacing-sm);
162 + .scheduler-detail-actions {
163 + width: 100%;
164 + }
165 +
166 + .scheduler-detail-footer {
167 + padding: 0.6rem 1rem;
168 + }
169 +
170 + .scheduler-detail-footer-actions {
171 + width: 100%;
172 }
173 </style>
174
webui/components/modals/scheduler/scheduler-task-editor.html
+40 -39
@@ -12,13 +12,14 @@
12 <div class="scheduler-form" x-show="$store.schedulerStore.isCreating">
13 <div class="scheduler-form-header">
14 <div class="scheduler-form-title">Create New Task</div>
15 - <div class="scheduler-form-actions">
16 - <button class="btn btn-action-header cancel" @click="$store.schedulerStore.cancelEdit()" title="Cancel">
17 - <span class="material-symbols-outlined">close</span>
18 - </button>
19 - <button class="btn btn-action-header confirm" @click="$store.schedulerStore.saveTask()" title="Save Task">
20 - <span class="material-symbols-outlined">check</span>
21 - </button>
15 + </div>
16 + <div class="buttons-container scheduler-editor-actions scheduler-editor-actions-top">
17 + <div class="buttons-left"></div>
18 + <div class="buttons-right">
19 + <button type="button" class="button cancel"
20 + @click="$store.schedulerStore.cancelEdit()">Cancel</button>
21 + <button type="button" class="button confirm"
22 + @click="$store.schedulerStore.saveTask()">Save</button>
23 </div>
24 </div>
25
@@ -70,22 +71,22 @@
71 <div class="scheduler-state-selector">
72 <span class="scheduler-status-badge scheduler-status-idle"
73 :class="{'scheduler-status-selected': $store.schedulerStore.editingTask.state === 'idle'}"
73 - @click="$store.schedulerStore.editingTask.state = 'idle'">idle</span>
74 + @click="$store.schedulerStore.editingTask.state = 'idle'">Idle</span>
75 <span class="scheduler-status-badge scheduler-status-running"
76 :class="{'scheduler-status-selected': $store.schedulerStore.editingTask.state === 'running'}"
76 - @click="$store.schedulerStore.editingTask.state = 'running'">running</span>
77 + @click="$store.schedulerStore.editingTask.state = 'running'">Running</span>
78 <span class="scheduler-status-badge scheduler-status-disabled"
79 :class="{'scheduler-status-selected': $store.schedulerStore.editingTask.state === 'disabled'}"
79 - @click="$store.schedulerStore.editingTask.state = 'disabled'">disabled</span>
80 + @click="$store.schedulerStore.editingTask.state = 'disabled'">Disabled</span>
81 <span class="scheduler-status-badge scheduler-status-error"
82 :class="{'scheduler-status-selected': $store.schedulerStore.editingTask.state === 'error'}"
82 - @click="$store.schedulerStore.editingTask.state = 'error'">error</span>
83 + @click="$store.schedulerStore.editingTask.state = 'error'">Error</span>
84 </div>
85 <div class="scheduler-state-explanation">
85 - <span x-show="$store.schedulerStore.editingTask.state === 'idle'"><strong>idle</strong>: ready to run</span>
86 - <span x-show="$store.schedulerStore.editingTask.state === 'running'"><strong>running</strong>: currently executing</span>
87 - <span x-show="$store.schedulerStore.editingTask.state === 'disabled'"><strong>disabled</strong>: won't execute automatically</span>
88 - <span x-show="$store.schedulerStore.editingTask.state === 'error'"><strong>error</strong>: task encountered an error</span>
86 + <span x-show="$store.schedulerStore.editingTask.state === 'idle'"><strong>Idle</strong>: Ready to run</span>
87 + <span x-show="$store.schedulerStore.editingTask.state === 'running'"><strong>Running</strong>: Currently executing</span>
88 + <span x-show="$store.schedulerStore.editingTask.state === 'disabled'"><strong>Disabled</strong>: Won't execute automatically</span>
89 + <span x-show="$store.schedulerStore.editingTask.state === 'error'"><strong>Error</strong>: Task encountered an error</span>
90 </div>
91 </div>
92 </div>
@@ -218,13 +219,17 @@
219 <div class="scheduler-form" x-show="$store.schedulerStore.isEditing">
220 <div class="scheduler-form-header">
221 <div class="scheduler-form-title">Edit Task</div>
221 - <div class="scheduler-form-actions">
222 - <button class="btn btn-action-header cancel" @click="$store.schedulerStore.cancelEdit()" title="Cancel">
223 - <span class="material-symbols-outlined">close</span>
224 - </button>
225 - <button class="btn btn-action-header confirm" @click="$store.schedulerStore.saveTask()" title="Save Task">
226 - <span class="material-symbols-outlined">check</span>
227 - </button>
222 + </div>
223 + <div class="buttons-container scheduler-editor-actions scheduler-editor-actions-top">
224 + <div class="buttons-left">
225 + <button type="button" class="button cancel"
226 + @click="$store.schedulerStore.deleteTask($store.schedulerStore.editingTask.uuid)">Delete</button>
227 + </div>
228 + <div class="buttons-right">
229 + <button type="button" class="button cancel"
230 + @click="$store.schedulerStore.cancelEdit()">Cancel</button>
231 + <button type="button" class="button confirm"
232 + @click="$store.schedulerStore.saveTask()">Save</button>
233 </div>
234 </div>
235
@@ -271,22 +276,22 @@
276 <div class="scheduler-state-selector">
277 <span class="scheduler-status-badge scheduler-status-idle"
278 :class="{'scheduler-status-selected': $store.schedulerStore.editingTask.state === 'idle'}"
274 - @click="$store.schedulerStore.editingTask.state = 'idle'">idle</span>
279 + @click="$store.schedulerStore.editingTask.state = 'idle'">Idle</span>
280 <span class="scheduler-status-badge scheduler-status-running"
281 :class="{'scheduler-status-selected': $store.schedulerStore.editingTask.state === 'running'}"
277 - @click="$store.schedulerStore.editingTask.state = 'running'">running</span>
282 + @click="$store.schedulerStore.editingTask.state = 'running'">Running</span>
283 <span class="scheduler-status-badge scheduler-status-disabled"
284 :class="{'scheduler-status-selected': $store.schedulerStore.editingTask.state === 'disabled'}"
280 - @click="$store.schedulerStore.editingTask.state = 'disabled'">disabled</span>
285 + @click="$store.schedulerStore.editingTask.state = 'disabled'">Disabled</span>
286 <span class="scheduler-status-badge scheduler-status-error"
287 :class="{'scheduler-status-selected': $store.schedulerStore.editingTask.state === 'error'}"
283 - @click="$store.schedulerStore.editingTask.state = 'error'">error</span>
288 + @click="$store.schedulerStore.editingTask.state = 'error'">Error</span>
289 </div>
290 <div class="scheduler-state-explanation">
286 - <span x-show="$store.schedulerStore.editingTask.state === 'idle'"><strong>idle</strong>: ready to run</span>
287 - <span x-show="$store.schedulerStore.editingTask.state === 'running'"><strong>running</strong>: currently executing</span>
288 - <span x-show="$store.schedulerStore.editingTask.state === 'disabled'"><strong>disabled</strong>: won't execute automatically</span>
289 - <span x-show="$store.schedulerStore.editingTask.state === 'error'"><strong>error</strong>: task encountered an error</span>
291 + <span x-show="$store.schedulerStore.editingTask.state === 'idle'"><strong>Idle</strong>: Ready to run</span>
292 + <span x-show="$store.schedulerStore.editingTask.state === 'running'"><strong>Running</strong>: Currently executing</span>
293 + <span x-show="$store.schedulerStore.editingTask.state === 'disabled'"><strong>Disabled</strong>: Won't execute automatically</span>
294 + <span x-show="$store.schedulerStore.editingTask.state === 'error'"><strong>Error</strong>: Task encountered an error</span>
295 </div>
296 </div>
297 </div>
@@ -419,15 +424,7 @@
424 </div>
425
426 <style>
422 - /* Form header with icon buttons - matches memory-detail-modal pattern */
423 - .scheduler-form-header {
424 - display: flex;
425 - justify-content: space-between;
426 - align-items: center;
427 - padding: 0.75rem 0;
428 - margin-bottom: 1rem;
429 - border-bottom: 1px solid var(--color-border);
430 - }
427 + /* Form header with Save/Cancel buttons - aligns with Projects pattern */
428
429 .scheduler-form-title {
430 font-size: 1.2rem;
@@ -440,6 +437,10 @@
437 gap: 0.5rem;
438 }
439
440 + .scheduler-editor-actions {
441 + margin: 0 0 1rem 0;
442 + }
443 +
444 /* Generate token button - extends .btn-action from buttons.css */
445 .btn-action.generate-token {
446 padding: 0.4rem 0.75rem;
webui/components/sidebar/chats/chats-list.html
+20 -2
@@ -10,7 +10,18 @@
10 <div x-data>
11 <template x-if="$store.chats">
12 <div class="chats-list-container" x-data>
13 - <h3 class="section-header">Chats</h3>
13 + <div class="section-header-row">
14 + <h3 class="section-header">Chats</h3>
15 + <!-- New Chat Button -->
16 + <button id="newChat" @click="$store.chats.newChat()" aria-label="New Chat">
17 + <svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 110 135" width="32" height="32">
18 + <path d="m38.3 81.3 3.2-9.1 3.1-9v-.1c0-.2.1-.3.2-.4.1-.2.2-.3.3-.4L82.4 25c1.6-1.6 3.7-2.4 5.7-2.4h.2c2 0 4 .8 5.6 2.4l3.7 3.7.1.2c1.5 1.6 2.2 3.6 2.2 5.6v.2c0 2-.8 4-2.4 5.6l-.1.1-3.8 3.6-.1.1-.1.1-32.9 33-.1.1q-.45.45-.9.6l-9.1 3.2h-.1l-9.1 3.1c-1.2.4-2.5-.2-2.9-1.4q-.3-.75 0-1.5m7.5-7.6-1.6 4.6 4.6-1.6 5.7-2-3.4-3.4-3.3-3.3zm4.2-9.9 4.3 4.3 4.3 4.3 30-30-8.6-8.5zm35.7-35.7-2.5 2.5 8.6 8.6 2.4-2.4.1-.1c.6-.6 1-1.5 1-2.3v-.1c0-.9-.3-1.8-1-2.4l-3.7-3.7c-.6-.6-1.5-1-2.3-1h-.1c-.9-.1-1.8.3-2.5.9m.4 44.1c0-1.3 1-2.3 2.3-2.3s2.3 1 2.3 2.3V101c0 3.2-1.3 6.1-3.4 8.2s-5 3.4-8.2 3.4H21.6c-3.2 0-6.1-1.3-8.2-3.4s-3.4-5-3.4-8.2V43.4c0-3.2 1.3-6.1 3.4-8.2s5-3.4 8.2-3.4h28.8c1.3 0 2.3 1 2.3 2.3s-1 2.3-2.3 2.3H21.6c-1.9 0-3.7.8-4.9 2-1.3 1.3-2 3-2 4.9v57.6c0 1.9.8 3.6 2 4.9 1.3 1.3 3 2 4.9 2h57.6c1.9 0 3.7-.8 4.9-2 1.3-1.3 2-3 2-4.9z" style="fill:currentColor"></path>
19 + </svg>
20 + </button>
21 + </div>
22 +
23 +
24 +
25 <ul class="config-list chats-config-list" x-show="$store.chats.contexts.length > 0">
26 <template x-for="context in $store.chats.contexts" :key="context.id">
27 <li>
@@ -35,13 +46,20 @@
46 </div>
47
48 <style>
38 - .chats-list-container .section-header {
49 + .chats-list-container .section-header-row {
50 + display: flex;
51 + align-items: center;
52 + justify-content: space-between;
53 position: sticky;
54 top: 0;
55 flex-shrink: 0;
56 z-index: 10;
57 }
58
59 + .chats-list-container .section-header {
60 + margin: 0;
61 + }
62 +
63 /* Chats list container and items */
64 .chats-list-container {
65 display: flex;
webui/components/sidebar/top-section/header-icons.html
-27
@@ -17,13 +17,6 @@
17 <img src="./public/splash.jpg" alt="a0" width="22" height="22">
18 </a>
19 </div>
20 -
21 - <!-- New Chat Button -->
22 - <button id="newChat" @click="$store.chats.newChat()" aria-label="New Chat">
23 - <svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 110 135" width="32" height="32">
24 - <path d="m38.3 81.3 3.2-9.1 3.1-9v-.1c0-.2.1-.3.2-.4.1-.2.2-.3.3-.4L82.4 25c1.6-1.6 3.7-2.4 5.7-2.4h.2c2 0 4 .8 5.6 2.4l3.7 3.7.1.2c1.5 1.6 2.2 3.6 2.2 5.6v.2c0 2-.8 4-2.4 5.6l-.1.1-3.8 3.6-.1.1-.1.1-32.9 33-.1.1q-.45.45-.9.6l-9.1 3.2h-.1l-9.1 3.1c-1.2.4-2.5-.2-2.9-1.4q-.3-.75 0-1.5m7.5-7.6-1.6 4.6 4.6-1.6 5.7-2-3.4-3.4-3.3-3.3zm4.2-9.9 4.3 4.3 4.3 4.3 30-30-8.6-8.5zm35.7-35.7-2.5 2.5 8.6 8.6 2.4-2.4.1-.1c.6-.6 1-1.5 1-2.3v-.1c0-.9-.3-1.8-1-2.4l-3.7-3.7c-.6-.6-1.5-1-2.3-1h-.1c-.9-.1-1.8.3-2.5.9m.4 44.1c0-1.3 1-2.3 2.3-2.3s2.3 1 2.3 2.3V101c0 3.2-1.3 6.1-3.4 8.2s-5 3.4-8.2 3.4H21.6c-3.2 0-6.1-1.3-8.2-3.4s-3.4-5-3.4-8.2V43.4c0-3.2 1.3-6.1 3.4-8.2s5-3.4 8.2-3.4h28.8c1.3 0 2.3 1 2.3 2.3s-1 2.3-2.3 2.3H21.6c-1.9 0-3.7.8-4.9 2-1.3 1.3-2 3-2 4.9v57.6c0 1.9.8 3.6 2 4.9 1.3 1.3 3 2 4.9 2h57.6c1.9 0 3.7-.8 4.9-2 1.3-1.3 2-3 2-4.9z" style="fill:currentColor"></path>
25 - </svg>
26 - </button>
20 </div>
21
22
@@ -72,26 +65,6 @@
65
66 .light-mode #logo-container img { -webkit-filter: invert(100%) grayscale(100%); filter: invert(100%) grayscale(100%); }
67
75 - /* New Chat Button */
76 - #newChat {
77 - display: flex;
78 - flex-wrap: nowrap;
79 - background-color: transparent;
80 - border: none;
81 - align-items: center;
82 - position: absolute;
83 - left: 12rem;
84 - top: var(--spacing-md);
85 - z-index: 1004;
86 - opacity: 0.6;
87 - cursor: pointer;
88 - -webkit-transition: all 0.1s ease-in-out, left var(--transition-speed) ease-in-out;
89 - transition: all 0.1s ease-in-out, left var(--transition-speed) ease-in-out;
90 - }
91 - #newChat:hover { opacity: 0.85; transform: scale(1.04); }
92 - #newChat:active { opacity: 0.5; transform: scale(0.98); }
93 - #newChat svg { color: var(--color-text); }
94 -
68 @media (max-width: 768px) {
69 .toggle-sidebar-button { position: fixed; left: var(--spacing-md); z-index: 1004; }
70 #logo-container { -webkit-transition: all 0.3s ease; transition: all 0.3s ease; z-index: 1004; }
webui/components/sidebar/top-section/quick-actions.html
+30 -5
@@ -2,7 +2,8 @@
2
3 <head>
4 <script type="module">
5 - import { store } from "/components/sidebar/chats/chats-store.js";
5 + import { store as chatsStore } from "/components/sidebar/chats/chats-store.js";
6 + import { store as projectsStore } from "/components/projects/projects-store.js";
7 </script>
8 </head>
9
@@ -11,7 +12,7 @@
12 <div id="quick-actions">
13 <!-- Dashboard -->
14 <button class="config-button" id="dashboard" @click="deselectChat()" title="Dashboard">
14 - <span class="material-symbols-outlined">dashboard</span>
15 + <span class="material-symbols-outlined">home</span>
16 </button>
17
18 <!-- Memory -->
@@ -42,9 +43,14 @@
43 <div class="dropdown-header">Navigation</div>
44
45 <button class="dropdown-item" @click="deselectChat(); dropdownOpen = false">
45 - <span class="material-symbols-outlined">dashboard</span>
46 + <span class="material-symbols-outlined">home</span>
47 <span>Dashboard</span>
48 </button>
49 +
50 + <button class="dropdown-item" @click="$store.projects.openProjectsModal(); dropdownOpen = false">
51 + <span class="material-symbols-outlined">snippet_folder</span>
52 + <span>Projects</span>
53 + </button>
54
55 <button class="dropdown-item" @click="openModal('modals/memory/memory-dashboard.html'); dropdownOpen = false">
56 <span class="material-symbols-outlined">psychology</span>
@@ -78,6 +84,11 @@
84 <span class="material-symbols-outlined">save</span>
85 <span>Save Chat</span>
86 </button>
87 +
88 + <button class="dropdown-item" @click="$store.chats.resetChat(); dropdownOpen = false">
89 + <span class="material-symbols-outlined">delete_sweep</span>
90 + <span>Clear Chat</span>
91 + </button>
92
93 <div class="dropdown-separator"></div>
94
@@ -94,9 +105,7 @@
105 /* Wrapper container for icon toolbar */
106 .wrapper {
107 position: relative;
97 - padding: 0.2rem;
108 border-radius: 0.6rem;
99 - background-color: var(--color-background);
109 }
110
111 /* Icon toolbar layout */
@@ -181,6 +190,22 @@
190 font-size: 18px;
191 }
192
193 + /* New Chat Button */
194 + #newChat {
195 + display: flex;
196 + flex-wrap: nowrap;
197 + background-color: transparent;
198 + border: none;
199 + align-items: center;
200 + opacity: 0.6;
201 + cursor: pointer;
202 + -webkit-transition: all 0.1s ease-in-out, left var(--transition-speed) ease-in-out;
203 + transition: all 0.1s ease-in-out, left var(--transition-speed) ease-in-out;
204 + }
205 + #newChat:hover { opacity: 0.85; transform: scale(1.04); }
206 + #newChat:active { opacity: 0.5; transform: scale(0.98); }
207 + #newChat svg { color: var(--color-text); }
208 +
209 /* Light mode */
210 .light-mode .config-button {
211 background-color: var(--color-background);
webui/css/modals.css
+1 -1
@@ -426,7 +426,7 @@ input[type="range"]::-moz-range-thumb {
426 flex-grow: 1;
427 }
428 .modal-footer {
429 - padding: var(--spacing-sm) 0 var(--spacing-sm) 0 !important;
429 + padding: var(--spacing-sm) !important;
430 }
431 .section {
432 margin-bottom: 1.5rem;
webui/css/scheduler.css
+516 -112
@@ -1,4 +1,9 @@
1 -/* Scheduler Status Badges */
1 +/* Scheduler Styles */
2 +
3 +/* ==========================================================================
4 + Status Badges
5 + ========================================================================== */
6 +
7 .scheduler-status-badge {
8 display: inline-block;
9 padding: 4px 8px;
@@ -34,13 +39,23 @@
39 border: 1px solid rgba(230, 57, 70, 0.3);
40 }
41
37 -/* Status badge selected state for editor */
42 +.scheduler-status-badge-small {
43 + font-size: 10px;
44 + padding: 2px 6px;
45 + margin-right: 5px;
46 + min-width: 40px;
47 + text-align: center;
48 +}
49 +
50 +/* Status badge selected state */
51 .scheduler-status-selected {
39 - outline: 2px solid var(--color-primary);
40 - outline-offset: 2px;
52 + opacity: 1 !important;
53 + box-shadow: 0 0 0 2px var(--color-bg), 0 0 0 4px var(--color-border);
54 + border: 1px solid var(--color-border) !important;
55 + outline: none;
56 }
57
43 -/* Light mode adjustments */
58 +/* Light mode status badges */
59 .light-mode .scheduler-status-idle {
60 background-color: rgba(42, 157, 143, 0.1);
61 color: #1a6f65;
@@ -61,151 +76,198 @@
76 color: #c5283d;
77 }
78
64 -/* Scheduler Form Styles */
65 -.scheduler-form {
66 - background-color: var(--color-bg-secondary);
67 - border-radius: 4px;
68 - padding: 20px;
69 - margin-bottom: 20px;
79 +.light-mode .scheduler-status-selected {
80 + box-shadow: 0 0 0 2px var(--color-bg-light), 0 0 0 4px var(--color-accent);
81 }
82
72 -.scheduler-form-grid {
73 - display: grid;
74 - grid-template-columns: 1fr 1fr;
75 - gap: 16px;
76 - margin-bottom: 20px;
83 +/* ==========================================================================
84 + Container & Layout
85 + ========================================================================== */
86 +
87 +.scheduler-container {
88 + width: 100%;
89 + box-sizing: border-box;
90 + display: block;
91 + padding: 0.5rem 0;
92 }
93
79 -.scheduler-form-field {
94 +.scheduler-loading {
95 + text-align: center;
96 + padding: 40px 0;
97 + color: var(--color-text-secondary);
98 +}
99 +
100 +.task-container-vertical {
101 display: flex;
102 flex-direction: column;
103 + width: 100%;
104 gap: 6px;
105 }
106
85 -.full-width {
86 - grid-column: 1 / -1;
107 +/* ==========================================================================
108 + Task List Table
109 + ========================================================================== */
110 +
111 +.scheduler-task-list {
112 + width: 100%;
113 + min-width: 100%;
114 + margin: 0;
115 + border-collapse: separate;
116 + border-spacing: 0;
117 + white-space: nowrap;
118 + padding-bottom: 8px;
119 + table-layout: fixed;
120 }
121
89 -.scheduler-form-label {
90 - font-weight: 500;
122 +.scheduler-task-list th,
123 +.scheduler-task-list td {
124 + padding: 8px 12px;
125 + text-align: left;
126 + vertical-align: middle;
127 + border-bottom: 1px solid var(--color-border);
128 }
129
93 -.scheduler-form-help {
94 - font-size: 12px;
95 - color: var(--color-text-secondary);
130 +/* Column styles */
131 +.scheduler-task-list .col-name {
132 + width: 30%;
133 + overflow: hidden;
134 + text-overflow: ellipsis;
135 }
136
98 -.label-help-wrapper {
99 - display: flex;
100 - flex-direction: column;
101 - gap: 2px;
137 +.scheduler-task-list .col-state {
138 + width: 12%;
139 }
140
104 -/* State selector in form */
105 -.scheduler-state-selector {
106 - display: flex;
107 - gap: 8px;
108 - flex-wrap: wrap;
109 - margin-bottom: 8px;
141 +.scheduler-task-list .col-project {
142 + width: 20%;
143 }
144
112 -.scheduler-state-explanation {
113 - font-size: 12px;
114 - color: var(--color-text-secondary);
145 +.scheduler-task-list .col-lastrun {
146 + width: 20%;
147 }
148
117 -/* Schedule Builder */
118 -.scheduler-schedule-builder {
119 - display: grid;
120 - grid-template-columns: repeat(5, 1fr);
121 - gap: 12px;
149 +.scheduler-task-list .col-actions {
150 + width: 18%;
151 + text-align: right;
152 }
153
124 -.scheduler-schedule-field {
154 +/* Task actions container */
155 +.scheduler-task-actions {
156 display: flex;
126 - flex-direction: column;
127 - gap: 4px;
128 - max-width: 70px;
157 + justify-content: flex-end;
158 + gap: 10px;
159 + flex-wrap: nowrap;
160 }
161
131 -.scheduler-schedule-field input {
132 - width: 100%;
133 - min-width: 0;
134 - font-size: 0.9rem;
162 +/* Task action buttons */
163 +.scheduler-task-action {
164 + display: inline-flex;
165 + align-items: center;
166 + justify-content: center;
167 + background-color: transparent;
168 + border: 1px solid var(--color-border);
169 + color: var(--color-text);
170 + padding: 4px;
171 + border-radius: 4px;
172 + cursor: pointer;
173 + transition: all 0.2s ease;
174 + width: 28px;
175 + height: 28px;
176 + flex-shrink: 0;
177 }
178
137 -.scheduler-schedule-label {
138 - font-size: 12px;
139 - color: var(--color-text-secondary);
179 +.scheduler-task-action:hover {
180 + background-color: var(--color-secondary);
181 }
182
142 -/* Plan Builder */
143 -.scheduler-plan-builder {
183 +/* ==========================================================================
184 + Form Styles
185 + ========================================================================== */
186 +
187 +.scheduler-form {
188 display: flex;
189 flex-direction: column;
146 - gap: 12px;
190 + gap: 1.5rem;
191 + padding: 1rem 0;
192 }
193
149 -.scheduler-plan-todo {
194 +.scheduler-form-header {
195 display: flex;
151 - flex-direction: column;
152 - gap: 8px;
196 + padding-bottom: var(--spacing-sm);
197 + border-bottom: 1px solid var(--color-border);
198 + justify-content: space-between;
199 }
200
155 -.scheduler-plan-label {
156 - font-weight: 500;
157 - font-size: 0.9rem;
201 +.scheduler-form-title {
202 + font-size: 1.25rem;
203 + font-weight: bold;
204 + color: var(--color-primary);
205 + margin: 0;
206 }
207
160 -.scheduler-todo-list {
208 +.scheduler-form-actions {
209 display: flex;
162 - flex-direction: column;
163 - gap: 8px;
164 - padding: 12px;
165 - background: var(--color-background);
166 - border: 1px solid var(--color-border);
167 - border-radius: 4px;
210 + gap: 0.8rem;
211 + justify-content: flex-end;
212 + align-items: center;
213 }
214
170 -.scheduler-todo-item {
171 - display: flex;
172 - justify-content: space-between;
173 - align-items: center;
174 - padding: 8px;
175 - background: var(--color-panel);
176 - border: 1px solid var(--color-border);
177 - border-radius: 4px;
215 +.scheduler-form-grid {
216 + display: grid;
217 + grid-template-columns: 1fr;
218 + gap: 1.5rem;
219 + overflow-x: auto;
220 }
221
180 -.scheduler-empty-plan {
181 - color: var(--color-text-secondary);
182 - font-style: italic;
183 - text-align: center;
184 - padding: 12px;
222 +.scheduler-form-field {
223 + display: grid;
224 + grid-template-columns: 1fr 2fr;
225 + gap: 1rem;
226 + align-items: flex-start;
227 }
228
187 -.scheduler-add-todo {
188 - display: flex;
189 - gap: 8px;
190 - margin-top: 8px;
229 +.full-width {
230 + grid-column: 1 / -1;
231 }
232
193 -.scheduler-add-todo input {
194 - flex: 1;
233 +.scheduler-form-label {
234 + font-weight: bold;
235 + color: var(--color-primary);
236 + margin-bottom: 0.25rem;
237 }
238
197 -/* Input group for token field */
198 -.input-group {
239 +.scheduler-form-help {
240 + color: var(--color-text);
241 + font-size: 0.875rem;
242 + opacity: 0.8;
243 + margin: 0.25rem 0 0.5rem 0;
244 +}
245 +
246 +/* Label and help text wrapper for tighter grouping */
247 +.label-help-wrapper {
248 display: flex;
200 - gap: 8px;
249 + flex-direction: column;
250 + gap: 2px;
251 + margin-bottom: 0.5rem;
252 +}
253 +
254 +.label-help-wrapper .scheduler-form-label {
255 + margin-bottom: 2px;
256 +}
257 +
258 +.label-help-wrapper .scheduler-form-help {
259 + margin-top: 0;
260 + margin-bottom: 0;
261 }
262
203 -/* Task detail view styling */
263 +/* ==========================================================================
264 + Detail View
265 + ========================================================================== */
266 +
267 .scheduler-detail-view {
268 background-color: var(--color-bg-secondary);
269 border-radius: 4px;
207 - padding: 20px;
208 - margin-bottom: 20px;
270 + margin-bottom: var(--spacing-md);
271 animation: fadeIn 0.3s ease;
272 }
273
@@ -213,11 +275,21 @@
275 display: flex;
276 justify-content: space-between;
277 align-items: center;
216 - margin-bottom: 20px;
217 - padding-bottom: 10px;
218 - border-bottom: 1px solid var(--color-border);
278 flex-wrap: wrap;
279 gap: 10px;
280 + margin: var(--spacing-md) 0;
281 + width: 100%;
282 +}
283 +
284 +.scheduler-detail-header-left {
285 + display: flex;
286 + align-items: center;
287 + gap: 10px;
288 + flex-wrap: wrap;
289 +}
290 +
291 +.scheduler-detail-header-left .scheduler-detail-title {
292 + margin: 0;
293 }
294
295 .scheduler-detail-header .scheduler-detail-title {
@@ -231,6 +303,41 @@
303 margin-right: 10px;
304 }
305
306 +.scheduler-detail-header-actions {
307 + display: flex;
308 + align-items: center;
309 + gap: 0.5rem;
310 +}
311 +
312 +.scheduler-detail-header .btn-action-header {
313 + padding: 0.4rem 0.6rem;
314 + display: flex;
315 + align-items: center;
316 + justify-content: space-between;
317 + background: var(--color-bg-secondary);
318 + border: 1px solid var(--color-border);
319 + color: var(--color-text);
320 + cursor: pointer;
321 +}
322 +
323 +.scheduler-detail-header .btn-action-header .btn-cancel {
324 + margin-left: var(--spacing-sm);
325 +}
326 +
327 +.scheduler-detail-header .btn-action-header:hover {
328 + border-color: var(--color-primary);
329 + color: var(--color-primary);
330 +}
331 +
332 +.scheduler-detail-header .btn-action-header.danger:hover {
333 + border-color: var(--color-accent);
334 + color: var(--color-accent);
335 +}
336 +
337 +.scheduler-detail-header .btn-action-header .material-symbols-outlined {
338 + font-size: 18px;
339 +}
340 +
341 .scheduler-detail-content {
342 margin-bottom: 20px;
343 }
@@ -239,7 +346,7 @@
346 display: grid;
347 grid-template-columns: 120px 1fr;
348 gap: 8px 16px;
242 - margin-bottom: 16px;
349 + margin-top: var(--spacing-md);
350 }
351
352 .scheduler-details-label {
@@ -260,41 +367,338 @@
367 gap: 8px;
368 }
369
263 -/* Misc */
370 +/* ==========================================================================
371 + State Selector
372 + ========================================================================== */
373 +
374 +.scheduler-state-selector {
375 + display: flex;
376 + gap: 10px;
377 + flex-wrap: wrap;
378 +}
379 +
380 +.scheduler-state-selector .scheduler-status-badge {
381 + cursor: pointer;
382 + transition: all 0.2s ease;
383 + opacity: 0.5;
384 + border: 1px solid transparent;
385 +}
386 +
387 +.scheduler-state-selector .scheduler-status-badge:hover {
388 + opacity: 0.9;
389 +}
390 +
391 +/* Make status badges in selector more prominent */
392 +.scheduler-state-selector .scheduler-status-idle,
393 +.scheduler-state-selector .scheduler-status-running,
394 +.scheduler-state-selector .scheduler-status-disabled,
395 +.scheduler-state-selector .scheduler-status-error {
396 + font-weight: 600;
397 + padding: 6px 12px;
398 +}
399 +
400 +/* State explanation styling */
401 +.scheduler-state-explanation {
402 + margin-top: 10px;
403 + font-size: 0.85rem;
404 + color: var(--color-text-secondary);
405 + line-height: 1.4;
406 + min-height: 1.4em;
407 + transition: all 0.2s ease;
408 +}
409 +
410 +.scheduler-state-explanation span {
411 + display: block;
412 + padding: 4px 8px;
413 + background-color: rgba(0, 0, 0, 0.05);
414 + border-radius: 4px;
415 + margin-top: 8px;
416 +}
417 +
418 +.light-mode .scheduler-state-explanation span {
419 + background-color: rgba(255, 255, 255, 0.3);
420 +}
421 +
422 +/* ==========================================================================
423 + Schedule Builder (for scheduled tasks)
424 + ========================================================================== */
425 +
426 +.scheduler-schedule-builder {
427 + display: grid;
428 + grid-template-columns: repeat(5, 1fr);
429 + gap: 10px;
430 + width: 100%;
431 + margin-bottom: 10px;
432 +}
433 +
434 +.scheduler-schedule-field {
435 + display: flex;
436 + flex-direction: column;
437 + gap: 4px;
438 + max-width: 70px;
439 +}
440 +
441 +.scheduler-schedule-field input {
442 + width: 100%;
443 + min-width: 0;
444 + font-size: 0.9rem;
445 +}
446 +
447 +.scheduler-schedule-label {
448 + font-size: 0.8rem;
449 + margin-bottom: 5px;
450 + color: var(--color-text);
451 + opacity: 0.8;
452 +}
453 +
454 .scheduler-no-schedule {
455 color: var(--color-text-secondary);
456 opacity: 0.7;
457 font-style: italic;
458 }
459
270 -.task-container-vertical {
460 +/* ==========================================================================
461 + Plan Builder (for planned tasks)
462 + ========================================================================== */
463 +
464 +.scheduler-plan-builder {
465 + width: 100%;
466 + margin-bottom: 10px;
467 + border: 1px solid var(--color-border);
468 + border-radius: 8px;
469 + padding: 10px;
470 + background-color: rgba(0, 0, 0, 0.2);
471 +}
472 +
473 +.scheduler-plan-todo {
474 display: flex;
475 flex-direction: column;
273 - width: 100%;
274 - gap: 6px;
476 }
477
277 -.scheduler-status-badge-small {
278 - font-size: 10px;
279 - padding: 2px 6px;
280 - margin-right: 5px;
281 - min-width: 40px;
282 - text-align: center;
478 +.scheduler-plan-label {
479 + font-size: 0.9rem;
480 + margin-bottom: 10px;
481 + color: var(--color-text);
482 + font-weight: bold;
483 }
484
285 -.scheduler-loading {
485 +.scheduler-todo-list {
486 + display: flex;
487 + flex-direction: column;
488 + gap: 10px;
489 + margin-top: 8px;
490 + max-height: 200px;
491 + overflow-y: auto;
492 +}
493 +
494 +.scheduler-todo-item {
495 + display: flex;
496 + align-items: center;
497 + justify-content: space-between;
498 + background-color: var(--color-background);
499 + border-radius: 6px;
500 + padding: 8px 12px;
501 + border: 1px solid var(--color-border);
502 + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
503 +}
504 +
505 +.scheduler-todo-item span {
506 + flex: 1;
507 + font-size: 14px;
508 +}
509 +
510 +.scheduler-add-todo {
511 + margin-top: 12px;
512 + display: flex;
513 + gap: 8px;
514 + align-items: center;
515 +}
516 +
517 +.scheduler-add-todo input {
518 + flex: 1;
519 +}
520 +
521 +.scheduler-add-todo input[type="datetime-local"] {
522 + flex: 1;
523 + min-width: 0;
524 + padding: 8px 12px;
525 + border-radius: 6px;
526 + border: 1px solid var(--color-border);
527 + background-color: var(--color-background);
528 + color: var(--color-text);
529 +}
530 +
531 +.scheduler-add-todo-button {
532 + display: flex;
533 + align-items: center;
534 + justify-content: center;
535 + background-color: var(--color-accent);
536 + color: white;
537 + border: none;
538 + border-radius: 6px;
539 + padding: 8px 12px;
540 + cursor: pointer;
541 + transition: background-color 0.2s ease;
542 + font-weight: 500;
543 +}
544 +
545 +.scheduler-add-todo-button:hover {
546 + background-color: var(--color-accent-dark);
547 +}
548 +
549 +.scheduler-todo-remove {
550 + display: flex;
551 + align-items: center;
552 + justify-content: center;
553 + background-color: transparent;
554 + color: var(--color-text);
555 + border: none;
556 + border-radius: 4px;
557 + width: 24px;
558 + height: 24px;
559 + cursor: pointer;
560 + transition: background-color 0.2s ease;
561 + margin-left: 8px;
562 +}
563 +
564 +.scheduler-todo-remove:hover {
565 + background-color: var(--color-accent-light);
566 + color: var(--color-accent-dark);
567 +}
568 +
569 +.scheduler-empty-plan {
570 + padding: 12px;
571 + color: var(--color-text-muted);
572 + font-style: italic;
573 text-align: center;
287 - padding: 40px 0;
288 - color: var(--color-text-secondary);
574 + border: 1px dashed var(--color-border);
575 + border-radius: 6px;
576 + margin-top: 8px;
577 }
578
291 -/* Responsive adjustments */
579 +.light-mode .scheduler-todo-item {
580 + background-color: var(--color-background-light);
581 + border-color: var(--color-border-light);
582 +}
583 +
584 +.light-mode .scheduler-todo-remove:hover {
585 + background-color: #e0e0e0;
586 + color: #d32f2f;
587 +}
588 +
589 +/* ==========================================================================
590 + Input Group (for token field with generate button)
591 + ========================================================================== */
592 +
593 +.input-group {
594 + display: flex;
595 + gap: 8px;
596 + width: 100%;
597 +}
598 +
599 +.input-group input[type="text"] {
600 + flex: 1;
601 + min-width: 0;
602 +}
603 +
604 +/* Specific styling for the Generate button in token field */
605 +.input-group .scheduler-task-action {
606 + white-space: nowrap;
607 + padding: 4px 10px;
608 + width: auto;
609 + height: auto;
610 + background-color: var(--color-secondary);
611 + font-size: 0.9rem;
612 +}
613 +
614 +.input-group .scheduler-task-action:hover {
615 + background-color: var(--color-accent);
616 + color: var(--color-bg);
617 +}
618 +
619 +/* Ensure parent container allows proper flow */
620 +.scheduler-form-field .input-group {
621 + max-width: 100%;
622 + overflow: hidden;
623 +}
624 +
625 +/* ==========================================================================
626 + Responsive Design
627 + ========================================================================== */
628 +
629 @media (max-width: 768px) {
630 + /* Task list column visibility */
631 + .scheduler-task-list .col-project,
632 + .scheduler-task-list .col-lastrun {
633 + display: none;
634 + }
635 +
636 + .scheduler-task-list .col-name {
637 + width: 50%;
638 + }
639 +
640 + .scheduler-task-list .col-state {
641 + width: 25%;
642 + }
643 +
644 + .scheduler-task-list .col-actions {
645 + width: 25%;
646 + }
647 +
648 + /* Form responsiveness */
649 + .scheduler-form-header {
650 + flex-direction: column;
651 + align-items: flex-start;
652 + gap: 1rem;
653 + }
654 +
655 + .scheduler-form-actions {
656 + align-self: flex-end;
657 + }
658 +
659 + .scheduler-form-field {
660 + grid-template-columns: 1fr;
661 + gap: 0.5rem;
662 + }
663 +
664 .scheduler-form-grid {
665 grid-template-columns: 1fr;
666 }
667
668 + /* Detail header responsiveness */
669 + .scheduler-detail-header {
670 + gap: 0.75rem;
671 + }
672 +
673 + .scheduler-detail-actions {
674 + width: 100%;
675 + flex-wrap: wrap;
676 + gap: 0.5rem;
677 + }
678 +
679 + /* Schedule builder responsiveness */
680 .scheduler-schedule-builder {
681 grid-template-columns: 1fr 1fr;
682 }
683 +
684 + /* Input group responsiveness */
685 + .input-group .scheduler-task-action {
686 + padding: 4px 8px;
687 + font-size: 0.8rem;
688 + }
689 +
690 + /* Plan builder responsiveness */
691 + .scheduler-add-todo {
692 + flex-direction: column;
693 + }
694 +}
695 +
696 +@media (max-width: 480px) {
697 + .input-group {
698 + flex-direction: column;
699 + }
700 +
701 + .input-group .scheduler-task-action {
702 + align-self: flex-start;
703 + }
704 }
webui/css/settings.css
+6 -549
@@ -67,7 +67,6 @@ textarea {
67 scroll-behavior: smooth;
68 resize: none;
69 background-clip: border-box;
70 - border: 6px solid transparent;
70 }
71
72 textarea:focus {
@@ -373,139 +372,6 @@ nav ul li a img {
372 }
373 }
374
376 -/* Scheduler Task List - updated with guaranteed width handling */
377 -.scheduler-task-list {
378 - width: 100%;
379 - min-width: 100%;
380 - margin: 0;
381 - border-collapse: separate;
382 - border-spacing: 0;
383 - white-space: nowrap;
384 - padding-bottom: 8px;
385 - table-layout: fixed;
386 -}
387 -
388 -.scheduler-task-list th,
389 -.scheduler-task-list td {
390 - padding: 8px 12px;
391 - text-align: left;
392 - vertical-align: middle;
393 - border-bottom: 1px solid var(--color-border);
394 -}
395 -
396 -/* Column styles */
397 -.scheduler-task-list .col-name {
398 - width: 30%;
399 - overflow: hidden;
400 - text-overflow: ellipsis;
401 -}
402 -
403 -.scheduler-task-list .col-state {
404 - width: 12%;
405 -}
406 -
407 -.scheduler-task-list .col-project {
408 - width: 20%;
409 -}
410 -
411 -.scheduler-task-list .col-lastrun {
412 - width: 20%;
413 -}
414 -
415 -.scheduler-task-list .col-actions {
416 - width: 18%;
417 - text-align: right;
418 -}
419 -
420 -/* Mobile: hide less important columns */
421 -@media (max-width: 768px) {
422 - .scheduler-task-list .col-project,
423 - .scheduler-task-list .col-lastrun {
424 - display: none;
425 - }
426 -
427 - .scheduler-task-list .col-name {
428 - width: 50%;
429 - }
430 -
431 - .scheduler-task-list .col-state {
432 - width: 25%;
433 - }
434 -
435 - .scheduler-task-list .col-actions {
436 - width: 25%;
437 - }
438 -}
439 -
440 -
441 -/* Task actions container */
442 -.scheduler-task-actions {
443 - display: flex;
444 - justify-content: flex-end;
445 - gap: 10px;
446 - flex-wrap: nowrap;
447 -}
448 -
449 -/* Scheduler form styles */
450 -.scheduler-form {
451 - display: flex;
452 - flex-direction: column;
453 - gap: 1.5rem;
454 - padding: 1rem 0;
455 -}
456 -
457 -.scheduler-form-header {
458 - display: flex;
459 - justify-content: space-between;
460 - align-items: center;
461 - margin-bottom: 1.5rem;
462 -}
463 -
464 -.scheduler-form-title {
465 - font-size: 1.25rem;
466 - font-weight: bold;
467 - color: var(--color-primary);
468 - margin: 0;
469 -}
470 -
471 -.scheduler-form-actions {
472 - display: flex;
473 - gap: 0.8rem;
474 - justify-content: flex-end;
475 - align-items: center;
476 -}
477 -
478 -.scheduler-form-grid {
479 - display: grid;
480 - grid-template-columns: 1fr;
481 - gap: 1.5rem;
482 - overflow-x: auto;
483 -}
484 -
485 -.scheduler-form-field {
486 - display: grid;
487 - grid-template-columns: 1fr 2fr;
488 - gap: 1rem;
489 - align-items: flex-start;
490 -}
491 -
492 -@media (max-width: 768px) {
493 - .scheduler-form-header {
494 - flex-direction: column;
495 - align-items: flex-start;
496 - gap: 1rem;
497 - }
498 -
499 - .scheduler-form-actions {
500 - align-self: flex-end;
501 - }
502 -
503 - .scheduler-form-field {
504 - grid-template-columns: 1fr;
505 - gap: 0.5rem;
506 - }
507 -}
508 -
375 /* Section Styles */
376 .section {
377 margin-bottom: 2rem;
@@ -513,8 +379,8 @@ nav ul li a img {
379 padding-bottom: 0;
380 border: 1px solid var(--color-border);
381 border-radius: 0.5rem;
516 - overflow-x: visible; /* Desktop: No horizontal scroll */
517 - width: 100%; /* Fill available width */
382 + overflow-x: visible;
383 + width: 100%;
384 min-width: min-content;
385 display: block;
386 box-sizing: border-box;
@@ -532,39 +398,10 @@ nav ul li a img {
398 margin-bottom: 1rem;
399 }
400
535 -/* Scheduler container - updated with guaranteed width handling */
536 -.scheduler-container {
537 - width: 100%;
538 - box-sizing: border-box;
539 - display: block;
540 - padding: 0.5rem 0;
541 -}
542 -
543 -/* Scheduler task actions and buttons */
544 -.scheduler-task-action {
545 - display: inline-flex;
546 - align-items: center;
547 - justify-content: center;
548 - background-color: transparent;
549 - border: 1px solid var(--color-border);
550 - color: var(--color-text);
551 - padding: 4px;
552 - border-radius: 4px;
553 - cursor: pointer;
554 - transition: all 0.2s ease;
555 - width: 28px;
556 - height: 28px;
557 - flex-shrink: 0;
558 -}
559 -
560 -.scheduler-task-action:hover {
561 - background-color: var(--color-secondary);
562 -}
563 -
564 -/* Scrollbar styling for better visibility */
401 +/* Scrollbar styling for sections */
402 .section::-webkit-scrollbar {
566 - height: 10px; /* Taller scrollbar for better usability */
567 - background-color: rgba(0,0,0,0.1);
403 + height: 10px;
404 + background-color: rgba(0, 0, 0, 0.1);
405 }
406
407 .section::-webkit-scrollbar-thumb {
@@ -576,12 +413,10 @@ nav ul li a img {
413 background-color: rgba(155, 155, 155, 0.9);
414 }
415
579 -/* Mobile styles for scheduler sections */
416 @media (max-width: 1280px) {
581 - /* Scrollbar styling for mobile view */
417 .section::-webkit-scrollbar {
418 height: 10px;
584 - background-color: rgba(0,0,0,0.1);
419 + background-color: rgba(0, 0, 0, 0.1);
420 }
421
422 .section::-webkit-scrollbar-thumb {
@@ -593,381 +428,3 @@ nav ul li a img {
428 background-color: rgba(155, 155, 155, 0.9);
429 }
430 }
596 -
597 -/* Scheduler form field styling to match standard field styling */
598 -.scheduler-form-label {
599 - font-weight: bold;
600 - color: var(--color-primary);
601 - margin-bottom: 0.25rem; /* Add consistent spacing between label and help text */
602 -}
603 -
604 -.scheduler-form-help {
605 - color: var(--color-text);
606 - font-size: 0.875rem;
607 - opacity: 0.8;
608 - margin: 0.25rem 0 0.5rem 0; /* Match the spacing of field-description */
609 -}
610 -
611 -/* Label and help text wrapper for tighter grouping */
612 -.label-help-wrapper {
613 - margin-bottom: 0.5rem;
614 -}
615 -
616 -.label-help-wrapper .scheduler-form-label {
617 - margin-bottom: 2px;
618 -}
619 -
620 -.label-help-wrapper .scheduler-form-help {
621 - margin-top: 0;
622 - margin-bottom: 0;
623 -}
624 -
625 -/* Scheduler detail header styling */
626 -.scheduler-detail-header {
627 - display: flex;
628 - justify-content: space-between;
629 - align-items: center;
630 - flex-wrap: wrap;
631 - gap: 10px;
632 - width: 100%;
633 -}
634 -
635 -.scheduler-detail-header-left {
636 - display: flex;
637 - align-items: center;
638 - gap: 10px;
639 - flex-wrap: wrap;
640 -}
641 -
642 -.scheduler-detail-header-left .scheduler-detail-title {
643 - margin: 0;
644 -}
645 -
646 -.scheduler-detail-header-actions {
647 - display: flex;
648 - align-items: center;
649 - gap: 0.5rem;
650 -}
651 -
652 -.scheduler-detail-header .btn-action-header {
653 - padding: 0.4rem 0.6rem;
654 - display: flex;
655 - align-items: center;
656 - justify-content: space-between;
657 - background: var(--color-bg-secondary);
658 - border: 1px solid var(--color-border);
659 - color: var(--color-text);
660 - cursor: pointer;
661 -}
662 -
663 -.scheduler-detail-header .btn-action-header .btn-cancel {
664 - margin-left: var(--spacing-sm);
665 -}
666 -
667 -.scheduler-detail-header .btn-action-header:hover {
668 - border-color: var(--color-primary);
669 - color: var(--color-primary);
670 -}
671 -
672 -.scheduler-detail-header .btn-action-header.danger:hover {
673 - border-color: var(--color-accent);
674 - color: var(--color-accent);
675 -}
676 -
677 -.scheduler-detail-header .btn-action-header .material-symbols-outlined {
678 - font-size: 18px;
679 -}
680 -
681 -/* Responsive adjustments for headers */
682 -@media (max-width: 768px) {
683 - .scheduler-form-header {
684 - flex-direction: column;
685 - align-items: flex-start;
686 - gap: 1rem;
687 - }
688 -
689 - .scheduler-form-actions {
690 - align-self: flex-end;
691 - }
692 -
693 - .scheduler-detail-header {
694 - flex-direction: column;
695 - align-items: flex-start;
696 - gap: 0.75rem;
697 - }
698 -
699 - .scheduler-detail-header-actions {
700 - width: 100%;
701 - justify-content: flex-end;
702 - }
703 -
704 - .scheduler-form-field {
705 - grid-template-columns: 1fr;
706 - gap: 0.5rem;
707 - }
708 -}
709 -
710 -/* Input group for token field with generate button */
711 -.input-group {
712 - display: flex;
713 - gap: 8px;
714 - width: 100%;
715 -}
716 -
717 -.input-group input[type="text"] {
718 - flex: 1;
719 - min-width: 0; /* Allows the input to shrink below its content size */
720 -}
721 -
722 -/* Specific styling for the Generate button in token field */
723 -.input-group .scheduler-task-action {
724 - white-space: nowrap;
725 - padding: 4px 10px;
726 - width: auto;
727 - height: auto;
728 - background-color: var(--color-secondary);
729 - font-size: 0.9rem;
730 -}
731 -
732 -.input-group .scheduler-task-action:hover {
733 - background-color: var(--color-accent);
734 - color: var(--color-bg);
735 -}
736 -
737 -/* Ensure parent container allows proper flow */
738 -.scheduler-form-field .input-group {
739 - max-width: 100%;
740 - overflow: hidden;
741 -}
742 -
743 -/* Adjustments for mobile */
744 -@media (max-width: 768px) {
745 - .input-group .scheduler-task-action {
746 - padding: 4px 8px;
747 - font-size: 0.8rem;
748 - }
749 -}
750 -
751 -@media (max-width: 480px) {
752 - .input-group {
753 - flex-direction: column;
754 - }
755 -
756 - .input-group .scheduler-task-action {
757 - align-self: flex-start;
758 - }
759 -}
760 -
761 -/* Task state selector styling */
762 -.scheduler-state-selector {
763 - display: flex;
764 - gap: 10px;
765 - flex-wrap: wrap;
766 -}
767 -
768 -.scheduler-state-selector .scheduler-status-badge {
769 - cursor: pointer;
770 - transition: all 0.2s ease;
771 - opacity: 0.7;
772 - border: 1px solid transparent;
773 -}
774 -
775 -.scheduler-state-selector .scheduler-status-badge:hover {
776 - opacity: 0.9;
777 - transform: scale(1.05);
778 -}
779 -
780 -.scheduler-status-selected {
781 - opacity: 1 !important;
782 - transform: scale(1.05);
783 - box-shadow: 0 0 0 2px var(--color-bg), 0 0 0 4px var(--color-border);
784 - border: 2px solid var(--color-border) !important;
785 - outline: none;
786 -}
787 -
788 -/* Make status badges in selector more prominent */
789 -.scheduler-state-selector .scheduler-status-idle,
790 -.scheduler-state-selector .scheduler-status-running,
791 -.scheduler-state-selector .scheduler-status-disabled,
792 -.scheduler-state-selector .scheduler-status-error {
793 - font-weight: 600;
794 - padding: 6px 12px;
795 -}
796 -
797 -.light-mode .scheduler-status-selected {
798 - box-shadow: 0 0 0 2px var(--color-bg-light), 0 0 0 4px var(--color-accent);
799 -}
800 -
801 -/* State explanation styling */
802 -.scheduler-state-explanation {
803 - margin-top: 10px;
804 - font-size: 0.85rem;
805 - color: var(--color-text-secondary);
806 - line-height: 1.4;
807 - min-height: 1.4em; /* Ensure consistent height even when changing descriptions */
808 - transition: all 0.2s ease;
809 -}
810 -
811 -.scheduler-state-explanation span {
812 - display: block;
813 - padding: 4px 8px;
814 - background-color: rgba(0, 0, 0, 0.05);
815 - border-radius: 4px;
816 - margin-top: 8px;
817 -}
818 -
819 -.light-mode .scheduler-state-explanation span {
820 - background-color: rgba(255, 255, 255, 0.3);
821 -}
822 -
823 -/* Schedule Builder (for scheduled tasks) */
824 -.scheduler-schedule-builder {
825 - display: grid;
826 - grid-template-columns: repeat(5, 1fr);
827 - gap: 10px;
828 - width: 100%;
829 - margin-bottom: 10px;
830 -}
831 -
832 -.scheduler-schedule-field {
833 - display: flex;
834 - flex-direction: column;
835 -}
836 -
837 -.scheduler-schedule-label {
838 - font-size: 0.8rem;
839 - margin-bottom: 5px;
840 - color: var(--color-text);
841 - opacity: 0.8;
842 -}
843 -
844 -/* Plan Builder (for planned tasks) */
845 -.scheduler-plan-builder {
846 - width: 100%;
847 - margin-bottom: 10px;
848 - border: 1px solid var(--color-border);
849 - border-radius: 8px;
850 - padding: 10px;
851 - background-color: rgba(0, 0, 0, 0.2);
852 -}
853 -
854 -.scheduler-plan-todo {
855 - display: flex;
856 - flex-direction: column;
857 -}
858 -
859 -.scheduler-plan-label {
860 - font-size: 0.9rem;
861 - margin-bottom: 10px;
862 - color: var(--color-text);
863 - font-weight: bold;
864 -}
865 -
866 -.scheduler-todo-list {
867 - display: flex;
868 - flex-direction: column;
869 - gap: 10px;
870 - margin-top: 8px;
871 - max-height: 200px;
872 - overflow-y: auto;
873 -}
874 -
875 -.scheduler-todo-item {
876 - display: flex;
877 - align-items: center;
878 - justify-content: space-between;
879 - background-color: var(--color-background);
880 - border-radius: 6px;
881 - padding: 8px 12px;
882 - border: 1px solid var(--color-border);
883 - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
884 -}
885 -
886 -.scheduler-todo-item span {
887 - flex: 1;
888 - font-size: 14px;
889 -}
890 -
891 -.scheduler-add-todo {
892 - margin-top: 12px;
893 - display: flex;
894 - gap: 8px;
895 - align-items: center;
896 -}
897 -
898 -.scheduler-add-todo input[type="datetime-local"] {
899 - flex: 1;
900 - min-width: 0;
901 - padding: 8px 12px;
902 - border-radius: 6px;
903 - border: 1px solid var(--color-border);
904 - background-color: var(--color-background);
905 - color: var(--color-text);
906 -}
907 -
908 -.scheduler-add-todo-button {
909 - display: flex;
910 - align-items: center;
911 - justify-content: center;
912 - background-color: var(--color-accent);
913 - color: white;
914 - border: none;
915 - border-radius: 6px;
916 - padding: 8px 12px;
917 - cursor: pointer;
918 - transition: background-color 0.2s ease;
919 - font-weight: 500;
920 -}
921 -
922 -.scheduler-add-todo-button:hover {
923 - background-color: var(--color-accent-dark);
924 -}
925 -
926 -.scheduler-todo-remove {
927 - display: flex;
928 - align-items: center;
929 - justify-content: center;
930 - background-color: transparent;
931 - color: var(--color-text);
932 - border: none;
933 - border-radius: 4px;
934 - width: 24px;
935 - height: 24px;
936 - cursor: pointer;
937 - transition: background-color 0.2s ease;
938 - margin-left: 8px;
939 -}
940 -
941 -.scheduler-todo-remove:hover {
942 - background-color: var(--color-accent-light);
943 - color: var(--color-accent-dark);
944 -}
945 -
946 -.light-mode .scheduler-todo-item {
947 - background-color: var(--color-background-light);
948 - border-color: var(--color-border-light);
949 -}
950 -
951 -.light-mode .scheduler-todo-remove:hover {
952 - background-color: #e0e0e0;
953 - color: #d32f2f;
954 -}
955 -
956 -.scheduler-empty-plan {
957 - padding: 12px;
958 - color: var(--color-text-muted);
959 - font-style: italic;
960 - text-align: center;
961 - border: 1px dashed var(--color-border);
962 - border-radius: 6px;
963 - margin-top: 8px;
964 -}
965 -
966 -/* Responsive design for plan builder */
967 -@media (max-width: 768px) {
968 - .scheduler-add-todo {
969 - flex-direction: column;
970 - }
971 -}
972 -
973 -/* Token field (for ad-hoc tasks) */