feat: add action_dropdown macro with loading state support

- Create action_dropdown macro in dropdowns.html supporting:
  - Loading/disabled state via loading_var parameter
  - Custom loading label
  - Icon support
  - Primary/secondary variants
- Update code quality dashboard to use new macro
- Add Dropdowns section to components page with examples:
  - Basic dropdown
  - Action dropdown with loading state
  - Context menu (3-dot)
  - Variant showcase (primary, secondary, ghost)

Architecture validation now passes with 0 errors and 0 warnings.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-21 21:13:08 +01:00
parent d50b154823
commit 245040d256
4 changed files with 225 additions and 38 deletions

View File

@@ -2,6 +2,7 @@
{% extends "admin/base.html" %}
{% from 'shared/macros/alerts.html' import loading_state, error_state, alert_dynamic %}
{% from 'shared/macros/headers.html' import page_header_flex, refresh_button %}
{% from 'shared/macros/dropdowns.html' import action_dropdown, dropdown_item %}
{% block title %}Code Quality Dashboard{% endblock %}
@@ -14,44 +15,18 @@
{% block content %}
{% call page_header_flex(title='Code Quality Dashboard', subtitle='Unified code quality tracking: architecture, security, and performance') %}
{{ refresh_button(variant='secondary') }}
{# Custom dropdown: disabled state + template switching not supported by macro #}
<div x-data="{ scanDropdownOpen: false }" class="relative">
<button @click="scanDropdownOpen = !scanDropdownOpen"
:disabled="scanning"
class="flex items-center px-4 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple disabled:opacity-50">
<template x-if="!scanning">
<span class="flex items-center">
<span x-html="$icon('search', 'w-4 h-4 mr-2')"></span>
Run Scan
<span x-html="$icon('chevron-down', 'w-4 h-4 ml-1')"></span>
</span>
</template>
<template x-if="scanning">
<span>Scanning...</span>
</template>
</button>
<div x-show="scanDropdownOpen"
@click.away="scanDropdownOpen = false"
x-transition
class="absolute right-0 mt-2 w-48 bg-white dark:bg-gray-800 rounded-lg shadow-lg z-10 border border-gray-200 dark:border-gray-700">
<button @click="runScan('all'); scanDropdownOpen = false"
class="block w-full px-4 py-2 text-sm text-left text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-t-lg">
Run All Validators
</button>
<button @click="runScan('architecture'); scanDropdownOpen = false"
class="block w-full px-4 py-2 text-sm text-left text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700">
Architecture Only
</button>
<button @click="runScan('security'); scanDropdownOpen = false"
class="block w-full px-4 py-2 text-sm text-left text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700">
Security Only
</button>
<button @click="runScan('performance'); scanDropdownOpen = false"
class="block w-full px-4 py-2 text-sm text-left text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-b-lg">
Performance Only
</button>
</div>
</div>
{% call action_dropdown(
label='Run Scan',
loading_label='Scanning...',
open_var='scanDropdownOpen',
loading_var='scanning',
icon='search'
) %}
{{ dropdown_item('Run All Validators', 'runScan("all"); scanDropdownOpen = false') }}
{{ dropdown_item('Architecture Only', 'runScan("architecture"); scanDropdownOpen = false') }}
{{ dropdown_item('Security Only', 'runScan("security"); scanDropdownOpen = false') }}
{{ dropdown_item('Performance Only', 'runScan("performance"); scanDropdownOpen = false') }}
{% endcall %}
{% endcall %}
{{ loading_state('Loading dashboard...') }}