Deployment and lifecycle management for Nix
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add accessible text to all deploy and status icons

- Add aria-label to online/1 SVG (Online/Offline)
- Add aria-label to result/1 SVG (Success/Failed/No result)
- Show full text label in deployment_status/1 completed state,
matching the other states (Created, Dispatched, etc.)
- Fix empty column label on deployments index table to 'Status'

fix: compact deploy status on mobile and seed deployments

- Add compact attr to deployment_status component to render icon-only
- Use compact mode on mobile in garden show deployments table
- Use compact mode for seed deployment results on deployment show
- Add aria-labels to dot indicators in deployment_status
- Add Status column label to garden show deployments table
- Hide Retry action on mobile in garden show deployments table
- Truncate SID on mobile in garden show deployments table

fix: remove broken action_hide_on from garden deployments table

action_hide_on generates Tailwind classes dynamically via string
interpolation, but Tailwind's purge doesn't detect them so the
responsive classes are never generated. This is a pre-existing
bug in the table component. Removing it restores the Retry button
visibility that existed before the previous commit.

SOW-109

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+48 -16
+38 -11
apps/sower/lib/sower_web/components/sower_components.ex
··· 267 267 268 268 def online(assigns) do 269 269 ~H""" 270 - <svg class="w-4 h-4" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> 270 + <svg 271 + class="w-4 h-4" 272 + viewBox="0 0 24 24" 273 + xmlns="http://www.w3.org/2000/svg" 274 + role="img" 275 + aria-label={if @state, do: "Online", else: "Offline"} 276 + > 271 277 <circle 272 278 cx="12" 273 279 cy="12" ··· 292 298 293 299 attr :state, :atom, required: true 294 300 attr :result, :atom, default: nil 301 + attr :compact, :boolean, default: false 295 302 296 303 def deployment_status(assigns) do 297 304 ~H""" 298 305 <%= case @state do %> 299 306 <% :created -> %> 300 307 <span class="inline-flex items-center gap-1.5 text-sm text-zinc-500 dark:text-zinc-400"> 301 - <span class="relative flex h-2.5 w-2.5"> 308 + <span class="relative flex h-2.5 w-2.5" role="img" aria-label="Created"> 302 309 <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-zinc-400 opacity-75" /> 303 310 <span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-zinc-400" /> 304 311 </span> 305 - Created 312 + <span class={@compact && "sr-only"}>Created</span> 306 313 </span> 307 314 <% :dispatched -> %> 308 315 <span class="inline-flex items-center gap-1.5 text-sm text-blue-600 dark:text-blue-400"> 309 - <span class="relative flex h-2.5 w-2.5"> 316 + <span class="relative flex h-2.5 w-2.5" role="img" aria-label="Dispatched"> 310 317 <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-500 opacity-75" /> 311 318 <span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-blue-500" /> 312 319 </span> 313 - Dispatched 320 + <span class={@compact && "sr-only"}>Dispatched</span> 314 321 </span> 315 322 <% :acknowledged -> %> 316 323 <span class="inline-flex items-center gap-1.5 text-sm text-blue-600 dark:text-blue-400"> 317 - <span class="relative flex h-2.5 w-2.5"> 324 + <span class="relative flex h-2.5 w-2.5" role="img" aria-label="Acknowledged"> 318 325 <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-500 opacity-75" /> 319 326 <span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-blue-500" /> 320 327 </span> 321 - Acknowledged 328 + <span class={@compact && "sr-only"}>Acknowledged</span> 322 329 </span> 323 330 <% :completed -> %> 324 - <.result result={@result} /> 331 + <span class={[ 332 + "inline-flex items-center gap-1.5 text-sm", 333 + result_text_class(@result) 334 + ]}> 335 + <.result result={@result} /> 336 + <span :if={not @compact}>{result_label(@result)}</span> 337 + </span> 325 338 <% :stale -> %> 326 339 <span class="inline-flex items-center gap-1.5 text-sm text-amber-600 dark:text-amber-400"> 327 - <span class="relative flex h-2.5 w-2.5"> 340 + <span class="relative flex h-2.5 w-2.5" role="img" aria-label="Stale"> 328 341 <span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-amber-500" /> 329 342 </span> 330 - Stale 343 + <span class={@compact && "sr-only"}>Stale</span> 331 344 </span> 332 345 <% end %> 333 346 """ ··· 337 350 338 351 def result(assigns) do 339 352 ~H""" 340 - <svg class="w-5 h-5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> 353 + <svg 354 + class="w-5 h-5" 355 + viewBox="0 0 24 24" 356 + xmlns="http://www.w3.org/2000/svg" 357 + role="img" 358 + aria-label={result_label(@result)} 359 + > 341 360 <%= cond do %> 342 361 <% @result == :success -> %> 343 362 <path ··· 376 395 </svg> 377 396 """ 378 397 end 398 + 399 + defp result_label(:success), do: "Success" 400 + defp result_label(nil), do: "No result" 401 + defp result_label(_), do: "Failed" 402 + 403 + defp result_text_class(:success), do: "text-green-600 dark:text-green-400" 404 + defp result_text_class(nil), do: "text-zinc-500 dark:text-zinc-400" 405 + defp result_text_class(_), do: "text-red-600 dark:text-red-400" 379 406 380 407 attr :datetime, DateTime, default: nil 381 408 attr :user_timezone, :string, required: true
+1 -1
apps/sower/lib/sower_web/live/deployment_live/index.html.heex
··· 52 52 path={~p"/deployments"} 53 53 row_click={fn deployment -> JS.navigate(~p"/deployments/#{deployment}") end} 54 54 > 55 - <:col :let={deployment} label=""> 55 + <:col :let={deployment} label="Status"> 56 56 <.deployment_status state={deployment.state} result={deployment.result} /> 57 57 </:col> 58 58 <:col :let={deployment} label="sid">
+1
apps/sower/lib/sower_web/live/deployment_live/show.ex
··· 94 94 :if={sd.result} 95 95 state={:completed} 96 96 result={sd.result} 97 + compact 97 98 /> 98 99 <.button 99 100 :if={sd.log}
+8 -4
apps/sower/lib/sower_web/live/garden_live/show.html.heex
··· 110 110 rows={@deployments} 111 111 row_click={fn deployment -> JS.navigate(~p"/deployments/#{deployment.sid}") end} 112 112 > 113 - <:col :let={deployment} label=""> 114 - <.deployment_status state={deployment.state} result={deployment.result} /> 113 + <:col :let={deployment} label="Status"> 114 + <span class="sm:hidden"> 115 + <.deployment_status state={deployment.state} result={deployment.result} compact /> 116 + </span> 117 + <span class="hidden sm:inline-flex"> 118 + <.deployment_status state={deployment.state} result={deployment.result} /> 119 + </span> 115 120 </:col> 116 121 <:col :let={deployment} label="SID"> 117 122 <span 118 - class="sm:hidden truncate max-sm:max-w-[12rem] inline-block align-bottom" 123 + class="truncate max-w-[8rem] sm:max-w-none inline-block align-bottom" 119 124 title={deployment.sid} 120 125 > 121 126 {deployment.sid} 122 127 </span> 123 - <span class="hidden sm:inline">{deployment.sid}</span> 124 128 </:col> 125 129 <:col :let={deployment} label="Created" hide_on={:sm}> 126 130 <.local_datetime datetime={deployment.inserted_at} user_timezone={@user_timezone} />