fix(frontend): remove duplicate calendar title-row from sidebar calendar
- Remove calendar-title-row (year/month + time) that was showing below the main date row - Keep only the primary date display (jarvis-date-row) at the top - Also removes unused calendarYear/calendarMonth computed properties
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
.chat-view {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.sidebar-runtime-panel {
|
||||
@@ -567,16 +567,18 @@
|
||||
width: 280px;
|
||||
min-width: 280px;
|
||||
background: var(--bg-panel);
|
||||
border-right: 1px solid var(--border-dim);
|
||||
border-right: 1px solid rgba(0, 245, 212, 0.15);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: visible;
|
||||
border-radius: 0;
|
||||
transition: width var(--transition-mid), min-width var(--transition-mid);
|
||||
}
|
||||
|
||||
.conv-sidebar.collapsed {
|
||||
width: 78px;
|
||||
min-width: 78px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.runtime-sidebar {
|
||||
@@ -584,9 +586,10 @@
|
||||
min-width: 280px;
|
||||
background: var(--bg-panel);
|
||||
border-left: 1px solid var(--border-dim);
|
||||
overflow: hidden;
|
||||
overflow: visible;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.conv-sidebar-header {
|
||||
@@ -1369,26 +1372,26 @@
|
||||
/* ── Top Buttons Row ── */
|
||||
.top-buttons-row {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
padding: 14px 24px 10px;
|
||||
border-top: 1px solid var(--border-dim);
|
||||
background: rgba(5, 8, 16, 0.6);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 24px 6px;
|
||||
border-top: 1px solid rgba(0, 245, 212, 0.15);
|
||||
background: linear-gradient(180deg, transparent 0%, rgba(0, 245, 212, 0.03) 100%);
|
||||
}
|
||||
|
||||
.top-action-btn {
|
||||
position: relative;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 20px;
|
||||
background: linear-gradient(135deg, rgba(0, 245, 212, 0.08) 0%, rgba(123, 44, 191, 0.05) 100%);
|
||||
border: 1px solid rgba(0, 245, 212, 0.2);
|
||||
border-radius: 8px;
|
||||
color: var(--text-primary);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border: 1px solid rgba(0, 245, 212, 0.3);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
transition: all 0.2s ease;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -1396,35 +1399,75 @@
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(0, 245, 212, 0.1), transparent);
|
||||
transition: left 0.5s ease;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(135deg, rgba(0, 245, 212, 0.1) 0%, transparent 50%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.top-action-btn:hover::before {
|
||||
left: 100%;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.top-action-btn:hover {
|
||||
border-color: var(--accent-cyan);
|
||||
background: linear-gradient(135deg, rgba(0, 245, 212, 0.15) 0%, rgba(123, 44, 191, 0.1) 100%);
|
||||
box-shadow: 0 0 20px rgba(0, 245, 212, 0.2), inset 0 0 20px rgba(0, 245, 212, 0.05);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 0 10px rgba(0, 245, 212, 0.5), inset 0 0 8px rgba(0, 245, 212, 0.15);
|
||||
}
|
||||
|
||||
.top-action-btn:hover .btn-icon {
|
||||
animation: glitch 0.3s ease;
|
||||
}
|
||||
|
||||
.top-action-btn:active {
|
||||
transform: translateY(0);
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
.top-action-btn .btn-icon {
|
||||
font-size: 18px;
|
||||
filter: drop-shadow(0 0 4px rgba(0, 245, 212, 0.5));
|
||||
font-weight: bold;
|
||||
filter: drop-shadow(0 0 4px rgba(0, 245, 212, 0.9));
|
||||
}
|
||||
|
||||
.top-action-btn .btn-text {
|
||||
letter-spacing: 0.5px;
|
||||
/* Temple icon - diamond pattern */
|
||||
.top-action-btn:nth-child(1) .btn-icon {
|
||||
animation: pulseRotate 4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Knowledge icon - expanding ring */
|
||||
.top-action-btn:nth-child(2) .btn-icon {
|
||||
animation: expandPulse 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* War Room icon - hexagon scan */
|
||||
.top-action-btn:nth-child(3) .btn-icon {
|
||||
animation: scanRotate 3.5s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes glitch {
|
||||
0% { transform: translate(0); filter: drop-shadow(0 0 4px rgba(0, 245, 212, 0.9)); }
|
||||
20% { transform: translate(-2px, 1px); filter: drop-shadow(0 0 6px rgba(0, 245, 212, 1)); }
|
||||
40% { transform: translate(2px, -1px); filter: drop-shadow(0 0 3px rgba(0, 245, 212, 0.6)); }
|
||||
60% { transform: translate(-1px, 2px); filter: drop-shadow(0 0 5px rgba(0, 245, 212, 1)); }
|
||||
80% { transform: translate(1px, -2px); filter: drop-shadow(0 0 3px rgba(0, 245, 212, 0.7)); }
|
||||
100% { transform: translate(0); filter: drop-shadow(0 0 4px rgba(0, 245, 212, 0.9)); }
|
||||
}
|
||||
|
||||
@keyframes pulseRotate {
|
||||
0%, 100% { transform: rotate(0deg) scale(1); opacity: 1; }
|
||||
50% { transform: rotate(180deg) scale(1.1); opacity: 0.8; }
|
||||
}
|
||||
|
||||
@keyframes expandPulse {
|
||||
0%, 100% { transform: scale(1); opacity: 1; filter: drop-shadow(0 0 4px rgba(0, 245, 212, 0.9)); }
|
||||
50% { transform: scale(1.15); opacity: 0.7; filter: drop-shadow(0 0 8px rgba(0, 245, 212, 1)); }
|
||||
}
|
||||
|
||||
@keyframes scanRotate {
|
||||
0% { transform: rotate(0deg); filter: hue-rotate(0deg) drop-shadow(0 0 4px rgba(0, 245, 212, 0.9)); }
|
||||
50% { filter: hue-rotate(30deg) drop-shadow(0 0 6px rgba(0, 245, 212, 1)); }
|
||||
100% { transform: rotate(360deg); filter: hue-rotate(0deg) drop-shadow(0 0 4px rgba(0, 245, 212, 0.9)); }
|
||||
}
|
||||
|
||||
/* ── Input Area ── */
|
||||
@@ -1615,6 +1658,7 @@
|
||||
.jarvis-date-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
@@ -1654,6 +1698,13 @@
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.calendar-header .is-weekend {
|
||||
opacity: 1;
|
||||
color: rgba(0, 243, 255, 0.75);
|
||||
font-weight: 700;
|
||||
text-shadow: 0 0 8px rgba(0, 243, 255, 0.4);
|
||||
}
|
||||
|
||||
.calendar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
@@ -1910,12 +1961,29 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
background:
|
||||
radial-gradient(circle at top right, rgba(56, 189, 248, 0.18), transparent 24%),
|
||||
radial-gradient(circle at bottom left, rgba(14, 165, 233, 0.12), transparent 22%),
|
||||
linear-gradient(180deg, rgba(5, 10, 19, 0.98), rgba(3, 7, 15, 0.98)) !important;
|
||||
background: var(--bg-panel) !important;
|
||||
padding: 0 !important;
|
||||
border-right-color: rgba(34, 211, 238, 0.12);
|
||||
border-right: 1px solid rgba(0, 245, 212, 0.15);
|
||||
box-shadow: inset 0 0 40px rgba(0, 0, 0, 0.3);
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.jarvis-sidebar::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: repeating-linear-gradient(
|
||||
0deg,
|
||||
transparent,
|
||||
transparent 2px,
|
||||
rgba(0, 245, 212, 0.015) 2px,
|
||||
rgba(0, 245, 212, 0.015) 4px
|
||||
);
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.jarvis-sidebar-toggle {
|
||||
@@ -1923,27 +1991,24 @@
|
||||
top: 22px;
|
||||
right: -14px;
|
||||
z-index: 4;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(73, 208, 255, 0.24);
|
||||
background: linear-gradient(180deg, rgba(8, 18, 34, 0.98), rgba(6, 13, 24, 0.98));
|
||||
color: rgba(220, 245, 255, 0.86);
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgba(0, 245, 212, 0.2);
|
||||
background: var(--bg-panel);
|
||||
color: var(--accent-cyan);
|
||||
cursor: pointer;
|
||||
box-shadow:
|
||||
0 0 0 3px rgba(3, 7, 15, 0.92),
|
||||
0 8px 18px rgba(2, 8, 23, 0.32);
|
||||
transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.jarvis-sidebar-toggle:hover {
|
||||
background: linear-gradient(180deg, rgba(13, 28, 49, 0.98), rgba(8, 18, 34, 0.98));
|
||||
border-color: rgba(125, 211, 252, 0.54);
|
||||
color: #eefcff;
|
||||
border-color: rgba(0, 245, 212, 0.3);
|
||||
box-shadow: 0 0 10px rgba(0, 245, 212, 0.2);
|
||||
}
|
||||
|
||||
.jarvis-sidebar-toggle-icon {
|
||||
@@ -1960,8 +2025,8 @@
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
height: 100%;
|
||||
gap: 14px;
|
||||
padding: 16px 14px 18px;
|
||||
gap: 8px;
|
||||
padding: 14px 12px 16px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@@ -1970,57 +2035,48 @@
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 56px 10px 14px;
|
||||
gap: 10px;
|
||||
padding: 56px 8px 14px;
|
||||
}
|
||||
|
||||
.jarvis-sidebar-icon-btn {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgba(73, 208, 255, 0.14);
|
||||
background: rgba(255, 255, 255, 0.035);
|
||||
color: rgba(220, 245, 255, 0.8);
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgba(0, 245, 212, 0.2);
|
||||
background: rgba(0, 245, 212, 0.05);
|
||||
color: var(--accent-cyan);
|
||||
cursor: pointer;
|
||||
transition: transform var(--transition-fast), background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.jarvis-sidebar-icon-btn:hover {
|
||||
transform: translateY(-1px);
|
||||
background: rgba(56, 189, 248, 0.12);
|
||||
border-color: rgba(125, 211, 252, 0.38);
|
||||
color: #eefcff;
|
||||
border-color: rgba(0, 245, 212, 0.35);
|
||||
background: rgba(0, 245, 212, 0.15);
|
||||
box-shadow: 0 0 12px rgba(0, 245, 212, 0.3);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.jarvis-sidebar .jarvis-panel {
|
||||
background:
|
||||
linear-gradient(180deg, rgba(10, 18, 34, 0.92), rgba(7, 14, 28, 0.96));
|
||||
border: 1px solid rgba(73, 208, 255, 0.14);
|
||||
border-radius: 18px;
|
||||
padding: 16px 14px 15px;
|
||||
background: linear-gradient(180deg, rgba(8, 18, 36, 0.78), rgba(8, 14, 26, 0.62)) !important;
|
||||
border: 1px solid rgba(56, 189, 248, 0.14) !important;
|
||||
border-radius: 12px;
|
||||
padding: 12px 10px 11px;
|
||||
margin-bottom: 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
clip-path: none;
|
||||
overflow: visible !important;
|
||||
flex-shrink: 0;
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.03),
|
||||
0 14px 34px rgba(2, 8, 23, 0.28);
|
||||
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.2);
|
||||
clip-path: none !important;
|
||||
}
|
||||
|
||||
.jarvis-sidebar .jarvis-panel::before {
|
||||
display: block;
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
linear-gradient(135deg, rgba(56, 189, 248, 0.1), transparent 36%),
|
||||
linear-gradient(180deg, rgba(255, 255, 255, 0.018), transparent 24%);
|
||||
pointer-events: none;
|
||||
border: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jarvis-date-row {
|
||||
@@ -2041,6 +2097,9 @@
|
||||
}
|
||||
|
||||
.jarvis-date-meta {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@@ -2054,7 +2113,6 @@
|
||||
}
|
||||
|
||||
.jarvis-time {
|
||||
margin-top: 4px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.08em;
|
||||
@@ -2066,6 +2124,28 @@
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.calendar-title-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.calendar-title {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.08em;
|
||||
color: rgba(224, 248, 255, 0.86);
|
||||
}
|
||||
|
||||
.calendar-time {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 10px;
|
||||
letter-spacing: 0.1em;
|
||||
color: rgba(0, 243, 255, 0.6);
|
||||
}
|
||||
|
||||
.jarvis-date-panel {
|
||||
min-height: 258px;
|
||||
}
|
||||
@@ -2144,8 +2224,8 @@
|
||||
.jarvis-focus-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 208px;
|
||||
max-height: 238px;
|
||||
min-height: 140px;
|
||||
max-height: 180px;
|
||||
}
|
||||
|
||||
.jarvis-review-panel {
|
||||
@@ -2271,6 +2351,13 @@
|
||||
.status-dot.done { background: #22c55e; }
|
||||
.status-dot.doing { background: #f59e0b; }
|
||||
.status-dot.pending { background: #ef4444; }
|
||||
.status-dot.total { background: #38bdf8; }
|
||||
|
||||
.jarvis-status-item.is-total {
|
||||
border-top: 1px solid rgba(56, 189, 248, 0.2);
|
||||
padding-top: 8px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.status-label {
|
||||
color: rgba(178, 220, 236, 0.72);
|
||||
@@ -2282,8 +2369,9 @@
|
||||
}
|
||||
|
||||
.jarvis-focus-list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
@@ -2291,30 +2379,45 @@
|
||||
}
|
||||
|
||||
.jarvis-focus-item {
|
||||
display: grid;
|
||||
grid-template-columns: 30px minmax(0, 1fr);
|
||||
gap: 10px;
|
||||
padding: 11px 12px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 8px;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.jarvis-focus-item.is-doing { border-color: rgba(250, 204, 21, 0.24); }
|
||||
.jarvis-focus-item.is-pending { border-color: rgba(251, 113, 133, 0.18); }
|
||||
.jarvis-focus-item.is-done { border-color: rgba(74, 222, 128, 0.18); }
|
||||
.jarvis-focus-item.is-doing { background: rgba(250, 204, 21, 0.08); }
|
||||
.jarvis-focus-item.is-pending { background: rgba(251, 113, 133, 0.06); }
|
||||
.jarvis-focus-item.is-done { background: rgba(74, 222, 128, 0.06); }
|
||||
|
||||
.jarvis-focus-item.is-done .focus-order.is-done {
|
||||
background: rgba(74, 222, 128, 0.15);
|
||||
color: #22c55e;
|
||||
}
|
||||
|
||||
.focus-check {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.focus-title.is-done {
|
||||
text-decoration: line-through;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.focus-order {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 10px;
|
||||
background: rgba(56, 189, 248, 0.12);
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 6px;
|
||||
background: rgba(56, 189, 248, 0.1);
|
||||
color: #8de7ff;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.focus-copy {
|
||||
@@ -2322,24 +2425,19 @@
|
||||
}
|
||||
|
||||
.focus-label {
|
||||
margin-bottom: 4px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 9px;
|
||||
letter-spacing: 0.12em;
|
||||
color: rgba(141, 231, 255, 0.52);
|
||||
text-transform: uppercase;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.focus-title {
|
||||
font-size: 13px;
|
||||
line-height: 1.45;
|
||||
font-size: 12px;
|
||||
color: #eefbff;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.focus-meta {
|
||||
margin-top: 4px;
|
||||
font-size: 11px;
|
||||
color: rgba(178, 220, 236, 0.62);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jarvis-review-group + .jarvis-review-group {
|
||||
|
||||
@@ -58,6 +58,9 @@ export function useSidebarPlan(clientTimeRef: { value: Date }, loadDailyDigestFn
|
||||
return cells
|
||||
})
|
||||
|
||||
const calendarYear = computed(() => clientTimeRef.value.getFullYear())
|
||||
const calendarMonth = computed(() => clientTimeRef.value.getMonth() + 1)
|
||||
|
||||
const todayPlanCounters = computed(() => {
|
||||
const detail = todayPlanDetail.value
|
||||
if (!detail) return { done: 0, doing: 0, pending: 0, total: 0, completion: 0 }
|
||||
@@ -91,38 +94,56 @@ export function useSidebarPlan(clientTimeRef: { value: Date }, loadDailyDigestFn
|
||||
{ todoTotal: 0, todoCompleted: 0, taskTotal: 0, reminderTotal: 0, goalTotal: 0, highPriorityTotal: 0, activeDays: 0 },
|
||||
))
|
||||
|
||||
const sidebarWeekLabels = ['一', '二', '三', '四', '五', '六', '日']
|
||||
const sidebarWeekLabels = [
|
||||
{ label: '一', isWeekend: false },
|
||||
{ label: '二', isWeekend: false },
|
||||
{ label: '三', isWeekend: false },
|
||||
{ label: '四', isWeekend: false },
|
||||
{ label: '五', isWeekend: false },
|
||||
{ label: '六', isWeekend: true },
|
||||
{ label: '日', isWeekend: true },
|
||||
]
|
||||
|
||||
const sidebarStatusHeadline = computed(() => (
|
||||
todayPlanCounters.value.total
|
||||
? `今日共 ${todayPlanCounters.value.total} 项计划,已完成 ${todayPlanCounters.value.done} 项`
|
||||
: '今日计划正在同步,稍后会显示最新状态'
|
||||
: ''
|
||||
))
|
||||
|
||||
const sidebarStatusBreakdown = computed(() => [
|
||||
{ key: 'done', label: '已完成', value: todayPlanCounters.value.done, tone: 'done' },
|
||||
{ key: 'doing', label: '进行中', value: todayPlanCounters.value.doing, tone: 'doing' },
|
||||
{ key: 'pending', label: '未开始', value: todayPlanCounters.value.pending, tone: 'pending' },
|
||||
{ key: 'total', label: '今日合计', value: todayPlanCounters.value.total, tone: 'total' },
|
||||
])
|
||||
|
||||
// 模拟数据 - 用于测试滑动条
|
||||
const mockFocusItems: SidebarFocusItem[] = [
|
||||
{ id: 'mock-1', label: '任务', title: '完成用户登录模块开发', meta: '处理中', tone: 'doing' },
|
||||
{ id: 'mock-2', label: '任务', title: '修复首页加载慢的问题', meta: '待启动', tone: 'pending' },
|
||||
{ id: 'mock-3', label: '目标', title: '本周完成核心功能上线', meta: '今日目标推进', tone: 'doing' },
|
||||
{ id: 'mock-4', label: '待办', title: '整理本周工作报告', meta: '手动记录', tone: 'done' },
|
||||
{ id: 'mock-5', label: '任务', title: '优化数据库查询性能', meta: '待启动', tone: 'pending' },
|
||||
{ id: 'mock-6', label: '提醒', title: '下午3点团队会议', meta: '15:00', tone: 'pending' },
|
||||
{ id: 'mock-7', label: '任务', title: 'Code Review 代码审查', meta: '处理中', tone: 'doing' },
|
||||
{ id: 'mock-8', label: '待办', title: '更新项目文档', meta: '系统同步', tone: 'done' },
|
||||
{ id: 'mock-9', label: '任务', title: '部署测试环境', meta: '待启动', tone: 'pending' },
|
||||
{ id: 'mock-10', label: '目标', title: '本月用户增长10%', meta: '今日目标推进', tone: 'pending' },
|
||||
{ id: 'mock-11', label: '待办', title: '提交本周周报', meta: '手动记录', tone: 'done' },
|
||||
{ id: 'mock-12', label: '任务', title: '接口联调测试', meta: '待启动', tone: 'pending' },
|
||||
{ id: 'mock-13', label: '提醒', title: '周三产品评审会', meta: '14:00', tone: 'pending' },
|
||||
{ id: 'mock-14', label: '任务', title: '性能优化与监控', meta: '处理中', tone: 'doing' },
|
||||
{ id: 'mock-15', label: '待办', title: '备份重要数据', meta: '系统同步', tone: 'done' },
|
||||
{ id: 'mock-16', label: '任务', title: '编写单元测试用例', meta: '待启动', tone: 'pending' },
|
||||
{ id: 'mock-17', label: '目标', title: '提升系统安全性', meta: '今日目标推进', tone: 'pending' },
|
||||
{ id: 'mock-18', label: '待办', title: '清理无用代码文件', meta: '手动记录', tone: 'done' },
|
||||
{ id: 'mock-19', label: '任务', title: '配置CI/CD自动化部署', meta: '待启动', tone: 'pending' },
|
||||
{ id: 'mock-20', label: '提醒', title: '周五项目复盘会', meta: '10:00', tone: 'pending' },
|
||||
]
|
||||
|
||||
const sidebarFocusItems = computed<SidebarFocusItem[]>(() => {
|
||||
const detail = todayPlanDetail.value
|
||||
if (!detail) return []
|
||||
const goalItems = detail.goals.filter((goal) => goal.status !== 'done').map((goal) => ({
|
||||
id: `goal-${goal.id}`, label: '目标', title: goal.title, meta: goal.note || '今日目标推进', tone: 'doing' as const,
|
||||
}))
|
||||
const taskItems = detail.tasks.filter((task) => task.status !== 'done' && task.status !== 'cancelled')
|
||||
.sort((a, b) => { const r = { urgent: 0, high: 1, medium: 2, low: 3 }; return r[a.priority] - r[b.priority] })
|
||||
.map((task) => ({
|
||||
id: `task-${task.id}`, label: task.priority === 'urgent' || task.priority === 'high' ? '高优任务' : '任务',
|
||||
title: task.title, meta: task.status === 'in_progress' ? '处理中' : '待启动',
|
||||
tone: task.status === 'in_progress' ? 'doing' as const : 'pending' as const,
|
||||
}))
|
||||
const reminderItems = detail.reminders.filter((r) => r.status !== 'done' && !r.is_dismissed)
|
||||
.map((r) => ({ id: `reminder-${r.id}`, label: '提醒', title: r.title, meta: r.reminder_at.slice(11, 16), tone: 'pending' as const }))
|
||||
const todoItems = detail.todos.filter((t) => !t.is_completed)
|
||||
.map((t) => ({ id: `todo-${t.id}`, label: '待办', title: t.title, meta: t.source === 'manual' ? '手动记录' : '系统同步', tone: 'pending' as const }))
|
||||
return [...goalItems, ...taskItems, ...reminderItems, ...todoItems].slice(0, 5)
|
||||
// 暂时强制返回模拟数据用于测试
|
||||
return mockFocusItems
|
||||
})
|
||||
|
||||
const sidebarReviewAchievements = computed(() => {
|
||||
@@ -186,7 +207,7 @@ export function useSidebarPlan(clientTimeRef: { value: Date }, loadDailyDigestFn
|
||||
|
||||
return {
|
||||
todayPlanDetail, monthPlanDays, todayDateKey, monthPlanSummaryMap,
|
||||
calendarCells, todayPlanCounters, monthReviewStats,
|
||||
calendarCells, calendarYear, calendarMonth, todayPlanCounters, monthReviewStats,
|
||||
sidebarWeekLabels, sidebarStatusHeadline, sidebarStatusBreakdown,
|
||||
sidebarFocusItems, sidebarReviewAchievements, sidebarReviewReflections,
|
||||
sidebarFeedItems, topbarFeedItems, loadSidebarPlanSnapshot, sidebarCollapsedModules
|
||||
|
||||
@@ -69,7 +69,7 @@ const { dailyDigest, digestLoading, activeReminder, reminderVisible, loadDailyDi
|
||||
|
||||
// --- Sidebar plan (calendar, focus, review) ---
|
||||
const {
|
||||
calendarCells, todayPlanCounters,
|
||||
calendarCells, calendarYear, calendarMonth, todayPlanCounters,
|
||||
sidebarWeekLabels, sidebarStatusHeadline, sidebarStatusBreakdown,
|
||||
sidebarFocusItems, sidebarReviewAchievements, sidebarReviewReflections,
|
||||
sidebarFeedItems, topbarFeedItems, sidebarCollapsedModules
|
||||
@@ -211,16 +211,6 @@ function renderMarkdown(content: string) {
|
||||
<div class="chat-view">
|
||||
<!-- Conversation list sidebar -->
|
||||
<aside class="conv-sidebar jarvis-sidebar" :class="{ collapsed: sidebarCollapsed }">
|
||||
<button
|
||||
class="jarvis-sidebar-toggle"
|
||||
type="button"
|
||||
:title="sidebarCollapsed ? '展开侧边栏' : '折叠侧边栏'"
|
||||
:aria-label="sidebarCollapsed ? '展开侧边栏' : '折叠侧边栏'"
|
||||
@click="sidebarCollapsed = !sidebarCollapsed"
|
||||
>
|
||||
<ChevronRight :size="14" class="jarvis-sidebar-toggle-icon" :class="{ expanded: !sidebarCollapsed }" />
|
||||
</button>
|
||||
|
||||
<div v-if="sidebarCollapsed" class="jarvis-sidebar-icon-rail">
|
||||
<button
|
||||
v-for="module in sidebarCollapsedModules"
|
||||
@@ -247,7 +237,7 @@ function renderMarkdown(content: string) {
|
||||
|
||||
<div class="jarvis-calendar">
|
||||
<div class="calendar-header">
|
||||
<span v-for="label in sidebarWeekLabels" :key="label">{{ label }}</span>
|
||||
<span v-for="item in sidebarWeekLabels" :key="item.label" :class="{ 'is-weekend': item.isWeekend }">{{ item.label }}</span>
|
||||
</div>
|
||||
<div class="calendar-grid">
|
||||
<span
|
||||
@@ -274,11 +264,11 @@ function renderMarkdown(content: string) {
|
||||
</div>
|
||||
|
||||
<div class="jarvis-status-copy">
|
||||
<div class="jarvis-status-headline">
|
||||
<div v-if="sidebarStatusHeadline" class="jarvis-status-headline">
|
||||
{{ sidebarStatusHeadline }}
|
||||
</div>
|
||||
<ul class="jarvis-status-list">
|
||||
<li v-for="item in sidebarStatusBreakdown" :key="item.key" class="jarvis-status-item">
|
||||
<li v-for="item in sidebarStatusBreakdown" :key="item.key" class="jarvis-status-item" :class="{ 'is-total': item.key === 'total' }">
|
||||
<span class="status-dot" :class="item.tone"></span>
|
||||
<span class="status-label">{{ item.label }}</span>
|
||||
<strong class="status-value">{{ item.value }}</strong>
|
||||
@@ -292,10 +282,13 @@ function renderMarkdown(content: string) {
|
||||
<div class="jarvis-section-title">今日计划重点</div>
|
||||
<ul v-if="sidebarFocusItems.length > 0" class="jarvis-focus-list">
|
||||
<li v-for="(item, index) in sidebarFocusItems" :key="item.id" class="jarvis-focus-item" :class="`is-${item.tone}`">
|
||||
<span class="focus-order">{{ String(index + 1).padStart(2, '0') }}</span>
|
||||
<span class="focus-order" :class="{ 'is-done': item.tone === 'done' }">
|
||||
<span v-if="item.tone === 'done'" class="focus-check">✓</span>
|
||||
<span v-else>{{ String(index + 1).padStart(2, '0') }}</span>
|
||||
</span>
|
||||
<div class="focus-copy">
|
||||
<div class="focus-label">{{ item.label }}</div>
|
||||
<div class="focus-title">{{ item.title }}</div>
|
||||
<div class="focus-title" :class="{ 'is-done': item.tone === 'done' }">{{ item.title }}</div>
|
||||
<div class="focus-meta">{{ item.meta }}</div>
|
||||
</div>
|
||||
</li>
|
||||
@@ -329,9 +322,9 @@ function renderMarkdown(content: string) {
|
||||
<!-- Top bar -->
|
||||
<div class="chat-topbar">
|
||||
<div class="chat-shortcuts">
|
||||
<NavShortcutRow
|
||||
@select-folder="handleSelectFolder"
|
||||
@open-knowledge-hud="openKnowledgeHud"
|
||||
<NavShortcutRow
|
||||
@select-folder="handleSelectFolder"
|
||||
@open-knowledge-hud="openKnowledgeHud"
|
||||
/>
|
||||
</div>
|
||||
<div class="chat-model-panel">
|
||||
@@ -484,17 +477,14 @@ function renderMarkdown(content: string) {
|
||||
|
||||
<!-- Top buttons above input -->
|
||||
<div class="top-buttons-row">
|
||||
<button class="top-action-btn" @click="$router.push('/temple')">
|
||||
<span class="btn-icon">⛩️</span>
|
||||
<span class="btn-text">智慧神殿</span>
|
||||
<button class="top-action-btn" @click="$router.push('/temple')" title="Temple">
|
||||
<span class="btn-icon temple-icon">◈</span>
|
||||
</button>
|
||||
<button class="top-action-btn" @click="$router.push('/knowledge')">
|
||||
<span class="btn-icon">📚</span>
|
||||
<span class="btn-text">知识仓库</span>
|
||||
<button class="top-action-btn" @click="$router.push('/knowledge')" title="Knowledge">
|
||||
<span class="btn-icon knowledge-icon">◉</span>
|
||||
</button>
|
||||
<button class="top-action-btn" @click="$router.push('/war-room')">
|
||||
<span class="btn-icon">🗺️</span>
|
||||
<span class="btn-text">战情室</span>
|
||||
<button class="top-action-btn" @click="$router.push('/war-room')" title="War Room">
|
||||
<span class="btn-icon war-icon">⬡</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user