tag hiding in buckets to prevent orphaning

This commit is contained in:
2026-02-19 17:36:04 -06:00
parent 96ee1168b1
commit 9d8e80a2bf
2 changed files with 49 additions and 9 deletions
+32 -6
View File
@@ -1,6 +1,6 @@
import { type Component, createEffect, createSignal, For } from "solid-js";
import { type Component, createEffect, createSignal, For, createMemo } from "solid-js";
import { Sheet, SheetContent } from "@/components/ui/sheet";
import { type Task, removeTask, restoreTask, updateTask, saveTaskAsTemplate, shareTask, revokeShare, splitTask, loadTaskContent } from "@/store";
import { type Task, removeTask, restoreTask, updateTask, saveTaskAsTemplate, shareTask, revokeShare, splitTask, loadTaskContent, currentTaskContext } from "@/store";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { ArrowUpCircle, Clock, Calendar, Type, Trash2, X, Copy, MoreHorizontal, Gauge, Share2, UserMinus, GitBranch, Tag, Settings } from "lucide-solid";
@@ -96,7 +96,19 @@ export const TaskDetail: Component<TaskDetailProps> = (props) => {
};
const updateTags = (tags: string[]) => {
updateTask(props.task.id, { tags });
const ctx = currentTaskContext();
let newTags = [...tags];
// If in a bucket view, ensure the bucket tag is preserved (it was hidden from the UI so it's missing from 'tags')
if (typeof ctx === 'object' && 'bucketId' in ctx) {
const bucketName = (ctx as { name: string }).name;
// Check case-insensitive existence
if (!newTags.some(t => t.toLowerCase() === bucketName.toLowerCase())) {
newTags.push(bucketName);
}
}
updateTask(props.task.id, { tags: newTags });
};
const onDateInputChange = (e: Event) => {
@@ -110,6 +122,20 @@ export const TaskDetail: Component<TaskDetailProps> = (props) => {
// Calculate current urgency level for display
const currentUrgency = () => calculateUrgencyFromDate(props.task.dueDate).toString();
// Filter out bucket tags if we are currently INSIDE that bucket view
const visibleTags = createMemo(() => {
const tags = props.task.tags || [];
const ctx = currentTaskContext();
if (typeof ctx === 'object' && 'bucketId' in ctx) {
// We are in a bucket view. Hide the tag that matches this bucket's name.
const bucketName = (ctx as { name: string }).name.toLowerCase();
return tags.filter(t => t.toLowerCase() !== bucketName);
}
return tags;
});
return (
<Sheet open={props.isOpen} onOpenChange={(open) => {
if (!open) {
@@ -333,11 +359,11 @@ export const TaskDetail: Component<TaskDetailProps> = (props) => {
<span class="text-[0.625rem] uppercase font-bold tracking-wider text-muted-foreground/60 shrink-0">Tags</span>
<div class="flex flex-wrap items-center gap-1.5 min-w-0 flex-1">
<TagPicker
selectedTags={props.task.tags || []}
selectedTags={visibleTags()}
onTagsChange={updateTags}
/>
<div class="flex flex-wrap items-center gap-1.5">
<For each={props.task.tags || []}>
<For each={visibleTags()}>
{(tag) => (
<Badge
variant="secondary"
@@ -358,7 +384,7 @@ export const TaskDetail: Component<TaskDetailProps> = (props) => {
return getThemeAdjustedColor(def?.color, def?.theme, resolvedTheme()) || "inherit";
})()
}}
onClick={() => updateTags((props.task.tags || []).filter(t => t !== tag))}
onClick={() => updateTags(visibleTags().filter(t => t !== tag))}
>
<div
class="w-1.5 h-1.5 rounded-full"