Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2024-05-18 - Missing ARIA Expansion States on Custom Dropdowns
**Learning:** Custom popovers and dropdown triggers throughout the app (like Quick Tasks and Calendar View Options) often lack `aria-expanded` and `aria-haspopup` attributes, leaving screen reader users unaware of the dropdown's current open/closed state.
**Action:** When implementing custom toggle buttons that reveal dropdowns or dialogs, always dynamically bind `:aria-expanded="isOpen"` and include `aria-haspopup="dialog"` (or `listbox`/`menu`) to ensure state is announced to assistive technologies.
5 changes: 1 addition & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ jobs:
- name: Install Playwright (chromium)
run: npx playwright install --with-deps chromium

- name: Setup Supabase CLI
uses: supabase/setup-cli@v1
with:
version: latest


- name: Boot Supabase + run two-client Realtime e2e (R1–R7)
run: |
Expand Down
2 changes: 1 addition & 1 deletion scripts/run-e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
set -euo pipefail

# Auto-fetch keys from local Supabase if not already set
SUPABASE_STATUS_ENV="${SUPABASE_STATUS_ENV:-$(supabase status -o env 2>&1 || true)}"
SUPABASE_STATUS_ENV="${SUPABASE_STATUS_ENV:-$(npx supabase status -o env 2>&1 || true)}"

if [ -z "${SUPABASE_SERVICE_ROLE_KEY:-}" ]; then
# Try new-format secret key first (Supabase v2.x uses sb_secret_* instead of HS256 JWT)
Expand Down
16 changes: 8 additions & 8 deletions src/components/QuickSortCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ defineProps<{
}>()

const emit = defineEmits<{
(e: 'swipe-right'): void
(e: 'swipe-left'): void
(e: 'swipe-up'): void
(e: 'swipe-down'): void
(e: 'swipeRight'): void
(e: 'swipeLeft'): void
(e: 'swipeUp'): void
(e: 'swipeDown'): void
}>()

const cardRef = ref<HTMLElement | null>(null)
Expand All @@ -105,10 +105,10 @@ const {
haptics: true,
fourDirectional: true,
mouse: true,
onSwipeRight: () => emit('swipe-right'),
onSwipeLeft: () => emit('swipe-left'),
onSwipeUp: () => emit('swipe-up'),
onSwipeDown: () => emit('swipe-down')
onSwipeRight: () => emit('swipeRight'),
onSwipeLeft: () => emit('swipeLeft'),
onSwipeUp: () => emit('swipeUp'),
onSwipeDown: () => emit('swipeDown')
})

// Card transform style - supports both horizontal and vertical movement
Expand Down
28 changes: 21 additions & 7 deletions src/components/ai/AIMemoryHealthDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,17 @@
</div>

<!-- Error -->
<div v-if="error" class="error-banner glass">{{ error }}</div>
<div v-if="error" class="error-banner glass">
{{ error }}
</div>

<!-- Summary Cards -->
<div v-if="report" class="summary-cards">
<div class="card glass score-card" :class="gradeClass">
<h3>Memory Grade</h3>
<div class="grade-display">{{ report.grade }}</div>
<div class="grade-display">
{{ report.grade }}
</div>
<p>{{ gradeLabel }}</p>
</div>

Expand All @@ -56,21 +60,27 @@

<div class="card glass stat-card">
<h3>Sections</h3>
<div class="stat-value">{{ report.sections.length }}</div>
<div class="stat-value">
{{ report.sections.length }}
</div>
<p>{{ report.mode === 'full' ? 'Full assessment' : 'Quick check' }}</p>
</div>

<div class="card glass stat-card">
<h3>Duration</h3>
<div class="stat-value stat-value--small">{{ formatDuration(report.durationMs) }}</div>
<div class="stat-value stat-value--small">
{{ formatDuration(report.durationMs) }}
</div>
<p>{{ formatTime(report.timestamp) }}</p>
</div>
</div>

