feat: закрытые задачи в глобальном поиске зачёркнуты + бейдж статуса
searchTasksByKeyword теперь возвращает isCompleted и через leftJoin formStatuses — statusName/statusColor/statusIsFinal. В HomeGlobalSearch закрытые задачи (isCompleted || statusIsFinal) зачёркнуты и приглушены, у каждой задачи цветной бейдж текущего статуса.
This commit is contained in:
@@ -16,6 +16,10 @@ interface TaskItem {
|
||||
id: number;
|
||||
title: string;
|
||||
formId: number;
|
||||
isCompleted?: boolean;
|
||||
statusName?: string | null;
|
||||
statusColor?: string | null;
|
||||
statusIsFinal?: boolean | null;
|
||||
}
|
||||
|
||||
interface HomeGlobalSearchProps {
|
||||
@@ -120,16 +124,27 @@ export function HomeGlobalSearch({ className }: HomeGlobalSearchProps) {
|
||||
{tasks.length > 0 && (
|
||||
<div>
|
||||
<div className="px-2 py-1 text-[10px] font-semibold text-muted-foreground uppercase">Задачи</div>
|
||||
{tasks.map((t) => (
|
||||
<button
|
||||
key={`task-${t.id}`}
|
||||
className="w-full flex items-center gap-2 px-2 py-1.5 text-xs hover:bg-accent rounded text-left"
|
||||
onClick={() => handleSelectTask(t)}
|
||||
>
|
||||
<CheckSquare className="w-3.5 h-3.5 text-muted-foreground shrink-0" />
|
||||
<span className="truncate">{t.title}</span>
|
||||
</button>
|
||||
))}
|
||||
{tasks.map((t) => {
|
||||
const isClosed = !!t.isCompleted || !!t.statusIsFinal;
|
||||
return (
|
||||
<button
|
||||
key={`task-${t.id}`}
|
||||
className="w-full flex items-center gap-2 px-2 py-1.5 text-xs hover:bg-accent rounded text-left"
|
||||
onClick={() => handleSelectTask(t)}
|
||||
>
|
||||
<CheckSquare className={cn('w-3.5 h-3.5 shrink-0', isClosed ? 'text-muted-foreground/60' : 'text-muted-foreground')} />
|
||||
<span className={cn('truncate flex-1 min-w-0', isClosed && 'line-through text-muted-foreground')}>{t.title}</span>
|
||||
{t.statusName && (
|
||||
<span
|
||||
className="shrink-0 px-1.5 py-0.5 rounded text-[10px] leading-none"
|
||||
style={{ backgroundColor: (t.statusColor || '#6b7280') + '20', color: t.statusColor || '#6b7280' }}
|
||||
>
|
||||
{t.statusName}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -195,7 +195,7 @@ export interface IStorage {
|
||||
updateTask(id: number, organizationId: number, updates: Partial<Task>): Promise<Task>;
|
||||
updateTaskIfNotModified(id: number, organizationId: number, updates: Partial<Task>, requiredUpdatedAt: Date): Promise<Task | null>;
|
||||
deleteTask(id: number, organizationId: number): Promise<void>;
|
||||
searchTasksByKeyword(organizationId: number, query: string, limit?: number): Promise<Pick<Task, 'id' | 'title' | 'description' | 'formId' | 'currentStatusId'>[]>;
|
||||
searchTasksByKeyword(organizationId: number, query: string, limit?: number): Promise<(Pick<Task, 'id' | 'title' | 'description' | 'formId' | 'currentStatusId' | 'isCompleted'> & { statusName: string | null; statusColor: string | null; statusIsFinal: boolean | null })[]>;
|
||||
|
||||
// Task Field Values
|
||||
getTaskFieldValues(taskId: number, organizationId: number): Promise<TaskFieldValue[]>;
|
||||
|
||||
@@ -347,7 +347,7 @@ export class TasksCoreStorage extends FormsStorage {
|
||||
organizationId: number,
|
||||
query: string,
|
||||
limit: number = 10
|
||||
): Promise<Pick<Task, 'id' | 'title' | 'description' | 'formId' | 'currentStatusId'>[]> {
|
||||
): Promise<(Pick<Task, 'id' | 'title' | 'description' | 'formId' | 'currentStatusId' | 'isCompleted'> & { statusName: string | null; statusColor: string | null; statusIsFinal: boolean | null })[]> {
|
||||
const pattern = `%${query}%`;
|
||||
const results = await db
|
||||
.select({
|
||||
@@ -356,9 +356,14 @@ export class TasksCoreStorage extends FormsStorage {
|
||||
description: tasks.description,
|
||||
formId: tasks.formId,
|
||||
currentStatusId: tasks.currentStatusId,
|
||||
isCompleted: tasks.isCompleted,
|
||||
statusName: formStatuses.name,
|
||||
statusColor: formStatuses.color,
|
||||
statusIsFinal: formStatuses.isFinal,
|
||||
})
|
||||
.from(tasks)
|
||||
.innerJoin(forms, eq(tasks.formId, forms.id))
|
||||
.leftJoin(formStatuses, eq(tasks.currentStatusId, formStatuses.id))
|
||||
.where(
|
||||
and(
|
||||
eq(forms.organizationId, organizationId),
|
||||
|
||||
Reference in New Issue
Block a user