Merge pull request 'enlarge journal calendar cells and pair day/title on one line' (#1) from journal-calendar-ui-tweaks into main
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -116,10 +116,15 @@ class JournalAttachmentOut(BaseModel):
|
||||
has_thumbnail: bool
|
||||
|
||||
|
||||
class JournalCalendarEntry(BaseModel):
|
||||
color: str # 그 엔트리가 속한 카테고리 색상 (점 표시용)
|
||||
title: str # 제목(없으면 내용 일부)
|
||||
|
||||
|
||||
class JournalCalendarDay(BaseModel):
|
||||
entry_date: date
|
||||
total_count: int
|
||||
category_colors: list[str] # 그 날 엔트리가 있는 카테고리들의 색상(점 표시용, 중복 제거)
|
||||
entries: list[JournalCalendarEntry] # 엔트리별 (색상, 제목) 쌍 — 점과 제목이 한 줄에 붙어 나오도록 1:1로 매칭
|
||||
|
||||
|
||||
class JournalDayDetailItem(BaseModel):
|
||||
|
||||
@@ -23,6 +23,7 @@ from app.models.journal import (
|
||||
from app.schemas.journal import (
|
||||
JournalAttachmentOut,
|
||||
JournalCalendarDay,
|
||||
JournalCalendarEntry,
|
||||
JournalCategoryCreate,
|
||||
JournalDayDetailItem,
|
||||
JournalEntryCreate,
|
||||
@@ -363,25 +364,33 @@ def get_monthly_journal_summary(
|
||||
last_day = date(year, month, days_in_month)
|
||||
|
||||
stmt = (
|
||||
select(JournalEntry.entry_date, JournalCategory.color)
|
||||
select(JournalEntry.entry_date, JournalCategory.color, JournalEntry.title, JournalEntry.content)
|
||||
.join(JournalCategory, JournalEntry.category_id == JournalCategory.id)
|
||||
.where(JournalEntry.user_id == user_id, JournalEntry.entry_date.between(first_day, last_day))
|
||||
.order_by(JournalEntry.entry_date, JournalEntry.created_at)
|
||||
)
|
||||
if category_id is not None:
|
||||
stmt = stmt.where(JournalEntry.category_id == category_id)
|
||||
rows = db.execute(stmt).all()
|
||||
|
||||
counts: dict[date, int] = {}
|
||||
colors_by_date: dict[date, list[str]] = {}
|
||||
for entry_date, color in rows:
|
||||
entries_by_date: dict[date, list[JournalCalendarEntry]] = {}
|
||||
for entry_date, color, title, content in rows:
|
||||
counts[entry_date] = counts.get(entry_date, 0) + 1
|
||||
colors = colors_by_date.setdefault(entry_date, [])
|
||||
color = color or "var(--color-accent)"
|
||||
if color not in colors:
|
||||
colors.append(color)
|
||||
entries = entries_by_date.setdefault(entry_date, [])
|
||||
entries.append(
|
||||
JournalCalendarEntry(
|
||||
color=color or "var(--color-accent)",
|
||||
title=title or (content[:12] + ("…" if len(content) > 12 else "")),
|
||||
)
|
||||
)
|
||||
|
||||
return {
|
||||
d: JournalCalendarDay(entry_date=d, total_count=counts[d], category_colors=colors_by_date[d])
|
||||
d: JournalCalendarDay(
|
||||
entry_date=d,
|
||||
total_count=counts[d],
|
||||
entries=entries_by_date[d],
|
||||
)
|
||||
for d in counts
|
||||
}
|
||||
|
||||
|
||||
@@ -872,15 +872,48 @@ label {
|
||||
}
|
||||
|
||||
/* 저널링 */
|
||||
.journal-day-dots {
|
||||
.calendar-cell-journal {
|
||||
aspect-ratio: auto;
|
||||
min-height: 76px;
|
||||
padding: 6px 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.calendar-cell-journal .calendar-date {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.journal-day-entries {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.journal-day-entry {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.journal-day-dot {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.journal-day-title {
|
||||
min-width: 0;
|
||||
font-size: 10px;
|
||||
line-height: 1.3;
|
||||
color: var(--color-text-muted);
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.journal-prompt-card,
|
||||
|
||||
@@ -252,16 +252,19 @@
|
||||
{% for d in week %}
|
||||
{% set day_summary = summary_map.get(d) %}
|
||||
<div
|
||||
class="calendar-cell clickable{{ '' if d.month == month else ' muted' }}"
|
||||
class="calendar-cell calendar-cell-journal clickable{{ '' if d.month == month else ' muted' }}"
|
||||
hx-get="/journal/day/{{ d.isoformat() }}"
|
||||
hx-target="#day-detail"
|
||||
hx-swap="innerHTML"
|
||||
>
|
||||
<span class="calendar-date">{{ d.day }}</span>
|
||||
{% if day_summary %}
|
||||
<span class="journal-day-dots">
|
||||
{% for color in day_summary.category_colors %}
|
||||
<span class="journal-day-dot" style="background: {{ color }};"></span>
|
||||
<span class="journal-day-entries">
|
||||
{% for entry in day_summary.entries %}
|
||||
<span class="journal-day-entry">
|
||||
<span class="journal-day-dot" style="background: {{ entry.color }};"></span>
|
||||
<span class="journal-day-title">{{ entry.title }}</span>
|
||||
</span>
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
@@ -285,7 +285,7 @@ def test_get_monthly_journal_summary_counts_entries_per_day(db_session, test_use
|
||||
|
||||
summary = journal_service.get_monthly_journal_summary(db_session, test_user.id, today.year, today.month)
|
||||
assert summary[today].total_count == 2
|
||||
assert summary[today].category_colors == ["#ff0000"]
|
||||
assert [e.color for e in summary[today].entries] == ["#ff0000", "#ff0000"]
|
||||
|
||||
|
||||
def test_get_day_entries_returns_entries_for_that_date(db_session, test_user):
|
||||
|
||||
Reference in New Issue
Block a user