Files
taskplaner/.planning/phases/05-search/05-01-PLAN.md
Thomas Richter f6144f4edf docs(05): create phase plan
Phase 05: Search
- 3 plans in 2 waves
- Wave 1: 05-01 (UI components), 05-02 (filtering logic) — parallel
- Wave 2: 05-03 (integration + recent searches + "/" shortcut)
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 14:15:38 +01:00

6.5 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, must_haves
phase plan type wave depends_on files_modified autonomous must_haves
05-search 01 execute 1
src/lib/components/SearchBar.svelte
src/lib/components/FilterBar.svelte
src/lib/types/search.ts
true
truths artifacts key_links
Search input is visible at top of page
Filter controls (type, tags, date) are visible alongside search
User can type in search input
User can interact with filter controls
path provides min_lines
src/lib/components/SearchBar.svelte Text search input with debounced value binding 40
path provides min_lines
src/lib/components/FilterBar.svelte Filter controls for type, tags, and date range 60
path provides exports
src/lib/types/search.ts SearchFilters interface and default values
SearchFilters
defaultFilters
hasActiveFilters
from to via pattern
src/lib/components/SearchBar.svelte parent component $bindable value prop value = $bindable
from to via pattern
src/lib/components/FilterBar.svelte parent component onchange callback prop onchange.*SearchFilters
Create the search and filter UI components with type definitions.

Purpose: Establish the visual search/filter interface that users interact with. These components emit filter state changes but do not perform filtering themselves. Output: SearchBar.svelte, FilterBar.svelte, and search.ts type definitions ready for integration.

<execution_context> @/home/tho/.claude/get-shit-done/workflows/execute-plan.md @/home/tho/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/05-search/05-CONTEXT.md @.planning/phases/05-search/05-RESEARCH.md @src/lib/components/EntryList.svelte @src/lib/stores/preferences.svelte.ts Task 1: Create search types and utility functions src/lib/types/search.ts Create the SearchFilters interface and related utilities:
export interface SearchFilters {
  query: string;
  tags: string[];
  type: 'task' | 'thought' | 'all';
  dateRange: {
    start: string | null;
    end: string | null;
  };
}

export const defaultFilters: SearchFilters = {
  query: '',
  tags: [],
  type: 'all',
  dateRange: { start: null, end: null }
};

export function hasActiveFilters(filters: SearchFilters): boolean {
  return (
    filters.query.length >= 2 ||
    filters.tags.length > 0 ||
    filters.type !== 'all' ||
    filters.dateRange.start !== null ||
    filters.dateRange.end !== null
  );
}

// Date preset helper for quick date range selection
export function getDatePreset(preset: 'today' | 'week' | 'month'): { start: string; end: string } {
  const now = new Date();
  const end = now.toISOString().split('T')[0];

  let start: Date;
  switch (preset) {
    case 'today':
      start = now;
      break;
    case 'week':
      start = new Date(now);
      start.setDate(start.getDate() - 7);
      break;
    case 'month':
      start = new Date(now);
      start.setMonth(start.getMonth() - 1);
      break;
  }

  return {
    start: start.toISOString().split('T')[0],
    end
  };
}
TypeScript compiles without errors: `npx tsc --noEmit` SearchFilters interface exported and importable from other files Task 2: Create SearchBar component with debounced input src/lib/components/SearchBar.svelte Create SearchBar.svelte with: - Text input with placeholder 'Search entries... (press "/")' - Debounced value binding (300ms delay, using $effect cleanup pattern) - Only trigger search when query >= 2 characters OR when cleared to empty - Bindable value prop for parent to receive debounced search term - Styling: full width, px-4 py-2, border rounded-lg, focus ring

Props interface:

interface Props {
  value: string;  // bindable - the debounced search query
}

Implementation notes:

  • Use internal $state for inputValue (immediate user typing)
  • Use $effect with setTimeout/clearTimeout for debounce
  • Update the bound value only after debounce completes
  • Match existing Tailwind styling patterns from other components Component renders without errors when imported SearchBar accepts text input and exposes debounced value via $bindable prop
Task 3: Create FilterBar component with type, tag, and date controls src/lib/components/FilterBar.svelte Create FilterBar.svelte with:
  1. Type filter - three-state toggle (All / Tasks / Thoughts):

    • Use button group with active state highlighting
    • Default: 'all'
  2. Tag filter - multi-select from available tags:

    • Re-use existing Svelecte pattern from TagInput.svelte
    • Multiple selection enabled
    • AND logic (handled by filtering logic in Plan 02)
  3. Date range filter:

    • Quick preset buttons: Today, This week, This month
    • Custom range: two native date inputs (start/end)
    • Use getDatePreset helper from search.ts
  4. Clear/Reset button:

    • Only visible when hasActiveFilters() returns true
    • Resets all filters to defaultFilters

Props interface:

interface Props {
  filters: SearchFilters;
  availableTags: Tag[];
  onchange: (filters: SearchFilters) => void;
}

Layout:

  • Horizontal flex wrap on desktop
  • Stack vertically on mobile (use flex-wrap and gap)
  • Each filter group visually separated

Styling notes:

  • Match existing component patterns (border-gray-200, rounded-lg, focus:ring-2)
  • Active type button: bg-blue-100 text-blue-700
  • Inactive type button: bg-white text-gray-600 hover:bg-gray-50 Component renders with all filter controls visible and interactive FilterBar displays type toggle, tag selector, date range controls, and clear button (when filters active)
- `npm run check` passes (Svelte and TypeScript) - SearchBar and FilterBar import without errors - Type definitions are correct and exported

<success_criteria>

  • SearchBar.svelte renders with debounced text input
  • FilterBar.svelte renders with all filter controls (type, tags, date range)
  • Clear button appears only when filters are active
  • All components follow existing project patterns </success_criteria>
After completion, create `.planning/phases/05-search/05-01-SUMMARY.md`