{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "feature-flags-manager",
  "title": "Feature Flags Manager",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/feature-flags-manager/feature-flags-manager.component.ts",
      "content": "// Feature flags management dashboard: header with create button, KPI metric cards, a search +\n// status filter toolbar, and a flag table with master switches, rollout progress, targeting\n// rules, environment badges and a per-row actions menu. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, DestroyRef, Input, computed, inject, signal } from '@angular/core'\nimport {\n  Check,\n  Copy,\n  Flag,\n  History,\n  LucideAngularModule,\n  MoreHorizontal,\n  Plus,\n  Search,\n  ShieldAlert,\n  Sliders,\n  SlidersHorizontal,\n  Trash2,\n  Zap,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiCardComponent } from '@/ui/card/card.component'\nimport {\n  UiDropdownMenuComponent,\n  UiDropdownMenuContentComponent,\n  UiDropdownMenuItemComponent,\n  UiDropdownMenuSeparatorComponent,\n  UiDropdownMenuTriggerComponent,\n} from '@/ui/dropdown-menu/dropdown-menu.component'\nimport { UiInputComponent } from '@/ui/input/input.component'\nimport { UiProgressComponent } from '@/ui/progress/progress.component'\nimport { UiSwitchComponent } from '@/ui/switch/switch.component'\nimport {\n  UiTableBodyComponent,\n  UiTableCellComponent,\n  UiTableComponent,\n  UiTableHeadComponent,\n  UiTableHeaderComponent,\n  UiTableRowComponent,\n} from '@/ui/table/table.component'\n\nexport interface EnvironmentState {\n  production: boolean\n  staging: boolean\n  development: boolean\n}\n\nexport interface FeatureFlag {\n  id: string\n  name: string\n  key: string\n  description: string\n  tags: string[]\n  enabled: boolean\n  rollout: number\n  targetingRules: string\n  environments: EnvironmentState\n  evaluationCount?: string\n  lastUpdated?: string\n}\n\nexport type FeatureFlagStatusFilter = 'all' | 'enabled' | 'disabled'\n\nexport const defaultFlags: FeatureFlag[] = [\n  {\n    id: 'ff-1',\n    name: 'New Checkout Experience',\n    key: 'new-checkout-v2',\n    description: 'Modern multi-step checkout flow with one-click payment options.',\n    tags: ['Frontend', 'Beta', 'Core'],\n    enabled: true,\n    rollout: 50,\n    targetingRules: \"plan === 'enterprise' && country === 'US'\",\n    environments: { production: true, staging: true, development: false },\n    evaluationCount: '1.8M/day',\n    lastUpdated: '10 min ago',\n  },\n  {\n    id: 'ff-2',\n    name: 'Dark Mode V2 Beta',\n    key: 'dark-mode-beta',\n    description: 'High-contrast OKLCH dark palette with custom system theme sync.',\n    tags: ['Frontend', 'Beta'],\n    enabled: true,\n    rollout: 100,\n    targetingRules: 'beta_tester === true',\n    environments: { production: true, staging: true, development: true },\n    evaluationCount: '920K/day',\n    lastUpdated: '2 hours ago',\n  },\n  {\n    id: 'ff-3',\n    name: 'AI Auto Complete',\n    key: 'ai-auto-complete',\n    description: 'LLM-assisted syntax suggestion and context-aware auto-completion.',\n    tags: ['AI', 'Core', 'Beta'],\n    enabled: true,\n    rollout: 25,\n    targetingRules: \"org_tier IN ['growth', 'enterprise']\",\n    environments: { production: true, staging: true, development: false },\n    evaluationCount: '640K/day',\n    lastUpdated: '1 day ago',\n  },\n  {\n    id: 'ff-4',\n    name: 'GraphQL API v2 Gateway',\n    key: 'graphql-api-v2',\n    description: 'High-throughput GraphQL federation engine replacing legacy REST proxy.',\n    tags: ['Backend', 'Core'],\n    enabled: false,\n    rollout: 0,\n    targetingRules: 'internal_team === true',\n    environments: { production: false, staging: true, development: true },\n    evaluationCount: '480K/day',\n    lastUpdated: '3 days ago',\n  },\n  {\n    id: 'ff-5',\n    name: 'Crypto Payments Pilot',\n    key: 'crypto-payments',\n    description: 'USDC and Ethereum settlement rail for international enterprise invoices.',\n    tags: ['Core', 'Beta'],\n    enabled: false,\n    rollout: 10,\n    targetingRules: \"country IN ['US', 'DE', 'SG'] && plan === 'enterprise'\",\n    environments: { production: false, staging: true, development: false },\n    evaluationCount: '120K/day',\n    lastUpdated: '5 days ago',\n  },\n]\n\ninterface EnvBadge {\n  label: string\n  key: keyof EnvironmentState\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-feature-flags-manager, [ui-feature-flags-manager]',\n  standalone: true,\n  // React renders the root <div> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiDropdownMenuComponent,\n    UiDropdownMenuContentComponent,\n    UiDropdownMenuItemComponent,\n    UiDropdownMenuSeparatorComponent,\n    UiDropdownMenuTriggerComponent,\n    UiInputComponent,\n    UiProgressComponent,\n    UiSwitchComponent,\n    UiTableComponent,\n    UiTableBodyComponent,\n    UiTableCellComponent,\n    UiTableHeadComponent,\n    UiTableHeaderComponent,\n    UiTableRowComponent,\n  ],\n  template: `\n    <div data-slot=\"feature-flags-manager\" [class]=\"rootClass\">\n      <!-- Header Section -->\n      <div class=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n        <div>\n          <h2 class=\"text-foreground text-2xl font-bold tracking-tight\">Feature Flags</h2>\n          <p class=\"text-muted-foreground mt-1 text-sm\">\n            Safely deploy features with percentage rollouts, user targeting, and kill switches.\n          </p>\n        </div>\n        <div class=\"flex items-center gap-2\">\n          <button ui-button>\n            <lucide-icon [img]=\"Plus\" aria-hidden=\"true\" class=\"size-4\" />\n            Create Flag\n          </button>\n        </div>\n      </div>\n\n      <!-- Summary Metric Cards -->\n      <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n        <div ui-card class=\"p-4 shadow-xs\">\n          <div class=\"flex items-center justify-between gap-x-2\">\n            <span class=\"text-muted-foreground text-xs font-medium\">Total Flags</span>\n            <div class=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-md\">\n              <lucide-icon [img]=\"Flag\" aria-hidden=\"true\" class=\"size-4\" />\n            </div>\n          </div>\n          <div class=\"mt-2\">\n            <div class=\"text-foreground text-2xl font-bold tracking-tight\">24</div>\n            <p class=\"text-muted-foreground mt-1 text-xs\">5 in current scope</p>\n          </div>\n        </div>\n\n        <div ui-card class=\"p-4 shadow-xs\">\n          <div class=\"flex items-center justify-between gap-x-2\">\n            <span class=\"text-muted-foreground text-xs font-medium\">Active Rollouts</span>\n            <div class=\"bg-info/10 text-info flex size-8 items-center justify-center rounded-md\">\n              <lucide-icon [img]=\"SlidersHorizontal\" aria-hidden=\"true\" class=\"size-4\" />\n            </div>\n          </div>\n          <div class=\"mt-2\">\n            <div class=\"text-foreground text-2xl font-bold tracking-tight\">8</div>\n            <p class=\"text-muted-foreground mt-1 text-xs\">Gradual traffic ramps</p>\n          </div>\n        </div>\n\n        <div ui-card class=\"p-4 shadow-xs\">\n          <div class=\"flex items-center justify-between gap-x-2\">\n            <span class=\"text-muted-foreground text-xs font-medium\">Kill-Switches Armed</span>\n            <div class=\"bg-warning/10 text-warning flex size-8 items-center justify-center rounded-md\">\n              <lucide-icon [img]=\"ShieldAlert\" aria-hidden=\"true\" class=\"size-4\" />\n            </div>\n          </div>\n          <div class=\"mt-2\">\n            <div class=\"text-foreground text-2xl font-bold tracking-tight\">3</div>\n            <p class=\"text-muted-foreground mt-1 text-xs\">Instant emergency trip</p>\n          </div>\n        </div>\n\n        <div ui-card class=\"p-4 shadow-xs\">\n          <div class=\"flex items-center justify-between gap-x-2\">\n            <span class=\"text-muted-foreground text-xs font-medium\">Evaluation Volume</span>\n            <div class=\"bg-success/10 text-success flex size-8 items-center justify-center rounded-md\">\n              <lucide-icon [img]=\"Zap\" aria-hidden=\"true\" class=\"size-4\" />\n            </div>\n          </div>\n          <div class=\"mt-2\">\n            <div class=\"text-foreground text-2xl font-bold tracking-tight\">4.2M/day</div>\n            <p class=\"text-muted-foreground mt-1 text-xs\">99.99% cache hit · 1.2ms p99</p>\n          </div>\n        </div>\n      </div>\n\n      <!-- Filter & Search Toolbar -->\n      <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n        <div class=\"flex flex-1 flex-wrap items-center gap-2\">\n          <div class=\"relative w-full sm:w-80\">\n            <lucide-icon\n              [img]=\"Search\"\n              aria-hidden=\"true\"\n              class=\"text-muted-foreground pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2\"\n            />\n            <ui-input\n              [value]=\"searchQuery()\"\n              (valueChange)=\"searchQuery.set($event)\"\n              placeholder=\"Search flags by name, key, or tag...\"\n              class=\"h-9 pl-8.5 text-xs sm:text-sm\"\n            />\n          </div>\n\n          <div class=\"border-border bg-muted/30 flex items-center rounded-lg border p-0.5\">\n            @for (opt of statusOptions; track opt.value) {\n              <button type=\"button\" [class]=\"statusButtonClass(opt.value)\" (click)=\"selectedStatus.set(opt.value)\">\n                {{ opt.label }}\n              </button>\n            }\n          </div>\n        </div>\n\n        <div class=\"flex items-center gap-2\">\n          <span class=\"text-muted-foreground text-xs tabular-nums\">\n            Showing {{ filteredFlags().length }} of {{ flags().length }} flags\n          </span>\n        </div>\n      </div>\n\n      <!-- Feature Flags Table -->\n      <div class=\"bg-card border-border overflow-hidden rounded-xl border shadow-xs\">\n        <div class=\"overflow-x-auto\">\n          <div ui-table class=\"max-w-[920px] min-w-full\">\n            <thead ui-table-header>\n              <tr ui-table-row class=\"bg-muted/40 hover:bg-transparent\">\n                <th ui-table-head class=\"w-[300px]\">Flag</th>\n                <th ui-table-head class=\"w-[130px]\">Status</th>\n                <th ui-table-head class=\"w-[160px]\">Rollout</th>\n                <th ui-table-head class=\"min-w-[240px]\">Targeting Rules</th>\n                <th ui-table-head class=\"w-[160px]\">Environments</th>\n                <th ui-table-head class=\"w-[50px] text-right\">\n                  <span class=\"sr-only\">Actions</span>\n                </th>\n              </tr>\n            </thead>\n            <tbody ui-table-body>\n              @for (flag of filteredFlags(); track flag.id) {\n                <tr ui-table-row [class]=\"rowClass(flag)\">\n                  <!-- Flag Name, Key, Description & Tags -->\n                  <td ui-table-cell class=\"py-3.5 align-top\">\n                    <div class=\"space-y-1\">\n                      <div class=\"flex items-center gap-2\">\n                        <span class=\"text-foreground text-sm font-semibold\">{{ flag.name }}</span>\n                      </div>\n                      <div class=\"flex items-center gap-1.5\">\n                        <code\n                          class=\"bg-muted/70 text-muted-foreground border-border/50 rounded border px-1.5 py-0.5 font-mono text-xs select-all\"\n                          >{{ flag.key }}</code\n                        >\n                        <button\n                          type=\"button\"\n                          class=\"text-muted-foreground hover:text-foreground hover:bg-muted inline-flex min-h-6 min-w-6 items-center justify-center rounded p-0.5 transition-colors\"\n                          [attr.title]=\"copiedKey() === flag.key ? 'Copied!' : 'Copy key'\"\n                          (click)=\"copyFlagKey(flag.key)\"\n                        >\n                          @if (copiedKey() === flag.key) {\n                            <lucide-icon [img]=\"Check\" class=\"text-success size-3\" />\n                          } @else {\n                            <lucide-icon [img]=\"Copy\" class=\"size-3\" />\n                          }\n                          <span class=\"sr-only\">Copy {{ flag.key }}</span>\n                        </button>\n                      </div>\n                      <p class=\"text-muted-foreground line-clamp-1 pt-0.5 text-xs\">{{ flag.description }}</p>\n                      <div class=\"flex flex-wrap items-center gap-1 pt-1\">\n                        @for (tag of flag.tags; track tag) {\n                          <span\n                            ui-badge\n                            variant=\"outline\"\n                            class=\"text-muted-foreground px-1.5 py-0 text-xs font-normal\"\n                            >{{ tag }}</span\n                          >\n                        }\n                      </div>\n                    </div>\n                  </td>\n\n                  <!-- Master Status Switch -->\n                  <td ui-table-cell class=\"py-3.5 align-middle\">\n                    <div class=\"flex items-center gap-2.5\">\n                      <button\n                        ui-switch\n                        [checked]=\"flag.enabled\"\n                        [attr.aria-label]=\"'Toggle ' + flag.name\"\n                        (checkedChange)=\"toggleFlag(flag.id)\"\n                      ></button>\n                      <span [class]=\"statusTextClass(flag)\">{{ flag.enabled ? 'Enabled' : 'Disabled' }}</span>\n                    </div>\n                  </td>\n\n                  <!-- Rollout % Visual Progress Bar -->\n                  <td ui-table-cell class=\"py-3.5 align-middle\">\n                    <div class=\"max-w-[130px] space-y-1.5\">\n                      <div class=\"flex items-center justify-between gap-x-2 text-xs\">\n                        <span class=\"text-foreground font-semibold tabular-nums\">{{\n                          flag.enabled ? flag.rollout + '%' : '0%'\n                        }}</span>\n                        <span class=\"text-muted-foreground text-xs\">{{ rolloutLabel(flag) }}</span>\n                      </div>\n                      <div ui-progress [value]=\"flag.enabled ? flag.rollout : 0\" class=\"h-1.5\"></div>\n                    </div>\n                  </td>\n\n                  <!-- Targeting Rules Summary -->\n                  <td ui-table-cell class=\"py-3.5 align-middle\">\n                    <div class=\"flex items-center\">\n                      <code\n                        class=\"border-border/60 bg-muted/40 text-foreground/80 inline-flex max-w-[260px] items-center gap-1 truncate rounded border px-2 py-1 font-mono text-xs\"\n                        [attr.title]=\"flag.targetingRules\"\n                      >\n                        <span class=\"text-muted-foreground font-sans text-xs\">Target:</span>\n                        <span class=\"truncate\">{{ flag.targetingRules }}</span>\n                      </code>\n                    </div>\n                  </td>\n\n                  <!-- Environment Badges -->\n                  <td ui-table-cell class=\"py-3.5 align-middle\">\n                    <div class=\"flex items-center gap-1\">\n                      @for (env of envBadges; track env.key) {\n                        <span [class]=\"envBadgeClass(flag, env.key)\">\n                          <span [class]=\"envDotClass(flag, env.key)\"></span>\n                          {{ env.label }}\n                        </span>\n                      }\n                    </div>\n                  </td>\n\n                  <!-- Actions Dropdown -->\n                  <td ui-table-cell class=\"py-3.5 text-right align-middle\">\n                    <ui-dropdown-menu>\n                      <button\n                        ui-button\n                        ui-dropdown-menu-trigger\n                        variant=\"ghost\"\n                        size=\"icon-sm\"\n                        class=\"text-muted-foreground hover:text-foreground\"\n                      >\n                        <lucide-icon [img]=\"MoreHorizontal\" aria-hidden=\"true\" class=\"size-4\" />\n                        <span class=\"sr-only\">Actions for {{ flag.name }}</span>\n                      </button>\n                      <ui-dropdown-menu-content align=\"end\">\n                        <ui-dropdown-menu-item>\n                          <lucide-icon [img]=\"Sliders\" aria-hidden=\"true\" class=\"mr-2 size-4\" />\n                          Edit rules\n                        </ui-dropdown-menu-item>\n                        <ui-dropdown-menu-item>\n                          <lucide-icon [img]=\"History\" aria-hidden=\"true\" class=\"mr-2 size-4\" />\n                          Audit history\n                        </ui-dropdown-menu-item>\n                        <ui-dropdown-menu-item (select)=\"copyFlagKey(flag.key)\">\n                          <lucide-icon [img]=\"Copy\" aria-hidden=\"true\" class=\"mr-2 size-4\" />\n                          Copy flag key\n                        </ui-dropdown-menu-item>\n                        <ui-dropdown-menu-separator />\n                        <ui-dropdown-menu-item\n                          class=\"text-destructive focus:text-destructive\"\n                          (select)=\"deleteFlag(flag.id)\"\n                        >\n                          <lucide-icon [img]=\"Trash2\" aria-hidden=\"true\" class=\"mr-2 size-4\" />\n                          Delete flag\n                        </ui-dropdown-menu-item>\n                      </ui-dropdown-menu-content>\n                    </ui-dropdown-menu>\n                  </td>\n                </tr>\n              }\n\n              <!-- Empty State -->\n              @if (filteredFlags().length === 0) {\n                <tr ui-table-row>\n                  <td ui-table-cell colspan=\"6\" class=\"text-muted-foreground h-36 text-center\">\n                    <div class=\"flex flex-col items-center justify-center space-y-1.5\">\n                      <lucide-icon [img]=\"Search\" class=\"text-muted-foreground/40 size-6\" />\n                      <p class=\"text-foreground text-sm font-medium\">No feature flags found</p>\n                      <p class=\"text-muted-foreground text-xs\">\n                        No flags match your search or filter criteria. Try adjusting your query.\n                      </p>\n                    </div>\n                  </td>\n                </tr>\n              }\n            </tbody>\n          </div>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiFeatureFlagsManagerComponent {\n  protected readonly Check = Check\n  protected readonly Copy = Copy\n  protected readonly Flag = Flag\n  protected readonly History = History\n  protected readonly MoreHorizontal = MoreHorizontal\n  protected readonly Plus = Plus\n  protected readonly Search = Search\n  protected readonly ShieldAlert = ShieldAlert\n  protected readonly Sliders = Sliders\n  protected readonly SlidersHorizontal = SlidersHorizontal\n  protected readonly Trash2 = Trash2\n  protected readonly Zap = Zap\n\n  protected readonly statusOptions: { value: FeatureFlagStatusFilter; label: string }[] = [\n    { value: 'all', label: 'All' },\n    { value: 'enabled', label: 'Enabled' },\n    { value: 'disabled', label: 'Disabled' },\n  ]\n\n  protected readonly envBadges: EnvBadge[] = [\n    { label: 'Prod', key: 'production' },\n    { label: 'Stg', key: 'staging' },\n    { label: 'Dev', key: 'development' },\n  ]\n\n  private readonly destroyRef = inject(DestroyRef)\n  private readonly timers = new Set<ReturnType<typeof setTimeout>>()\n\n  /** Seed rows; later edits live in the component's own state, as in React's useState initialiser. */\n  @Input() set initialFlags(value: FeatureFlag[] | undefined) {\n    this.flags.set(value ?? defaultFlags)\n  }\n  @Input('class') className?: string\n\n  readonly flags = signal<FeatureFlag[]>(defaultFlags)\n  readonly searchQuery = signal('')\n  readonly selectedStatus = signal<FeatureFlagStatusFilter>('all')\n  readonly copiedKey = signal<string | null>(null)\n\n  readonly filteredFlags = computed(() => {\n    const query = this.searchQuery().trim().toLowerCase()\n    const status = this.selectedStatus()\n    return this.flags().filter((flag) => {\n      if (status === 'enabled' && !flag.enabled) return false\n      if (status === 'disabled' && flag.enabled) return false\n      if (!query) return true\n      return (\n        flag.name.toLowerCase().includes(query) ||\n        flag.key.toLowerCase().includes(query) ||\n        flag.description.toLowerCase().includes(query) ||\n        flag.tags.some((t) => t.toLowerCase().includes(query))\n      )\n    })\n  })\n\n  constructor() {\n    this.destroyRef.onDestroy(() => {\n      for (const t of this.timers) clearTimeout(t)\n      this.timers.clear()\n    })\n  }\n\n  get rootClass(): string {\n    return cn('w-full space-y-6', this.className)\n  }\n\n  toggleFlag(id: string): void {\n    this.flags.update((prev) => prev.map((flag) => (flag.id === id ? { ...flag, enabled: !flag.enabled } : flag)))\n  }\n\n  deleteFlag(id: string): void {\n    this.flags.update((prev) => prev.filter((flag) => flag.id !== id))\n  }\n\n  copyFlagKey(key: string): void {\n    if (typeof navigator !== 'undefined' && navigator.clipboard) {\n      void navigator.clipboard.writeText(key)\n      this.copiedKey.set(key)\n      const t = setTimeout(() => {\n        this.timers.delete(t)\n        this.copiedKey.update((curr) => (curr === key ? null : curr))\n      }, 2000)\n      this.timers.add(t)\n    }\n  }\n\n  statusButtonClass(value: FeatureFlagStatusFilter): string {\n    return cn(\n      'min-h-6 rounded-md px-2.5 py-1 text-xs font-medium transition-colors',\n      this.selectedStatus() === value\n        ? 'bg-background text-foreground shadow-xs'\n        : 'text-muted-foreground hover:text-foreground',\n    )\n  }\n\n  rowClass(flag: FeatureFlag): string {\n    return cn('hover:bg-muted/40 transition-colors', !flag.enabled && 'opacity-75 dark:opacity-70')\n  }\n\n  statusTextClass(flag: FeatureFlag): string {\n    return cn('text-xs font-medium', flag.enabled ? 'text-success dark:text-success' : 'text-muted-foreground')\n  }\n\n  rolloutLabel(flag: FeatureFlag): string {\n    if (!flag.enabled) return 'Inactive'\n    return flag.rollout === 100 ? 'All users' : 'Ramp'\n  }\n\n  envBadgeClass(flag: FeatureFlag, key: keyof EnvironmentState): string {\n    return cn(\n      'inline-flex items-center gap-1 rounded border px-1.5 py-0.5 font-mono text-xs font-medium',\n      flag.environments[key]\n        ? 'bg-success/10 text-success border-success/20'\n        : 'bg-muted/40 text-muted-foreground border-transparent opacity-60',\n    )\n  }\n\n  envDotClass(flag: FeatureFlag, key: keyof EnvironmentState): string {\n    return cn('size-1.5 rounded-full', flag.environments[key] ? 'bg-success' : 'bg-muted-foreground/40')\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/feature-flags-manager/feature-flags-manager.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/feature-flags-manager/index.ts",
      "content": "export {\n  UiFeatureFlagsManagerComponent,\n  defaultFlags,\n  type EnvironmentState,\n  type FeatureFlag,\n  type FeatureFlagStatusFilter,\n} from './feature-flags-manager.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/feature-flags-manager/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json",
    "https://uipkge.dev/r/angular/dropdown-menu.json",
    "https://uipkge.dev/r/angular/input.json",
    "https://uipkge.dev/r/angular/progress.json",
    "https://uipkge.dev/r/angular/switch.json",
    "https://uipkge.dev/r/angular/table.json"
  ],
  "description": "LaunchDarkly and PostHog style feature flags management dashboard: top header with search and create flag button, summary KPI metric cards, master status switch, percentage rollout indicators, targeting rules summary, environment statuses, and action menus.",
  "categories": [
    "devops",
    "dashboard",
    "app",
    "data"
  ]
}