<!-- Empty State -->
<div v-else-if="!isRunning" class="empty-state glass">
<p>No assessment results yet.</p>
<p class="empty-hint">"Quick Check" runs heuristic tests instantly. "Full Assessment" adds LLM-as-judge context utilization tests (~30s).</p>
<p class="empty-hint">
"Quick Check" runs heuristic tests instantly. "Full Assessment" adds LLM-as-judge context utilization tests (~30s).
</p>
</div>

<!-- Sections -->
Expand Down Expand Up @@ -115,7 +125,9 @@
<span class="check-name">{{ check.name }}</span>
<span class="check-score" :class="scoreColorClass(check.score)">{{ check.score }}%</span>
</div>
<div class="check-value">{{ check.value }}</div>
<div class="check-value">
{{ check.value }}
</div>
<div v-if="check.recommendation" class="check-recommendation">
{{ check.recommendation }}
</div>
Expand Down Expand Up @@ -160,7 +172,9 @@
<span class="history-time">{{ formatTime(h.timestamp) }}</span>
</div>
</div>
<button class="btn btn-ghost" @click="handleClearHistory">Clear History</button>
<button class="btn btn-ghost" @click="handleClearHistory">
Clear History
</button>
</div>
</div>
</template>
Expand Down
44 changes: 27 additions & 17 deletions src/components/ai/ChatMessage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -371,15 +371,7 @@ function weeklyPlanTaskIds(rec: WeeklyPlanRecommendation): string[] {
.filter(taskId => !dismissedCardTaskIds.value.has(taskId))
}

function weeklyPlanPrimaryTaskIds(rec: WeeklyPlanRecommendation): string[] {
return rec.primaryTaskId && !dismissedCardTaskIds.value.has(rec.primaryTaskId) ? [rec.primaryTaskId] : []
}

function weeklyPlanRelatedChipIds(rec: WeeklyPlanRecommendation): string[] {
return [...new Set(rec.relatedTaskIds ?? [])]
.filter(taskId => taskId !== rec.primaryTaskId && !dismissedCardTaskIds.value.has(taskId))
.slice(0, 4)
}

