the kebab menu calls the date on tasks a due date, but it's not a due date... it's just a date. can we make sure the codebase, documentation and everything is consistent about this?
- Renamed `due_date` field on Task struct to `date` (Rust, TypeScript, all usages) - Renamed `group_by_due_date` field on TaskList/ListMetadata to `group_by_date` - Renamed `set_group_by_due_date`/`get_group_by_due_date` methods to `set_group_by_date`/`get_group_by_date` in repository, Tauri commands, and JS store - Renamed `with_due_date()` builder method to `with_date()` - Renamed `parse_due_date` CLI function to `parse_date` - Updated UI text "Group by due date" → "Group by date" in TasksScreen.svelte kebab menu - Renamed JS variables `dueDate`/`dueDateHasTime` → `date`/`dateHasTime` in NewTaskInput.svelte - Updated all test names and assertions across models.rs and repository.rs - Updated CLAUDE.md documentation to use "date" terminology consistently Close kebab menu when toggling subtasks When toggling the "show subtasks" option from the main panel kebab menu, the menu remained open which could obscure UI and lead to unexpected interactions. Ensure that opening/closing the subtasks list also closes the kebab (showListMenu = false) so the menu is dismissed when the user chooses to view subtasks. can we animate opening and closing of the kebab menus? Also, lets move the "NO DATE" section when selecting Group By Date to the top of the list before OVERDUE - app.css: added CSS @starting-style + display transition on .dropdown-menu for open/close scale+fade animation - app.svelte.ts: moved "No Date" group to the top (before "Overdue") in groupedPendingTasks
This commit is contained in:
parent
6a4b79801b
commit
afedac7d32
|
|
@ -248,7 +248,7 @@ body {
|
|||
border-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/* ── Dropdown/kebab menu shadow ──────────────────────────────────── */
|
||||
/* ── Dropdown/kebab menu shadow + open/close animation ───────────── */
|
||||
|
||||
.menu-shadow {
|
||||
box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.12);
|
||||
|
|
@ -257,6 +257,18 @@ body {
|
|||
box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
transition: opacity 120ms ease, transform 120ms ease, display 120ms ease allow-discrete;
|
||||
transform-origin: top right;
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
|
||||
@starting-style {
|
||||
opacity: 0;
|
||||
transform: scale(0.92);
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Borderless mode: square corners on all popups/overlays ─────── */
|
||||
|
||||
.decorations-none .rounded-sm,
|
||||
|
|
|
|||
|
|
@ -139,8 +139,8 @@
|
|||
<!-- Date picker overlay -->
|
||||
{#if showDatePicker}
|
||||
<DateTimePicker
|
||||
value={dueDate}
|
||||
has_time={dueDateHasTime}
|
||||
value={date}
|
||||
has_time={dateHasTime}
|
||||
onchange={handleDateChange}
|
||||
onclose={() => (showDatePicker = false)}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -118,12 +118,12 @@
|
|||
renamingListId = null;
|
||||
}
|
||||
|
||||
async function handleToggleGroupByDueDate() {
|
||||
async function handleToggleGroupByDate() {
|
||||
showListMenu = false;
|
||||
if (!app.activeListId) return;
|
||||
var list = app.lists.find(l => l.id === app.activeListId);
|
||||
if (!list) return;
|
||||
await app.setGroupByDueDate(app.activeListId, !list.group_by_due_date);
|
||||
await app.setGroupByDate(app.activeListId, !list.group_by_date);
|
||||
}
|
||||
|
||||
function handleKeydown(e: KeyboardEvent) {
|
||||
|
|
@ -188,16 +188,16 @@
|
|||
const targetGroup = app.groupedPendingTasks?.find((g) => g.label === group);
|
||||
const task = app.pendingTasks.find((t) => t.id === taskId);
|
||||
if (task && targetGroup !== undefined) {
|
||||
let newDueDate: string | null = null;
|
||||
let newDate: string | null = null;
|
||||
if (targetGroup.date !== null) {
|
||||
const target = new Date(targetGroup.date);
|
||||
if (task.has_time && task.due_date) {
|
||||
const existing = new Date(task.due_date);
|
||||
if (task.has_time && task.date) {
|
||||
const existing = new Date(task.date);
|
||||
target.setHours(existing.getHours(), existing.getMinutes(), existing.getSeconds(), 0);
|
||||
}
|
||||
newDueDate = target.toISOString();
|
||||
newDate = target.toISOString();
|
||||
}
|
||||
await app.updateTask({ ...task, due_date: newDueDate, has_time: newDueDate ? task.has_time : false });
|
||||
await app.updateTask({ ...task, date: newDate, has_time: newDate ? task.has_time : false });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -554,21 +554,21 @@
|
|||
</button>
|
||||
{/if}
|
||||
<button
|
||||
onclick={handleToggleGroupByDueDate}
|
||||
onclick={handleToggleGroupByDate}
|
||||
class="flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-black/5 dark:hover:bg-white/10"
|
||||
>
|
||||
<svg class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Group by due date
|
||||
{#if app.activeList?.group_by_due_date}
|
||||
Group by date
|
||||
{#if app.activeList?.group_by_date}
|
||||
<svg class="ml-auto h-4 w-4 text-primary" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" />
|
||||
</svg>
|
||||
{/if}
|
||||
</button>
|
||||
<button
|
||||
onclick={() => (showSubtasks = !showSubtasks)}
|
||||
onclick={() => { showSubtasks = !showSubtasks; showListMenu = false; }}
|
||||
class="flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-black/5 dark:hover:bg-white/10"
|
||||
>
|
||||
<svg class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ let groupedPendingTasks = $derived.by((): TaskGroup[] | null => {
|
|||
tomorrow.sort(sortByDue);
|
||||
|
||||
const groups: TaskGroup[] = [];
|
||||
if (noDate.length) groups.push({ label: "No Date", tasks: noDate, date: null });
|
||||
if (overdue.length) groups.push({ label: "Overdue", tasks: overdue, date: null });
|
||||
if (today.length) groups.push({ label: "Today", tasks: today, date: todayStart });
|
||||
if (tomorrow.length) groups.push({ label: "Tomorrow", tasks: tomorrow, date: tomorrowStart });
|
||||
|
|
@ -108,7 +109,6 @@ let groupedPendingTasks = $derived.by((): TaskGroup[] | null => {
|
|||
groups.push({ label: date.toLocaleDateString(undefined, opts), tasks, date });
|
||||
}
|
||||
|
||||
if (noDate.length) groups.push({ label: "No Date", tasks: noDate, date: null });
|
||||
return groups;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -310,8 +310,8 @@ pub async fn sync_google_tasks(
|
|||
TaskStatus::Backlog
|
||||
};
|
||||
|
||||
// Google Tasks due dates are date-only (time is always T00:00:00Z).
|
||||
let due_date = gt_task.due.as_deref()
|
||||
// Google Tasks dates are date-only (time is always T00:00:00Z).
|
||||
let date = gt_task.due.as_deref()
|
||||
.and_then(|s| s.parse::<DateTime<Utc>>().ok());
|
||||
|
||||
let parent_id = gt_task.parent.as_deref().map(gt_id_to_uuid);
|
||||
|
|
@ -321,7 +321,7 @@ pub async fn sync_google_tasks(
|
|||
title: gt_task.title.clone(),
|
||||
description: gt_task.notes.clone(),
|
||||
status,
|
||||
due_date,
|
||||
date,
|
||||
has_time: false,
|
||||
version: 1,
|
||||
parent_id,
|
||||
|
|
@ -441,7 +441,7 @@ fn render_task_markdown(task: &Task) -> String {
|
|||
TaskStatus::Completed => "completed",
|
||||
};
|
||||
let mut yaml = format!("id: {}\nstatus: {}\nversion: 1\n", task.id, status_str);
|
||||
if let Some(due) = task.due_date {
|
||||
if let Some(due) = task.date {
|
||||
yaml.push_str(&format!("due: {}\n", due.to_rfc3339()));
|
||||
}
|
||||
if let Some(parent) = task.parent_id {
|
||||
|
|
|
|||
|
|
@ -166,10 +166,10 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_task_with_due_date() {
|
||||
fn test_task_with_date() {
|
||||
let dt = Utc::now();
|
||||
let task = Task::new("T".to_string()).with_due_date(dt);
|
||||
assert_eq!(task.due_date, Some(dt));
|
||||
let task = Task::new("T".to_string()).with_date(dt);
|
||||
assert_eq!(task.date, Some(dt));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -242,7 +242,7 @@ mod tests {
|
|||
let list = TaskList::new("My List".to_string());
|
||||
assert_eq!(list.title, "My List");
|
||||
assert!(list.tasks.is_empty());
|
||||
assert!(!list.group_by_due_date);
|
||||
assert!(!list.group_by_date);
|
||||
assert!(list.created_at <= Utc::now());
|
||||
assert!(list.updated_at <= Utc::now());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ impl From<&Task> for TaskFrontmatter {
|
|||
Self {
|
||||
id: task.id,
|
||||
status: task.status,
|
||||
due: task.due_date,
|
||||
due: task.date,
|
||||
has_time: task.has_time,
|
||||
version: task.version,
|
||||
parent: task.parent_id,
|
||||
|
|
|
|||
Loading…
Reference in a new issue