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) */