function weeklyLaneTitle(rec: WeeklyPlanRecommendation): string {
const locale = weeklyPlan.value?.locale ?? 'en'
Expand Down Expand Up @@ -2586,13 +2578,17 @@ async function saveSchedule() {
data-testid="ai-clarification"
>
<header class="ai-clarification-header">
<div class="weekly-plan-source">{{ clarification.progressLabel }}</div>
<div class="weekly-plan-source">
{{ clarification.progressLabel }}
</div>
<h2>{{ clarification.locale === 'he' ? 'שאלה קצרה לפני התכנון' : 'Quick question before planning' }}</h2>
<p>{{ clarification.summary }}</p>
<details v-if="clarificationDebugLines(clarification).length" class="ai-debug-details">
<summary>{{ clarification.locale === 'he' ? 'למה אני שואל?' : 'Why ask?' }}</summary>
<ul>
<li v-for="line in clarificationDebugLines(clarification)" :key="line">{{ line }}</li>
<li v-for="line in clarificationDebugLines(clarification)" :key="line">
{{ line }}
</li>
</ul>
</details>
</header>
Expand Down Expand Up @@ -2781,7 +2777,9 @@ async function saveSchedule() {
</div>
<h2>{{ weeklyPlan.headline }}</h2>
<p>{{ weeklyPlan.weekRead.summary }}</p>
<p v-if="weeklyPlan.weekRead.mainTradeoff && !isCompactWeeklyPlan" class="weekly-plan-muted">{{ weeklyPlan.weekRead.mainTradeoff }}</p>
<p v-if="weeklyPlan.weekRead.mainTradeoff && !isCompactWeeklyPlan" class="weekly-plan-muted">
{{ weeklyPlan.weekRead.mainTradeoff }}
</p>
</header>

<section
Expand Down Expand Up @@ -2904,8 +2902,12 @@ async function saveSchedule() {
<div class="weekly-plan-focus" dir="auto">
{{ weeklyPlan.locale === 'he' ? 'נתיב' : 'Lane' }}
</div>
<h3 dir="auto">{{ weeklyLaneTitle(rec) }}</h3>
<p dir="auto">{{ weeklyLaneSubtitle(rec) }}</p>
<h3 dir="auto">
{{ weeklyLaneTitle(rec) }}
</h3>
<p dir="auto">
{{ weeklyLaneSubtitle(rec) }}
</p>
</div>
<button
v-if="!props.wideMode"
Expand Down Expand Up @@ -3077,12 +3079,18 @@ async function saveSchedule() {
>
<div class="weekly-plan-focus" dir="auto">
{{ isCompactWeeklyPlan && weeklyPlan.locale === 'he' ? 'נתיב' : isCompactWeeklyPlan ? 'Lane' : rec.focusArea }}
<template v-if="isCompactWeeklyPlan">: {{ rec.focusArea }}</template>
<template v-if="isCompactWeeklyPlan">
: {{ rec.focusArea }}
</template>
</div>
<h3>{{ rec.rank }}. {{ rec.title }}</h3>
<p v-if="!isCompactWeeklyPlan">{{ rec.whyThisMatters }}</p>
<p v-if="!isCompactWeeklyPlan">
{{ rec.whyThisMatters }}
</p>
<p>{{ rec.whyThisWeek }}</p>
<p v-if="rec.riskIfIgnored && !isCompactWeeklyPlan" class="weekly-plan-muted">{{ rec.riskIfIgnored }}</p>
<p v-if="rec.riskIfIgnored && !isCompactWeeklyPlan" class="weekly-plan-muted">
{{ rec.riskIfIgnored }}
</p>
<p class="weekly-next-action">
<strong>{{ weeklyPlan.locale === 'he' ? 'הצעד הבא' : 'Next action' }}:</strong>
{{ rec.nextAction }}
Expand Down Expand Up @@ -3255,7 +3263,9 @@ async function saveSchedule() {
<footer v-if="weeklyPlan.deferrals.length && !isCompactWeeklyPlan" class="weekly-plan-footer">
<div v-if="weeklyPlan.deferrals.length">
<strong>{{ weeklyPlan.locale === 'he' ? 'לדחות בכוונה' : 'Intentional deferrals' }}</strong>
<p v-for="defer in weeklyPlan.deferrals" :key="defer.taskId">{{ defer.reason }}</p>
<p v-for="defer in weeklyPlan.deferrals" :key="defer.taskId">
{{ defer.reason }}
</p>
</div>
</footer>
</article>
Expand Down
3 changes: 2 additions & 1 deletion src/components/base/BaseInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
<div class="input-container">
<slot name="prefix" />

<input :dir="inputDir"
<input
:id="inputId"
ref="inputRef"
v-model="localValue"
:dir="inputDir"
:type="type"
:placeholder="placeholder"
:disabled="disabled"
Expand Down
4 changes: 3 additions & 1 deletion src/components/calendar/CalendarHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ const toggleViewOptions = () => {
:class="{ active: showViewOptions || showFilters || hideCalendarDoneTasks || showFutureRecurring }"
aria-label="View options"
title="View options"
aria-haspopup="dialog"
:aria-expanded="showViewOptions"
@click="toggleViewOptions"
>
<MoreVertical :size="16" :stroke-width="1.5" />
Expand All @@ -98,7 +100,7 @@ const toggleViewOptions = () => {
:y="popoverY"
position="bottom"
variant="menu"
:close-on-click-outside="true"
close-on-click-outside
@close="showViewOptions = false"
>
<div class="view-options-menu">
Expand Down
2 changes: 2 additions & 0 deletions src/components/timer/QuickTaskDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
class="quick-task-trigger"
aria-label="Quick Tasks"
title="Quick Tasks"
aria-haspopup="dialog"
:aria-expanded="isOpen"
@click="toggleDropdown"
>
<Zap :size="16" />
Expand Down
2 changes: 1 addition & 1 deletion stats.html

Large diffs are not rendered by default.

Loading